ff to current state #6

Merged
kistaro merged 27 commits from pyrex/chameleonic:main into main 2022-12-19 07:03:33 +00:00
Showing only changes of commit 06e09bfc2e - Show all commits

View File

@ -569,7 +569,7 @@ function player:update()
self.todo={{
update=function()
return self.rope==nil or not self.rope:casting()
return self.rope==nil or self.rope:latched()
end
},{},{}}
else
@ -578,7 +578,7 @@ function player:update()
end
elseif btn(❎) then
if self.rope!=nil then
self.rope=nil
self.rope:destroy()
end
end
end
@ -718,24 +718,26 @@ function rope:new(
src={x=src_x,y=src_y,todo={}},
ancs={},
dst={x=x,y=y,todo={}},
cast={dx=dx,dy=dy},
state={name="cast",dx=dx,dy=dy},
latch=nil,
latch_frame=0,
under_destruction=false,
}
setmetatable(r,rope)
return r
end
function rope:casting()
return self.cast!=nil
function rope:latched()
return self.state.name=="latched"
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()
@ -746,17 +748,26 @@ function rope:busy()
end
function rope:update()
if self.cast!=nil then
if self.state.name=="cast" then
self:continue_cast()
return
end
elseif self.state.name=="latched" then
self.latch_frame+=1
if self.latch_frame>=10 then
self.latch_frame=10
end
self:_make_consistent()
elseif self.state.name=="destroy" then -- destroy
self.state.frame+=1
if (self.state.frame>=5) self.state={name="done"}
else --
assert(false, "todo")
end
end
function rope:destroy()
if (self.state.name=="destroy" or self.state.name=="done") return
self.state={name="destroy",frame=0}
end
function rope:_make_consistent()
@ -765,8 +776,9 @@ function rope:_make_consistent()
_apply(anc,anc.todo,i)
end
if (self.latch==nil) self:destroy() return
if
not self.under_destruction and
self.latch!=nil and
self.latch.rec!=nil
then
@ -777,14 +789,14 @@ function rope:_make_consistent()
if #self.latch.rec.todo==0 then
if self.latch.rec.dead==true then
self.under_destruction=true
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.under_destruction=true
self:destroy()
return
end
end
@ -793,7 +805,7 @@ function rope:_make_consistent()
end
function rope:continue_cast()
local dx,dy=self.cast.dx,self.cast.dy
local dx,dy=self.state.dx,self.state.dy
local x0=self.src.x
local y0=self.src.y
local x1=x0+dx
@ -807,10 +819,10 @@ function rope:continue_cast()
if latch!=nil or level:pcoll(x,y) then
self.latch=latch
self.cast=nil
self.state={name="latched"}
break
end
self.src={x=x,y=y,todo={}}
self.src={x=x,y=y,todo={},dirty=true}
end
end
@ -824,17 +836,37 @@ end
function rope:draw()
local points=self:_anchors_simplified()
for i=1,(#points-1) do
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
local len=0
for i=1,#points-1 do
len+=distance(points[i],points[i+1])
end
local len_to_show=perc_to_show*len
local len_cumulative=0
for i=#points-1,1,-1 do
local src=points[i]
local dst=points[i+1]
local x,y=src.x,src.y
local dx,dy=dst.x-x,dst.y-y
local x,y=dst.x,dst.y
local dx,dy=src.x-x,src.y-y
local len_here=len_to_show-len_cumulative
local dist_base=distance_dxy(dx,dy)
len_cumulative+=dist_base
if len_here>0 and dist_base>0 then
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+0.5,y+0.5,1.0,8)
circfill(x+dx+0.5,y+dy+0.5,1.0,8)
end
end
for i,p in ipairs(self.ancs) do
rectfill(p.x-1,p.y-1,p.x+1,p.y+1,12)
@ -886,7 +918,7 @@ function rope:drag(
end
function rope:_tidy_up_gen()
if (self.under_destruction) return
if (not self:latched()) return
if (not self.dirty) return
local settled=true
@ -1077,6 +1109,10 @@ function sum_distance(x,y,z)
return distance(x,y) + distance(y,z)
end
function distance_dxy(dx,dy)
return sqrt(dx*dx+dy*dy)
end
function distance(p1,p2)
local dx=p2.x-p1.x
local dy=p2.y-p1.y
@ -1243,7 +1279,7 @@ end
function rope:tug()
self:_make_consistent()
if (self.under_destruction) return
if (not self:latched()) return
self:_tug()
self:_make_consistent()
end