#include "ScriptMgr.h" #include "Player.h" #include "GameObject.h" #include "ObjectAccessor.h" #include "Config.h" #include "LootMgr.h" namespace { bool sEnabled = true; uint32 sTickMs = 200; float sScanRange = 30.0f; std::vector sBobberEntries; std::vector ParseEntryList(std::string const& csv) { std::vector out; std::stringstream ss(csv); std::string item; while (std::getline(ss, item, ',')) { item.erase(0, item.find_first_not_of(" \t\r\n")); item.erase(item.find_last_not_of(" \t\r\n") + 1); if (!item.empty()) out.push_back(uint32(std::stoul(item))); } return out; } void TryAutoFish(Player* plr) { if (!plr || !plr->IsInWorld()) return; std::list nearList; for (auto entry : sBobberEntries) plr->GetGameObjectListWithEntryInGrid(nearList, entry, sScanRange); for (GameObject* go : nearList) { if (!go || go->GetOwnerGUID() != plr->GetGUID()) continue; if (go->getLootState() == GO_READY) { plr->SendLoot(go->GetGUID(), LOOT_FISHING); Loot* loot = &go->loot; for (uint32 i = 0; i < loot->items.size(); ++i) { if (LootItem* li = loot->LootItemInSlot(i, plr)) plr->AutoStoreLootItem(i, loot); } plr->SendLootRelease(go->GetGUID()); go->SetLootState(GO_JUST_DEACTIVATED); return; } } } } class AutoFish_WorldScript : public WorldScript { public: AutoFish_WorldScript() : WorldScript("AutoFish_WorldScript") {} void OnAfterConfigLoad(bool) override { sEnabled = sConfigMgr->GetOption("AutoFish.Enabled", true); sTickMs = sConfigMgr->GetOption("AutoFish.TickMs", 200u); sScanRange = sConfigMgr->GetOption("AutoFish.ScanRange", 30.0f); sBobberEntries = ParseEntryList(sConfigMgr->GetOption("AutoFish.BobberEntries", "35591")); } void OnUpdate(uint32 diff) override { if (!sEnabled) return; static uint32 acc = 0; acc += diff; if (acc < sTickMs) return; acc = 0; auto const& players = ObjectAccessor::GetPlayers(); for (auto const& kv : players) { Player* plr = kv.second; if (!plr || !plr->IsInWorld() || plr->IsGameMaster()) continue; TryAutoFish(plr); } } }; void AddSC_autofish_world() { new AutoFish_WorldScript(); }