3 Commits

Author SHA1 Message Date
8fe5d4dd43 Show blocked moves as an animated X.
I am not convinced the sprite is very good. This could help the player learn what pulls were considered before proposing the ones that would occur if the player pulled the tongue. Or it's just visual noise that sucks. Anyway, this correctly captures what the blocked considered moves were, and we can decide whether to use it or not.
2023-01-02 15:05:18 -08:00
04d2a680dd block writes while reading
Disabling writes during "wipe" and "first load" is not quite semantically what we want, it's writes during read we want to block. This happens because turning the music on or off tries to save the state, and it's easier to just ignore that persistence request than to rework the music code so it doesn't. "wipe" and "first load" are when we're actually reading (and enacting) state, but it's the act of reading rather than those two acts that should block writes.

It is also unwilling to write until it's done its first read, which I think is a feature; it makes it harder to accidentally blank out the player's data.
2023-01-02 15:04:27 -08:00
7b931d1fba Save/load system. Not golfed.
Saves the music flag, the last level the player played, and the furthest level reached. Loads music flag on launch. Title screen starts on most recent level played; when in "release configuration" the title screen will only let the player pick levels up to the maximum reached through gameplay, but right now this is replaced with the 31.

Save file can be wiped by holding the down arrow at the title screen.
2023-01-02 13:43:26 -08:00

View File

@ -5,13 +5,15 @@ __lua__
modules={}
real_modules={}
frame=0
function _init()
-- printh("restarting")
_doall("init")
end
function _update()
_doall("update") end
frame+=1
if (frame%1==0) _doall("update") end
function _draw()
_doall("draw") end
@ -95,10 +97,11 @@ function linefill(ax,ay,bx,by,r,c)
local _x1,_y1=x1,y1
if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0
local dx=(x1-x0)/(y1-y0)
if(y0<0) x0-=y0*dx y0=-1
local cy0=y0\1+1
-- sub-pix shift
x0+=(cy0-y0)*dx
for y=cy0,min(y1\1,127) do
for y=y0\1+1,min(y1\1,127) do
-- open span?
local span=spans[y]
if (span) rectfill(x0,y,span,y)
@ -122,6 +125,15 @@ function sgn0(x)
return x!=0 and sgn(x) or 0
end
function inorder(tbl)
local prev
for v in all(tbl) do
if (prev and v < prev) return
prev = v
end
return true
end
function _mnmx(x,y)
if (x>y)return y,x
return x,y
@ -129,16 +141,18 @@ end
function _rast(
xys,x0,y0,x1,y1
xs,ys,x0,y0,x1,y1
)
local function _add()
local n=#xys
local xy0={x0,y0}
if (n==0 or not _anch_eq(xys[n],xy0)) add(xys,xy0)
local n=#xs
if (n==0 or xs[n]!=x0 or ys[n]!=y0) add(xs,x0) add(ys,y0)
end
local dx,dy=abs(x1-x0),abs(y1-y0)
local sx,sy=sgn(x1-x0),sgn(y1-y0)
local sx=-1
local sy=-1
if (x0<x1) sx=1
if (y0<y1) sy=1
local done,err
if dx>dy then
@ -416,9 +430,8 @@ end
function level:recollide_reanchor()
self._coll={}
for mx=0,15 do
local kmx=mx..","
for my=0,15 do
local mxy=kmx..my
local mxy=_mix{mx,my}
self._coll[mxy]=
fget(self:_mget(mx,my),7) or
self._crates[mxy]
@ -426,24 +439,18 @@ function level:recollide_reanchor()
end
local anch_new={}
for dxy in all(gsv[[-1`-1
1`-1
-1`1
1`1]]) do
for dxy in all{{-1,-1},{1,-1},{-1,1},{1,1}} do
local dx,dy=unpack(dxy)
local c=self._coll
assert(dx!=0 and dy!=0)
for mx0=0,15 do
local mx1=mx0+dx
local kmx0,kmx1=mx0..",",mx1..","
for my0=0,15 do
local my1=my0+dy
local mx1,my1=mx0+dx,my0+dy
-- bypass mcoll for MEGA SPEED
if (
c[kmx0..my0] and not self:get_crate(mx0,my0) and
not c[kmx0..my1] and
not c[kmx1..my0] and
not c[kmx1..my1]
self:mcoll(mx0,my0) and not self:get_crate(mx0,my0) and
not self:mcoll(mx0,my1) and
not self:mcoll(mx1,my0) and
not self:mcoll(mx1,my1)
) then
local key=_mix{"GEOM",mx0,my0,dx,dy}
anch_new[key]= {
@ -487,6 +494,10 @@ function level:recollide_reanchor()
if player.rope then
player.rope:experience_anchor_moves(moves)
end
for point in self:anchor_points() do
point.moved=nil
end
end
function level:win_at(mx,my)
@ -547,8 +558,7 @@ function level:spawn_exit()
assert(spawned)
end
function level:mcoll(mxy)
local mx,my=unpack(mxy)
function level:mcoll(mx,my)
if ((mx | my) & 0xFFF0!=0) return true
return self._coll[_mix{mx,my}]
end
@ -623,17 +633,15 @@ end
ropecheck=split"-0.6,0.4,0.4"
-- argument "o" is a rope operation:
-- array of [mx0,my0,dmx,dmy]
function level:can_move(
is_player,o,exclude_src,exclude_dst
is_player,
mx0,my0,dmx,dmy,exclude_src,exclude_dst
)
local mx0,my0,dmx,dmy=unpack(o)
local mx1,my1=mx0+dmx,my0+dmy
if (is_player and self:win_at(mx1,my1)) return true
if (is_player and self:get_open_pit(mx1,my1)) return wrongbleep:adequately_warned()
if (self:mcoll{mx1,my1} or player.x==mx1 and player.y==my1) return
if (self:mcoll(mx1,my1) or player.x==mx1 and player.y==my1) return
if player.rope then
local w,h=1.2,0.2
@ -644,12 +652,7 @@ function level:can_move(
return true
end
-- argument is a rope operation:
-- array of [mx0,my0,dmx,dmy]
-- must be a free function
-- to use as a foreach target
function level_tug_crate(t)
local self,mx0,my0,dmx,dmy=level,unpack(t)
function level:tug_crate(mx0,my0,dmx,dmy)
local mxy0=_mix{mx0,my0}
local existing=self._crates[mxy0]
if (not existing) return
@ -731,7 +734,7 @@ function player:update()
else
local x,y=self.x,self.y
local function try_move(dx,dy,f)
if level:can_move(true,{x,y,dx,dy},0,2) then
if level:can_move(true,x,y,dx,dy,0,2) then
self.todo=f
self.cooldown=3
local t=f[#f]
@ -753,7 +756,7 @@ function player:update()
local dx,dy=self.orientx,self.orienty
if (dy!=0) dx=0
while not level:mcoll{x,y} do x+=dx y+=dy end
while not level:mcoll(x,y) do x+=dx y+=dy end
self.rope=rope:new(
{x+0.5-dx*0.5,y+0.5-dy*0.5},
@ -869,7 +872,7 @@ function player:draw()
if (self.orientx==1) rx+=6
if self.rope then
local rx_adj,ry_adj=self.rope:affected_src_xy{rx,ry}
local rx_adj,ry_adj=self.rope:affected_src_xy(rx,ry)
if rx_adj then
local drx,dry=rx_adj-rx,ry_adj-ry
rx,ry=rx+drx,ry+dry
@ -877,16 +880,17 @@ function player:draw()
end
end
setpal()
if self.orientx==-1 then
setpal()
spr(16,px+6,py-2,1,1)
spr(17,px+1,py,1,1)
if (self.rope and invis_level<=0.25) pal() self.rope:draw{self.x*8+self.px+1,self.y*8+self.py+2} setpal()
if (self.rope and invis_level<=0.25) pal() self.rope:draw(self.x*8+self.px+1,self.y*8+self.py+2) setpal()
spr(head,px-3,py-3,1,1)
else
setpal()
spr(16,px-6,py-2,1,1,true)
spr(17,px-1,py,1,1,true)
if (self.rope and invis_level<=0.25) pal() self.rope:draw{self.x*8+self.px+7,self.y*8+self.py+2} setpal()
if (self.rope and invis_level<=0.25) pal() self.rope:draw(self.x*8+self.px+7,self.y*8+self.py+2) setpal()
spr(head,px+3,py-3,1,1,true)
end
pal()
@ -933,7 +937,13 @@ function rope:update()
elseif self.state.name=="latched" then
if (not self.latch) wrongbleep:bleep(5) self:destroy() return
if (self.latch.rec and self.latch.rec.dead) self:destroy()
if self.latch.rec then
if self.latch.rec.dead==true then
self:destroy()
end
end
if (not self:_check_pinch()) self:destroy()
elseif self.state.name=="destroy" then -- destroy
@ -949,100 +959,125 @@ function rope:destroy(reelin)
self.state={name="destroy",frame=0,reelin=reelin}
end
function rope:_resegment(points,artificial_pxy,cb)
local n,perc_to_show,from_end=self.state.name,1.0
function rope:affected_src_xy(artificial_px,artificial_py)
-- this is the loop from :draw but simplified
if (not self.state.reelin) return
perc_to_show=(1.0-self.state.frame/8)^2
local points=self:_anchors_simplified()
points[#points]={x=artificial_px,y=artificial_py}
local len=0
for i=1,#points-1 do len+=distance(points[i],points[i+1]) end
local len_to_show=perc_to_show*len
local len_cumulative=0
for i=1,#points-1 do
local src=points[i]
local dst=points[i+1]
local x,y=dst.x,dst.y
local dx,dy=src.x-x,src.y-y
local len_here=len_to_show-len_cumulative
local dist_base=distance_dxy(dx,dy)
len_cumulative+=dist_base
if len_here>0 and dist_base>0 then
local coef=min(len_here/dist_base,1.0)
return x+dx-dx*coef,y+dy-dy*coef
end
end
return points[1]
end
function rope:draw(artificial_px,artificial_py)
local points,highlight,hypo_ops,hypo_blocks=self:_tug(true)
local n,perc_to_show,from_end = self.state.name,1.0
if (n=="done") return
if (n=="cast") perc_to_show=self.state.frame/2
if (n=="destroy") perc_to_show=(1.0-self.state.frame/4)^2
if (self.state.reelin) from_end=true
local artificial_px,artificial_py=unpack(artificial_pxy)
points[#points]={x=artificial_px,y=artificial_py}
local len=0
for i=1,#points-1 do
len+=distance(points[i],points[i+1])
end
local len_to_show,ia,iz,istep=perc_to_show*len,#points-1,1,-1
if (from_end) ia,iz,istep=iz,ia,1
local len_to_show=perc_to_show*len
for i=ia,iz,istep do
local src,dst=points[i],points[i+1]
local x,y=dst.x,dst.y
local dx,dy=src.x-x,src.y-y
local dist_base=sqrt(dx*dx+dy*dy)
local coef=min(len_to_show/dist_base,1.0)
len_to_show-=dist_base
dx,dy=dx*coef,dy*coef
if (from_end) x,y=src.x-dx,src.y-dy
local v0,v1=cb(x,y,dx,dy,i)
if (coef<1) return v0,v1
end
end
function rope:affected_src_xy(artificial_pxy)
if (not self.state.reelin) return
return self:_resegment(
self:_anchors_simplified(),artificial_pxy,
function(x,y) return x,y end
)
end
TONGUE_SEGS=gsv[[0`0.25`1
0.25`0.9`0.5
0.9`1`1]]
function rope:draw(artificial_pxy)
local points,highlight,hypo_ops,hypo_blocks=self:_tug(true)
local len_cumulative=0
local ia,iz,istep=#points-1,1,-1
if (from_end) ia,iz,istep=1,#points-1,1
local function colorh(ix)
color(8)
if (highlight==ix) color(12)
end
for i=ia,iz,istep do
local src=points[i]
local dst=points[i+1]
local x,y=dst.x,dst.y
local dx,dy=src.x-x,src.y-y
local len_here=len_to_show-len_cumulative
local dist_base=distance_dxy(dx,dy)
len_cumulative+=dist_base
if len_here>0 and dist_base>0 then
local coef=min(len_here/dist_base,1.0)
if from_end then
x,y=x+dx-dx*coef,y+dy-dy*coef
end
dx,dy=dx*coef,dy*coef
self:_resegment(points,artificial_pxy,
function(x,y,dx,dy,i)
colorh(i)
foreach(TONGUE_SEGS,function(row)
local d0,d1,w=unpack(row)
local function lf(d0,d1,w)
linefill(x+d0*dx,y+d0*dy,x+d1*dx,y+d1*dy,w)
end)
circfill(x+dx,y+dy,1)
end
lf(0,0.25,1.0)
lf(0.25,1,0.5)
lf(0.9,1,1.0)
circfill(x+dx+0.5,y+dy+0.5,1.0)
end
)
end
-- draw latch
local l=self.latch
if l and l.rec and (self.state.reelin or self:latched()) then
if l and l.rec and (perc_to_show>=1.0 or from_end) then
local function rfsplit(x) rectfill(unpack(split(x))) end
local ldx,ldy=l.dx,l.dy
colorh(0)
camera(-l.rec.px,-l.rec.py)
if (l.dx==-1) rfsplit"0,3,2,4"
if (l.dx==1) rfsplit"5,3,7,4"
if (l.dy==-1) rfsplit"3,0,4,2"
if (l.dy==1) rfsplit"3,5,4,7"
if (ldx==-1) rfsplit"0,3,2,4"
if (ldx==1) rfsplit"5,3,7,4"
if (ldy==-1) rfsplit"3,0,4,2"
if (ldy==1) rfsplit"3,5,4,7"
camera()
color()
end
-- hypothetical
local time=t()-self.flicker_t
local flicker_on=time%0.5>0.25
if self:latched() and time>0 and not level:busy() then
if flicker_on then
foreach(hypo_ops, function(o)
if n=="latched" and time>0 and not level:busy() then
if time%0.5>0.25 then
for o in all(hypo_ops) do
local mx0,my0,dmx,dmy=unpack(o)
spr(14,(mx0+dmx)*8,(my0+dmy)*8)
end)
local px1,py1=(mx0+dmx)*8,(my0+dmy)*8
spr(14,px1,py1)
end
end
foreach(hypo_blocks, function(o)
for o in all(hypo_blocks) do
local x,y,dx,dy=unpack(o)
spr(34,8*x+4*dx,8*y+4*dy,1,1,flicker_on)
end)
spr(53,8*x+4*dx,8*y+4*dy,1,1,time%0.5>0.25)
end
end
-- debug
@ -1136,43 +1171,60 @@ function rope:_check_pinch()
local n0=self.src
local qxys={}
local qxs,qys={},{}
while true do
local n1=n0.next
if (not n1) break
local n0ax,n0ay=_anch_unpack(n0)
local n1ax,n1ay=_anch_unpack(n1)
_rast(qxys,n0ax\0.5,n0ay\0.5,n1ax\0.5,n1ay\0.5)
_rast(qxs,qys,flr(n0ax*2),flr(n0ay*2),flr(n1ax*2),flr(n1ay*2))
n0=n1
end
local function _possible_tiles(t)
local qx,qy=unpack(qxys[t])
local function _possible_tiles(qx,qy)
local mx0=(qx-1)\2
local mx1=qx\2
local my0=(qy-1)\2
local my1=qy\2
local poss={}
for mx=(qx-1)\2,qx\2 do
for my=(qy-1)\2,qy\2 do
if (not level:mcoll{mx,my}) add(poss,{mx,my})
for mx=mx0,mx1 do
for my=my0,my1 do
add(poss,{mx=mx,my=my})
end
end
return all(poss)
return poss
end
local function _blocked(qx,qy)
for i in all(_possible_tiles(qx,qy)) do
if (not level:mcoll(i.mx,i.my)) return
end
return true
end
-- find cases where i move through an impassable zone
for i=1,#qxys do
if (not _possible_tiles(i)()) return
for i=1,#qxs do
if (_blocked(qxs[i],qys[i])) return
end
-- find cases where i am cut off diagonally
for i=3,#qxys do
local qx1,qy1=unpack(qxys[i-1])
if (qx1|qy1)&1==0 then
for i=3,#qxs do
local qx1,qy1=qxs[i-1],qys[i-1]
if qx1%2==0 and qy1%2==0 then
local ok
for m0 in _possible_tiles(i-2) do
for m2 in _possible_tiles(i) do
local mx0,my0=unpack(m0)
local mx2,my2=unpack(m2)
if (mx0==mx2 or my0==my2 or not level:mcoll{mx0,my2} or not level:mcoll{mx2,my0}) ok=true
for m0 in all(_possible_tiles(qxs[i-2],qys[i-2])) do
for m2 in all(_possible_tiles(qxs[i],qys[i])) do
local mx0,my0=m0.mx,m0.my
local mx2,my2=m2.mx,m2.my
if not (level:mcoll(mx0,my0) or level:mcoll(mx2,my2)) then
local dmx,dmy=abs(mx2-mx0),abs(my2-my0)
if dmx==1 and dmy==1 and level:mcoll(mx0,my2) and level:mcoll(mx2,my0) then
else
ok=true
end
end
end
end
@ -1402,6 +1454,10 @@ function _which_side(xy,x0y0,x1y1)
return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
end
function distance_dxy(dx,dy)
return sqrt(dx*dx+dy*dy)
end
function distance(p1,p2)
local dx=p2.x-p1.x
local dy=p2.y-p1.y
@ -1484,19 +1540,22 @@ function rope:_tug(hypothetically)
local blocks = {}
for i=#ancs-1,2,-1 do
local ops_before_trash,blocks_before_trash=self:_calc_push(ancs[i+1],ancs[i],ancs[i-1],ancs[i-2])
local ops = {}
local ops_to_do,corners={}
for b in all(blocks_before_trash) do add(blocks, b) end
if #ops_before_trash>0 then
ops=ops_before_trash
ops_to_do=ops_before_trash
else
local ops_after_trash,blocks_after_trash=self:_calc_push(ancs[i-2],ancs[i-1],ancs[i],ancs[i+1])
ops=ops_after_trash
ops_to_do=ops_after_trash
for b in all(blocks_after_trash) do add(blocks,b) end
end
local ops=ops_to_do
if #ops>0 then
if (hypothetically) return ancs,i-1,ops,blocks
foreach(ops, level_tug_crate)
for o in all(ops) do level:tug_crate(unpack(o)) end
return true
end
end
@ -1545,19 +1604,18 @@ function rope:_tug(hypothetically)
end
if not invalid_move then
local mv = {mx0,my0,dmx,dmy}
if level:can_move(false,mv,1,0) then
if (hypothetically) return ancs,0,{mv},blocks
if level:can_move(false,mx0,my0,dmx,dmy,1,0) then
if (hypothetically) return ancs,0,{{mx0,my0,dmx,dmy}},blocks
level_tug_crate(mv)
level:tug_crate(mx0,my0,dmx,dmy)
return true
else
add(blocks, mv)
add(blocks, {mx0,my0,dmx,dmy})
end
end
end
if (hypothetically) return ancs,32767,{},blocks -- invalid
if (hypothetically) return ancs,0,{},blocks
return
end
@ -1582,16 +1640,21 @@ function rope:_calc_push(
smy=-smy
end
local dmx=1 -- maybe push right?
local mx,dmx
if anch.adx==-1 and a0.x>an.x+7 then
-- push left
ax0, dmx=ax0-1,-1
elseif anch.adx!=1 or a0.x>=an.x-7 then
mx=ax0-1
dmx=-1
elseif anch.adx==1 and a0.x<an.x-7 then
-- push right
mx=ax0
dmx=1
else
return {}
end
for my=my0,my1,smy do
add(ops,{ax0,my,dmx,0})
add(ops,{mx,my,dmx,0})
end
end
@ -1603,26 +1666,38 @@ function rope:_calc_push(
smx=-smx
end
local dmy=1 -- maybe push down?
local my,dmy
if anch.ady==-1 and a0.y>an.y+6 then
-- push up
ay0,dmy=ay0-1,-1
elseif anch.ady!=1 or a0.y>=an.y-6 then
my=ay0-1
dmy=-1
elseif anch.ady==1 and a0.y<an.y-6 then
-- push down
my=ay0
dmy=1
else
return {}
end
for mx=mx0,mx1,smx do
add(ops,{mx,ay0,0,dmy})
add(ops,{mx,my,0,dmy})
end
end
local ops2,blocked={},{}
for o in all(ops) do
local mx,my=unpack(o)
if level:mcoll{mx,my} then
if (not level:get_crate(mx, my)) break
if not level:can_move(false,o,0,0) then
add(blocked,o)
local mx,my,dmx,dmy=unpack(o)
if not level:mcoll(mx,my) then
-- great!
else
local crate=level:get_crate(mx,my)
if crate then
if not level:can_move(false,mx,my,dmx,dmy,0,0) then
add(blocked,o)
break
end
else
break
end
add(ops2,o)
@ -1900,20 +1975,20 @@ __gfx__
00000ee00c44455500aaaa00efe33eee1ff11ff1eee33efeeeeeeeeeeeeeee5efffffffffff11111ff1ff1ff11111fff88888888888888888888888888888888
00eeee000c004005000aa000efe33e5e11ffff11e5e33efee5555e555e555e5effffffffffffffffff1ff1ffffffffff88888888888888888855885588558855
eeee0000cc04405500444400efeeee5e11111111e5eeeefeeeeeeeeeeeeeeeeeffffffffffffffffff1ff1ffffffffff88888888888888885555555555555555
00000000000a900000000000efe33eeeeeeeeeeeeee33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000aaaaaaa910000000000efe33e5555e555e555e33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
0000aaaaaa1a911000a00200efe33eeeeeeeeeeeeee33efeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000
0aaaaaaaaa1a9111000a2000efe333e3333e333e33333efeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000
0aaaaaaaa41a91a10002a000efee33e3333e333e3333eefeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000
0a000aa4441a91a100200a00effeeeeeeeeeeeeeeeeeeffeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000
00a0044449a110a100000000eeffffffffffffffffffffeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
000aa1119911111000000000eeeeeeeeeeeeeeeeeeeeeeeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000a90005bbbbbb3efe33eeeeeeeeeeeeee33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000aaaaaaa9100bbbbbbbbefe33e5555e555e555e33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
0000aaaaaa1a9110bbb7aabbefe33eeeeeeeeeeeeee33efeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000
0aaaaaaaaa1a9111bbbaabbbefe333e3333e333e33333efeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000
0aaaaaaaa41a91a1bbaaabbbefee33e3333e333e3333eefeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000
0a000aa4441a91a1bbabbbbbeffeeeeeeeeeeeeeeeeeeffeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000
00a0044449a110a1bbbbbbbbeeffffffffffffffffffffeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
000aa111991111103bbbbbb3eeeeeeeeeeeeeeeeeeeeeeeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
0000000099100000f765000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111999999111111111
00000000990000007700000000000000000000000000000000000000000000000000000000000000000000000000000019911991999999911999999119999999
00000000990000006060000000000000000000000000000000000000000000000000000000000000000000000000000019977991999999911999999119999999
00000000090000005005000000000000000000000000000000000000000000000000000000000000000000000000000019911991999117111991199111711999
00000000aa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000019911991999117111991199111711999
0000000077a000000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991999999911997799119999999
00000000990000006060000000000000000bc0000090020000000000000000000000000000000000000000000000000019977991999999911999999119999999
00000000090000005005000000bbcc00000bc0000009200000000000000000000000000000000000000000000000000019911991999117111991199111711999
00000000aa0000000000000000ccbb00000cb0000002900000000000000000000000000000000000000000000000000019911991999117111991199111711999
0000000077a000000000000000000000000cb0000020090000000000000000000000000000000000000000000000000019999991999999911997799119999999
00000007777a00000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991999999911991199119999999
00044444444444000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991111111111111111111111111
44444444444004444444444444400444444444444440044444444444444004444444444444400444444444444440044444444444444004444444444444400444
@ -1949,37 +2024,37 @@ eeee0000cc04405500444400efeeee5e11111111e5eeeefeeeeeeeeeeeeeeeeeffffffffffffffff
00880888880880888880880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000888888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d030404050d0d0d0d0d0d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030404040404040402140404040404050
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304040404050316400510041d0d0d0d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003174000000f3000000000030404050d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000310000e1e1000042e1520000000051d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000451304000500031000051d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031000400000000000051003242d152d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031000000005131000051003040f14050
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032424242425232424252000000000051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c000000000f300c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030404040503040404050003100000051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c00000e1e10000c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003100000051d300000051003242d14252
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c00000000491b100c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031000000d1d100440051003040f150d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c000040000000000c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031000000f1f1001400510000000051d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0000000c000c0c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000310000005131000000510031000051d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c000c0c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000324242005232e14200521432424252d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c000c0c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d0d0d0000000004100000041d0d0d0d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c000c0c0c0c0c0c0c051
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d021d0d0d0d0d0d0d0d0d0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032424242424242104242424242424252
d0d0d0d0d0d0d0d0e3d0d0d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
d0d0d0d0d0d04100000041d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
@ -2143,7 +2218,7 @@ __label__
77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
__gff__
000000c0c0c0c0c0c0c0c0c0c0c00000000000c0c0c0c0c0c0c0c0c020202020004000c0c0c0c0c0c008080800000000404000000000080808080808c0c0c0c000000000080808080808080800000008000000000808080808080808000000000008080808080808080808080000000000080808080808080808080800000000
000000c0c0c0c0c0c0c0c0c0c0c00000000000c0c0c0c0c0c0c0c0c0202020200040c0c0c0c0c0c0c008080800000000404000000000080808080808c0c0c0c000000000080808080808080800000008000000000808080808080808000000000008080808080808080808080000000000080808080808080808080800000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1203040404050d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d03043e0a040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
@ -2162,22 +2237,22 @@ __map__
0d0d0d0d0d0d0d0d0d080d0d0d0d0d0d0d0d230024242425141300000000150d0d0d134f1e00151414141400140d0d0d0d0d0d0d0d13000006240024070000150d2324240024242513000040441500140d0d0d0d0d0d0d0d0d080d0d0d0d0d0d0100000000000000062424242514140d0100001d1d483f230024242424242425
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1400140d0d0d0d2324242424250d0d0d13000000000000000000140d0d0d0d0d0d0d0d23242425140014232424250d0d0d1400140d0d13000000001500120d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1423242424243c250d0d0d0d0d0d0d0d14131f1f00000000140d0d0d0d0d0d
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424251414141414140d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d010d0d0d232424242425140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424251414140d0d0d0d0d0d
0d0d0d0d0d0d0d0d030404040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d120d0d0d03040404040404041204040404040405
0d03040404040405133d00001c00150d0d0d0d0d0d0d0d0d0304043e0404050d0d0d0d0d030404000404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d14030404040404041400140d0d130c0c0c0c0c0c0c000c0c0c0c0c0c15
0d13001c1c004f0000421e1d1f00150d0d0d0d0d0d0d0d0d130000000000150d0d0d0d0317420000004816050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d141413000000000000001e003f0d130c0c0c0c0c0c0c000c0c0c0c0c0c15
0d13001c1c1d00150000001c000000010d03040404040405130000000000150d0d0d141300191b1d191b0015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d030417001d1d1d1d1d0015140d0d130c0c0c0c0c0c0c000c0c0c0c0c0c15
0d13001f1f000015131e1e1f1d1d150d0d13460044004c15130000000000150d0d3d001e0042001f0048001e003f0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d130000001c1c421c1c00150d0d0d130c0c0c0c0c0c0c000c0c0c0c0c0c15
0d13000000000015130000001c1c150d0d131d1d1e1d1d152324241d2424250d0d140023240700410006242500140d0d0d0d0d0d030404040404050d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001d1d1f1f001c1c00150d0d0d130c0c0c0c0c0c1d001d00000c0c0c15
0927271b1e1e0015130014001c1c150d0d131c3d001c1c000000001f040404050d1400000023243c2425000000140d0d0d0d0d0d130000001c000000000d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c0000001c1c00150d0d0d130c0c0c0c0c3d1c001c00000c0c0c15
0d131c1c00000000000000001c1c150d0d131f1f1e1f1f1514141300280000150d14000000001f1f1f00000000140d0d0d141414130028001c4516050014140d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c001e001c1c00150d0d0d130c0c0c0c0c0c1f1f1f0c000c0c0c15
0d131c1c0014001513001e1e1927270b0d1300004100001514141300000000010d144f47411400000014000000140d0d01000000000000001f0000150000001200000000000000000000000000000000000000000000000000000000000000000d0d13001c1c0000001c1c00150d0d0d130c0c0c0c0c0c00000000000c0c0c15
0d131c1c00000015130000000000150d0927271b001927270b031741280000150d14434b491400000014000000140d0d0d14141413002800000000151414140d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c001d1d1f1f00150d0d0d0100000000000000410000000c0c0c15
0d131f1f1d1e1e151300001d1d00150d0d131f1c001c1c151f130000004900150d03040404040000000304040405140d0d0d0d0d13000000000006250d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c481c1c000000150d0d0d130c0c0c0c0c0c0c0c0c0c0c0c0c0c15
120000001c00000013001f1c1c00150d0d13001f001f1c0000131d1d000000150d1300000000000003170000000000120d0d0d0d232424242424250d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d1413001f1f1f1f1f000624250d0d0d130c0c0c0c0c0c0c0c0c0c0c0c0c0c15
0d13001d1f1e4800004f001c1c00150d0d13000000001f1500232424242424250d13000000001d1d1d0000000015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000010000000000000000001514140d0d0d130c0c0c0c0c0c0c0c0c0c0c0c0c0c15
0d13001c00003f15232424242424250d0d1300000000001500140d0d0d0d0d0d0d130000000625031700000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d14232424242424242425140d0d0d0d130c0c0c0c0c0c0c0c0c0c0c0c0c0c15
0d232424242424250d0d0d0d0d0d0d0d0d2324242424242500140d0d0d0d0d0d0d130000062503170000000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d130c0c0c0c0c0c0c0c0c0c0c0c0c0c15
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d232424250d23242424242424250d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424242424242424242424242425
0d0d0d0d0d0d0d0d030404040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d120d0d0d00000000000000000000000000000000
0d03040404040405133d00001c00150d0d0d0d0d0d0d0d0d0304043e0404050d0d0d0d0d030404000404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d14030404040404041400140d0d00000000000000000000000000000000
0d13001c1c004f0000421e1d1f00150d0d0d0d0d0d0d0d0d130000000000150d0d0d0d0317420000004816050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d141413000000000000001e003f0d00000000000000000000000000000000
0d13001c1c1d00150000001c000000010d03040404040405130000000000150d0d0d141300191b1d191b0015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d030417001d1d1d1d1d0015140d0d00000000000000000000000000000000
0d13001f1f000015131e1e1f1d1d150d0d13460044004c15130000000000150d0d3d001e0042001f0048001e003f0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d130000001c1c421c1c00150d0d0d00000000000000000000000000000000
0d13000000000015130000001c1c150d0d131d1d1e1d1d152324241d2424250d0d140023240700410006242500140d0d0d0d0d0d030404040404050d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001d1d1f1f001c1c00150d0d0d00000000000000000000000000000000
0927271b1e1e0015130014001c1c150d0d131c3d001c1c000000001f040404050d1400000023243c2425000000140d0d0d0d0d0d130000001c000000000d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c0000001c1c00150d0d0d00000000000000000000000000000000
0d131c1c00000000000000001c1c150d0d131f1f1e1f1f1514141300280000150d14000000001f1f1f00000000140d0d0d141414130028001c4516050014140d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c001e001c1c00150d0d0d00000000000000000000000000000000
0d131c1c0014001513001e1e1927270b0d1300004100001514141300000000010d144f47411400000014000000140d0d01000000000000001f0000150000001200000000000000000000000000000000000000000000000000000000000000000d0d13001c1c0000001c1c00150d0d0d00000000000000000000000000000000
0d131c1c00000015130000000000150d0927271b001927270b031741280000150d14434b491400000014000000140d0d0d14141413002800000000151414140d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c001d1d1f1f00150d0d0d00000000000000000000000000000000
0d131f1f1d1e1e151300001d1d00150d0d131f1c001c1c151f130000004900150d03040404040000000304040405140d0d0d0d0d13000000000006250d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c481c1c000000150d0d0d00000000000000000000000000000000
120000001c00000013001f1c1c00150d0d13001f001f1c0000131d1d000000150d1300000000000003170000000000120d0d0d0d232424242424250d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d1413001f1f1f1f1f000624250d0d0d00000000000000000000000000000000
0d13001d1f1e4800004f001c1c00150d0d13000000001f1500232424242424250d13000000001d1d1d0000000015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000010000000000000000001514140d0d0d00000000000000000000000000000000
0d13001c00003f15232424242424250d0d1300000000001500140d0d0d0d0d0d0d130000000625031700000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d14232424242424242425140d0d0d0d00000000000000000000000000000000
0d232424242424250d0d0d0d0d0d0d0d0d2324242424242500140d0d0d0d0d0d0d130000062503170000000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d232424250d23242424242424250d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000
__sfx__
00110000250002500025030250302503000000230350000023030230302303023030230302303023030230302103021030210302103021030210300000000000177401774017740177311e7501e7501e7501e750
00110000290202a0212a0202a0202a0202a02025030250052503025030250302503025030250302503025030250302503025030250302503225030230322504526030260302a040000002d0402d0402d0402d040