Reworks attack scripts to handle effect chance and effect name through data files.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
e2675d06fb
commit
340520e0e3
|
@ -5,11 +5,13 @@ using namespace CreatureLib::Library;
|
|||
export uint8_t CreatureLib_AttackData_Construct(AttackData*& out, const char* name, uint8_t type,
|
||||
AttackCategory category, uint8_t power, uint8_t accuracy,
|
||||
uint8_t baseUsage, AttackTarget target, int8_t priority,
|
||||
const char* flags[], size_t flagsCount) {
|
||||
Try(std::unordered_set<uint32_t> conversedFlags(flagsCount);
|
||||
for (size_t i = 0; i < flagsCount; i++) { conversedFlags.insert(ConstString::GetHash(flags[i])); }
|
||||
int8_t effectChance, const char* effectName, const char* flags[],
|
||||
size_t flagsCount) {
|
||||
Try(std::unordered_set<uint32_t> conversedFlags(flagsCount); for (size_t i = 0; i < flagsCount; i++) {
|
||||
conversedFlags.insert(ConstString::GetHash(flags[i]));
|
||||
} auto effect = SecondaryEffect(effectChance, Arbutils::CaseInsensitiveConstString(effectName));
|
||||
|
||||
out = new AttackData(ConstString(name), type, category, power, accuracy, baseUsage, target, priority,
|
||||
out = new AttackData(ConstString(name), type, category, power, accuracy, baseUsage, target, priority, effect,
|
||||
conversedFlags);)
|
||||
};
|
||||
|
||||
|
|
|
@ -154,7 +154,9 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe
|
|||
hit->SetDamage(dmgLibrary->GetDamage(attack, target, hitIndex));
|
||||
|
||||
if (attackData->GetCategory() == Library::AttackCategory::Status) {
|
||||
HOOK(OnStatusMove, userSource, attack, target, hitIndex);
|
||||
if (attackData->HasSecondaryEffect()) {
|
||||
HOOK(OnStatusMove, userSource, attack, target, hitIndex);
|
||||
}
|
||||
} else {
|
||||
auto damage = hit->GetDamage();
|
||||
if (damage > target->GetCurrentHealth()) {
|
||||
|
@ -164,10 +166,22 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe
|
|||
if (damage > 0) {
|
||||
target->Damage(damage, DamageSource::AttackDamage);
|
||||
|
||||
bool preventSecondary = false;
|
||||
HOOK(PreventSecondaryEffects, targetSource, attack, target, hitIndex, &preventSecondary);
|
||||
if (!preventSecondary) {
|
||||
HOOK(OnSecondaryEffect, userSource, attack, target, hitIndex);
|
||||
if (attackData->HasSecondaryEffect()) {
|
||||
bool preventSecondary = false;
|
||||
HOOK(PreventSecondaryEffects, targetSource, attack, target, hitIndex, &preventSecondary);
|
||||
if (!preventSecondary) {
|
||||
auto effect = attackData->GetSecondaryEffect();
|
||||
bool hasSecondaryEffect;
|
||||
if (effect.GetChance() == -1) {
|
||||
hasSecondaryEffect = true;
|
||||
} else {
|
||||
hasSecondaryEffect =
|
||||
user->GetBattle()->GetRandom()->EffectChance(effect.GetChance(), attack, target);
|
||||
}
|
||||
if (hasSecondaryEffect) {
|
||||
HOOK(OnSecondaryEffect, userSource, attack, target, hitIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ static CreatureLib::Library::AttackData* _replacementAttackData = nullptr;
|
|||
|
||||
static CreatureLib::Library::AttackData* GetReplacementAttackData() {
|
||||
if (_replacementAttackData == nullptr) {
|
||||
_replacementAttackData =
|
||||
new CreatureLib::Library::AttackData("replacement"_cnc, 0, CreatureLib::Library::AttackCategory::Physical,
|
||||
30, 255, 255, CreatureLib::Library::AttackTarget::Any, 0, {});
|
||||
_replacementAttackData = new CreatureLib::Library::AttackData(
|
||||
"replacement"_cnc, 0, CreatureLib::Library::AttackCategory::Physical, 30, 255, 255,
|
||||
CreatureLib::Library::AttackTarget::Any, 0, CreatureLib::Library::SecondaryEffect(), {});
|
||||
}
|
||||
return _replacementAttackData;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,11 @@ namespace CreatureLib::Battling {
|
|||
return;
|
||||
auto battle = user->GetBattle();
|
||||
if (battle != nullptr) {
|
||||
auto library = battle->GetLibrary();
|
||||
_attackScript = library->LoadScript(ScriptCategory::Attack, _attack->GetAttack()->GetName());
|
||||
if (_attack->GetAttack()->HasSecondaryEffect()) {
|
||||
auto library = battle->GetLibrary();
|
||||
_attackScript = library->LoadScript(ScriptCategory::Attack,
|
||||
_attack->GetAttack()->GetSecondaryEffect().GetEffectName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ CreatureLib::Library::AttackData::AttackData(const ConstString& name, uint8_t ty
|
|||
CreatureLib::Library::AttackCategory category, uint8_t power,
|
||||
uint8_t accuracy, uint8_t baseUsage,
|
||||
CreatureLib::Library::AttackTarget target, int8_t priority,
|
||||
std::unordered_set<uint32_t> flags)
|
||||
SecondaryEffect effect, std::unordered_set<uint32_t> flags)
|
||||
: _name(std::move(name)), _type(type), _category(category), _basePower(power), _accuracy(accuracy),
|
||||
_baseUsages(baseUsage), _target(target), _priority(priority), _flags(std::move(flags)) {}
|
||||
_baseUsages(baseUsage), _target(target), _priority(priority), _effect(effect), _flags(std::move(flags)) {}
|
||||
|
||||
bool CreatureLib::Library::AttackData::HasFlag(const ConstString& key) const noexcept {
|
||||
return this->_flags.find(key) != this->_flags.end();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <unordered_set>
|
||||
#include "AttackCategory.hpp"
|
||||
#include "AttackTarget.hpp"
|
||||
#include "SecondaryEffect.hpp"
|
||||
|
||||
using ConstString = Arbutils::CaseInsensitiveConstString;
|
||||
|
||||
|
@ -20,11 +21,13 @@ namespace CreatureLib::Library {
|
|||
uint8_t _baseUsages;
|
||||
AttackTarget _target;
|
||||
int8_t _priority;
|
||||
SecondaryEffect _effect;
|
||||
std::unordered_set<uint32_t> _flags;
|
||||
|
||||
public:
|
||||
AttackData(const ConstString& name, uint8_t type, AttackCategory category, uint8_t power, uint8_t accuracy,
|
||||
uint8_t baseUsage, AttackTarget target, int8_t priority, std::unordered_set<uint32_t> flags);
|
||||
uint8_t baseUsage, AttackTarget target, int8_t priority, SecondaryEffect effect,
|
||||
std::unordered_set<uint32_t> flags);
|
||||
virtual ~AttackData() = default;
|
||||
|
||||
inline const ConstString& GetName() const noexcept { return _name; }
|
||||
|
@ -35,6 +38,10 @@ namespace CreatureLib::Library {
|
|||
inline uint8_t GetBaseUsages() const noexcept { return _baseUsages; }
|
||||
inline AttackTarget GetTarget() const noexcept { return _target; }
|
||||
inline int8_t GetPriority() const noexcept { return _priority; }
|
||||
inline bool HasSecondaryEffect() const noexcept {
|
||||
return _effect.GetChance() != 0 && _effect.GetEffectName() != ""_cnc;
|
||||
}
|
||||
inline const SecondaryEffect& GetSecondaryEffect() const noexcept { return _effect; }
|
||||
|
||||
bool HasFlag(const ConstString& key) const noexcept;
|
||||
bool HasFlag(uint32_t keyHash) const noexcept;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef CREATURELIB_SECONDARYEFFECT_HPP
|
||||
#define CREATURELIB_SECONDARYEFFECT_HPP
|
||||
|
||||
#include <Arbutils/ConstString.hpp>
|
||||
namespace CreatureLib::Library {
|
||||
class SecondaryEffect {
|
||||
private:
|
||||
float _chance;
|
||||
Arbutils::CaseInsensitiveConstString _effectName;
|
||||
|
||||
public:
|
||||
constexpr SecondaryEffect() noexcept : _chance(0), _effectName(""_cnc) {}
|
||||
constexpr SecondaryEffect(float chance, const Arbutils::CaseInsensitiveConstString& effectName) noexcept
|
||||
: _chance(chance), _effectName(effectName) {}
|
||||
|
||||
constexpr float GetChance() const noexcept { return _chance; }
|
||||
constexpr const Arbutils::CaseInsensitiveConstString& GetEffectName() const noexcept { return _effectName; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CREATURELIB_SECONDARYEFFECT_HPP
|
|
@ -33,13 +33,13 @@ SpeciesLibrary* TestLibrary::BuildSpeciesLibrary() {
|
|||
AttackLibrary* TestLibrary::BuildAttackLibrary() {
|
||||
auto l = new AttackLibrary();
|
||||
l->Insert("standard"_cnc, new AttackData("standard"_cnc, 0, AttackCategory::Physical, 20, 100, 30,
|
||||
AttackTarget::AdjacentOpponent, 0, {}));
|
||||
AttackTarget::AdjacentOpponent, 0, SecondaryEffect(), {}));
|
||||
l->Insert("highPriority"_cnc, new AttackData("highPriority"_cnc, 0, AttackCategory::Physical, 20, 100, 30,
|
||||
AttackTarget::AdjacentOpponent, 1, {}));
|
||||
AttackTarget::AdjacentOpponent, 1, SecondaryEffect(), {}));
|
||||
l->Insert("higherPriority"_cnc, new AttackData("higherPriority"_cnc, 0, AttackCategory::Physical, 20, 100, 30,
|
||||
AttackTarget::AdjacentOpponent, 2, {}));
|
||||
AttackTarget::AdjacentOpponent, 2, SecondaryEffect(), {}));
|
||||
l->Insert("lowPriority"_cnc, new AttackData("lowPriority"_cnc, 0, AttackCategory::Physical, 20, 100, 30,
|
||||
AttackTarget::AdjacentOpponent, -1, {}));
|
||||
AttackTarget::AdjacentOpponent, -1, SecondaryEffect(), {}));
|
||||
return l;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue