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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user