forked from pyrex/chameleonic
		
	main #21
| @@ -633,10 +633,12 @@ end | ||||
|  | ||||
| ropecheck=split"-0.6,0.4,0.4" | ||||
|  | ||||
| -- argument "o" is a rope operation: | ||||
| -- array of [mx0,my0,dmx,dmy] | ||||
| function level:can_move( | ||||
|  is_player, | ||||
|  mx0,my0,dmx,dmy,exclude_src,exclude_dst | ||||
|  is_player,o,exclude_src,exclude_dst | ||||
| ) | ||||
|  local mx0,my0,dmx,dmy=unpack(o) | ||||
|  local mx1,my1=mx0+dmx,my0+dmy | ||||
|  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() | ||||
| @@ -652,7 +654,12 @@ function level:can_move( | ||||
|  return true | ||||
| end | ||||
|  | ||||
| function level:tug_crate(mx0,my0,dmx,dmy) | ||||
| -- argument is a rope operation: | ||||
| --  array of [mx0,my0,dmx,dmy] | ||||
| -- must be a free function | ||||
| --   to use as a foreach target | ||||
| function level_tug_crate(t) | ||||
|  local self,mx0,my0,dmx,dmy=level,unpack(t) | ||||
|  local mxy0=_mix{mx0,my0} | ||||
|  local existing=self._crates[mxy0] | ||||
|  if (not existing) return | ||||
| @@ -734,7 +741,7 @@ function player:update() | ||||
|   else | ||||
|    local x,y=self.x,self.y | ||||
|    local function try_move(dx,dy,f) | ||||
|     if level:can_move(true,x,y,dx,dy,0,2) then  | ||||
|     if level:can_move(true,{x,y,dx,dy},0,2) then  | ||||
|      self.todo=f  | ||||
|      self.cooldown=3 | ||||
|      local t=f[#f] | ||||
| @@ -1540,22 +1547,19 @@ function rope:_tug(hypothetically) | ||||
|  local blocks = {} | ||||
|  for i=#ancs-1,2,-1 do | ||||
|   local ops_before_trash,blocks_before_trash=self:_calc_push(ancs[i+1],ancs[i],ancs[i-1],ancs[i-2]) | ||||
|   local ops_to_do,corners={} | ||||
|   local ops = {} | ||||
|   for b in all(blocks_before_trash) do add(blocks, b) end | ||||
|   if #ops_before_trash>0 then  | ||||
|    ops_to_do=ops_before_trash | ||||
|    ops=ops_before_trash | ||||
|   else  | ||||
|    local ops_after_trash,blocks_after_trash=self:_calc_push(ancs[i-2],ancs[i-1],ancs[i],ancs[i+1]) | ||||
|    ops_to_do=ops_after_trash | ||||
|    ops=ops_after_trash | ||||
|    for b in all(blocks_after_trash) do add(blocks,b) end | ||||
|   end | ||||
|  | ||||
|   local ops=ops_to_do | ||||
|  | ||||
|   if #ops>0 then | ||||
|    if (hypothetically) return ancs,i-1,ops,blocks | ||||
|  | ||||
|    for o in all(ops) do level:tug_crate(unpack(o)) end | ||||
|    foreach(ops, level_tug_crate) | ||||
|    return true | ||||
|   end | ||||
|  end | ||||
| @@ -1604,13 +1608,14 @@ function rope:_tug(hypothetically) | ||||
|   end | ||||
|    | ||||
|   if not invalid_move then | ||||
|    if level:can_move(false,mx0,my0,dmx,dmy,1,0) then | ||||
|     if (hypothetically) return ancs,0,{{mx0,my0,dmx,dmy}},blocks | ||||
|    local mv = {mx0,my0,dmx,dmy} | ||||
|    if level:can_move(false,mv,1,0) then | ||||
|     if (hypothetically) return ancs,0,{mv},blocks | ||||
|  | ||||
|     level:tug_crate(mx0,my0,dmx,dmy)  | ||||
|     level_tug_crate(mv)  | ||||
|     return true | ||||
|    else | ||||
|     add(blocks, {mx0,my0,dmx,dmy}) | ||||
|     add(blocks, mv) | ||||
|    end | ||||
|   end | ||||
|  end | ||||
| @@ -1640,21 +1645,16 @@ function rope:_calc_push( | ||||
|    smy=-smy | ||||
|   end | ||||
|    | ||||
|   local mx,dmx | ||||
|   local dmx=1 -- maybe push right? | ||||
|   if anch.adx==-1 and a0.x>an.x+7 then | ||||
|    -- push left | ||||
|    mx=ax0-1 | ||||
|    dmx=-1 | ||||
|   elseif anch.adx==1 and a0.x<an.x-7 then | ||||
|    -- push right | ||||
|    mx=ax0 | ||||
|    dmx=1 | ||||
|   else | ||||
|    ax0, dmx=ax0-1,-1 | ||||
|   elseif anch.adx!=1 or a0.x>=an.x-7 then | ||||
|    return {} | ||||
|   end | ||||
|    | ||||
|   for my=my0,my1,smy do | ||||
|    add(ops,{mx,my,dmx,0}) | ||||
|    add(ops,{ax0,my,dmx,0}) | ||||
|   end | ||||
|  end | ||||
|   | ||||
| @@ -1666,38 +1666,26 @@ function rope:_calc_push( | ||||
|    smx=-smx | ||||
|   end | ||||
|    | ||||
|   local my,dmy | ||||
|   local dmy=1 -- maybe push down? | ||||
|   if anch.ady==-1 and a0.y>an.y+6 then | ||||
|    -- push up | ||||
|    my=ay0-1 | ||||
|    dmy=-1 | ||||
|     | ||||
|   elseif anch.ady==1 and a0.y<an.y-6 then | ||||
|    -- push down | ||||
|    my=ay0 | ||||
|    dmy=1 | ||||
|   else | ||||
|    ay0,dmy=ay0-1,-1 | ||||
|   elseif anch.ady!=1 or a0.y>=an.y-6 then | ||||
|    return {} | ||||
|   end | ||||
|    | ||||
|   for mx=mx0,mx1,smx do | ||||
|    add(ops,{mx,my,0,dmy}) | ||||
|    add(ops,{mx,ay0,0,dmy}) | ||||
|   end | ||||
|  end | ||||
|  | ||||
|  local ops2,blocked={},{} | ||||
|  for o in all(ops) do | ||||
|   local mx,my,dmx,dmy=unpack(o) | ||||
|   if not level:mcoll(mx,my) then | ||||
|    -- great! | ||||
|   else | ||||
|    local crate=level:get_crate(mx,my) | ||||
|    if crate then | ||||
|     if not level:can_move(false,mx,my,dmx,dmy,0,0) then | ||||
|      add(blocked,o) | ||||
|      break | ||||
|     end | ||||
|    else | ||||
|   local mx,my=unpack(o) | ||||
|   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) | ||||
|     break | ||||
|    end | ||||
|    add(ops2,o) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user