diff --git a/conf/mod_autofish.conf.dist b/conf/mod_autofish.conf.dist index f94167f..2705469 100644 --- a/conf/mod_autofish.conf.dist +++ b/conf/mod_autofish.conf.dist @@ -8,3 +8,7 @@ AutoFish.ScanRange = 30.0 AutoFish.BobberEntries = 35591 # Automatically loot fish AutoFish.ServerAutoLoot = 1 +# Automatically Recast the fishing line +AutoFish.AutoRecast = 1 +AutoFish.RecastDelayMs = 500 +AutoFish.RecastSpell = 131474 diff --git a/src/mod_autofish.cpp b/src/mod_autofish.cpp index b33c513..20bfb42 100644 --- a/src/mod_autofish.cpp +++ b/src/mod_autofish.cpp @@ -9,15 +9,22 @@ #include #include #include +#include namespace { bool sEnabled = true; bool sServerAutoLoot = true; + bool sAutoRecast = true; uint32 sTickMs = 200; float sScanRange = 30.0f; + uint32 sRecastDelayMs = 500; + uint32 sRecastSpell = 131474; std::vector sBobberEntries; + struct GuidHash { std::size_t operator()(ObjectGuid const& g) const noexcept { return std::hash()(g.GetRawValue()); } }; + std::unordered_map sRecastTimers; + std::vector ParseEntryList(std::string const& csv) { std::vector out; @@ -33,6 +40,32 @@ namespace return out; } + void ScheduleRecast(Player* plr) + { + if (!sAutoRecast || !plr || !plr->IsInWorld()) + return; + sRecastTimers[plr->GetGUID()] = sRecastDelayMs; + } + + void TickRecast(uint32 diff) + { + for (auto it = sRecastTimers.begin(); it != sRecastTimers.end();) + { + if (it->second > diff) + { + it->second -= diff; + ++it; + } + else + { + Player* plr = ObjectAccessor::FindPlayer(it->first); + if (plr && plr->IsInWorld() && plr->IsAlive() && !plr->IsInCombat()) + plr->CastSpell(plr, sRecastSpell, true); + it = sRecastTimers.erase(it); + } + } + } + void TryAutoFish(Player* plr) { if (!plr || !plr->IsInWorld()) @@ -61,11 +94,11 @@ namespace InventoryResult msg = EQUIP_ERR_OK; plr->StoreLootItem(uint8(i), loot, msg); } - plr->SendLootRelease(go->GetGUID()); go->SetLootState(GO_JUST_DEACTIVATED); } + ScheduleRecast(plr); return; } } @@ -81,8 +114,11 @@ public: { sEnabled = sConfigMgr->GetOption("AutoFish.Enabled", true); sServerAutoLoot = sConfigMgr->GetOption("AutoFish.ServerAutoLoot", true); + sAutoRecast = sConfigMgr->GetOption("AutoFish.AutoRecast", true); sTickMs = sConfigMgr->GetOption("AutoFish.TickMs", 200u); sScanRange = sConfigMgr->GetOption("AutoFish.ScanRange", 30.0f); + sRecastDelayMs = sConfigMgr->GetOption("AutoFish.RecastDelayMs", 500u); + sRecastSpell = sConfigMgr->GetOption("AutoFish.RecastSpell", 131474u); sBobberEntries = ParseEntryList(sConfigMgr->GetOption("AutoFish.BobberEntries", "35591")); } @@ -93,18 +129,20 @@ public: static uint32 acc = 0; acc += diff; - if (acc < sTickMs) - return; - acc = 0; - - auto const& players = ObjectAccessor::GetPlayers(); - for (auto const& kv : players) + if (acc >= sTickMs) { - Player* plr = kv.second; - if (!plr || !plr->IsInWorld() || plr->IsGameMaster()) - continue; - TryAutoFish(plr); + 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); + } } + + TickRecast(diff); } };