diff --git a/chameleonic.p8 b/chameleonic.p8 index ab9aa37..0320839 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -345,6 +345,10 @@ function level:recollide() end end +function level:anchor_for(axy) + return self._anch_by_axy[_mix(axy.ax,axy.ay)] +end + function level:reanchor() local anch_new={} for dxy in all{{-1,-1},{1,-1},{-1,1},{1,1}} do @@ -380,20 +384,17 @@ function level:reanchor() local anch_old=self._anch if (anch_old==nil) anch_old={} - for _,old in pairs(anch_old) do - old.dropped=true - end 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 - old.dropped=nil end end self._anch=anch_new self._anch_keys={} + self._anch_by_axy={} for k,_ in pairs(self._anch) do add(self._anch_keys,{key=k}) end @@ -404,6 +405,9 @@ function level:reanchor() player.rope:be_pushed_by(point,point.ax_old,point.ay_old) end point.ax_old,point.ay_old=nil,nil + + local axykey=_mix(point.ax,point.ay) + self._anch_by_axy[axykey]=self._anch_by_axy[axykey] or point end if (player.rope) player.rope:relax() @@ -959,38 +963,36 @@ function rope:draw(artificial_px,artificial_py) end -- debug - --[[ local n1=self.src local sy=0 while true do if (n1==nil) break local x=n1.ax*8 local y=n1.ay*8 - if n1.associated_with then - if (n1.associated_with.adx>0) x-=1 - if (n1.associated_with.ady>0) y-=1 + local real_anch = level:anchor_for(n1) + if real_anch then + if (real_anch.adx>0) x-=1 + if (real_anch.ady>0) y-=1 end rectfill(x-1,y-1,x+1,y+1,12) print("ax="..n1.ax..",ay="..n1.ay,72,sy) - print(tostring(n1.associated_with and (not n1.associated_with.dropped and n1.associated_with.ax==n1.ax and n1.associated_with.ay==n1.ay)),76,sy+7) - sy+=14 + sy+=7 local n0=n1.prev local n2=n1.next if n0!=nil and n2!=nil then - if n1.associated_with then - local _,_,_,adx,ady=would_stick(n0.ax,n0.ay,n1.associated_with,n2.ax,n2.ay) + if real_anch then + local _,_,_,adx,ady=would_stick(real_anch,n0.ax,n0.ay,n1.ax,n1.ay,n2.ax,n2.ay) assert(adx==-1 or adx==0 or adx==1) assert(ady==-1 or ady==0 or ady==1) --assert(not (adx==0 and ady==0)) local c=3 - if (n1.associated_with.dropped) c=4 rectfill(x+2,y+2,x+4,y+4,c) pset(x+adx*2,y,9) pset(x,y+ady*2,9) else - rectfill(x+2,y+2,x+4,y+4,2) + rectfill(x+2,y+2,x+4,y+4,2) end else rectfill(x+2,y+2,x+4,y+4,4) @@ -1007,7 +1009,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) @@ -1026,21 +1027,6 @@ function rope:drag(n1,ax_new,ay_new) end function rope:relax() - local n0=self.src - while true do - if (n0==nil) break - if n0.associated_with and n0.associated_with.dropped then - for i in level:anchor_points() do - if i.ax==n0.ax and i.ay==n0.ay then - n0.associated_with=i - break - end - end - end - - n0=n0.next - end - local n0=self.src while true do local n1=n0.next @@ -1063,21 +1049,16 @@ function rope:relax() local n2=n1.next if (n2==nil) return - if n1.associated_with!=nil then - + + if n0 and n2 then + local real_anch = level:anchor_for(n1) 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}}) - -- printh("relaxing: "..tostring(n0.associated_with).."->"..tostring(n1.associated_with).."->"..tostring(n2.associated_with)) + local would,x1_new,y1_new=would_stick(real_anch,x0,y0,x1,y1,x2,y2) + if not would then + printh("dragging: "..tostring{real_anch,{n1.ax,n1.ay},{x1_new, y1_new}}) self:_drag(n1,x1_new,y1_new,n1.ax,n1.ay) n0=n1.prev n2=n1.next @@ -1158,8 +1139,8 @@ function rope:_check_sane() return true end -function would_stick(x0,y0,anchor,x2,y2) - local x1,y1=anchor.ax,anchor.ay +function would_stick(anchor,x0,y0,x1,y1,x2,y2) + if (anchor) x1,y1=anchor.ax,anchor.ay local dx=x2-x0 local dy=y2-y0 @@ -1187,7 +1168,7 @@ function would_stick(x0,y0,anchor,x2,y2) if (x0"..tostring(n05.associated_with).."->"..tostring(n1.associated_with)) + -- printh("local: "..tostring(n0.TODO).."->"..tostring(n05.TODO).."->"..tostring(n1.TODO)) else n0=n0.next end @@ -1261,7 +1242,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing) if not _uncreatable(anchor) and (ax0<=anchor.ax and anchor.ax<=ax1) and - would_stick(ax_pivot,ay_pivot,anchor,ax_far,ay_far_new) and + would_stick(anchor,ax_pivot,ay_pivot,nil,nil,ax_far,ay_far_new) and ( _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) @@ -1282,7 +1263,7 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing) if not _uncreatable(anchor) and (ay0<=anchor.ay and anchor.ay<=ay1) and - would_stick(ax_pivot,ay_pivot,anchor,ax_far_new,ay_far) and + would_stick(anchor,ax_pivot,ay_pivot,nil,nil,ax_far_new,ay_far) and ( _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) @@ -1308,8 +1289,8 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing) n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new ) if (anch==nil) 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)) + local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1} + -- printh("creating pre: "..tostring(n0.TODO).."->"..tostring(n05.TODO).."->"..tostring(n1.TODO)) n0.next=n05 n1.prev=n05 n0=n05 @@ -1323,8 +1304,8 @@ function rope:_drag(n1,ax1_new,ay1_new,ax_removing,ay_removing) n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new ) if (anch==nil) 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)) + local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2} + -- printh("creating post: "..tostring(n1.TODO).."->"..tostring(n15.TODO).."->"..tostring(n2.TODO)) n1.next=n15 n2.prev=n15 n2=n15 @@ -1610,7 +1591,7 @@ function rope:_anchors_simplified() x=flr(a.ax*8+0.5),y=flr(a.ay*8+0.5), ax=a.ax,ay=a.ay } - local aw=a.associated_with + local aw=level:anchor_for(a) local l=self.latch if aw then if (aw.adx==1) point.x-=1