Cleanup of ExecutingAttack, removing TargetData, and reducing the number of allocations needed.
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2020-04-25 20:09:20 +02:00
parent 8eb22ad68d
commit 7fd3687564
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
4 changed files with 29 additions and 45 deletions

View File

@ -11,9 +11,9 @@ export uint8_t CreatureLib_ExecutingAttack_Construct(ExecutingAttack*& out, Crea
export void CreatureLib_ExecutingAttack_Destruct(ExecutingAttack* p) { delete p; }
export uint8_t CreatureLib_ExecutingAttack_GetAttackDataForTarget(ExecutingAttack::TargetData*& out, ExecutingAttack* p,
Creature* target) {
Try(out = &p->GetAttackDataForTarget(target);)
export uint8_t CreatureLib_ExecutingAttack_GetHitData(ExecutingAttack::HitData*& out, ExecutingAttack* p,
Creature* target, uint8_t hit) {
Try(out = &p->GetHitData(target, hit);)
}
export bool CreatureLib_ExecutingAttack_IsCreatureTarget(ExecutingAttack* p, Creature* target) {
@ -23,13 +23,6 @@ export bool CreatureLib_ExecutingAttack_IsCreatureTarget(ExecutingAttack* p, Cre
export Creature* CreatureLib_ExecutingAttack_GetUser(ExecutingAttack* p) { return p->GetUser(); }
export LearnedAttack* CreatureLib_ExecutingAttack_GetAttack(ExecutingAttack* p) { return p->GetAttack(); }
export uint8_t CreatureLib_TargetData_GetHit(ExecutingAttack::HitData*& out, ExecutingAttack::TargetData* p,
uint8_t hit) {
Try(out = &p->GetHit(hit);)
}
export uint8_t CreatureLib_TargetData_GetNumberOfHits(ExecutingAttack::TargetData* p) { return p->GetNumberOfHits(); }
export bool CreatureLib_TargetData_IsHit(ExecutingAttack::TargetData* p) { return p->IsHit(); }
#define HITDATA_GET_FUNC(name, returnType) \
export returnType CreatureLib_HitData##_##name(const ExecutingAttack::HitData* p) { return p->name(); }

View File

@ -90,16 +90,15 @@ void TurnHandler::ExecuteAttackChoice(AttackTurnChoice* choice) {
}
HOOK(OnBeforeAttack, attack, attack);
for (auto& kv : attack->GetTargets()) {
HandleAttackForTarget(attack, kv.first, kv.second);
for (auto& t : attack->GetTargets()) {
HandleAttackForTarget(attack, t);
}
// TODO: We currently delete this, but we probably want to store this in a log, so scripts can look it up.
delete attack;
}
void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* target,
ExecutingAttack::TargetData& targetData) {
void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* target) {
auto user = attack->GetUser();
AssertNotNull(user)
AssertNotNull(target)
@ -121,26 +120,24 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe
return;
}
if (!targetData.IsHit()) {
auto numberOfHits = attack->GetNumberOfHits();
if (numberOfHits == 0) {
HOOK(OnAttackMiss, targetSource, attack, target);
return;
}
auto numHits = targetData.GetNumberOfHits();
if (numHits == 0)
return;
auto attackData = attack->GetAttack()->GetAttack();
auto library = user->GetBattle()->GetLibrary();
AssertNotNull(library)
auto dmgLibrary = library->GetDamageLibrary();
for (uint8_t hitIndex = 0; hitIndex < numHits; hitIndex++) {
for (uint8_t hitIndex = 0; hitIndex < numberOfHits; hitIndex++) {
if (user->IsFainted()) {
break;
}
if (target->IsFainted()) {
break;
}
auto& hit = targetData.GetHit(hitIndex);
auto& hit = attack->GetHitData(target, hitIndex);
auto hitType = hit.GetType();
HOOK(ChangeAttackType, targetSource, attack, target, hitIndex, &hitType);
auto effectiveness = library->GetTypeLibrary()->GetEffectiveness(hitType, target->GetTypes());

View File

@ -14,8 +14,7 @@ namespace CreatureLib::Battling {
static void ExecuteChoice(BaseTurnChoice* choice);
static void ExecuteAttackChoice(AttackTurnChoice* choice);
static void HandleAttackForTarget(ExecutingAttack* attack, Creature* target,
ExecutingAttack::TargetData& targetData);
static void HandleAttackForTarget(ExecutingAttack* attack, Creature* target);
static void ExecuteSwitchChoice(SwitchTurnChoice* choice);
static void ExecuteFleeChoice(FleeTurnChoice* choice);

View File

@ -37,24 +37,10 @@ namespace CreatureLib::Battling {
inline void SetType(uint8_t value) noexcept { _type = value; }
};
class TargetData {
bool _isHit = true;
List<HitData> _hits;
public:
explicit TargetData(uint8_t numberOfHits) : _hits(numberOfHits) { _hits.Resize(numberOfHits, HitData()); }
TargetData() = default;
TargetData& operator=(const TargetData&) = delete;
HitData& GetHit(uint8_t index) { return _hits[index]; }
uint8_t GetNumberOfHits() const noexcept { return _hits.Count(); }
bool IsHit() const noexcept { return _isHit; }
};
private:
Dictionary<Creature*, TargetData> _targets;
List<Creature*> _targets;
uint8_t _numberHits;
List<HitData> _hits;
Creature* _user;
LearnedAttack* _attack;
Script* _script;
@ -62,21 +48,30 @@ namespace CreatureLib::Battling {
public:
ExecutingAttack(const List<Creature*>& targets, uint8_t numberHits, Creature* user, LearnedAttack* attack,
Script* script)
: _targets(targets.Count()), _user(user), _attack(attack), _script(script) {
: _targets(targets.Count()), _numberHits(numberHits), _hits(targets.Count() * numberHits), _user(user),
_attack(attack), _script(script) {
AssertNotNull(user)
AssertNotNull(attack)
for (auto target : targets) {
_targets.Insert(target, TargetData(numberHits));
_targets.Append(target);
_hits.Resize(numberHits);
}
}
virtual ~ExecutingAttack() noexcept { delete _script; };
TargetData& GetAttackDataForTarget(Creature* creature) { return _targets[creature]; }
HitData& GetHitData(Creature* creature, uint8_t hit) {
for (size_t i = 0; i < _targets.Count(); i++) {
if (_targets[i] == creature) {
return _hits[i * _numberHits + hit];
}
}
throw CreatureException("Invalid target requested.");
}
bool IsCreatureTarget(Creature* creature) noexcept { return _targets.Has(creature); }
Dictionary<Creature*, TargetData>& GetTargets() noexcept { return _targets; }
bool IsCreatureTarget(Creature* creature) noexcept { return _targets.IndexOf(creature) != -1; }
const List<Creature*>& GetTargets() noexcept { return _targets; }
uint8_t GetNumberOfHits() const noexcept { return _numberHits; }
Creature* GetUser() noexcept { return _user; }