forked from pyrex/chameleonic
main #21
138
chameleonic.p8
138
chameleonic.p8
@ -102,6 +102,13 @@ function _mnmx(x,y)
|
|||||||
return x,y
|
return x,y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _anch_eq(a0,a1)
|
||||||
|
if (a0==nil) return a1==nil
|
||||||
|
if (a1==nil) return false
|
||||||
|
return a0.ax==a1.ax and a0.ay==a1.ay
|
||||||
|
end
|
||||||
|
function _anch_unpack(a0) return a0.ax,a0.ay end
|
||||||
|
|
||||||
|
|
||||||
function _rast(
|
function _rast(
|
||||||
xs,ys,x0,y0,x1,y1
|
xs,ys,x0,y0,x1,y1
|
||||||
@ -394,7 +401,7 @@ function level:recollide_reanchor()
|
|||||||
local old=(self._anch or {})[k]
|
local old=(self._anch or {})[k]
|
||||||
if old then
|
if old then
|
||||||
anch_new[k]=new
|
anch_new[k]=new
|
||||||
if (old.ax!=new.ax or old.ay!=new.ay) add(moves,{old.ax,old.ay,new.ax,new.ay,old,key=k})
|
if (not _anch_eq(old,new)) add(moves,{old,new,key=k})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self._anch=anch_new
|
self._anch=anch_new
|
||||||
@ -428,9 +435,9 @@ function level:anchor_points()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function level:anchor_at(ax,ay)
|
function level:anchor_at(point)
|
||||||
for i in self:anchor_points() do
|
for i in self:anchor_points() do
|
||||||
if (i.ax==ax and i.ay==ay) return i
|
if (_anch_eq(point,i)) return i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -672,8 +679,8 @@ function player:update()
|
|||||||
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,
|
{ax=x+0.5-dx*0.5,ay=y+0.5-dy*0.5},
|
||||||
self.x+0.5,self.y+0.5,
|
{ax=self.x+0.5,ay=self.y+0.5},
|
||||||
level:get_latch(dx,dy,x*8,y*8)
|
level:get_latch(dx,dy,x*8,y*8)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -815,19 +822,15 @@ rope={}
|
|||||||
rope.__index=rope
|
rope.__index=rope
|
||||||
|
|
||||||
function rope:new(
|
function rope:new(
|
||||||
src_ax,src_ay,dst_ax,dst_ay,latch
|
src,dst,latch
|
||||||
)
|
)
|
||||||
local r={
|
local r={
|
||||||
id=0,
|
id=0,
|
||||||
anchors={
|
|
||||||
{ax=src_ax,ay=src_ay},
|
|
||||||
{ax=dst_ax,ay=dst_ay}
|
|
||||||
},
|
|
||||||
state={name="cast",frame=0},
|
state={name="cast",frame=0},
|
||||||
latch=latch,
|
latch=latch,
|
||||||
}
|
}
|
||||||
r.src=r.anchors[1]
|
r.src=src
|
||||||
r.dst=r.anchors[2]
|
r.dst=dst
|
||||||
r.src.next=r.dst
|
r.src.next=r.dst
|
||||||
r.dst.prev=r.src
|
r.dst.prev=r.src
|
||||||
setmetatable(r,rope)
|
setmetatable(r,rope)
|
||||||
@ -991,7 +994,7 @@ function rope:draw(artificial_px,artificial_py)
|
|||||||
local sy=0
|
local sy=0
|
||||||
while true do
|
while true do
|
||||||
if (n1==nil) break
|
if (n1==nil) break
|
||||||
local anch=level:anchor_at(n1.ax,n1.ay)
|
local anch=level:anchor_at(n1)
|
||||||
local x=n1.ax*8
|
local x=n1.ax*8
|
||||||
local y=n1.ay*8
|
local y=n1.ay*8
|
||||||
if anch then
|
if anch then
|
||||||
@ -1042,8 +1045,8 @@ end
|
|||||||
|
|
||||||
function rope:drag(n1,ax_new,ay_new)
|
function rope:drag(n1,ax_new,ay_new)
|
||||||
self:relax()
|
self:relax()
|
||||||
self:_drag(n1,ax_new,n1.ay)
|
self:_drag(n1,{ax=ax_new,ay=n1.ay})
|
||||||
self:_drag(n1,ax_new,ay_new)
|
self:_drag(n1,{ax=ax_new,ay=ay_new})
|
||||||
self:relax()
|
self:relax()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1053,7 +1056,7 @@ function rope:relax()
|
|||||||
local n1=n0.next
|
local n1=n0.next
|
||||||
if (not n1) break
|
if (not n1) break
|
||||||
local n2=n1.next
|
local n2=n1.next
|
||||||
if n0.ax==n1.ax and n0.ay==n1.ay then
|
if _anch_eq(n0,n1) then
|
||||||
n0.next=n2
|
n0.next=n2
|
||||||
if (n2) n2.prev=n0
|
if (n2) n2.prev=n0
|
||||||
else
|
else
|
||||||
@ -1068,14 +1071,10 @@ function rope:relax()
|
|||||||
local n2=n1.next
|
local n2=n1.next
|
||||||
if (not n2) return
|
if (not n2) return
|
||||||
|
|
||||||
local x0,y0=n0.ax,n0.ay
|
local anch=level:anchor_at(n1)
|
||||||
local x1,y1=n1.ax,n1.ay
|
local wouldstick,axy_new=would_stick(anch,n0,n1,n2)
|
||||||
local x2,y2=n2.ax,n2.ay
|
if not (wouldstick or _anch_eq(n1,axy_new)) then
|
||||||
|
self:_drag(n1,axy_new,{ax=n1.ax,ay=n1.ay})
|
||||||
local anch=level:anchor_at(n1.ax,n1.ay)
|
|
||||||
local would,x1_new,y1_new=would_stick(anch,x0,y0,x1,y1,x2,y2)
|
|
||||||
if not would and not (n1.ax==x1_new and n1.ay==y1_new) then
|
|
||||||
self:_drag(n1,x1_new,y1_new,n1.ax,n1.ay)
|
|
||||||
n0=n1.prev
|
n0=n1.prev
|
||||||
n2=n1.next
|
n2=n1.next
|
||||||
n0.next=n2
|
n0.next=n2
|
||||||
@ -1097,7 +1096,9 @@ function rope:_check_sane()
|
|||||||
local n1=n0.next
|
local n1=n0.next
|
||||||
if (not n1) break
|
if (not n1) break
|
||||||
|
|
||||||
_rast(qxs,qys,flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2))
|
local n0ax,n0ay=_anch_unpack(n0)
|
||||||
|
local n1ax,n1ay=_anch_unpack(n1)
|
||||||
|
_rast(qxs,qys,flr(n0ax*2),flr(n0ay*2),flr(n1ax*2),flr(n1ay*2))
|
||||||
n0=n1
|
n0=n1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1154,8 +1155,10 @@ function rope:_check_sane()
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function would_stick(anchor,x0,y0,x1,y1,x2,y2)
|
function would_stick(anchor,xy0,xy1,xy2)
|
||||||
x1,y1=x1 or anchor.ax,y1 or anchor.ay
|
local x0,y0=_anch_unpack(xy0)
|
||||||
|
local x1,y1=_anch_unpack(xy1 or anchor)
|
||||||
|
local x2,y2=_anch_unpack(xy2)
|
||||||
|
|
||||||
local dx,dy=x2-x0,y2-y0
|
local dx,dy=x2-x0,y2-y0
|
||||||
|
|
||||||
@ -1181,7 +1184,7 @@ function would_stick(anchor,x0,y0,x1,y1,x2,y2)
|
|||||||
|
|
||||||
return
|
return
|
||||||
anchor and anchor.adx==adx and anchor.ady==ady,
|
anchor and anchor.adx==adx and anchor.ady==ady,
|
||||||
x1_new,y1_new
|
{ax=x1_new,ay=y1_new}
|
||||||
end
|
end
|
||||||
|
|
||||||
function rope:experience_anchor_moves(moves)
|
function rope:experience_anchor_moves(moves)
|
||||||
@ -1194,15 +1197,15 @@ function rope:_be_dragged_by(moves)
|
|||||||
local n=self.src
|
local n=self.src
|
||||||
while n do
|
while n do
|
||||||
for t in all(moves) do
|
for t in all(moves) do
|
||||||
local ax_old,ay_old,ax_new,ay_new=unpack(t)
|
local axy_old,axy_new=unpack(t)
|
||||||
if (ax_old==n.ax and ay_old==n.ay) n.dest={ax_new,ay_new} break
|
if (_anch_eq(axy_old,n)) n.dest=axy_new break
|
||||||
end
|
end
|
||||||
n=n.next
|
n=n.next
|
||||||
end
|
end
|
||||||
|
|
||||||
n=self.src
|
n=self.src
|
||||||
while n do
|
while n do
|
||||||
if (n.dest) self:_drag(n,unpack(n.dest)) n.dest=nil
|
if (n.dest) self:_drag(n,n.dest) n.dest=nil
|
||||||
n=n.next
|
n=n.next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1213,25 +1216,30 @@ function rope:_be_pushed_by(moves)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function rope:_be_pushed_by1(ax_old,ay_old,ax_new,ay_new,anch)
|
function rope:_be_pushed_by1(anch_old,anch_new)
|
||||||
local n0=self.src
|
local n0=self.src
|
||||||
while true do
|
|
||||||
|
local ax_old,ay_old=_anch_unpack(anch_old)
|
||||||
|
local ax_new,ay_new=_anch_unpack(anch_new)
|
||||||
|
|
||||||
|
while n0 do
|
||||||
n1=n0.next
|
n1=n0.next
|
||||||
if (not n1) return
|
if (not n1) return
|
||||||
|
|
||||||
local nx0,ny0=n0.ax,n0.ay
|
local nx0,ny0=_anch_unpack(n0)
|
||||||
local nx1,ny1=n1.ax,n1.ay
|
local nx1,ny1=_anch_unpack(n1)
|
||||||
|
|
||||||
local nxmn,nxmx = _mnmx(nx0,nx1)
|
local nxmn,nxmx = _mnmx(nx0,nx1)
|
||||||
local nymn,nymx = _mnmx(ny0,ny1)
|
local nymn,nymx = _mnmx(ny0,ny1)
|
||||||
|
|
||||||
|
-- nprinth("has: "..tostring{anch==nil,n0==nil,n1==nil})
|
||||||
if
|
if
|
||||||
(ax_new!=ax_old or (nxmn<ax_new and ax_new<nxmx)) and
|
(ax_new!=ax_old or (nxmn<ax_new and ax_new<nxmx)) and
|
||||||
(ay_new!=ay_old or (nymn<ay_new and ay_new<nymx)) and
|
(ay_new!=ay_old or (nymn<ay_new and ay_new<nymx)) and
|
||||||
|
|
||||||
(_which_side(ax_old,ay_old,nx0,ny0,nx1,ny1)!=
|
(_which_side(anch_old,n0,n1)!=
|
||||||
_which_side(ax_new,ay_new,nx0,ny0,nx1,ny1)
|
_which_side(anch_new,n0,n1)
|
||||||
) and would_stick(anch,nx0,ny0,nil,nil,nx1,ny1)
|
) and would_stick(anch_new,n0,nil,n1)
|
||||||
then
|
then
|
||||||
local nx05,ny05
|
local nx05,ny05
|
||||||
if ax_new==ax_old then
|
if ax_new==ax_old then
|
||||||
@ -1247,21 +1255,20 @@ function rope:_be_pushed_by1(ax_old,ay_old,ax_new,ay_new,anch)
|
|||||||
n1.prev=n05
|
n1.prev=n05
|
||||||
-- printh("creating: "..tostring{anch,{n0.ax,n0.ay},{n05.ax,n05.ay},{n1.ax,n1.ay}})
|
-- printh("creating: "..tostring{anch,{n0.ax,n0.ay},{n05.ax,n05.ay},{n1.ax,n1.ay}})
|
||||||
-- printh("dragging: "..tostring{anch,{n05.ax,n05.ay},{ax_new,ay_new}})
|
-- printh("dragging: "..tostring{anch,{n05.ax,n05.ay},{ax_new,ay_new}})
|
||||||
self:_drag(n05,ax_new,ay_new)
|
self:_drag(n05,{ax=ax_new,ay=ay_new})
|
||||||
else
|
else
|
||||||
n0=n0.next
|
n0=n0.next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
function rope:_drag(n1,new,removing)
|
||||||
local function _sweep_radar(ax_lhs,ay_lhs,ax_rhs,ay_rhs,ax_pivot,ay_pivot,ax_src,ay_src,ax_dst,ay_dst)
|
local function _sweep_radar(lhs,rhs,pivot,src,dst)
|
||||||
if (ax_src==ax_dst and ay_src==ay_dst) return
|
-- printh(tostring{{lhs.ax,lhs.ay},{rhs.ax,rhs.ay},{pivot.ax,pivot.ay},{src.ax,src.ay},{dst.ax,dst.ay}})
|
||||||
|
if (_anch_eq(src,dst)) return
|
||||||
|
|
||||||
local function _uncreatable(anchor)
|
local function _uncreatable(anchor)
|
||||||
return anchor.ax==ax_lhs and anchor.ay==ay_lhs or
|
return _anch_eq(anchor,lhs) or _anch_eq(anchor,lhs) or _anch_eq(anchor,removing)
|
||||||
anchor.ax==ax_rhs and anchor.ay==ay_rhs or
|
|
||||||
anchor.ax==ax_removing and anchor.ay==ay_removing
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _sweep(extent_old,extent_new,cb_in_bounds,cb_would_stick,cb_side)
|
local function _sweep(extent_old,extent_new,cb_in_bounds,cb_would_stick,cb_side)
|
||||||
@ -1278,34 +1285,31 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ax_src==ax_dst then
|
if src.ax==dst.ax then
|
||||||
|
local ax_pivot,ax_dst=pivot.ax,dst.ax
|
||||||
return _sweep(
|
return _sweep(
|
||||||
ay_src,ay_dst,
|
src.ay,dst.ay,
|
||||||
function(anchor) return mid(ax_pivot,anchor.ax,ax_dst)==anchor.ax end,
|
function(anchor) return mid(ax_pivot,anchor.ax,ax_dst)==anchor.ax end,
|
||||||
function(anchor,ay) return would_stick(anchor,ax_pivot,ay_pivot,nil,nil,ax_dst,ay) end,
|
function(anchor,ay) return would_stick(anchor,pivot,nil,{ax=ax_dst,ay=ay}) end,
|
||||||
function(anchor,ay) return _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_dst,ay) end
|
function(anchor,ay) return _which_side(anchor,pivot,{ax=ax_dst,ay=ay}) end
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
assert(ay_src==ay_dst)
|
local ay_pivot,ay_dst=pivot.ay,dst.ay
|
||||||
return _sweep(
|
return _sweep(
|
||||||
ax_src,ax_dst,
|
src.ax,dst.ax,
|
||||||
function(anchor) return mid(ay_pivot,anchor.ay,ay_dst)==anchor.ay end,
|
function(anchor) return mid(ay_pivot,anchor.ay,ay_dst)==anchor.ay end,
|
||||||
function(anchor,ax) return would_stick(anchor,ax_pivot,ay_pivot,nil,nil,ax,ay_dst) end,
|
function(anchor,ax) return would_stick(anchor,pivot,nil,{ax=ax,ay=ay_dst}) end,
|
||||||
function(anchor,ax) return _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax,ay_dst) end
|
function(anchor,ax) return _which_side(anchor,pivot,{ax=ax,ay=ay_dst}) end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local ax1_old,ay1_old=n1.ax,n1.ay
|
local old={ax=n1.ax,ay=n1.ay}
|
||||||
n1.ax=ax1_new
|
n1.ax,n1.ay=new.ax,new.ay
|
||||||
n1.ay=ay1_new
|
|
||||||
|
|
||||||
local n0=n1.prev
|
local n0=n1.prev
|
||||||
while n0 do
|
while n0 do
|
||||||
local anch=_sweep_radar(
|
local anch=_sweep_radar(n0,n1,n0,old,new)
|
||||||
n0.ax,n0.ay,n1.ax,n1.ay,
|
|
||||||
n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new
|
|
||||||
)
|
|
||||||
if (not anch) break
|
if (not anch) break
|
||||||
local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1}
|
local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1}
|
||||||
n0.next=n05
|
n0.next=n05
|
||||||
@ -1315,10 +1319,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing)
|
|||||||
|
|
||||||
local n2=n1.next
|
local n2=n1.next
|
||||||
while n2 do
|
while n2 do
|
||||||
local anch=_sweep_radar(
|
local anch=_sweep_radar(n1,n2,n2,old,new)
|
||||||
n1.ax,n1.ay,n2.ax,n2.ay,
|
|
||||||
n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new
|
|
||||||
)
|
|
||||||
if (not anch) break
|
if (not anch) break
|
||||||
local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2}
|
local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2}
|
||||||
n1.next=n15
|
n1.next=n15
|
||||||
@ -1354,7 +1355,12 @@ function _stepfrom(x0,x1)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _which_side(x,y,x0,y0,x1,y1)
|
function _which_side(xy,x0y0,x1y1)
|
||||||
|
local x,y=_anch_unpack(xy)
|
||||||
|
local x0,y0=_anch_unpack(x0y0)
|
||||||
|
local x1,y1=_anch_unpack(x1y1)
|
||||||
|
-- printh("anchors: "..tostring{x,y,x0,y0,x1,y1})
|
||||||
|
|
||||||
return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
|
return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1606,7 +1612,7 @@ function rope:_anchors_simplified()
|
|||||||
x=flr(a.ax*8+0.5),y=flr(a.ay*8+0.5),
|
x=flr(a.ax*8+0.5),y=flr(a.ay*8+0.5),
|
||||||
ax=a.ax,ay=a.ay
|
ax=a.ax,ay=a.ay
|
||||||
}
|
}
|
||||||
local aw=level:anchor_at(a.ax,a.ay)
|
local aw=level:anchor_at(a)
|
||||||
local l=self.latch
|
local l=self.latch
|
||||||
if aw then
|
if aw then
|
||||||
if (aw.adx==1) point.x-=1
|
if (aw.adx==1) point.x-=1
|
||||||
|
Loading…
Reference in New Issue
Block a user