BlockMen / cme

Creatures MOB-Engine for Minetest
Other
18 stars 10 forks source link

Bug in eat_node call (the "sheep bug") #14

Open Acuddle opened 7 years ago

Acuddle commented 7 years ago

I got annoyed at the "sheep bug" that make the server crash ever now and then and had previously reported by enigma and ParaklataChotou of the minetest forums. 2016-07-22 17:31:09: ERROR[Main]: ServerError: Lua: Runtime error from mod 'sheep' in callback luaentity_Step(): {location of minetest directory}/.minetest/mods/cme/creatures/functions.lua:483: attempt to index field 'last_node' (a nil value) 2016-07-22 17:31:09: ERROR[Main]: stack traceback: 2016-07-22 17:31:09: ERROR[Main]: {location of minetest directory}/.minetest/mods/cme/creatures/functions.lua:483: in function 'on_step' 2016-07-22 17:31:09: ERROR[Main]: {location of minetest directory} /.minetest/mods/cme/creatures/register.lua:216: in function <{location of minetest directory}/.minetest/mods/cme/creatures/register.lua:211>

I had a stab at it and maybe found the origin of the error. It happens when the sheeps eat.

  if current_mode == "eat" and not self.eat_node then
    local nodes = modes[current_mode].nodes
    local p = {x = current_pos.x, y = current_pos.y - 1, z = current_pos.z}
    local sn = core.get_node_or_nil(p)
    local eat_node
    for _,name in pairs(nodes) do
      if name == self.last_node.name then
        eat_node = current_pos
        break
      elseif sn and sn.name == name then
        eat_node = p
        break
      end
    end
    if not eat_node then
      current_mode = "idle"
    else
      self.eat_node = eat_node
    end
  end

I do not have any experience in Lua and I don't know when self.last_node would be nil (maybe if the sheep is in mid-air while eating, which may be true if the sheep is "dangling" to a node while being directly at the top of none), but I went and put a verification at the beginning.

  if current_mode == "eat" and not self.eat_node then
    local nodes = modes[current_mode].nodes
    local p = {x = current_pos.x, y = current_pos.y - 1, z = current_pos.z}
    local sn = core.get_node_or_nil(p)
    local eat_node
    for _,name in pairs(nodes) do
      if not self.last_node then
        break
      else
        if name == self.last_node.name then
          eat_node = current_pos
          break
        elseif sn and sn.name == name then
          eat_node = p
          break
        end
      end

    end

    if not eat_node then
      current_mode = "idle"
    else
      self.eat_node = eat_node
    end
  end

I don't know if the fix worked, but it doesn't crash when the sheep eat normally, so I guess it's better than nothing. The "sn" variable may be useful in more precise fixing (it would depend on the propension of the core.get_node_or_nil to get nodes and no nils).

Here's the "fixed" functions.lua (in a zip, sorry for the inconvenience).

functions.zip

diogogomes commented 7 years ago

@BlockMen has abandoned the development of this repository.

Please, open issues and make pull requests in Mob Engine of Minetest Mods Team.