More rope fixes

This commit is contained in:
Pyrex 2022-12-18 16:46:46 -08:00
parent d2e1e9274c
commit 5a0b8ab73d

View File

@ -428,6 +428,8 @@ function level:get_latch(dx,dy,px,py)
local mxy=_mix(mx,my)
local crate=self._crates[mxy]
local dx1,dy1=-sgn0(dx),-sgn0(dy)
if crate then
if
(crate.def.up and dy>0) or
@ -437,9 +439,9 @@ function level:get_latch(dx,dy,px,py)
then
return {
el="crate",
dx=-dx,dy=-dy,
px_offset=px-crate.px-sgn0(dx),
py_offset=py-crate.py-sgn0(dy),
dx=dx1,dy=dy1,
px_offset=px-crate.px+dx1,
py_offset=py-crate.py+dy1,
rec=crate
}
end
@ -448,14 +450,14 @@ function level:get_latch(dx,dy,px,py)
local m=self:_mget(mx,my)
if
(m==60 and dy>0) or
(m==61 and dx<0) or
(m==62 and dy<0) or
(m==63 and dx>0)
(m==60 and dy1<0) or
(m==61 and dx1>0) or
(m==62 and dy1>0) or
(m==63 and dx1<0)
then
return {
el="eyehook",
dx=-dx,dy=-dy,
dx=dx1,dy=dy1,
mx=mx,my=my
}
end
@ -864,6 +866,7 @@ end
function rope:draw()
local points,highlight=self:_tug(true)
if (self:busy()) highlight=nil
if (self.state.name=="done") return
local perc_to_show=1.0
if (self.state.name=="destroy") perc_to_show=(1.0-self.state.frame/5)^2
@ -891,7 +894,7 @@ function rope:draw()
dx,dy=dx*coef,dy*coef
local color=8
if (highlight==i) color=14
if (highlight==i) color=12
linefill(x,y,x+0.25*dx,y+0.25*dy,1.0,color)
linefill(x+0.25*dx,y+0.25*dy,x+1*dx,y+1*dy,0.5,color)
@ -899,6 +902,25 @@ function rope:draw()
circfill(x+dx+0.5,y+dy+0.5,1.0,color)
end
end
-- draw latch
if self.latch!=nil and perc_to_show>=1.0 then
local x,y=points[1].x,points[1].y
local ldx,ldy=self.latch.dx,self.latch.dy
local color=8
if (highlight==0) color=12
if self.latch.dx==-1 and self.latch.dy==0 then
rectfill(x+1,y,x+3,y+1,color)
elseif self.latch.dx==1 and self.latch.dy==0 then
rectfill(x-1,y,x-3,y+1,color)
elseif self.latch.dx==0 and self.latch.dy==-1 then
rectfill(x,y+1,x-1,y+3,color)
elseif self.latch.dx==0 and self.latch.dy==1 then
rectfill(x,y-1,x-1,y-3,color)
end
end
--[[
for i=0,#self.ancs+1 do
p=self:_anc(i)
local c=12
@ -918,6 +940,7 @@ function rope:draw()
--print(o.mx..","..o.my,0,i*8,3)
end
end
]]--
end
function rope:_anc(i)
@ -978,7 +1001,6 @@ function rope:_tidy_up_gen()
if (not self.dirty) return
local settled=true
local touched={}
local loop=function(f)
local a=0
while a<=#self.ancs+1 do
@ -1358,55 +1380,34 @@ function rope:_tug(hypothetically)
local touched={}
for i=#ancs-1,2,-1 do
local ops= self:_calc_push(ancs[i+1],ancs[i],ancs[i-1])
for o in all(ops) do
add(self.all_ops,o)
end
local find_all=function(lhs,rhs,di)
local ops2do={}
for i=lhs,rhs,di do
local o=ops[i]
if not level:mcoll(o.mx,o.my) then
-- great!
else
local crate=level:get_crate(o.mx,o.my)
if crate==nil or touched[_mix(o.mx,o.my)] then
break
else
if not level:can_move(false,o.mx,o.my,o.dmx,o.dmy,0,0) then
break
end
end
add(ops2do,o)
end
end
return ops2do
end
local ops_before_trash=find_all(1,#ops,1)
local ops_before_trash=self:_calc_push(ancs[i+1],ancs[i],ancs[i-1])
local ops_after_trash=self:_calc_push(ancs[i+1],ancs[i-1],ancs[i])
local ops_to_do={}
local corners={}
if #ops_before_trash>0 then
ops_to_do=ops_before_trash
corners[i-1]=true
else
ops_to_do=find_all(#ops,1,-1)
corners[i]=true
ops_to_do=ops_after_trash
end
local do_all=#ops==#ops_to_do
ops=ops_to_do
local _is=function(x1,x2)
return x1.mx==x2.mx and x1.my==x2.my
end
if (do_all) corners[i-1]=true corners[i]=true
local _caps=function(x,lst)
return #lst>0 and (_is(x,lst[1]) or _is(x,lst[#lst]))
end
local corners={}
if (_caps(ops_to_do[1],ops_before_trash)) corners[i-1]=true
if (_caps(ops_to_do[#ops_to_do],ops_after_trash)) corners[i]=true
local ops=ops_to_do
if #ops>0 then
if (hypothetically) return ancs,i-1
local dmx,dmy=ops[1].dmx,ops[1].dmy
for o in all(ops) do
touched[_mix(o.mx,o.my)]=true
touched[_mix(o.mx+dmx,o.my+dmy)]=true
level:tug_crate(
o.mx,o.my,dmx,dmy
)
@ -1475,10 +1476,9 @@ function rope:_tug(hypothetically)
end
if not too_far and
not touched[_mix(mx0,my0)] and
level:can_move(false,mx0,my0,dmx,dmy,1,0)
then
if (hypothetically) return ancs,1
if (hypothetically) return ancs,0
level:tug_crate(
mx0,my0,
@ -1549,7 +1549,24 @@ function rope:_calc_push(
add(ops,{mx=mx,my=my,dmx=0,dmy=dmy})
end
end
return ops
local ops2={}
for o in all(ops) do
if not level:mcoll(o.mx,o.my) then
-- great!
else
local crate=level:get_crate(o.mx,o.my)
if crate==nil then
break
else
if not level:can_move(false,o.mx,o.my,o.dmx,o.dmy,0,0) then
break
end
end
add(ops2,o)
end
end
return ops2
end
function rope:_anchors_simplified()
@ -1761,10 +1778,10 @@ __map__
0c00000000001c0000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c0000000000000000000000000000410000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c000000000000000c0c0c0c0c0c0c0c0c00000000000020210000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c000000000000000000000c0c0c0c0c0c00000000000030310000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c0000000000000c00000000000000120100000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3d00000c4f00003f0c000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c0c0c0c0c0c00000000000c0c0c0c0c0c00000000000030310000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c00000000000c0c0000000c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c00000c4f00000c00000000000000120100000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3d0000000000003f0c000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c0000000000000000000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
010000000000000c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0c0c0c0c00000c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000