@@ -67,7 +67,8 @@ uint8 _npcBotOwnerExpireMode;
67
67
int32 _botInfoPacketsLimit;
68
68
uint32 _gearBankCapacity;
69
69
uint32 _gearBankEquipmentSetsCount;
70
- uint32 _npcBotsCost;
70
+ uint32 _npcBotsCostHire;
71
+ uint32 _npcBotsCostRent;
71
72
uint32 _npcBotUpdateDelayBase;
72
73
uint32 _npcBotEngageDelayDPS_default;
73
74
uint32 _npcBotEngageDelayHeal_default;
@@ -281,6 +282,7 @@ void AddNpcBotScripts()
281
282
BotMgr::BotMgr (Player* const master) : _owner(master), _dpstracker(new DPSTracker())
282
283
{
283
284
_quickrecall = false ;
285
+ _update_lock = false ;
284
286
_data = nullptr ;
285
287
}
286
288
BotMgr::~BotMgr ()
@@ -384,7 +386,8 @@ void BotMgr::LoadConfig(bool reload)
384
386
_limitNpcBotsRaids = sConfigMgr ->GetBoolDefault (" NpcBot.Limit.Raid" , true );
385
387
_hideSpawns = sConfigMgr ->GetBoolDefault (" NpcBot.HideSpawns" , false );
386
388
_botInfoPacketsLimit = sConfigMgr ->GetIntDefault (" NpcBot.InfoPacketsLimit" , -1 );
387
- _npcBotsCost = sConfigMgr ->GetIntDefault (" NpcBot.Cost" , 1000000 );
389
+ _npcBotsCostHire = sConfigMgr ->GetIntDefault (" NpcBot.Cost.Hire" , 1000000 );
390
+ _npcBotsCostRent = sConfigMgr ->GetIntDefault (" NpcBot.Cost.Rent" , 0 );
388
391
_npcBotUpdateDelayBase = sConfigMgr ->GetIntDefault (" NpcBot.UpdateDelay.Base" , 0 );
389
392
_npcBotEngageDelayDPS_default = sConfigMgr ->GetIntDefault (" NpcBot.EngageDelay.DPS" , 0 );
390
393
_npcBotEngageDelayHeal_default = sConfigMgr ->GetIntDefault (" NpcBot.EngageDelay.Heal" , 0 );
@@ -1190,6 +1193,12 @@ bool BotMgr::IsWanderingWorldBot(Creature const* bot)
1190
1193
1191
1194
void BotMgr::Update (uint32 diff)
1192
1195
{
1196
+ while (!_delayedRemoveList.empty ())
1197
+ {
1198
+ decltype (_delayedRemoveList)::iterator itr = _delayedRemoveList.begin ();
1199
+ RemoveBot (itr->first , itr->second );
1200
+ }
1201
+
1193
1202
// remove temp bots from bot map before updating it
1194
1203
while (!_removeList.empty ())
1195
1204
{
@@ -1217,6 +1226,8 @@ void BotMgr::Update(uint32 diff)
1217
1226
if (partyCombat)
1218
1227
bot_ai::CalculateAoeSpots (_owner, _aoespots);
1219
1228
1229
+ _update_lock = true ;
1230
+
1220
1231
for (BotMap::const_iterator itr = _bots.begin (); itr != _bots.end (); ++itr)
1221
1232
{
1222
1233
// guid = itr->first;
@@ -1264,6 +1275,8 @@ void BotMgr::Update(uint32 diff)
1264
1275
ai->canUpdate = false ;
1265
1276
}
1266
1277
1278
+ _update_lock = false ;
1279
+
1267
1280
if (_quickrecall)
1268
1281
{
1269
1282
_quickrecall = false ;
@@ -1805,6 +1818,14 @@ void BotMgr::RemoveAllBots(uint8 removetype)
1805
1818
// Bot is being abandoned by player
1806
1819
void BotMgr::RemoveBot (ObjectGuid guid, uint8 removetype)
1807
1820
{
1821
+ if (_update_lock)
1822
+ {
1823
+ _delayedRemoveList.emplace_back (guid, BotRemoveType (removetype));
1824
+ return ;
1825
+ }
1826
+ else if (!_delayedRemoveList.empty ())
1827
+ _delayedRemoveList.remove_if ([=](decltype (_delayedRemoveList)::value_type const & p) { return p.first == guid; });
1828
+
1808
1829
BotMap::const_iterator itr = _bots.find (guid);
1809
1830
ASSERT (itr != _bots.end (), " Trying to remove bot which does not belong to this botmgr(a)!!" );
1810
1831
// ASSERT(_owner->IsInWorld(), "Trying to remove bot while not in world(a)!!");
@@ -1843,16 +1864,16 @@ void BotMgr::RemoveBot(ObjectGuid guid, uint8 removetype)
1843
1864
BotAIResetType resetType;
1844
1865
switch (removetype)
1845
1866
{
1846
- case BOT_REMOVE_DISMISS: resetType = BOTAI_RESET_DISMISS; break ;
1847
- case BOT_REMOVE_UNBIND: resetType = BOTAI_RESET_UNBIND; break ;
1848
- default : resetType = BOTAI_RESET_LOGOUT; break ;
1867
+ case BOT_REMOVE_DISMISS: case BOT_REMOVE_UNAFFORD: resetType = BOTAI_RESET_DISMISS; break ;
1868
+ case BOT_REMOVE_UNBIND: resetType = BOTAI_RESET_UNBIND; break ;
1869
+ default : resetType = BOTAI_RESET_LOGOUT; break ;
1849
1870
}
1850
1871
bot->GetBotAI ()->ResetBotAI (resetType);
1851
1872
1852
1873
bot->SetFaction (bot->GetCreatureTemplate ()->faction );
1853
1874
bot->SetLevel (bot->GetCreatureTemplate ()->minlevel );
1854
1875
1855
- if (removetype == BOT_REMOVE_DISMISS )
1876
+ if (resetType == BOTAI_RESET_DISMISS )
1856
1877
{
1857
1878
BotDataMgr::ResetNpcBotTransmogData (bot->GetEntry (), false );
1858
1879
uint32 newOwner = 0 ;
@@ -1925,7 +1946,7 @@ BotAddResult BotMgr::AddBot(Creature* bot)
1925
1946
// }
1926
1947
if (!owned)
1927
1948
{
1928
- uint32 cost = GetNpcBotCost (_owner->GetLevel (), bot->GetBotClass ());
1949
+ uint32 cost = GetNpcBotCostHire (_owner->GetLevel (), bot->GetBotClass ());
1929
1950
if (!_owner->HasEnoughMoney (cost))
1930
1951
{
1931
1952
ChatHandler ch (_owner->GetSession ());
@@ -2067,7 +2088,12 @@ bool BotMgr::RemoveAllBotsFromGroup()
2067
2088
return true ;
2068
2089
}
2069
2090
2070
- uint32 BotMgr::GetNpcBotCost (uint8 level, uint8 botclass)
2091
+ uint32 BotMgr::GetNpcBotCostRent ()
2092
+ {
2093
+ return _npcBotsCostRent;
2094
+ }
2095
+
2096
+ uint32 BotMgr::GetNpcBotCostHire (uint8 level, uint8 botclass)
2071
2097
{
2072
2098
// assuming default 1000000
2073
2099
// level 1: 500 //5 silver
@@ -2078,11 +2104,11 @@ uint32 BotMgr::GetNpcBotCost(uint8 level, uint8 botclass)
2078
2104
// rest is linear
2079
2105
// rare / rareelite bots have their cost adjusted
2080
2106
uint32 cost =
2081
- level < 10 ? _npcBotsCost / 2000 : // 5 silver
2082
- level < 20 ? _npcBotsCost / 100 : // 1 gold
2083
- level < 30 ? _npcBotsCost / 20 : // 5 gold
2084
- level < 40 ? _npcBotsCost / 5 : // 20 gold
2085
- (_npcBotsCost * (level - (level % 10 ))) / DEFAULT_MAX_LEVEL; // 50 - 100 gold
2107
+ level < 10 ? _npcBotsCostHire / 2000 : // 5 silver
2108
+ level < 20 ? _npcBotsCostHire / 100 : // 1 gold
2109
+ level < 30 ? _npcBotsCostHire / 20 : // 5 gold
2110
+ level < 40 ? _npcBotsCostHire / 5 : // 20 gold
2111
+ (_npcBotsCostHire * (level - (level % 10 ))) / DEFAULT_MAX_LEVEL; // 50 - 100 gold
2086
2112
2087
2113
switch (botclass)
2088
2114
{
@@ -2110,7 +2136,7 @@ std::string BotMgr::GetNpcBotCostStr(uint8 level, uint8 botclass)
2110
2136
{
2111
2137
std::ostringstream money;
2112
2138
2113
- if (uint32 cost = GetNpcBotCost (level, botclass))
2139
+ if (uint32 cost = GetNpcBotCostHire (level, botclass))
2114
2140
{
2115
2141
uint32 gold = uint32 (cost / GOLD);
2116
2142
cost -= (gold * GOLD);
@@ -2125,6 +2151,23 @@ std::string BotMgr::GetNpcBotCostStr(uint8 level, uint8 botclass)
2125
2151
money << cost << " |TInterface\\ Icons\\ INV_Misc_Coin_05:8|t" ;
2126
2152
}
2127
2153
2154
+ if (uint32 rcost = GetNpcBotCostRent ())
2155
+ {
2156
+ uint32 gold = uint32 (rcost / GOLD);
2157
+ rcost -= (gold * GOLD);
2158
+ uint32 silver = uint32 (rcost / SILVER);
2159
+ rcost -= (silver * SILVER);
2160
+
2161
+ money << " + |TInterface\\ Icons\\ INV_Misc_PocketWatch_01:16|t" ;
2162
+
2163
+ if (gold != 0 )
2164
+ money << gold << " |TInterface\\ Icons\\ INV_Misc_Coin_01:8|t" ;
2165
+ if (silver != 0 )
2166
+ money << silver << " |TInterface\\ Icons\\ INV_Misc_Coin_03:8|t" ;
2167
+ if (rcost)
2168
+ money << rcost << " |TInterface\\ Icons\\ INV_Misc_Coin_05:8|t" ;
2169
+ }
2170
+
2128
2171
return money.str ();
2129
2172
}
2130
2173
0 commit comments