Opened 14 years ago

Closed 14 years ago

#211 closed bug (fixed)

Level.isAlive isn't robust

Reported by: tehtmi Owned by: epyon
Priority: minor Milestone: 0.9.9.4
Component: engine Version: 0.9.9.3
Keywords: Cc:
Blocked By: Blocking:

Description

Level.isAlive (in pascal) checks if a being is alive by checking if the entry in Beings is nil. However, if the being is dead but a new being has been created in the meantime, Level.isAlive will return the wrong value.

This caused a crash here:
CForum:4376

Presumably, the former human fired at the barrel killing himself, then killing a pain elemental. The lost souls created by the pain elemental's death filled in the former human's slot in Beings, causing the observed failure of Level.isAlive.

Change History (4)

comment:1 Changed 14 years ago by tehtmi

  • Resolution set to invalid
  • Status changed from new to closed

It seems this was already fixed.

comment:2 Changed 14 years ago by tehtmi

  • Resolution invalid deleted
  • Status changed from closed to reopened

Actually, it wasn't fixed. I didn't realize there were two versions of isAlive. The relevant one here is the BeingNum? one.

comment:3 Changed 14 years ago by tehtmi

I can consistently reproduce this bug by using this function to set up the scenario:

function TR211()
  local pain
  local former
  for b in Level.beings() do
    if b ~= player then
      b:destroy(true)
    end
  end
  former = Level.drop_being("former", coord.new(4, 2))
  if former then
    for i = 1, 100 do
      if Level.get_being(i) == former then
        ui.msg("Former Human: #" .. i)
        break
      end
    end
  else
    return
  end
  pain = Level.drop_being("pain", coord.new(8, 2))
  if pain then
    pain.speed = 0
    pain.hp = 1
    for i = 1, 100 do
      if Level.get_being(i) == pain then
        ui.msg("Pain elemental: #" .. i)
        break
      end
    end
  else
    return
  end
  Level[coord.new(6, 2)] = "barrel"
  thing.displace(player, coord.new(11, 2))
end

The pain elemental is immobilized. Wait for the former to blow up the barrel. If the barrel doesn't kill the lost soul that takes the former's spot, then the crash will occur.

comment:4 Changed 14 years ago by epyon

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [1656]) * UID system implemented

  • isAlive(num) reimplemented with num x uid pairs (fixes #211)
  • level.get_being_by_uid and level.get_item_by_uid added for modders
Note: See TracTickets for help on using tickets.