diff --git a/L2BotCore/Domain/Entities/ArmorItem.h b/L2BotCore/Domain/Entities/ArmorItem.h new file mode 100644 index 0000000..b75871e --- /dev/null +++ b/L2BotCore/Domain/Entities/ArmorItem.h @@ -0,0 +1,170 @@ +#pragma once +#include +#include +#include +#include "BaseItem.h" +#include "../Enums/ArmorType.h" +#include "../Enums/CrystalType.h" + +namespace L2Bot::Domain::Entities +{ + class ArmorItem : public BaseItem + { + public: + void Update(const EntityInterface* other) override + { + const ArmorItem* casted = static_cast(other); + + BaseItem::Update(other); + + m_IsEquipped = casted->m_IsEquipped; + m_EnchantLevel = casted->m_EnchantLevel; + m_ArmorType = casted->m_ArmorType; + m_CrystalType = casted->m_CrystalType; + m_PDef = casted->m_PDef; + m_MDef = casted->m_MDef; + m_SetEffect = casted->m_SetEffect; + m_AddSetEffect = casted->m_AddSetEffect; + m_EnchantEffect = casted->m_EnchantEffect; + } + void SaveState() override + { + BaseItem::SaveState(); + m_PrevState = + { + m_IsEquipped, + m_EnchantLevel, + m_PDef, + m_MDef, + false + }; + } + const bool IsEqual(const EntityInterface* other) const override + { + const ArmorItem* casted = static_cast(other); + return BaseItem::IsEqual(other) && + m_IsEquipped == casted->m_IsEquipped && + m_EnchantLevel == casted->m_EnchantLevel && + m_ArmorType == casted->m_ArmorType && + m_CrystalType == casted->m_CrystalType && + m_PDef == casted->m_PDef && + m_MDef == casted->m_MDef && + m_SetEffect == casted->m_SetEffect && + m_AddSetEffect == casted->m_AddSetEffect && + m_EnchantEffect == casted->m_EnchantEffect; + } + + const std::vector BuildSerializationNodes() const override + { + std::vector result = BaseItem::BuildSerializationNodes(); + + if (m_PrevState.isNewState) + { + result.push_back({ "armorType", std::to_string(static_cast(m_ArmorType)) }); + result.push_back({ "crystalType", std::to_string(static_cast(m_CrystalType)) }); + result.push_back({ "setEffect", m_SetEffect }); + result.push_back({ "addSetEffect", m_AddSetEffect }); + result.push_back({ "enchantEffect", m_EnchantEffect }); + } + + if (m_PrevState.isNewState || m_IsEquipped != m_PrevState.isEquipped) + { + result.push_back({ "isEquipped", std::to_string(m_IsEquipped) }); + } + if (m_PrevState.isNewState || m_EnchantLevel != m_PrevState.enchantLevel) + { + result.push_back({ "enchantLevel", std::to_string(m_EnchantLevel) }); + } + if (m_PrevState.isNewState || m_PDef != m_PrevState.pDef) + { + result.push_back({ "pDef", std::to_string(m_PDef) }); + } + if (m_PrevState.isNewState || m_MDef != m_PrevState.mDef) + { + result.push_back({ "mDef", std::to_string(m_MDef) }); + } + + return result; + } + + ArmorItem( + const uint32_t objectId, + const uint32_t itemId, + const int32_t mana, + const std::string& name, + const std::string& iconName, + const std::string& description, + const uint16_t weight, + const bool isEquipped, + const uint16_t enchantLevel, + const Enums::ArmorType armorType, + const Enums::CrystalType crystalType, + const uint16_t pDef, + const uint16_t mDef, + const std::string& setEffect, + const std::string& addSetEffect, + const std::string& enchantEffect + ) : + BaseItem + ( + objectId, + itemId, + mana, + name, + iconName, + description, + weight + ), + m_IsEquipped(isEquipped), + m_EnchantLevel(enchantLevel), + m_ArmorType(armorType), + m_CrystalType(crystalType), + m_PDef(pDef), + m_MDef(mDef), + m_SetEffect(setEffect), + m_AddSetEffect(addSetEffect), + m_EnchantEffect(enchantEffect) + { + } + + ArmorItem(const ArmorItem* other) : + BaseItem(other), + m_IsEquipped(other->m_IsEquipped), + m_EnchantLevel(other->m_EnchantLevel), + m_ArmorType(other->m_ArmorType), + m_CrystalType(other->m_CrystalType), + m_PDef(other->m_PDef), + m_MDef(other->m_MDef), + m_SetEffect(other->m_SetEffect), + m_AddSetEffect(other->m_AddSetEffect), + m_EnchantEffect(other->m_EnchantEffect) + { + } + + ArmorItem() = default; + virtual ~ArmorItem() = default; + + private: + struct GetState + { + bool isEquipped = 0; + uint16_t enchantLevel = 0; + uint16_t pDef = 0; + uint16_t mDef = 0; + + bool isNewState = true; + }; + + private: + bool m_IsEquipped = 0; + uint16_t m_EnchantLevel = 0; + Enums::ArmorType m_ArmorType = Enums::ArmorType::none; + Enums::CrystalType m_CrystalType = Enums::CrystalType::none; + uint16_t m_PDef = 0; + uint16_t m_MDef = 0; + std::string m_SetEffect = ""; + std::string m_AddSetEffect = ""; + std::string m_EnchantEffect = ""; + GetState m_PrevState = GetState(); + }; +} diff --git a/L2BotCore/Domain/Entities/BaseItem.h b/L2BotCore/Domain/Entities/BaseItem.h index e17ee20..2c0c524 100644 --- a/L2BotCore/Domain/Entities/BaseItem.h +++ b/L2BotCore/Domain/Entities/BaseItem.h @@ -9,44 +9,37 @@ namespace L2Bot::Domain::Entities class BaseItem : public EntityInterface { public: - const uint32_t GetId() const + const uint32_t GetId() const override { - return m_ItemId; + return m_ObjectId; } - void Update(const EntityInterface* other) override + virtual void Update(const EntityInterface* other) override { const BaseItem* casted = static_cast(other); SaveState(); + m_ObjectId = casted->m_ObjectId; m_ItemId = casted->m_ItemId; - m_Amount = casted->m_Amount; - m_IsEquipped = casted->m_IsEquipped; - m_EnchantLevel = casted->m_EnchantLevel; m_Mana = casted->m_Mana; m_Name = casted->m_Name; m_IconName = casted->m_IconName; m_Description = casted->m_Description; m_Weight = casted->m_Weight; } - void SaveState() override + virtual void SaveState() override { m_PrevState = { - m_Amount, - m_IsEquipped, - m_EnchantLevel, m_Mana, m_Weight, false }; } - const bool IsEqual(const EntityInterface* other) const override + virtual const bool IsEqual(const EntityInterface* other) const override { const BaseItem* casted = static_cast(other); - return m_ItemId == casted->m_ItemId && - m_Amount == casted->m_Amount && - m_IsEquipped == casted->m_IsEquipped && - m_EnchantLevel == casted->m_EnchantLevel && + return m_ObjectId == casted->m_ObjectId && + m_ItemId == casted->m_ItemId && m_Mana == casted->m_Mana && m_Name == casted->m_Name && m_IconName == casted->m_IconName && @@ -54,10 +47,11 @@ namespace L2Bot::Domain::Entities m_Weight == casted->m_Weight; } - const std::vector BuildSerializationNodes() const override + virtual const std::vector BuildSerializationNodes() const override { std::vector result; + result.push_back({ "objectId", std::to_string(m_ObjectId) }); result.push_back({ "itemId", std::to_string(m_ItemId) }); if (m_PrevState.isNewState) @@ -67,18 +61,6 @@ namespace L2Bot::Domain::Entities result.push_back({ "description", m_Description }); } - if (m_PrevState.isNewState || m_Amount != m_PrevState.amount) - { - result.push_back({ "amount", std::to_string(m_Amount) }); - } - if (m_PrevState.isNewState || m_IsEquipped != m_PrevState.isEquipped) - { - result.push_back({ "isEquipped", std::to_string(m_IsEquipped) }); - } - if (m_PrevState.isNewState || m_EnchantLevel != m_PrevState.enchantLevel) - { - result.push_back({ "enchantLevel", std::to_string(m_EnchantLevel) }); - } if (m_PrevState.isNewState || m_Mana != m_PrevState.mana) { result.push_back({ "mana", std::to_string(m_Mana) }); @@ -92,20 +74,16 @@ namespace L2Bot::Domain::Entities } BaseItem( + const uint32_t objectId, const uint32_t itemId, - const uint32_t amount, - const bool isEquipped, - const uint16_t enchantLevel, const int32_t mana, const std::string& name, const std::string& iconName, const std::string& description, const uint16_t weight ) : + m_ObjectId(objectId), m_ItemId(itemId), - m_Amount(amount), - m_IsEquipped(isEquipped), - m_EnchantLevel(enchantLevel), m_Mana(mana), m_Name(name), m_IconName(iconName), @@ -115,10 +93,8 @@ namespace L2Bot::Domain::Entities } BaseItem(const BaseItem* other) : + m_ObjectId(other->m_ObjectId), m_ItemId(other->m_ItemId), - m_Amount(other->m_Amount), - m_IsEquipped(other->m_IsEquipped), - m_EnchantLevel(other->m_EnchantLevel), m_Mana(other->m_Mana), m_Name(other->m_Name), m_IconName(other->m_IconName), @@ -133,9 +109,6 @@ namespace L2Bot::Domain::Entities private: struct GetState { - uint32_t amount = 0; - bool isEquipped = 0; - uint16_t enchantLevel = 0; int32_t mana = -1; uint16_t weight = 0; @@ -143,10 +116,8 @@ namespace L2Bot::Domain::Entities }; private: + uint32_t m_ObjectId = 0; uint32_t m_ItemId = 0; - uint32_t m_Amount = 0; - bool m_IsEquipped = 0; - uint16_t m_EnchantLevel = 0; int32_t m_Mana = -1; std::string m_Name = ""; std::string m_IconName = ""; diff --git a/L2BotCore/Domain/Entities/EtcItem.h b/L2BotCore/Domain/Entities/EtcItem.h new file mode 100644 index 0000000..65245d7 --- /dev/null +++ b/L2BotCore/Domain/Entities/EtcItem.h @@ -0,0 +1,104 @@ +#pragma once +#include +#include +#include +#include "BaseItem.h" + +namespace L2Bot::Domain::Entities +{ + class EtcItem : public BaseItem + { + public: + void Update(const EntityInterface* other) override + { + const EtcItem* casted = static_cast(other); + + BaseItem::Update(other); + + m_Amount = casted->m_Amount; + m_IsQuest = casted->m_IsQuest; + } + void SaveState() override + { + BaseItem::SaveState(); + m_PrevState = + { + m_Amount, + false + }; + } + const bool IsEqual(const EntityInterface* other) const override + { + const EtcItem* casted = static_cast(other); + return BaseItem::IsEqual(other) && + m_IsQuest == casted->m_IsQuest && + m_Amount == casted->m_Amount; + } + + const std::vector BuildSerializationNodes() const override + { + std::vector result = BaseItem::BuildSerializationNodes(); + + if (m_PrevState.isNewState) + { + result.push_back({ "isQuest", std::to_string(m_IsQuest) }); + } + + if (m_PrevState.isNewState || m_Amount != m_PrevState.amount) + { + result.push_back({ "amount", std::to_string(m_Amount) }); + } + + return result; + } + + EtcItem( + const uint32_t objectId, + const uint32_t itemId, + const int32_t mana, + const std::string& name, + const std::string& iconName, + const std::string& description, + const uint16_t weight, + const uint32_t amount, + const bool isQuest + ) : + BaseItem + ( + objectId, + itemId, + mana, + name, + iconName, + description, + weight + ), + m_Amount(amount), + m_IsQuest(isQuest) + { + } + + EtcItem(const EtcItem* other) : + BaseItem(other), + m_Amount(other->m_Amount), + m_IsQuest(other->m_IsQuest) + { + } + + EtcItem() = default; + virtual ~EtcItem() = default; + + private: + struct GetState + { + uint32_t amount = 0; + + bool isNewState = true; + }; + + private: + uint32_t m_Amount = 0; + bool m_IsQuest = false; + GetState m_PrevState = GetState(); + }; +} diff --git a/L2BotCore/Domain/Enums/ArmorType.h b/L2BotCore/Domain/Enums/ArmorType.h new file mode 100644 index 0000000..2651d83 --- /dev/null +++ b/L2BotCore/Domain/Enums/ArmorType.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace L2Bot::Domain::Enums +{ + enum class ArmorType : uint8_t + { + none = 0, + light, + heavy, + robe + }; +} \ No newline at end of file diff --git a/L2BotCore/Domain/Enums/CrystalType.h b/L2BotCore/Domain/Enums/CrystalType.h new file mode 100644 index 0000000..fb391e2 --- /dev/null +++ b/L2BotCore/Domain/Enums/CrystalType.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace L2Bot::Domain::Enums +{ + enum class CrystalType : int8_t + { + none = -1, + ng, + d, + c, + b, + a, + s + }; +} \ No newline at end of file diff --git a/L2BotCore/L2BotCore.vcxproj b/L2BotCore/L2BotCore.vcxproj index b82719a..1f275ee 100644 --- a/L2BotCore/L2BotCore.vcxproj +++ b/L2BotCore/L2BotCore.vcxproj @@ -160,9 +160,13 @@ + + + + diff --git a/L2BotCore/L2BotCore.vcxproj.filters b/L2BotCore/L2BotCore.vcxproj.filters index 04977fa..7781603 100644 --- a/L2BotCore/L2BotCore.vcxproj.filters +++ b/L2BotCore/L2BotCore.vcxproj.filters @@ -111,6 +111,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/L2BotDll/DTO/ItemData.h b/L2BotDll/DTO/ItemData.h index 0839051..d5e6df5 100644 --- a/L2BotDll/DTO/ItemData.h +++ b/L2BotDll/DTO/ItemData.h @@ -4,9 +4,11 @@ struct ItemData { + const uint32_t objectId = 0; const uint32_t itemId = 0; const uint32_t amount = 0; const uint16_t isEquipped = 0; const uint16_t enchantLevel = 0; const int32_t mana = -1; + const bool isQuest = false; }; \ No newline at end of file diff --git a/L2BotDll/Events/ItemCreatedEvent.h b/L2BotDll/Events/ItemCreatedEvent.h index c6833d1..a089c5c 100644 --- a/L2BotDll/Events/ItemCreatedEvent.h +++ b/L2BotDll/Events/ItemCreatedEvent.h @@ -20,7 +20,7 @@ public: return m_ItemData; } - ItemCreatedEvent(const ItemData& itemData) : + ItemCreatedEvent(const ItemData itemData) : m_ItemData(itemData) { diff --git a/L2BotDll/Events/ItemDeletedEvent.h b/L2BotDll/Events/ItemDeletedEvent.h index 2c19db0..550e761 100644 --- a/L2BotDll/Events/ItemDeletedEvent.h +++ b/L2BotDll/Events/ItemDeletedEvent.h @@ -15,13 +15,13 @@ public: return std::string(name); } - const uint32_t GetItemId() const + const uint32_t GetObjectId() const { - return m_Id; + return m_ObjectId; } - ItemDeletedEvent(const uint32_t id) : - m_Id(id) + ItemDeletedEvent(const uint32_t objectId) : + m_ObjectId(objectId) { } @@ -30,5 +30,5 @@ public: virtual ~ItemDeletedEvent() = default; private: - const uint32_t m_Id; + const uint32_t m_ObjectId; }; \ No newline at end of file diff --git a/L2BotDll/Events/ItemUpdatedEvent.h b/L2BotDll/Events/ItemUpdatedEvent.h index a4fa7df..508f01a 100644 --- a/L2BotDll/Events/ItemUpdatedEvent.h +++ b/L2BotDll/Events/ItemUpdatedEvent.h @@ -20,7 +20,7 @@ public: return m_ItemData; } - ItemUpdatedEvent(const ItemData& itemData) : + ItemUpdatedEvent(const ItemData itemData) : m_ItemData(itemData) { diff --git a/L2BotDll/Services/WorldHandler.h b/L2BotDll/Services/WorldHandler.h index d37a63a..0147d28 100644 --- a/L2BotDll/Services/WorldHandler.h +++ b/L2BotDll/Services/WorldHandler.h @@ -119,8 +119,8 @@ private: { std::vector items { - /*Serializers::SerializableStateContainer{m_HeroService.GetEntities(), "hero"}, - Serializers::SerializableStateContainer{m_DropService.GetEntities(), "drop"}, + Serializers::SerializableStateContainer{m_HeroService.GetEntities(), "hero"}, + /*Serializers::SerializableStateContainer{m_DropService.GetEntities(), "drop"}, Serializers::SerializableStateContainer{m_NPCService.GetEntities(), "npc"}, Serializers::SerializableStateContainer{m_PlayerService.GetEntities(), "player"}, Serializers::SerializableStateContainer{m_SkillService.GetEntities(), "skill"},*/ diff --git a/L2BotDll/Versions/Interlude/Factories/ItemFactory.h b/L2BotDll/Versions/Interlude/Factories/ItemFactory.h index a6221ea..780b43f 100644 --- a/L2BotDll/Versions/Interlude/Factories/ItemFactory.h +++ b/L2BotDll/Versions/Interlude/Factories/ItemFactory.h @@ -6,7 +6,8 @@ #include "../GameStructs/L2GameDataWrapper.h" #include "../GameStructs/FName.h" #include "../../../Common/Common.h" -#include "Domain/Entities/BaseItem.h" +#include "Domain/Entities/EtcItem.h" +#include "Domain/Entities/ArmorItem.h" #include "../../../DTO/ItemData.h" using namespace L2Bot::Domain; @@ -30,19 +31,98 @@ namespace Interlude const auto data = m_L2GameData.GetItemData(itemInfo.itemId); const auto nameEntry = data ? m_FName.GetEntry(data->nameIndex) : nullptr; + const auto name = nameEntry ? ConvertFromWideChar(nameEntry->value) : ""; const auto iconEntry = data ? m_FName.GetEntry(data->iconNameIndex) : nullptr; - const auto description = data && data->description ? data->description : L""; + const auto icon = iconEntry ? ConvertFromWideChar(iconEntry->value) : ""; + const auto description = data && data->description ? ConvertFromWideChar(data->description) : ""; - return std::make_unique( + if (data) + { + switch (data->dataType) + { + case L2::ItemDataType::ARMOR: + return CreateArmor(itemInfo, data, name, icon, description); + case L2::ItemDataType::WEAPON: + return CreateEtc(itemInfo, data, name, icon, description); + } + } + + return CreateEtc(itemInfo, data, name, icon, description); + } + + std::unique_ptr CreateFromPointer(const Entities::BaseItem* other) const + { + { + const auto object = dynamic_cast(other); + if (object) + { + return std::make_unique(object); + } + } + { + const auto object = dynamic_cast(other); + if (object) + { + return std::make_unique(object); + } + } + + return std::make_unique(other); + } + + private: + std::unique_ptr CreateEtc( + const ItemData& itemInfo, + const FL2ItemDataBase* itemData, + const std::string& name, + const std::string& icon, + const std::string& description + ) const + { + return std::make_unique( + itemInfo.objectId, itemInfo.itemId, + itemInfo.mana, + name, + icon, + description, + itemData ? itemData->weight : 0, itemInfo.amount, + itemInfo.isQuest + ); + } + + std::unique_ptr CreateArmor( + const ItemData& itemInfo, + const FL2ItemDataBase* itemData, + const std::string& name, + const std::string& icon, + const std::string& description + ) const + { + const auto casted = static_cast(itemData); + + const auto setEffect = casted && casted->setEffect ? ConvertFromWideChar(casted->setEffect) : ""; + const auto addSetEffect = casted && casted->setEffect ? ConvertFromWideChar(casted->setEffect) : ""; + const auto enchantEffect = casted && casted->enchantEffect ? ConvertFromWideChar(casted->enchantEffect) : ""; + + return std::make_unique( + itemInfo.objectId, + itemInfo.itemId, + itemInfo.mana, + name, + icon, + description, + itemData ? itemData->weight : 0, itemInfo.isEquipped > 0, itemInfo.enchantLevel, - itemInfo.mana, - nameEntry ? ConvertFromWideChar(nameEntry->value) : "", - iconEntry ? ConvertFromWideChar(iconEntry->value) : "", - ConvertFromWideChar(description), - data ? data->weight : 0 + casted ? static_cast(casted->armorType) : Enums::ArmorType::none, + casted ? static_cast(casted->crystalType) : Enums::CrystalType::none, + casted ? casted->pDef : 0, + casted ? casted->mDef : 0, + setEffect, + addSetEffect, + enchantEffect ); } diff --git a/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp b/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp index 442430d..df666cd 100644 --- a/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp +++ b/L2BotDll/Versions/Interlude/GameStructs/GameEngineWrapper.cpp @@ -107,11 +107,13 @@ namespace Interlude { ItemData { + itemInfo.objectId, itemInfo.itemId, itemInfo.amount, itemInfo.isEquipped, itemInfo.enchantLevel, itemInfo.mana, + itemInfo.type2 == L2::ItemType2::QUEST } } ); @@ -122,11 +124,13 @@ namespace Interlude { const ItemData itemData { + itemInfo.objectId, itemInfo.itemId, itemInfo.amount, itemInfo.isEquipped, itemInfo.enchantLevel, itemInfo.mana, + itemInfo.type2 == L2::ItemType2::QUEST }; switch (actionType) @@ -138,7 +142,7 @@ namespace Interlude EventDispatcher::GetInstance().Dispatch(ItemUpdatedEvent{ itemData }); break; case UpdateItemListActionType::deleted: - EventDispatcher::GetInstance().Dispatch(ItemDeletedEvent{ itemInfo.itemId }); + EventDispatcher::GetInstance().Dispatch(ItemDeletedEvent{ itemInfo.objectId }); break; } (*__OnReceiveUpdateItemList)(This, actionType, itemInfo); diff --git a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h index 0b77ca2..db0ecab 100644 --- a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h @@ -10,6 +10,7 @@ #include "../../../Events/ItemCreatedEvent.h" #include "../../../Events/ItemUpdatedEvent.h" #include "../../../Events/ItemDeletedEvent.h" +#include "../../../Events/HeroDeletedEvent.h" #include "../../../Events/EventDispatcher.h" using namespace L2Bot::Domain; @@ -30,7 +31,7 @@ namespace Interlude } const auto objects = m_EntityHandler.GetEntities(itemPtrs, [this](Entities::BaseItem* item) { - return std::make_unique(item); + return m_Factory.CreateFromPointer(item); }); auto result = std::vector>(); @@ -57,6 +58,18 @@ namespace Interlude EventDispatcher::GetInstance().Subscribe(ItemDeletedEvent::name, [this](const Event& evt) { OnItemDeleted(evt); }); + EventDispatcher::GetInstance().Subscribe(HeroDeletedEvent::name, [this](const Event& evt) { + OnHeroDeleted(evt); + }); + } + + void OnHeroDeleted(const Event& evt) + { + std::shared_lock(m_Mutex); + if (evt.GetName() == HeroDeletedEvent::name) + { + Reset(); + } } void OnItemCreated(const Event& evt) @@ -68,14 +81,14 @@ namespace Interlude const auto& data = casted.GetItemData(); auto item = m_Factory.Create(data); - if (m_Items.find(data.itemId) == m_Items.end()) + if (m_Items.find(data.objectId) == m_Items.end()) { - m_Items.emplace(data.itemId, std::move(item)); + m_Items.emplace(data.objectId, std::move(item)); } else { // When equip/unequip accessories - m_Items[data.itemId]->Update(item.get()); + m_Items[data.objectId]->Update(item.get()); } } } @@ -89,16 +102,17 @@ namespace Interlude const auto& data = casted.GetItemData(); //todo exception? - if (m_Items.find(data.itemId) == m_Items.end()) + if (m_Items.find(data.objectId) == m_Items.end()) { return; } auto item = m_Factory.Create(data); - m_Items[data.itemId]->Update(item.get()); + m_Items[data.objectId]->Update(item.get()); } } + //todo deleted ehchant scroll void OnItemDeleted(const Event& evt) { //fixme may be a race condition @@ -107,7 +121,7 @@ namespace Interlude { const auto casted = static_cast(evt); - m_Items.erase(casted.GetItemId()); + m_Items.erase(casted.GetObjectId()); } }