From 649e8a1d4a1156404444469f9342aff422024d1d Mon Sep 17 00:00:00 2001 From: Fuzz Date: Wed, 24 Jul 2024 16:32:36 +1000 Subject: [PATCH 1/3] [Battlegrounds] fixed main EOTS issues (teleport bots off starting platform, fixed incorrect BG objective for the bases), still some minor pathing issues present --- src/strategy/actions/BattleGroundTactics.cpp | 73 +++++++++++--------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/src/strategy/actions/BattleGroundTactics.cpp b/src/strategy/actions/BattleGroundTactics.cpp index e2ec787c..74e792fc 100644 --- a/src/strategy/actions/BattleGroundTactics.cpp +++ b/src/strategy/actions/BattleGroundTactics.cpp @@ -1634,9 +1634,9 @@ BattleBotPath vPath_AV_Frostdagger_Pass_Lower_to_Iceblood_Garrison = BattleBotPath vPath_AV_Icewing_Bunker_Crossroad_to_Frostdagger_Pass_Lower = { //these are to cause bot to pick this when resurrecting at stonehearth (not really needed anymore as they get captain down in first wave since uneeded dismounting was fixed) - //{ 68.793f, -396.742f, 45.299f, nullptr }, - //{ 99.042f, -389.310f, 45.101f, nullptr }, - //{ 123.787f, -373.551f, 42.893f, nullptr }, + { 68.793f, -396.742f, 45.299f, nullptr }, + { 99.042f, -389.310f, 45.101f, nullptr }, + { 123.787f, -373.551f, 42.893f, nullptr }, { 119.693f, -351.311f, 42.728f, nullptr }, { 107.710f, -321.162f, 37.168f, nullptr }, { 84.953f, -273.434f, 23.944f, nullptr }, @@ -2397,12 +2397,12 @@ static uint32 AB_AttackObjectives[] = { BG_AB_NODE_GOLD_MINE } }; -static uint32 EY_AttackObjectives[] = +static std::pair EY_AttackObjectives[] = { - { POINT_FEL_REAVER }, - { POINT_BLOOD_ELF }, - { POINT_DRAENEI_RUINS }, - { POINT_MAGE_TOWER } + { POINT_FEL_REAVER, BG_EY_OBJECT_FLAG_FEL_REAVER}, + { POINT_BLOOD_ELF, BG_EY_OBJECT_FLAG_BLOOD_ELF }, + { POINT_DRAENEI_RUINS, BG_EY_OBJECT_FLAG_DRAENEI_RUINS }, + { POINT_MAGE_TOWER, BG_EY_OBJECT_FLAG_MAGE_TOWER } }; // useful commands for fixing BG bugs and checking waypoints/paths @@ -2935,6 +2935,7 @@ bool BGTactics::Execute(Event event) switch (bot->GetMotionMaster()->GetCurrentMovementGeneratorType()) { + //TODO: should ESCORT_MOTION_TYPE be here seeing as bots use it by default? case IDLE_MOTION_TYPE: case CHASE_MOTION_TYPE: case POINT_MOTION_TYPE: @@ -3712,8 +3713,8 @@ bool BGTactics::selectObjective(bool reset) uint8 rootTeamIndex = TEAM_NEUTRAL; uint32 role = context->GetValue("bg role")->Get(); - uint32 attackObjectivesFront[2]; - uint32 attackObjectivesBack[2]; + std::pair attackObjectivesFront[2]; + std::pair attackObjectivesBack[2]; uint32 areaTrigger; Position flagDeliverPoint; TeamId rootTeam = bot->GetTeamId(); @@ -3741,29 +3742,29 @@ bool BGTactics::selectObjective(bool reset) { if (role == 1) //Harass left back { - BgObjective = bg->GetBGObject(attackObjectivesBack[0]); + BgObjective = bg->GetBGObject(attackObjectivesBack[0].second); } else if (role == 2) //Harass right back { - BgObjective = bg->GetBGObject(attackObjectivesBack[1]); + BgObjective = bg->GetBGObject(attackObjectivesBack[1].second); } else if (role < 8) //Attack and Defend { while (BgObjective == nullptr) { - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0])._ownerTeamId != rootTeamIndex || - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1])._ownerTeamId != rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0].first)._ownerTeamId != rootTeamIndex || + eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1].first)._ownerTeamId != rootTeamIndex) { // Capture front objectives before attacking back objectives // LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Get Front Objectives", // bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); if (role < 6) { - BgObjective = bg->GetBGObject(attackObjectivesFront[0]); + BgObjective = bg->GetBGObject(attackObjectivesFront[0].second); } else if (role < 8) { - BgObjective = bg->GetBGObject(attackObjectivesFront[1]); + BgObjective = bg->GetBGObject(attackObjectivesFront[1].second); } } else @@ -3773,29 +3774,29 @@ bool BGTactics::selectObjective(bool reset) // bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); if (role < 4) { - BgObjective = bg->GetBGObject(attackObjectivesFront[0]); + BgObjective = bg->GetBGObject(attackObjectivesFront[0].second); } else if (role < 5) { - BgObjective = bg->GetBGObject(attackObjectivesFront[1]); + BgObjective = bg->GetBGObject(attackObjectivesFront[1].second); } else if (role < 8) { - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0])._ownerTeamId != rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0].first)._ownerTeamId != rootTeamIndex) { - BgObjective = bg->GetBGObject(attackObjectivesBack[0]); + BgObjective = bg->GetBGObject(attackObjectivesBack[0].second); } - else if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1])._ownerTeamId != rootTeamIndex) + else if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1].first)._ownerTeamId != rootTeamIndex) { - BgObjective = bg->GetBGObject(attackObjectivesBack[1]); + BgObjective = bg->GetBGObject(attackObjectivesBack[1].second); } } } - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0])._ownerTeamId == rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1])._ownerTeamId == rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0])._ownerTeamId == rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1])._ownerTeamId == rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0].first)._ownerTeamId == rootTeamIndex && + eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1].first)._ownerTeamId == rootTeamIndex && + eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0].first)._ownerTeamId == rootTeamIndex && + eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1].first)._ownerTeamId == rootTeamIndex) { role = urand(0, 9); } @@ -3838,8 +3839,8 @@ bool BGTactics::selectObjective(bool reset) { BgObjective = nullptr; - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0])._ownerTeamId != rootTeamIndex && eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1])._ownerTeamId != rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0])._ownerTeamId !=rootTeamIndex && eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1])._ownerTeamId !=rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0].first)._ownerTeamId != rootTeamIndex && eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1].first)._ownerTeamId != rootTeamIndex && + eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0].first)._ownerTeamId != rootTeamIndex && eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1].first)._ownerTeamId != rootTeamIndex) { //Retreat with flag //LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Retreat with flag", @@ -3860,22 +3861,22 @@ bool BGTactics::selectObjective(bool reset) //Deliver flag //LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Deliver flag", //bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); - if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[0])._ownerTeamId == rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[0].first)._ownerTeamId == rootTeamIndex) { areaTrigger = AT_FEL_REAVER_POINT; flagDeliverPoint = EY_FLAG_RETURN_POS_REAVER_RUINS; } - else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[1])._ownerTeamId == rootTeamIndex) + else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[1].first)._ownerTeamId == rootTeamIndex) { areaTrigger = AT_BLOOD_ELF_POINT; flagDeliverPoint = EY_FLAG_RETURN_POS_BLOOD_ELF_TOWER; } - else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[2])._ownerTeamId == rootTeamIndex) + else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[2].first)._ownerTeamId == rootTeamIndex) { areaTrigger = AT_DRAENEI_RUINS_POINT; flagDeliverPoint = EY_FLAG_RETURN_POS_DRAENEI_RUINS; } - else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[3])._ownerTeamId == rootTeamIndex) + else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[3].first)._ownerTeamId == rootTeamIndex) { areaTrigger = AT_MAGE_TOWER_POINT; flagDeliverPoint = EY_FLAG_RETURN_POS_MAGE_TOWER; @@ -4351,6 +4352,14 @@ bool BGTactics::moveToObjective() return moveToStart(true); } } + else if (bgType == BATTLEGROUND_EY) + { + // just teleport them down for now + if (bot->GetDistance(1831.673f, 1541.025f, 1256.794f) < 16) + bot->TeleportTo(bg->GetMapId(), 1867.821f, 1541.739f, 1209.07f, bot->GetOrientation()); + if (bot->GetDistance(2496.949f, 1596.353f, 1257.225f) < 16) + bot->TeleportTo(bg->GetMapId(), 2471.215f, 1604.309f, 1213.61f, bot->GetOrientation()); + } PositionInfo pos = context->GetValue("position")->Get()["bg objective"]; if (!pos.isSet()) From 9a3f513cc87e9f6157532e7d899acc5b47adae0f Mon Sep 17 00:00:00 2001 From: Fuzz Date: Fri, 26 Jul 2024 15:17:16 +1000 Subject: [PATCH 2/3] [Battlegrounds] bots now jump down from starting platforms in EOTS, fixed assymetric flag cap strategy between teams --- src/strategy/actions/BattleGroundTactics.cpp | 290 ++++++++++--------- src/strategy/actions/BattleGroundTactics.h | 1 + src/strategy/actions/MovementActions.cpp | 10 + src/strategy/actions/MovementActions.h | 1 + 4 files changed, 169 insertions(+), 133 deletions(-) diff --git a/src/strategy/actions/BattleGroundTactics.cpp b/src/strategy/actions/BattleGroundTactics.cpp index 74e792fc..212dfae6 100644 --- a/src/strategy/actions/BattleGroundTactics.cpp +++ b/src/strategy/actions/BattleGroundTactics.cpp @@ -61,10 +61,6 @@ Position const AV_STONEHEARTH_ATTACKING_HORDE = { -55.210f, -288.546f, 15.578f, Position const EY_WAITING_POS_HORDE = { 1809.102f, 1540.854f, 1267.142f, 6.18f }; Position const EY_WAITING_POS_ALLIANCE = { 2526.020f, 1596.787f, 1270.127f, 3.14f }; -Position const EY_FLAG_RETURN_POS_REAVER_RUINS = { 2044.097f, 1730.323f, 1189.822f, 0.0f }; -Position const EY_FLAG_RETURN_POS_BLOOD_ELF_TOWER = { 2048.933f, 1394.058f, 1194.419f, 0.0f }; -Position const EY_FLAG_RETURN_POS_DRAENEI_RUINS = { 2286.754f, 1402.372f, 1197.120f, 0.0f }; -Position const EY_FLAG_RETURN_POS_MAGE_TOWER = { 2284.585f, 1731.297f, 1189.862f, 0.0f }; Position const EY_FLAG_RETURN_POS_RETREAT_HORDE = { 1885.529f, 1532.157f, 1200.635f, 0.0f }; Position const EY_FLAG_RETURN_POS_RETREAT_ALLIANCE = { 2452.253f, 1602.356f, 1203.617f, 0.0f }; @@ -2397,12 +2393,12 @@ static uint32 AB_AttackObjectives[] = { BG_AB_NODE_GOLD_MINE } }; -static std::pair EY_AttackObjectives[] = +static std::tuple EY_AttackObjectives[] = { - { POINT_FEL_REAVER, BG_EY_OBJECT_FLAG_FEL_REAVER}, - { POINT_BLOOD_ELF, BG_EY_OBJECT_FLAG_BLOOD_ELF }, - { POINT_DRAENEI_RUINS, BG_EY_OBJECT_FLAG_DRAENEI_RUINS }, - { POINT_MAGE_TOWER, BG_EY_OBJECT_FLAG_MAGE_TOWER } + { POINT_FEL_REAVER, BG_EY_OBJECT_FLAG_FEL_REAVER, AT_FEL_REAVER_POINT }, + { POINT_BLOOD_ELF, BG_EY_OBJECT_FLAG_BLOOD_ELF, AT_BLOOD_ELF_POINT }, + { POINT_DRAENEI_RUINS, BG_EY_OBJECT_FLAG_DRAENEI_RUINS, AT_DRAENEI_RUINS_POINT }, + { POINT_MAGE_TOWER, BG_EY_OBJECT_FLAG_MAGE_TOWER, AT_MAGE_TOWER_POINT } }; // useful commands for fixing BG bugs and checking waypoints/paths @@ -2833,6 +2829,53 @@ bool BGTactics::wsgPaths() return false; } +bool BGTactics::eyJumpDown() +{ + Battleground* bg = bot->GetBattleground(); + if (!bg) + return false; + Position const hordeJumpPositions[] = + { + EY_WAITING_POS_HORDE, + { 1838.007f, 1539.856f, 1253.383f }, + { 1846.264f, 1535.062f, 1240.796f }, + { 1849.813f, 1527.303f, 1237.262f }, + { 1849.041f, 1518.884f, 1223.624f }, + }; + Position const allianceJumpPositions[] = + { + EY_WAITING_POS_ALLIANCE, + { 2492.955f, 1597.769f, 1254.828f }, + { 2484.601f, 1598.209f, 1244.344f }, + { 2478.424f, 1609.539f, 1238.651f }, + { 2475.926f, 1619.658f, 1218.706f }, + }; + Position const *positons = bot->GetTeamId() == TEAM_HORDE ? hordeJumpPositions : allianceJumpPositions; + { + if (bot->GetDistance(positons[0]) < 16.0f) + { + MoveTo(bg->GetMapId(), positons[1].GetPositionX(), positons[1].GetPositionY(), positons[1].GetPositionZ()); + return true; + } + if (bot->GetDistance(positons[1]) < 4.0f) + { + JumpTo(bg->GetMapId(), positons[2].GetPositionX(), positons[2].GetPositionY(), positons[2].GetPositionZ()); + return true; + } + if (bot->GetDistance(positons[2]) < 4.0f) + { + MoveTo(bg->GetMapId(), positons[3].GetPositionX(), positons[3].GetPositionY(), positons[3].GetPositionZ()); + return true; + } + if (bot->GetDistance(positons[3]) < 4.0f) + { + JumpTo(bg->GetMapId(), positons[4].GetPositionX(), positons[4].GetPositionY(), positons[4].GetPositionZ()); + return true; + } + } + return false; +} + // // actual bg tactics below // @@ -3708,63 +3751,111 @@ bool BGTactics::selectObjective(bool reset) case BATTLEGROUND_EY: // Role < 4: Defender, else Attacker. In the beginning split for all points. Afterwards pick random strategies { BattlegroundEY* eyeOfTheStormBG = (BattlegroundEY*)bg; + TeamId botTeam = bot->GetTeamId(); - //Variables - uint8 rootTeamIndex = TEAM_NEUTRAL; - uint32 role = context->GetValue("bg role")->Get(); - - std::pair attackObjectivesFront[2]; - std::pair attackObjectivesBack[2]; - uint32 areaTrigger; - Position flagDeliverPoint; - TeamId rootTeam = bot->GetTeamId(); - - //Set attackobjectives for teams - if (rootTeam == TEAM_HORDE) + if (bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL)) //has flag { - attackObjectivesFront[0] = EY_AttackObjectives[0]; - attackObjectivesFront[1] = EY_AttackObjectives[1]; - attackObjectivesBack[0] = EY_AttackObjectives[2]; - attackObjectivesBack[1] = EY_AttackObjectives[3]; - rootTeamIndex = TEAM_HORDE; + //try to deliver flag + BgObjective = nullptr; + uint32 areaTrigger = 0; + float closestDist = FLT_MAX; + // previous method just went to first objective owned (going though list same order regardless of team) which made both teams more likely to go go to horde side of map (seemed to boost alliance) + for (const auto& objective : EY_AttackObjectives) + { + if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(objective))._ownerTeamId == botTeam) + { + if (GameObject* go = bg->GetBGObject(std::get<1>(objective))) + { + float dist = sqrt(bot->GetDistance(go)); + if (closestDist > dist && (closestDist - dist > 1 || urand(0, 1)))//if distance difference is minor (as it will be when they first pick flag up from middle) add some randomness so its not going to same point every time + { + closestDist = dist; + BgObjective = go; + areaTrigger = std::get<2>(objective); + } + } + } + } + + if (BgObjective) + { + //deliver flag to owned base + pos.Set(BgObjective->GetPositionX(), BgObjective->GetPositionY(), BgObjective->GetPositionZ(), bg->GetMapId()); + } + else if (botTeam == TEAM_HORDE) + { + //TODO - just make them go for base on their side its better than cowering in corner + areaTrigger = 0; + pos.Set(EY_FLAG_RETURN_POS_RETREAT_HORDE.GetPositionX(), EY_FLAG_RETURN_POS_RETREAT_HORDE.GetPositionY(), EY_FLAG_RETURN_POS_RETREAT_HORDE.GetPositionZ(), bg->GetMapId()); + } + else + { + //TODO - just make them go for base on their side its better than cowering in corner + areaTrigger = 0; + pos.Set(EY_FLAG_RETURN_POS_RETREAT_ALLIANCE.GetPositionX(), EY_FLAG_RETURN_POS_RETREAT_ALLIANCE.GetPositionY(), EY_FLAG_RETURN_POS_RETREAT_ALLIANCE.GetPositionZ(), bg->GetMapId()); + } + + if (areaTrigger && bot->IsWithinDist3d(pos.x, pos.y, pos.z, INTERACTION_DISTANCE)) + { + WorldPacket data(CMSG_AREATRIGGER); + data << uint32(areaTrigger); + bot->GetSession()->HandleAreaTriggerOpcode(data); + pos.Reset(); + posMap["bg objective"] = pos; + } + else if (!MoveTo(bot->GetMapId(), pos.x, pos.y, pos.z)) + posMap["bg objective"] = pos; + + return true; } - else if (rootTeam == TEAM_ALLIANCE) + else //not flag carrier { - attackObjectivesFront[0] = EY_AttackObjectives[2]; - attackObjectivesFront[1] = EY_AttackObjectives[3]; - attackObjectivesBack[0] = EY_AttackObjectives[0]; - attackObjectivesBack[1] = EY_AttackObjectives[1]; - rootTeamIndex = TEAM_ALLIANCE; - } + uint32 role = context->GetValue("bg role")->Get(); - //Get BgObjective if not set - if (!bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL)) - { + std::tuple attackObjectivesFront[2]; + std::tuple attackObjectivesBack[2]; + TeamId rootTeam = bot->GetTeamId(); + + //Set attackobjectives for teams + if (rootTeam == TEAM_HORDE) + { + attackObjectivesFront[0] = EY_AttackObjectives[0]; + attackObjectivesFront[1] = EY_AttackObjectives[1]; + attackObjectivesBack[0] = EY_AttackObjectives[2]; + attackObjectivesBack[1] = EY_AttackObjectives[3]; + } + else if (rootTeam == TEAM_ALLIANCE) + { + attackObjectivesFront[0] = EY_AttackObjectives[2]; + attackObjectivesFront[1] = EY_AttackObjectives[3]; + attackObjectivesBack[0] = EY_AttackObjectives[0]; + attackObjectivesBack[1] = EY_AttackObjectives[1]; + } if (role == 1) //Harass left back { - BgObjective = bg->GetBGObject(attackObjectivesBack[0].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesBack[0])); } else if (role == 2) //Harass right back { - BgObjective = bg->GetBGObject(attackObjectivesBack[1].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesBack[1])); } else if (role < 8) //Attack and Defend { while (BgObjective == nullptr) { - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0].first)._ownerTeamId != rootTeamIndex || - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1].first)._ownerTeamId != rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[0]))._ownerTeamId != botTeam || + eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[1]))._ownerTeamId != botTeam) { // Capture front objectives before attacking back objectives // LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Get Front Objectives", // bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); if (role < 6) { - BgObjective = bg->GetBGObject(attackObjectivesFront[0].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[0])); } else if (role < 8) { - BgObjective = bg->GetBGObject(attackObjectivesFront[1].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[1])); } } else @@ -3774,30 +3865,31 @@ bool BGTactics::selectObjective(bool reset) // bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); if (role < 4) { - BgObjective = bg->GetBGObject(attackObjectivesFront[0].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[0])); } else if (role < 5) { - BgObjective = bg->GetBGObject(attackObjectivesFront[1].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[1])); } else if (role < 8) { - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0].first)._ownerTeamId != rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesBack[0]))._ownerTeamId != botTeam) { - BgObjective = bg->GetBGObject(attackObjectivesBack[0].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesBack[0])); } - else if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1].first)._ownerTeamId != rootTeamIndex) + else if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesBack[1]))._ownerTeamId != botTeam) { - BgObjective = bg->GetBGObject(attackObjectivesBack[1].second); + BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesBack[1])); } } } - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0].first)._ownerTeamId == rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1].first)._ownerTeamId == rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0].first)._ownerTeamId == rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1].first)._ownerTeamId == rootTeamIndex) + if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[0]))._ownerTeamId == botTeam && + eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[1]))._ownerTeamId == botTeam && + eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesBack[0]))._ownerTeamId == botTeam && + eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesBack[1]))._ownerTeamId == botTeam) { + // TODO: what's the point of this? we dont store it back in bg role role = urand(0, 9); } } @@ -3835,70 +3927,6 @@ bool BGTactics::selectObjective(bool reset) } } - if (bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL)) - { - BgObjective = nullptr; - - if (eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[0].first)._ownerTeamId != rootTeamIndex && eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesFront[1].first)._ownerTeamId != rootTeamIndex && - eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[0].first)._ownerTeamId != rootTeamIndex && eyeOfTheStormBG->GetCapturePointInfo(attackObjectivesBack[1].first)._ownerTeamId != rootTeamIndex) - { - //Retreat with flag - //LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Retreat with flag", - //bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); - if (rootTeam == TEAM_HORDE) - { - areaTrigger = 0; - flagDeliverPoint = EY_FLAG_RETURN_POS_RETREAT_HORDE; - } - else - { - areaTrigger = 0; - flagDeliverPoint = EY_FLAG_RETURN_POS_RETREAT_ALLIANCE; - } - } - else - { - //Deliver flag - //LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Deliver flag", - //bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); - if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[0].first)._ownerTeamId == rootTeamIndex) - { - areaTrigger = AT_FEL_REAVER_POINT; - flagDeliverPoint = EY_FLAG_RETURN_POS_REAVER_RUINS; - } - else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[1].first)._ownerTeamId == rootTeamIndex) - { - areaTrigger = AT_BLOOD_ELF_POINT; - flagDeliverPoint = EY_FLAG_RETURN_POS_BLOOD_ELF_TOWER; - } - else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[2].first)._ownerTeamId == rootTeamIndex) - { - areaTrigger = AT_DRAENEI_RUINS_POINT; - flagDeliverPoint = EY_FLAG_RETURN_POS_DRAENEI_RUINS; - } - else if (eyeOfTheStormBG->GetCapturePointInfo(EY_AttackObjectives[3].first)._ownerTeamId == rootTeamIndex) - { - areaTrigger = AT_MAGE_TOWER_POINT; - flagDeliverPoint = EY_FLAG_RETURN_POS_MAGE_TOWER; - } - - if (bot->IsWithinDist3d(flagDeliverPoint.GetPositionX(), flagDeliverPoint.GetPositionY(), flagDeliverPoint.GetPositionZ(), INTERACTION_DISTANCE)) - { - WorldPacket data(CMSG_AREATRIGGER); - data << uint32(areaTrigger); - bot->GetSession()->HandleAreaTriggerOpcode(data); - } - } - - if (!MoveTo(bot->GetMapId(), flagDeliverPoint.GetPositionX(), flagDeliverPoint.GetPositionY(), flagDeliverPoint.GetPositionZ())) - { - pos.Set(flagDeliverPoint.GetPositionX(), flagDeliverPoint.GetPositionY(), flagDeliverPoint.GetPositionZ(), bot->GetMapId()); - posMap["bg objective"] = pos; - } - - return true; - } - if (BgObjective) { pos.Set(BgObjective->GetPositionX(), BgObjective->GetPositionY(), BgObjective->GetPositionZ(), BgObjective->GetMapId()); @@ -4344,23 +4372,6 @@ bool BGTactics::moveToObjective() if (bgType == BATTLEGROUND_RB) bgType = bg->GetBgTypeID(true); - // get bots out of cave when respawned there (otherwise path selection happens while they're deep within cave and the results arent good) - if (bgType == BATTLEGROUND_AV) - { - Position const caveSpawn = bot->GetTeamId() == TEAM_ALLIANCE ? AV_CAVE_SPAWN_ALLIANCE : AV_CAVE_SPAWN_HORDE; - if (sqrt(bot->GetDistance(caveSpawn)) < 4.0f) { - return moveToStart(true); - } - } - else if (bgType == BATTLEGROUND_EY) - { - // just teleport them down for now - if (bot->GetDistance(1831.673f, 1541.025f, 1256.794f) < 16) - bot->TeleportTo(bg->GetMapId(), 1867.821f, 1541.739f, 1209.07f, bot->GetOrientation()); - if (bot->GetDistance(2496.949f, 1596.353f, 1257.225f) < 16) - bot->TeleportTo(bg->GetMapId(), 2471.215f, 1604.309f, 1213.61f, bot->GetOrientation()); - } - PositionInfo pos = context->GetValue("position")->Get()["bg objective"]; if (!pos.isSet()) return selectObjective(); @@ -4419,6 +4430,19 @@ bool BGTactics::selectObjectiveWp(std::vector const& vPaths) // use Rym's waypoints for WSG if (bgType == BATTLEGROUND_WS /* && (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG))*/) return wsgPaths(); + else if (bgType == BATTLEGROUND_AV) + { + // get bots out of cave when they respawn there (otherwise path selection happens while they're deep within cave and the results arent good) + Position const caveSpawn = bot->GetTeamId() == TEAM_ALLIANCE ? AV_CAVE_SPAWN_ALLIANCE : AV_CAVE_SPAWN_HORDE; + if (sqrt(bot->GetDistance(caveSpawn)) < 4.0f) { + return moveToStart(true); + } + } + else if (bgType == BATTLEGROUND_EY) + { + if (eyJumpDown()) + return true; + } float chosenPathScore = FLT_MAX;//lower score is better BattleBotPath* chosenPath = nullptr; diff --git a/src/strategy/actions/BattleGroundTactics.h b/src/strategy/actions/BattleGroundTactics.h index db280fff..66f0c8a8 100644 --- a/src/strategy/actions/BattleGroundTactics.h +++ b/src/strategy/actions/BattleGroundTactics.h @@ -54,6 +54,7 @@ class BGTactics : public MovementAction bool startNewPathFree(std::vector const& vPaths); bool resetObjective(); bool wsgPaths(); + bool eyJumpDown(); bool atFlag(std::vector const& vPaths, std::vector const& vFlagIds); bool flagTaken(); bool teamFlagTaken(); diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 0aef8b4e..3de2c96f 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -57,6 +57,16 @@ void MovementAction::CreateWp(Player* wpOwner, float x, float y, float z, float wpCreature->SetObjectScale(0.5f); } +void MovementAction::JumpTo(uint32 mapId, float x, float y, float z) { + float botZ = bot->GetPositionZ(); + float speed = bot->GetSpeed(MOVE_RUN); + MotionMaster& mm = *bot->GetMotionMaster(); + botAI->SetNextCheckDelay(1000); + mm.Clear(); + mm.MoveJump(x, y, z, speed, speed, 1); + AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); +} + bool MovementAction::MoveNear(uint32 mapId, float x, float y, float z, float distance) { float angle = GetFollowAngle(); diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h index c00ee5c8..0964ddfb 100644 --- a/src/strategy/actions/MovementActions.h +++ b/src/strategy/actions/MovementActions.h @@ -21,6 +21,7 @@ class MovementAction : public Action MovementAction(PlayerbotAI* botAI, std::string const name); protected: + void JumpTo(uint32 mapId, float x, float y, float z); bool MoveNear(uint32 mapId, float x, float y, float z, float distance = sPlayerbotAIConfig->contactDistance); bool MoveToLOS(WorldObject* target, bool ranged = false); bool MoveTo(uint32 mapId, float x, float y, float z, bool idle = false, bool react = false, bool normal_only = false); From 0e129f315ea99771f607470dc2dc2e092a3cc1ae Mon Sep 17 00:00:00 2001 From: Fuzz Date: Mon, 29 Jul 2024 13:03:01 +1000 Subject: [PATCH 3/3] [Battlegrounds] EOTS - improved path selection, bots no longer just hide near spawn when they have flag but no objective (they try to take to neutral or enemy point with to capture both point then flag), bots now defend points on their side of map more aggressively --- src/strategy/actions/BattleGroundTactics.cpp | 110 ++++++++++--------- src/strategy/actions/BattleGroundTactics.h | 2 +- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/src/strategy/actions/BattleGroundTactics.cpp b/src/strategy/actions/BattleGroundTactics.cpp index 212dfae6..403c50fe 100644 --- a/src/strategy/actions/BattleGroundTactics.cpp +++ b/src/strategy/actions/BattleGroundTactics.cpp @@ -3233,7 +3233,7 @@ bool BGTactics::selectObjective(bool reset) if (enemyCaptain->getDeathState() != DeathState::Dead) { BgObjective = enemyCaptain; - uint32 attackCount = getDefendersCount(AV_STONEHEARTH_WAITING_HORDE, 10.0f, false) + getDefendersCount(AV_STONEHEARTH_ATTACKING_HORDE, 10.0f, false); + uint32 attackCount = getPlayersInArea(bot->GetTeamId(), AV_STONEHEARTH_WAITING_HORDE, 10.0f, false) + getPlayersInArea(bot->GetTeamId(), AV_STONEHEARTH_ATTACKING_HORDE, 10.0f, false); // prepare to attack Captain if (attackCount < 15 && !enemyCaptain->IsInCombat()) { @@ -3398,7 +3398,7 @@ bool BGTactics::selectObjective(bool reset) if (enemyCaptain->getDeathState() != DeathState::Dead) { BgObjective = enemyCaptain; - uint32 attackCount = getDefendersCount(AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE, 10.0f, false) + getDefendersCount(AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE, 10.0f, false); + uint32 attackCount = getPlayersInArea(bot->GetTeamId(), AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE, 10.0f, false) + getPlayersInArea(bot->GetTeamId(), AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE, 10.0f, false); // prepare to attack Captain if (attackCount < 15 && !enemyCaptain->IsInCombat()) { @@ -3753,62 +3753,67 @@ bool BGTactics::selectObjective(bool reset) BattlegroundEY* eyeOfTheStormBG = (BattlegroundEY*)bg; TeamId botTeam = bot->GetTeamId(); - if (bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL)) //has flag + if (bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL))//has flag { - //try to deliver flag BgObjective = nullptr; uint32 areaTrigger = 0; - float closestDist = FLT_MAX; - // previous method just went to first objective owned (going though list same order regardless of team) which made both teams more likely to go go to horde side of map (seemed to boost alliance) + uint8 closestObjectiveOwnership = 0;//(2 == owned 1 == neutral 0 == enemy) + float closestObjectiveDist = FLT_MAX; + // find the closest objective, prioritising friendly objectives over neutral over enemy for (const auto& objective : EY_AttackObjectives) { - if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(objective))._ownerTeamId == botTeam) + if (GameObject* go = bg->GetBGObject(std::get<1>(objective))) { - if (GameObject* go = bg->GetBGObject(std::get<1>(objective))) + TeamId pointOwner = eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(objective))._ownerTeamId; + uint8 ownership = pointOwner == bot->GetTeamId() ? 2 : pointOwner == TEAM_NEUTRAL ? 1 : 0; + if (closestObjectiveOwnership > ownership) + continue; + float dist = sqrt(bot->GetDistance(go)); + if (closestObjectiveOwnership < ownership || (closestObjectiveDist > dist && (closestObjectiveDist - dist > 1 || urand(0, 1))))//if distance difference is minor (as it will be when they first pick flag up from middle) add some randomness so its not going to same point every time { - float dist = sqrt(bot->GetDistance(go)); - if (closestDist > dist && (closestDist - dist > 1 || urand(0, 1)))//if distance difference is minor (as it will be when they first pick flag up from middle) add some randomness so its not going to same point every time - { - closestDist = dist; - BgObjective = go; - areaTrigger = std::get<2>(objective); - } + closestObjectiveOwnership = ownership; + closestObjectiveDist = dist; + BgObjective = go; + areaTrigger = std::get<2>(objective); } } } if (BgObjective) { - //deliver flag to owned base pos.Set(BgObjective->GetPositionX(), BgObjective->GetPositionY(), BgObjective->GetPositionZ(), bg->GetMapId()); } - else if (botTeam == TEAM_HORDE) - { - //TODO - just make them go for base on their side its better than cowering in corner - areaTrigger = 0; - pos.Set(EY_FLAG_RETURN_POS_RETREAT_HORDE.GetPositionX(), EY_FLAG_RETURN_POS_RETREAT_HORDE.GetPositionY(), EY_FLAG_RETURN_POS_RETREAT_HORDE.GetPositionZ(), bg->GetMapId()); - } else { - //TODO - just make them go for base on their side its better than cowering in corner + //old fallback method that has them cowering in corner, shouldn't happen anymore areaTrigger = 0; - pos.Set(EY_FLAG_RETURN_POS_RETREAT_ALLIANCE.GetPositionX(), EY_FLAG_RETURN_POS_RETREAT_ALLIANCE.GetPositionY(), EY_FLAG_RETURN_POS_RETREAT_ALLIANCE.GetPositionZ(), bg->GetMapId()); + Position const retreatPos = botTeam == TEAM_HORDE ? EY_FLAG_RETURN_POS_RETREAT_HORDE : EY_FLAG_RETURN_POS_RETREAT_ALLIANCE; + pos.Set(retreatPos.GetPositionX(), retreatPos.GetPositionY(), retreatPos.GetPositionZ(), bg->GetMapId()); } if (areaTrigger && bot->IsWithinDist3d(pos.x, pos.y, pos.z, INTERACTION_DISTANCE)) { - WorldPacket data(CMSG_AREATRIGGER); - data << uint32(areaTrigger); - bot->GetSession()->HandleAreaTriggerOpcode(data); - pos.Reset(); - posMap["bg objective"] = pos; + if (closestObjectiveOwnership == 2)//means we own the objective, so capture flag at point + { + WorldPacket data(CMSG_AREATRIGGER); + data << uint32(areaTrigger); + bot->GetSession()->HandleAreaTriggerOpcode(data); + pos.Reset(); + posMap["bg objective"] = pos; + } + else//wait until point is yours + { + botAI->SetNextCheckDelay(500); + } } else if (!MoveTo(bot->GetMapId(), pos.x, pos.y, pos.z)) + { posMap["bg objective"] = pos; + } return true; } - else //not flag carrier + else//does not have flag { uint32 role = context->GetValue("bg role")->Get(); @@ -3831,47 +3836,49 @@ bool BGTactics::selectObjective(bool reset) attackObjectivesBack[0] = EY_AttackObjectives[0]; attackObjectivesBack[1] = EY_AttackObjectives[1]; } - if (role == 1) //Harass left back + if (role == 0) //Harass left back { BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesBack[0])); } - else if (role == 2) //Harass right back + else if (role == 1) //Harass right back { BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesBack[1])); } - else if (role < 8) //Attack and Defend + else if (role < 8) //2,3,4,5,6,7 - Attack and Defend { while (BgObjective == nullptr) { - if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[0]))._ownerTeamId != botTeam || - eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[1]))._ownerTeamId != botTeam) + bool front0Owned = eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[0]))._ownerTeamId == botTeam; + bool front1Owned = eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesFront[1]))._ownerTeamId == botTeam; + + if (!front0Owned || !front1Owned) { // Capture front objectives before attacking back objectives // LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Get Front Objectives", // bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); - if (role < 6) + if (role < (front1Owned ? 7 : front0Owned ? 3 : 5))//if we own one put most on the point we dont have, otherwise split evenly { BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[0])); } - else if (role < 8) + else { BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[1])); } } else { - // Now capture all objectives with priority on back + // Now capture all objectives // LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Get All Objectives", // bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); - if (role < 4) + if (role < 4)//2,3 - Defend { BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[0])); } - else if (role < 5) + else if (role < 6)//4,5 - Defend { BgObjective = bg->GetBGObject(std::get<1>(attackObjectivesFront[1])); } - else if (role < 8) + else//6,7 - Attack (along with 0,1) { if (eyeOfTheStormBG->GetCapturePointInfo(std::get<0>(attackObjectivesBack[0]))._ownerTeamId != botTeam) { @@ -3894,7 +3901,7 @@ bool BGTactics::selectObjective(bool reset) } } } - else if (role < 10) + else//8,9 - flag cap { //Get the flag or defend flag carrier Unit* teamFC = AI_VALUE(Unit*, "team flag carrier"); @@ -3989,8 +3996,8 @@ bool BGTactics::selectObjective(bool reset) // mount defensive cannons if (role > 10) // disabled { - uint32 firstTower = getDefendersCount(IC_CANNON_POS_HORDE1, 10.0f); - uint32 secondTower = getDefendersCount(IC_CANNON_POS_HORDE2, 10.0f); + uint32 firstTower = getPlayersInArea(bot->GetTeamId(), IC_CANNON_POS_HORDE1, 10.0f); + uint32 secondTower = getPlayersInArea(bot->GetTeamId(), IC_CANNON_POS_HORDE2, 10.0f); if (firstTower < 2) { @@ -4178,8 +4185,8 @@ bool BGTactics::selectObjective(bool reset) // mount defensive cannons if (role > 10) // disabled { - uint32 firstTower = getDefendersCount(IC_CANNON_POS_ALLIANCE1, 10.0f); - uint32 secondTower = getDefendersCount(IC_CANNON_POS_ALLIANCE2, 10.0f); + uint32 firstTower = getPlayersInArea(bot->GetTeamId(), IC_CANNON_POS_ALLIANCE1, 10.0f); + uint32 secondTower = getPlayersInArea(bot->GetTeamId(), IC_CANNON_POS_ALLIANCE2, 10.0f); if (firstTower < 3) { @@ -4455,7 +4462,7 @@ bool BGTactics::selectObjectiveWp(std::vector const& vPaths) if (bgType == BATTLEGROUND_IC) botDistanceLimit = 80.0f; - else if (bgType == BATTLEGROUND_AB) + else if (bgType == BATTLEGROUND_AB || bgType == BATTLEGROUND_EY) { botDistanceScoreSubtract = 2.0f; botDistanceScoreMultiply = 4.0f; @@ -4537,7 +4544,7 @@ bool BGTactics::resetObjective() return false; // sometimes change role - should do so less often on larger BG's otherwise bots will spend too much time running around map instead of doing something useful - uint32 rollChangeOdds = BATTLEGROUND_AV == bg->GetBgTypeID() ? 63 : 5; + uint32 rollChangeOdds = BATTLEGROUND_AV == bg->GetBgTypeID() ? 63 : BATTLEGROUND_EY == bg->GetBgTypeID() ? 31 : 5; if (!urand(0, rollChangeOdds) && !(bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL))) context->GetValue("bg role")->Set(urand(0, 9)); @@ -4557,8 +4564,7 @@ bool BGTactics::moveToObjectiveWp(BattleBotPath* const& currentPath, uint32 curr uint32 const lastPointInPath = reverse ? 0 : ((*currentPath).size() - 1); if ((currentPoint == lastPointInPath) || - (bot->IsInCombat() && !(bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL))) || !bot->IsAlive()) - { + (bot->IsInCombat() && !(bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL))) || !bot->IsAlive()) { // Path is over. //std::ostringstream out; //out << "Reached path end!"; @@ -4993,7 +4999,7 @@ bool BGTactics::useBuff() return false; } -uint32 BGTactics::getDefendersCount(Position point, float range, bool combat) +uint32 BGTactics::getPlayersInArea(TeamId teamId, Position point, float range, bool combat) { uint32 defCount = 0; @@ -5010,7 +5016,7 @@ uint32 BGTactics::getDefendersCount(Position point, float range, bool combat) if (!player) continue; - if (player->IsAlive() && player->GetTeamId() == bot->GetTeamId()) + if (player->IsAlive() && (teamId == TEAM_NEUTRAL || teamId == player->GetTeamId())) { if (!combat && player->IsInCombat()) continue; diff --git a/src/strategy/actions/BattleGroundTactics.h b/src/strategy/actions/BattleGroundTactics.h index 66f0c8a8..7fba2076 100644 --- a/src/strategy/actions/BattleGroundTactics.h +++ b/src/strategy/actions/BattleGroundTactics.h @@ -60,7 +60,7 @@ class BGTactics : public MovementAction bool teamFlagTaken(); bool protectFC(); bool useBuff(); - uint32 getDefendersCount(Position point, float range, bool combat = true); + uint32 getPlayersInArea(TeamId teamId, Position point, float range, bool combat = true); bool IsLockedInsideKeep(); };