Rewrite rope #11
200
chameleonic.p8
200
chameleonic.p8
@ -7,10 +7,6 @@ real_modules={}
|
|||||||
|
|
||||||
frame=0
|
frame=0
|
||||||
function _init()
|
function _init()
|
||||||
-- cls(0)
|
|
||||||
-- for i in _stepfrom(0.5,-2.5) do print(i) end
|
|
||||||
-- assert(false)
|
|
||||||
|
|
||||||
_doall("init") end
|
_doall("init") end
|
||||||
function _update()
|
function _update()
|
||||||
frame+=1
|
frame+=1
|
||||||
@ -97,13 +93,13 @@ function _apply(x,ts,a)
|
|||||||
local t=deli(ts,1)
|
local t=deli(ts,1)
|
||||||
for k,v in pairs(t) do
|
for k,v in pairs(t) do
|
||||||
if k=="update" then
|
if k=="update" then
|
||||||
if not v(x,a) then
|
--
|
||||||
add(ts,t,1)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
x[k]=v
|
x[k]=v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (t and t.update and not t.update(x,a)) add(ts,t,1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function sgn0(x)
|
function sgn0(x)
|
||||||
@ -401,28 +397,16 @@ end
|
|||||||
|
|
||||||
function level:recollide()
|
function level:recollide()
|
||||||
self._coll={}
|
self._coll={}
|
||||||
self._coll_nocrate={}
|
|
||||||
for mx=0,15 do
|
for mx=0,15 do
|
||||||
for my=0,15 do
|
for my=0,15 do
|
||||||
local mxy=_mix(mx,my)
|
local mxy=_mix(mx,my)
|
||||||
self._coll_nocrate[mxy]=
|
|
||||||
fget(self:_mget(mx,my),7)
|
|
||||||
self._coll[mxy]=
|
self._coll[mxy]=
|
||||||
self._coll_nocrate[mxy] or
|
fget(self:_mget(mx,my),7) or
|
||||||
self._crates[mxy]!=nil
|
self._crates[mxy]!=nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
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()
|
function level:reanchor()
|
||||||
local anch_new={}
|
local anch_new={}
|
||||||
for dxy in all{{-1,-1},{1,-1},{-1,1},{1,1}} do
|
for dxy in all{{-1,-1},{1,-1},{-1,1},{1,1}} do
|
||||||
@ -433,7 +417,7 @@ function level:reanchor()
|
|||||||
local mx1,my1=mx0+dx,my0+dy
|
local mx1,my1=mx0+dx,my0+dy
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self:mcoll_nocrate(mx0,my0) and
|
self:mcoll(mx0,my0) and not self:get_crate(mx0,my0) and
|
||||||
not self:mcoll(mx0,my1) and
|
not self:mcoll(mx0,my1) and
|
||||||
not self:mcoll(mx1,my0) and
|
not self:mcoll(mx1,my0) and
|
||||||
not self:mcoll(mx1,my1)
|
not self:mcoll(mx1,my1)
|
||||||
@ -497,12 +481,6 @@ function level:get_open_pit(mx,my)
|
|||||||
if (pit and pit.contents==nil) return pit
|
if (pit and pit.contents==nil) return pit
|
||||||
end
|
end
|
||||||
|
|
||||||
function level:point_anchor(px,py)
|
|
||||||
local ax,ay=self:p2a(px,py)
|
|
||||||
local anc=self._anch[_amix(ax,ay)]
|
|
||||||
return anc
|
|
||||||
end
|
|
||||||
|
|
||||||
function level:spawn_exit()
|
function level:spawn_exit()
|
||||||
self._wins={}
|
self._wins={}
|
||||||
local spawned=false
|
local spawned=false
|
||||||
@ -516,9 +494,11 @@ function level:spawn_exit()
|
|||||||
end
|
end
|
||||||
local win_at=function(x,y)
|
local win_at=function(x,y)
|
||||||
if (self:_mget(x,y)!=18) return
|
if (self:_mget(x,y)!=18) return
|
||||||
for n in all(neighbors{x=x,y=y}) do
|
for nx=x-1,x+1 do
|
||||||
if n.x<0 or n.y<0 or n.x>15 or n.y>15 then
|
for ny=y-1,y+1 do
|
||||||
self._wins[_mix(n.x,n.y)]=true
|
if nx<0 or ny<0 or nx>15 or ny>15 then
|
||||||
|
self._wins[_mix(nx,ny)]=true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -529,22 +509,9 @@ function level:spawn_exit()
|
|||||||
assert(spawned)
|
assert(spawned)
|
||||||
end
|
end
|
||||||
|
|
||||||
function level:p2a(px,py)
|
|
||||||
return px\4,py\4
|
|
||||||
end
|
|
||||||
|
|
||||||
function level:a2p(ax,ay)
|
|
||||||
local px=ax*4+3*(ax%2)
|
|
||||||
local py=ay*4+3*(ay%2)
|
|
||||||
return px,py
|
|
||||||
end
|
|
||||||
|
|
||||||
function level:mcoll(mx,my)
|
function level:mcoll(mx,my)
|
||||||
return self._coll[_mix(mx,my)]!=false
|
return self._coll[_mix(mx,my)]!=false
|
||||||
end
|
end
|
||||||
function level:mcoll_nocrate(mx,my)
|
|
||||||
return self._coll_nocrate[_mix(mx,my)]!=false
|
|
||||||
end
|
|
||||||
|
|
||||||
function level:pcoll(px,py)
|
function level:pcoll(px,py)
|
||||||
return self:mcoll(px\8,py\8)
|
return self:mcoll(px\8,py\8)
|
||||||
@ -671,20 +638,16 @@ function level:tug_crate(mx0,my0,dmx,dmy)
|
|||||||
|
|
||||||
local mx1,my1=mx0+dmx,my0+dmy
|
local mx1,my1=mx0+dmx,my0+dmy
|
||||||
local mxy1=_mix(mx1,my1)
|
local mxy1=_mix(mx1,my1)
|
||||||
existing.mx=mx1
|
|
||||||
existing.my=my1
|
|
||||||
existing.todo={
|
existing.todo={
|
||||||
{px=mx0*8+dmx*2,py=my0*8+dmy*2},
|
{px=mx1*8+dmx,py=my1*8+dmy,mx=mx1,my=my1,update=function()
|
||||||
{px=mx0*8+dmx*7,py=my0*8+dmy*7},
|
self:recollide()
|
||||||
{px=mx1*8,py=my1*8,update=function()
|
self:reanchor()
|
||||||
self:reanchor(true)
|
|
||||||
return true
|
return true
|
||||||
end}
|
end},
|
||||||
|
{px=mx1*8,py=my1*8}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._crates[mxy1]=existing
|
self._crates[mxy1]=existing
|
||||||
self:recollide()
|
|
||||||
self:reanchor(false)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-->8
|
-->8
|
||||||
@ -955,8 +918,8 @@ function rope:update()
|
|||||||
self.latch.rec!=nil
|
self.latch.rec!=nil
|
||||||
then
|
then
|
||||||
self:drag_src(
|
self:drag_src(
|
||||||
self.latch.rec.px/8+0.5+self.latch.ax_offset,
|
self.latch.rec.mx+0.5+self.latch.ax_offset,
|
||||||
self.latch.rec.py/8+0.5+self.latch.ay_offset
|
self.latch.rec.my+0.5+self.latch.ay_offset
|
||||||
)
|
)
|
||||||
|
|
||||||
if #self.latch.rec.todo==0 then
|
if #self.latch.rec.todo==0 then
|
||||||
@ -1023,28 +986,34 @@ function rope:draw(artificial_dx,artificial_dy)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- draw latch
|
-- draw latch
|
||||||
if self.latch!=nil and perc_to_show>=1.0 then
|
if self.latch!=nil and self.latch.rec and perc_to_show>=1.0 then
|
||||||
local x,y=points[1].x,points[1].y
|
local x,y=self.latch.rec.px,self.latch.rec.py
|
||||||
local ldx,ldy=self.latch.dx,self.latch.dy
|
local ldx,ldy=self.latch.dx,self.latch.dy
|
||||||
local color=8
|
local color=8
|
||||||
if (highlight==0) color=12
|
if (highlight==0) color=12
|
||||||
if self.latch.dx==-1 and self.latch.dy==0 then
|
if self.latch.dx==-1 and self.latch.dy==0 then
|
||||||
rectfill(x+1,y-1,x+3,y,color)
|
rectfill(x,y+3,x+2,y+4,color)
|
||||||
elseif self.latch.dx==1 and self.latch.dy==0 then
|
elseif self.latch.dx==1 and self.latch.dy==0 then
|
||||||
rectfill(x-1,y-1,x-3,y,color)
|
rectfill(x+5,y+3,x+7,y+4,color)
|
||||||
elseif self.latch.dx==0 and self.latch.dy==-1 then
|
elseif self.latch.dx==0 and self.latch.dy==-1 then
|
||||||
rectfill(x,y+1,x-1,y+3,color)
|
rectfill(x+3,y,x+4,y+2,color)
|
||||||
elseif self.latch.dx==0 and self.latch.dy==1 then
|
elseif self.latch.dx==0 and self.latch.dy==1 then
|
||||||
rectfill(x,y-1,x-1,y-3,color)
|
rectfill(x+3,y+5,x+4,y+7,color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local n1=self.src
|
|
||||||
|
-- debug
|
||||||
--[[
|
--[[
|
||||||
|
local n1=self.src
|
||||||
local sy=0
|
local sy=0
|
||||||
while true do
|
while true do
|
||||||
if (n1==nil) break
|
if (n1==nil) break
|
||||||
local x=n1.ax*8
|
local x=n1.ax*8
|
||||||
local y=n1.ay*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
|
||||||
|
end
|
||||||
rectfill(x-1,y-1,x+1,y+1,12)
|
rectfill(x-1,y-1,x+1,y+1,12)
|
||||||
print("ax="..n1.ax..",ay="..n1.ay,0,sy)
|
print("ax="..n1.ax..",ay="..n1.ay,0,sy)
|
||||||
sy+=7
|
sy+=7
|
||||||
@ -1074,11 +1043,14 @@ function rope:draw(artificial_dx,artificial_dy)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _,p in pairs(level._anch) do
|
for _,p in pairs(level._anch) do
|
||||||
pset(p.ax*8,p.ay*8,11)
|
local x,y=p.ax*8,p.ay*8
|
||||||
pset(p.ax*8+p.adx,p.ay*8,11)
|
if (p.adx>0) x-=1
|
||||||
pset(p.ax*8,p.ay*8+p.ady,11)
|
if (p.ady>0) y-=1
|
||||||
|
pset(x,y,11)
|
||||||
|
pset(x+p.adx,y,11)
|
||||||
|
pset(x,y+p.ady,11)
|
||||||
end
|
end
|
||||||
]]--
|
]]
|
||||||
end
|
end
|
||||||
|
|
||||||
function rope:drag_dst(x,y)
|
function rope:drag_dst(x,y)
|
||||||
@ -1125,7 +1097,7 @@ function rope:relax()
|
|||||||
|
|
||||||
local would,x1_new,y1_new=would_stick(x0,y0,n1.associated_with,x2,y2)
|
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
|
if not would and not (n1.ax==x1_new and n1.ay==y1_new) then
|
||||||
printh("relaxing: "..tostring(n0.associated_with).."->"..tostring(n1.associated_with).."->"..tostring(n2.associated_with))
|
--printh("relaxing: "..tostring(n0.associated_with).."->"..tostring(n1.associated_with).."->"..tostring(n2.associated_with))
|
||||||
self:_drag(n1,x1_new,y1_new)
|
self:_drag(n1,x1_new,y1_new)
|
||||||
n0=n1.prev
|
n0=n1.prev
|
||||||
n2=n1.next
|
n2=n1.next
|
||||||
@ -1133,7 +1105,6 @@ function rope:relax()
|
|||||||
n2.prev=n0
|
n2.prev=n0
|
||||||
n1.next=nil
|
n1.next=nil
|
||||||
n1.prev=nil
|
n1.prev=nil
|
||||||
--n0=n0.next
|
|
||||||
else n0=n0.next end
|
else n0=n0.next end
|
||||||
else n0=n0.next end
|
else n0=n0.next end
|
||||||
end
|
end
|
||||||
@ -1143,7 +1114,6 @@ function rope:_check_sane()
|
|||||||
if (self.state.name!="latched") return true
|
if (self.state.name!="latched") return true
|
||||||
if (level:busy()) return true
|
if (level:busy()) return true
|
||||||
|
|
||||||
printh("start")
|
|
||||||
local n0=self.src
|
local n0=self.src
|
||||||
|
|
||||||
local qxs,qys={},{}
|
local qxs,qys={},{}
|
||||||
@ -1152,32 +1122,62 @@ function rope:_check_sane()
|
|||||||
if (n1==nil) break
|
if (n1==nil) break
|
||||||
|
|
||||||
for qx,qy in _rast(flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2)) do
|
for qx,qy in _rast(flr(n0.ax*2),flr(n0.ay*2),flr(n1.ax*2),flr(n1.ay*2)) do
|
||||||
add(qxs,qx)
|
if not (qx==qxs[#qxs] and qy==qys[#qys]) then
|
||||||
add(qys,qy)
|
add(qxs,qx)
|
||||||
|
add(qys,qy)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
n0=n1
|
n0=n1
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _blocked(qx,qy)
|
local function _possible_tiles(qx,qy)
|
||||||
local mx0=(qx-1)\2
|
local mx0=(qx-1)\2
|
||||||
local mx1=qx\2
|
local mx1=qx\2
|
||||||
local my0=(qy-1)\2
|
local my0=(qy-1)\2
|
||||||
local my1=qy\2
|
local my1=qy\2
|
||||||
|
|
||||||
return level:mcoll(mx0,my0) and level:mcoll(mx1,my1)
|
local poss={}
|
||||||
|
for mx=mx0,mx1 do
|
||||||
|
for my=my0,my1 do
|
||||||
|
add(poss,{mx=mx,my=my})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return poss
|
||||||
end
|
end
|
||||||
for i=1,#qxs do
|
local function _blocked(qx,qy)
|
||||||
if (_blocked(qxs[i],qys[i])) printh("blocked"..qxs[i]..","..qys[i]) return false
|
for i in all(_possible_tiles(qx,qy)) do
|
||||||
|
if (not level:mcoll(i.mx,i.my)) return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- find cases where i move through an impassable zone
|
||||||
|
for i=1,#qxs do
|
||||||
|
if (_blocked(qxs[i],qys[i])) return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- find cases where i am cut off diagonally
|
||||||
for i=3,#qxs do
|
for i=3,#qxs do
|
||||||
local qx1,qy1=qxs[i-1],qys[i-1]
|
local qx1,qy1=qxs[i-1],qys[i-1]
|
||||||
if qx1%2==0 and qy1%2==0 then
|
if qx1%2==0 and qy1%2==0 then
|
||||||
local qx0,qy0=qxs[i-2],qys[i-2]
|
local ok=false
|
||||||
local qx2,qy2=qxs[i],qys[i]
|
for m0 in all(_possible_tiles(qxs[i-2],qys[i-2])) do
|
||||||
local mx0,my0=qx0\2,qy0\2
|
for m2 in all(_possible_tiles(qxs[i],qys[i])) do
|
||||||
local mx2,my2=qx2\2,qy2\2
|
local mx0,my0=m0.mx,m0.my
|
||||||
if (level:mcoll(mx0,my2) and level:mcoll(mx2,my0)) printh("not traversable") return false
|
local mx2,my2=m2.mx,m2.my
|
||||||
|
if not (level:mcoll(mx0,my0) or level:mcoll(mx2,my2)) then
|
||||||
|
local dmx,dmy=abs(mx2-mx0),abs(my2-my0)
|
||||||
|
|
||||||
|
if dmx==1 and dmy==1 and level:mcoll(mx0,my2) and level:mcoll(mx2,my0) then
|
||||||
|
else
|
||||||
|
--printh("ok! "..tostring({qxs[i-2],qys[i-2]})..tostring({qxs[i],qys[i]})..tostring(m0)..tostring(m2))
|
||||||
|
ok=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not ok) return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
@ -1213,8 +1213,6 @@ function would_stick(x0,y0,anchor,x2,y2)
|
|||||||
return not wouldnt,x1_new,y1_new,adx,ady
|
return not wouldnt,x1_new,y1_new,adx,ady
|
||||||
end
|
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)
|
function rope:_drag(n1,ax1_new,ay1_new)
|
||||||
local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
|
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
|
if (ax_far0==ax_far1 and ay_far0==ay_far1) return nil
|
||||||
@ -1268,8 +1266,6 @@ function rope:_drag(n1,ax1_new,ay1_new)
|
|||||||
end
|
end
|
||||||
ax_far_old=ax_far_new
|
ax_far_old=ax_far_new
|
||||||
end
|
end
|
||||||
else
|
|
||||||
assert(false, "wtf?")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1283,7 +1279,7 @@ function rope:_drag(n1,ax1_new,ay1_new)
|
|||||||
local anch=_sweep_radar(n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new)
|
local anch=_sweep_radar(n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new)
|
||||||
if (anch==nil) break
|
if (anch==nil) break
|
||||||
local n05={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n0,next=n1}
|
local n05={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n0,next=n1}
|
||||||
printh("creating post: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with))
|
--printh("creating post: "..tostring(n0.associated_with).."->"..tostring(n05.associated_with).."->"..tostring(n1.associated_with))
|
||||||
n0.next=n05
|
n0.next=n05
|
||||||
n1.prev=n05
|
n1.prev=n05
|
||||||
n0=n05
|
n0=n05
|
||||||
@ -1295,7 +1291,7 @@ function rope:_drag(n1,ax1_new,ay1_new)
|
|||||||
local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new)
|
local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new)
|
||||||
if (anch==nil) break
|
if (anch==nil) break
|
||||||
local n15={ax=anch.ax,ay=anch.ay,associated_with=anch,prev=n1,next=n2}
|
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))
|
--printh("creating post: "..tostring(n1.associated_with).."->"..tostring(n15.associated_with).."->"..tostring(n2.associated_with))
|
||||||
n1.next=n15
|
n1.next=n15
|
||||||
n2.prev=n15
|
n2.prev=n15
|
||||||
n2=n15
|
n2=n15
|
||||||
@ -1329,24 +1325,10 @@ function _stepfrom(x0,x1)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _in_box(x,y,x0,y0,x1,y1)
|
|
||||||
x0,x1=_mnmx(x0,x1)
|
|
||||||
y0,y1=_mnmx(y0,y1)
|
|
||||||
return x0<=x and y0<=y and x<=x1 and y<=y1
|
|
||||||
end
|
|
||||||
|
|
||||||
function _which_side(x,y,x0,y0,x1,y1)
|
function _which_side(x,y,x0,y0,x1,y1)
|
||||||
return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
|
return sgn0((x1-x0)*(y-y0) - (y1-y0)*(x-x0))
|
||||||
end
|
end
|
||||||
|
|
||||||
function _linedist(x0,v,x1)
|
|
||||||
return 100 * (sum_distance(x0,v,x1)-distance(x0,x1))/distance(x0,x1)
|
|
||||||
end
|
|
||||||
|
|
||||||
function sum_distance(x,y,z)
|
|
||||||
return distance(x,y) + distance(y,z)
|
|
||||||
end
|
|
||||||
|
|
||||||
function distance_dxy(dx,dy)
|
function distance_dxy(dx,dy)
|
||||||
return sqrt(dx*dx+dy*dy)
|
return sqrt(dx*dx+dy*dy)
|
||||||
end
|
end
|
||||||
@ -1361,10 +1343,10 @@ function rope:collide_mrect(mx0,my0,mw,mh,exclude_src,exclude_dst)
|
|||||||
local mx1,my1=mx0+mw,my0+mh
|
local mx1,my1=mx0+mw,my0+mh
|
||||||
local n0=self.src
|
local n0=self.src
|
||||||
|
|
||||||
mx0+=0.1
|
mx0+=0.4
|
||||||
my0+=0.1
|
my0+=0.4
|
||||||
mx1-=0.1
|
mx1-=0.4
|
||||||
my1-=0.1
|
my1-=0.4
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local n1=n0.next
|
local n1=n0.next
|
||||||
@ -1401,18 +1383,6 @@ function _line_line(x1,y1,x2,y2,x3,y3,x4,y4)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function neighbors(p)
|
|
||||||
local r={}
|
|
||||||
for dx=-1,1,1 do
|
|
||||||
for dy=-1,1,1 do
|
|
||||||
if dx!=0 or dy!=0 then
|
|
||||||
add(r,{x=p.x+dx,y=p.y+dy})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return r
|
|
||||||
end
|
|
||||||
|
|
||||||
-->8
|
-->8
|
||||||
-- moved here because it's complicated
|
-- moved here because it's complicated
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user