diff --git a/chameleonic.p8 b/chameleonic.p8 index b5e3e04..4c5748c 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -337,6 +337,15 @@ function level:recollide() end end +function add_adjacent_anchors(tbl,mx,my) + for ax in all{mx*2-1,mx*2+2} do + for ay in all{my*2-1,my*2+2} do + local px,py=level:a2p(ax,ay) + tbl[_amix(ax,ay)]={ax=ax0,ay=ay0,x=px,y=py} + end + end +end + function level:reanchor(remove) if remove or not self._anch then self._anch={} @@ -362,12 +371,7 @@ function level:reanchor(remove) end for _,cr in pairs(self._crates) do - for ax in all{cr.mx*2-1,cr.mx*2+2} do - for ay in all{cr.my*2-1,cr.my*2+2} do - local px,py=self:a2p(ax,ay) - self._anch[_amix(ax,ay)]={ax=ax0,ay=ay0,x=px,y=py} - end - end + add_adjacent_anchors(self._anch,cr.mx,cr.my) end if (player.rope!=nil) player.rope:make_dirty() @@ -1034,29 +1038,29 @@ function rope:drag( a.y=y a.dirty=true self.dirty=true + --self:_find_needed_anchors(i()) + --self:_find_needed_anchors(i()+1) if (not busy) self:_tidy_up_gen() end end end -function rope:make_dirty() - for a=0,#self.ancs+1 do - self:_anc(a).dirty=true +function rope:make_dirty(only_if_invalid) + local invalid=false + for a=0,#self.ancs do + local a0=self:_anc(a) + local a1=self:_anc(a+1) + if not self:_can_stretch(a0,a1) then + a0.dirty=true + a1.dirty=true + invalid=true + end end - self.dirty=true + if (invalid or not only_if_invalid) self.dirty=true end function rope:_tidy_up_gen() - local invalid=false - for i=0,#self.ancs do - local a0=self:_anc(i) - local a1=self:_anc(i+1) - if not self:_can_stretch(a0,a1) then - invalid=true - break - end - end - if (invalid) self:make_dirty() + self:make_dirty(true) local busy=self:busy() if (not self:latched()) return @@ -1131,7 +1135,7 @@ function rope:_tidy_up_gen() self.dirty=false end -function rope:_find_needed_anchors(i) +function rope:_find_needed_anchors(i,busy) if (i<=0) return false if (#self.ancs+10 then ops_to_do=ops_before_trash - corners[i-1]=true - corners[i]=hit_end1 else local ops_after_trash,hit_end2=self:_calc_push(ancs[i-2],ancs[i-1],ancs[i],ancs[i+1]) ops_to_do=ops_after_trash - corners[i-1]=true - corners[i]=hit_end1 end local ops=ops_to_do @@ -1462,10 +1462,10 @@ function rope:_tug(hypothetically) if (hypothetically) return ancs,i-1 local dmx,dmy=ops[1].dmx,ops[1].dmy + local adjacent_ancs={} for o in all(ops) do - level:tug_crate( - o.mx,o.my,dmx,dmy - ) + add_adjacent_anchors(adjacent_ancs,o.mx,o.my) + level:tug_crate(o.mx,o.my,o.dmx,o.dmy) end for node=ancs[i-1].ix,ancs[i].ix do local anc=self:_anc(node) @@ -1483,7 +1483,8 @@ function rope:_tug(hypothetically) end} end local dmxh,dmyh=dmx,dmy - if (not corners[node]) dmxh,dmyh=0,0 + local ax,ay=level:p2a(x0,y0) + if (adjacent_ancs[_amix(ax,ay)]==nil) dmxh,dmyh=0,0 anc.todo={ {}, upd(x0+dmxh*2,y0+dmyh*2), @@ -1857,7 +1858,7 @@ __map__ 0c000000000000000c0c0c0c0c0c0c0c0c00000000000020210000000000000c00000000000e00000e0e0000000000000e0000000000000e0e0e0000000000000e000000000e0e0e0e0e0000000000000e00000000000e0000000000000000000e00000000000e0e0e000000000000000e000000000000000e00000000000000 0c0c0c0c0c0c00000000000c0c0c0c0c0c00000000000030310000000000000c000000000000000e0e000000000000000e00000000000000000e0000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e00000000000e00000e0000000000000e0000000000000e0000000000000000 0c00000000000c0c004f000c0c0c0c0c0c00000000000000000000000000000c0000000000000e0e00000000000000000e00000000000e0e0e0e0000000000000e0000000000000e00000000000000000e000000000000000e000000000000000e0000000000000e0e000000000000000e0000000000000e0000000000000000 -0c00000c4f00000c00000000000000120100000000000000000000000000000c00000000000e0e0e0e0e0000000000000e0000000000000000000000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e0000000000000000000000000000000e000000000000000000000000000000 +0c00000c4f00000000000000000000120100000000000000000000000000000c00000000000e0e0e0e0e0000000000000e0000000000000000000000000000000e0000000000000e00000000000000000e00000000000e0e0e000000000000000e0000000000000000000000000000000e000000000000000000000000000000 3d0000000000003f0c000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 0c0000000000000000000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000 010000000000000c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e0000000000000000000000000000000e000000000000000000000000000000