Skip to content

Commit

Permalink
Change how chunk_copy() skips ghost not used from the source chunk
Browse files Browse the repository at this point in the history
Also use passed chunk argument rather than cave when resetting the ghost in delete_monster_idx().

Avoids an assertion failure copying over the monster groups when both chunks have a ghost.

This is cleaner than #423 and possible now that delete_monster_idx() takes a chunk argument.
  • Loading branch information
backwardsEric authored and NickMcConnell committed Jun 6, 2024
1 parent ac430bd commit 1c6b7b3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
25 changes: 23 additions & 2 deletions src/gen-chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ bool chunk_copy(struct chunk *dest, struct player *p, struct chunk *source,
struct loc grid;
int h = source->height, w = source->width;
int mon_skip = dest->mon_max - 1;
int skipped_ghost_id = -1;

/* Check bounds */
if (rotate % 1) {
Expand Down Expand Up @@ -430,9 +431,17 @@ bool chunk_copy(struct chunk *dest, struct player *p, struct chunk *source,
/* Deal with player ghosts */
if (source_mon->race &&
rf_has(source_mon->race->flags, RF_PLAYER_GHOST)) {
/* Only allow one ghost */
/*
* Only allow one ghost, preferring the ghost from
* the destination if both chunks have a ghost.
* Remember a ghost from the source that was not
* put in dest->ghost so it can be deleted once the
* monsters and monster groups are copied.
*/
if (dest->ghost->bones_selector) {
continue;
/* source should not have multiple ghosts. */
assert(skipped_ghost_id == -1);
skipped_ghost_id = source_mon->midx + mon_skip;
} else {
/* Shift the ghost */
mem_free(dest->ghost);
Expand Down Expand Up @@ -521,6 +530,18 @@ bool chunk_copy(struct chunk *dest, struct player *p, struct chunk *source,
if (source->good_item)
dest->good_item = true;

if (skipped_ghost_id != -1) {
/*
* dest->ghost does not refer to the ghost at skipped_ghost_id
* so remember it and restore it after delete_monster_idx()
* does its work.
*/
struct ghost_info preserved_ghost = *dest->ghost;

delete_monster_idx(dest, skipped_ghost_id);
*dest->ghost = preserved_ghost;
}

return true;
}

Expand Down
8 changes: 4 additions & 4 deletions src/mon-make.c
Original file line number Diff line number Diff line change
Expand Up @@ -995,10 +995,10 @@ void delete_monster_idx(struct chunk *c, int m_idx)
if (player->upkeep->monster_race == mon->race) {
player->upkeep->monster_race = NULL;
}
cave->ghost->bones_selector = 0;
cave->ghost->has_spoken = false;
cave->ghost->string_type = 0;
my_strcpy(cave->ghost->string, "", sizeof(cave->ghost->string));
c->ghost->bones_selector = 0;
c->ghost->has_spoken = false;
c->ghost->string_type = 0;
my_strcpy(c->ghost->string, "", sizeof(c->ghost->string));
}

/* Wipe the Monster */
Expand Down

0 comments on commit 1c6b7b3

Please sign in to comment.