Skip to content

Commit

Permalink
NPCBots: Fix being unable to attack wandering bots in FFAPvP server m…
Browse files Browse the repository at this point in the history
…ode. Set wandering bots' faction to Neutral Hostile instead of Hostile To All to prevent guards' reaction towards neutral team wandering bots
  • Loading branch information
trickerer committed Dec 5, 2024
1 parent 0c5da7c commit 0dfd6dd
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/server/game/AI/NpcBots/bot_GridNotifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class NearestHostileUnitCheck
NearestHostileUnitCheck(NearestHostileUnitCheck const&) = delete;
explicit NearestHostileUnitCheck(Unit const* unit, float dist, bool magic, bot_ai const* m_ai, bool targetCCed, bool withSecondary) :
me(unit), m_range(dist), byspell(magic), ai(m_ai), AttackCCed(targetCCed), checkSecondary(withSecondary)
{ free = ai->IAmFree(); berserk = free && (ai->IsWanderer() || unit->GetFaction() == 14); }
{ free = ai->IAmFree(); berserk = free && (ai->IsWanderer() || unit->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE); }
explicit NearestHostileUnitCheck(Unit const* unit, float dist, bool magic, bot_ai const* m_ai) :
NearestHostileUnitCheck(unit, dist, magic, m_ai, true, false)
{}
Expand Down
37 changes: 26 additions & 11 deletions src/server/game/AI/NpcBots/bot_ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ void bot_ai::BuffAndHealGroup(uint32 diff)
if (HealTarget(me, diff))
return;

if (me->GetFaction() == 14 || me->HasAura(BERSERK))
if (me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE || me->HasAura(BERSERK))
return;

std::list<Unit*> targets2;
Expand Down Expand Up @@ -1659,7 +1659,7 @@ void bot_ai::ResurrectGroup(uint32 spell_id)

if (IAmFree())
{
if (me->GetFaction() == 14 || me->HasAura(BERSERK))
if (me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE || me->HasAura(BERSERK))
return;

WorldObject* playerOrCorpse = GetNearbyRezTarget();
Expand Down Expand Up @@ -1825,7 +1825,7 @@ void bot_ai::CureGroup(uint32 cureSpell, uint32 diff)
if (botPet && !me->IsInCombat() && _canCureTarget(botPet, cureSpell))
targets.push_back(botPet);

if (!(me->GetFaction() == 14 || me->HasAura(BERSERK)))
if (!(me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE || me->HasAura(BERSERK)))
{
std::list<Unit*> targets1;
GetNearbyFriendlyTargetsList(targets1, 30);
Expand Down Expand Up @@ -3630,7 +3630,7 @@ bool bot_ai::IsInBotParty(Unit const* unit) const

if (IAmFree())
{
if (me->GetFaction() == 14 || unit->GetFaction() == 14)
if (me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE || unit->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE)
return false;

if (me->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) ||
Expand Down Expand Up @@ -3801,7 +3801,7 @@ bool bot_ai::CanBotAttack(Unit const* target, int8 byspell, bool secondary) cons
return false;
if (me->GetFaction() == 35 && IAmFree() && target->GetTypeId() == TYPEID_UNIT && target->GetVictim() != me)
return false;
if ((target->GetFaction() == 35 || target->GetFaction() == me->GetFaction()) && me->GetFaction() != 14)
if ((target->GetFaction() == 35 || target->GetFaction() == me->GetFaction()) && me->GetFaction() != FACTION_TEMPLATE_NEUTRAL_HOSTILE)
return false;
if (!CanBotAttackOnVehicle())
return false;
Expand All @@ -3814,6 +3814,13 @@ bool bot_ai::CanBotAttack(Unit const* target, int8 byspell, bool secondary) cons
return false;
if (BotMgr::EnableWanderingUntargetNpcFlightmaster() && target->IsTaxi())
return false;
//do not attack friendly targets in FFAPvP mode
if (me->IsFFAPvP() && me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE)
{
uint32 base_faction = BotDataMgr::GetDefaultFactionForBotRace(me->GetRace());
if (me->GetFaction() != base_faction && Unit::GetFactionReactionTo(sFactionTemplateStore.LookupEntry(base_faction), target) >= REP_FRIENDLY)
return false;
}
}

if (IAmFree())
Expand Down Expand Up @@ -3863,7 +3870,7 @@ bool bot_ai::CanBotAttack(Unit const* target, int8 byspell, bool secondary) cons
}
}

