#ifndef CREATURELIB_ATTACKTURNCHOICE_HPP #define CREATURELIB_ATTACKTURNCHOICE_HPP #include "../Models/Battle.hpp" #include "../Models/CreatureIndex.hpp" #include "../Models/LearnedAttack.hpp" #include "../ScriptHandling/ScriptCategory.hpp" #include "../ScriptHandling/ScriptMacros.hpp" #include "BaseTurnChoice.hpp" namespace CreatureLib::Battling { class AttackTurnChoice : public BaseTurnChoice { ArbUt::BorrowedPtr _attack; CreatureIndex _target; ArbUt::OptionalUniquePtr _attackScript = nullptr; i8 _priority = 0; bool _hasFailed = false; void ResolveScript(ArbUt::BorrowedPtr attack) { if (_attackScript != nullptr) return; auto user = GetUser(); auto battle = user->GetBattle(); if (battle.HasValue()) { if (attack->HasSecondaryEffect()) { auto library = battle.GetValue()->GetLibrary(); auto& effect = attack->GetSecondaryEffect(); _attackScript = library->LoadScript(this, ScriptCategory::Attack, effect->GetEffectName()).TakeOwnership(); if (_attackScript.HasValue()) { _attackScript.GetValue()->OnInitialize(battle.GetValue()->GetLibrary().GetRaw(), effect->GetParameters()); } } } } public: AttackTurnChoice(Creature* user, const ArbUt::BorrowedPtr& attack, const CreatureIndex& target) : BaseTurnChoice(user), _attack(attack), _target(target) { EnsureNotNull(user) ResolveScript(attack->GetAttack()); _priority = _attack->GetAttack()->GetPriority(); } AttackTurnChoice(Creature* user, const ArbUt::BorrowedPtr& attack, const CreatureIndex& target, BattleScript* script) : BaseTurnChoice(user), _attack(attack), _target(target), _attackScript(script) { _priority = _attack->GetAttack()->GetPriority(); } ~AttackTurnChoice() = default; inline const ArbUt::BorrowedPtr& GetAttack() const noexcept { return _attack; } void ChangeAttackScript(ArbUt::BorrowedPtr attack) { _attackScript = nullptr; ResolveScript(attack); ResetActiveScripts(); } TurnChoiceKind GetKind() const noexcept override { return TurnChoiceKind ::Attack; } inline i8 GetPriority() const noexcept { return _priority; } inline void SetPriority(i8 priority) noexcept { _priority = priority; } const CreatureIndex& GetTarget() const noexcept { return _target; } ArbUt::OptionalUniquePtr& GetAttackScript() noexcept { return _attackScript; } size_t ScriptCount() const override { return 1 + GetUser()->ScriptCount(); } void GetActiveScripts(ArbUt::List& scripts) override { GetOwnScripts(scripts); GetUser()->GetActiveScripts(scripts); } void GetOwnScripts(ArbUt::List& scripts) override { scripts.Append(ScriptWrapper::FromScript(&_attackScript)); } inline bool HasFailed() const noexcept { return _hasFailed; } inline void Fail() noexcept { _hasFailed = true; } }; } #endif // CREATURELIB_ATTACKTURNCHOICE_HPP