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