if (master->IsInCombat() || target->IsInCombat() || IsWanderer() || (IAmFree() && me->GetFaction() == 14) || pulling)
if (master->IsInCombat() || target->IsInCombat() || IsWanderer() || (IAmFree() && me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE) || pulling)
{
//if master is killed pursue to the end)
if (!master->IsAlive() || target->IsControlledByPlayer() || pulling || (followdist > 0 && (master->GetDistance(target) <= foldist || HasBotCommandState(BOT_COMMAND_STAY))))
Expand Down Expand Up @@ -10758,9 +10765,9 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
}
else if (reason == -1)
{
me->SetFaction(14);
me->SetFaction(FACTION_TEMPLATE_NEUTRAL_HOSTILE);
if (botPet)
botPet->SetFaction(14);
botPet->SetFaction(FACTION_TEMPLATE_NEUTRAL_HOSTILE);
BotYell(LocalizedNpcText(player, BOT_TEXT_DIE), player);
me->Attack(player, true);
break;
Expand Down Expand Up @@ -10847,9 +10854,9 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
}
//if (urand(1,100) <= 25)
//{
// me->SetFaction(14);
// me->SetFaction(FACTION_TEMPLATE_HATES_EVERYTHING_1);
// if (Creature* pet = GetBotsPet())
// pet->SetFaction(14);
// pet->SetFaction(FACTION_TEMPLATE_HATES_EVERYTHING_1);
// BotSay("Fool...", player);
// me->Attack(player, true);
//}
Expand Down Expand Up @@ -15003,7 +15010,7 @@ void bot_ai::InitFaction()
{
uint32 faction = _botData->faction;

//if (faction == 14)
//if (faction == FACTION_TEMPLATE_HATES_EVERYTHING_1)
// faction = 35;

me->SetFaction(faction);
Expand Down Expand Up @@ -16370,6 +16377,9 @@ void bot_ai::OnDeath([[maybe_unused]] Unit* attacker/* = nullptr*/)

void bot_ai::KilledUnit(Unit* u)
{
if (u->GetOwnerGUID() == me->GetGUID() || u->GetGUID() == me->GetGUID())
return;

++_killsCount;
if (u->IsControlledByPlayer() || u->IsPvP() || u->IsNPCBotOrPet())
{
Expand Down Expand Up @@ -19323,6 +19333,11 @@ WanderNode const* bot_ai::GetNextWanderNode(Position const* fromPos, uint8 lvl,
};

uint32 faction = me->GetFaction();
if (me->IsFFAPvP())
{
ChrRacesEntry const* rentry = sChrRacesStore.LookupEntry(me->GetRace());
faction = (_botclass >= BOT_CLASS_EX_START) ? FACTION_TEMPLATE_NEUTRAL_HOSTILE : rentry ? rentry->FactionID : FACTION_TEMPLATE_NEUTRAL_HOSTILE;
}

//Node got deleted (or forced)! Select close point and go from there
NodeList nlinks;
Expand Down
4 changes: 2 additions & 2 deletions src/server/game/AI/NpcBots/botcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3156,7 +3156,7 @@ class script_bot_commands : public CommandScript
else if ((*factionStr)[0] == 'h')
factionId = 1801; //Horde
else if ((*factionStr)[0] == 'm')
factionId = 14; //Monsters
factionId = FACTION_TEMPLATE_NEUTRAL_HOSTILE; //Monsters
else if ((*factionStr)[0] == 'f')
factionId = 35; //Friendly to all

Expand Down Expand Up @@ -3343,7 +3343,7 @@ class script_bot_commands : public CommandScript
if (teamid)
{
ChrRacesEntry const* rentry = sChrRacesStore.LookupEntry(race);
uint32 faction = rentry ? rentry->FactionID : 14;
uint32 faction = rentry ? rentry->FactionID : FACTION_TEMPLATE_NEUTRAL_HOSTILE;
TeamId team = BotDataMgr::GetTeamIdForFaction(faction);

if (*teamid != uint8(team))
Expand Down
2 changes: 1 addition & 1 deletion src/server/game/AI/NpcBots/botcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ enum BotCommonValues
//COMMON GAMEEVENTS
GAME_EVENT_WINTER_VEIL = 2,
//COMMON FACTIONS
FACTION_TEMPLATE_HATES_EVERYTHING_1 = 2150, //faction 966 - Monster spar buddy
FACTION_TEMPLATE_NEUTRAL_HOSTILE = FACTION_CREATURE, // 2150 //Hates players and other bots, not attacked by guards
//SOUNDS
SOUND_FREEZE_IMPACT_WINDWALK = 29,
SOUND_AXE_2H_IMPACT_FLESH_CRIT = 158,
Expand Down
46 changes: 26 additions & 20 deletions src/server/game/AI/NpcBots/botdatamgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,15 @@ struct WanderingBotsGenerator
using NodeVec = std::vector<WanderNode const*>;

const std::map<uint8, uint32> wbot_faction_for_ex_class = {
{BOT_CLASS_BM, 14u/*2u*/},
{BOT_CLASS_SPHYNX, 14u},
{BOT_CLASS_ARCHMAGE, 14u/*1u*/},
{BOT_CLASS_DREADLORD, 14u},
{BOT_CLASS_SPELLBREAKER, 14u/*1610u*/},
{BOT_CLASS_DARK_RANGER, 14u},
{BOT_CLASS_NECROMANCER, 14u},
{BOT_CLASS_SEA_WITCH, 14u},
{BOT_CLASS_CRYPT_LORD, 14u}
{BOT_CLASS_BM, FACTION_TEMPLATE_NEUTRAL_HOSTILE/*2u*/},
{BOT_CLASS_SPHYNX, FACTION_TEMPLATE_NEUTRAL_HOSTILE},
{BOT_CLASS_ARCHMAGE, FACTION_TEMPLATE_NEUTRAL_HOSTILE/*1u*/},
{BOT_CLASS_DREADLORD, FACTION_TEMPLATE_NEUTRAL_HOSTILE},
{BOT_CLASS_SPELLBREAKER, FACTION_TEMPLATE_NEUTRAL_HOSTILE/*1610u*/},
{BOT_CLASS_DARK_RANGER, FACTION_TEMPLATE_NEUTRAL_HOSTILE},
{BOT_CLASS_NECROMANCER, FACTION_TEMPLATE_NEUTRAL_HOSTILE},
{BOT_CLASS_SEA_WITCH, FACTION_TEMPLATE_NEUTRAL_HOSTILE},
{BOT_CLASS_CRYPT_LORD, FACTION_TEMPLATE_NEUTRAL_HOSTILE}
};

uint32 next_bot_id;
Expand Down Expand Up @@ -286,12 +286,6 @@ struct WanderingBotsGenerator
_spareBotIdsPerClassMap.erase(c);
}

uint32 GetDefaultFactionForRaceClass(uint8 bot_class, uint8 bot_race) const
{
ChrRacesEntry const* rentry = sChrRacesStore.LookupEntry(bot_race);
return (bot_class >= BOT_CLASS_EX_START) ? wbot_faction_for_ex_class.find(bot_class)->second : rentry ? rentry->FactionID : 14u;
}

bool GenerateWanderingBotToSpawn(std::pair<uint8, uint32> const& spareBotPair, uint8 desired_bracket,
NodeVec const& spawns_a, NodeVec const& spawns_h, NodeVec const& spawns_n,
bool immediate, PvPDifficultyEntry const* bracketEntry, NpcBotRegistry* registry)
Expand All @@ -304,7 +298,7 @@ struct WanderingBotsGenerator
const uint32 orig_entry = spareBotPair.second;
CreatureTemplate const* orig_template = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(orig_entry));
NpcBotExtras const* orig_extras = ASSERT_NOTNULL(BotDataMgr::SelectNpcBotExtras(orig_entry));
uint32 bot_faction = GetDefaultFactionForRaceClass(bot_class, orig_extras->race);
uint32 bot_faction = BotDataMgr::GetDefaultFactionForBotRace(orig_extras->race);

NodeVec const* bot_spawn_nodes;
TeamId bot_team = BotDataMgr::GetTeamIdForFaction(bot_faction);
Expand Down Expand Up @@ -361,6 +355,12 @@ struct WanderingBotsGenerator
bot_template.minlevel = std::min<uint32>(std::max<uint32>(desired_bracket * 10, spawnLoc->GetLevels().first), max_level);
bot_template.maxlevel = std::min<uint32>(std::min<uint32>(desired_bracket * 10 + 9, spawnLoc->GetLevels().second), max_level);
bot_template.flags_extra &= ~(CREATURE_FLAG_EXTRA_NO_XP);

if (sWorld->IsFFAPvPRealm())
{
bot_template.faction = FACTION_TEMPLATE_NEUTRAL_HOSTILE;
bot_faction = FACTION_TEMPLATE_NEUTRAL_HOSTILE;
}
}

bot_template.InitializeQueryData();
Expand Down Expand Up @@ -422,14 +422,14 @@ struct WanderingBotsGenerator
if (kv.first >= BOT_CLASS_EX_START)
{
auto cit = wbot_faction_for_ex_class.find(kv.first);
if (cit != wbot_faction_for_ex_class.cend() && cit->second == FACTION_MONSTER)
if (cit != wbot_faction_for_ex_class.cend() && cit->second == FACTION_TEMPLATE_NEUTRAL_HOSTILE)
continue;
}

for (uint32 entry : kv.second)
{
NpcBotExtras const* extras = ASSERT_NOTNULL(BotDataMgr::SelectNpcBotExtras(entry));
uint32 bot_faction = GetDefaultFactionForRaceClass(kv.first, extras->race);
uint32 bot_faction = BotDataMgr::GetDefaultFactionForBotRace(extras->race);
TeamId bot_team = BotDataMgr::GetTeamIdForFaction(bot_faction);
if (teamId == bot_team)
++count;
Expand Down Expand Up @@ -542,7 +542,7 @@ struct WanderingBotsGenerator
for (uint32 spareBotId : kv.second)
{
NpcBotExtras const* orig_extras = ASSERT_NOTNULL(BotDataMgr::SelectNpcBotExtras(spareBotId));
uint32 bot_faction = GetDefaultFactionForRaceClass(kv.first, orig_extras->race);
uint32 bot_faction = BotDataMgr::GetDefaultFactionForBotRace(orig_extras->race);
uint32 botTeam = BotDataMgr::GetTeamForFaction(bot_faction);

if (int32(botTeam) != team)
Expand Down Expand Up @@ -3191,7 +3191,7 @@ int32 BotDataMgr::GetBotBaseReputation(Creature const* bot, FactionEntry const*
if (bot->IsNPCBotPet())
bot = bot->GetBotPetAI()->GetPetsOwner();

uint32 raceMask = bot->GetFaction() == 14 ? 0 : bot->GetRaceMask();
uint32 raceMask = GetDefaultFactionForBotRace(bot->GetRace()) == FACTION_TEMPLATE_NEUTRAL_HOSTILE ? 0 : bot->GetRaceMask();
uint32 classMask = bot->GetClassMask();

int32 minRep = 42999;
Expand All @@ -3209,6 +3209,12 @@ int32 BotDataMgr::GetBotBaseReputation(Creature const* bot, FactionEntry const*
return std::min<int32>(minRep, 0);
}

uint32 BotDataMgr::GetDefaultFactionForBotRace(uint8 bot_race)
{
ChrRacesEntry const* rentry = sChrRacesStore.LookupEntry(bot_race);
return rentry ? rentry->FactionID : FACTION_TEMPLATE_NEUTRAL_HOSTILE;
}

TeamId BotDataMgr::GetTeamIdForFaction(uint32 factionTemplateId)
{
if (FactionTemplateEntry const* fte = sFactionTemplateStore.LookupEntry(factionTemplateId))
Expand Down
1 change: 1 addition & 0 deletions src/server/game/AI/NpcBots/botdatamgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ class BotDataMgr
static uint8 GetMaxLevelForMapId(uint32 mapId);
static uint8 GetMinLevelForBotClass(uint8 m_class);
static int32 GetBotBaseReputation(Creature const* bot, FactionEntry const* factionEntry);
static uint32 GetDefaultFactionForBotRace(uint8 bot_race);
static TeamId GetTeamIdForFaction(uint32 factionTemplateId);
static uint32 GetTeamForFaction(uint32 factionTemplateId);

Expand Down
2 changes: 1 addition & 1 deletion src/server/game/AI/NpcBots/bpet_ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ bool bot_pet_ai::IsInBotParty(Unit const* unit) const

if (IAmFree())
{
if (me->GetFaction() == 14 || unit->GetFaction() == 14)
if (me->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE || unit->GetFaction() == FACTION_TEMPLATE_NEUTRAL_HOSTILE)
return false;

if (me->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) ||
Expand Down
4 changes: 4 additions & 0 deletions src/server/game/Entities/Unit/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12580,6 +12580,8 @@ bool Unit::IsInPartyWith(Unit const* unit) const
return (pla->GetGroup() && pla->GetGroup() == bot->GetBotGroup()) ? pla->GetSubGroup() == bot->GetSubGroup() : !!pla->GetBotMgr()->GetBot(bot->GetGUID());
if (u1->IsNPCBot() && u2->IsNPCBot() && u1->ToCreature()->GetBotGroup() && u1->ToCreature()->GetBotGroup() == u2->ToCreature()->GetBotGroup())
return u1->ToCreature()->GetSubGroup() == u2->ToCreature()->GetSubGroup();
if (u1->IsNPCBot() && u2->IsNPCBot() && u1->IsFFAPvP() && u2->IsFFAPvP())
return false;
//end npcbot

return u1->GetTypeId() == TYPEID_UNIT && u2->GetTypeId() == TYPEID_UNIT && u1->GetFaction() == u2->GetFaction();
Expand Down Expand Up @@ -12607,6 +12609,8 @@ bool Unit::IsInRaidWith(Unit const* unit) const
return (pla->GetGroup() && pla->GetGroup() == bot->GetBotGroup()) ? true : !!pla->GetBotMgr()->GetBot(bot->GetGUID());
if (u1->IsNPCBot() && u2->IsNPCBot() && u1->ToCreature()->GetBotGroup())
return u1->ToCreature()->GetBotGroup() == u2->ToCreature()->GetBotGroup();
if (u1->IsNPCBot() && u2->IsNPCBot() && u1->IsFFAPvP() && u2->IsFFAPvP())
return false;
//end npcbot

return u1->GetTypeId() == TYPEID_UNIT && u2->GetTypeId() == TYPEID_UNIT && u1->GetFaction() == u2->GetFaction();
Expand Down

0 comments on commit 0dfd6dd

Please sign in to comment.