diff --git a/src/teleport-to-node.cpp b/src/teleport-to-node.cpp index 356df2c..5e62acf 100644 --- a/src/teleport-to-node.cpp +++ b/src/teleport-to-node.cpp @@ -4,17 +4,17 @@ #include "ChatCommand.h" #include "Player.h" #include "GameObject.h" +#include "ObjectAccessor.h" +#include "Timer.h" #include -#include #include -#include using namespace Acore::ChatCommands; static constexpr float TELEPORT_DISTANCE = 250.0f; -static constexpr float Z_BUMP = 1.5f; -static constexpr float MIN_RETELEPORT_DIST = 1.0f; +static constexpr float Z_BUMP = 1.0f; +static constexpr uint32 RECHECK_INTERVAL_MS = 5000; static const std::vector kVeinEntries = { 324,1610,1667,1731,1732,1733,1734,2054,2055,3763,3764,19903, @@ -25,57 +25,49 @@ static const std::vector kVeinEntries = { 189978,189979,189980,189981,195036, }; -static std::unordered_map s_lastNodeByPlayer; - -static GameObject* FindNearestReadyVein(Player* player, float maxRange, float minDistanceFromPlayer) +static GameObject* FindNearestVein(Player* player, float maxRange) { GameObject* nearest = nullptr; float nearestDist = std::numeric_limits::infinity(); - uint64 lastNode = 0; - if (auto it = s_lastNodeByPlayer.find(player->GetGUID().GetRawValue()); it != s_lastNodeByPlayer.end()) - lastNode = it->second; for (uint32 entry : kVeinEntries) { if (GameObject* go = player->FindNearestGameObject(entry, maxRange)) { - if (go->GetGUID().GetRawValue() == lastNode) - continue; - - if (go->getLootState() != LootState::GO_READY) - continue; - - if (go->GetGoState() != GOState::GO_STATE_READY) - continue; - - float d = player->GetDistance(go); - if (d < minDistanceFromPlayer) - continue; - - if (d <= maxRange && d < nearestDist) + float dist = player->GetDistance(go); + if (dist <= maxRange && dist < nearestDist) { nearest = go; - nearestDist = d; + nearestDist = dist; } } } return nearest; } -static bool DoTeleNode(Player* player) +static void DumpNearbyNodes(Player* player) +{ + ChatHandler(player->GetSession()).PSendSysMessage("Nearby node coordinates:"); + for (uint32 entry : kVeinEntries) + { + if (GameObject* go = player->FindNearestGameObject(entry, TELEPORT_DISTANCE)) + { + ChatHandler(player->GetSession()).PSendSysMessage( + "Entry %u -> Map %u X: %.2f Y: %.2f Z: %.2f", + entry, go->GetMapId(), go->GetPositionX(), go->GetPositionY(), go->GetPositionZ() + ); + } + } +} + +static void TeleportToNearest(Player* player) { if (!player) - return false; + return; - if (player->IsInCombat()) + GameObject* node = FindNearestVein(player, TELEPORT_DISTANCE); + if (node) { - ChatHandler(player->GetSession()).PSendSysMessage("You can't use this while in combat."); - return true; - } - - if (GameObject* node = FindNearestReadyVein(player, TELEPORT_DISTANCE, MIN_RETELEPORT_DIST)) - { - s_lastNodeByPlayer[player->GetGUID().GetRawValue()] = node->GetGUID().GetRawValue(); player->TeleportTo( node->GetMapId(), node->GetPositionX(), @@ -83,12 +75,41 @@ static bool DoTeleNode(Player* player) node->GetPositionZ() + Z_BUMP, node->GetOrientation() ); + ChatHandler(player->GetSession()).PSendSysMessage("Teleported to nearest node."); } else { - ChatHandler(player->GetSession()).PSendSysMessage("No mining nodes found within range."); + ChatHandler(player->GetSession()).PSendSysMessage("No node found within range."); + } +} + +class TeleNodeRunnable : public BasicEvent +{ +public: + explicit TeleNodeRunnable(Player* player) : _player(player) { } + bool Execute(uint64 /*time*/, uint32 /*diff*/) override + { + if (!_player || !_player->IsInWorld()) + return true; + + DumpNearbyNodes(_player); + TeleportToNearest(_player); + _player->m_Events.AddEvent(new TeleNodeRunnable(_player), _player->m_Events.CalculateTime(RECHECK_INTERVAL_MS)); + return true; } +private: + Player* _player; +}; + +static bool HandleTeleNode(ChatHandler* handler) +{ + Player* player = handler->GetSession()->GetPlayer(); + if (!player) + return false; + + player->m_Events.AddEvent(new TeleNodeRunnable(player), player->m_Events.CalculateTime(0)); + handler->PSendSysMessage("telenode started: re-evaluating every 5 seconds."); return true; } @@ -105,23 +126,6 @@ public: }; return commandTable; } - -private: - static bool HandleTeleNode(ChatHandler* handler) - { - if (!handler) - return false; - - Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr; - if (!player) - { - handler->SendSysMessage("Player only."); - handler->SetSentErrorMessage(true); - return false; - } - - return DoTeleNode(player); - } }; void AddSC_telenode_commandscript()