diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index c98323a9..ad9b8cd5 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -1644,6 +1644,26 @@ void Entity::PickupItem(const LWOOBJID& objectID) { droppedLoot.erase(objectID); } +bool Entity::CanPickupCoins(uint64_t count) { + if (!IsPlayer()) return false; + auto* player = static_cast(this); + auto droppedCoins = player->GetDroppedCoins(); + if (count > droppedCoins) { + return false; + } else { + player->SetDroppedCoins(droppedCoins - count); + return true; + } +} + +void Entity::RegisterCoinDrop(uint64_t count) { + if (!IsPlayer()) return; + auto* player = static_cast(this); + auto droppedCoins = player->GetDroppedCoins(); + droppedCoins += count; + player->SetDroppedCoins(droppedCoins); +} + void Entity::AddChild(Entity* child) { m_ChildEntities.push_back(child); } diff --git a/dGame/Entity.h b/dGame/Entity.h index 01699a84..31b2b303 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -202,6 +202,9 @@ public: void AddLootItem(const Loot::Info& info); void PickupItem(const LWOOBJID& objectID); + bool CanPickupCoins(uint64_t count); + void RegisterCoinDrop(uint64_t count); + void ScheduleKillAfterUpdate(Entity* murderer = nullptr); void TriggerEvent(std::string eveneventtID, Entity* optionalTarget = nullptr); void ScheduleDestructionAfterUpdate() { m_ShouldDestroyAfterUpdate = true; } diff --git a/dGame/Player.cpp b/dGame/Player.cpp index 9a158c8f..634d4a68 100644 --- a/dGame/Player.cpp +++ b/dGame/Player.cpp @@ -24,6 +24,7 @@ Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Enti m_GMLevel = m_Character->GetGMLevel(); m_SystemAddress = m_ParentUser->GetSystemAddress(); m_DroppedLoot = {}; + m_DroppedCoins = 0; m_GhostReferencePoint = NiPoint3::ZERO; m_GhostOverridePoint = NiPoint3::ZERO; @@ -290,6 +291,14 @@ const std::vector& Player::GetAllPlayers() return m_Players; } +uint64_t Player::GetDroppedCoins() { + return m_DroppedCoins; +} + +void Player::SetDroppedCoins(uint64_t value) { + m_DroppedCoins = value; +} + Player::~Player() { Game::logger->Log("Player", "Deleted player\n"); diff --git a/dGame/Player.h b/dGame/Player.h index abd811c5..bba01363 100644 --- a/dGame/Player.h +++ b/dGame/Player.h @@ -36,6 +36,8 @@ public: std::map& GetDroppedLoot(); + uint64_t GetDroppedCoins(); + /** * Setters */ @@ -52,6 +54,8 @@ public: void SetGhostOverride(bool value); + void SetDroppedCoins(uint64_t value); + /** * Wrapper for sending an in-game mail. * @@ -126,5 +130,7 @@ private: std::map m_DroppedLoot; + uint64_t m_DroppedCoins; + static std::vector m_Players; }; diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c6b3c9bd..fad5d7de 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1031,6 +1031,10 @@ void GameMessages::SendDropClientLoot(Entity* entity, const LWOOBJID& sourceID, entity->AddLootItem(info); } + if (item == LOT_NULL && currency != 0) { + entity->RegisterCoinDrop(currency); + } + if (spawnPos != NiPoint3::ZERO) { bUsePosition = true; @@ -5232,8 +5236,12 @@ void GameMessages::HandlePickupCurrency(RakNet::BitStream* inStream, Entity* ent unsigned int currency; inStream->Read(currency); + if (currency == 0) return; + auto* ch = entity->GetCharacter(); - ch->SetCoins(ch->GetCoins() + currency); + if (entity->CanPickupCoins(currency)) { + ch->SetCoins(ch->GetCoins() + currency); + } } void GameMessages::HandleRequestDie(RakNet::BitStream* inStream, Entity* entity) {