Skip to content

Instantly share code, notes, and snippets.

@Powersaurus
Created June 27, 2020 12:42
Show Gist options
  • Save Powersaurus/ea9a1d57fb30ea166e7e48762dca0dde to your computer and use it in GitHub Desktop.
Save Powersaurus/ea9a1d57fb30ea166e7e48762dca0dde to your computer and use it in GitHub Desktop.
Caped Feline Arena June '20 build
pico-8 cartridge // http://www.pico-8.com
version 27
__lua__
-- caped feline arena
-- raycaster demo
-- by @powersaurus
-- based heavily on http://lodev.org/cgtutor/raycasting.html
-- and http://lodev.org/cgtutor/raycasting2.html
-- and inspired by the work of @matthughson
-- Heap sort by @CasualEffects
-- thanks for advice from @kometbomb and @doyousketch2
-- todo
-- player pos should not be obj
-- smoke - this consumes way too many tokens to call
-- 7413 to beat w/ weapons
maps={
--name,x,y,xlimit,ylimit,numplayers)
{"port",0,0,31,23,7},
--{"the crossing",32,0,56,31,8},
{"the crypt",56,0,72,16,4},
--{"the mine",56,16,72,32,2},
{"the stone circle",72,0,96,24,7},
{"the great hall",96,0,127,24,8}
--{"new map",0,20,16,31,2}
}
diagonals={
--*/
--[[
xt=1
yt=2
stx=3
sty=4
dx=5
dy=6
t=7
--]]
[72]={-1,0,
0,1,
1,-1,-1},
--\*
[73]={0,-1,
0,0,
1,1,1},
--*\
[74]={-1,0,
0,0,
1,1,-1},
--/*
[75]={0,1,
0,1,
1,-1,1}
}
function _init()
init_gfx()
skip_title=false
world=make_world({"intro",0,0,31,31})
player=make_player(11,6)
instructions=false
map_pick=0
_draw=draw_title
_update=update_title
end
function update_title()
if skip_title or btnp(5) then
init_game()
elseif btnp(4) then
sfx(9)
instructions=not instructions
elseif btnp(➡️) then
map_pick=(map_pick+1)%#maps
elseif btnp(⬅️) then
map_pick=(map_pick-1)%#maps
end
turn_player(player,0.0027)
end
function draw_title()
draw_perspective(world,
player,dist_table)
if instructions then
print("❎ toggle strafe",32,32,7)
print("🅾️ fire",32,40,7)
print(" ⬆️",24,48,7)
print("⬅️⬇️➡️ move - l/r turn",24,56,7)
else
print("caped feline arena",28,32,7)
local name=maps[map_pick+1][1]
print("play map: "..name,36-#name,64,7)
print("⬅️ and ➡️ to select",26,72,7)
end
print("press ❎ to start",28,96,7)
print("press 🅾️ for instructions",12,104,7)
end
function init_game()
respawn_timer=0
scoreboard_timer=0
timer=0
level_time_limit=5400
id=1
start_idx=0
strafe=false
draw_map=false--false
ai=true
hvy=0 -- move hand
frog_msg=""
frog_msg_timer=0
init_gfx()
projectiles={}
w_items={}
world=make_world(
maps[map_pick+1]
)
--92,13
player=make_player(14,3)
--24,11)-- --14,3
-- if selecting maps
respawn_pl(player)
-- turn_player(player,0.333)
cats={}
players={}
names={
"marlin",
"balthozar",
"sabrini",
"gendilf",
"wellow",
"mergona",
"praspero"
}
--[[ local cat=make_cat(
{11.5,5.5,1,0,0})
add(sprites,cat)
add(cats,cat)
add(players,cat)--]]
for i=1,maps[map_pick+1][6]-1 do
spawn_cat()
end
add(players,player)
_draw=draw
_update=update
menuitem(1,"toggle map",toggle_map)
menuitem(2,"toggle ai",function()
ai=not ai
end)
end
function init_gfx()
create_palettes()
dist_table={}
cam_t={}
for y=0,128 do
dist_table[y]=128/(2*y-128)
cam_t[y]=2*y/128-1
end
sprites={}
particles={}
end
function toggle_map()
draw_map=not draw_map
end
function update()
if timer>=level_time_limit then
scoreboard_timer+=1
respawn_timer=0
if scoreboard_timer==300
or btnp(4) then
_init()
end
return
else
timer+=1
hy=clamp(hvy,0,20)
hvy=max(hvy-4,-3)
update_doors(doors)
if(frog_msg_timer>0)frog_msg_timer-=1
if respawn_timer>0 then
if respawn_timer==1 or btnp(4) then
respawn_pl(player)
respawn_timer=0
return
end
respawn_timer-=1
else
do_input()
player:update()
end
if ai then
for _,s in pairs(cats) do
s:update()
end
end
for _,p in pairs(projectiles) do
p:update(players)
if p.health==0 then
del(projectiles,p)
del(sprites,p)
end
end
for _,s in pairs(particles) do
s.z+=s.vz
s.x+=s.vx
s.y+=s.vy
s.health-=1
if(s.z>30 or s.health==0)del(particles,s)
end
end
end
function do_input()
strafe=false
if(btn(5))strafe=true
local sp=0.08
local ssp=0.1
if btn(4) then
if player.shoot_timer<=0 then
if player.wand==3 then
hvy+=5
else
hvy+=20
end
fire(player,projectiles)
end
end
if btn(0) then
if strafe then
strafe_in_current_dir(player,-ssp)
else
turn_player2(player,-0.0027)
end
end
if btn(1) then
if strafe then
strafe_in_current_dir(player,ssp)
else
turn_player2(player,.0027)
end
end
if btn(2) then
move_in_current_dir(player,sp)
end
if btn(3) then
move_in_current_dir(player,-sp)
end
end
function pick_spawn_pt(e)
start_idx=(start_idx+1)%#world.starts
return world.starts[start_idx+1]
end
hy=0
function draw()
reset_palette()
if draw_map then
draw_map_view(world,player)
else
draw_perspective(world,
player,dist_table)
if timer>=level_time_limit
or respawn_timer>0
then
draw_scoreboard(player,cats)
else
--hand
sspr(96,112,32,16,64+hy,96+hy/2,64,32)
sspr(64+player.wand*8,96,8,24,80+hy,56+hy/2,16,48)
draw_hud(player)
end
end
end
function draw_scoreboard(p,cats)
local scores={}
add(scores,{
name=p.name,
frogs=p.frogs})
foreach(cats,function(c)add(scores,{name=c.name,frogs=c.frogs})end)
for i=1,#scores do
for j=i+1,#scores do
if(scores[i].frogs<scores[j].frogs)scores[i],scores[j]=scores[j],scores[i]
end
end
clock()
print("scores",50,16,7)
for i,c in pairs(scores) do
print(c.name,28,16+i*10,7)
print(c.frogs,96,16+i*10,7)
end
local r_o_r="respawn"
if(timer>level_time_limit)r_o_r="restart"
print("press 🅾️ to "..r_o_r,26,112,7)
end
function set_frog_msg(msg)
frog_msg=msg
frog_msg_timer=30
end
function draw_hud(player)
reset_palette()
--health
if(player.hurt_timer>0)rectfill(0,119,22,128,8)
local ps=251
if(player.quad_timer>0)ps=191
spr(ps,1,119)
print(player.health,10,121,7)
spr(248,23,120)
if player.wand>0 then
print(player.ammo,33,121,7)
else
spr(249,33,120)
end
if player.hat>0 then
spr(250,1,111)
print(player.hat,10,113)
end
clock()
if(frog_msg_timer>0)print(frog_msg,2,10,7)
print("cpu: "..stat(1),2,2,7)
end
function clock()
local countdown=level_time_limit-timer
local seconds=flr(countdown/30)%60
if(seconds<10)seconds="0"..seconds
print(flr(countdown/1800)
..":"..seconds,57,2,7)
end
-->8
-- raycasting
-- draw the 3d view
function draw_perspective(
world,
player,
dist_table)
local posx=player.x
local posy=player.y
local drx=player.drx
local dry=player.dry
local camx=player.camx
local camy=player.camy
local ang=player.a
local invdet=1/(camx*dry-camy*drx)
local floors={}
local zbuf={}
local dr_buf={}
-- sky
rectfill(0,64,128,76,0)
rectfill(0,28,128,64,1)
floor_cast(
world,
posx,posy,drx,dry,camx,camy,
dist_table)
-- first raycast pass
ray_cast(
world,
posx,posy,drx,dry,camx,camy,
diagonals,
cam_t,
0,
127,
nil,
false,
floors,
zbuf,
dr_buf)
-- pass for walls over doors
for i=1,#dr_buf,3 do
ray_cast(
world,
posx,posy,drx,dry,camx,camy,
diagonals,
cam_t,
dr_buf[i],
dr_buf[i+1],
dr_buf[i+2],
true)
end
ceiling_cast(
floors,
world.ceiling,posx,posy,dist_table)
--]]
-- draw sprites
ce_heap_sort(sprites,posx,posy)
for _,s in pairs(sprites) do
s:draw(posx,posy,drx,dry,
camx,camy,ang,invdet,zbuf)
end
reset_palette()
for _,s in pairs(particles) do
local s_x=s.x-posx
local s_y=s.y-posy
local tfx=invdet*(dry*s_x-drx*s_y)
local tfy=invdet*(-camy*s_x+camx*s_y)
local scr_x=64*(1+tfx/tfy)
local scr_y=64-(s.z/tfy)
if tfy>0 and tfy<128 then
local sz=
flr(clamp(5-sqrt(s_x*s_x+s_y*s_y),0,3))
rectfill(
scr_x,
scr_y,
scr_x+sz,
scr_y+sz,
s.c)
end
end
end
oh_tex={
[-1]=6,
[-2]=2,
[-4]=3,
[-5]=13,
[-7]=13
}
function ray_cast(
world,
posx,posy,drx,dry,camx1,camy,
diagonals,
cam_t,
s_x,e_x,
dr_tex,
bad_wall_hack,
floors,
zbuf,
dr_buf)
local rayx=posx
local rayy=posy
local perpwalldist=0
local wallx=0
local raydirx=0
local raydiry=0
local mapx=0
local mapy=0
-- dr originally meant 'door'
local dr_ptr=-2
local dr_seg=false
local old_p=0
local old_h=0
local old_side=0
local dond=0
local dend=0
local half_height=0
local side=0
local stepx=0
local stepy=0
local sidedistx=0
local sidedisty=0
local stack_tex={}
for x=s_x,e_x do
rayx=posx
rayy=posy
local camx=cam_t[x]
raydirx=drx+camx1*camx
raydiry=dry+camy*camx
mapx=flr(rayx)
mapy=flr(rayy)
local ddx=abs(1/raydirx)
local ddy=abs(1/raydiry)
if abs(raydirx)<0.01 then
if raydirx<0 then
raydirx=-0.01
else
raydirx=0.01
end
ddx=100
end
if abs(raydiry)<0.01 then
if raydiry<0 then
raydiry=-0.01
else
raydiry=0.01
end
ddy=100
end
local hit=0
local texidx=world[mapy][mapx]
local last_texidx=texidx
local d_open=nil--door
local dr_ray=false
local tele_dist=0--backwards,weird
-- no function call plz
local ry={x=raydirx,y=raydiry}
if raydirx<0 then
stepx=-1
sidedistx=(rayx-mapx)*ddx
elseif raydirx>0 then
stepx=1
sidedistx=(mapx+1-rayx)*ddx
end
-- perpendicular so 'infinite'
-- sidedistx=20000
--end
if raydiry<0 then
stepy=-1
sidedisty=(rayy-mapy)*ddy
elseif raydiry>0 then
stepy=1
sidedisty=(mapy+1-rayy)*ddy
end
-- sidedisty=20000
--end
while hit==0 do
if sidedistx<sidedisty then
sidedistx+=ddx
mapx+=stepx
side=0
else
sidedisty+=ddy
mapy+=stepy
side=1
end
last_texidx=texidx
texidx=world[mapy][mapx]
-- check moving from outside->inside overhang
-- >=-6 lo wall indoors tiles
-- <=-7 hi wall indoors+outdoors
-- <=-8 hi wall outdoors
if (texidx<=-1 and texidx>=-6) --inside
and last_texidx<=-7 --outside
and (sidedistx>2.3
or sidedisty>2.3) then
if bad_wall_hack then
hit=1
texidx=dr_tex
elseif last_texidx<=-7 --outside
and not dr_seg then
dr_ptr+=3
dr_buf[dr_ptr]=x
dr_buf[dr_ptr+2]=
oh_tex[texidx]
if not oh_tex[texidx] then
printh("need t for "..texidx)
end
dr_seg=true
end
dr_ray=true
elseif texidx==-68 then
texidx=last_wall(mapx,mapy,world)
hit=1
-- check for wall texture tiles
elseif texidx>=0 then
-- wall over door
if (texidx==0 or texidx==1)
and last_texidx<=-7
and bad_wall_hack then
hit=1
texidx=dr_tex or 14
elseif texidx==0 or texidx==1 then
-- door handling
if last_texidx<=-7
and not dr_seg then
dr_ptr+=3
dr_buf[dr_ptr]=x
dr_buf[dr_ptr+2]=last_wall(mapx,mapy,world)
dr_seg=true
end
dr_ray=true
-- do a load of extra calculations
-- for the offset door
local map_x2=mapx
local map_y2=mapy
if (rayx<map_x2) map_x2-=1
if (rayy>map_y2) map_y2+=1
if(texidx==0)d_open=door_for(mapx,mapy).open_pcnt/100
local rdy2=raydiry*raydiry
local rdx2=raydirx*raydirx
if side==0 then
local ray_mult=((map_x2-rayx)+1)/raydirx
local rye=rayy+raydiry*ray_mult
local ddx2=sqrt(1+rdy2/rdx2)
local y_step=sqrt(ddx2*ddx2-1)
local plus_half_step=rye+(stepy*y_step)/2
if flr(plus_half_step)==mapy then
if (texidx==1
and flr((plus_half_step-mapy)*16)%4<3)
or (texidx==0
and plus_half_step-mapy>d_open)
then
hit=1
mapx+=stepx/2
end
end
else
local ray_mult=(map_y2-rayy)/raydiry
local rxe=rayx+raydirx*ray_mult
local ddy2=sqrt(1+rdx2/rdy2)
local x_step=sqrt(ddy2*ddy2-1)
local plus_half_step=rxe+(stepx*x_step)/2
if flr(plus_half_step)==mapx then
if (texidx==1
and flr(((plus_half_step)-mapx)*16)%4<3)
or (texidx==0
and plus_half_step-mapx>d_open)
then
hit=1
mapy+=stepy/2
end
end
end
elseif texidx==99 then
if tele_dist==0 then
if side==0 then
tele_dist=64+64/((mapx-rayx+
(1-stepx)/2)/raydirx)
else
tele_dist=64+64/((mapy-rayy+
(1-stepy)/2)/raydiry)
end
end
local tele=tele_for(mapx,mapy,world)
mapx-=tele.x
rayx-=tele.x
mapy-=tele.y
rayy-=tele.y
elseif texidx>=72 then--diagonal
local s=diagonals[texidx]
local dx,dy=sub_v2(
posx,posy,
mapx+s[3],
mapy+s[4])
local int=
cross(
dx,dy,raydirx,raydiry)
/cross(raydirx,raydiry,s[5],s[6])
if int<1 and int>=0 then
texidx=world[mapy][mapx+s[7]]
if side==0 then
mapx+=s[1]+s[5]*int
else
mapy+=s[2]+s[6]*int
end
hit=1
end
else
if not dr_ray
and dr_seg
and dr_ptr>0 then
dr_buf[dr_ptr+1]=x
dr_seg=false
end
hit=1
end
end
end
if side==0 then
perpwalldist=(mapx-rayx+
(1-stepx)/2)/raydirx
wallx=rayy+perpwalldist*raydiry
else
perpwalldist=(mapy-rayy+
(1-stepy)/2)/raydiry
wallx=rayx+perpwalldist*raydirx
end
wallx-=flr(wallx)
local texx=flr(wallx*16)
stack_tex[0]=texidx
stack_tex[1]=min(texidx%8,texidx)
local stacks=0
-- hi-wall tiles or water
if ((last_texidx<-6 and last_texidx>=-13)
or last_texidx==-16)
and texidx>1 then
stacks=1
end
local stack_start=0
-- this is terrible, but i am trying to avoid an extra check
if bad_wall_hack then
stack_start=1
else
zbuf[x]=perpwalldist
end
if texidx==0 then
if d_open>0 then--whuuuuuut
texx+=1
end
texx-=d_open*16
end
local lheight=flr(128/perpwalldist)
if lheight~=old_h
or side~=old_side then
half_height=lheight/2
local dstart=-(half_height)+64
dend=half_height+64
local dcol=
min(15,flr((dend-dstart)/2))
if (side==1) dcol=max(dcol-3,0)
local p=clamp(15-dcol,0,6)
if p~=old_p then
palette_no_t(p)
old_p=p
end
dond=dend-dstart+1
end
-- teleport
if tele_dist~=0 then
palette_no_t(7)
line(x,tele_dist,x,dend,1)
end
-- no walls for water tile
if not(last_texidx==-16
and texidx==15) then
for i=stack_start,stacks do
local dstart2=
-half_height*(max(1,i*3))+64
sspr(
stack_tex[i]%8*16+texx,
flr(stack_tex[i]/8)*16,
1,16,
x,dstart2,
1,dond)
if last_texidx==-7
or last_texidx==-8 then
pal(1,1)
line(x,0,x,dstart2,1)
end
end
end
old_h=lheight
old_side=side
-- draw every other vertical line
if x%2==0
and not bad_wall_hack then
add(floors,
{
x,
raydirx,
raydiry,
flr(max(max(
80,
dend),tele_dist))})
end
end
reset_palette()
if dr_seg or (not bad_wall_hack
and #dr_buf%3>0) then
dr_buf[dr_ptr+1]=127
end
end
function last_wall(mapx,mapy,world)
local t=world[mapy-1][mapx]
if(t>1)return t
return world[mapy][mapx-1]
end
skx=0
function floor_cast(
world,
posx,posy,drx,dry,camx,camy,
dist_table)
local px=posx-1
local py=posy-1
-- player direction
local stx=-camx+drx
local sty=-camy+dry
-- do not loop floor textures
poke(0x5f38,0)
poke(0x5f39,0)
poke(0x5f3a,0)
poke(0x5f3b,0)
for y=77,127 do
palette(
clamp(82-y,0,15)
)
local curdist=dist_table[y]
local d16=curdist/64
local j=y%2*.025
tline(0,y,127,y,
j+px+stx*curdist,
j+py+sty*curdist,
d16*camx,d16*camy)
end
poke(0x5f38,4)
poke(0x5f39,4)
poke(0x5f3a,28)
poke(0x5f3b,28)
--
for y=0,32 do
local curdist=dist_table[y]
local d16=curdist/64
local j=y%2*.03
tline(0,y,127,y,
j-skx+28+stx*curdist*1.2,
j+28+sty*curdist*1.2,
d16*camx,d16*camy)
end
skx+=0.0075
end
function ceiling_cast(
floors,
ceiling,
px,py,
dist_table)
palette(3)
for i,f in pairs(floors) do
local x=f[1]
local x_width=x+3
local raydirx=f[2]
local raydiry=f[3]
local start_dither=f[4]
for y=128-i%2,start_dither,-2 do
local curdist=dist_table[y]
local cfloorx=curdist*raydirx+px
local cfloory=curdist*raydiry+py
local floortex=
ceiling[flr(cfloory)][flr(cfloorx)]
--.767->.775
if floortex<999 then
rectfill(x,128-y,x_width,128-y,
sget(cfloorx*8%8+floortex,
cfloory*8%8+48)
)
end
end
end
end
-->8
-- cats/sprites
function spawn_cat(cat)
local spawn_pt=pick_spawn_pt(cat)
if cat then
respawn(cat,spawn_pt,true)
else
cat=make_cat(spawn_pt)
add(sprites,cat)
add(cats,cat)
add(players,cat)
end
cat.target_p=nil
cat.think_timer=1
cat.strafe_accel=0
end
function make_cat(spawn_pt)
local c=make_sprite(
spawn_pt,
0,
spawn_pt[3],
spawn_pt[4],
24,32,
0,64,
0.75,1,
spawn_pt[5],true)
respawn(c,spawn_pt,false)
c.id=id
c.think_timer=1
c.shoot_timer=0
c.strafe_timer=0
c.target=vec(-100,-100)
c.target_timer=0
c.name=names[id]
c.frogs=0
id+=1 --each cat needs their own id
c.kill=function(self,pj)
hurt(self,pj)
--50% chance they will
--target you
if rnd(1)<0.5
and self.id~=pj.src.id then
self.target_p=pj.src
end
if self.health<=0 then
drop_wand(self)
add_frog(self)
spawn_cat(self)
return true
end
return false
end
c.do_plan=function(self,has_los)
local accelr=0.08
local rot=pick_rotation(self.a,self.target_r)
local dist=dist_sq(self,self.target_p)
if not c.search
and dist<11
and c.strafe_timer<=0 then
c.strafe_accel=(flr(rnd(2))*2-1)*0.1
c.strafe_timer=15
end
if rot>0 then
self.vr+=0.0027
else
self.vr-=0.0027
end
--end
--[[if dist_sq(self,self.target_p)
>8 then
-- far from player
-- so accel stays 0.08==]]
if has_los
and not c.search
and dist<10
then
-- close, so slow
accelr=-0.08
elseif c.search then
c.strafe_accel=0
end
if abs(rot)<0.043
and has_los then
self.shoot=true
end
move_in_current_dir(self,accelr)
strafe_in_current_dir(self,c.strafe_accel)
update_p(self)
if self.shoot_timer<=0
and self.shoot then
fire(self,projectiles)
self.shoot=false
end
end
c.update=function(c)
c.think_timer-=1
c.target_timer-=1
c.strafe_timer-=1
if not c.target_p
or c.target_timer<0 then
c.target_p=pick_target(c,cats,player)
c.target_timer=30
end
local has_los=has_los_to_target(c,world)
local near_item=pick_target(
c,w_items,c.target_p)
--printh("get that gun")
if has_los then
-- printh("can see")
-- try to track, instantly
c.target=copy(c.target_p)
c.last_seen=c.target
c.target_timer+=1
c.search=false
elseif c.last_seen
and c.think_timer>0 then
c.target=c.last_seen
c.last_seen=nil
c.think_timer=120
elseif c.wand==0 then
c.target=copy(near_item)
c.think_timer=120
elseif c.search
and c.think_timer>0
and (dist_sq(c,c.target)<3
or (c.think_timer<75
and dist_sq(c,c.last)<4)) then
search(c)
elseif c.think_timer<=0 then
search(c)
end
turn_to_target(c)
c:do_plan(has_los)
end
printh(c.name.." joined the game")
return c
end
function search(c)
c.think_timer=160
c.last=copy(c)
local try=c.last_seen
if(not try)try=c
c.target=vec(
try.x+rnd(4)-2,
try.y+rnd(4)-2
)
c.last_seen=nil
c.search=true
end
function pick_rotation(a,t_a)
local cw=
(a+(1.0-t_a))%1.0
local ccw=
((1.0-a)+t_a)%1.0
if cw>ccw then
return ccw
else
return -cw
end
end
function pick_target(
c,things,
was_closest)
local closest=was_closest
local c_dist=dist_sq(c,closest)
for a in all(things) do
if a.respawn_timer==0
or a.id~=c.id then
local d=dist_sq(c,a)
if d<c_dist
and a.health>0 then
c_dist=d
closest=a
end
end
end
return closest
end
function has_los_to_target(c,world)
local rxe,rye=single_ray_cast(
c,
normalize(sub_v(c,c.target_p)),
world
)
return is_between_v(
c.target_p,
c,
{x=rxe,y=rye})
end
function turn_to_target(c)
local t=sub_v(c,c.target)
local new_r=
loop_angle(atan2(-t.y,-t.x)-0.25)
rotate_to(c,new_r)
end
function add_frog(s)
local sp=make_sprite(
s,
50,
s.drx,
s.dry,
16,16,
48,112,
0.3,0.3,
0,false)
sp.health=20
sp.vy=-20
sp.update=function(s)
s.health-=1
s.vy+=2
s.z+=s.vy
end
add(sprites,sp)
add(projectiles,sp)
end
function make_sprite(pos,z,drx,dry,
width,height,
tex_x,tex_y,
w_scale,v_scale,
a,rotate)
local s={
a=a,
target_r=0,
drx=drx,
dry=dry,
z=z,
health=100,
rotate=rotate,
width=width,
height=height,
tex_x=tex_x,
tex_y=tex_y,
scale=v_scale,
w_scale=w_scale,
draw=draw_billboard_sprite
}
copy2(s,pos)
return s
end
function draw_billboard_sprite(
s,
posx,
posy,
drx,
dry,
camx,
camy,
ang,
invdet,
zbuf)
local tex_x=s.tex_x
local tex_y=s.tex_y
local t_w=s.width
local t_h=s.height
local s_x=s.x-posx
local s_y=s.y-posy
local shade=not s.fullbright
local rotate_s=s.rotate
local s_scale=s.scale
local s_w_scale=s.w_scale
local s_dist=
sqrt(s_x*s_x+s_y*s_y)
local t_x=invdet*(
dry*s_x-
drx*s_y
)
local t_y=invdet*(
-camy*s_x+
camx*s_y
)
-- if t_y>0 and t_y<128 then
local sscr_x=flr(64*(1+t_x/t_y))
local sc_y=flr(abs(128/t_y))
local s_height=sc_y*s_scale
local s_width=sc_y*s_w_scale
local s_width2=s_width/2
local ds_y=-s_height/2+64+(s.z/t_y)
local ds_x=-s_width2+sscr_x
if(ds_x<0) ds_x=0
local de_x=s_width2+sscr_x
if (de_x>=128) de_x=127
if t_y>0 and t_y<128 then
local a_to_spr=loop_angle(s.a-ang)
local rot_tex_idx=tex_x
if rotate_s then
local h=s.hurt_timer>0
if a_to_spr<.125
or a_to_spr>.875 then
rot_tex_idx+=t_w*2
elseif a_to_spr>=.125
and a_to_spr<.347 then
rot_tex_idx+=t_w
if(h)rot_tex_idx=t_w*3
elseif a_to_spr>.625 then
rot_tex_idx+=t_w*2
if(h)rot_tex_idx=t_w*4
t_w*=-1
elseif h then
rot_tex_idx+=t_w*4
end
end
if shade then
palette(clamp(flr(s_dist-2),0,15))
else
reset_palette()
end
for i=ds_x,de_x do
-- this is broken
if zbuf[flr(i)]>s_dist then
local texx=(
i-(-s_width2+sscr_x))*t_w/s_width
sspr(rot_tex_idx+texx,tex_y,1,t_h,i,ds_y,1,s_height)
end
end
end
end
-->8
-- utils
function is_between(e,a,b)
-- mega bad hack booooo fix fix fix
-- fix fix fix
if(a==b) return true
local tmp=a
if b<a then
a=b
b=tmp
end
if e>=a and e<=b then
return true
end
return false
end
-- if a cardinal direction
-- it will not work, because
-- the x or y value will be the same
function is_between_v(e,a,b)
if is_between(e.x,a.x,b.x)
and is_between(e.y,a.y,b.y)
then
return true
end
return false
end
function loop_angle(a)
if (a>=1) return a-1
if (a<0) return a+1
return a
end
function clamp(val,mi,ma)
return max(mi,min(ma,val))
end
function vec(x,y)
return {x=x,y=y}
end
function sub_v(a,b)
return {x=b.x-a.x,y=b.y-a.y}
end
function sub_v2(ax,ay,bx,by)
return bx-ax,by-ay
end
function dot(a,b)
return a.x*b.x+a.y*b.y
end
function cross(ax,ay,bx,by)
return ax*by-ay*bx
end
function v_len(x,y)
return sqrt(x*x+y*y)
end
function normalize(a)
local len=v_len(a.x,a.y)
return {x=a.x/len,y=a.y/len}
end
function dist_sq(a,b)
local dx=a.x-b.x
local dy=a.y-b.y
return dx*dx+dy*dy
end
function dist_sq2(a,b)
if flr(a.x)~=flr(b.x)
or flr(a.y)~=flr(b.y) then
return 100
end
return 0
end
function dist_sq3(ax,ay,bx,by)
local dx=ax-bx
local dy=ay-by
return dx*dx+dy*dy
end
function copy(a)
if(not a)return nil
return {x=a.x,y=a.y}
end
function copy2(a,b)
a.x,a.y=b.x,b.y
end
-- adapted from heap sort
-- originally by @casualeffects
function ce_heap_sort(data,x,y)
if (#data==0) return
local n = #data
for d in all(data) do
local dx=(d.x-x)/10
local dy=(d.y-y)/10
d.key=dx*dx+dy*dy
end
-- form a max heap
for i = flr(n / 2) + 1, 1, -1 do
-- m is the index of the max child
local parent, value, m = i, data[i], i + i
local key = value.key
while m <= n do
-- find the max child
if ((m < n) and (data[m + 1].key < data[m].key)) m += 1
local mval = data[m]
if (key < mval.key) break
data[parent] = mval
parent = m
m += m
end
data[parent] = value
end
-- read out the values,
-- restoring the heap property
-- after each step
for i = n, 2, -1 do
-- swap root with last
local value = data[i]
data[i], data[1] = data[1], value
-- restore the heap
local parent, terminate, m = 1, i - 1, 2
local key = value.key
while m <= terminate do
local mval = data[m]
local mkey = mval.key
if (m < terminate) and (data[m + 1].key < mkey) then
m += 1
mval = data[m]
mkey = mval.key
end
if (key < mkey) break
data[parent] = mval
parent = m
m += m
end
data[parent] = value
end
end
-->8
-- player
function make_player(x,y)
local p={
id=0,
vr=0,
name="playero",
frogs=0,
update=update_p,
kill=function(s,pj)
if s.health>0 then
hurt(s,pj)
if s.health<1 then
drop_wand(s)
respawn_timer=90
return true
end
end
return false
end
}
respawn(p,
{x,y,1,0,0},
false)
return p
end
--929
function drop_wand(s)
if s.wand>0 then
local i=items[s.wand]
local w=add_item(
s.x,s.y,
i[1],i[2],
get_wand,
i[5])
w.typ=i[3]
w.ammo=s.ammo
w.no_respawn=true
end
if s.quad_timer>0 then
local q=add_item(
s.x,s.y,
56,96,
get_quad,
"got quad")
q.time=s.quad_timer
q.no_respawn=true
end
end
function respawn(self,spawn_pt,announce)
self.x=spawn_pt[1]
self.y=spawn_pt[2]
self.a=spawn_pt[5]
self.v=0
self.vr=0
self.sv=0
self.drx=spawn_pt[3]
self.dry=spawn_pt[4]
self.camx=(self.dry)/3*2
self.camy=(self.drx)/3*2
self.health=100
self.hat=0
self.wand=0
self.ammo=0
self.hurt_timer=0
self.shoot_timer=0
self.quad_timer=0
if announce then
f_smoke(self,12)
near_sfx(0,1,self,player)
end
end
function hurt(s,pj)
local dmg=pj.dmg
local less=
min(s.hat,flr(dmg*0.5))
s.hat=max(s.hat-less,0)
dmg-=less
s.health-=dmg
s.hurt_timer=4
if(s.health<1)set_frog_msg(pj.src.name.." frogged "..s.name)
end
function move_in_current_dir(s,amount)
s.v=clamp(s.v+amount,-0.3,0.3)
end
function strafe_in_current_dir(s,amount)
s.sv=clamp(s.sv+amount,-0.2,0.2)
end
function calc_rot(player,ar)
local r=player.a
player.drx=cos(r)
player.dry=-sin(r)
local oldplanex=player.camx
player.camx=oldplanex*cos(ar)+
player.camy*sin(ar)
player.camy=-oldplanex*sin(ar)+
player.camy*cos(ar)
end
function turn_player(player,ar)
player.a=loop_angle(player.a+ar)
calc_rot(player,ar)
end
function turn_player2(player,ar)
player.vr=clamp(player.vr+ar,-6,6)
end
function update_p(s)
s.shoot_timer-=1
if(s.hurt_timer>0)s.hurt_timer-=1
if(s.quad_timer>0)s.quad_timer-=1
s.vr*=0.9
s.a=loop_angle(s.a+s.vr)
calc_rot(s,s.vr)
s.v*=0.6
s.sv*=0.95
local mvx=player.camx*s.sv
+s.drx*s.v
local mvy=player.camy*s.sv
+s.dry*s.v
local px=s.x
local py=s.y
local movex=px+mvx
local movey=py+mvy
local mvx_a=(mvx/abs(mvx))*0.3
local mvy_a=(mvy/abs(mvy))*0.3
if(mvx==0)mvx_a=0
if(mvy==0)mvy_a=0
local mmx=flr(movex+mvx_a)
local mmy=flr(py)
local move_sq=world
[mmy][mmx]
if move_sq<0
and move_sq~=-16
or open_door_for(
mmx,mmy,move_sq)
or check_diag(
px,py,
mvx,0,
mmx,mmy,
move_sq,0.55)
then
s.x=movex
px=movex
elseif move_sq==99 then
teleport(s,mmx,mmy,world)
return
end
mmx=flr(px)
mmy=flr(movey+mvy_a)
move_sq=world
[mmy][mmx]
if move_sq<0
and move_sq~=-16
or open_door_for(
mmx,mmy,move_sq)
or check_diag(
px,py,
0,mvy,
mmx,mmy,
move_sq,0.55)
then
s.y=movey
elseif move_sq==99 then
teleport(s,mmx,mmy,world)
end
if(move_sq==-68)set_frog_msg("you found a secret!")
end
function check_diag(
px,py,
raydirx,raydiry,
mapx,mapy,
move_sq,di)
if move_sq>=72 and move_sq<=75 then
local s=diagonals[move_sq]
local dx,dy=sub_v2(
px,py,
mapx+s[3],
mapy+s[4])
local int=
cross(
dx,dy,raydirx,raydiry)
/cross(raydirx,raydiry,s[5],s[6])
if int<1 then
--[[ if raydirx==0 then
-- correct intersection for y in both dirs
local ti=mapy+abs(s.sty-int)
--py<ti and raydiry+y>ti
local i=int+mapy
local m=raydiry+py
printh(move_sq.." int="..
ti.." newpos="..m.." "..
abs(ti-m))]]
--end--]]
if raydiry==0 then
local ti=mapx+abs(s[3]-int)
if abs(ti-(raydirx+px))>di then
return true
end
end
if raydirx==0 then
local ti=mapy+abs(s[4]-int)
if abs(ti-(raydiry+py))>di then
return true
end
end
end
end
return false
end
function rotate_to(s,targetrotation)
s.target_r = targetrotation
end
function teleport(s,mmx,mmy,world)
copy2(s,sub_v(
tele_for(
mmx,
mmy,
world),
s))
near_sfx(0,1,s,player)
f_smoke(s,12)
end
function respawn_pl(s)
respawn(s,pick_spawn_pt(s),true)
end
function near_sfx(s,ch,spos,ppos)
if dist_sq(spos,ppos)<25 then
-- and stat(16+ch)==-1 then
sfx(s,ch)
end
end
-->8
-- map utils/doors
map_dr={
{0,1,0.75},
{0,-1,0.25},
{-1,0,0.5},
{1,0,0}
}
saved_ents={}
tele_entries={92,93,94,95}
tele_exits={76,77,78,79}
function save_ent(x,y,map_tile,last_floor_tile)
add(saved_ents,{x,y,map_tile})
mset(x,y,last_floor_tile)
end
function make_world(mp)
set_frog_msg("you enter "..mp[1])
map_to_tex={}
for i=1,16 do
map_to_tex[95+i]=-i --floor
map_to_tex[112+i-1]=i-1 --wall
local i4=i%4
map_to_tex[72+i4]=72+i4 --diagonal
map_to_tex[92+i4]=99 --tele
end
map_to_tex[68]=-68
local last_floor_tile=96
-- restore map
for e in all(saved_ents) do
mset(e[1],e[2],e[3])
end
saved_ents={}
local new_world={
starts={},ceiling={}
}
doors={}
local tele={{},{},{},{}}
for y=mp[3],mp[5] do
local ry=y+1
new_world[ry]={}
new_world.ceiling[ry]={}
for x=mp[2],mp[4] do
local rx=x+1
local cx=rx+.5
local cy=ry+.5
local map_tile=mget(x,y)
-- is it a floor tile
if map_tile>=96 and map_tile<=109 then
last_floor_tile=map_tile
end
-- is it a player start
if map_tile>=80 and map_tile<=83 then
local dr=map_dr[map_tile-79] -- set floor tex
-- add p start
--x,y,drx,dry,ang
add(new_world.starts,
{
cx,cy,
dr[1],dr[2],
dr[3]
})
elseif map_tile==91 then
add_item(
cx,cy,
48,96,
get_health,
"got health")
elseif map_tile==85 then
local q=add_item(
cx,cy,
56,96,
get_quad,
"got medal of quard d' mage")
q.time=300
--7993->8003 :(
elseif map_tile>=87
and map_tile<=89 then
items={
{96,96,1,5,"got the double barreled wand"},
{104,96,2,5,"got the bombnd"},
{112,96,3,100,"got the chainwand"}
}
local i=items[map_tile-86]
local w=add_item(
cx,cy,
i[1],i[2],
get_wand,
i[5])
w.typ=i[3]
w.ammo=i[4]
elseif map_tile==90 then
add_item(
cx,cy,
120,96,
get_hat,
"got the hat of hardiness")
elseif map_tile==68 then
save_ent(x,y,map_tile,last_floor_tile)
map_tile=68
end
for p=1,4 do
if tele_entries[p]==map_tile then
tele[p].entry=vec(rx,ry)
save_ent(x,y,map_tile,last_floor_tile)
elseif tele_exits[p]==map_tile then
tele[p].exit=vec(rx,ry)
end
end
if map_tile>=76
and map_tile<=91 then
save_ent(x,y,map_tile,last_floor_tile)
map_tile=last_floor_tile
end
local t=map_to_tex[map_tile]
new_world[ry][rx]=t
new_world.ceiling[ry][rx]=
to_ceiling(t)
if map_tile==112 then--door
add(doors,{x=rx,y=ry,open_pcnt=0,open_vel=0})
save_ent(x,y,map_tile,last_floor_tile)
elseif map_tile==113 then--bars
save_ent(x,y,map_tile,last_floor_tile)
elseif (map_tile>=72 and map_tile<=75)--diag
then
local ft=mget(
x-diagonals[map_tile][7],y
)
save_ent(x,y,map_tile,ft)
new_world.ceiling[ry][rx]=
to_ceiling(map_to_tex[ft])
end
end
end
for p=1,4 do
local t=tele[p]
if t.entry then
t.d=
sub_v(
t.exit,
t.entry)
end
end
new_world.tele=tele
return new_world
end
function to_ceiling(t)
if t and t<=1 and t>=-6 then
return max(abs(t*8)-8,0)
end
return 9999
end
function door_for(x,y)
for _,d in pairs(doors) do
if d.x==x and d.y==y then
return d
end
end
return nil
end
function open_door_for(x,y,s)
return s==0 and door_for(
x,y
).open_pcnt>70
end
function tele_for(x,y,world)
for _,d in pairs(world.tele) do
if d.entry and d.entry.x==x and d.entry.y==y then
return d.d
end
end
return nil
end
function update_doors(doors)
for _,d in pairs(doors) do
local near_door=false
for _,p in pairs(players) do
near_door=near_door or
dist_sq3(
p.x,p.y,
d.x+0.5,d.y+0.5)<2
end
if near_door then
if d.open_pcnt==100 then
near_sfx(6,1,{x=d.x,y=d.y},player)
end
if d.open_pcnt<100 then
d.open_vel=5
if d.open_pcnt==0 then
sfx(-1,1)
end
end
else
if d.open_pcnt>0 then
d.open_vel=-5
if(stat(17)~=7) then
near_sfx(7,1,{x=d.x,y=d.y},player)
end
elseif d.open_pcnt==100 then
sfx(-1,1)
end
end
d.open_pcnt=clamp(d.open_pcnt+d.open_vel,0,100)
end
end
--247 tokens
function draw_map_view(world,player)
cls(5)
pal(7,7)
local px=8*(player.x-1)
local py=8*(player.y-1)
camera(px-64,py-64)
reset_palette()
map(
0,0,
0,0,
128,32)
local pxe=px+player.drx*5
local pye=py+player.dry*5
local cpxe=px+player.camx*5
local cpxe2=px-player.camx*5
local cpye=py+player.camy*5
local cpye2=py-player.camy*5
line(
px,py,
pxe,pye,
10)
line(
cpxe2,cpye2,
cpxe,cpye,
8)
pset(px,py,9)
for _,s in pairs(sprites) do
local px=8*(s.x-1)
local py=8*(s.y-1)
if s.drx then
local pxe=px+s.drx*5
local pye=py+s.dry*5
line(
px,py,
pxe,pye,
10)
end
if s.src then
line(
px,py,
8*(s.src.x-1),8*(s.src.y-1),
8)
end
circfill(px,py,1,8)
if s.target then
circfill(8*(s.target.x-1),8*(s.target.y-1),3,14)
end
if s.target_p then
circfill(8*(s.target_p.x-1),8*(s.target_p.y-1),2,11)
end
--]]
end
--[[for _,p in pairs(particles) do
pset(8*(p.x-1),8*(p.y-1),11)
end]]
camera()
print(player.x..","..player.y,2,120,7)
end
--]]
--[[
function pad(x)
if(x<10)return "0"..x
return x
end
function write_map(mx,my,mw,mh,num_p)
for e in all(saved_ents) do
mset(e[1],e[2],e[3])
end
local map_str=pad(mx)..pad(my)..mw..mh..pad(num_p)
for y=my,mh do
for x=mx,mw do
map_str=map_str..chr(mget(x,y))
end
end
printh(#map_str)
printh(map_str)
return map_str
end
function read_map(m,maps)
local mx=tonum(sub(m,1,2))
local my=tonum(sub(m,3,4))
local mw=tonum(sub(m,5,6))
local mh=tonum(sub(m,7,8))
local num_p=tonum(sub(m,9,10))
printh(mx)
printh(my)
printh(mw)
printh(mh)
printh(num_p)
local i=11
for y=my,mh do
for x=mx,mw do
mset(x,y,ord(sub(m,i,i)))
i+=1
end
end
printh("wrote "..(i-9).." tiles")
maps[99]={"user map",mx,my,mw,mh,num_p}
map_pick=98
end
--]]
-->8
--projectiles
function check_hit_fireball(self,e)
if dist_sq(self,e)<self.scale then
self.hit=true
smoke(e.x,e.y,0.5,10,10,self.id)
if e:kill(self) then
self.src.frogs+=1
self.src.target_p=nil
near_sfx(5,3,self,player)
else
near_sfx(2,2,self,player)
end
end
end
function fire(s,projectiles)
s.shoot_timer=8
if s.wand==1 then
local l=add_fireball(
s,projectiles,
28,0.25,0.5)
local r=add_fireball(
s,projectiles,
28,0.25,0.5)
local spx=s.camx*.3
local spy=s.camy*.3
l.x+=spx
l.y+=spy
r.x-=spx
r.y-=spy
elseif s.wand==2 then
local p=add_fireball(
s,projectiles,
80,0.5,0.3)
p.typ=2
p.tex_x=32
p.tex_y=112
elseif s.wand==3 then
local f=add_fireball(
s,projectiles,
6,0.125,0.6)
local z=sin((timer*20)/360)*0.3+0.2
f.x+=s.camx*z
f.y+=s.camy*z
f.z+=rnd(30)-15
s.shoot_timer=3
else
add_fireball(
s,projectiles,
12,0.3,0.5)
end
if s.wand>0 then
s.ammo-=1
if s.ammo==0 then
s.wand=0
f_smoke(s,12)
end
end
if s.quad_timer>0 then
f_smoke(s,11)
near_sfx(13,1,s,player)
end
end
function add_fireball(
s,
projectiles,
dmg,
sc,v)
local pj=make_sprite(
s,
30,
s.drx,
s.dry,
16,16,
32,96,
sc,sc,
0,false)
pj.id=s.id
pj.src=s
pj.health=4
pj.dmg=dmg
if(s.quad_timer>0)pj.dmg*=4
pj.update=update_projectile
pj.v=v
pj.fullbright=true
add(projectiles,pj)
add(sprites,pj)
near_sfx(1,0,s,player)
return pj
end
function get_health(i,c)
c.health=min(c.health+25,125)
end
function get_quad(i,c)
c.quad_timer=i.time
sfx(14,1)
end
function get_hat(i,c)
c.hat=min(c.hat+50,100)
end
function get_wand(i,c)
if i.typ==c.wand then
c.ammo+=i.ammo
else
c.wand=i.typ
c.ammo=i.ammo
end
if(c.id==0)hvy=30
end
-- tables is not fewer tokens atm
function add_item(
x,y,
tex_x,tex_y,
get_item,
get_msg)
local h=make_sprite(
vec(x,y),
30+rnd(20),
0,0,
8,8,
tex_x,tex_y,
0.33,0.33,
0,false)
h.vz=0
h.fullbright=true
h.respawn_timer=0
h.get_item=get_item
h.get_msg=get_msg
h.ammo=5
h.update=function(s,players)
s.z+=s.vz
s.vz+=0.4
if(s.z>50)s.vz=-3
if s.respawn_timer>0 then
s.respawn_timer-=1
else
for _,c in pairs(players)do
if dist_sq2(s,c)<2
and s.respawn_timer==0
and c.health>0 then
s.respawn_timer=300
s:get_item(c)
f_smoke(c,10)
if c.id==0 then
set_frog_msg(s.get_msg)
sfx(10,0)
end
if s.no_respawn then
s.health=0
del(items,s)
end
end
end
end
end
h.draw=function(
s,px,py,dx,dy,cx,cy,a,i,z)
if s.respawn_timer==0 then
draw_billboard_sprite(
s,
px,
py,
dx,
dy,
cx,
cy,
a,
i,
z)
end
end
add(projectiles,h)
add(w_items,h)
add(sprites,h)
return h
end
function update_exp(s)
check_hits(s)
s.health-=1
s.z=-30
s.scale+=0.5
s.w_scale+=0.5
end
function update_projectile(s)
local px=s.x
local py=s.y
local mvx=s.drx*s.v
local mvy=s.dry*s.v
local movex=px+mvx
local movey=py+mvy
local mmx=flr(movex)
local mmy=flr(py)
local move_sq=world
[mmy][mmx]
if move_sq<0
or open_door_for(
mmx,mmy,move_sq)
or (check_diag(
px,py,
mvx,0,
mmx,mmy,
move_sq,0.1))
then
s.x=movex
px=movex
else
s.hit=true
end
if not s.hit then
mmx=flr(px)
mmy=flr(movey)
move_sq=world
[mmy]
[mmx]
if move_sq<0
or open_door_for(
mmx,mmy,move_sq)
or (check_diag(
px,py,
0,mvy,
mmx,mmy,
move_sq,0.1))
then
s.y=movey
py=movey
else
s.hit=true
end
end
if s.hit then
s.health=0
smoke(px,py+0.25,0.1,10,10,s.id)
near_sfx(4,2,s,player)
end
if not s.hit then
check_hits(s)
end
if s.hit and s.typ==2 then
smoke(px,py+0.25,
0.4,10,10,s.id)
near_sfx(15,4,s,player)
s.health=0
local pj=add_fireball(s.src,projectiles,6,0.2,0.2)
pj.update=update_exp
copy2(pj,s)
pj.height=10
-- pj.z=-50
pj.health=6
pj.id=-99
end
end
function check_hits(s)
for _,e in pairs(players) do
if e.id~=s.id then
check_hit_fireball(s,e)
end
end
end
function f_smoke(s,c)
smoke(s.x+s.drx,s.y+s.dry,0.5,1,c,0,0,0)
end
function smoke(
x,y,d,s,c,id,vx,vy)
-- dont make far away particles
if(id~=0 and dist_sq3(x,y,player.x,player.y)>25)return
for i=0,1,0.1 do
local dx=-d*sin(i)-rnd(0.2)
local dy=d*cos(i)-rnd(0.2)
local nvx=vx or dx
local nvy=vy or dy
add(particles,{
x=x+dx,
y=y+dy,
z=rnd(100)-70,
vx=nvx/3,
vy=nvy/3,
vz=rnd(1.0)+s,
health=10+rnd(5),
c=c })
end
end
function single_ray_cast(p,ray,world)
local px=p.x
local py=p.y
local rayx=ray.x
local rayy=ray.y
local map_x=flr(px)
local map_y=flr(py)
local side=0
local step_x=0
local step_y=0
local dx=abs(1/rayx)
local dy=abs(1/rayy)
local hit=0
local rxe=0
local rye=0
if rayx<0 then
step_x=-1
side_x=(px-map_x)*dx
else
step_x=1
side_x=(map_x+1-px)*dx
end
if rayy<0 then
step_y=-1
side_y=(py-map_y)*dy
else
step_y=1
side_y=(map_y+1-py)*dy
end
while hit==0 do
if side_x<side_y then
side_x+=dx
map_x+=step_x
side=0
else
side_y+=dy
map_y+=step_y
side=1
end
local t=world[map_y][map_x]
if t>1 then
hit=1
if (px<map_x) map_x-=1
if (py>map_y) map_y+=1
local adj=1
local ray_mult=1
if side==1 then
adj=map_y-py
ray_mult=adj/rayy
else
adj=(map_x-px)+1
ray_mult=adj/rayx
end
rxe=px+rayx*ray_mult
rye=py+rayy*ray_mult
end
end
return rxe,rye
end
-->8
--palette stuff
function reset_palette()
palette(0)
end
function palette(z)
memcpy(0x5f00,0x5000+16*z,16)
palt(12,true)
end
function palette_no_t(z)
memcpy(0x5f00,0x5000+16*z,16)
palt(12,false)
end
function create_palettes()
for z=0,7 do
for i=0,15 do
poke(0x5000+16*z+i,
sget(i,z+32))
end
end
end
--[[
-- for extended pico palette
function new_palette()
--[[ for i=0,15 do
pal(i,i+128,1)
end]]
--[[ext_pal(1)
ext_pal(2)
ext_pal(4)
ext_pal(5)
ext_pal(6)
ext_pal(8)
ext_pal(13)
ext_pal(14)]]
poke(0x5f2e,1)
end
function ext_pal(c)
pal(c,c+128,1)
end
function original_palette()
--[[ for i=0,15 do
pal(i,i,0)
end]]
end]]
__gfx__
11111111111111111510151015101510112221111112221111111111515113331224212224912449999144949991449911111111111111111155511111115551
19f29f59f29f29f115101510151015104111114422115114155111b3bb65111112449124249124494491122444411124d66d61d6661d6661155d511155155dd1
14954944954954f11d101d101d101d102211142222211142bb15133b3bbb5111124491244291244422211112224111125555d1555d1555d1156d5115d5156dd5
14424424454424911d101d101d101d10222112222222112255113335bb6b353312449124429124241111111211111111111111111111111111565115651156d5
14944944944944411d101d101d101d1025211222555211223300133355533513124491244291242400000010000000100000000000000000111d5111d5111dd5
14424424425424411d101d101d101d105511155551111112115111313333151112449124429144441111111011111110001001001001001015dd515dd515ddd5
12222222222222211d101d101d101d101111111111442111111551101111111112249124429144492224499144429991111111111111111115555155551555d5
14245242542442411d101d101d101d101144221114422111b5b3331510151533122421244291444215222221242245411565155115667771156d5156d5156dd5
14444444444dd1411d101d101d101d1014222214422221113333115155566b1312249124429144421552222155524551155551100555556111565115651156d5
12222222222211211d101d101d101d101222251222222144110115333535b651124491244291444911111221111222515d5d511005ddd551111d5111d5111dd5
11111111111111111d101d101d101d10112551122222114210001133335533151244912442912449111111111111111115d5d11005dddd5115dd515dd515ddd5
12212212212212211d101d101d101d1021111122525114225111511333333111124491244291244922212222222122221d5d51100511d55115555155551555d5
1242452552441441151015101510151051111125551112221566510113311101124491244291244222411442442111241111115001111111156d5156d5156dd5
121144144145114115101510151015101144211251141152b635b6100111016b12449124429124422241141124211114d55155100165155511565115651156d5
11112111211211111110111011101110142222111142211153335b6510005b35124491224291242912211111112111116d51151111dd155d111551115511155d
111111111111111111101110111011101222221111222211333333351155333312249124429124291111111111111111d6d11111111111110111111111111111
12421111112444211524444515124451112221111112221153333b3505333333222222224524422214444444144444441111111111111111666d6ddd666d66d6
241111111111114211122222115112214111114422115114b553b355153333bb222245224422425219999944124449925d6771111d677715dddddddddddddddd
4111159422221114151151111111111122221122222111423b33351111533b35245244222422224214444222112454425dddd155ddddd6151111111111111111
2111942211112114111114420942111122222122222211221133511531113511545242222222522211522222112224425d5d51555d5d55150000000000000000
11194251115152124591199409941122222521155222112255111105351111154442424452255225111115221111111211155111111511510101010010001010
115421511151121144411aa90aa911225555111155521112dd511100051111554452222444244424111111111111111111511111111111111111111111111111
119421511151152111211000000011121111111111111111ddd511010011155d44222222242444222999122244991444551155d6677715562122121221212221
11921111111111215111199409941111114421111442211166d521010011255d24255242242242222454115222221242551155555556155552252155d212d2d2
119211211121112111211aaa0aaa1221142122144222211166d521011011255d22245244241222212455115522221555d51ddddddd5515d555d5d51551215555
114211211121114111110aaa0aaa1221121215121212214466d521011012235d222442442222441222251111112211115d11ddddddd5115d5555155d55155555
11421121112111411111094409441111112111112111114266b5210113b235b412144222212144221111111111111111d51111111d5511d55d555d555dddd5d5
1142112111211121551100001111122521111112125114226335130110312235222442144112422412222222122222221111111151111111555dd55ddddd5ddd
1152115111511151445111111111122451111121111112123343b1001013153542122112441221441112422411442442555d666711555d555d5ddddddddddddd
1155115111511151222111122551111111d51111111111513633113b0013b545422442214422424411114224114112425555d5d61155d6d5555dddd5555dd555
115511511151115111111111211111111d511d51115111114555255033123525121441122224412411111122111111121111111511111d6d5155d555d55551d5
11111111111111112255555511225551155155111d5511d55155151000115151211121111414111211111111111111115d5d515d5d5d5d5d1111151511151111
0123456789abcdef222222282222222822222228012345670000000000000001d66666d11d66666d125555555555552122222224111111131111111e1111111d
0123456789abcdef2888888e28eeee8e288eee8e012321d6010111000010001066666d1221d66666d125ddd55ddd521d299999971bbbbbb71222222f1dddddd7
0123556624abdd89288e888e28e8888e28e888e90123215d01111110000000006666d125521d66666d125dd55dd521d6222221241333313b1111e11e1111111d
012311dd12a35524288ee88e28eee88e2e8888e90111215d0155551000111100666d12555521d66666d125d55d521d66222221241333313b1111e11e1111111d
0015105d11a51112288eee8e28e8888e2888ee8e01111155005550100111110066d125d55d521d66666d12555521d666292292271b33b3371211211f1d11d117
1101001511a11011288ee88e28eeee8e2889888e0001111501155110000110006d125dd55dd521d66666d125521d6666292292271b33b337121121171d11d117
1000111111a11011288e888e2888888e288ee88e000011110111111000000000d125ddd55ddd521d66666d1221d66666299999971bbbbbb7122222271dddddd7
01ddcdccdccccccc8eeeeeee8eeeeeee8ee99eee0000101100000000000000001255555555555521d66666d11d66666d4777777737777777ef777777d7777777
1111111511111115111111151111111504400000550000251111111100000000d510000000000d50000110000000000022222224111111131111111e1111111d
1dddddd61dddddd61dddddd61dddddd60332533025225555151555110a944420dd511110011155150101501005555550299999971bbbbbb71222222f1dddddd7
1ddd2dd61d2222261ddd2dd61dd2ddd633bb2b332555d5dd155555510a9442216d5518111111d15d1015d50155666675292222971b3333b7121111271d1111d7
1dd222d61dd222d61dd22dd61dd22dd63a7abbb35885588d15dddd510011111116d552211d5d65d11015d501b5555551292222971b3333b7121111271d1111d7
1d2222261ddd2dd61d222dd61dd222d63a7abb315985598511ddd1510a944420116d5191551511110115dd50b3666631299229971bb33bb7122112271dd11dd7
1dddddd61dddddd61dd22dd61dd22dd653bbb35125522555155dd5510a944221118217a1515d11110115dd50bb536631299229971bb33bb7122112271dd11dd7
1dddddd61dddddd61ddd2dd61dd2ddd60533551012525d51155555510011111101129a7a55d111101111511d0b333330299999971bbbbbb7122222271dddddd7
56666666566666665666666656666666005111000225ddd01111111100000000000000aa0000000000111150000000004777777737777777ef777777d7777777
5555555d44244494111111115351113111111224cccccccc222222294424449411b1151514414414ddddddd6994999f913b3b51144244494499004491dd11dd1
5d5ddd5554452444151555111113511112222222cccccccc2424442254452444b135315114914424d6d666dd59954999d53533515445244442924a92115dd511
5dddddd544522442155555511115311112244442cccccccc24499442444244421153113514914924d666666d9954499433531133445224420449999011d11d11
5d6666d52422194415dddd513113111512444942cccccccc249f9942242414441531b11324914924d677776d49442f995335135324221944049a49a911d1dd11
556665d54444444211ddd5511111515512449942cccccccc249f9242444444443135135124924929dd777d6d9999999435135b354444444299940494d5dd115d
5dd66dd542245442155dd5511131113122499942cccccccc24999442442454421511151314914924d667766d944959943111111342245442044909921d1111d1
5dddddd521424444155555511135111124444442cccccccc24494442244244445111513524414914d666666d42949999535351352142444420299a991d1111d1
5555555d42144124111111111351135112222224cccccccc22222229421441241111153124424914ddddddd694299249113135314214412492424904d5d1115d
11111111111111110011110051115113144144142222222211111111111111111111111111000011cccccccc511151131111111111111111111111110ccccccc
19a29a5110011001115254911311131b14914424222245221dddddd515d115d112211412122a4a12cccccccc1311131b12211412122494121d1d1dd1000c000c
1495494150055005129554211331111b1491492424524422111111111565156111111111114a2411cccccccc1131111b11111111111111111d6761d1c00000cc
1442442160066006124152211b31511b24914924545242221dd005511565156121442214244a4a14cccccccc51155115215dd514244412441dddd151cc000ccc
14944941d00dd00d1521122113b3111b24924929444242441d50055115d5156111444211104a4a11cccccccc51155115111dd111111111111d5d5151cc0000cc
1442442150055005152154511b33131314914924445222241115511115d515d11144421210000025cccccccc51155115115115121111112211155111c00cc00c
1222222110011001151155111b3b1113244149144422222211511d6115d115d11194421111111111cccccccc5115511511d11d111111111111511d61c0cccc00
1111111111111111011011101b331511244249142425524211111111111211124194421444512451cccccccc1111111141d11d144441244411111111ccccccc0
c1111ccccccccccccc11111ccccc111ccccc155cccccccccccc11111cccccccccc11111ccccc111ccccc155cccccccccc1111ccccccccccccc11111ccccccccc
c155511cc111111c115f551ccccc15f55cc155fcccccccccccc1555511c1111c1155551ccccc15f55cc155fcccccccccc155511cc111111c115f551ccccccccc
c155ff9115555551555f51cccccc15ff5551559ccccccccccccc155555155551555551cccccc15ff555151111cccccccc155ff9115555551555f51cccccccccc
cc15ff9155555555519f51cccccc159ff5555555cccccccccccc151155555555551151cccccc159ff5551aaaa1cccccccc15ff9155555555519f51cccccccccc
cc15f99155555555551951cccccc1599555551155ccccccccccc151155555555551151cccccc159955551aa0a1cccccccc15f99111111555551951cccccccccc
cc15011511115555511151cccccc155555551aa155cccccccccc111555555555555111cccccc155555551aa0a1cccccccc15011aaaaaa155111111cccccccccc
ccc11151aaaa15551aaa1ccccccc115555551a0155ccccccccccc5555555555555555ccccccc115555551aaaa15cccccccc1111a00aaa151aaaaa1cccccccccc
ccc11151aa0a15551a0a1ccccccc115555551a015555ccccccccc5555555555555555ccccccc1155555551aaa155ccccccc1111a00aaa151aa00a1cccccccccc
cccc1151aa0a15551a0a1ccccccc115555551aa155500cccccccc5555555555555555ccccccc11555555551115500ccccccc1151aaaaa151aa00a1cc55cccc25
cccc1151aaaa15551aaa15cccccc115555551aa155000ccccccc555555555555555555cccccc11555555555555000ccccccc1151aaaaa151aaaaa1cc25225555
cccc115511115115511155cccccc11555555511555050ccccccc155555555555555551cccccc11555555555555050ccccccc11551aaa11151aaa15cc2555d5dd
cccc111555555005555555cccccc11155555555555055cccccc11155555555555555111ccccc11155555500000055ccc4ccc111551115005511155cc5335533d
cccc91100555000055505ccccccc11155555555550555cccccccc1155551111555511ccccccc11155555507770555cccc4cc11100000000055505ccc5b355b35
cccc41110000055000015ccccccc11115555555005515ccccccc111111111111111111cccccc11115555500005515cccc29c11107777770000015ccc25522555
cccc2911111555555115ccccccccc1111155555555119ccccccccc11111111111111ccccccccc111115555555511cccccc4cc110777700555115cccc22525d5d
cccc241111111155555ccccccccc1111111111115ccc4cccccccccc111111111111cc4cccccc1111111111115ccccccccc24111111111155555cccccc225dddc
cccc121111115555551ccccccccc1111111111155cc24ccccccccc1111111555551c44cccccc111111111115ccccccccccc2411111115551111ccccccccccccc
ccc11291551111111111ccccccc115511111115555c4cccccccc111155555d5ddd664cccccc1155111111155ccccccc4ccc22111555551111dd6cccccccccccc
cc1d12455555511155516ccccc111ddddd5551155554ccccccc1111d55dddd5ddddd6ccccc111ddddd5551155cccc24ccc11555111111111dd6d6ccccccccccc
cc1d1245555515151551d6cccc111dddd5d6d1111522ccccccc1111d5ddddd55d1dd6ccccc111dddd5ddd11555cc24cccc1155515511551dd66d6ccccccccccc
cc1d1111555511515511dd6ccc111dddd5d6d15551111cccccc1111ddd5dddd5d11d6ccccc111dddd5ddd11115c24ccccc11155151111515d6dd34cccccccccc
c11d1551155555555111dd6cc1111dd1d5d6d15555551ccccc11111dd51dddddd51dd6ccc1111dd1d5ddd15511111cccc11d11111155111ddddd6ccccccccccc
c1dd15551555555551515d6cc1111d51dd55615555551cccc111111d551dddddd51dd6ccc1111d51dd55d15555551cccc11ddd111555515dddd666cccccccccc
c1d515551555555551515d6cc1111d51dddd511111551cccc111111551ddddddd551d6ccc1111d51dddd515555551cccc1dddd15555551ddddd6d6cccccccccc
c1d511111555555551115dd6c1111151dd1d51555111ccccc111111551dddd1ddd51d6c1c1111151dd1d511115551cccc1dddd15555115ddddd6d6cc55cccc25
1dd511115555555555515dd611111151d51d5155555ccccc1111111111ddd51ddd551dd111111151d51d51555111cccc1ddddd1155115ddd556dd6cc25225555
1dddd1115555555555511ddd11111111d5115155555ccccc1111111115ddd51dddd51dd111111111d5155155555ccccc1ddddd11551155d55dddd6cc2555d5dd
1dddd1115555555555551ddd1111111115115115555ccccc1111111115555551ddd551d11111111111155155555ccccc155dddd155551155ddddd6cc5885588d
155dd11155555555555515ddc111111115115511555ccccc11555111111111111dd55111c111111111151151555cccccc1155dd155555115ddddd6cc59855985
111551111111115555551555c111111111111111115ccccc115555555511111111111cccc111111111111551115ccccccc11155511111111555dd6cc25522555
cc11111111111111111115ccccc11111111111111111cccccc11155555511111111cccccccc11111111115111111cccccc11111111111111111111cc22525d5d
cccc1111111111111111cccccccccc11111111111111cccccccc111111111111111ccccccccccc11111111111111cccccccc11111111111111111cccc225dddc
d555511115555555111155ddddd5555dcccccccccccccccccccccccc55cccc25cc4ccccc4cc4ccccc51cccccc111cccccccccccccccccccccccccd5cccc11ccc
d55511111555555511115555555555ddccccc111111cccccc6dddddc25225555cc9ccccc9cc9ccccc51ccccc12421cccc9cc9ccccc1221cccccc5515ccc15ccc
d55511115555555111115555555555ddccc1112222221ccc55dd55152555d5ddcc42cccc42c4ccccc35ccccc24141cccc94c94ccc128821cc111d15dcc15d5cc
55551111515555551111555555555dd5cc11999aa99921cc3dbddd355885588dcc42cccc42c42ccccd5ccccc24c91ccccc4cc4ccc289982c15d675d1cc15d5cc
55551111111155555d1155555555ddddc1129a777aa921cc36dd66d359855985cc42cccc42c42cccc155cccc22141cccc144141cc287782c5d151111c105dd5c
d5551111111115dddddd55555555ddddc129aa7777aa921c3db5ddb325522555cc944ccc94492cccc135cccc21211ccc11142021c128821c515d11115005dd51
d555511111155dddd1115555555dddddc129a777777a921c13bbbb3112525d51ccc94cccc9412cccc1c35cccc21911ccc110202c1122221155d1111c0001511d
555555515555dddd1111155555dddd55c129a777777a921cc111111cc225dddcccc42cccc4211cccc5cd5cccc219111cccccccccc111111ccccccccccc00015c
155555555ddddddd1111155555dd55d1c129a777777a921cccccccccccccccccccc422ccc42212ccc5cd5ccc2114121cddddddddcccccccccccccccccccccccc
1115555555dddddd1111555555d55111c129a777777a921cccccccccccccccccccc422ccc42212ccc15d5ccc24c1541cddddddddcccccccccccccccccccccccc
11115555555ddddd11111555555d1111c129a77777aa921cccccccccccccccccccc422ccc42212ccc1135ccc2211141cddddddddcccccccccccccccccccccccc
11111555555555dd1111115555511111c129aaaaaaa921ccccccccccccccccccccc922ccc92211ccc1d55ccc212121ccddddddddcccccccccccccccccccccccc
11111115555555555111115555ddd111cc129999999911cccccccccccccccccccccc92cccc9211ccc1351cccc2411cccddddddddcccccccccccccccccccccccc
1dd111111155555551115555dddddd11ccc1222222211ccccccccccccccccccccccc422ccc42212cc15511ccc291ccccddddddddcccccccccccccccccccccccc
dddd11111115555551111111111dddddccccc111111ccccccccccccccccccccccccc422ccc42212cc35111ccc19111ccddddddddcccccccccccccccccccccccc
dddd11111111555551111111151111ddcccccccccccccccccccccccccccccccccccc422ccc42212cd55151cc2142111cddddddddcccccccccccccccccccccccc
11111dd111115555511111ddd5551111cccc2ccccccccccccccccccc17cccccccccc422ccc42212cd5c151cc2211121ccccccccccccccccccccccccccccccccc
11111dd55111555511111dddd5555111ccccc111111c2cccccc8cccc17cccccccccc422ccc42211c35c115cc241c221ccccccccccccccccccccccccccccccccc
11111dd5551555551111dddddd55d111cc2c11222222cc2ccc888cbbddc17ccccccc422ccc4221115511555c29cc241ccccc111111111111cccccccccccccccc
1111ddd5555555551111ddddddddd111c2c18888988821ccc3cc883355c17ccccccc922ccc922111c513551c29cc241cccc15515555111111111111ccccccccc
1111ddd55555555511dddddddd555551cc128999f99821ccc33cc853333ddcccccccc92cccc92111c1d5511c24c2121cccc155525511111111555511cccccccc
d555dd55111555551ddddddddd5dd55dcc1899ff7f99821c3b33c2253335ccccccccc422ccc42211cd35111c2221211cccc155f911111111115555511ccccccc
dd55d55115115551dddddddddddd555dcc189ff77ff9821cccc33cc55351ccccccccc422ccc42211d351c1152222411cccc155f9155555551111115551cccccc
dd55555555111511dddddddddddd555dcc289f7777f921cccccc3333551cccccccccc422ccc42211335cc155c222211cccc115f91555555111115ddddd666ccc
d55555555111111dddddddddddddddddcc289f7777f921ccccccbb33351cccbccc1111ccccccccccccc11ccc55cccc15ccc1111155555511115dddddddddd666
555555551155511dddddddddddddddddcc189ff77ff9821ccabbbab335533333c124991cccccccccccc15ccc15115555cccc11155555111115dddddddddddddd
555555551555111dddddd5555dddddddc12899ffff99821ccb33bbb355cccc5c12497791c77c776ccc15d5cc1555d5ddccc1551555511101111ddddddddddddd
dd555555555511dddddddd555dddddddc1288999999821cccb335bb355cccccc0249aa917cc75cc6cc15d5cc5aa55aadccc15f155551100111111ddddddddddd
ddddd555555511ddddddddd55dddddddcc12888888881c2cccb35115b3333ccc014499417ccd7ccdc105dd5c59a559a5ccc1591155510011111111dddddddddd
ddddd555555511dddddddddddd55ddddc2c1222222212ccc33355ccca3553ccc01444441c6d5c6dcc005dd5c15511555ccc159111511001111111111dddddddd
ddddd555555511dd555dddddddd55dddccccc112111cccccb3351cccccb33b3cc011221ccccccccc0001511d11515d5dccc119111111000011111111111ddddd
555555555511555511555dddddddd555ccc2cccccccc2cccab5cccccccb3511ccc0000cccccccccccc00015cc115dddccccc1111111100000011111111111ddd
__label__
221111111111112555555555dddddddddddddddddddddddddddddddddddddddd55555555555555555555555111d5115511110000000111111111ddddd1111111
221111111111112555555555ddddddddddddddddddddddddddddddddddddddddddd5555555555555555555111dd5115111110000000111111111ddd111115555
2217717771717125555555777ddddd7ddd777d777d777dddddddddddd777ddd557575777555555555555551ddd11111111000000001111111111ddd111115555
227111717171712755555575755ddd7ddddd7d7d7ddd7dddddddddddddd7dd7dd7575557555555555555551ddd11111100000110001111111111ddd115555555
2271117771717115555555757ddddd777ddd7d7d7dd77dddddddddddd777ddddd777d777555555555555551dd111111000000111111111111111ddd115555555
127111741171711755555575755ddd7d7ddd7d7d7ddd7dddddddddddd7dddd7dddd7575555555555555555151111100000000111111dd1111111dd1115555555
11177174111771125555557775575d777ddd7d777d777dddddddddddd777ddddddd7d77755555555555555151111100010000111111dd1111111d11115555555
1111114411111112555555555555dddddddddddddddddddddddddddddddddddddddddddddd555555555555111111000010001111111dd1111111111115555555
111111441111111155555555555555555555ddddddddddddddddddddddddddddddddddd555555555555555111100000010111111111dd1111111111115555555
11111144111111115555555555555555555555ddddddddddddddddddddddddddddddddddd5555555555555111000000011111111111111111111111555555511
11111144111111111111111155555555555ddddddddddddddddddddddddddddddddddddd55555555555555100001000111111111111111511111111555551111
11444144112112111111111115555555555555ddddddddddddddddddddddddddddddddd555555555555555100001011111111111111115511111111555551111
11444144112212111111111155555555555ddddddddddddddddddddddddddddddddddddddddddd55555555000001011111111111111115511111111555551111
1144442211222211111111111155555555555ddddddddddddddddddddddddddddddddddddddddddd555555010011111111111111115115511111111115551111
1144442221222111111111115555555555dddddddddddddddddddddddddddddddddddddddddd55555555550100111d1111111111555111111111111115551111
1124442222222111111111111155555555555ddddddddddddddddddddddddddddddddddddddddd555555550101111d1100011111555111111111111115511111
1122242222222111111111115555555555555ddddddddddddddddddddddddddddddddddddddddd555555dd0111dddd1100011111551551111111111111111111
11222222222221111111111111555555555555dddddddddddddddddddddddddddddddddddddddd5555555d1111ddd11100011111111551111111111111111111
1122222222222111411111111111155555555555555ddddddddddddddddddddddddddddddddddddddddddd1dddddd1110001111511155551111111111111111d
111222222222211144112211111111155555555555555ddddddddddddddddddddddddddddddddddddddddd1ddd1111110001111511111551111111111111111d
111112222222212124112222111111111555555555dddddddddddddddddddddddddddddddddddddddddddd1ddd1115110001111511511551111111111111111d
11111155222221212222112211111111111555555555dddddddddddddddddddddddddddddddddddddddddd1d111155110001111155511511111111111111111d
21111155112221212222111111111111155555555ddddddddddddddddddddddddddddddddddddddddddddd1d1155551100011111555111111111111111111155
2211115511222121222211111111111111155555555ddddddddddddddddddddddddddddddddddddddddddd1d1155551100011111551111111111111111115555
22111155112221212222111141441155555555555ddddddddddddddddddddddddddddddddddddddddddddd111155551100011111111111115111111111115555
2211111111222122225521114144221125dd555555dddddddddddddddddddddddddddddddddddddddddddd111155551100011111111111155111111111115555
22111111111221125255211124222211222ddddddddddddddddddddddddddddddddddddddddddddddddddd111555511100011111111111155115111111115555
22111111111121125555211122222221122ddddddddddddddddddddddddddddddddddddddddddddddddddd115555111100011111111111155155111111111111
222221111111111215552111222222221111111ddddddddddddddddddddddddddddddddddddddddddddddd11555111110001111111111115d555111111111111
2222221111111112111111115222222211111110000000110ddddddddddddddddddddddddddddddddddddd1111511111000111111111155dd555111111111111
2222221111111111111111115222552221111110000000110dddddddddd11ddddddddddddddddddddddddd1111511111000111111111155dd551111111111111
2222221111111111111111111555552221112331100055555100555ddddd11111ddddddddddddddddddddd1111111111000111111111155d5111111111111111
2222221111111211111111111555555521112335010555555510000111111111111111111111d1111111111111111d110001111111111dd55111111111111111
22222211111112111144444221115511111221150105555555100000011111111111111111111111111111111111dd110001111111155dd55111111111111111
55222211111112111144444221111111111223310055515555510000011111111111111111111111111111111111dd111111111111155dd5511111111111dddd
55111211111112111122222222111115511223350005551115551551111100111111111111111111111111111111d5111111111111155dd5111111111ddddddd
55111111111111111122222222111115521121150005551115551550111111111111111111111111111111111115551111111111111551111111111ddddddddd
55111111111111111111222252145555221111101000505551551050111111000111111111111111111111111115551111111111111111111111111ddddddddd
55111111111111111111252255125555221111100110000005501001111011001000010100011111111111111115511111111111111111111111111ddddddddd
11111111111111112211255515122222221113300110000005501001011111011100111100011111111111511111111111111111111115511111111dd5555555
1111114411111112221111551112222222111331555501000000000111111001100000111000011111111151111111111111111dddddd5511111111dd5555555
1111114411211112551111111112222222111335550010111010155111110001100001110101001111111111111111111111111dddddd5511111111dd5555555
1111114411222212551111111122552221111115550010111010155010110000000001110101011111111111111111111111111dddddd5511111111dd5555555
111111441122222211111111112255222111111000015555115550511110000001000111010101000001111111111d551111111ddd5555511111111dd1155551
111111221122222211114442112555251111211000005555551551011110110001000000010001011011101111dddd5511111115555555511111111111115551
1111112222222222114444421125555111122110000055555115501111011101101000000000010100001011dddddd5551111115555555511111111111115551
1111112222222222114422222112555111222110001005555115501111111101110000100100000100011111ddddd55551111115555555511111111111115551
1111112222222221112222222211551151122111551000005555000111111100000011111101000010011011dd55555551111111555115511111111111111111
1111112222222221112222222211111151112331551000005500000110110110010100101101010010000011dd55555511111111555115511111111111111111
1111112222222221111122222211111522112335515500000500000010110000110000010010010001000011dd55515511111111555115511111111111111111
11111122222221214411222212111112222111155515510000000551101100010010000000001101100000111115115511111111551111111111111111111111
11111122222221214411111111111112222113355515510000015511111100101010000000010010100001111115115511111111111111111111111111111111
11111111212221112222111111442211222113355555510000015511101000111110100000000001100011111115111111111111111111111111111111111111
11111111112221112222111141442221111111155555510011155551101011111011010010110000010000111111111111111111111111111111111111111111
11111111112221112222111144222222111113311555110015555550011001010011101111111011111000111111111111111111111111111111111111111111
11111111112221112222211122222222111123355551000005555550010010000000000100001111010101111111111111111111111111111111111111111111
2211111111122111225521112222222221112335555100000155551111001011111010100010000001101111111111111111111111111111111d11111111dddd
22111111111111112255211122225522211221105510015500051001111100001001000101110100000010111111111111111111111111111ddd11111111dddd
2211111111111111555521115222555521122111000001551005100110100000101000000101101111100015511d1dddddd55111111111111ddd11111111dddd
22111111111111115555111155555511111221110000015510000010111010000010000001000001000010d5511dddddddd55111111111111ddd11111111dddd
22111111111111111111111115555511111125511000000010000110011010011000101000110100010000d5511dddddddd551111111111111d111111111ddd1
22111111111111111111111111111115521115511100000000000110011110100100111000100101001000d5511dd1111111111111111111111111111111ddd1
2211111111111111111111422111111552111551110000000000111001111010000011100100011010110013355d11111111111111111111111111111111ddd1
2211111111111111111144422211115522111dd5111000000001111100211011100011100101011000110013355d11111111111111111111111111111111ddd1
2211111111111112114444222211555522111dd511100000000111110021101110001010010101110011001dd5511151551151151151111151115151111111d1
2211111111111112114422222214552222111dd511100000000111110011111111111012000101110010001dd551115555555555555111155111555111111111
2211111111111112112222225512222222111dd51110000000115112001112222222222101210011101010111555515555555555555111155111555111111111
2211111111111112112222225512222221111dd55110000055151512101112222222222000210100001000511555555555555555555111155111555111111111
2211114411111222111125551112222221112dd55110000055151221118888889988888211100100111001511335555555555555111115511555111111111111
2211114411111221111125551112552221122dd5510500000501151122899999ff99988211100111000100511335555555555555111115511555111111111115
2211114411111221121111111122552511122dd5155000000050151122899999ff99988211110001101001111113355511555555111115511555111111111115
2211114411111121221111111122555111222335155000000050151188999fff77f9999822111110100100111113355511111111111111511555111111111115
22111144112221212511111111255551111123355500550000551111889ffff777fff9982210100000000015511dd55511111111111111155111555111111115
11111144112221215511114211255511511123311111105550151111889ffff777fff9982210000000000015511dd55511111111111111155111555111111111
11111144112221115111444211125511521111111111105550151112889ff777777ff9921100000000000015511dd55111111111111111155111555111111111
11111144112221111111442222111115222111101101000000010102889ff777777ff9921100000000000015511dd55111111111111111151111555111111111
11144122222221111144222222111112222111100000000000000002889ff777777ff9921100000000000011155dd55111111111111111111111111111111111
11444422222221111144222222111112211100111111111111111111889ffff777fff9982211111000011111155dd5511dddd111111111111111111111111111
11444422222221111122222222110110000000000000550000550001889ffff777fff9982211110000000011111335511ddddddd555111111111111111111111
1144442222222112112222111111133311111111111111131111111288999ffffff999982211111113111111111335511ddddddd555111111111111111111111
11444422222221121115111555111155555511111111115555333112888999999999988211111555311555111dd555511dd55ddd555111111111111511111111
112222222222211211151111111bbb11111111111111bbb33111111288899999999998821111551111111b511dd555511dd55115555111111111111551111111
1122222222222112111155533333333333355551111111111111115122888888888888815121111135553351133551111dd55115111111111111111551111111
1122222221222112bbb3333511155551333111155551111511155223112222222222211211111111bb3333511335511111d55115111111111111511551111111
11222255112221111111bbbb11553333111511111331155555551223112222222222211211111111111111511555511111111111111111111111555d51111111
11111155112221115551111553331111553355555115511111111155553111121111131555551115111111511555511111111111111111111111555dd5551111
1111115511222111111151111111111bb1111111111111111111bbbb223111111155513233311135555511133551111115111111111111111111555dd5551111
1111115511111115555111311111bbbb155555111111111111111111221111111111111211113333333333333551111115511111111111111555d55dd5551111
111111111111111111115555533333333333333355555111111111111111b111155555311115555511555dd55551155115511111111111111555ddd5d5551111
1111111111111211111555535555533335111115555515555511111555551111153333311111333335555dd55551155111511111555115111555ddd551151111
22111111111112bbbbbb331111111155511133333111333555551113331111155511111111111bb111111dd55111155111111111555115511555ddd551111111
22111111111112b111111111111111111113331113333335553333333311155511111111111bbbbb11115dd551111551111111115551155115551dd551111111
2211111111111211111bbbbbb1155553333331155551111113311115555555511133333311133311111153355311111551111111111115511555111551111111
221222111111111111bbb11155555533331155555551115551111115555111111113333553333331111333355331111551111111111111511555111551111111
22222211111115555551111555333333111111333333355551155555511111111111115555535555553335555111155555551555555111111155111551115511
22222211111155555555555553333331111111333333111111155555511111111111115333333555555355555111155555511155555551111111111551115551
22222213333331111115511111111111111bbbb111111111111111111111111111bbbbbbb3331111111111555113355551131113335555555111133351115551
22233333333111115511111111111111bbbbbbb111115511111111111111111111bbbbbbb1111111111111155113355551133333333355555553333333115551
2333335555555555555133333311111111b1111115555555111111111111111111111111111111bbbbb111111dd5555111111111133311113333333333555551
3115555555555555113333333111111331111111555555311111111111111111111111111111bbbbbbbb11111dd5555111111111111111111333333335555555
11115511111111111113355555533333331113333333333331115555511111111111111111111111bbb1111dd335511111111155555555111155511111111555
11111111111111111155555555333333313333333333333335555555511111111111111111111111b111111dd335511111111115555555511555551111111155
5551111111111111111555553335555555533333555111111115555551155555555111111115511111111dd33551111111155111111333333335555555155555
5111111111111111115553333355555555333355551111111155555111555555555111111115511111111dd33551111111155111111333333333555551115555
11111111111bbbbbbbb3333333335111111155555555113333333111111115555555511111111555511553333551111115555111111111111111111111111111
111111111bbbbbbbbb33333333111111111555555551333333331111111155555555511111111555511553333551111115555111111111111111111111111111
1111111111bbbbbbb111111111111111111111111111113333333133333333355555555333311555555225555111111111111111155555555111111111111111
11111111bbbbbbb11111111111111111111111111111333333311333333333555555553333311555555225555111111111111111155555555111111111111111
111111111111111111111111bbbb11111111111111133331111111113333331113333333333115555ff991111111111111111111155555555551111155555555
1111111111111111111111bbbbb111111111111111333311111111133333311133333333333115555ff991111111111111111111155555555551111115555555
1111111111111111111bbbbbbbbbb1111555553333333333111155555511111111133333111115555ff991155555555555555111111111111555555111111555
11111111111111111bbbbbbbbbb111115555533333333331111155555111111111333333111115555ff991155555555555555111111111111555555111111555
1111111111111111111bbbb1111115555555555333311111155555555551111155555111111111155ff9911555555555555111111111155dddddddddd6666663
11111111111111111bbbbb11111555555555553333311111555555555511111155551111111111155ff9911555555555555111111111155dddddddddd6666663
11111111111115555551111111111155553333331111111111555553333335555555555111111111111115555555555551111111155dddddddddddddddddddd6
11111111111155555111111111115555553333111111111115555555333355555555551111111111111115555555555551111111155dddddddddddddddddddd6
111111115555555555511111155555333333333331111111111133333333333555555111155551111115555555555111111111155ddddddddddddddddddddddd
111111555555555551111111155533333333333111111111113333333333355555555511555551111115555555555111111111155ddddddddddddddddddddddd
11111111555555551115555555555533333333311111111111111333333333111111111111111555511555555551111110011111111ddddddddddddddddddddd
11111555555555551555555555553333333333311111111111133333333333311111111111511555511555555551111110011111111ddddddddddddddddddddd
1111113111111111111555555111151111111111111111111111111111111111111111111111155ff115555555511110000111111111111ddddddddddddddddd
1111b10111771177757775551249913117771111111111111111333111111111111111111111155ff115555555511110000111111111111ddddddddddddddddd
3111a111111711717175751124977911111711111111111bbbbbbbb1111111111111111111111559911115555551100001111111111111111ddddddddddddddd
31ba7ab10117117175757550249aa9111177111111111111bbbbbb11111111111111111111111559911115555551100001111111111111111ddddddddddddddd
3111a111011711757571711014499411111711111111bbbbbbbbbbbbb111111115555111111115599111111551111000011111111111111111111ddddddddddd
3301b1000177717771777110144444111777111111bbbbbbbbbbbbb11111111111111111111115599111111551111000011111111111111111111ddddddddddd
333111055555555555511111011221111111111111111bbbbbbbbbbbbb55555555555551111111199111111111111000000001111111111111111111111ddddd
3331000555555555111111111000011111111111111bbbbbbbbbbbbb1111155555555111111111199111111111111000000001111111111111111111111ddddd
__gff__
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000002020000020200000000000000000000020200000
__map__
727f7f7f727272727272727e7e7e7e7e7e7e7e72727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727e7e7e7e7272687272727272727272727272727b7b7b72727272727272727272727d7d7d7d7d7d7d7d727e7e7e7e7e7e7e7e7e7e7e7272727272727272c2
726f6f6f7272727268516868686868686868687e727272727272727272727272726d6d6d6d6d6d6d6d6d68497b48685b7b7272727272726d72726868686868686868606060497e6172687248517b7b7b727272727b4d68497b7272727272727272727d7d4866666666497d607e57706a6a6a6a6a6a6a7e727272727272727272
72727172727272726868686860607e7e7e68687e727272727272727272727272726d4b726d6d5b724a6d686868686d6868686d727272726d725368686869696868687e626060497e727248686863636868684972726868687b7272727272727272727d48666666596666497d7e607e6a6a77595b776a527e7272727272727272
726060605d72727268686868686860607e68687e727272727272727272727272726d49726f6f6f6872507b7b4a68686d6d6868727272726d7268686f6f69586f6f687e627762627e7272686868636368686868686168684b7b727272727272727d4d64666666777766666670605b7e6a6a6a6a6a6a6a7e727272727272727272
72606a6072625b72686868686868605a7e68687e7e7272727272727272727272726d6d726f6f6f6f7272497b7b686d6d687b68527272726d7272686868696968686860606060607e7248687b7b635b7b7b68684b7272727251727272727272727d7d7d66666677776666667d7e7e7e7e607e60607e607e727272727272727272
72606a607262607068686868686860607e686860497e72727272727f7f7f7f72724a6d726f6f6f6f6f6868497b7b68687b68686d7272726d727268686868686868687e6262775b7e7268687b7b63637b7b6868727248686868497272727272727d53646666665b666666667d7e5c7e6f6f6f69696f6f6f727272727272727272
72606a60726060726868686868607e7e7e68686060497e7e72726d6f6f6f6f7f72726d726f6f6f6f6f68686868686d6d68684b737272726d72517d707d7d7d7d707d7e4a6262627e7268686868686868686868706868686859686868497272727d7d7d4a6666666666664b7d7e707e686f6f69696f6f6f727272727272727272
72606055726060726868686868686868686868606060497e72726d6f6f6f6f7f7268686968686f6f6f6f686d6d6d6d6b687b72727272726d7d6262606060576060627d7e4a62627e7b685768684b7270727272726868686868686868687b72727272727d647d7d7d7d647d7d686a686868686d6d68684b727272727272727272
726272766260606072727271726872717272727e4a60607e7e726d6f6f6f6f7f726868686868686f6f6f6f6363636f6f6f6f6f6f6f6f6f727d626060605b60606062527e7e707e7e7b687b686872486149724868684b7e7e7e7e4a6868497b7272647d7d707d7d7d7d707d7d68684b7b4a686868684b72727272727272727272
726272626262606072776868686868686868777e7e6a6a6a516d6f6f6f6f6f7f726a7d4a68686868686f6f6363636f6f6f6f6f6f6f6f6f727860606f6f6f777777627d536060607d7b635b6368726158617068684b7e486868497e4a68687b72727d66666666665b7d647d7d6868497b486868684b7272727272727272727272
726272627760776072686d6d6d6d6d6d6d68687e6f6d6d68686d6f6f6f6f7f6072607d7d4a5b4b7d717d4a6868684b7d717d4a7d7d7d7d727d60606f6f6f777777627d62626060787b63636368726161617268687e4868685b68497e6868497b727d6666666666667d647d48686868686868684b727272727272727272727272
725370606060606071686d68684c68686d6868716f6d6d6d6d6d6f6f6f6f6f7f72627d517d7d7d7d5b7d7d6060607d7d5b60497d7d517d7d7860556f6f6f6f6f5b607d7d7d62627d7b687b6868724a614b7268686868687e7e6868686868687b727d667d66667d667164646868684b7b4a686849726472727272727272727272
726272606a576a6072686d686f6f6f686d68527e6f6f6d6d6d686d6f6f6f6f7f726262626060606060497d6060606060607460606060497d7d6277776f6f6f6f60607d606262627d7b6868684b7272707248685768686d5c5e6d6868575a687b727d6666666666667d647d4a6868497b48686868726472727272727272727272
727272606060606071686d68685968686d6868716f6f6f6d6d58686d6f6f6f7f727d6262746262746260606060606060626262626060607d7d62777760596060606070606062627872686868725b6868725b68686868687e7e6868686868687b7d536666586666667064527d68686868684b7b5b727272727272727272727272
727272627760776072686d6d6d6d6d6d6d68687e6f6d6d6d6d6d686d6f6f6f7f727d60626262626262626060606060627d4e7d6260604b7d7d6262626060606060627d606262627d7272617248686868724a68687e4a686868684b7e6868687b727d6666666666667d647d48685568684b7b6368727272727272727272727272
727272626250626072776868686868686868777e6868686a68686d6f6f6f6f7f727d60607d4d7d7d7d7d7d6060607d7d7d627d62607d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d787d7d726868686868686849726868497e4a68684b7e4868684b7b727d667d66667d66716464686868687b7b7b6368497272727272727272727272
727272727272727272727272727272727072727272727e707e72726d6d6f6f7f727d60607d607d7d7d7d486a6a6a497d7d5f7d62607d7d7d72727272727272727272727272727272727b68686d586d686870686868497e7e7e7e4868684b7b72727d6666666666667d647d4a68686363527b6368587272727272727272727272
72727272727272727272727272727272624972724d77606060775b726d6f6f7f727d60607d5c7d7d6a6a6a6a6a6a6a6a527d62626060497d72727248616161497272727272727272725368686f6f6f6d6872686868686858686868684b7b7272727d66666666665b7d647d7d68687b7b7b7b63684b7272727272727272727272
727272727272727272727272727272724a6249726277606a607762726d6f6f7f7e7e60607e7e7e7e6a6d6a6a6a6a6d6a6a7d62606060607d727248614b724a614972727272727272727b636363636368687b7b4a686868686868684b7b727272727d7d7d64647d7d7d647d486868497b7b486868727272727272727272727272
72727272727272727272727272727272724a62706262606a606262726d6f6f7f7e6a6a6a6a6a6a7e6a6d6d6a6a6d746d6a70606060604b7d7272614b727272616161497272727272727b637b7b7b7b7b7b72687b4a68686868684b7b7b7b7b727d5364666666666664647d686868685b6868684b727272727272727272727272
727272727272727272727272727272727272727262626057606252727f7f7f7f7e6a686868686a706a6d6d6a6a6a6d6a6a7d7d7d7d7d7d7272486172726b6b6b7261617272727272727b687b48686868497b72687b7b7b507b7b7b486868687b7d7d7d66666666577d7d486868684b7272617272727272727272727272727272
72727272727272727272727272727272727272727272727072727272727272727e5b6a6a6a6a6a7e4a6a6a6a6a6a5b6a6a7d7272727272727261616b6b6b4b7248614b7272727272727b68685b5868684e7b72727272727b68724c685b58685d7d4c64666666666664646868684b72727261615d727272727272727272727272
72686868687d6868687d666666666672727272727272725c72727272727272727e7e7e7e7e7e607e7e717d4a6a4b7d4a6a7d727272727272724a616172727248614b72727272727272727b7b4a6868684b7b72727272727272687b4a6868687b7d7d7d66666666667d7d4a684b72727272727272727272727272727272727272
72686868687d68684b7d666666666672727272727272727272727272727272727272727d5d7d60607d717d7d707d7d7d7d7d5e7d7d72727272724a61616161614b72727272727272727272727b7b7b7b72727272727272727272727b7b7b7b727d7d7d7d7d7d7d7d7d7d7d727272727272727272727272727272727272727272
72687272687d68687d7d6666666666727272727272727272c0c1c2c3c0c1c2c37272727d607d606060606262625b7d7d7d7d627d7d7272727272724a6161514b72727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
7268686868646857497d666666666672727272727272727dd0d1d2d3d0d1d2d372517d7d4c7d506060606062624b7d517d7d4f7d7d727272727272724a61617272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
72685b555364686868706666666652727272727272727272e0e1e2e3e0e1e2e37262626262497d7d7d7d7d7d7d7d7d627d4a6262497d7d72727272727261614972727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
72686868686468684b7d6666666666727272727272727272f0f1f2f3f0f1f2f372626262626f62627d62626262626262627d4a626262497d727272727261616149727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
72685768687d68687d7d6666666666727272727272727272c0c1c2c3c0c1c2c37262626f6f6f62627062776060607762627d7d6260605b7d7272727272724a6161497272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
72686868687d6868497d666666666672727272727272727dd0d1d2d3d0d1d2d372626263636362627d62776060607762627d48626060627d727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
727272727272727272727272727272727272727272727272e0e1e2e3e0e1e2e37262626f6f6f6262715b6262626262626270626262624b7d727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
727272727272727272727272727272727272737373727272f0f1f2f3f0f1f2f3727272727272727d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272
__sfx__
011000001155411557115571155527503085000a5000c500115001450016500165001650017500175001750016500000000000000000000000000000000000000000000000000000000000000000000000000000
000400000e5541255312300095000a5030a50311603136020b0050000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000900000e6140f612003120031200312000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000700000062403020010200002002600026000260001600016000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000500000333103333215010233100331003210032100323003010030100301003010050100501005010050100501000010000100001000010000100000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000300000305403070030700000000000000000805408070080700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000800000065400050056540005400004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000300000631706327063270633706357063520635206352063520635206340063300632006310063100631000000000000000000000000000000000000000000000000000000000000000000000000000000000
000300000631206312063120632206332063420635206352063520635206352063520635206352063520635300000000000000000000000000000000000000000000000000000000000000000000000000000000
000c00000032400652006520064200632006220060000600006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment