Overhaul memory model to new Arbutils memory.
Some checks failed
continuous-integration/drone/push Build is failing

Signed-off-by: Deukhoofd <Deukhoofd@gmail.com>
This commit is contained in:
2020-12-12 12:22:48 +01:00
parent 1dc3aafd33
commit 5c39694f19
33 changed files with 279 additions and 211 deletions

View File

@@ -15,9 +15,9 @@ namespace CreatureLib::Battling {
return 1;
}
static ArbUt::List<ArbUt::BorrowedPtr<Creature>> ResolveTargets(const CreatureIndex& index,
CreatureLib::Library::AttackTarget target,
const ArbUt::BorrowedPtr<Battle>& battle) {
static ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>>
ResolveTargets(const CreatureIndex& index, CreatureLib::Library::AttackTarget target,
const ArbUt::BorrowedPtr<Battle>& battle) {
switch (target) {
case CreatureLib::Library::AttackTarget::Adjacent: {
return {battle->GetCreature(index)};
@@ -32,14 +32,15 @@ namespace CreatureLib::Battling {
return {battle->GetCreature(index)};
};
case CreatureLib::Library::AttackTarget::All: {
ArbUt::BorrowedPtr<Creature> arr[battle->GetCreaturesPerSide() * battle->GetSides().Count()];
ArbUt::OptionalBorrowedPtr<Creature>
arr[battle->GetCreaturesPerSide() * battle->GetSides().Count()];
size_t i = 0;
for (auto side : battle->GetSides()) {
for (auto mon : side->GetCreatures()) {
arr[i++] = mon;
}
}
return ArbUt::List<ArbUt::BorrowedPtr<Creature>>(arr, arr + i);
return ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>>(arr, arr + i);
}
case CreatureLib::Library::AttackTarget::AllAdjacent: {
auto left = index.GetCreatureIndex() - 1;
@@ -77,20 +78,20 @@ namespace CreatureLib::Battling {
}
}
case CreatureLib::Library::AttackTarget::AllAlly: {
ArbUt::BorrowedPtr<Creature> arr[battle->GetCreaturesPerSide()];
ArbUt::OptionalBorrowedPtr<Creature> arr[battle->GetCreaturesPerSide()];
size_t i = 0;
for (auto mon : battle->GetSides()[index.GetSideIndex()]->GetCreatures()) {
arr[i++] = mon;
}
return ArbUt::List<ArbUt::BorrowedPtr<Creature>>(arr, arr + i);
return ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>>(arr, arr + i);
};
case CreatureLib::Library::AttackTarget::AllOpponent: {
ArbUt::BorrowedPtr<Creature> arr[battle->GetCreaturesPerSide()];
ArbUt::OptionalBorrowedPtr<Creature> arr[battle->GetCreaturesPerSide()];
size_t i = 0;
for (auto mon : battle->GetSides()[index.GetSideIndex()]->GetCreatures()) {
arr[i++] = mon;
}
return ArbUt::List<ArbUt::BorrowedPtr<Creature>>(arr, arr + i);
return ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>>(arr, arr + i);
};
case CreatureLib::Library::AttackTarget::Any: {
return {battle->GetCreature(index)};

View File

@@ -15,14 +15,14 @@ void TurnHandler::RunTurn(ArbUt::BorrowedPtr<ChoiceQueue> queue) {
auto item = queue->Dequeue();
AssertNotNull(item)
AssertNotNull(item->GetUser())
AssertNotNull(item->GetUser()->GetBattle())
AssertNotNull(item->GetUser()->GetBattleSide())
auto index = (uint32_t)item->GetUser()->GetBattleSide()->GetCreatureIndex(item->GetUser());
Assert(item->GetUser()->GetBattle().HasValue())
Assert(item->GetUser()->GetBattleSide().HasValue())
auto index = (uint32_t)item->GetUser()->GetBattleSide().GetValue()->GetCreatureIndex(item->GetUser());
try_creature(ExecuteChoice(item.get()),
"Executing choice failed for choice by mon on side "
<< ((uint32_t)item->GetUser()->GetBattleSide()->GetSideIndex()) << " and index " << index
<< ". Choice had choice kind "
<< ((uint32_t)item->GetUser()->GetBattleSide().GetValue()->GetSideIndex()) << " and index "
<< index << ". Choice had choice kind "
<< CreatureLib::Battling::TurnChoiceKindHelper::ToString(item->GetKind()) << " "
<< " with message");
}
@@ -37,14 +37,15 @@ void TurnHandler::ExecuteChoice(ArbUt::BorrowedPtr<BaseTurnChoice> choice) {
}
auto user = choice->GetUser();
AssertNotNull(user)
if (user->GetBattle()->HasEnded())
if (!user->GetBattle().HasValue())
return;
auto battle = user->GetBattle().GetValue();
if (battle->HasEnded())
return;
// If the user is fainted, we don't want to execute its choice.
if (user->IsFainted()) {
return;
}
auto battle = user->GetBattle();
AssertNotNull(battle)
// If the user is not in the field, we don't want to execute its choice.
if (!user->IsOnBattleField()) {
return;
@@ -76,8 +77,9 @@ void TurnHandler::ExecuteAttackChoice(const ArbUt::BorrowedPtr<AttackTurnChoice>
}
auto targetType = choice->GetAttack()->GetAttack()->GetTarget();
ArbUt::List<ArbUt::BorrowedPtr<Creature>> targets;
try_creature(targets = TargetResolver::ResolveTargets(choice->GetTarget(), targetType, battle);
ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>> targets;
Assert(battle.HasValue());
try_creature(targets = TargetResolver::ResolveTargets(choice->GetTarget(), targetType, battle.GetValue());
, "Exception during target determination");
auto attack = new ExecutingAttack(targets, 1, choice->GetUser(), choice->GetAttack(), choice->GetAttackScript());
@@ -94,8 +96,8 @@ void TurnHandler::ExecuteAttackChoice(const ArbUt::BorrowedPtr<AttackTurnChoice>
return;
}
battle->TriggerEventListener<AttackUseEvent>(attack);
battle->RegisterHistoryElement<AttackUseHistory>(attack);
battle.GetValue()->TriggerEventListener<AttackUseEvent>(attack);
battle.GetValue()->RegisterHistoryElement<AttackUseHistory>(attack);
// HOOK: check if attack fails
bool fail = false;
@@ -114,7 +116,10 @@ void TurnHandler::ExecuteAttackChoice(const ArbUt::BorrowedPtr<AttackTurnChoice>
for (uint8_t i = 0; i < attack->GetTargetCount(); i++) {
auto target = attack->GetTargets()[i];
try_creature(HandleAttackForTarget(attack, target), "Exception occurred during handling attack for target");
if (target.HasValue()) {
try_creature(HandleAttackForTarget(attack, target.GetValue()), "Exception occurred during handling attack "
"for target");
}
}
}
@@ -124,8 +129,8 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
AssertNotNull(user)
AssertNotNull(target)
auto& battle = user->GetBattle();
AssertNotNull(battle)
if (battle->HasEnded())
Assert(battle.HasValue())
if (battle.GetValue()->HasEnded())
return;
bool fail = false;
@@ -145,7 +150,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
auto numberOfHits = attack->GetNumberOfHits();
if (numberOfHits == 0) {
HOOK(OnAttackMiss, target, attack, target.GetRaw());
battle->TriggerEventListener<MissEvent>(user);
battle.GetValue()->TriggerEventListener<MissEvent>(user);
return;
}
@@ -154,7 +159,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
auto& attackData = learnedAttack->GetAttack();
AssertNotNull(attackData);
auto& library = battle->GetLibrary();
auto& library = battle.GetValue()->GetLibrary();
AssertNotNull(library)
auto& dmgLibrary = library->GetDamageLibrary();
auto& typeLibrary = library->GetTypeLibrary();
@@ -165,7 +170,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
auto hitIterator = attack->GetTargetIteratorBegin(target);
for (uint8_t hitIndex = 0; hitIndex < numberOfHits; hitIndex++) {
if (battle->HasEnded())
if (battle.GetValue()->HasEnded())
return;
if (user->IsFainted()) {
break;
@@ -193,7 +198,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
hasSecondaryEffect = true;
} else {
hasSecondaryEffect =
battle->GetRandom()->EffectChance(effect->GetChance(), attack, target.GetRaw());
battle.GetValue()->GetRandom()->EffectChance(effect->GetChance(), attack, target.GetRaw());
}
if (hasSecondaryEffect) {
HOOK(OnSecondaryEffect, user, attack, target.GetRaw(), hitIndex);
@@ -223,7 +228,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
if (effect->GetChance() == -1) {
hasSecondaryEffect = true;
} else {
auto random = battle->GetRandom();
auto random = battle.GetValue()->GetRandom();
AssertNotNull(random);
hasSecondaryEffect = random->EffectChance(effect->GetChance(), attack, target.GetRaw());
}
@@ -257,20 +262,24 @@ void TurnHandler::ExecuteSwitchChoice(ArbUt::BorrowedPtr<SwitchTurnChoice> choic
auto user = choice->GetUser();
user->ClearVolatileScripts();
auto userSide = user->GetBattleSide();
auto userIndex = userSide->GetCreatureIndex(user);
userSide->SetCreature(choice->GetNewCreature(), userIndex);
if (userSide.HasValue()) {
auto userIndex = userSide.GetValue()->GetCreatureIndex(user);
userSide.GetValue()->SetCreature(choice->GetNewCreature(), userIndex);
}
}
void TurnHandler::ExecuteFleeChoice(ArbUt::BorrowedPtr<FleeTurnChoice> choice) {
auto user = choice->GetUser();
auto battle = user->GetBattle();
if (!battle->CanFlee()) {
if (!battle.HasValue() || !battle.GetValue()->CanFlee()) {
return;
}
// TODO: If any of the creatures on the users side has a script that prevents it from running, block.
// TODO: If any of the creatures on any other side has a script that prevents this side from running, block.
if (battle->GetLibrary()->GetMiscLibrary()->CanFlee(choice.GetRaw())) {
user->GetBattleSide()->MarkAsFled();
battle->ValidateBattleState();
if (battle.GetValue()->GetLibrary()->GetMiscLibrary()->CanFlee(choice.GetRaw())) {
if (user->GetBattleSide().HasValue()) {
user->GetBattleSide().GetValue()->MarkAsFled();
}
battle.GetValue()->ValidateBattleState();
}
}