forked from pyrex/chameleonic
Correct when the rope crashes into the other side of something
This commit is contained in:
parent
672f1b3951
commit
6658f71ba2
110
chameleonic.p8
110
chameleonic.p8
@ -450,7 +450,7 @@ function level:reanchor()
|
|||||||
local old=anch_old[k]
|
local old=anch_old[k]
|
||||||
if old then
|
if old then
|
||||||
anch_new[k]=old
|
anch_new[k]=old
|
||||||
old.ax,old.ay,old.adx,old.ady=new.ax,new.ay,new.adx,new.ady
|
old.ax_old,old.ay_old,old.ax,old.ay,old.adx,old.ady=old.ax,old.ay,new.ax,new.ay,new.adx,new.ady
|
||||||
old.dropped=nil
|
old.dropped=nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -459,6 +459,17 @@ function level:reanchor()
|
|||||||
for k,_ in pairs(self._anch) do
|
for k,_ in pairs(self._anch) do
|
||||||
add(self._anch_keys,{key=k})
|
add(self._anch_keys,{key=k})
|
||||||
end
|
end
|
||||||
|
shellsort(self._anch_keys)
|
||||||
|
for point in self:anchor_points() do
|
||||||
|
if point.ax_old!=nil then
|
||||||
|
if (player.rope!=nil) player.rope:be_pushed_by(point,point.ax_old,point.ay_old)
|
||||||
|
point.ax_old=nil
|
||||||
|
point.ay_old=nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for point in self:anchor_points() do
|
||||||
|
assert(not point.dropped)
|
||||||
|
end
|
||||||
|
|
||||||
if (player.rope!=nil) player.rope:relax()
|
if (player.rope!=nil) player.rope:relax()
|
||||||
end
|
end
|
||||||
@ -617,13 +628,13 @@ function level:can_move(
|
|||||||
if player.rope then
|
if player.rope then
|
||||||
local chk=false
|
local chk=false
|
||||||
if dmx==0 and dmy==-1 then
|
if dmx==0 and dmy==-1 then
|
||||||
chk=player.rope:collide_mrect(mx0,my0-1,1,2,exclude_src,exclude_dst)
|
chk=player.rope:collide_mrect(mx0+0.4,my0-0.8,0.2,1.6,exclude_src,exclude_dst)
|
||||||
elseif dmx==0 and dmy==1 then
|
elseif dmx==0 and dmy==1 then
|
||||||
chk=player.rope:collide_mrect(mx0,my0,1,2,exclude_src,exclude_dst)
|
chk=player.rope:collide_mrect(mx0+0.4,my0+0.2,0.2,1.6,exclude_src,exclude_dst)
|
||||||
elseif dmx==-1 and dmy==0 then
|
elseif dmx==-1 and dmy==0 then
|
||||||
chk=player.rope:collide_mrect(mx0-1,my0,2,1,exclude_src,exclude_dst)
|
chk=player.rope:collide_mrect(mx0-0.8,my0+0.4,1.6,0.2,exclude_src,exclude_dst)
|
||||||
elseif dmx==1 and dmy==0 then
|
elseif dmx==1 and dmy==0 then
|
||||||
chk=player.rope:collide_mrect(mx0,my0,2,1,exclude_src,exclude_dst)
|
chk=player.rope:collide_mrect(mx0+0.2,my0+0.4,1.6,0.2,exclude_src,exclude_dst)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (chk) return false
|
if (chk) return false
|
||||||
@ -781,7 +792,10 @@ function player:update()
|
|||||||
|
|
||||||
if self.rope then
|
if self.rope then
|
||||||
self.rope:update()
|
self.rope:update()
|
||||||
self.rope:drag_dst(self.x+self.px/8+0.5,self.y+self.py/8+0.5)
|
local rx=self.x+self.px/8+0.5
|
||||||
|
local ry=self.y+self.py/8+0.5
|
||||||
|
-- do the hokey pokey to work out kinks in the rope
|
||||||
|
self.rope:drag_dst(rx,ry)
|
||||||
|
|
||||||
local tdx,tdy=self.rope:tug_orientxy()
|
local tdx,tdy=self.rope:tug_orientxy()
|
||||||
if (tdx!=0) self.orientx=tdx
|
if (tdx!=0) self.orientx=tdx
|
||||||
@ -1030,7 +1044,7 @@ function rope:draw(artificial_px,artificial_py)
|
|||||||
--assert(not (adx==0 and ady==0))
|
--assert(not (adx==0 and ady==0))
|
||||||
|
|
||||||
local c=3
|
local c=3
|
||||||
if (n1.associated_with.dropped) c=8
|
if (n1.associated_with.dropped) c=4
|
||||||
rectfill(x+2,y+2,x+4,y+4,c)
|
rectfill(x+2,y+2,x+4,y+4,c)
|
||||||
pset(x+adx*2,y,9)
|
pset(x+adx*2,y,9)
|
||||||
pset(x,y+ady*2,9)
|
pset(x,y+ady*2,9)
|
||||||
@ -1083,6 +1097,20 @@ function rope:relax()
|
|||||||
n=n.next
|
n=n.next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local n0=self.src
|
||||||
|
while true do
|
||||||
|
local n1=n0.next
|
||||||
|
if (n1==nil) break
|
||||||
|
local n2=n1.next
|
||||||
|
|
||||||
|
if n0.ax==n1.ax and n0.ay==n1.ay then
|
||||||
|
n0.next=n2
|
||||||
|
n2.prev=n0
|
||||||
|
else
|
||||||
|
n0=n0.next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local n0=self.src
|
local n0=self.src
|
||||||
while true do
|
while true do
|
||||||
if (n0==nil) return
|
if (n0==nil) return
|
||||||
@ -1187,7 +1215,6 @@ end
|
|||||||
|
|
||||||
function would_stick(x0,y0,anchor,x2,y2)
|
function would_stick(x0,y0,anchor,x2,y2)
|
||||||
local x1,y1=anchor.ax,anchor.ay
|
local x1,y1=anchor.ax,anchor.ay
|
||||||
if (x0>x2) x0,y0,x2,y2=x2,y2,x0,y0
|
|
||||||
|
|
||||||
local dx=x2-x0
|
local dx=x2-x0
|
||||||
local dy=y2-y0
|
local dy=y2-y0
|
||||||
@ -1195,6 +1222,7 @@ function would_stick(x0,y0,anchor,x2,y2)
|
|||||||
local adx,ady
|
local adx,ady
|
||||||
local x1_new,y1_new
|
local x1_new,y1_new
|
||||||
if abs(dx)>abs(dy) then
|
if abs(dx)>abs(dy) then
|
||||||
|
if (x0>x2) dx,x0,y0,x2,y2=-dx,x2,y2,x0,y0
|
||||||
local dprop=(x1-x0)/dx
|
local dprop=(x1-x0)/dx
|
||||||
x1_new,y1_new=x1,y0+dprop*(y2-y0)
|
x1_new,y1_new=x1,y0+dprop*(y2-y0)
|
||||||
ady=sgn0(y1_new-y1)
|
ady=sgn0(y1_new-y1)
|
||||||
@ -1202,25 +1230,66 @@ function would_stick(x0,y0,anchor,x2,y2)
|
|||||||
if (y0>y2) adx=ady
|
if (y0>y2) adx=ady
|
||||||
if (y0<y2) adx=-ady
|
if (y0<y2) adx=-ady
|
||||||
else
|
else
|
||||||
|
if (y0>y2) dy,x0,y0,x2,y2=-dy,x2,y2,x0,y0
|
||||||
local dprop=(y1-y0)/dy
|
local dprop=(y1-y0)/dy
|
||||||
x1_new,y1_new=x0+dprop*(x2-x0),y1
|
x1_new,y1_new=x0+dprop*(x2-x0),y1
|
||||||
adx=sgn0(x1_new-x1)
|
adx=sgn0(x1_new-x1)
|
||||||
ady=0
|
ady=0
|
||||||
if (y0>y2) ady=adx
|
if (x0>x2) ady=adx
|
||||||
if (y0<y2) ady=-adx
|
if (x0<x2) ady=-adx
|
||||||
end
|
end
|
||||||
|
|
||||||
local wouldnt=anchor.dropped or (anchor.adx==-adx or anchor.ady==-ady)
|
local wouldnt=anchor.dropped or (anchor.adx!=adx or anchor.ady!=ady)
|
||||||
|
|
||||||
return not wouldnt,x1_new,y1_new,adx,ady
|
return not wouldnt,x1_new,y1_new,adx,ady
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function rope:be_pushed_by(anchor,ax_old,ay_old)
|
||||||
|
local n0=self.src
|
||||||
|
local ax_new,ay_new=anchor.ax,anchor.ay
|
||||||
|
while true do
|
||||||
|
n1=n0.next
|
||||||
|
if (n1==nil) return
|
||||||
|
|
||||||
|
local nx0,ny0=n0.ax,n0.ay
|
||||||
|
local nx1,ny1=n1.ax,n1.ay
|
||||||
|
|
||||||
|
if
|
||||||
|
not (anchor.ax==nx0 and anchor.ay==ny0) and
|
||||||
|
not (anchor.ax==nx1 and anchor.ay==ny1) and
|
||||||
|
(_which_side(ax_old,ay_old,nx0,ny0,nx1,ny1)!=
|
||||||
|
_which_side(ax_new,ay_new,nx0,ny0,nx1,ny1)
|
||||||
|
) and would_stick(nx0,ny0,anchor,nx1,ny1)
|
||||||
|
then
|
||||||
|
local nx05,ny05
|
||||||
|
if ax_new==ax_old then
|
||||||
|
nx05=anchor.ax
|
||||||
|
ny05=ny0+(nx05-nx0)/(nx1-nx0) * (ny1-ny0)
|
||||||
|
--printh("found (x): "..tostring({nx05,ny05}))
|
||||||
|
elseif ay_new==ay_old then
|
||||||
|
ny05=anchor.ay
|
||||||
|
nx05=nx0+(ny05-ny0)/(ny1-ny0) * (nx1-nx0)
|
||||||
|
--printh("found (y): "..tostring({nx05,ny05}))
|
||||||
|
else
|
||||||
|
assert(false,"wtf?")
|
||||||
|
end
|
||||||
|
|
||||||
|
local n05={ax=nx05,ay=ny05,associated_with=anchor,prev=n0,next=n1}
|
||||||
|
--printh("adding: "..tostring({nx05,ny05,anchor}))
|
||||||
|
n0.next=n05
|
||||||
|
n1.prev=n05
|
||||||
|
self:_drag(n05,anchor.ax,anchor.ay)
|
||||||
|
-- printh("dragged: "..tostring({n05.ax,n05.ay,anchor}))
|
||||||
|
-- printh("local: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with))
|
||||||
|
else
|
||||||
|
n0=n0.next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function rope:_drag(n1,ax1_new,ay1_new)
|
function rope:_drag(n1,ax1_new,ay1_new)
|
||||||
local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
|
local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
|
||||||
if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil
|
if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil
|
||||||
local function crossed(x,y)
|
|
||||||
return x!=y
|
|
||||||
end
|
|
||||||
|
|
||||||
if ax_far0==ax_far1 then
|
if ax_far0==ax_far1 then
|
||||||
local ax_far=ax_far0
|
local ax_far=ax_far0
|
||||||
@ -1235,8 +1304,8 @@ function rope:_drag(n1,ax1_new,ay1_new)
|
|||||||
not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and
|
not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and
|
||||||
(ax0<=anchor.ax and anchor.ax<=ax1) and
|
(ax0<=anchor.ax and anchor.ax<=ax1) and
|
||||||
would_stick(ax_pivot,ay_pivot,anchor,ax_far,ay_far_new) and
|
would_stick(ax_pivot,ay_pivot,anchor,ax_far,ay_far_new) and
|
||||||
crossed(
|
(
|
||||||
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_old),
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_old) !=
|
||||||
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_new)
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_new)
|
||||||
)
|
)
|
||||||
then
|
then
|
||||||
@ -1258,8 +1327,8 @@ function rope:_drag(n1,ax1_new,ay1_new)
|
|||||||
not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and
|
not (anchor.ax==ax_far1 and anchor.ay==ay_far1) and
|
||||||
would_stick(ax_pivot,ay_pivot,anchor,ax_far_new,ay_far) and
|
would_stick(ax_pivot,ay_pivot,anchor,ax_far_new,ay_far) and
|
||||||
(ay0<=anchor.ay and anchor.ay<=ay1) and
|
(ay0<=anchor.ay and anchor.ay<=ay1) and
|
||||||
crossed(
|
(
|
||||||
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_old,ay_far),
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_old,ay_far) !=
|
||||||
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far)
|
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far)
|
||||||
)
|
)
|
||||||
then
|
then
|
||||||
@ -1345,11 +1414,6 @@ function rope:collide_mrect(mx0,my0,mw,mh,exclude_src,exclude_dst)
|
|||||||
local mx1,my1=mx0+mw,my0+mh
|
local mx1,my1=mx0+mw,my0+mh
|
||||||
local n0=self.src
|
local n0=self.src
|
||||||
|
|
||||||
mx0+=0.4
|
|
||||||
my0+=0.4
|
|
||||||
mx1-=0.4
|
|
||||||
my1-=0.4
|
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local n1=n0.next
|
local n1=n0.next
|
||||||
if (n1==nil) return false
|
if (n1==nil) return false
|
||||||
|
Loading…
Reference in New Issue
Block a user