diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 2f4942e20f7..c968c57ccdf 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -5613,6 +5613,15 @@ bool Player::isMarketExhausted() const { return (OTSYS_TIME() - lastMarketInteraction < exhaust_time); } +// Player talk with npc exhausted +bool Player::isNpcExhausted(uint32_t exhaustionTime /*= 250*/) const { + return (OTSYS_TIME() - lastNpcInteraction < exhaustionTime); +} + +void Player::updateNpcExhausted() { + lastNpcInteraction = OTSYS_TIME(); +} + uint64_t Player::getItemCustomPrice(uint16_t itemId, bool buyPrice/* = false*/) const { auto it = itemPriceMap.find(itemId); diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index a806c446830..1b542caef8f 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -1692,6 +1692,9 @@ class Player final : public Creature, public Cylinder lastMarketInteraction = OTSYS_TIME(); } + bool isNpcExhausted(uint32_t exhaustionTime = 150) const; + void updateNpcExhausted(); + bool isQuickLootListedItem(const Item* item) const { if (!item) { return false; @@ -2211,7 +2214,8 @@ class Player final : public Creature, public Cylinder int64_t skullTicks = 0; int64_t lastWalkthroughAttempt = 0; int64_t lastToggleMount = 0; - int64_t lastMarketInteraction = 0; // Market exhaust. + int64_t lastMarketInteraction = 0; + int64_t lastNpcInteraction = 0; int64_t lastStashInteraction = 0; int64_t lastDepotSearchInteraction = 0; int64_t lastPing; diff --git a/src/game/game.cpp b/src/game/game.cpp index dd1e73a7945..5b965c5a826 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -4359,7 +4359,14 @@ void Game::playerBuyItem(uint32_t playerId, uint16_t itemId, uint8_t count, uint return; } + // Check npc say exhausted + if (player->isNpcExhausted()) { + player->sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED); + return; + } + merchant->onPlayerBuyItem(player, it.id, count, amount, ignoreCap, inBackpacks); + player->updateNpcExhausted(); } void Game::playerSellItem(uint32_t playerId, uint16_t itemId, uint8_t count, uint8_t amount, bool ignoreEquipped) @@ -4383,7 +4390,14 @@ void Game::playerSellItem(uint32_t playerId, uint16_t itemId, uint8_t count, uin return; } + // Check npc say exhausted + if (player->isNpcExhausted()) { + player->sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED); + return; + } + merchant->onPlayerSellItem(player, it.id, count, amount, ignoreEquipped); + player->updateNpcExhausted(); } void Game::playerCloseShop(uint32_t playerId) @@ -5309,6 +5323,17 @@ bool Game::playerSpeakTo(Player* player, SpeakClasses type, const std::string& r void Game::playerSpeakToNpc(Player* player, const std::string& text) { + if (player == nullptr) { + SPDLOG_ERROR("[Game::playerSpeakToNpc] - Player is nullptr"); + return; + } + + // Check npc say exhausted + if (player->isNpcExhausted()) { + player->sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED); + return; + } + SpectatorHashSet spectators; map.getSpectators(spectators, player->getPosition()); for (Creature* spectator : spectators) { @@ -5316,6 +5341,8 @@ void Game::playerSpeakToNpc(Player* player, const std::string& text) spectator->onCreatureSay(player, TALKTYPE_PRIVATE_PN, text); } } + + player->updateNpcExhausted(); } //--