diff --git a/chameleonic.p8 b/chameleonic.p8 index 7c34aea..a4fdc40 100644 --- a/chameleonic.p8 +++ b/chameleonic.p8 @@ -309,6 +309,7 @@ function level:reanchor(remove) end end end + if (player.rope!=nil) player.rope:make_dirty() end function level:win_at(mx,my) @@ -772,12 +773,6 @@ end function rope:done() return self.state.name=="done" - --[[ - return self.latch_frame>=2 and ( - self.latch==nil or - self.under_destruction - ) - ]] end function rope:busy() @@ -800,8 +795,8 @@ function rope:update() elseif self.state.name=="destroy" then -- destroy self.state.frame+=1 if (self.state.frame>=5) self.state={name="done"} - else -- - assert(false, "todo") + else + -- done state end end @@ -818,6 +813,8 @@ function rope:_make_consistent() if (self.latch==nil) self:destroy() return + self:_tidy_up_gen() + if self.latch!=nil and self.latch.rec!=nil @@ -830,18 +827,27 @@ function rope:_make_consistent() if #self.latch.rec.todo==0 then if self.latch.rec.dead==true then self:destroy() - return - end - 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 - self:destroy() - return - end end end end + 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:_tidy_up_gen() + 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 + self:_destroy() + end + end + end function rope:continue_cast() @@ -875,7 +881,7 @@ function rope:_reindex() end function rope:draw() - local points=self:_anchors_simplified() + local points,highlight=self:_tug(true) if (self.state.name=="done") return local perc_to_show=1.0 if (self.state.name=="destroy") perc_to_show=(1.0-self.state.frame/5)^2 @@ -902,14 +908,19 @@ function rope:draw() local coef=min(len_here/dist_base,1.0) dx,dy=dx*coef,dy*coef - linefill(x,y,x+0.25*dx,y+0.25*dy,1.0,8) - linefill(x+0.25*dx,y+0.25*dy,x+1*dx,y+1*dy,0.5,8) - linefill(x+0.9*dx,y+0.9*dy,x+dx,y+dy,1.0,8) - circfill(x+dx+0.5,y+dy+0.5,1.0,8) + local color=8 + if (highlight==i) color=14 + + linefill(x,y,x+0.25*dx,y+0.25*dy,1.0,color) + linefill(x+0.25*dx,y+0.25*dy,x+1*dx,y+1*dy,0.5,color) + linefill(x+0.9*dx,y+0.9*dy,x+dx,y+dy,1.0,color) + circfill(x+dx+0.5,y+dy+0.5,1.0,color) end end for i,p in ipairs(self.ancs) do - rectfill(p.x-1,p.y-1,p.x+1,p.y+1,12) + local c=12 + if (p.dirty) c=13 + rectfill(p.x-1,p.y-1,p.x+1,p.y+1,c) print(p.id..":"..p.x..","..p.y..","..#p.todo,0,-8+i*8,9) end for _,p in pairs(level._anch) do @@ -957,6 +968,13 @@ function rope:drag( end end +function rope:make_dirty() + for a=0,#self.ancs+1 do + self:_anc(a).dirty=true + end + self.dirty=true +end + function rope:_tidy_up_gen() if (not self:latched()) return if (not self.dirty) return @@ -1012,6 +1030,7 @@ function rope:_tidy_up_gen() for a=0,#self.ancs+1,1 do local anc=self:_anc(a) if (anc.seen) anc.dirty=anc.changed + if (anc.dirty) settled=false end if (settled) break @@ -1111,6 +1130,8 @@ function rope:_elide_point(i) end deli(self.ancs,i) + --self:_anc(i-1).dirty=true + --self:_anc(i).dirty=true return true end @@ -1324,7 +1345,7 @@ function rope:tug() self:_make_consistent() end -function rope:_tug() +function rope:_tug(hypothetically) local ancs=self:_anchors_simplified() local touched={} @@ -1334,24 +1355,28 @@ function rope:_tug() add(self.all_ops,o) end - local can_do=true + local ops_to_do={} for o in all(ops) do if not level:mcoll(o.mx,o.my) then -- great! else local crate=level:get_crate(o.mx,o.my) if crate==nil or touched[_mix(o.mx,o.my)] then - can_do=false + break else if not level:can_move(false,o.mx,o.my,o.dmx,o.dmy,0,0) then - can_do=false + break end end + add(ops_to_do,o) end - if (not can_do) break end + local do_all=#ops==#ops_to_do + ops=ops_to_do + + if #ops>0 then + if (hypothetically) return ancs,i-1 - if can_do and #ops>=1 then local dmx,dmy=ops[1].dmx,ops[1].dmy for o in all(ops) do touched[_mix(o.mx,o.my)]=true @@ -1360,6 +1385,8 @@ function rope:_tug() o.mx,o.my,dmx,dmy ) end + local move_up_to=i + if (do_all) move_up_to=i-1 for node=ancs[i-1].ix,ancs[i].ix do local anc=self:_anc(node) local x0,y0=anc.x,anc.y @@ -1369,16 +1396,19 @@ function rope:_tug() if force or not level:pcoll(x,y) then s.x=x s.y=y - self.dirty=true end + s.dirty=true + self.dirty=true return true end} end + local dmxh,dmyh=dmx,dmy + if (nodea1.y then + my0,my1=my1,my0 + smy=-smy + end local mx,dmx if a0.x%8==0 and a0.x>an.x+7 then @@ -1450,14 +1488,18 @@ function rope:_calc_push( return {} end - for my=my0,my1,1 do + for my=my0,my1,smy do add(ops,{mx=mx,my=my,dmx=dmx,dmy=0}) end end if a0.y==a1.y then local x0,x1=_mnmx(a0.x,a1.x) - local mx0,mx1=(x0+1)\8,(x1-1)\8 + local mx0,mx1,smx=(x0+1)\8,(x1-1)\8,1 + if a0.x>a1.x then + mx0,mx1=mx1,mx0 + smx=-smx + end local my,dmy if a0.y%8==0 and a0.y>an.y+6 then @@ -1473,7 +1515,7 @@ function rope:_calc_push( return {} end - for mx=mx0,mx1,1 do + for mx=mx0,mx1,smx do add(ops,{mx=mx,my=my,dmx=0,dmy=dmy}) end end @@ -1686,15 +1728,15 @@ __map__ 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c000000000044000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c000000000000000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0100000000001c000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0c00000000001c000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c000000000000000c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c000000000000000c0c0c0c0c0c0c0c0c00000000000020210000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c000000000000000000000c0c0c0c0c0c00000000000030310000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c0c0c0c0c0c0c0c0000000c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0c0c0c0c0c0c0c0c00000000000000120100000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0c0000000000000c00000000000000120100000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +3d00000c4f00003f0c000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0c0000000000000000000c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +010000000000000c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 __sfx__