mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge branch 'master' into configured65-mod-playerbots-pr-branch
This commit is contained in:
@@ -341,6 +341,13 @@ AiPlayerbot.GlobalCooldown = 500
|
|||||||
# Max wait time when moving
|
# Max wait time when moving
|
||||||
AiPlayerbot.MaxWaitForMove = 5000
|
AiPlayerbot.MaxWaitForMove = 5000
|
||||||
|
|
||||||
|
# Disables use of MoveSplinePath for bot movement, will result in more erratic bot movement but means stun/snare/root/etc
|
||||||
|
# will work on bots (they wont reliably work when MoveSplinePath is enabled, though slowing effects still work ok)
|
||||||
|
# Default: 0 - MoveSplinePath enabled
|
||||||
|
# 1 - MoveSplinePath disabled in BG/Arena only
|
||||||
|
# 2 - MoveSplinePath disabled everywhere
|
||||||
|
AiPlayerbot.DisableMoveSplinePath = 0
|
||||||
|
|
||||||
# Max search time for movement (higher for better movement on slopes)
|
# Max search time for movement (higher for better movement on slopes)
|
||||||
# default: 3
|
# default: 3
|
||||||
AiPlayerbot.MaxMovementSearchTime = 3
|
AiPlayerbot.MaxMovementSearchTime = 3
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
|
|
||||||
globalCoolDown = sConfigMgr->GetOption<int32>("AiPlayerbot.GlobalCooldown", 1500);
|
globalCoolDown = sConfigMgr->GetOption<int32>("AiPlayerbot.GlobalCooldown", 1500);
|
||||||
maxWaitForMove = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxWaitForMove", 5000);
|
maxWaitForMove = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxWaitForMove", 5000);
|
||||||
|
disableMoveSplinePath = sConfigMgr->GetOption<int32>("AiPlayerbot.DisableMoveSplinePath", 0);
|
||||||
maxMovementSearchTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxMovementSearchTime", 3);
|
maxMovementSearchTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxMovementSearchTime", 3);
|
||||||
expireActionTime = sConfigMgr->GetOption<int32>("AiPlayerbot.ExpireActionTime", 5000);
|
expireActionTime = sConfigMgr->GetOption<int32>("AiPlayerbot.ExpireActionTime", 5000);
|
||||||
dispelAuraDuration = sConfigMgr->GetOption<int32>("AiPlayerbot.DispelAuraDuration", 7000);
|
dispelAuraDuration = sConfigMgr->GetOption<int32>("AiPlayerbot.DispelAuraDuration", 7000);
|
||||||
@@ -272,6 +273,9 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
equipmentPersistence = sConfigMgr->GetOption<bool>("AiPlayerbot.EquipmentPersistence", false);
|
equipmentPersistence = sConfigMgr->GetOption<bool>("AiPlayerbot.EquipmentPersistence", false);
|
||||||
equipmentPersistenceLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.EquipmentPersistenceLevel", 80);
|
equipmentPersistenceLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.EquipmentPersistenceLevel", 80);
|
||||||
groupInvitationPermission = sConfigMgr->GetOption<int32>("AiPlayerbot.GroupInvitationPermission", 1);
|
groupInvitationPermission = sConfigMgr->GetOption<int32>("AiPlayerbot.GroupInvitationPermission", 1);
|
||||||
|
allowSummonInCombat = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowSummonInCombat", true);
|
||||||
|
allowSummonWhenMasterIsDead = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowSummonWhenMasterIsDead", true);
|
||||||
|
allowSummonWhenBotIsDead = sConfigMgr->GetOption<bool>("AiPlayerbot.AllowSummonWhenBotIsDead", true);
|
||||||
botReviveWhenSummon = sConfigMgr->GetOption<int>("AiPlayerbot.BotReviveWhenSummon", 1);
|
botReviveWhenSummon = sConfigMgr->GetOption<int>("AiPlayerbot.BotReviveWhenSummon", 1);
|
||||||
botRepairWhenSummon = sConfigMgr->GetOption<bool>("AiPlayerbot.BotRepairWhenSummon", true);
|
botRepairWhenSummon = sConfigMgr->GetOption<bool>("AiPlayerbot.BotRepairWhenSummon", true);
|
||||||
autoInitOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoInitOnly", false);
|
autoInitOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.AutoInitOnly", false);
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ class PlayerbotAIConfig
|
|||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool allowGuildBots, allowPlayerBots;
|
bool allowGuildBots, allowPlayerBots;
|
||||||
uint32 globalCoolDown, reactDelay, maxWaitForMove, maxMovementSearchTime, expireActionTime,
|
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime,
|
||||||
dispelAuraDuration, passiveDelay, repeatDelay,
|
expireActionTime, dispelAuraDuration, passiveDelay, repeatDelay,
|
||||||
errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
||||||
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance,
|
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance,
|
||||||
fleeDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance,
|
fleeDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance,
|
||||||
@@ -214,6 +214,9 @@ class PlayerbotAIConfig
|
|||||||
bool equipmentPersistence;
|
bool equipmentPersistence;
|
||||||
int32 equipmentPersistenceLevel;
|
int32 equipmentPersistenceLevel;
|
||||||
int32 groupInvitationPermission;
|
int32 groupInvitationPermission;
|
||||||
|
bool allowSummonInCombat;
|
||||||
|
bool allowSummonWhenMasterIsDead;
|
||||||
|
bool allowSummonWhenBotIsDead;
|
||||||
int32 botReviveWhenSummon;
|
int32 botReviveWhenSummon;
|
||||||
bool botRepairWhenSummon;
|
bool botRepairWhenSummon;
|
||||||
bool autoInitOnly;
|
bool autoInitOnly;
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
|||||||
availableRaces[CLASS_PRIEST].push_back(RACE_NIGHTELF);
|
availableRaces[CLASS_PRIEST].push_back(RACE_NIGHTELF);
|
||||||
availableRaces[CLASS_PRIEST].push_back(RACE_TROLL);
|
availableRaces[CLASS_PRIEST].push_back(RACE_TROLL);
|
||||||
availableRaces[CLASS_PRIEST].push_back(RACE_UNDEAD_PLAYER);
|
availableRaces[CLASS_PRIEST].push_back(RACE_UNDEAD_PLAYER);
|
||||||
availableRaces[CLASS_PRIEST].push_back(RACE_DRAENEI);
|
|
||||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||||
{
|
{
|
||||||
|
availableRaces[CLASS_PRIEST].push_back(RACE_DRAENEI);
|
||||||
availableRaces[CLASS_PRIEST].push_back(RACE_BLOODELF);
|
availableRaces[CLASS_PRIEST].push_back(RACE_BLOODELF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,12 +40,16 @@ Position const WS_FLAG_HIDE_ALLIANCE_2 = { 1540.286f, 1476.026f, 352.692f, 2.91f
|
|||||||
Position const WS_FLAG_HIDE_ALLIANCE_3 = { 1495.807f, 1466.774f, 352.350f, 1.50f };
|
Position const WS_FLAG_HIDE_ALLIANCE_3 = { 1495.807f, 1466.774f, 352.350f, 1.50f };
|
||||||
std::vector<Position> const WS_FLAG_HIDE_HORDE = { WS_FLAG_HIDE_HORDE_1 , WS_FLAG_HIDE_HORDE_2, WS_FLAG_HIDE_HORDE_3 };
|
std::vector<Position> const WS_FLAG_HIDE_HORDE = { WS_FLAG_HIDE_HORDE_1 , WS_FLAG_HIDE_HORDE_2, WS_FLAG_HIDE_HORDE_3 };
|
||||||
std::vector<Position> const WS_FLAG_HIDE_ALLIANCE = { WS_FLAG_HIDE_ALLIANCE_1 , WS_FLAG_HIDE_ALLIANCE_2, WS_FLAG_HIDE_ALLIANCE_3 };
|
std::vector<Position> const WS_FLAG_HIDE_ALLIANCE = { WS_FLAG_HIDE_ALLIANCE_1 , WS_FLAG_HIDE_ALLIANCE_2, WS_FLAG_HIDE_ALLIANCE_3 };
|
||||||
|
|
||||||
Position const AB_WAITING_POS_HORDE = { 702.884f, 703.045f, -16.115f, 0.77f };
|
Position const AB_WAITING_POS_HORDE = { 702.884f, 703.045f, -16.115f, 0.77f };
|
||||||
Position const AB_WAITING_POS_ALLIANCE = { 1286.054f, 1282.500f, -15.697f, 3.95f };
|
Position const AB_WAITING_POS_ALLIANCE = { 1286.054f, 1282.500f, -15.697f, 3.95f };
|
||||||
|
|
||||||
Position const AV_WAITING_POS_ALLIANCE = { 793.627f, -493.814f, 99.689f, 3.09f };
|
Position const AV_WAITING_POS_ALLIANCE = { 793.627f, -493.814f, 99.689f, 3.09f };
|
||||||
Position const AV_WAITING_POS_HORDE = { -1381.865f, -544.872f, 54.773f, 0.76f };
|
Position const AV_WAITING_POS_HORDE = { -1381.865f, -544.872f, 54.773f, 0.76f };
|
||||||
Position const AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE = { -492.17f, -187.077f, 57.1342f, 2.77f };
|
Position const AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE = { -523.105f, -182.178f, 57.956f, 2.77f };
|
||||||
Position const AV_STONEHEARTH_WAITING_HORDE = { 28.1264f, -302.593f, 15.076f, 2.96f };
|
Position const AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE = { -545.288f, -167.932f, 57.012f, 2.77f };
|
||||||
|
Position const AV_STONEHEARTH_WAITING_HORDE = { -36.399f, -306.403f, 15.565f, 2.96f };
|
||||||
|
Position const AV_STONEHEARTH_ATTACKING_HORDE = { -55.210f, -288.546f, 15.578f, 2.96f };
|
||||||
|
|
||||||
Position const EY_WAITING_POS_HORDE = { 1809.102f, 1540.854f, 1267.142f, 6.18f };
|
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_WAITING_POS_ALLIANCE = { 2526.020f, 1596.787f, 1270.127f, 3.14f };
|
||||||
@@ -799,7 +803,16 @@ BattleBotPath vPath_AB_Farm_to_LumberMill =
|
|||||||
|
|
||||||
BattleBotPath vPath_AV_Horde_Cave_to_Tower_Point_Crossroad =
|
BattleBotPath vPath_AV_Horde_Cave_to_Tower_Point_Crossroad =
|
||||||
{
|
{
|
||||||
{ -885.928f, -536.612f, 55.1936f, nullptr },
|
{ -1362.395f, -529.615f, 52.636f, nullptr },
|
||||||
|
{ -1327.036f, -511.374f, 51.138f, nullptr },
|
||||||
|
{ -1277.047f, -516.327f, 50.667f, nullptr },
|
||||||
|
{ -1214.901f, -529.350f, 52.251f, nullptr },
|
||||||
|
{ -1151.129f, -545.598f, 51.990f, nullptr },
|
||||||
|
{ -1085.775f, -538.719f, 47.905f, nullptr },
|
||||||
|
{ -1038.552f, -517.946f, 43.876f, nullptr },
|
||||||
|
{ -981.371f, -494.593f, 41.127f, nullptr },
|
||||||
|
{ -930.598f, -463.751f, 43.060f, nullptr },
|
||||||
|
{ -887.138f, -475.816f, 44.374f, nullptr },
|
||||||
{ -880.957f, -525.119f, 53.6791f, nullptr },
|
{ -880.957f, -525.119f, 53.6791f, nullptr },
|
||||||
{ -839.408f, -499.746f, 49.7505f, nullptr },
|
{ -839.408f, -499.746f, 49.7505f, nullptr },
|
||||||
{ -820.21f, -469.193f, 49.4085f, nullptr },
|
{ -820.21f, -469.193f, 49.4085f, nullptr },
|
||||||
@@ -2262,48 +2275,48 @@ std::vector<BattleBotPath*> const vPaths_HordeMine =
|
|||||||
&vPath_AV_Coldtooth_Mine_Entrance_to_Coldtooth_Mine_Boss,
|
&vPath_AV_Coldtooth_Mine_Entrance_to_Coldtooth_Mine_Boss,
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32 AV_HordeAttackObjectives[] =
|
static std::pair<uint32, uint32> AV_HordeAttackObjectives[] =
|
||||||
{
|
{
|
||||||
// Attack
|
// Attack
|
||||||
{ BG_AV_NODES_STONEHEART_BUNKER },
|
{ BG_AV_NODES_STONEHEART_BUNKER, BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER },
|
||||||
{ BG_AV_NODES_STONEHEART_GRAVE },
|
{ BG_AV_NODES_STONEHEART_GRAVE, BG_AV_OBJECT_FLAG_A_STONEHEART_GRAVE },
|
||||||
{ BG_AV_NODES_ICEWING_BUNKER },
|
{ BG_AV_NODES_ICEWING_BUNKER, BG_AV_OBJECT_FLAG_A_ICEWING_BUNKER },
|
||||||
{ BG_AV_NODES_STORMPIKE_GRAVE },
|
{ BG_AV_NODES_STORMPIKE_GRAVE, BG_AV_OBJECT_FLAG_A_STORMPIKE_GRAVE },
|
||||||
{ BG_AV_NODES_DUNBALDAR_SOUTH },
|
{ BG_AV_NODES_DUNBALDAR_SOUTH, BG_AV_OBJECT_FLAG_A_DUNBALDAR_SOUTH },
|
||||||
{ BG_AV_NODES_DUNBALDAR_NORTH },
|
{ BG_AV_NODES_DUNBALDAR_NORTH, BG_AV_OBJECT_FLAG_A_DUNBALDAR_NORTH },
|
||||||
{ BG_AV_NODES_FIRSTAID_STATION }
|
{ BG_AV_NODES_FIRSTAID_STATION, BG_AV_OBJECT_FLAG_A_FIRSTAID_STATION }
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32 AV_HordeDefendObjectives[] =
|
static std::pair<uint32, uint32> AV_HordeDefendObjectives[] =
|
||||||
{
|
{
|
||||||
// Defend
|
// Defend
|
||||||
{ BG_AV_NODES_FROSTWOLF_GRAVE },
|
{ BG_AV_NODES_FROSTWOLF_GRAVE, BG_AV_OBJECT_FLAG_H_FROSTWOLF_GRAVE },
|
||||||
{ BG_AV_NODES_FROSTWOLF_ETOWER },
|
{ BG_AV_NODES_FROSTWOLF_ETOWER, BG_AV_OBJECT_FLAG_H_FROSTWOLF_ETOWER },
|
||||||
{ BG_AV_NODES_FROSTWOLF_WTOWER },
|
{ BG_AV_NODES_FROSTWOLF_WTOWER, BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER },
|
||||||
{ BG_AV_NODES_TOWER_POINT },
|
{ BG_AV_NODES_TOWER_POINT, BG_AV_OBJECT_FLAG_H_TOWER_POINT },
|
||||||
{ BG_AV_NODES_ICEBLOOD_TOWER },
|
{ BG_AV_NODES_ICEBLOOD_TOWER, BG_AV_OBJECT_FLAG_H_ICEBLOOD_TOWER },
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32 AV_AllianceAttackObjectives[] =
|
static std::pair<uint32, uint32> AV_AllianceAttackObjectives[] =
|
||||||
{
|
{
|
||||||
// Attack
|
// Attack
|
||||||
{ BG_AV_NODES_ICEBLOOD_TOWER },
|
{ BG_AV_NODES_ICEBLOOD_TOWER, BG_AV_OBJECT_FLAG_H_ICEBLOOD_TOWER},
|
||||||
{ BG_AV_NODES_ICEBLOOD_GRAVE },
|
{ BG_AV_NODES_ICEBLOOD_GRAVE, BG_AV_OBJECT_FLAG_H_ICEBLOOD_GRAVE},
|
||||||
{ BG_AV_NODES_TOWER_POINT },
|
{ BG_AV_NODES_TOWER_POINT, BG_AV_OBJECT_FLAG_H_TOWER_POINT },
|
||||||
{ BG_AV_NODES_FROSTWOLF_GRAVE },
|
{ BG_AV_NODES_FROSTWOLF_GRAVE, BG_AV_OBJECT_FLAG_H_FROSTWOLF_GRAVE },
|
||||||
{ BG_AV_NODES_FROSTWOLF_ETOWER },
|
{ BG_AV_NODES_FROSTWOLF_ETOWER, BG_AV_OBJECT_FLAG_H_FROSTWOLF_ETOWER },
|
||||||
{ BG_AV_NODES_FROSTWOLF_WTOWER },
|
{ BG_AV_NODES_FROSTWOLF_WTOWER, BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER },
|
||||||
{ BG_AV_NODES_FROSTWOLF_HUT },
|
{ BG_AV_NODES_FROSTWOLF_HUT, BG_AV_OBJECT_FLAG_H_FROSTWOLF_HUT },
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32 AV_AllianceDefendObjectives[] =
|
static std::pair<uint32, uint32> AV_AllianceDefendObjectives[] =
|
||||||
{
|
{
|
||||||
// Defend
|
// Defend
|
||||||
{ BG_AV_NODES_STORMPIKE_GRAVE },
|
{ BG_AV_NODES_STORMPIKE_GRAVE, BG_AV_OBJECT_FLAG_A_STORMPIKE_GRAVE },
|
||||||
{ BG_AV_NODES_DUNBALDAR_SOUTH },
|
{ BG_AV_NODES_DUNBALDAR_SOUTH, BG_AV_OBJECT_FLAG_A_DUNBALDAR_SOUTH },
|
||||||
{ BG_AV_NODES_DUNBALDAR_NORTH },
|
{ BG_AV_NODES_DUNBALDAR_NORTH, BG_AV_OBJECT_FLAG_A_DUNBALDAR_NORTH },
|
||||||
{ BG_AV_NODES_ICEWING_BUNKER },
|
{ BG_AV_NODES_ICEWING_BUNKER, BG_AV_OBJECT_FLAG_A_ICEWING_BUNKER },
|
||||||
{ BG_AV_NODES_STONEHEART_BUNKER },
|
{ BG_AV_NODES_STONEHEART_BUNKER, BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER },
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32 AB_AttackObjectives[] =
|
static uint32 AB_AttackObjectives[] =
|
||||||
@@ -2937,7 +2950,7 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_STONEHEART_BUNKER).TotalOwnerId != TEAM_ALLIANCE &&
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_STONEHEART_BUNKER).TotalOwnerId != TEAM_ALLIANCE &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FIRSTAID_STATION).TotalOwnerId != TEAM_ALLIANCE)
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FIRSTAID_STATION).TotalOwnerId != TEAM_ALLIANCE)
|
||||||
{
|
{
|
||||||
if (Creature* pVanndar = bg->GetBGCreature(AV_NPC_A_BOSS))
|
if (Creature* pVanndar = bg->GetBGCreature(AV_CPLACE_TRIGGER17))
|
||||||
{
|
{
|
||||||
BgObjective = pVanndar;
|
BgObjective = pVanndar;
|
||||||
endBoss = true;
|
endBoss = true;
|
||||||
@@ -2952,8 +2965,9 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
|
|
||||||
// Only go to Snowfall Graveyard if already close to it.
|
// Only go to Snowfall Graveyard if already close to it.
|
||||||
// Need to fix AV script
|
// Need to fix AV script
|
||||||
if (!BgObjective && supporter && (alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_ALLIANCE ||
|
if (!BgObjective && supporter &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_HORDE || alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_OTHER))
|
(alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_ALLIANCE ||
|
||||||
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_OTHER))
|
||||||
{
|
{
|
||||||
if (GameObject* pGO = bg->GetBGObject(BG_AV_NODES_SNOWFALL_GRAVE))
|
if (GameObject* pGO = bg->GetBGObject(BG_AV_NODES_SNOWFALL_GRAVE))
|
||||||
if (bot->IsWithinDist(pGO, 200.f))
|
if (bot->IsWithinDist(pGO, 200.f))
|
||||||
@@ -2967,19 +2981,20 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
|
|
||||||
if (!BgObjective && alterValleyBG->IsCaptainAlive(0))
|
if (!BgObjective && alterValleyBG->IsCaptainAlive(0))
|
||||||
{
|
{
|
||||||
if (Creature* pBalinda = bg->GetBGCreature(AV_NPC_A_CAPTAIN))
|
if (Creature* pBalinda = bg->GetBGCreature(AV_CPLACE_TRIGGER16))
|
||||||
{
|
{
|
||||||
if (pBalinda->getDeathState() != DeathState::Dead)
|
if (pBalinda->getDeathState() != DeathState::Dead)
|
||||||
{
|
{
|
||||||
uint32 attackCount = 0;
|
uint32 attackCount = getDefendersCount(AV_STONEHEARTH_WAITING_HORDE, 10.0f, false) + getDefendersCount(AV_STONEHEARTH_ATTACKING_HORDE, 10.0f, false);
|
||||||
attackCount += getDefendersCount(AV_STONEHEARTH_WAITING_HORDE, 10.0f, false);
|
|
||||||
|
|
||||||
// prepare to attack Captain
|
// prepare to attack Captain
|
||||||
if (attackCount < 10 && !pBalinda->IsInCombat())
|
if (attackCount < 10 && !pBalinda->IsInCombat())
|
||||||
{
|
{
|
||||||
// get in position to attack Captain
|
// get in position to attack Captain
|
||||||
pos.Set(AV_STONEHEARTH_WAITING_HORDE.GetPositionX(), AV_STONEHEARTH_WAITING_HORDE.GetPositionY(),
|
pos.Set(AV_STONEHEARTH_WAITING_HORDE.GetPositionX(),
|
||||||
AV_STONEHEARTH_WAITING_HORDE.GetPositionZ(), bg->GetMapId());
|
AV_STONEHEARTH_WAITING_HORDE.GetPositionY(),
|
||||||
|
AV_STONEHEARTH_WAITING_HORDE.GetPositionZ(),
|
||||||
|
bg->GetMapId());
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Taking position at Stonehearth!";
|
out << "Taking position at Stonehearth!";
|
||||||
@@ -2987,6 +3002,12 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// they need help getting there (or did before I fixed the target creature, will leave in anyway, as it probably makes it more robust)
|
||||||
|
pos.Set(AV_STONEHEARTH_ATTACKING_HORDE.GetPositionX(),
|
||||||
|
AV_STONEHEARTH_ATTACKING_HORDE.GetPositionY(),
|
||||||
|
AV_STONEHEARTH_ATTACKING_HORDE.GetPositionZ(),
|
||||||
|
bg->GetMapId());
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Attacking Balinda!";
|
out << "Attacking Balinda!";
|
||||||
//bot->Say(out.str(), LANG_UNIVERSAL);
|
//bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
@@ -3007,9 +3028,9 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
{
|
{
|
||||||
for (const auto& objective : AV_HordeDefendObjectives)
|
for (const auto& objective : AV_HordeDefendObjectives)
|
||||||
{
|
{
|
||||||
if (!BgObjective && alterValleyBG->GetAVNodeInfo(objective).OwnerId == TEAM_ALLIANCE)
|
if (!BgObjective && alterValleyBG->GetAVNodeInfo(objective.first).OwnerId == TEAM_ALLIANCE)
|
||||||
{
|
{
|
||||||
if (GameObject* pGO = bg->GetBGObject(objective))
|
if (GameObject* pGO = bg->GetBGObject(objective.second))
|
||||||
if (bot->IsWithinDist(pGO, 400.0f))
|
if (bot->IsWithinDist(pGO, 400.0f))
|
||||||
{
|
{
|
||||||
BgObjective = pGO;
|
BgObjective = pGO;
|
||||||
@@ -3022,7 +3043,8 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mine capture (need paths & script fix)
|
// Mine capture (need paths & script fix)
|
||||||
if (!BgObjective && supporter && !endBoss && (alterValleyBG->GetMineOwner(AV_NORTH_MINE) == TEAM_ALLIANCE || alterValleyBG->GetMineOwner(AV_NORTH_MINE) == TEAM_OTHER) &&
|
if (!BgObjective && supporter && !endBoss &&
|
||||||
|
(alterValleyBG->GetMineOwner(AV_NORTH_MINE) == TEAM_ALLIANCE || alterValleyBG->GetMineOwner(AV_NORTH_MINE) == TEAM_OTHER) &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_STORMPIKE_GRAVE).OwnerId != TEAM_ALLIANCE)
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_STORMPIKE_GRAVE).OwnerId != TEAM_ALLIANCE)
|
||||||
{
|
{
|
||||||
if (Creature* mBossNeutral = bg->GetBGCreature(AV_CPLACE_MINE_N_3))
|
if (Creature* mBossNeutral = bg->GetBGCreature(AV_CPLACE_MINE_N_3))
|
||||||
@@ -3055,10 +3077,9 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
for (const auto& objective : AV_HordeAttackObjectives)
|
for (const auto& objective : AV_HordeAttackObjectives)
|
||||||
{
|
{
|
||||||
if ((!BgObjective/* || (supporter && objective.first == BG_AV_NODES_STONEHEART_BUNKER && !bg->IsActiveEvent(BG_AV_NODE_CAPTAIN_DEAD_A, 0))*/) &&
|
if ((!BgObjective/* || (supporter && objective.first == BG_AV_NODES_STONEHEART_BUNKER && !bg->IsActiveEvent(BG_AV_NODE_CAPTAIN_DEAD_A, 0))*/) &&
|
||||||
(alterValleyBG->GetAVNodeInfo(objective).OwnerId == TEAM_ALLIANCE || alterValleyBG->GetAVNodeInfo(objective).TotalOwnerId == TEAM_ALLIANCE ||
|
alterValleyBG->GetAVNodeInfo(objective.first).TotalOwnerId == TEAM_ALLIANCE)//need to check TotalOwnerId for attack objectives
|
||||||
alterValleyBG->GetAVNodeInfo(objective).OwnerId == TEAM_OTHER))
|
|
||||||
{
|
{
|
||||||
if (GameObject* pGO = bg->GetBGObject(objective))
|
if (GameObject* pGO = bg->GetBGObject(objective.second))
|
||||||
{
|
{
|
||||||
BgObjective = pGO;
|
BgObjective = pGO;
|
||||||
//std::ostringstream out;
|
//std::ostringstream out;
|
||||||
@@ -3073,11 +3094,13 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
{
|
{
|
||||||
bool endBoss = false;
|
bool endBoss = false;
|
||||||
// End boss
|
// End boss
|
||||||
if (alterValleyBG->GetAVNodeInfo(BG_AV_NODES_ICEBLOOD_TOWER).OwnerId != TEAM_HORDE && alterValleyBG->GetAVNodeInfo(BG_AV_NODES_TOWER_POINT).OwnerId != TEAM_HORDE &&
|
if (alterValleyBG->GetAVNodeInfo(BG_AV_NODES_ICEBLOOD_TOWER).TotalOwnerId != TEAM_HORDE &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_ETOWER).OwnerId != TEAM_HORDE && alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_WTOWER).OwnerId != TEAM_HORDE &&
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_TOWER_POINT).TotalOwnerId != TEAM_HORDE &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_HUT).OwnerId != TEAM_HORDE)
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_ETOWER).TotalOwnerId != TEAM_HORDE &&
|
||||||
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_WTOWER).TotalOwnerId != TEAM_HORDE &&
|
||||||
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_HUT).TotalOwnerId != TEAM_HORDE)
|
||||||
{
|
{
|
||||||
if (Creature* pDrek = bg->GetBGCreature(AV_NPC_H_BOSS))
|
if (Creature* pDrek = bg->GetBGCreature(AV_CPLACE_TRIGGER19))
|
||||||
{
|
{
|
||||||
BgObjective = pDrek;
|
BgObjective = pDrek;
|
||||||
endBoss = true;
|
endBoss = true;
|
||||||
@@ -3091,9 +3114,9 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
bool supporter = role < 3;
|
bool supporter = role < 3;
|
||||||
|
|
||||||
// Only go to Snowfall Graveyard if already close to it.
|
// Only go to Snowfall Graveyard if already close to it.
|
||||||
if (!BgObjective && supporter && (alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_HORDE ||
|
if (!BgObjective && supporter &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).TotalOwnerId == TEAM_HORDE ||
|
(alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_HORDE ||
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).TotalOwnerId == TEAM_OTHER))
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE).OwnerId == TEAM_OTHER))
|
||||||
{
|
{
|
||||||
if (GameObject* pGO = bg->GetBGObject(BG_AV_NODES_SNOWFALL_GRAVE))
|
if (GameObject* pGO = bg->GetBGObject(BG_AV_NODES_SNOWFALL_GRAVE))
|
||||||
if (bot->IsWithinDist(pGO, 200.f))
|
if (bot->IsWithinDist(pGO, 200.f))
|
||||||
@@ -3110,9 +3133,9 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
{
|
{
|
||||||
for (const auto& objective : AV_AllianceDefendObjectives)
|
for (const auto& objective : AV_AllianceDefendObjectives)
|
||||||
{
|
{
|
||||||
if (!BgObjective && alterValleyBG->GetAVNodeInfo(objective).OwnerId == TEAM_HORDE)
|
if (!BgObjective && alterValleyBG->GetAVNodeInfo(objective.first).OwnerId == TEAM_HORDE)
|
||||||
{
|
{
|
||||||
if (GameObject* pGO = bg->GetBGObject(objective))
|
if (GameObject* pGO = bg->GetBGObject(objective.second))
|
||||||
{
|
{
|
||||||
BgObjective = pGO;
|
BgObjective = pGO;
|
||||||
//std::ostringstream out; out << "Defending Node #" << objective.first;
|
//std::ostringstream out; out << "Defending Node #" << objective.first;
|
||||||
@@ -3123,8 +3146,8 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mine capture (need paths & script fix)
|
// Mine capture (need paths & script fix)
|
||||||
if (!BgObjective && supporter && !endBoss && (alterValleyBG->GetMineOwner(AV_SOUTH_MINE) == TEAM_HORDE ||
|
if (!BgObjective && supporter && !endBoss &&
|
||||||
alterValleyBG->GetMineOwner(AV_SOUTH_MINE) == TEAM_OTHER) &&
|
(alterValleyBG->GetMineOwner(AV_SOUTH_MINE) == TEAM_HORDE || alterValleyBG->GetMineOwner(AV_SOUTH_MINE) == TEAM_OTHER) &&
|
||||||
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_GRAVE).TotalOwnerId != TEAM_HORDE)
|
alterValleyBG->GetAVNodeInfo(BG_AV_NODES_FROSTWOLF_GRAVE).TotalOwnerId != TEAM_HORDE)
|
||||||
{
|
{
|
||||||
if (Creature* mBossNeutral = bg->GetBGCreature(AV_CPLACE_MINE_S_3))
|
if (Creature* mBossNeutral = bg->GetBGCreature(AV_CPLACE_MINE_S_3))
|
||||||
@@ -3158,17 +3181,18 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
|
|
||||||
if (alterValleyBG->IsCaptainAlive(1))
|
if (alterValleyBG->IsCaptainAlive(1))
|
||||||
{
|
{
|
||||||
if (Creature* pGalvangar = bg->GetBGCreature(AV_NPC_H_CAPTAIN))
|
if (Creature* pGalvangar = bg->GetBGCreature(AV_CPLACE_TRIGGER18))
|
||||||
{
|
{
|
||||||
uint32 attackCount = 0;
|
uint32 attackCount = getDefendersCount(AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE, 10.0f, false) + getDefendersCount(AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE, 10.0f, false);
|
||||||
attackCount += getDefendersCount(AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE, 10.0f, false);
|
|
||||||
|
|
||||||
// prepare to attack Captain
|
// prepare to attack Captain
|
||||||
if (attackCount < 10 && !pGalvangar->IsInCombat())
|
if (attackCount < 10 && !pGalvangar->IsInCombat())
|
||||||
{
|
{
|
||||||
// get in position to attack Captain
|
// get in position to attack Captain
|
||||||
pos.Set(AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE.GetPositionX(), AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE.GetPositionY(),
|
pos.Set(AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE.GetPositionX(),
|
||||||
AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE.GetPositionZ(), bg->GetMapId());
|
AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE.GetPositionY(),
|
||||||
|
AV_ICEBLOOD_GARRISON_WAITING_ALLIANCE.GetPositionZ(),
|
||||||
|
bg->GetMapId());
|
||||||
|
|
||||||
//std::ostringstream out;
|
//std::ostringstream out;
|
||||||
//out << "Taking position at Iceblood Outpost!";
|
//out << "Taking position at Iceblood Outpost!";
|
||||||
@@ -3176,6 +3200,12 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// they need help getting there (or did before I fixed the target creature, will leave in anyway, as it probably makes it more robust)
|
||||||
|
pos.Set(AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE.GetPositionX(),
|
||||||
|
AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE.GetPositionY(),
|
||||||
|
AV_ICEBLOOD_GARRISON_ATTACKING_ALLIANCE.GetPositionZ(),
|
||||||
|
bg->GetMapId());
|
||||||
|
|
||||||
//std::ostringstream out;
|
//std::ostringstream out;
|
||||||
// out << "Attacking Galvangar!";
|
// out << "Attacking Galvangar!";
|
||||||
//bot->Say(out.str(), LANG_UNIVERSAL);
|
//bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
@@ -3187,11 +3217,9 @@ bool BGTactics::selectObjective(bool reset)
|
|||||||
|
|
||||||
for (const auto& objective : AV_AllianceAttackObjectives)
|
for (const auto& objective : AV_AllianceAttackObjectives)
|
||||||
{
|
{
|
||||||
if (alterValleyBG->GetAVNodeInfo(objective).OwnerId == TEAM_HORDE ||
|
if (alterValleyBG->GetAVNodeInfo(objective.first).TotalOwnerId == TEAM_HORDE)//need to check TotalOwnerId for attack objectives
|
||||||
alterValleyBG->GetAVNodeInfo(objective).TotalOwnerId == TEAM_HORDE ||
|
|
||||||
alterValleyBG->GetAVNodeInfo(objective).TotalOwnerId == TEAM_OTHER)
|
|
||||||
{
|
{
|
||||||
if (GameObject* pGO = bg->GetBGObject(objective))
|
if (GameObject* pGO = bg->GetBGObject(objective.second))
|
||||||
{
|
{
|
||||||
float const distance = sqrt(bot->GetDistance(pGO));
|
float const distance = sqrt(bot->GetDistance(pGO));
|
||||||
if (attackObjectiveDistance > distance)
|
if (attackObjectiveDistance > distance)
|
||||||
@@ -4124,7 +4152,7 @@ bool BGTactics::moveToObjective()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't try to move if already close
|
// don't try to move if already close
|
||||||
if (sqrt(bot->GetDistance(pos.x, pos.y, pos.z)) < 5.0f)
|
if (sqrt(bot->GetDistance(pos.x, pos.y, pos.z)) < 2.0f)
|
||||||
{
|
{
|
||||||
resetObjective();
|
resetObjective();
|
||||||
|
|
||||||
@@ -4134,8 +4162,8 @@ bool BGTactics::moveToObjective()
|
|||||||
//std::ostringstream out; out << "Moving to objective " << pos.x << ", " << pos.y << ", Distance: " << sServerFacade->GetDistance2d(bot, pos.x, pos.y);
|
//std::ostringstream out; out << "Moving to objective " << pos.x << ", " << pos.y << ", Distance: " << sServerFacade->GetDistance2d(bot, pos.x, pos.y);
|
||||||
//bot->Say(out.str(), LANG_UNIVERSAL);
|
//bot->Say(out.str(), LANG_UNIVERSAL);
|
||||||
|
|
||||||
// more precise position for wsg
|
// more precise position for wsg and AV (flags in AV towers require precision)
|
||||||
if (bgType == BATTLEGROUND_WS)
|
if (bgType == BATTLEGROUND_WS || bgType == BATTLEGROUND_AV)
|
||||||
return MoveTo(bot->GetMapId(), pos.x, pos.y, pos.z);
|
return MoveTo(bot->GetMapId(), pos.x, pos.y, pos.z);
|
||||||
else
|
else
|
||||||
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z, 3.0f);
|
return MoveNear(bot->GetMapId(), pos.x, pos.y, pos.z, 3.0f);
|
||||||
@@ -4162,99 +4190,84 @@ bool BGTactics::selectObjectiveWp(std::vector<BattleBotPath*> const& vPaths)
|
|||||||
if (bgType == BATTLEGROUND_WS /* && (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG))*/)
|
if (bgType == BATTLEGROUND_WS /* && (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG))*/)
|
||||||
return wsgPaths();
|
return wsgPaths();
|
||||||
|
|
||||||
BattleBotPath* pClosestPath = nullptr;
|
float chosenPathScore = FLT_MAX;//lower score is better
|
||||||
uint32 closestPoint = 0;
|
BattleBotPath* chosenPath = nullptr;
|
||||||
float closestDistanceToTarget = FLT_MAX;
|
uint32 chosenPathPoint = 0;
|
||||||
bool reverse = false;
|
bool chosenPathReverse = false;
|
||||||
float maxDistanceToPoint = 50.0f;
|
|
||||||
if (bgType == BATTLEGROUND_IC)
|
|
||||||
maxDistanceToPoint = 80.0f;
|
|
||||||
|
|
||||||
for (auto const& pPath : vPaths)
|
float botDistanceLimit = 50.0f; // limit for how far path can be from bot
|
||||||
|
float botDistanceScoreSubtract = 8.0f; // path score modifier - lower = less likely to chose a further path (it's basically the distance from bot that's ignored)
|
||||||
|
float botDistanceScoreMultiply = 3.0f; // path score modifier - higher = less likely to chose a further path (it's basically a multiplier on distance from bot - makes distance from bot more signifcant than distance from destination)
|
||||||
|
|
||||||
|
if (bgType == BATTLEGROUND_IC)
|
||||||
|
botDistanceLimit = 80.0f;
|
||||||
|
else if (bgType == BATTLEGROUND_AB)
|
||||||
|
{
|
||||||
|
botDistanceScoreSubtract = 2.0f;
|
||||||
|
botDistanceScoreMultiply = 4.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& path : vPaths)
|
||||||
{
|
{
|
||||||
// skip mine paths of own faction
|
// skip mine paths of own faction
|
||||||
if (bot->GetTeamId() == TEAM_ALLIANCE && std::find(vPaths_AllyMine.begin(), vPaths_AllyMine.end(), pPath) != vPaths_AllyMine.end())
|
if (bot->GetTeamId() == TEAM_ALLIANCE && std::find(vPaths_AllyMine.begin(), vPaths_AllyMine.end(), path) != vPaths_AllyMine.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (bot->GetTeamId() == TEAM_HORDE && std::find(vPaths_HordeMine.begin(), vPaths_HordeMine.end(), pPath) != vPaths_HordeMine.end())
|
if (bot->GetTeamId() == TEAM_HORDE && std::find(vPaths_HordeMine.begin(), vPaths_HordeMine.end(), path) != vPaths_HordeMine.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BattleBotWaypoint& lastPoint = ((*pPath)[pPath->size() - 1]);
|
BattleBotWaypoint& startPoint = ((*path)[0]);
|
||||||
float const distanceFromPathEndToTarget = sqrt(Position(pos.x, pos.y, pos.z, 0.f).GetExactDist(lastPoint.x, lastPoint.y, lastPoint.z));
|
float const startPointDistToDestination = sqrt(Position(pos.x, pos.y, pos.z, 0.f).GetExactDist(startPoint.x, startPoint.y, startPoint.z));
|
||||||
if (closestDistanceToTarget > distanceFromPathEndToTarget)
|
BattleBotWaypoint& endPoint = ((*path)[path->size() - 1]);
|
||||||
|
float const endPointDistToDestination = sqrt(Position(pos.x, pos.y, pos.z, 0.f).GetExactDist(endPoint.x, endPoint.y, endPoint.z));
|
||||||
|
|
||||||
|
bool reverse = startPointDistToDestination < endPointDistToDestination;
|
||||||
|
|
||||||
|
// dont travel reverse if it's a reverse paths
|
||||||
|
if (reverse && std::find(vPaths_NoReverseAllowed.begin(), vPaths_NoReverseAllowed.end(), path) != vPaths_NoReverseAllowed.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int closestPointIndex = -1;
|
||||||
|
float closestPointDistToBot = FLT_MAX;
|
||||||
|
for (uint32 i = 0; i < path->size(); i++)
|
||||||
{
|
{
|
||||||
float closestDistanceFromMeToPoint = FLT_MAX;
|
BattleBotWaypoint& waypoint = ((*path)[i]);
|
||||||
|
float const distToBot = sqrt(bot->GetDistance(waypoint.x, waypoint.y, waypoint.z));
|
||||||
for (uint32 i = 0; i < pPath->size(); i++)
|
if (closestPointDistToBot > distToBot)
|
||||||
{
|
{
|
||||||
BattleBotWaypoint& waypoint = ((*pPath)[i]);
|
closestPointDistToBot = distToBot;
|
||||||
float const distanceFromMeToPoint = sqrt(bot->GetDistance(waypoint.x, waypoint.y, waypoint.z));
|
closestPointIndex = i;
|
||||||
if (distanceFromMeToPoint < maxDistanceToPoint && closestDistanceFromMeToPoint > distanceFromMeToPoint)
|
|
||||||
{
|
|
||||||
reverse = false;
|
|
||||||
pClosestPath = pPath;
|
|
||||||
closestPoint = i;
|
|
||||||
closestDistanceToTarget = distanceFromPathEndToTarget;
|
|
||||||
closestDistanceFromMeToPoint = distanceFromMeToPoint;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip no reverse paths
|
// don't pick path where bot is already closest to the paths closest point to target (it means path cant lead it anywhere)
|
||||||
if (std::find(vPaths_NoReverseAllowed.begin(), vPaths_NoReverseAllowed.end(), pPath) != vPaths_NoReverseAllowed.end())
|
// don't pick path where closest point is too far away
|
||||||
|
if (closestPointIndex == (reverse ? 0 : path->size() - 1) || closestPointDistToBot > botDistanceLimit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// skip mine paths of own faction
|
|
||||||
if (bot->GetTeamId() == TEAM_ALLIANCE && std::find(vPaths_AllyMine.begin(), vPaths_AllyMine.end(), pPath) != vPaths_AllyMine.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (bot->GetTeamId() == TEAM_HORDE && std::find(vPaths_HordeMine.begin(), vPaths_HordeMine.end(), pPath) != vPaths_HordeMine.end())
|
// creates a score based on dist-to-bot and dist-to-destination, where lower is better, and dist-to-bot is more important (when its beyond a certain distance)
|
||||||
continue;
|
// dist-to-bot is more important because otherwise they cant reach it at all (or will fly through air with MM::MovePoint()), also bot may need to use multiple
|
||||||
|
// paths (one after another) anyway
|
||||||
|
float distToDestination = reverse ? startPointDistToDestination : endPointDistToDestination;
|
||||||
|
float pathScore = (closestPointDistToBot < botDistanceScoreSubtract ? 0.0f : ((closestPointDistToBot - botDistanceScoreSubtract) * botDistanceScoreMultiply)) + distToDestination;
|
||||||
|
|
||||||
{
|
//LOG_INFO("playerbots", "bot={}\t{:6.1f}\t{:4.1f}\t{:4.1f}\t{}", bot->GetName(), pathScore, closestPointDistToBot, distToDestination, vPaths_AB_name[pathNum]);
|
||||||
BattleBotWaypoint& firstPoint = ((*pPath)[0]);
|
|
||||||
float const distanceFromPathBeginToTarget = sqrt(Position(pos.x, pos.y, pos.z, 0).GetExactDist(firstPoint.x, firstPoint.y, firstPoint.z));
|
|
||||||
if (closestDistanceToTarget > distanceFromPathBeginToTarget)
|
|
||||||
{
|
|
||||||
float closestDistanceFromMeToPoint = FLT_MAX;
|
|
||||||
|
|
||||||
for (uint32 i = 0; i < pPath->size(); i++)
|
if (chosenPathScore > pathScore) {
|
||||||
{
|
chosenPathScore = pathScore;
|
||||||
BattleBotWaypoint& waypoint = ((*pPath)[i]);
|
chosenPath = path;
|
||||||
float const distanceFromMeToPoint = sqrt(bot->GetDistance(waypoint.x, waypoint.y, waypoint.z));
|
chosenPathPoint = closestPointIndex;
|
||||||
if (distanceFromMeToPoint < maxDistanceToPoint && closestDistanceFromMeToPoint > distanceFromMeToPoint)
|
chosenPathReverse = reverse;
|
||||||
{
|
|
||||||
reverse = true;
|
|
||||||
pClosestPath = pPath;
|
|
||||||
closestPoint = i;
|
|
||||||
closestDistanceToTarget = distanceFromPathBeginToTarget;
|
|
||||||
closestDistanceFromMeToPoint = distanceFromMeToPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pClosestPath)
|
if (!chosenPath)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Prevent picking last point of path.
|
//LOG_INFO("playerbots", "bot={} {}", bot->GetName(), vPaths_AB_name[chosenPathNum]);
|
||||||
// It means we are already there.
|
|
||||||
if (reverse)
|
|
||||||
{
|
|
||||||
if (closestPoint == 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (closestPoint == pClosestPath->size() - 1)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BattleBotPath* currentPath = pClosestPath;
|
return moveToObjectiveWp(chosenPath, chosenPathPoint, chosenPathReverse);
|
||||||
uint32 currentPoint = reverse ? closestPoint + 1 : closestPoint - 1;
|
|
||||||
|
|
||||||
return moveToObjectiveWp(currentPath, currentPoint, reverse);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4961,9 +4974,9 @@ bool ArenaTactics::moveToCenter(Battleground* bg)
|
|||||||
case BATTLEGROUND_DS:
|
case BATTLEGROUND_DS:
|
||||||
if (!MoveTo(bg->GetMapId(), 1291.58f + frand(-5, +5), 790.87f + frand(-5, +5), 7.8f, false, true)) {
|
if (!MoveTo(bg->GetMapId(), 1291.58f + frand(-5, +5), 790.87f + frand(-5, +5), 7.8f, false, true)) {
|
||||||
// they like to hang around at the tip of the pipes doing nothing, so we just teleport them down
|
// they like to hang around at the tip of the pipes doing nothing, so we just teleport them down
|
||||||
if (bot->GetDistance(1333.07f, 817.18f, 13.35f) < 2)
|
if (bot->GetDistance(1333.07f, 817.18f, 13.35f) < 4)
|
||||||
bot->TeleportTo(bg->GetMapId(), 1330.96f, 816.75f, 3.2f, bot->GetOrientation());
|
bot->TeleportTo(bg->GetMapId(), 1330.96f, 816.75f, 3.2f, bot->GetOrientation());
|
||||||
if (bot->GetDistance(1250.13f, 764.79f, 13.34f) < 2)
|
if (bot->GetDistance(1250.13f, 764.79f, 13.34f) < 4)
|
||||||
bot->TeleportTo(bg->GetMapId(), 1252.19f, 765.41f, 3.2f, bot->GetOrientation());
|
bot->TeleportTo(bg->GetMapId(), 1252.19f, 765.41f, 3.2f, bot->GetOrientation());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -163,7 +163,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
// }
|
// }
|
||||||
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
||||||
!bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
|
!bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
|
||||||
if (!generatePath) {
|
bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 ||
|
||||||
|
(sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground());
|
||||||
|
if (disableMoveSplinePath || !generatePath) {
|
||||||
float distance = bot->GetExactDist(x, y, z);
|
float distance = bot->GetExactDist(x, y, z);
|
||||||
if (distance > sPlayerbotAIConfig->contactDistance)
|
if (distance > sPlayerbotAIConfig->contactDistance)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -179,28 +179,25 @@ bool SummonAction::Teleport(Player* summoner, Player* player)
|
|||||||
if (sPlayerbotAIConfig->botRepairWhenSummon) // .conf option to repair bot gear when summoned 0 = off, 1 = on
|
if (sPlayerbotAIConfig->botRepairWhenSummon) // .conf option to repair bot gear when summoned 0 = off, 1 = on
|
||||||
bot->DurabilityRepairAll(false, 1.0f, false);
|
bot->DurabilityRepairAll(false, 1.0f, false);
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->botReviveWhenSummon < 2)
|
if (master->IsInCombat() && !sPlayerbotAIConfig->allowSummonInCombat)
|
||||||
{
|
{
|
||||||
if (master->IsInCombat())
|
botAI->TellError("You cannot summon me while you're in combat");
|
||||||
{
|
return false;
|
||||||
botAI->TellError("You cannot summon me while you're in combat");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!master->IsAlive())
|
|
||||||
{
|
|
||||||
botAI->TellError("You cannot summon me while you're dead");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST))
|
|
||||||
{
|
|
||||||
botAI->TellError("You cannot summon me while I'm dead, you need to release my spirit first");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->botReviveWhenSummon > 0 && bot->isDead())
|
if (!master->IsAlive() && !sPlayerbotAIConfig->allowSummonWhenMasterIsDead)
|
||||||
|
{
|
||||||
|
botAI->TellError("You cannot summon me while you're dead");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST) && !sPlayerbotAIConfig->allowSummonWhenBotIsDead)
|
||||||
|
{
|
||||||
|
botAI->TellError("You cannot summon me while I'm dead, you need to release my spirit first");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sPlayerbotAIConfig->botReviveWhenSummon == 2 || (sPlayerbotAIConfig->botReviveWhenSummon == 1 && !master->IsInCombat() && master->IsAlive()))
|
||||||
{
|
{
|
||||||
bot->ResurrectPlayer(1.0f, false);
|
bot->ResurrectPlayer(1.0f, false);
|
||||||
botAI->TellMasterNoFacing("I live, again!");
|
botAI->TellMasterNoFacing("I live, again!");
|
||||||
|
|||||||
@@ -47,8 +47,21 @@ GuidVector AttackersValue::Calculate()
|
|||||||
|
|
||||||
if (bot->duel && bot->duel->Opponent)
|
if (bot->duel && bot->duel->Opponent)
|
||||||
result.push_back(bot->duel->Opponent->GetGUID());
|
result.push_back(bot->duel->Opponent->GetGUID());
|
||||||
|
|
||||||
return result;
|
// workaround for bots of same faction not fighting in arena
|
||||||
|
if (bot->InArena())
|
||||||
|
{
|
||||||
|
GuidVector possibleTargets = AI_VALUE(GuidVector, "possible targets");
|
||||||
|
for (ObjectGuid const guid : possibleTargets)
|
||||||
|
{
|
||||||
|
Unit* unit = botAI->GetUnit(guid);
|
||||||
|
if (unit && unit->IsPlayer() && IsValidTarget(unit, bot)) {
|
||||||
|
result.push_back(unit->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttackersValue::AddAttackersOf(Group* group, std::unordered_set<Unit*>& targets)
|
void AttackersValue::AddAttackersOf(Group* group, std::unordered_set<Unit*>& targets)
|
||||||
|
|||||||
Reference in New Issue
Block a user