Adds functionality for held items
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
c40f063683
commit
c078d91b0d
|
@ -4,7 +4,10 @@ using namespace CreatureLib::Library;
|
|||
|
||||
export Item* CreatureLib_Item_Construct(const char* name, ItemCategory category, BattleItemCategory battleCategory,
|
||||
int32_t price, const char* effectName, EffectParameter* effectParameters[],
|
||||
size_t effectParameterCount, const char* flags[], size_t flagsCount) {
|
||||
size_t effectParameterCount, const char* battleTriggerEffectName,
|
||||
EffectParameter* battleTriggerEffectParameters[],
|
||||
size_t battleTriggerEffectParameterCount, const char* flags[],
|
||||
size_t flagsCount) {
|
||||
std::unordered_set<uint32_t> conversedFlags(flagsCount);
|
||||
for (size_t i = 0; i < flagsCount; i++) {
|
||||
conversedFlags.insert(ArbUt::StringView::CalculateHash(flags[i]));
|
||||
|
@ -14,6 +17,10 @@ export Item* CreatureLib_Item_Construct(const char* name, ItemCategory category,
|
|||
ArbUt::StringView(name), category, battleCategory, price,
|
||||
new SecondaryEffect(100, effectName,
|
||||
ArbUt::List<EffectParameter*>(effectParameters, effectParameters + effectParameterCount)),
|
||||
new SecondaryEffect(
|
||||
100, battleTriggerEffectName,
|
||||
ArbUt::List<EffectParameter*>(battleTriggerEffectParameters,
|
||||
battleTriggerEffectParameters + battleTriggerEffectParameterCount)),
|
||||
conversedFlags);
|
||||
};
|
||||
|
||||
|
|
|
@ -17,15 +17,20 @@ namespace CreatureLib::Battling {
|
|||
const Library::TalentIndex& talent, const std::vector<LearnedAttack*>& attacks,
|
||||
bool allowedExperienceGain)
|
||||
: _library(library), _species(species), _variant(variant), _level(level), _experience(experience),
|
||||
_uniqueIdentifier(uid), _gender(gender), _coloring(coloring), _heldItem(heldItem),
|
||||
_weight(variant->GetWeight()), _height(variant->GetHeight()), _nickname(std::move(nickname)),
|
||||
_talentIndex(talent), _hasOverridenTalent(false), _attacks(attacks),
|
||||
_allowedExperienceGain(allowedExperienceGain) {
|
||||
_uniqueIdentifier(uid), _gender(gender), _coloring(coloring), _weight(variant->GetWeight()),
|
||||
_height(variant->GetHeight()), _nickname(std::move(nickname)), _talentIndex(talent),
|
||||
_hasOverridenTalent(false), _attacks(attacks), _allowedExperienceGain(allowedExperienceGain),
|
||||
_heldItem(heldItem) {
|
||||
_activeTalent = std::unique_ptr<BattleScript>(
|
||||
_library->LoadScript(this, ScriptCategory::Talent, GetActiveTalent()->GetEffect()));
|
||||
if (_activeTalent != nullptr) {
|
||||
_activeTalent->OnInitialize(_library.GetRaw(), GetActiveTalent()->GetParameters());
|
||||
}
|
||||
if (_heldItem.HasValue() && _heldItem.GetValue()->GetBattleTriggerEffect().HasValue()) {
|
||||
_heldItemTriggerScript = std::unique_ptr<BattleScript>(
|
||||
_library->LoadScript(this, ScriptCategory::ItemBattleTrigger,
|
||||
_heldItem.GetValue()->GetBattleTriggerEffect().GetValue()->GetEffectName()));
|
||||
}
|
||||
for (auto t : _variant->GetTypes()) {
|
||||
_types.push_back(t);
|
||||
}
|
||||
|
@ -283,6 +288,7 @@ namespace CreatureLib::Battling {
|
|||
}
|
||||
}
|
||||
void Creature::GetOwnScripts(ArbUt::List<ScriptWrapper>& scripts) {
|
||||
scripts.Append(ScriptWrapper::FromScript(&_heldItemTriggerScript));
|
||||
scripts.Append(ScriptWrapper::FromScript(&_activeTalent));
|
||||
scripts.Append(ScriptWrapper::FromScript(&_status));
|
||||
scripts.Append(ScriptWrapper::FromSet(&_volatile));
|
||||
|
@ -318,18 +324,53 @@ namespace CreatureLib::Battling {
|
|||
return variant;
|
||||
}
|
||||
void Creature::SetHeldItem(const ArbUt::BasicStringView& itemName) {
|
||||
auto v = _library->GetItemLibrary()->TryGet(itemName.GetHash());
|
||||
if (!v.has_value()) {
|
||||
THROW("Item not found '", itemName.c_str(), "'.");
|
||||
if (itemName == ""_cnc) {
|
||||
_heldItem = {};
|
||||
_heldItemTriggerScript = {};
|
||||
} else {
|
||||
auto v = _library->GetItemLibrary()->TryGet(itemName.GetHash());
|
||||
if (!v.has_value()) {
|
||||
THROW("Item not found '", itemName.c_str(), "'.");
|
||||
}
|
||||
_heldItem = v.value();
|
||||
}
|
||||
_heldItem = v.value();
|
||||
}
|
||||
void Creature::SetHeldItem(uint32_t itemNameHash) {
|
||||
auto v = _library->GetItemLibrary()->TryGet(itemNameHash);
|
||||
if (!v.has_value()) {
|
||||
THROW("Item not found.");
|
||||
if (itemNameHash == ArbUt::StringView::CalculateHash("")) {
|
||||
_heldItem = {};
|
||||
_heldItemTriggerScript = {};
|
||||
} else {
|
||||
auto v = _library->GetItemLibrary()->TryGet(itemNameHash);
|
||||
if (!v.has_value()) {
|
||||
THROW("Item not found.");
|
||||
}
|
||||
_heldItem = v.value();
|
||||
}
|
||||
_heldItem = v.value();
|
||||
}
|
||||
|
||||
bool Creature::ConsumeHeldItem() {
|
||||
if (!_heldItem.HasValue()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* script = _library->GetScriptResolver()->LoadItemScript(_heldItem.GetValue());
|
||||
auto isCreatureUseItem = script->IsCreatureUseItem();
|
||||
if (isCreatureUseItem) {
|
||||
if (!script->IsUseValidForCreature(this)) {
|
||||
return false;
|
||||
}
|
||||
script->OnCreatureUse(this, true);
|
||||
} else {
|
||||
script->OnUse(_battleData.Battle.GetValue());
|
||||
}
|
||||
auto item = _heldItem;
|
||||
SetHeldItem(""_cnc);
|
||||
|
||||
if (_battleData.Battle.HasValue()) {
|
||||
HOOK(OnAfterHeldItemConsume, this, this, item.GetValue());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BattleScript* Creature::AddVolatileScript(const ArbUt::StringView& name) {
|
||||
|
@ -421,31 +462,30 @@ namespace CreatureLib::Battling {
|
|||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CreatureLib::Battling::Creature::SetStatus(const ArbUt::StringView& name) {
|
||||
if (_status != nullptr) {
|
||||
void Creature::SetStatus(const ArbUt::StringView& name) {
|
||||
if (_status != nullptr) {
|
||||
_status->OnRemove();
|
||||
}
|
||||
_status = std::unique_ptr<BattleScript>(_library->LoadScript(this, ScriptCategory::Status, name));
|
||||
if (_battleData.Battle.HasValue()) {
|
||||
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, name);
|
||||
}
|
||||
}
|
||||
void Creature::ClearStatus() {
|
||||
if (_status == nullptr) {
|
||||
return;
|
||||
}
|
||||
_status->OnRemove();
|
||||
_status = nullptr;
|
||||
if (_battleData.Battle.HasValue()) {
|
||||
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
|
||||
}
|
||||
}
|
||||
_status =
|
||||
std::unique_ptr<CreatureLib::Battling::BattleScript>(_library->LoadScript(this, ScriptCategory::Status, name));
|
||||
if (_battleData.Battle.HasValue()) {
|
||||
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, name);
|
||||
}
|
||||
}
|
||||
void CreatureLib::Battling::Creature::ClearStatus() {
|
||||
if (_status == nullptr) {
|
||||
return;
|
||||
}
|
||||
_status->OnRemove();
|
||||
_status = nullptr;
|
||||
if (_battleData.Battle.HasValue()) {
|
||||
_battleData.Battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
|
||||
}
|
||||
}
|
||||
|
||||
Battling::Creature::~Creature() {
|
||||
if (_battleData.OnBattleField && _battleData.Side.HasValue()) {
|
||||
_battleData.Side.GetValue()->ForceClearCreature(_battleData.Index.GetCreatureIndex());
|
||||
Creature::~Creature() {
|
||||
if (_battleData.OnBattleField && _battleData.Side.HasValue()) {
|
||||
_battleData.Side.GetValue()->ForceClearCreature(_battleData.Index.GetCreatureIndex());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace CreatureLib::Battling {
|
|||
uint32_t _uniqueIdentifier;
|
||||
Library::Gender _gender;
|
||||
uint8_t _coloring;
|
||||
ArbUt::OptionalBorrowedPtr<const Library::Item> _heldItem;
|
||||
|
||||
uint32_t _currentHealth = -1;
|
||||
|
||||
f32 _weight;
|
||||
|
@ -66,6 +66,9 @@ namespace CreatureLib::Battling {
|
|||
|
||||
std::vector<u8> _types = {};
|
||||
|
||||
ArbUt::OptionalBorrowedPtr<const Library::Item> _heldItem;
|
||||
std::unique_ptr<BattleScript> _heldItemTriggerScript = nullptr;
|
||||
|
||||
private:
|
||||
void OnFaint(DamageSource damageSource);
|
||||
|
||||
|
@ -109,6 +112,7 @@ namespace CreatureLib::Battling {
|
|||
void SetHeldItem(const ArbUt::BasicStringView& itemName);
|
||||
void SetHeldItem(uint32_t itemNameHash);
|
||||
inline void SetHeldItem(const ArbUt::BorrowedPtr<const Library::Item>& item) noexcept { _heldItem = item; };
|
||||
bool ConsumeHeldItem();
|
||||
|
||||
inline uint32_t GetCurrentHealth() const noexcept { return _currentHealth; }
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <Arbutils/Memory/Memory.hpp>
|
||||
#include <Arbutils/Misc.hpp>
|
||||
#include "../../Library/EffectParameter.hpp"
|
||||
#include "../../Library/Items/Item.hpp"
|
||||
#include "../../Library/Statistic.hpp"
|
||||
#include "../Models/DamageSource.hpp"
|
||||
|
||||
|
@ -117,6 +118,8 @@ namespace CreatureLib::Battling {
|
|||
virtual void OnDamage(Creature*, DamageSource, _par_ u32 oldHealth, _par_ u32 newHealth){};
|
||||
virtual void OnFaint(Creature*, DamageSource){};
|
||||
virtual void OnSwitchIn(Creature*){};
|
||||
|
||||
virtual void OnAfterHeldItemConsume(Creature*, const Library::Item*){};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
#define CREATURELIB_SCRIPTCATEGORY_HPP
|
||||
#include <Arbutils/Enum.hpp>
|
||||
|
||||
ENUM(ScriptCategory, uint8_t, Attack, Talent, Status, Creature, Battle, Side)
|
||||
ENUM(ScriptCategory, uint8_t, Attack, Talent, Status, Creature, Battle, Side, ItemBattleTrigger)
|
||||
|
||||
#endif // CREATURELIB_SCRIPTCATEGORY_HPP
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "ScriptResolver.hpp"
|
|
@ -8,26 +8,32 @@ namespace CreatureLib::Library {
|
|||
int32_t _price;
|
||||
|
||||
ArbUt::OptionalUniquePtr<const SecondaryEffect> _effect = nullptr;
|
||||
ArbUt::OptionalUniquePtr<const SecondaryEffect> _battleTriggerEffect = nullptr;
|
||||
std::unordered_set<uint32_t> _flags;
|
||||
|
||||
public:
|
||||
inline impl(const ArbUt::StringView& name, ItemCategory category, BattleItemCategory battleCategory,
|
||||
int32_t price, const SecondaryEffect* effect, const std::unordered_set<uint32_t>& flags) noexcept
|
||||
int32_t price, const SecondaryEffect* effect, const SecondaryEffect* battleTriggerEffect,
|
||||
const std::unordered_set<uint32_t>& flags) noexcept
|
||||
: _name(name), _category(category), _battleCategory(battleCategory), _price(price), _effect(effect),
|
||||
_flags(flags) {}
|
||||
_battleTriggerEffect(battleTriggerEffect), _flags(flags) {}
|
||||
|
||||
inline const ArbUt::StringView& GetName() const noexcept { return _name; }
|
||||
inline ItemCategory GetCategory() const noexcept { return _category; }
|
||||
inline BattleItemCategory GetBattleCategory() const noexcept { return _battleCategory; }
|
||||
inline int32_t GetPrice() const noexcept { return _price; }
|
||||
inline const ArbUt::OptionalUniquePtr<const SecondaryEffect>& GetEffect() const noexcept { return _effect; }
|
||||
inline const ArbUt::OptionalUniquePtr<const SecondaryEffect>& GetBattleTriggerEffect() const noexcept {
|
||||
return _battleTriggerEffect;
|
||||
}
|
||||
|
||||
inline bool HasFlag(const ArbUt::BasicStringView& flag) const noexcept { return this->_flags.contains(flag); }
|
||||
inline bool HasFlag(uint32_t flag) const noexcept { return this->_flags.contains(flag); }
|
||||
};
|
||||
Item::Item(const ArbUt::StringView& name, ItemCategory category, BattleItemCategory battleCategory, int32_t price,
|
||||
const SecondaryEffect* effect, const std::unordered_set<uint32_t>& flags) noexcept
|
||||
: _impl(new impl(name, category, battleCategory, price, effect, flags)) {}
|
||||
const SecondaryEffect* effect, const SecondaryEffect* battleTriggerEffect,
|
||||
const std::unordered_set<uint32_t>& flags) noexcept
|
||||
: _impl(new impl(name, category, battleCategory, price, effect, battleTriggerEffect, flags)) {}
|
||||
|
||||
Item::~Item() = default;
|
||||
const ArbUt::StringView& Item::GetName() const noexcept { return _impl->GetName(); }
|
||||
|
@ -37,6 +43,9 @@ namespace CreatureLib::Library {
|
|||
const ArbUt::OptionalUniquePtr<const SecondaryEffect>& Item::GetEffect() const noexcept {
|
||||
return _impl->GetEffect();
|
||||
}
|
||||
const ArbUt::OptionalUniquePtr<const SecondaryEffect>& Item::GetBattleTriggerEffect() const noexcept {
|
||||
return _impl->GetBattleTriggerEffect();
|
||||
}
|
||||
|
||||
bool Item::HasFlag(const ArbUt::BasicStringView& flag) const noexcept { return _impl->HasFlag(flag); }
|
||||
bool Item::HasFlag(uint32_t flag) const noexcept { return _impl->HasFlag(flag); }
|
||||
|
|
|
@ -16,7 +16,8 @@ namespace CreatureLib::Library {
|
|||
|
||||
public:
|
||||
Item(const ArbUt::StringView& name, ItemCategory category, BattleItemCategory battleCategory, int32_t price,
|
||||
const SecondaryEffect* effect, const std::unordered_set<uint32_t>& flags) noexcept;
|
||||
const SecondaryEffect* effect, const SecondaryEffect* battleTriggerEffect,
|
||||
const std::unordered_set<uint32_t>& flags) noexcept;
|
||||
NO_COPY_OR_MOVE(Item)
|
||||
|
||||
virtual ~Item();
|
||||
|
@ -27,6 +28,7 @@ namespace CreatureLib::Library {
|
|||
int32_t GetPrice() const noexcept;
|
||||
|
||||
const ArbUt::OptionalUniquePtr<const SecondaryEffect>& GetEffect() const noexcept;
|
||||
const ArbUt::OptionalUniquePtr<const SecondaryEffect>& GetBattleTriggerEffect() const noexcept;
|
||||
bool HasFlag(const ArbUt::BasicStringView& flag) const noexcept;
|
||||
bool HasFlag(uint32_t flag) const noexcept;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue