diff --git a/chameleonic.p8 b/chameleonic.p8 index ee6e2ac..4b28de8 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -102,6 +102,13 @@ function _mnmx(x,y) return x,y 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( xs,ys,x0,y0,x1,y1 @@ -394,7 +401,7 @@ function level:recollide_reanchor() local old=(self._anch or {})[k] if old then 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 self._anch=anch_new @@ -428,9 +435,9 @@ function level:anchor_points() end end -function level:anchor_at(ax,ay) +function level:anchor_at(point) 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 @@ -672,8 +679,8 @@ function player:update() 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, - self.x+0.5,self.y+0.5, + {ax=x+0.5-dx*0.5,ay=y+0.5-dy*0.5}, + {ax=self.x+0.5,ay=self.y+0.5}, level:get_latch(dx,dy,x*8,y*8) ) @@ -815,19 +822,15 @@ rope={} rope.__index=rope function rope:new( - src_ax,src_ay,dst_ax,dst_ay,latch + src,dst,latch ) local r={ id=0, - anchors={ - {ax=src_ax,ay=src_ay}, - {ax=dst_ax,ay=dst_ay} - }, state={name="cast",frame=0}, latch=latch, } - r.src=r.anchors[1] - r.dst=r.anchors[2] + r.src=src + r.dst=dst r.src.next=r.dst r.dst.prev=r.src setmetatable(r,rope) @@ -991,7 +994,7 @@ function rope:draw(artificial_px,artificial_py) local sy=0 while true do 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 y=n1.ay*8 if anch then @@ -1042,8 +1045,8 @@ end function rope:drag(n1,ax_new,ay_new) self:relax() - self:_drag(n1,ax_new,n1.ay) - self:_drag(n1,ax_new,ay_new) + self:_drag(n1,{ax=ax_new,ay=n1.ay}) + self:_drag(n1,{ax=ax_new,ay=ay_new}) self:relax() end @@ -1053,7 +1056,7 @@ function rope:relax() local n1=n0.next if (not n1) break local n2=n1.next - if n0.ax==n1.ax and n0.ay==n1.ay then + if _anch_eq(n0,n1) then n0.next=n2 if (n2) n2.prev=n0 else @@ -1068,14 +1071,10 @@ function rope:relax() local n2=n1.next if (not n2) return - local x0,y0=n0.ax,n0.ay - local x1,y1=n1.ax,n1.ay - local x2,y2=n2.ax,n2.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) + local anch=level:anchor_at(n1) + local wouldstick,axy_new=would_stick(anch,n0,n1,n2) + if not (wouldstick or _anch_eq(n1,axy_new)) then + self:_drag(n1,axy_new,{ax=n1.ax,ay=n1.ay}) n0=n1.prev n2=n1.next n0.next=n2 @@ -1097,7 +1096,9 @@ function rope:_check_sane() local n1=n0.next 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 end @@ -1154,8 +1155,10 @@ function rope:_check_sane() return true end -function would_stick(anchor,x0,y0,x1,y1,x2,y2) - x1,y1=x1 or anchor.ax,y1 or anchor.ay +function would_stick(anchor,xy0,xy1,xy2) + 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 @@ -1181,7 +1184,7 @@ function would_stick(anchor,x0,y0,x1,y1,x2,y2) return anchor and anchor.adx==adx and anchor.ady==ady, - x1_new,y1_new + {ax=x1_new,ay=y1_new} end function rope:experience_anchor_moves(moves) @@ -1194,15 +1197,15 @@ function rope:_be_dragged_by(moves) local n=self.src while n do for t in all(moves) do - local ax_old,ay_old,ax_new,ay_new=unpack(t) - if (ax_old==n.ax and ay_old==n.ay) n.dest={ax_new,ay_new} break + local axy_old,axy_new=unpack(t) + if (_anch_eq(axy_old,n)) n.dest=axy_new break end n=n.next end n=self.src 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 end end @@ -1213,25 +1216,30 @@ function rope:_be_pushed_by(moves) 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 - 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 if (not n1) return - local nx0,ny0=n0.ax,n0.ay - local nx1,ny1=n1.ax,n1.ay + local nx0,ny0=_anch_unpack(n0) + local nx1,ny1=_anch_unpack(n1) local nxmn,nxmx = _mnmx(nx0,nx1) local nymn,nymx = _mnmx(ny0,ny1) + -- nprinth("has: "..tostring{anch==nil,n0==nil,n1==nil}) if (ax_new!=ax_old or (nxmn