forked from pyrex/chameleonic
main #21
@ -129,11 +129,12 @@ end
|
||||
|
||||
|
||||
function _rast(
|
||||
xs,ys,x0,y0,x1,y1
|
||||
xys,x0,y0,x1,y1
|
||||
)
|
||||
local function _add()
|
||||
local n=#xs
|
||||
if (n==0 or xs[n]!=x0 or ys[n]!=y0) add(xs,x0) add(ys,y0)
|
||||
local n=#xys
|
||||
local xy0={x0,y0}
|
||||
if (n==0 or not _anch_eq(xys[n],xy0)) add(xys,xy0)
|
||||
end
|
||||
|
||||
local dx,dy=abs(x1-x0),abs(y1-y0)
|
||||
@ -432,10 +433,10 @@ function level:recollide_reanchor()
|
||||
local mx1,my1=mx0+dx,my0+dy
|
||||
|
||||
if (
|
||||
self:mcoll(mx0,my0) and not self:get_crate(mx0,my0) and
|
||||
not self:mcoll(mx0,my1) and
|
||||
not self:mcoll(mx1,my0) and
|
||||
not self:mcoll(mx1,my1)
|
||||
self:mcoll{mx0,my0} and not self:get_crate(mx0,my0) and
|
||||
not self:mcoll{mx0,my1} and
|
||||
not self:mcoll{mx1,my0} and
|
||||
not self:mcoll{mx1,my1}
|
||||
) then
|
||||
local key=_mix{"GEOM",mx0,my0,dx,dy}
|
||||
anch_new[key]= {
|
||||
@ -543,7 +544,8 @@ function level:spawn_exit()
|
||||
assert(spawned)
|
||||
end
|
||||
|
||||
function level:mcoll(mx,my)
|
||||
function level:mcoll(mxy)
|
||||
local mx,my=unpack(mxy)
|
||||
if ((mx | my) & 0xFFF0!=0) return true
|
||||
return self._coll[_mix{mx,my}]
|
||||
end
|
||||
@ -628,7 +630,7 @@ function level:can_move(
|
||||
if (is_player and self:win_at(mx1,my1)) return true
|
||||
if (is_player and self:get_open_pit(mx1,my1)) return wrongbleep:adequately_warned()
|
||||
|
||||
if (self:mcoll(mx1,my1) or player.x==mx1 and player.y==my1) return
|
||||
if (self:mcoll{mx1,my1} or player.x==mx1 and player.y==my1) return
|
||||
|
||||
if player.rope then
|
||||
local w,h=1.2,0.2
|
||||
@ -748,7 +750,7 @@ function player:update()
|
||||
local dx,dy=self.orientx,self.orienty
|
||||
if (dy!=0) dx=0
|
||||
|
||||
while not level:mcoll(x,y) do x+=dx y+=dy end
|
||||
while not level:mcoll{x,y} do x+=dx y+=dy end
|
||||
|
||||
self.rope=rope:new(
|
||||
{x+0.5-dx*0.5,y+0.5-dy*0.5},
|
||||
@ -1131,60 +1133,43 @@ function rope:_check_pinch()
|
||||
|
||||
local n0=self.src
|
||||
|
||||
local qxs,qys={},{}
|
||||
local qxys={}
|
||||
while true do
|
||||
local n1=n0.next
|
||||
if (not n1) break
|
||||
|
||||
local n0ax,n0ay=_anch_unpack(n0)
|
||||
local n1ax,n1ay=_anch_unpack(n1)
|
||||
_rast(qxs,qys,flr(n0ax*2),flr(n0ay*2),flr(n1ax*2),flr(n1ay*2))
|
||||
_rast(qxys,n0ax\0.5,n0ay\0.5,n1ax\0.5,n1ay\0.5)
|
||||
n0=n1
|
||||
end
|
||||
|
||||
local function _possible_tiles(qx,qy)
|
||||
local mx0=(qx-1)\2
|
||||
local mx1=qx\2
|
||||
local my0=(qy-1)\2
|
||||
local my1=qy\2
|
||||
|
||||
local function _possible_tiles(t)
|
||||
local qx,qy=unpack(qxys[t])
|
||||
local poss={}
|
||||
for mx=mx0,mx1 do
|
||||
for my=my0,my1 do
|
||||
add(poss,{mx=mx,my=my})
|
||||
for mx=(qx-1)\2,qx\2 do
|
||||
for my=(qy-1)\2,qy\2 do
|
||||
if (not level:mcoll{mx,my}) add(poss,{mx,my})
|
||||
end
|
||||
end
|
||||
return poss
|
||||
end
|
||||
local function _blocked(qx,qy)
|
||||
for i in all(_possible_tiles(qx,qy)) do
|
||||
if (not level:mcoll(i.mx,i.my)) return
|
||||
end
|
||||
return true
|
||||
return all(poss)
|
||||
end
|
||||
|
||||
-- find cases where i move through an impassable zone
|
||||
for i=1,#qxs do
|
||||
if (_blocked(qxs[i],qys[i])) return
|
||||
for i=1,#qxys do
|
||||
if (not _possible_tiles(i)()) return
|
||||
end
|
||||
|
||||
-- find cases where i am cut off diagonally
|
||||
for i=3,#qxs do
|
||||
local qx1,qy1=qxs[i-1],qys[i-1]
|
||||
if qx1%2==0 and qy1%2==0 then
|
||||
for i=3,#qxys do
|
||||
local qx1,qy1=unpack(qxys[i-1])
|
||||
if (qx1|qy1)&1==0 then
|
||||
local ok
|
||||
for m0 in all(_possible_tiles(qxs[i-2],qys[i-2])) do
|
||||
for m2 in all(_possible_tiles(qxs[i],qys[i])) do
|
||||
local mx0,my0=m0.mx,m0.my
|
||||
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
|
||||
ok=true
|
||||
end
|
||||
end
|
||||
for m0 in _possible_tiles(i-2) do
|
||||
for m2 in _possible_tiles(i) do
|
||||
local mx0,my0=unpack(m0)
|
||||
local mx2,my2=unpack(m2)
|
||||
if (mx0==mx2 or my0==my2 or not level:mcoll{mx0,my2} or not level:mcoll{mx2,my0}) ok=true
|
||||
end
|
||||
end
|
||||
|
||||
@ -1631,7 +1616,7 @@ function rope:_calc_push(
|
||||
local ops2,blocked={},{}
|
||||
for o in all(ops) do
|
||||
local mx,my=unpack(o)
|
||||
if level:mcoll(mx,my) then
|
||||
if level:mcoll{mx,my} then
|
||||
if (not level:get_crate(mx, my)) break
|
||||
if not level:can_move(false,o,0,0) then
|
||||
add(blocked,o)
|
||||
|
Loading…
Reference in New Issue
Block a user