First version I couldn't immediately break

This commit is contained in:
Pyrex 2022-12-20 16:27:08 -08:00
parent ca819b0e53
commit c71cd312b1

View File

@ -1056,6 +1056,38 @@ function rope:draw(artificial_dx,artificial_dy)
rectfill(x,y-1,x-1,y-3,color)
end
end
local n1=self.src
local sy=0
while true do
if (n1==nil) break
local x=n1.ax*8
local y=n1.ay*8
rectfill(x-1,y-1,x+1,y+1,12)
--print("ax="..n1.ax..",ay="..n1.ay,0,sy)
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)
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))
rectfill(x+2,y+2,x+4,y+4,3)
pset(x+adx*2,y,9)
pset(x,y+ady*2,9)
else
rectfill(x+2,y+2,x+4,y+4,2)
end
else
rectfill(x+2,y+2,x+4,y+4,4)
end
n1=n1.next
end
for _,p in pairs(level._anch) do
pset(p.ax*8,p.ay*8,11)
pset(p.ax*8+p.adx,p.ay*8,11)
@ -1063,13 +1095,6 @@ function rope:draw(artificial_dx,artificial_dy)
end
--[[
for i=0,#self.ancs+1 do
p=self:_anc(i)
local c=12
if (p.dirty) c=13
rectfill(p.x-1,p.y-1,p.x+1,p.y+1,c)
print(tostr(p.id)..":"..p.x..","..p.y..","..#p.todo,0,i*8,12)
end
print("dirty:"..tostr(self.dirty),32,0,9)
print("busy:"..tostr(self:busy()),32,7,9)
print("state:"..tostr(self.state.name),32,14,9)
@ -1111,31 +1136,9 @@ function rope:_relax()
local x1,y1=n1.ax,n1.ay
local x2,y2=n2.ax,n2.ay
if (x0>x2) x0,y0,x2,y2=x2,y2,x0,y0
local dx=x2-x0
local dy=y2-y0
local adx,ady
local x1_new,y1_new
if abs(dx)>abs(dy) then
local dprop=(x1-x0)/dx
x1_new,y1_new=x1,y0+dprop*(y2-y0)
ady=sgn0(y1_new-y1)
adx=0
if (y0>y2) adx=ady
if (y0<y2) adx=-ady
else
local dprop=(y1-y0)/dy
x1_new,y1_new=x0+dprop*(x2-x0),y1
adx=sgn0(x1_new-x1)
ady=0
if (y0>y2) ady=adx
if (y0<y2) ady=-adx
end
if false and (n1.associated_with.adx==-adx or n1.associated_with.ady==-ady) then
--self:_drag(n1,x1_new,y1_new)
local would,x1_new,y1_new=would_stick(x0,y0,n1.associated_with,x2,y2)
if not would then
self:_drag(n1,x1_new,y1_new)
n0=n1.prev
n2=n1.next
n0.next=n2
@ -1147,11 +1150,42 @@ function rope:_relax()
end
end
function would_stick(x0,y0,anchor,x2,y2)
local x1,y1=anchor.ax,anchor.ay
if (x0>x2) x0,y0,x2,y2=x2,y2,x0,y0
local dx=x2-x0
local dy=y2-y0
local adx,ady
local x1_new,y1_new
if abs(dx)>abs(dy) then
local dprop=(x1-x0)/dx
x1_new,y1_new=x1,y0+dprop*(y2-y0)
ady=sgn0(y1_new-y1)
adx=0
if (y0>y2) adx=ady
if (y0<y2) adx=-ady
else
local dprop=(y1-y0)/dy
x1_new,y1_new=x0+dprop*(x2-x0),y1
adx=sgn0(x1_new-x1)
ady=0
if (y0>y2) ady=adx
if (y0<y2) ady=-adx
end
return anchor.adx!=-adx and anchor.ady!=-ady,x1_new,y1_new,adx,ady
end
-- TODO: Upon adding a point, start from there to see if we need another
-- rather than adding at most one
function rope:_drag(n1,ax1_new,ay1_new)
local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil
local function crossed(x,y)
return x!=y
end
if ax_far0==ax_far1 then
local ax_far=ax_far0
@ -1161,9 +1195,14 @@ function rope:_drag(n1,ax1_new,ay1_new)
for ay_far_new in _stepfrom(ay_far0,ay_far1) do
for _,anchor in level:anchor_points() do
if
not (anchor.ax==ax_pivot and anchor.ay==ay_pivot) and
not (anchor.ax==ax_new and anchor.ay==ay_new) and
(ax0<=anchor.ax and anchor.ax<=ax1) 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)
would_stick(ax_pivot,ay_pivot,anchor,ax_far,ay_far_new) and
crossed(
_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)
)
then
return anchor
end
@ -1178,11 +1217,14 @@ function rope:_drag(n1,ax1_new,ay1_new)
for ax_far_new in _stepfrom(ax_far0,ax_far1) do
for _,anchor in level:anchor_points() do
if
-- anchor.ax!=ax_pivot and anchor.ay!=ay_pivot and
-- anchor.ax!=ax_new and anchor.ay!=ay_new and
not (anchor.ax==ax_pivot and anchor.ay==ay_pivot) and
not (anchor.ax==ax_new and anchor.ay==ay_new) and
would_stick(ax_pivot,ay_pivot,anchor,ax_far_new,ay_far) and
(ay0<=anchor.ay and anchor.ay<=ay1) 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)
crossed(
_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)
)
then
return anchor
end