diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index 26c284bf..b32c7c52 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -64,6 +64,7 @@ #include "FallSpeedBehavior.h" #include "ChangeIdleFlagsBehavior.h" #include "DarkInspirationBehavior.h" +#include "ConsumeItemBehavior.h" //CDClient includes #include "CDBehaviorParameterTable.h" @@ -200,7 +201,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { case BehaviorTemplates::BEHAVIOR_SKILL_EVENT: behavior = new SkillEventBehavior(behaviorId); break; - case BehaviorTemplates::BEHAVIOR_CONSUME_ITEM: break; + case BehaviorTemplates::BEHAVIOR_CONSUME_ITEM: + behavior = new ConsumeItemBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_SKILL_CAST_FAILED: behavior = new SkillCastFailedBehavior(behaviorId); break; diff --git a/dGame/dBehaviors/CMakeLists.txt b/dGame/dBehaviors/CMakeLists.txt index 8a9368b9..d1926525 100644 --- a/dGame/dBehaviors/CMakeLists.txt +++ b/dGame/dBehaviors/CMakeLists.txt @@ -16,6 +16,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp" "ChangeOrientationBehavior.cpp" "ChargeUpBehavior.cpp" "ClearTargetBehavior.cpp" + "ConsumeItemBehavior.cpp" "DamageAbsorptionBehavior.cpp" "DamageReductionBehavior.cpp" "DarkInspirationBehavior.cpp" diff --git a/dGame/dBehaviors/ConsumeItemBehavior.cpp b/dGame/dBehaviors/ConsumeItemBehavior.cpp new file mode 100644 index 00000000..c3b76fcb --- /dev/null +++ b/dGame/dBehaviors/ConsumeItemBehavior.cpp @@ -0,0 +1,31 @@ +#include "ConsumeItemBehavior.h" +#include "BehaviorContext.h" +#include "BehaviorBranchContext.h" +#include "InventoryComponent.h" + +void ConsumeItemBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + auto action_to_cast = m_ActionNotConsumed; + if (this->m_ConsumeLOT != -1) { + auto caster = Game::entityManager->GetEntity(context->caster); + if (!caster) return; + + auto inventoryComponent = caster->GetComponent(); + if (!inventoryComponent) return; + + if (inventoryComponent->RemoveItem(this->m_ConsumeLOT, this->m_NumToConsume, eInventoryType::INVALID, false, true)){ + action_to_cast = m_ActionConsumed; + } + } + if(action_to_cast) action_to_cast->Handle(context, bitStream, branch); +} + +void ConsumeItemBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) { + Handle(context, bitStream, branch); +} + +void ConsumeItemBehavior::Load() { + this->m_ConsumeLOT = GetInt("consume_lot", -1); + this->m_NumToConsume = GetInt("num_to_consume", 1); + this->m_ActionNotConsumed = GetAction("action_not_consumed"); + this->m_ActionConsumed = GetAction("action_consumed"); +} diff --git a/dGame/dBehaviors/ConsumeItemBehavior.h b/dGame/dBehaviors/ConsumeItemBehavior.h new file mode 100644 index 00000000..f3eeb330 --- /dev/null +++ b/dGame/dBehaviors/ConsumeItemBehavior.h @@ -0,0 +1,17 @@ +#pragma once +#include "Behavior.h" + +class ConsumeItemBehavior final : public Behavior +{ +public: + explicit ConsumeItemBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {} + void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Sync(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override; + void Load() override; + +private: + LOT m_ConsumeLOT; + uint32_t m_NumToConsume; + Behavior* m_ActionNotConsumed; + Behavior* m_ActionConsumed; +}; diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 7a7ca20a..4d737ab7 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -300,38 +300,26 @@ void InventoryComponent::AddItem( } } -void InventoryComponent::RemoveItem(const LOT lot, const uint32_t count, eInventoryType inventoryType, const bool ignoreBound) { +bool InventoryComponent::RemoveItem(const LOT lot, const uint32_t count, eInventoryType inventoryType, const bool ignoreBound, const bool silent) { if (count == 0) { LOG("Attempted to remove 0 of item (%i) from the inventory!", lot); - - return; + return false; } - - if (inventoryType == INVALID) { - inventoryType = Inventory::FindInventoryTypeForLot(lot); - } - + if (inventoryType == INVALID) inventoryType = Inventory::FindInventoryTypeForLot(lot); auto* inventory = GetInventory(inventoryType); - - if (inventory == nullptr) { - return; - } + if (!inventory) return false; auto left = std::min(count, inventory->GetLotCount(lot)); + if (left != count) return false; while (left > 0) { auto* item = FindItemByLot(lot, inventoryType, false, ignoreBound); - - if (item == nullptr) { - break; - } - + if (!item) break; const auto delta = std::min(left, item->GetCount()); - - item->SetCount(item->GetCount() - delta); - + item->SetCount(item->GetCount() - delta, silent); left -= delta; } + return true; } void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType inventory, const uint32_t count, const bool showFlyingLot, bool isModMoveAndEquip, const bool ignoreEquipped, const int32_t preferredSlot) { diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index e818d2cb..f4d38d43 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -118,8 +118,9 @@ public: * @param count the number of items to remove * @param inventoryType optional inventory type to remove the item from * @param ignoreBound ignores bound items + * @param silent silently remove the item */ - void RemoveItem(LOT lot, uint32_t count, eInventoryType inventoryType = INVALID, bool ignoreBound = false); + bool RemoveItem(LOT lot, uint32_t count, eInventoryType inventoryType = INVALID, bool ignoreBound = false, bool silent = false); /** * Moves an existing item to an inventory of the entity