diff --git a/src/server/game/AI/NpcBots/botdatamgr.cpp b/src/server/game/AI/NpcBots/botdatamgr.cpp index d61b2ef8de3a1..6a54baf6b8cdc 100644 --- a/src/server/game/AI/NpcBots/botdatamgr.cpp +++ b/src/server/game/AI/NpcBots/botdatamgr.cpp @@ -316,6 +316,8 @@ struct WanderingBotsGenerator //force level range for bgs bot_template.minlevel = std::min(bracketEntry->MinLevel, max_level); bot_template.maxlevel = std::min(bracketEntry->MaxLevel, max_level); + if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL)) + bot_template.flags_extra &= ~(CREATURE_FLAG_EXTRA_NO_XP); } else { diff --git a/src/server/game/AI/NpcBots/botmgr.cpp b/src/server/game/AI/NpcBots/botmgr.cpp index 5b0e4d7465d94..fd46451cc627a 100644 --- a/src/server/game/AI/NpcBots/botmgr.cpp +++ b/src/server/game/AI/NpcBots/botmgr.cpp @@ -871,7 +871,7 @@ bool BotMgr::CanBotParryWhileCasting(Creature const* bot) bool BotMgr::IsWanderingWorldBot(Creature const* bot) { - return (bot->IsWandererBot() && !(bot->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP)); + return bot->IsWandererBot() && (!bot->FindMap() || !bot->GetMap()->GetEntry() || bot->GetMap()->GetEntry()->IsWorldMap()); } void BotMgr::Update(uint32 diff) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index f51b4fcdfda2b..70898f329319b 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -2071,6 +2071,7 @@ void Battleground::HandleBotKillPlayer(Creature* killer, Player* victim) { // To be able to remove insignia -- ONLY IN Battlegrounds victim->SetUnitFlag(UNIT_FLAG_SKINNABLE); + RewardXPAtKill(killer, victim); } } void Battleground::HandleBotKillBot(Creature* killer, Creature* victim) @@ -2100,6 +2101,8 @@ void Battleground::HandleBotKillBot(Creature* killer, Creature* victim) UpdateBotScore(teamedBot, SCORE_HONORABLE_KILLS, 1); } } + if (!isArena() && !victim->GetLootRecipient()) // Prevent double reward (AI->KilledUnit (killing blow) and Unit::Kill (recipient)) + RewardXPAtKill(killer, victim); } void Battleground::HandlePlayerKillBot(Creature* victim, Player* killer) { @@ -2131,6 +2134,8 @@ void Battleground::HandlePlayerKillBot(Creature* victim, Player* killer) UpdateBotScore(teamedBot, SCORE_HONORABLE_KILLS, 1); } } + if (!isArena()) + RewardXPAtKill(killer, victim); } TeamId Battleground::GetOtherTeamId(TeamId teamId) const @@ -2294,6 +2299,74 @@ void Battleground::RewardXPAtKill(Player* killer, Player* victim) killer->RewardPlayerAndGroupAtKill(victim, true); } +//npcbot +void Battleground::RewardXPAtKill(Player* killer, Creature* victim) +{ + if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) && killer && victim) + killer->RewardPlayerAndGroupAtKill(victim, true); +} + +void Battleground::RewardXPAtKill(Creature* killer, Player* victim) +{ + if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) && killer && victim) + { + Player* pkiller = killer->IsFreeBot() ? nullptr : killer->GetBotOwner(); + if (!pkiller) + { + uint32 team = (BotDataMgr::GetTeamIdForFaction(killer->GetFaction()) == TEAM_ALLIANCE) ? ALLIANCE : HORDE; + if (Group const* group = GetBgRaid(team)) + { + float mindist = SIZE_OF_GRIDS; + for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + { + if (Player* gPlayer = itr->GetSource()) + { + float dist = gPlayer->GetExactDist2d(victim); + if (dist < mindist) + { + mindist = dist; + pkiller = gPlayer; + } + } + } + } + } + if (pkiller && pkiller->IsAtGroupRewardDistance(victim)) + pkiller->RewardPlayerAndGroupAtKill(victim, true); + } +} + +void Battleground::RewardXPAtKill(Creature* killer, Creature* victim) +{ + if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) && killer && victim) + { + Player* pkiller = killer->IsFreeBot() ? nullptr : killer->GetBotOwner(); + if (!pkiller) + { + uint32 team = (BotDataMgr::GetTeamIdForFaction(killer->GetFaction()) == TEAM_ALLIANCE) ? ALLIANCE : HORDE; + if (Group const* group = GetBgRaid(team)) + { + float mindist = SIZE_OF_GRIDS; + for (GroupReference const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + { + if (Player* gPlayer = itr->GetSource()) + { + float dist = gPlayer->GetExactDist2d(victim); + if (dist < mindist) + { + mindist = dist; + pkiller = gPlayer; + } + } + } + } + } + if (pkiller && pkiller->IsAtGroupRewardDistance(victim)) + pkiller->RewardPlayerAndGroupAtKill(victim, true); + } +} +//end npcbot + uint32 Battleground::GetTeamScore(uint32 teamId) const { if (teamId == TEAM_ALLIANCE || teamId == TEAM_HORDE) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 55669265061bc..4ac7194cff563 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -446,6 +446,9 @@ class TC_GAME_API Battleground TeamId GetBotTeamId(ObjectGuid guid) const; TeamId GetOtherTeamId(TeamId teamId) const; void AddOrSetBotToCorrectBgGroup(Creature* bot, uint32 team); + void RewardXPAtKill(Player* killer, Creature* victim); + void RewardXPAtKill(Creature* killer, Player* victim); + void RewardXPAtKill(Creature* killer, Creature* victim); virtual void AddBot(Creature* bot); virtual void RemoveBotAtLeave(ObjectGuid guid); virtual WorldSafeLocsEntry const* GetClosestGraveyardForBot(WorldLocation const& curPos, uint32 team) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0c08096b99ea7..ae8f9542de037 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2557,6 +2557,9 @@ void Player::GiveXP(uint32 xp, Unit* victim, float group_rate) return; if (victim && victim->GetTypeId() == TYPEID_UNIT && !victim->ToCreature()->hasLootRecipient()) + //npcbot + if (!(victim->IsNPCBot() && victim->FindMap() && victim->GetMap()->IsBattleground())) + //end npcbot return; uint8 level = GetLevel();