From 1c6b7b350a046df622a8c9eba27eb9508448ba0d Mon Sep 17 00:00:00 2001 From: Eric Branlund Date: Thu, 6 Jun 2024 13:50:48 -0600 Subject: [PATCH] Change how chunk_copy() skips ghost not used from the source chunk 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 https://github.com/NickMcConnell/FAangband/pull/423 and possible now that delete_monster_idx() takes a chunk argument. --- src/gen-chunk.c | 25 +++++++++++++++++++++++-- src/mon-make.c | 8 ++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/gen-chunk.c b/src/gen-chunk.c index be2ce9df7..5460b2229 100644 --- a/src/gen-chunk.c +++ b/src/gen-chunk.c @@ -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) { @@ -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); @@ -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; } diff --git a/src/mon-make.c b/src/mon-make.c index 7e7a3cea7..055c0b57d 100644 --- a/src/mon-make.c +++ b/src/mon-make.c @@ -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 */