Support overriding attacks through script hooks.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: Deukhoofd <Deukhoofd@gmail.com>
This commit is contained in:
@@ -84,17 +84,19 @@ void TurnHandler::ExecuteChoice(const ArbUt::BorrowedPtr<BaseTurnChoice>& choice
|
||||
|
||||
void TurnHandler::ExecuteAttackChoice(const ArbUt::BorrowedPtr<AttackTurnChoice>& choice) {
|
||||
auto battle = choice->GetUser()->GetBattle();
|
||||
auto attackName = choice->GetAttack()->GetAttack()->GetName();
|
||||
auto attackData = choice->GetAttack()->GetAttack();
|
||||
auto attackName = attackData->GetName();
|
||||
HOOK(ChangeAttack, choice, choice.GetRaw(), &attackName);
|
||||
if (attackName != choice->GetAttack()->GetAttack()->GetName()) {
|
||||
// TODO: Change attack
|
||||
attackData = battle.GetValue()->GetLibrary()->GetAttackLibrary()->Get(attackName);
|
||||
}
|
||||
|
||||
auto targetType = choice->GetAttack()->GetAttack()->GetTarget();
|
||||
auto targetType = attackData->GetTarget();
|
||||
ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>> targets;
|
||||
Ensure(battle.HasValue());
|
||||
try_creature(targets = TargetResolver::ResolveTargets(choice->GetTarget(), targetType, battle.GetValue());
|
||||
, "Exception during target determination");
|
||||
// HOOK: override targets
|
||||
|
||||
u8 numberHits = 1;
|
||||
HOOK(ModifyNumberOfHits, choice, choice, &numberHits);
|
||||
@@ -102,15 +104,14 @@ void TurnHandler::ExecuteAttackChoice(const ArbUt::BorrowedPtr<AttackTurnChoice>
|
||||
return;
|
||||
}
|
||||
|
||||
auto attackScoped = ArbUt::ScopedPtr<ExecutingAttack>(
|
||||
new ExecutingAttack(targets, numberHits, choice->GetUser(), choice->GetAttack(), choice->GetAttackScript()));
|
||||
auto attackScoped = ArbUt::ScopedPtr<ExecutingAttack>(new ExecutingAttack(
|
||||
targets, numberHits, choice->GetUser(), choice->GetAttack(), attackData, choice->GetAttackScript()));
|
||||
bool prevented = false;
|
||||
HOOK(PreventAttack, attackScoped, attackScoped, &prevented);
|
||||
if (prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
// HOOK: override targets
|
||||
if (!choice->GetAttack()->TryUse(1)) {
|
||||
return;
|
||||
}
|
||||
@@ -119,7 +120,6 @@ void TurnHandler::ExecuteAttackChoice(const ArbUt::BorrowedPtr<AttackTurnChoice>
|
||||
battle.GetValue()->TriggerEventListener<AttackUseEvent>(attack);
|
||||
battle.GetValue()->RegisterHistoryElement<AttackUseHistory>(attack);
|
||||
|
||||
// HOOK: check if attack fails
|
||||
bool fail = false;
|
||||
HOOK(FailAttack, attack, attack, &fail);
|
||||
if (fail) {
|
||||
@@ -173,8 +173,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, const ArbUt::Bo
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& learnedAttack = attack->GetAttack();
|
||||
const auto& attackData = learnedAttack->GetAttack();
|
||||
const auto& attackData = attack->GetUseAttack();
|
||||
|
||||
const auto& library = battle.GetValue()->GetLibrary();
|
||||
const auto& dmgLibrary = library->GetDamageLibrary();
|
||||
|
||||
@@ -20,7 +20,7 @@ uint8_t DamageLibrary::GetBasePower(ExecutingAttack* attack, Creature* target, u
|
||||
[[maybe_unused]] const ExecutingAttack::HitData& hitData) const {
|
||||
EnsureNotNull(attack)
|
||||
EnsureNotNull(target)
|
||||
auto bp = attack->GetAttack()->GetAttack()->GetBasePower();
|
||||
auto bp = attack->GetUseAttack()->GetBasePower();
|
||||
HOOK(OverrideBasePower, attack, attack, target, hitIndex, &bp);
|
||||
return bp;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ float DamageLibrary::GetStatModifier(ExecutingAttack* attack, Creature* target,
|
||||
HOOK(ChangeDamageStatsUser, attack, attack, target, hitIndex, &user);
|
||||
Library::Statistic offensiveStat;
|
||||
Library::Statistic defensiveStat;
|
||||
if (attack->GetAttack()->GetAttack()->GetCategory() == Library::AttackCategory::Physical) {
|
||||
if (attack->GetUseAttack()->GetCategory() == Library::AttackCategory::Physical) {
|
||||
offensiveStat = Library::Statistic::PhysicalAttack;
|
||||
defensiveStat = Library::Statistic::PhysicalDefense;
|
||||
} else {
|
||||
|
||||
@@ -37,15 +37,17 @@ namespace CreatureLib::Battling {
|
||||
std::unique_ptr<HitData[]> _hits;
|
||||
ArbUt::BorrowedPtr<Creature> _user;
|
||||
ArbUt::BorrowedPtr<LearnedAttack> _attack;
|
||||
ArbUt::BorrowedPtr<const Library::AttackData> _useAttack;
|
||||
std::unique_ptr<BattleScript> _script = nullptr;
|
||||
ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>> _targets;
|
||||
|
||||
public:
|
||||
ExecutingAttack(const ArbUt::List<ArbUt::OptionalBorrowedPtr<Creature>>& targets, uint8_t numberHits,
|
||||
ArbUt::BorrowedPtr<Creature> user, const ArbUt::BorrowedPtr<LearnedAttack>& attack,
|
||||
const ArbUt::BorrowedPtr<const Library::AttackData>& useAttack,
|
||||
const std::unique_ptr<BattleScript>& script)
|
||||
: _numberHits(numberHits), _hits(std::make_unique<HitData[]>(targets.Count() * numberHits)), _user(user),
|
||||
_attack(attack), _targets(targets) {
|
||||
_attack(attack), _useAttack(useAttack), _targets(targets) {
|
||||
// Take ownership of the script of the attack choice, and give attack choice our initial nullptr.
|
||||
_script.swap(const_cast<std::unique_ptr<BattleScript>&>(script));
|
||||
}
|
||||
@@ -98,6 +100,7 @@ namespace CreatureLib::Battling {
|
||||
inline const ArbUt::BorrowedPtr<Creature>& GetUser() noexcept { return _user; }
|
||||
|
||||
inline const ArbUt::BorrowedPtr<LearnedAttack>& GetAttack() noexcept { return _attack; }
|
||||
inline const ArbUt::BorrowedPtr<const Library::AttackData>& GetUseAttack() noexcept { return _useAttack; }
|
||||
size_t ScriptCount() const override { return _user->ScriptCount() + 1; }
|
||||
|
||||
inline ArbUt::BorrowedPtr<BattleScript> GetScript() const noexcept { return _script; }
|
||||
|
||||
Reference in New Issue
Block a user