Deal with Creatures being deleted before a battle they're part of.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Signed-off-by: Deukhoofd <Deukhoofd@gmail.com>
This commit is contained in:
parent
d89e0b0d77
commit
512a39e158
|
@ -54,7 +54,7 @@ void BattleSide::SetCreature(ArbUt::OptionalBorrowedPtr<Creature> creature, uint
|
||||||
if (old.HasValue()) {
|
if (old.HasValue()) {
|
||||||
old.GetValue()->SetOnBattleField(false);
|
old.GetValue()->SetOnBattleField(false);
|
||||||
}
|
}
|
||||||
_creatures[index] = creature.GetValue();
|
_creatures[index] = creature;
|
||||||
if (!creature.HasValue()) {
|
if (!creature.HasValue()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace CreatureLib::Battling {
|
||||||
void SetChoice(BaseTurnChoice* choice);
|
void SetChoice(BaseTurnChoice* choice);
|
||||||
void ResetChoices() noexcept;
|
void ResetChoices() noexcept;
|
||||||
|
|
||||||
|
void ForceClearCreature(uint8_t index) { _creatures[index] = {}; }
|
||||||
void SetCreature(ArbUt::OptionalBorrowedPtr<Creature> creature, uint8_t index);
|
void SetCreature(ArbUt::OptionalBorrowedPtr<Creature> creature, uint8_t index);
|
||||||
|
|
||||||
const ArbUt::OptionalBorrowedPtr<Creature>& GetCreature(uint8_t index) const;
|
const ArbUt::OptionalBorrowedPtr<Creature>& GetCreature(uint8_t index) const;
|
||||||
|
|
|
@ -391,4 +391,10 @@ void CreatureLib::Battling::Creature::ClearStatus() {
|
||||||
if (_battleData.Battle.HasValue()) {
|
if (_battleData.Battle.HasValue()) {
|
||||||
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
|
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Battling::Creature::~Creature() {
|
||||||
|
if (_battleData.OnBattleField && _battleData.Side.HasValue()) {
|
||||||
|
_battleData.Side.GetValue()->ForceClearCreature(_battleData.Index.GetCreatureIndex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace CreatureLib::Battling {
|
||||||
const Library::TalentIndex& talent, const std::vector<LearnedAttack*>& attacks,
|
const Library::TalentIndex& talent, const std::vector<LearnedAttack*>& attacks,
|
||||||
bool allowedExperienceGain = true);
|
bool allowedExperienceGain = true);
|
||||||
|
|
||||||
virtual ~Creature() = default;
|
virtual ~Creature();
|
||||||
|
|
||||||
virtual void Initialize() {
|
virtual void Initialize() {
|
||||||
RecalculateFlatStats();
|
RecalculateFlatStats();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifdef TESTS_BUILD
|
#ifdef TESTS_BUILD
|
||||||
#include "../../extern/doctest.hpp"
|
#include "../../extern/doctest.hpp"
|
||||||
|
#include "../../src/Battling/Models/Battle.hpp"
|
||||||
#include "../../src/Battling/Models/CreateCreature.hpp"
|
#include "../../src/Battling/Models/CreateCreature.hpp"
|
||||||
#include "../TestLibrary/TestLibrary.hpp"
|
#include "../TestLibrary/TestLibrary.hpp"
|
||||||
|
|
||||||
|
@ -54,4 +55,16 @@ TEST_CASE("Override Creature talent") {
|
||||||
delete creature;
|
delete creature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Creature can be deleted before battle is deleted") {
|
||||||
|
// This should not happen during normal battle executions, but can happen for certain GC solutions. We should not
|
||||||
|
// segfault in this case, but deal with it properly.
|
||||||
|
auto library = TestLibrary::Get();
|
||||||
|
auto creature = CreateCreature(library, "testSpecies1"_cnc, 1).Create();
|
||||||
|
auto battle = new Battle(library, {});
|
||||||
|
auto side = battle->GetSides()[0];
|
||||||
|
side->SetCreature(creature, 0);
|
||||||
|
delete creature;
|
||||||
|
delete battle;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue