diff --git a/chameleonic.p8 b/chameleonic.p8 index 59222a9..9d2ec6c 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -394,11 +394,14 @@ function level:reanchor() old.dropped=true end + local moves={} for k,new in pairs(anch_new) do local old=anch_old[k] if old then anch_new[k]=old - 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 + local ax_old,ay_old + ax_old,ay_old,old.ax,old.ay,old.adx,old.ady=old.ax,old.ay,new.ax,new.ay,new.adx,new.ady + if (ax_old!=old.ax or ay_old!=old.ay) add(moves,{ax_old,ay_old,new.ax,new.ay,key=k}) old.dropped=nil end end @@ -408,15 +411,16 @@ function level:reanchor() add(self._anch_keys,{key=k}) end shellsort(self._anch_keys) - for point in self:anchor_points() do - if point.ax_old and player.rope and (point.ax_old != point.ax or point.ay_old != point.ay) then - -- printh("moving: "..tostring({point.ax_old,point.ay_old}).."=>"..tostring({point.ax,point.ay})) - player.rope:be_pushed_by(point,point.ax_old,point.ay_old) - end - point.ax_old,point.ay_old=nil,nil + shellsort(moves) + printh("!!STARTING!!") + + if player.rope then + player.rope:experience_anchor_moves(moves) end - if (player.rope) player.rope:relax() + for point in self:anchor_points() do + point.moved=nil + end end function level:win_at(mx,my) @@ -424,9 +428,10 @@ function level:win_at(mx,my) end function level:anchor_points() - keys=all(self._anch_keys) + local i=0 return function() - local k=keys() + i+=1 + local k=self._anch_keys[i] if (k) return self._anch[k.key] end end @@ -988,7 +993,6 @@ function rope:draw(artificial_px,artificial_py) end -- debug - --[[ local n1=self.src local sy=0 while true do @@ -1036,7 +1040,6 @@ function rope:draw(artificial_px,artificial_py) pset(x+p.adx,y,11) pset(x,y+p.ady,11) end - ]] end function rope:drag_dst(x,y) @@ -1075,6 +1078,7 @@ function rope:relax() if (not n1) break local n2=n1.next + if n0.ax==n1.ax and n0.ay==n1.ay then n0.next=n2 if (n2) n2.prev=n0 @@ -1090,17 +1094,11 @@ 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 + if n1.associated_with then - - local x0,y0=n0.ax,n0.ay - local x1,y1=n1.ax,n1.ay - local x2,y2=n2.ax,n2.ay - - if x1!=n1.associated_with.ax or y1!=n1.associated_with.ay then - -- printh("dragging home: "..tostring{n1.ax,n1.ay}.."->"..tostring(n1.associated_with)) - self:_drag(n1,n1.associated_with.ax,n1.associated_with.ay) - end - local would,x1_new,y1_new=would_stick(x0,y0,n1.associated_with,x2,y2) if not would and not (n1.ax==x1_new and n1.ay==y1_new) then -- printh("dragging: "..tostring{n1.associated_with, {x1_new, y1_new}}) @@ -1219,9 +1217,37 @@ function would_stick(x0,y0,anchor,x2,y2) return not wouldnt,x1_new,y1_new,adx,ady end -function rope:be_pushed_by(anchor,ax_old,ay_old) +function rope:experience_anchor_moves(moves) + self:_be_dragged_by(moves) + self:_be_pushed_by(moves) + self:relax() +end + +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 + end + n=n.next + end + + n=self.src + while n do + if (n.dest) self:_drag(n,unpack(n.dest)) n.dest=nil + n=n.next + end +end + +function rope:_be_pushed_by(moves) + for i in all(moves) do + self:_be_pushed_by1(unpack(i)) + end +end + +function rope:_be_pushed_by1(ax_old,ay_old,ax_new,ay_new) local n0=self.src - local ax_new,ay_new=anchor.ax,anchor.ay while true do n1=n0.next if (not n1) return @@ -1229,17 +1255,18 @@ function rope:be_pushed_by(anchor,ax_old,ay_old) local nx0,ny0=n0.ax,n0.ay local nx1,ny1=n1.ax,n1.ay + printh(tostring{nx0,ny0,nx1,ny1}) local nxmn,nxmx = _mnmx(nx0,nx1) local nymn,nymx = _mnmx(ny0,ny1) -- printh(tostring({anchor,nxmn,nxmx,nymn,nymx})) if - (ax_new!=ax_old or (nxmn<=anchor.ax and anchor.ax<=nxmx)) and - (ay_new!=ay_old or (nymn<=anchor.ay and anchor.ay<=nymx)) 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 (_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) + ) and would_stick(nx0,ny0,{ax=ax_new,ay=ay_new},nx1,ny1) then -- printh("found (in): "..tostring({{nx0,ny0},{nx1,ny1}, anchor})) local nx05,ny05 @@ -1333,7 +1360,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing) ) if (not anch) break local n05={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n0,next=n1} - -- printh("creating pre: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with)) + printh("creating pre: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with)) n0.next=n05 n1.prev=n05 n0=n05 @@ -1347,7 +1374,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing) ) if (not anch) break local n15={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n1,next=n2} - -- printh("creating post: "..tostring(n1.associated_with).."->"..tostring(n15.associated_with).."->"..tostring(n2.associated_with)) + printh("creating post: "..tostring(n1.associated_with).."->"..tostring(n15.associated_with).."->"..tostring(n2.associated_with)) n1.next=n15 n2.prev=n15 n2=n15