Adds functionality for held items
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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"
|
||||
Reference in New Issue
Block a user