Compare commits

..

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

@ -1,20 +1,21 @@
pico-8 cartridge // http://www.pico-8.com pico-8 cartridge // http://www.pico-8.com
version 41 version 39
__lua__ __lua__
-- setup -- setup
modules={} modules={}
real_modules={} real_modules={}
frame=0
function _init() function _init()
-- printh("restarting") -- printh("restarting")
_doall"init" _doall("init")
end end
function _update60() function _update()
_doall"update" end frame+=1
if (frame%1==0) _doall("update") end
function _draw() function _draw()
_doall"draw" _doall("draw") end
end
function music_on() function music_on()
if (stat(54) ~= 0) music(0) if (stat(54) ~= 0) music(0)
@ -96,10 +97,11 @@ function linefill(ax,ay,bx,by,r,c)
local _x1,_y1=x1,y1 local _x1,_y1=x1,y1
if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0 if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0
local dx=(x1-x0)/(y1-y0) local dx=(x1-x0)/(y1-y0)
if(y0<0) x0-=y0*dx y0=-1
local cy0=y0\1+1 local cy0=y0\1+1
-- sub-pix shift -- sub-pix shift
x0+=(cy0-y0)*dx x0+=(cy0-y0)*dx
for y=cy0,min(y1\1,127) do for y=y0\1+1,min(y1\1,127) do
-- open span? -- open span?
local span=spans[y] local span=spans[y]
if (span) rectfill(x0,y,span,y) if (span) rectfill(x0,y,span,y)
@ -123,6 +125,15 @@ function sgn0(x)
return x!=0 and sgn(x) or 0 return x!=0 and sgn(x) or 0
end 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) function _mnmx(x,y)
if (x>y)return y,x if (x>y)return y,x
return x,y return x,y
@ -130,18 +141,20 @@ end
function _rast( function _rast(
xys,x0,y0,x1,y1 xs,ys,x0,y0,x1,y1
) )
local function _add() local function _add()
local n=#xys local n=#xs
local xy0={x0,y0} if (n==0 or xs[n]!=x0 or ys[n]!=y0) add(xs,x0) add(ys,y0)
if (n==0 or not _anch_eq(xys[n],xy0)) add(xys,xy0)
end end
local dx,dy=abs(x1-x0),abs(y1-y0) 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 err local done,err
if dx>dy then if dx>dy then
err=dx/2.0 err=dx/2.0
while x0!=x1 do while x0!=x1 do
@ -253,9 +266,9 @@ end
title={} title={}
add(modules,title) add(modules,title)
lvlshimmer = split"4,9,10,10,9" lvlshimmer = {4,9,10,10,9}
function title:draw() function title:draw()
cls"0" cls(0)
-- this is right for 72x32 -- this is right for 72x32
spr(96,28,56,9,2) spr(96,28,56,9,2)
print("pyrex",32,73,7) print("pyrex",32,73,7)
@ -277,7 +290,7 @@ end
function title:update() function title:update()
if (btnp"0") start_level-=1 if (btnp"0") start_level-=1
if (btnp"1") start_level+=1 if (btnp"1") start_level+=1
start_level%=max_level+1 start_level%=(max_level+1)
if btn"3" and not wiped then if btn"3" and not wiped then
wrongbleep:bleep() wrongbleep:bleep()
if (wrongbleep:adequately_warned()) then if (wrongbleep:adequately_warned()) then
@ -324,25 +337,10 @@ function level:advance()
end end
normpal = {[1]=0,[8]=0,[14]=0} normpal = {[1]=0,[8]=0,[14]=0}
ixes=split"5,3,15,10,13,4,9"
easy=split"1,131,6,129,6,141,12"
moderate=split"3,139,15,5,6,4,9"
hard=split"134,135,142,134,6,142,140"
brutal=split"8,137,9,130,6,13,138"
function level:draw3()
local p=easy
if (self.ix>=6) p=moderate
if (self.ix>=12) p=hard
if (self.ix>=21) p=brutal
for i=1,7 do
pal(ixes[i],p[i],1)
end
end
function level:draw() function level:draw()
cls(5)
fillp()
pal(normpal) pal(normpal)
cls"10"
map( map(
self.bigx*16,self.bigy*16, self.bigx*16,self.bigy*16,
0,0,16,16, 0,0,16,16,
@ -432,9 +430,8 @@ end
function level:recollide_reanchor() function level:recollide_reanchor()
self._coll={} self._coll={}
for mx=0,15 do for mx=0,15 do
local kmx=mx..","
for my=0,15 do for my=0,15 do
local mxy=kmx..my local mxy=_mix{mx,my}
self._coll[mxy]= self._coll[mxy]=
fget(self:_mget(mx,my),7) or fget(self:_mget(mx,my),7) or
self._crates[mxy] self._crates[mxy]
@ -442,24 +439,18 @@ function level:recollide_reanchor()
end end
local anch_new={} local anch_new={}
for dxy in all(gsv[[-1`-1 for dxy in all{{-1,-1},{1,-1},{-1,1},{1,1}} do
1`-1
-1`1
1`1]]) do
local dx,dy=unpack(dxy) local dx,dy=unpack(dxy)
local c=self._coll assert(dx!=0 and dy!=0)
for mx0=0,15 do for mx0=0,15 do
local mx1=mx0+dx
local kmx0,kmx1=mx0..",",mx1..","
for my0=0,15 do for my0=0,15 do
local my1=my0+dy local mx1,my1=mx0+dx,my0+dy
-- bypass mcoll for MEGA SPEED
if ( if (
c[kmx0..my0] and not self:get_crate(mx0,my0) and self:mcoll(mx0,my0) and not self:get_crate(mx0,my0) and
not c[kmx0..my1] and not self:mcoll(mx0,my1) and
not c[kmx1..my0] and not self:mcoll(mx1,my0) and
not c[kmx1..my1] not self:mcoll(mx1,my1)
) then ) then
local key=_mix{"GEOM",mx0,my0,dx,dy} local key=_mix{"GEOM",mx0,my0,dx,dy}
anch_new[key]= { anch_new[key]= {
@ -503,6 +494,10 @@ function level:recollide_reanchor()
if player.rope then if player.rope then
player.rope:experience_anchor_moves(moves) player.rope:experience_anchor_moves(moves)
end end
for point in self:anchor_points() do
point.moved=nil
end
end end
function level:win_at(mx,my) function level:win_at(mx,my)
@ -563,8 +558,7 @@ function level:spawn_exit()
assert(spawned) assert(spawned)
end end
function level:mcoll(mxy) function level:mcoll(mx,my)
local mx,my=unpack(mxy)
if ((mx | my) & 0xFFF0!=0) return true if ((mx | my) & 0xFFF0!=0) return true
return self._coll[_mix{mx,my}] return self._coll[_mix{mx,my}]
end end
@ -639,17 +633,15 @@ end
ropecheck=split"-0.6,0.4,0.4" ropecheck=split"-0.6,0.4,0.4"
-- argument "o" is a rope operation:
-- array of [mx0,my0,dmx,dmy]
function level:can_move( 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 local mx1,my1=mx0+dmx,my0+dmy
if (is_player and self:win_at(mx1,my1)) return true 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 (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 if player.rope then
local w,h=1.2,0.2 local w,h=1.2,0.2
@ -660,12 +652,7 @@ function level:can_move(
return true return true
end end
-- argument is a rope operation: function level:tug_crate(mx0,my0,dmx,dmy)
-- 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)
local mxy0=_mix{mx0,my0} local mxy0=_mix{mx0,my0}
local existing=self._crates[mxy0] local existing=self._crates[mxy0]
if (not existing) return if (not existing) return
@ -684,47 +671,6 @@ function level_tug_crate(t)
self._crates[_mix{mx1,my1}]=existing self._crates[_mix{mx1,my1}]=existing
end end
-->8
-- particles
particles={}
add(real_modules,particles)
function particles:init()
self.a={}
end
function particles:update()
local a2={}
for i in all(particles.a) do
i.t+=1
i[1]+=i.dx
i[2]+=i.dy
i.dy+=i.ddy
if (i.t<i.mt) add(a2,i)
end
particles.a=a2
end
function particles:move(x,y,dx,dy)
for i=0,1,0.25 do
local px=(x+dx*i)*8+2
local py=(y+dy*i)*8+4
px+=rnd"4"
py+=rnd"6"
add(self.a,{
px,py,6,
dx=rnd()-0.5,
dy=-rnd(0.5),
ddy=0.02,
t=-rnd"4",
mt=4+rnd"4"
})
end
end
function particles:draw()
for i in all(particles.a) do
if (i.t>0) pset(unpack(i))
end
end
-->8 -->8
--player handling --player handling
player={} player={}
@ -788,13 +734,12 @@ function player:update()
else else
local x,y=self.x,self.y local x,y=self.x,self.y
local function try_move(dx,dy,f) 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.todo=f
self.cooldown=8 self.cooldown=3
local t=f[#f] local t=f[#f]
t.x=x+dx t.x=x+dx
t.y=y+dy t.y=y+dy
particles:move(x,y,dx,dy)
return return
end end
wrongbleep:bleep() wrongbleep:bleep()
@ -811,7 +756,7 @@ function player:update()
local dx,dy=self.orientx,self.orienty local dx,dy=self.orientx,self.orienty
if (dy!=0) dx=0 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( self.rope=rope:new(
{x+0.5-dx*0.5,y+0.5-dy*0.5}, {x+0.5-dx*0.5,y+0.5-dy*0.5},
@ -857,7 +802,7 @@ end
function player:_vanish_if_requested() function player:_vanish_if_requested()
if kbd:btn(5) then if kbd:btn(5) then
self.vanish_frame+=0.5 self.vanish_frame+=1
if (self.fall_frame>0 or self.vanish_frame>20) then if (self.fall_frame>0 or self.vanish_frame>20) then
self.rope=nil self.rope=nil
@ -866,7 +811,7 @@ function player:_vanish_if_requested()
self.vanish_frame=20 self.vanish_frame=20
end end
else else
self.vanish_frame-=0.5 self.vanish_frame-=1
end end
self.vanish_frame=max(self.vanish_frame,0) self.vanish_frame=max(self.vanish_frame,0)
@ -917,7 +862,7 @@ function player:draw()
-- vanish colors -- vanish colors
local vanish=split"13,15,14,5,4,12,2,3,9,10" local vanish=split"13,15,14,5,4,12,2,3,9,10"
for i,ilc in ipairs(vanish) do for i,ilc in ipairs(vanish) do
if (vanish_level>i/#vanish) pal(ilc,10) if (vanish_level>i/#vanish) pal(ilc,5)
end end
if (self.fall_frame>3) local zc=@0x5f00&0xf0 for i=0x5f00,0x5f0c,4 do poke4(i,0x0505.0505) end poke(0x5f00,zc|0x01) if (self.fall_frame>3) local zc=@0x5f00&0xf0 for i=0x5f00,0x5f0c,4 do poke4(i,0x0505.0505) end poke(0x5f00,zc|0x01)
@ -927,7 +872,7 @@ function player:draw()
if (self.orientx==1) rx+=6 if (self.orientx==1) rx+=6
if self.rope then 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 if rx_adj then
local drx,dry=rx_adj-rx,ry_adj-ry local drx,dry=rx_adj-rx,ry_adj-ry
rx,ry=rx+drx,ry+dry rx,ry=rx+drx,ry+dry
@ -935,16 +880,17 @@ function player:draw()
end end
end end
setpal()
if self.orientx==-1 then if self.orientx==-1 then
setpal()
spr(16,px+6,py-2,1,1) spr(16,px+6,py-2,1,1)
spr(17,px+1,py,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) spr(head,px-3,py-3,1,1)
else else
setpal()
spr(16,px-6,py-2,1,1,true) spr(16,px-6,py-2,1,1,true)
spr(17,px-1,py,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) spr(head,px+3,py-3,1,1,true)
end end
pal() pal()
@ -991,7 +937,13 @@ function rope:update()
elseif self.state.name=="latched" then elseif self.state.name=="latched" then
if (not self.latch) wrongbleep:bleep(5) self:destroy() return 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() if (not self:_check_pinch()) self:destroy()
elseif self.state.name=="destroy" then -- destroy elseif self.state.name=="destroy" then -- destroy
@ -1007,100 +959,125 @@ function rope:destroy(reelin)
self.state={name="destroy",frame=0,reelin=reelin} self.state={name="destroy",frame=0,reelin=reelin}
end end
function rope:_resegment(points,artificial_pxy,cb) function rope:affected_src_xy(artificial_px,artificial_py)
local n,perc_to_show,from_end=self.state.name,1.0 -- 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=="done") return
if (n=="cast") perc_to_show=self.state.frame/2 if (n=="cast") perc_to_show=self.state.frame/2
if (n=="destroy") perc_to_show=(1.0-self.state.frame/4)^2 if (n=="destroy") perc_to_show=(1.0-self.state.frame/4)^2
if (self.state.reelin) from_end=true if (self.state.reelin) from_end=true
local artificial_px,artificial_py=unpack(artificial_pxy)
points[#points]={x=artificial_px,y=artificial_py} points[#points]={x=artificial_px,y=artificial_py}
local len=0 local len=0
for i=1,#points-1 do for i=1,#points-1 do
len+=distance(points[i],points[i+1]) len+=distance(points[i],points[i+1])
end end
local len_to_show,ia,iz,istep=perc_to_show*len,#points-1,1,-1 local len_to_show=perc_to_show*len
if (from_end) ia,iz,istep=iz,ia,1
for i=ia,iz,istep do local len_cumulative=0
local src,dst=points[i],points[i+1] local ia,iz,istep=#points-1,1,-1
local x,y=dst.x,dst.y if (from_end) ia,iz,istep=1,#points-1,1
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 function colorh(ix) local function colorh(ix)
color(8) color(8)
if (highlight==ix) color(12) if (highlight==ix) color(12)
end end
for i=ia,iz,istep do
local src=points[i]
local dst=points[i+1]
self:_resegment(points,artificial_pxy, local x,y=dst.x,dst.y
function(x,y,dx,dy,i) local dx,dy=src.x-x,src.y-y
colorh(i)
foreach(TONGUE_SEGS,function(row) local len_here=len_to_show-len_cumulative
local d0,d1,w=unpack(row) local dist_base=distance_dxy(dx,dy)
linefill(x+d0*dx,y+d0*dy,x+d1*dx,y+d1*dy,w) len_cumulative+=dist_base
end)
circfill(x+dx,y+dy,1) 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
colorh(i)
local function lf(d0,d1,w)
linefill(x+d0*dx,y+d0*dy,x+d1*dx,y+d1*dy,w)
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 end
)
-- draw latch -- draw latch
local l=self.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 function rfsplit(x) rectfill(unpack(split(x))) end
local ldx,ldy=l.dx,l.dy
colorh(0) colorh(0)
camera(-l.rec.px,-l.rec.py) camera(-l.rec.px,-l.rec.py)
if (l.dx==-1) rfsplit"0,3,2,4" if (ldx==-1) rfsplit"0,3,2,4"
if (l.dx==1) rfsplit"5,3,7,4" if (ldx==1) rfsplit"5,3,7,4"
if (l.dy==-1) rfsplit"3,0,4,2" if (ldy==-1) rfsplit"3,0,4,2"
if (l.dy==1) rfsplit"3,5,4,7" if (ldy==1) rfsplit"3,5,4,7"
camera() camera()
color() color()
end end
-- hypothetical -- hypothetical
local time=t()-self.flicker_t local time=t()-self.flicker_t
local flicker_on=time%0.5>0.25 if n=="latched" and time>0 and not level:busy() then
if self:latched() and time>0 and not level:busy() then if time%0.5>0.25 then
if flicker_on then for o in all(hypo_ops) do
foreach(hypo_ops, function(o)
local mx0,my0,dmx,dmy=unpack(o) local mx0,my0,dmx,dmy=unpack(o)
spr(14,(mx0+dmx)*8,(my0+dmy)*8) local px1,py1=(mx0+dmx)*8,(my0+dmy)*8
end) spr(14,px1,py1)
end end
foreach(hypo_blocks, function(o) end
for o in all(hypo_blocks) do
local x,y,dx,dy=unpack(o) local x,y,dx,dy=unpack(o)
spr(34,8*x+4*dx,8*y+4*dy,1,1,flicker_on) spr(53,8*x+4*dx,8*y+4*dy,1,1,time%0.5>0.25)
end) end
end end
-- debug -- debug
@ -1181,7 +1158,7 @@ function rope:relax()
local adxy,position_new=calc_tension(n0,n1,n2) local adxy,position_new=calc_tension(n0,n1,n2)
local anch=level:anchor_at_tension(n1,adxy) local anch=level:anchor_at_tension(n1,adxy)
if not anch then if not anch or _anch_eq(n1,position_new) then
self:_drag(n1,position_new,{_anch_unpack(n1)}) self:_drag(n1,position_new,{_anch_unpack(n1)})
_anch_del(n1) _anch_del(n1)
else n0=n0.next end else n0=n0.next end
@ -1194,43 +1171,60 @@ function rope:_check_pinch()
local n0=self.src local n0=self.src
local qxys={} local qxs,qys={},{}
while true do while true do
local n1=n0.next local n1=n0.next
if (not n1) break if (not n1) break
local n0ax,n0ay=_anch_unpack(n0) local n0ax,n0ay=_anch_unpack(n0)
local n1ax,n1ay=_anch_unpack(n1) 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 n0=n1
end end
local function _possible_tiles(t) local function _possible_tiles(qx,qy)
local qx,qy=unpack(qxys[t]) local mx0=(qx-1)\2
local mx1=qx\2
local my0=(qy-1)\2
local my1=qy\2
local poss={} local poss={}
for mx=(qx-1)\2,qx\2 do for mx=mx0,mx1 do
for my=(qy-1)\2,qy\2 do for my=my0,my1 do
if (not level:mcoll{mx,my}) add(poss,{mx,my}) add(poss,{mx=mx,my=my})
end end
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 end
-- find cases where i move through an impassable zone -- find cases where i move through an impassable zone
for i=1,#qxys do for i=1,#qxs do
if (not _possible_tiles(i)()) return if (_blocked(qxs[i],qys[i])) return
end end
-- find cases where i am cut off diagonally -- find cases where i am cut off diagonally
for i=3,#qxys do for i=3,#qxs do
local qx1,qy1=unpack(qxys[i-1]) local qx1,qy1=qxs[i-1],qys[i-1]
if (qx1|qy1)&1==0 then if qx1%2==0 and qy1%2==0 then
local ok local ok
for m0 in _possible_tiles(i-2) do for m0 in all(_possible_tiles(qxs[i-2],qys[i-2])) do
for m2 in _possible_tiles(i) do for m2 in all(_possible_tiles(qxs[i],qys[i])) do
local mx0,my0=unpack(m0) local mx0,my0=m0.mx,m0.my
local mx2,my2=unpack(m2) local mx2,my2=m2.mx,m2.my
if (mx0==mx2 or my0==my2 or not level:mcoll{mx0,my2} or not level:mcoll{mx2,my0}) ok=true 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
end end
@ -1460,6 +1454,10 @@ function _which_side(xy,x0y0,x1y1)
return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0)) return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
end end
function distance_dxy(dx,dy)
return sqrt(dx*dx+dy*dy)
end
function distance(p1,p2) function distance(p1,p2)
local dx=p2.x-p1.x local dx=p2.x-p1.x
local dy=p2.y-p1.y local dy=p2.y-p1.y
@ -1542,19 +1540,22 @@ function rope:_tug(hypothetically)
local blocks = {} local blocks = {}
for i=#ancs-1,2,-1 do 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_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 for b in all(blocks_before_trash) do add(blocks, b) end
if #ops_before_trash>0 then if #ops_before_trash>0 then
ops=ops_before_trash ops_to_do=ops_before_trash
else else
local ops_after_trash,blocks_after_trash=self:_calc_push(ancs[i-2],ancs[i-1],ancs[i],ancs[i+1]) 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 for b in all(blocks_after_trash) do add(blocks,b) end
end end
local ops=ops_to_do
if #ops>0 then if #ops>0 then
if (hypothetically) return ancs,i-1,ops,blocks 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 return true
end end
end end
@ -1603,19 +1604,18 @@ function rope:_tug(hypothetically)
end end
if not invalid_move then if not invalid_move then
local mv = {mx0,my0,dmx,dmy} if level:can_move(false,mx0,my0,dmx,dmy,1,0) then
if level:can_move(false,mv,1,0) then if (hypothetically) return ancs,0,{{mx0,my0,dmx,dmy}},blocks
if (hypothetically) return ancs,0,{mv},blocks
level_tug_crate(mv) level:tug_crate(mx0,my0,dmx,dmy)
return true return true
else else
add(blocks, mv) add(blocks, {mx0,my0,dmx,dmy})
end end
end end
end end
if (hypothetically) return ancs,32767,{},blocks -- invalid if (hypothetically) return ancs,0,{},blocks
return return
end end
@ -1640,16 +1640,21 @@ function rope:_calc_push(
smy=-smy smy=-smy
end end
local dmx=1 -- maybe push right? local mx,dmx
if anch.adx==-1 and a0.x>an.x+7 then if anch.adx==-1 and a0.x>an.x+7 then
-- push left -- push left
ax0, dmx=ax0-1,-1 mx=ax0-1
elseif anch.adx!=1 or a0.x>=an.x-7 then dmx=-1
elseif anch.adx==1 and a0.x<an.x-7 then
-- push right
mx=ax0
dmx=1
else
return {} return {}
end end
for my=my0,my1,smy do for my=my0,my1,smy do
add(ops,{ax0,my,dmx,0}) add(ops,{mx,my,dmx,0})
end end
end end
@ -1661,28 +1666,40 @@ function rope:_calc_push(
smx=-smx smx=-smx
end end
local dmy=1 -- maybe push down? local my,dmy
if anch.ady==-1 and a0.y>an.y+6 then if anch.ady==-1 and a0.y>an.y+6 then
-- push up -- push up
ay0,dmy=ay0-1,-1 my=ay0-1
elseif anch.ady!=1 or a0.y>=an.y-6 then dmy=-1
elseif anch.ady==1 and a0.y<an.y-6 then
-- push down
my=ay0
dmy=1
else
return {} return {}
end end
for mx=mx0,mx1,smx do for mx=mx0,mx1,smx do
add(ops,{mx,ay0,0,dmy}) add(ops,{mx,my,0,dmy})
end end
end end
local ops2,blocked={},{} local ops2,blocked={},{}
for o in all(ops) do for o in all(ops) do
local mx,my=unpack(o) local mx,my,dmx,dmy=unpack(o)
if level:mcoll{mx,my} then if not level:mcoll(mx,my) then
if (not level:get_crate(mx, my)) break -- great!
if not level:can_move(false,o,0,0) then 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) add(blocked,o)
break break
end end
else
break
end
add(ops2,o) add(ops2,o)
end end
end end
@ -1950,28 +1967,28 @@ __gfx__
002222200000220000222220efe33eeeeeeeeeeeeee33efeeee33eeeeee33eeeff1111ffff111111ff1ff1ff111111ffdddddddd111111110cccccc033333333 002222200000220000222220efe33eeeeeeeeeeeeee33efeeee33eeeeee33eeeff1111ffff111111ff1ff1ff111111ffdddddddd111111110cccccc033333333
000222c002222c0000022200efeeee555e555e55e5eeeefee5eeeeffffeeee5effffffffffffffffff1ff1ffffffffffdddddddd111111110cc00cc033300333 000222c002222c0000022200efeeee555e555e55e5eeeefee5eeeeffffeeee5effffffffffffffffff1ff1ffffffffffdddddddd111111110cc00cc033300333
00000cc00000cc0000000cc0efe33e5eeeeeeeeee5e33efee5e33efeefe33e5e1ffffff11fffffffff1ff1fffffffff1dddddddd111111110000000033300333 00000cc00000cc0000000cc0efe33e5eeeeeeeeee5e33efee5e33efeefe33e5e1ffffff11fffffffff1ff1fffffffff1dddddddd111111110000000033300333
0000ff000000000000000000efe33e5e11111111e5e33efee5e33efeefe33e5eff1ff1ffffffffffffffffffffffffff88888888aaaaaaaaaaaaaaaa88888888 0000ff000000000000000000efe33e5e11111111e5e33efee5e33efeefe33e5eff1ff1ffffffffffffffffffffffffff88888888555555555555555588888888
000f00f0000000000aa00aa0efe33eee11ffff11eee33efeeee33effffe33e5eff1ff1ffffffffffffffffffffffffff88888888aa88aa88aa88aa8888888888 000f00f0000000000aa00aa0efe33eee11ffff11eee33efeeee33effffe33e5eff1ff1ffffffffffffffffffffffffff88888888558855885588558888888888
00d0000f000000000aaaaaa0efe33e5e1ff11ff1e5e33efee5e33eeeeee33eeeff1ff1fffff11111ffffffff11111fff88888888888888888888888888888888 00d0000f000000000aaaaaa0efe33e5e1ff11ff1e5e33efee5e33eeeeee33eeeff1ff1fffff11111ffffffff11111fff88888888888888888888888888888888
00d0d00f00c040500aaaaaa0efeeee5e1f1111f1e5eeeefee5e333e333333e5eff1ff1fffff1ffffff1111ffffff1fff88888888888888888888888888888888 00d0d00f00c040500aaaaaa0efeeee5e1f1111f1e5eeeefee5e333e333333e5eff1ff1fffff1ffffff1111ffffff1fff88888888888888888888888888888888
00dd00ee00c4455000999900efe33e5e1f1111f1e5e33efee5e333e333333e5eff1111fffff1ffffff1ff1ffffff1fff88888888888888888888888888888888 00dd00ee00c4455000999900efe33e5e1f1111f1e5e33efee5e333e333333e5eff1111fffff1ffffff1ff1ffffff1fff88888888888888888888888888888888
00000ee00c44455500aaaa00efe33eee1ff11ff1eee33efeeeeeeeeeeeeeee5efffffffffff11111ff1ff1ff11111fff88888888888888888888888888888888 00000ee00c44455500aaaa00efe33eee1ff11ff1eee33efeeeeeeeeeeeeeee5efffffffffff11111ff1ff1ff11111fff88888888888888888888888888888888
00eeee000c004005000aa000efe33e5e11ffff11e5e33efee5555e555e555e5effffffffffffffffff1ff1ffffffffff888888888888888888aa88aa88aa88aa 00eeee000c004005000aa000efe33e5e11ffff11e5e33efee5555e555e555e5effffffffffffffffff1ff1ffffffffff88888888888888888855885588558855
eeee0000cc04405500444400efeeee5e11111111e5eeeefeeeeeeeeeeeeeeeeeffffffffffffffffff1ff1ffffffffff8888888888888888aaaaaaaaaaaaaaaa eeee0000cc04405500444400efeeee5e11111111e5eeeefeeeeeeeeeeeeeeeeeffffffffffffffffff1ff1ffffffffff88888888888888885555555555555555
00000000000a900000000000efe33eeeeeeeeeeeeee33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000 00000000000a90005bbbbbb3efe33eeeeeeeeeeeeee33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000aaaaaaa910000000000efe33e5555e555e555e33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000 00000aaaaaaa9100bbbbbbbbefe33e5555e555e555e33efeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
0000aaaaaa1a911000a00200efe33eeeeeeeeeeeeee33efeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000 0000aaaaaa1a9110bbb7aabbefe33eeeeeeeeeeeeee33efeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000
0aaaaaaaaa1a9111000a2000efe333e3333e333e33333efeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000 0aaaaaaaaa1a9111bbbaabbbefe333e3333e333e33333efeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000
0aaaaaaaa41a91a10002a000efee33e3333e333e3333eefeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000 0aaaaaaaa41a91a1bbaaabbbefee33e3333e333e3333eefeff1ff1ffffffffffff1ff1ff00000000000000000000000000000000000000000000000000000000
0a000aa4441a91a100200a00effeeeeeeeeeeeeeeeeeeffeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000 0a000aa4441a91a1bbabbbbbeffeeeeeeeeeeeeeeeeeeffeff1ff1ff11111111ff1111ff00000000000000000000000000000000000000000000000000000000
00a0044449a110a100000000eeffffffffffffffffffffeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000 00a0044449a110a1bbbbbbbbeeffffffffffffffffffffeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
000aa1119911111000000000eeeeeeeeeeeeeeeeeeeeeeeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000 000aa111991111103bbbbbb3eeeeeeeeeeeeeeeeeeeeeeeeff1ff1ffffffffffffffffff00000000000000000000000000000000000000000000000000000000
0000000099100000f765000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111999999111111111 0000000099100000f765000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111999999111111111
00000000990000007700000000000000000000000000000000000000000000000000000000000000000000000000000019911991999999911999999119999999 00000000990000007700000000000000000000000000000000000000000000000000000000000000000000000000000019911991999999911999999119999999
00000000990000006060000000000000000000000000000000000000000000000000000000000000000000000000000019977991999999911999999119999999 00000000990000006060000000000000000bc0000090020000000000000000000000000000000000000000000000000019977991999999911999999119999999
00000000090000005005000000000000000000000000000000000000000000000000000000000000000000000000000019911991999117111991199111711999 00000000090000005005000000bbcc00000bc0000009200000000000000000000000000000000000000000000000000019911991999117111991199111711999
00000000aa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000019911991999117111991199111711999 00000000aa0000000000000000ccbb00000cb0000002900000000000000000000000000000000000000000000000000019911991999117111991199111711999
0000000077a000000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991999999911997799119999999 0000000077a000000000000000000000000cb0000020090000000000000000000000000000000000000000000000000019999991999999911997799119999999
00000007777a00000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991999999911991199119999999 00000007777a00000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991999999911991199119999999
00044444444444000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991111111111111111111111111 00044444444444000000000000000000000000000000000000000000000000000000000000000000000000000000000019999991111111111111111111111111
44444444444004444444444444400444444444444440044444444444444004444444444444400444444444444440044444444444444004444444444444400444 44444444444004444444444444400444444444444440044444444444444004444444444444400444444444444440044444444444444004444444444444400444
@ -2006,38 +2023,38 @@ eeee0000cc04405500444400efeeee5e11111111e5eeeefeeeeeeeeeeeeeeeeeffffffffffffffff
00880880880880880880880aaaa0aaa0aaaa0aa0aa0aa0aaaa0aaaa0aa0aa0aaaaa0aa0a00000000000000000000000000000000000000000000000000000000 00880880880880880880880aaaa0aaa0aaaa0aa0aa0aa0aaaa0aaaa0aa0aa0aaaaa0aa0a00000000000000000000000000000000000000000000000000000000
00880888880880888880880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00880888880880888880880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000888888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000888888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d0d0d0304040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d030404050d0d0d0d0d0d0d0d0d0d0d0d0411041d0d0d0d0d0d0d0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030404040404040402140404040404050
d0d0d0310000000051d0d0d0d0d0d0d0d0d0d0d0d0d0410041d0d0d0d0d0d0d0304040404050316400510041d0d0d0d0d0d030404040400040404040404450d0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000010000000c1d000000000d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
d0d0d0320042420052d0d0d0d0d0d0d0d0d0d0d0d0d0410041d0d0d0d0d0d0d0317400000051000000000030404050d0d0d031000000000000000000000051d0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0c1c100c1d000c1c100d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
d0d0d0300040400050d0d0d0d0d0d0d0d0d0d030405030003040404050d0d0d0310000e1e1000042e1520000000051d0d0d032004242424200424242420052d0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0c1c300c1c100c1c300c1c1c1c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
d0d0413100000000614040404050d0d0d0d0d031005131000000000051d0d0d0100000000451304000500031000051d0d0304000405030400040503040004050 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0c1a400f10000c1a400f10000c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
100000000000040000e300000051d0d0d0d0d03100d1d100d1d1820051d0d0d031000400000000000051003242d152d0d0310000005131000000513100000051 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0c1000000c1c1c1000000c100c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
d0d0413270000000000000000051d0d0d0d0d0d300f1f10014c1f30051d0d0d031000000005131000051003040f14050d0318200825131820082513100000051 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0c1c1c1c1c1c1c1c1c1c1c100c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c0c000c0c0c0c0c0c051
d0d00000e1000000d10000040051d0d0d0d0d0310051310082f1820051d0d0d032424242425232424252000000000051d0310000605231000000513270000051 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0c1c1c1c1c1c1c1c1c1c100c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c000000000f300c0c0c0c0c0c051
d030005031e1d100c100d1d1005141d0d0d0d031005131000000000051d0d0d030404040503040404050003100000051d0324200524132420042524132424252 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0d0c1000000000000000000c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c00000e1e10000c0c0c0c0c0c051
d03100513100c100c100c100605241d0d0d0d032005232424200d14252d0d0d03100000051d300000051003242d14252d04100f400000000f400410000000021 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0d0c100c1c1c1c1c1c1c1c1c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c00000000491b100c0c0c0c0c051
d03100513100c100c100c10051304050d0d0d030005030404000c140504141d031000000d1d100440051003040f150d0d0304000405030400040503040004050 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0d0c100c1c100000000c1c1c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c000040000000000c0c0c0c0c051
d03100513100f1e1f1e1f10051310051d0d0d0310000000000a4f1000000002131000000f1f1001400510000000051d0d03100000051310000005131e100e151 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0c1c100c1c100c1c100c1c1c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0000000c000c0c0c0c0c0c0c051
d0310051310000000000000000000051d0d0d0324252324242424242524141d0310000005131000000510031000051d0d02400e100000000e100000000e10051 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0c1c300c1c100c1c300c1c1c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c000c0c0c0c0c0c0c051
d0320052324242424242424252310051d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0324242005232e14200521432424252d0d0310000005131000000513100000051 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0c13400f10000c1a400f1000000210000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c000c0c0c0c0c0c0c051
d0410041d0d0d0d0d0d0d0d0d0324252d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0000000004100000041d0d0d0d0d0324242425232424242523242424252 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0c1000000c1c1c1000000c1c1d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c0c0c0c0c0c000c0c0c0c0c0c0c051
d0d021d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d021d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000d0d0c1c1c1c1c1c1c1c1c1c1c1d0d0d00000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032424242424242104242424242424252
d0d0d0d0d0d0d0d0e3d0d0d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 d0d0d0d0d0d0d0d0e3d0d0d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
d0d0d0d0d0d04100000041d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 d0d0d0d0d0d04100000041d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
@ -2201,7 +2218,7 @@ __label__
77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777 77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777
__gff__ __gff__
000000c0c0c0c0c0c0c0c0c0c0c00000000000c0c0c0c0c0c0c0c0c020202020404000c0c0c0c0c0c008080800000000404000000000080808080808c0c0c0c000000000080808080808080800000008000000000808080808080808000000000008080808080808080808080000000000080808080808080808080800000000 000000c0c0c0c0c0c0c0c0c0c0c00000000000c0c0c0c0c0c0c0c0c0202020200040c0c0c0c0c0c0c008080800000000404000000000080808080808c0c0c0c000000000080808080808080800000008000000000808080808080808000000000008080808080808080808080000000000080808080808080808080800000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__ __map__
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1203040404050d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d03043e0a040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d 0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1203040404050d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d03043e0a040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d
@ -2220,22 +2237,22 @@ __map__
0d0d0d0d0d0d0d0d0d080d0d0d0d0d0d0d0d230024242425141300000000150d0d0d134f1e00151414141400140d0d0d0d0d0d0d0d13000006240024070000150d2324240024242513000040441500140d0d0d0d0d0d0d0d0d080d0d0d0d0d0d0100000000000000062424242514140d0100001d1d483f230024242424242425 0d0d0d0d0d0d0d0d0d080d0d0d0d0d0d0d0d230024242425141300000000150d0d0d134f1e00151414141400140d0d0d0d0d0d0d0d13000006240024070000150d2324240024242513000040441500140d0d0d0d0d0d0d0d0d080d0d0d0d0d0d0100000000000000062424242514140d0100001d1d483f230024242424242425
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1400140d0d0d0d2324242424250d0d0d13000000000000000000140d0d0d0d0d0d0d0d23242425140014232424250d0d0d1400140d0d13000000001500120d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1423242424243c250d0d0d0d0d0d0d0d14131f1f00000000140d0d0d0d0d0d 0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1400140d0d0d0d2324242424250d0d0d13000000000000000000140d0d0d0d0d0d0d0d23242425140014232424250d0d0d1400140d0d13000000001500120d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1423242424243c250d0d0d0d0d0d0d0d14131f1f00000000140d0d0d0d0d0d
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424251414141414140d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d010d0d0d232424242425140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424251414140d0d0d0d0d0d 0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424251414141414140d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d010d0d0d232424242425140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d23242424251414140d0d0d0d0d0d
0d0d0d0d0d0d0d0d030404040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d0d0d0304040404050304040404050d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d 0d0d0d0d0d0d0d0d030404040404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d120d0d0d00000000000000000000000000000000
0d03040404040405133d00001c00150d0d0d0d0d0d0d0d0d0304043e0404050d0d0d0d0d030404000404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0304040004050d0d0d0d0d0d0d0d0d0d0d0d1400140d0d0d0d0d0d0d0d0d1300000000151300000000150d0d0d0d14030404040404041400140d0d 0d03040404040405133d00001c00150d0d0d0d0d0d0d0d0d0304043e0404050d0d0d0d0d030404000404050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d14030404040404041400140d0d00000000000000000000000000000000
0d13001c1c004f0000421e1d1f00150d0d0d0d0d0d0d0d0d130000000000150d0d0d0d0317420000004816050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1300000000150d0d0d0d0d0d0d0d0d0d0d0d1400140d0d0d0d0d0d0d0d0d1300000000151300000000150d0d0d141413000000000000001e003f0d 0d13001c1c004f0000421e1d1f00150d0d0d0d0d0d0d0d0d130000000000150d0d0d0d0317420000004816050d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d141413000000000000001e003f0d00000000000000000000000000000000
0d13001c1c1d00150000001c000000010d03040404040405130000000000150d0d0d141300191b1d191b0015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1300000000150d0d0d0d0d0d0d0d0d0d0d030400040404050d0d0d0d0d0d130000001e1e1e00004848150d0d0d030417001d1d1d1d1d0015140d0d 0d13001c1c1d00150000001c000000010d03040404040405130000000000150d0d0d141300191b1d191b0015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d030417001d1d1d1d1d0015140d0d00000000000000000000000000000000
0d13001f1f000015131e1e1f1d1d150d0d13460044004c15130000000000150d0d3d001e0042001f0048001e003f0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d2307000006250d0d0d0d0d0d0d0d0d0d0d131c001c0000150d0d0d0d0d0d2324442424252324241d24250d0d0d130000001c1c421c1c00150d0d0d 0d13001f1f000015131e1e1f1d1d150d0d13460044004c15130000000000150d0d3d001e0042001f0048001e003f0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d130000001c1c421c1c00150d0d0d00000000000000000000000000000000
0d13000000000015130000001c1c150d0d131d1d1e1d1d152324241d2424250d0d140023240700410006242500140d0d0d0d0d0d030404040404050d0d0d0d0d0d030404040523001d2503040404050d0d0d0d0d0d0d3d1c001c0000150d0d0d0d0d0d0304000404050304041f04050d0d0d13001d1d1f1f001c1c00150d0d0d 0d13000000000015130000001c1c150d0d131d1d1e1d1d152324241d2424250d0d140023240700410006242500140d0d0d0d0d0d030404040404050d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001d1d1f1f001c1c00150d0d0d00000000000000000000000000000000
0927271b1e1e0015130014001c1c150d0d131c3d001c1c000000001f040404050d1400000023243c2425000000140d0d0d0d0d0d130000001c000000000d0d0d0d1300000000461d1c4c00000000150d0d0d0d030404171f1f1f2800150d0d0d0d0d0d1343004c1e151300000000150d0d0d13001c1c0000001c1c00150d0d0d 0927271b1e1e0015130014001c1c150d0d131c3d001c1c000000001f040404050d1400000023243c2425000000140d0d0d0d0d0d130000001c000000000d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c0000001c1c00150d0d0d00000000000000000000000000000000
0d131c1c00000000000000001c1c150d0d131f1f1e1f1f1514141300280000150d14000000001f1f1f00000000140d0d0d141414130028001c4516050014140d0d13000000001c1c1c1c00000000150d0d0d0d130000000000000000150d0d0d0d0d0d2324002424251300004100150d0d0d13001c1c001e001c1c00150d0d0d 0d131c1c00000000000000001c1c150d0d131f1f1e1f1f1514141300280000150d14000000001f1f1f00000000140d0d0d141414130028001c4516050014140d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c001e001c1c00150d0d0d00000000000000000000000000000000
0d131c1c0014001513001e1e1927270b0d1300004100001514141300000000010d144f47411400000014000000140d0d01000000000000001f000015000000120100004000001c1c1c1c000000003f0d0d0d0d13000000000000004a150d0d0d0d0d0d0304001e3e052324240024250d0d0d13001c1c0000001c1c00150d0d0d 0d131c1c0014001513001e1e1927270b0d1300004100001514141300000000010d144f47411400000014000000140d0d01000000000000001f0000150000001200000000000000000000000000000000000000000000000000000000000000000d0d13001c1c0000001c1c00150d0d0d00000000000000000000000000000000
0d131c1c00000015130000000000150d0927271b001927270b031741280000150d14434b491400000014000000140d0d0d14141413002800000000151414140d0d1300000000431c1c4900000000150d0d0d0d1300001d1d1d062424250d0d0d0d0d0d1300000000150304040004050d0d0d13001c1c001d1d1f1f00150d0d0d 0d131c1c00000015130000000000150d0927271b001927270b031741280000150d14434b491400000014000000140d0d0d14141413002800000000151414140d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c001d1d1f1f00150d0d0d00000000000000000000000000000000
0d131f1f1d1e1e151300001d1d00150d0d131f1c001c1c151f130000004900150d03040404040000000304040405140d0d0d0d0d13000000000006250d0d0d0d0d2324242425031c1f0523242424250d0d0d0d1300001c411c3f0d0d0d0d0d0d0d0d0d130000000015131e004100150d0d0d13001c1c481c1c000000150d0d0d 0d131f1f1d1e1e151300001d1d00150d0d131f1c001c1c151f130000004900150d03040404040000000304040405140d0d0d0d0d13000000000006250d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d13001c1c481c1c000000150d0d0d00000000000000000000000000000000
120000001c00000013001f1c1c00150d0d13001f001f1c0000131d1d000000150d1300000000000003170000000000120d0d0d0d232424242424250d0d0d0d0d0d0d0d0d0d03171f0016050d0d0d0d0d0d0d0d1300281c1c1c150d0d0d0d0d0d0d0d0d23241d241d252324240024250d0d1413001f1f1f1f1f000624250d0d0d 120000001c00000013001f1c1c00150d0d13001f001f1c0000131d1d000000150d1300000000000003170000000000120d0d0d0d232424242424250d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d1413001f1f1f1f1f000624250d0d0d00000000000000000000000000000000
0d13001d1f1e4800004f001c1c00150d0d13000000001f1500232424242424250d13000000001d1d1d0000000015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1300000000150d0d0d0d0d0d0d0d230024242424250d0d0d0d0d0d0d0d0d03041f041f050304040004050d010000000000000000001514140d0d0d 0d13001d1f1e4800004f001c1c00150d0d13000000001f1500232424242424250d13000000001d1d1d0000000015140d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0000000000000000000000000000000000000000000000000000000000000000010000000000000000001514140d0d0d00000000000000000000000000000000
0d13001c00003f15232424242424250d0d1300000000001500140d0d0d0d0d0d0d130000000625031700000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d1300000000150d0d0d0d0d0d0d0d1400140d0d0d0d0d0d0d0d0d0d0d0d0d130000000000000000410000120d14232424242424242425140d0d0d0d 0d13001c00003f15232424242424250d0d1300000000001500140d0d0d0d0d0d0d130000000625031700000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d14232424242424242425140d0d0d0d00000000000000000000000000000000
0d232424242424250d0d0d0d0d0d0d0d0d2324242424242500140d0d0d0d0d0d0d130000062503170000000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d2324242424250d0d0d0d0d0d0d0d1400140d0d0d0d0d0d0d0d0d0d0d0d0d23243c2400252324242424250d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d 0d232424242424250d0d0d0d0d0d0d0d0d2324242424242500140d0d0d0d0d0d0d130000062503170000000000150d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000
0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d232424250d23242424242424250d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d010d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d 0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d120d0d0d0d0d0d0d0d232424250d23242424242424250d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000
__sfx__ __sfx__
00110000250002500025030250302503000000230350000023030230302303023030230302303023030230302103021030210302103021030210300000000000177401774017740177311e7501e7501e7501e750 00110000250002500025030250302503000000230350000023030230302303023030230302303023030230302103021030210302103021030210300000000000177401774017740177311e7501e7501e7501e750
00110000290202a0212a0202a0202a0202a02025030250052503025030250302503025030250302503025030250302503025030250302503225030230322504526030260302a040000002d0402d0402d0402d040 00110000290202a0212a0202a0202a0202a02025030250052503025030250302503025030250302503025030250302503025030250302503225030230322504526030260302a040000002d0402d0402d0402d040