Skip to content

Hunting monster approaches stairs faster than expected #784

@brturn

Description

@brturn

Reported by Bentwing on Discord

The reported behavior is that a burning Zombie moves toward the stairs 5 "steps" in the time it takes the player to go up, then back down the stairs.

This is difficult to reproduce, so the following analysis is based on reading the code, not reproducing the behavior seen.

ANALYSIS

When a monster is hunting the player, and the player leaves the level, the monster gains a new status STATUS_ENTERS_LEVEL_IN:

monst->status[STATUS_ENTERS_LEVEL_IN] = clamp(mapToStairs[monst->loc.x][monst->loc.y] * monst->movementSpeed / 100 + 1, 1, 150);

This status tracks the number of steps the monster will take while the player is on another level. In the normal case, the status will count down and the monster will enter the level:

BrogueCE/src/brogue/Time.c

Lines 1955 to 1956 in 2e0ea9a

} else if (monst->status[STATUS_ENTERS_LEVEL_IN] == 1) {
monsterEntersLevel(monst, n);

If the player returns to the level before the monster makes it all the way to the stairs, monsters on that level are restored to their locations and states via restoreMosnter():

void restoreMonster(creature *monst, short **mapToStairs, short **mapToPit) {

A monster that has STATUS_ENTERS_LEVEL_IN must be handled differently, since it will have traversed some distance while the player was away:

if (monst->status[STATUS_ENTERS_LEVEL_IN] > 0) {

Once a new location is computed for the monster, the final placement location is chosen via getQualifyingPathLocNear(), which picks a legal location for the monster given a set of flags:

pos qualifiedPosition = getQualifyingPathLocNear((pos){ *x, *y }, true, T_DIVIDES_LEVEL & avoidedFlagsForMonster(&(monst->info)), 0,
avoidedFlagsForMonster(&(monst->info)), (HAS_MONSTER | HAS_PLAYER | HAS_STAIRS | IS_IN_MACHINE), true);

This is unproven, but I believe what is happening is the following:

  1. A burning zombie generates gas which is ignited around it. The zombie moves slowly, but the gas is generated quickly. So on any given turn, the zombie is often surrounded by a halo of 1-2 tiles of burning gas.
  2. Burning gas has the terrain flag T_IS_FIRE.
  3. The call to getQualifyingPathLocNear() passes a set of flags returned from avoidedFlagsForMonster()
  4. Zombies are not immune to fire, so the flag set forces the selection of a tile which is NOT on fire.
  5. The closest tile to the desired location, which is not on fire, is several spaces closer to the player than what would be expected in normal gameplay.

POTENTIAL FIX:

Allow tiles which the monster would already be willing to step into (eg. monsters on fire will continue to walk through fire).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions