diff --git a/src/dungeon_data.c b/src/dungeon_data.c index 4d09247121..d280be9a03 100644 --- a/src/dungeon_data.c +++ b/src/dungeon_data.c @@ -203,8 +203,7 @@ struct Thing *get_player_soul_container(PlayerNumber plyr_idx) TbBool player_has_heart(PlayerNumber plyr_idx) { - struct Dungeon* dungeon = get_players_num_dungeon(plyr_idx); - return (thing_exists(get_player_soul_container(plyr_idx)) && dungeon->heart_destroy_turn <= 0); + return thing_exists(get_player_soul_container(plyr_idx)); } /** Returns if given dungeon contains a room of given kind. diff --git a/src/game_loop.c b/src/game_loop.c index 4855567e89..037f557ac4 100644 --- a/src/game_loop.c +++ b/src/game_loop.c @@ -21,6 +21,7 @@ #include "thing_list.h" #include "player_computer.h" #include "thing_effects.h" +#include "thing_navigate.h" #include "thing_objects.h" #include "room_data.h" #include "room_library.h" @@ -95,8 +96,7 @@ void process_dungeon_destroy(struct Thing* heartng) } TbBool no_backup = !(dungeon->backup_heart_idx > 0); powerful_magic_breaking_sparks(heartng); - const struct Coord3d* central_pos; - central_pos = &heartng->mappos; + struct Coord3d* central_pos = &heartng->mappos; switch (dungeon->heart_destroy_state) { case 1: @@ -108,7 +108,10 @@ void process_dungeon_destroy(struct Thing* heartng) { if ((dungeon->heart_destroy_turn == 10) && (dungeon->free_soul_idx == 0)) { - soultng = create_creature(&dungeon->mappos, get_players_spectator_model(plyr_idx), plyr_idx); + if (thing_is_invalid(soultng)) + { + soultng = create_creature(central_pos, get_players_spectator_model(plyr_idx), plyr_idx); + } if (!thing_is_invalid(soultng)) { dungeon->num_active_creatrs--; @@ -130,8 +133,12 @@ void process_dungeon_destroy(struct Thing* heartng) else if (dungeon->heart_destroy_turn == 25) { struct Thing* bheartng = thing_get(dungeon->backup_heart_idx); - soultng->mappos = bheartng->mappos; - soultng->mappos.z.val = get_ceiling_height_at(&bheartng->mappos); + if (thing_is_creature_spectator(soultng)) + { + struct Coord3d movepos = bheartng->mappos; + movepos.z.val = get_ceiling_height_at(&movepos); + move_thing_in_map(soultng, &movepos); + } } else if (dungeon->heart_destroy_turn == 28) { @@ -202,7 +209,7 @@ void process_dungeon_destroy(struct Thing* heartng) struct PlayerInfo* player; player = get_player(plyr_idx); init_player_start(player, true); - if (player_has_heart(plyr_idx)) + if (player_has_heart(plyr_idx) && (dungeon->heart_destroy_turn <= 0)) { // If another heart was found, stop the process dungeon->devastation_turn = 0; diff --git a/src/thing_creature.c b/src/thing_creature.c index 2df3c056c9..4fddc124a8 100644 --- a/src/thing_creature.c +++ b/src/thing_creature.c @@ -3906,6 +3906,25 @@ TbBool thing_is_creature_special_digger(const struct Thing *thing) return ((get_creature_model_flags(thing) & CMF_IsSpecDigger) != 0); } +/** Returns if a thing the creature type set as spectator, normally the floating spirit. + * @param thing The thing to be checked. + * @return True if the thing is creature and listed as spectator , false otherwise. + */ +TbBool thing_is_creature_spectator(const struct Thing* thing) +{ + if (!thing_is_creature(thing)) + return false; + + ThingModel breed = game.conf.crtr_conf.spectator_breed; + if (breed == 0) + { + WARNLOG("There is no spectator breed"); + breed = game.conf.crtr_conf.special_digger_good; + } + return (thing->model == breed); +} + + void anger_set_creature_anger_all_types(struct Thing *thing, long new_value) { if (creature_can_get_angry(thing)) diff --git a/src/thing_creature.h b/src/thing_creature.h index cf4ff3e12f..8a58b6ef6c 100644 --- a/src/thing_creature.h +++ b/src/thing_creature.h @@ -198,6 +198,7 @@ TbBool creature_can_be_queried(struct PlayerInfo *player, struct Thing *creatng) TbBool thing_is_creature(const struct Thing *thing); TbBool thing_is_dead_creature(const struct Thing *thing); TbBool thing_is_creature_special_digger(const struct Thing *thing); +TbBool thing_is_creature_spectator(const struct Thing *thing); TbBool creature_is_slappable(const struct Thing *thing, PlayerNumber plyr_idx); TbBool creature_is_invisible(const struct Thing *thing); TbBool creature_can_see_invisible(const struct Thing *thing);