diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 5394959f..3c610ad0 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1441,7 +1441,7 @@ bool PlayerbotAI::IsCaster(Player* player) { return IsRanged(player) && player-> bool PlayerbotAI::IsCombo(Player* player) { - int tab = AiFactory::GetPlayerSpecTab(player); + // int tab = AiFactory::GetPlayerSpecTab(player); return player->getClass() == CLASS_ROGUE || (player->getClass() == CLASS_DRUID && player->HasAura(768)); // cat druid } @@ -2634,8 +2634,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) return true; } - aiObjectContext->GetValue("last movement")->Get().Set(nullptr); - aiObjectContext->GetValue("stay time")->Set(0); + // aiObjectContext->GetValue("last movement")->Get().Set(nullptr); + // aiObjectContext->GetValue("stay time")->Set(0); if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) { @@ -2820,8 +2820,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, float x, float y, float z, Item* ite return true; } - aiObjectContext->GetValue("last movement")->Get().Set(nullptr); - aiObjectContext->GetValue("stay time")->Set(0); + // aiObjectContext->GetValue("last movement")->Get().Set(nullptr); + // aiObjectContext->GetValue("stay time")->Set(0); MotionMaster& mm = *bot->GetMotionMaster(); diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 12909414..6a51fd92 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -19,9 +19,9 @@ bool CheckMountStateAction::Execute(Event event) bool enemy = AI_VALUE(Unit*, "enemy player target"); // ignore grind target in BG or bots will dismount near any creature (eg: the rams in AV) bool dps = AI_VALUE(Unit*, "dps target"); - bool fartarget = - (enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player target"), 40.0f)) || - (dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f)); + // bool fartarget = (enemy && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "enemy player + // target"), 40.0f)) || + // (dps && sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "dps target"), 50.0f)); bool attackdistance = false; // bool chasedistance = false; float attack_distance = 35.0f; @@ -34,6 +34,9 @@ bool CheckMountStateAction::Execute(Event event) attack_distance = 30.0f; } + // if (enemy) + // attack_distance /= 2; + if (dps || enemy) { Unit* currentTarget = AI_VALUE(Unit*, "current target"); @@ -91,8 +94,7 @@ bool CheckMountStateAction::Execute(Event event) } } - if (bot->InBattleground() && !attackdistance && (noattackers || fartarget) && !bot->IsInCombat() && - !bot->IsMounted()) + if (bot->InBattleground() && !attackdistance && noattackers && !bot->IsInCombat() && !bot->IsMounted()) { if (bot->GetBattlegroundTypeId() == BATTLEGROUND_WS) { diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 670735e4..eba8022d 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -68,7 +68,7 @@ void MovementAction::JumpTo(uint32 mapId, float x, float y, float z) 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()); + AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), 1000); } bool MovementAction::MoveNear(uint32 mapId, float x, float y, float z, float distance) @@ -167,6 +167,14 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, { return false; } + if (IsDuplicateMove(mapId, x, y, z)) + { + return false; + } + if (IsWaitingForLastMove()) + { + return false; + } // if (bot->Unit::IsFalling()) { // bot->Say("I'm falling!, flag:" + std::to_string(bot->m_movementInfo.GetMovementFlags()), LANG_UNIVERSAL); // return false; @@ -177,8 +185,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, // if (bot->Unit::IsFalling()) { // bot->Say("I'm falling", LANG_UNIVERSAL); // } - bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->IsFlying() && - !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater(); + // !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && + + bool generatePath = !bot->IsFlying() && !bot->isSwimming(); bool disableMoveSplinePath = sPlayerbotAIConfig->disableMoveSplinePath >= 2 || (sPlayerbotAIConfig->disableMoveSplinePath == 1 && bot->InBattleground()); if (disableMoveSplinePath || !generatePath) @@ -186,8 +195,6 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, float distance = bot->GetExactDist(x, y, z); if (distance > sPlayerbotAIConfig->contactDistance) { - WaitForReach(distance); - if (bot->IsSitState()) bot->SetStandState(UNIT_STAND_STATE_STAND); @@ -199,7 +206,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, MotionMaster& mm = *bot->GetMotionMaster(); mm.Clear(); mm.MovePoint(mapId, x, y, z, generatePath); - AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); + float delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, 1000.0f * MoveDelay(distance)); + AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay); return true; } } @@ -215,8 +223,6 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, float distance = bot->GetExactDist(x, y, modifiedZ); if (distance > sPlayerbotAIConfig->contactDistance) { - WaitForReach(distance); - if (bot->IsSitState()) bot->SetStandState(UNIT_STAND_STATE_STAND); @@ -229,7 +235,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, mm.Clear(); mm.MoveSplinePath(&path); - AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); + // mm.MoveSplinePath(&path); + float delay = std::min((float)sPlayerbotAIConfig->maxWaitForMove, 1000.0f * MoveDelay(distance)); + AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay); return true; } } @@ -847,6 +855,29 @@ bool MovementAction::IsMovingAllowed(uint32 mapId, float x, float y, float z) return IsMovingAllowed(); } +bool MovementAction::IsDuplicateMove(uint32 mapId, float x, float y, float z) +{ + LastMovement& lastMove = *context->GetValue("last movement"); + + // heuristic 5s + if (lastMove.msTime + sPlayerbotAIConfig->maxWaitForMove < getMSTime() || + lastMove.lastMoveShort.GetExactDist(x, y, z) > 0.01f) + return false; + + return true; +} + +bool MovementAction::IsWaitingForLastMove() +{ + LastMovement& lastMove = *context->GetValue("last movement"); + + // heuristic 5s + if (lastMove.lastdelayTime + lastMove.msTime > getMSTime()) + return true; + + return false; +} + bool MovementAction::IsMovingAllowed() { // do not allow if not vehicle driver @@ -878,7 +909,7 @@ void MovementAction::UpdateMovementState() { bot->SetSwim(true); } - else + else if (!bot->Unit::IsInWater()) { bot->SetSwim(false); } diff --git a/src/strategy/actions/MovementActions.h b/src/strategy/actions/MovementActions.h index c0a5b888..d8b178c2 100644 --- a/src/strategy/actions/MovementActions.h +++ b/src/strategy/actions/MovementActions.h @@ -39,6 +39,8 @@ protected: void WaitForReach(float distance); bool IsMovingAllowed(Unit* target); bool IsMovingAllowed(uint32 mapId, float x, float y, float z); + bool IsDuplicateMove(uint32 mapId, float x, float y, float z); + bool IsWaitingForLastMove(); bool IsMovingAllowed(); bool Flee(Unit* target); void ClearIdleState(); diff --git a/src/strategy/triggers/TriggerContext.h b/src/strategy/triggers/TriggerContext.h index e0b7ce99..2b5cbd06 100644 --- a/src/strategy/triggers/TriggerContext.h +++ b/src/strategy/triggers/TriggerContext.h @@ -183,202 +183,203 @@ public: creators["petition signed"] = &TriggerContext::petition_signed; creators["buy tabard"] = &TriggerContext::buy_tabard; creators["leave large guild"] = &TriggerContext::leave_large_guild; - - creators["rpg"] = &TriggerContext::rpg; - creators["rpg taxi"] = &TriggerContext::rpg_taxi; - creators["rpg discover"] = &TriggerContext::rpg_discover; - creators["rpg start quest"] = &TriggerContext::rpg_start_quest; - creators["rpg end quest"] = &TriggerContext::rpg_end_quest; - creators["rpg buy"] = &TriggerContext::rpg_buy; - creators["rpg sell"] = &TriggerContext::rpg_sell; - creators["rpg repair"] = &TriggerContext::rpg_repair; - creators["rpg train"] = &TriggerContext::rpg_train; - creators["rpg heal"] = &TriggerContext::rpg_heal; - creators["rpg home bind"] = &TriggerContext::rpg_home_bind; - creators["rpg queue bg"] = &TriggerContext::rpg_queue_bg; - creators["rpg buy petition"] = &TriggerContext::rpg_buy_petition; - creators["rpg use"] = &TriggerContext::rpg_use; - creators["rpg spell"] = &TriggerContext::rpg_spell; - creators["rpg craft"] = &TriggerContext::rpg_craft; - creators["rpg trade useful"] = &TriggerContext::rpg_trade_useful; - creators["rpg duel"] = &TriggerContext::rpg_duel; } - -private: - static Trigger* give_food(PlayerbotAI* botAI) { return new GiveFoodTrigger(botAI); } - static Trigger* give_water(PlayerbotAI* botAI) { return new GiveWaterTrigger(botAI); } - static Trigger* no_rti(PlayerbotAI* botAI) { return new NoRtiTrigger(botAI); } - static Trigger* _return(PlayerbotAI* botAI) { return new ReturnTrigger(botAI); } - static Trigger* sit(PlayerbotAI* botAI) { return new SitTrigger(botAI); } - static Trigger* far_from_rpg_target(PlayerbotAI* botAI) { return new FarFromRpgTargetTrigger(botAI); } - static Trigger* near_rpg_target(PlayerbotAI* botAI) { return new NearRpgTargetTrigger(botAI); } - static Trigger* far_from_travel_target(PlayerbotAI* botAI) { return new FarFromTravelTargetTrigger(botAI); } - static Trigger* no_travel_target(PlayerbotAI* botAI) { return new NoTravelTargetTrigger(botAI); } - static Trigger* no_rpg_target(PlayerbotAI* botAI) { return new NoRpgTargetTrigger(botAI); } - static Trigger* has_rpg_target(PlayerbotAI* botAI) { return new HasRpgTargetTrigger(botAI); } - static Trigger* collision(PlayerbotAI* botAI) { return new CollisionTrigger(botAI); } - static Trigger* lfg_proposal_active(PlayerbotAI* botAI) { return new LfgProposalActiveTrigger(botAI); } - static Trigger* unknown_dungeon(PlayerbotAI* botAI) { return new UnknownDungeonTrigger(botAI); } - static Trigger* invalid_target(PlayerbotAI* botAI) { return new InvalidTargetTrigger(botAI); } - static Trigger* critical_aoe_heal(PlayerbotAI* botAI) - { - return new AoeHealTrigger(botAI, "critical aoe heal", "critical", 2); - } - static Trigger* low_aoe_heal(PlayerbotAI* botAI) { return new AoeHealTrigger(botAI, "low aoe heal", "low", 2); } - static Trigger* medium_aoe_heal(PlayerbotAI* botAI) - { - return new AoeHealTrigger(botAI, "medium aoe heal", "medium", 2); - } - static Trigger* almost_full_aoe_heal(PlayerbotAI* botAI) - { - return new AoeHealTrigger(botAI, "almost full aoe heal", "almost full", 2); - } - static Trigger* group_heal_occasion(PlayerbotAI* ai) - { - return new AoeInGroupTrigger(ai, "group heal occasion", "almost full", 0.6); - } - static Trigger* medium_group_heal_occasion(PlayerbotAI* ai) - { - return new AoeInGroupTrigger(ai, "group heal occasion", "medium", 0.4); - } - static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); } - static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); } - static Trigger* no_possible_targets(PlayerbotAI* botAI) { return new NoPossibleTargetsTrigger(botAI); } - static Trigger* possible_adds(PlayerbotAI* botAI) { return new PossibleAddsTrigger(botAI); } - static Trigger* can_loot(PlayerbotAI* botAI) { return new CanLootTrigger(botAI); } - static Trigger* far_from_loot_target(PlayerbotAI* botAI) { return new FarFromCurrentLootTrigger(botAI); } - static Trigger* far_from_master(PlayerbotAI* botAI) { return new FarFromMasterTrigger(botAI); } - static Trigger* behind_target(PlayerbotAI* botAI) { return new IsBehindTargetTrigger(botAI); } - static Trigger* not_behind_target(PlayerbotAI* botAI) { return new IsNotBehindTargetTrigger(botAI); } - static Trigger* not_facing_target(PlayerbotAI* botAI) { return new IsNotFacingTargetTrigger(botAI); } - static Trigger* panic(PlayerbotAI* botAI) { return new PanicTrigger(botAI); } - static Trigger* outnumbered(PlayerbotAI* botAI) { return new OutNumberedTrigger(botAI); } - static Trigger* no_drink(PlayerbotAI* botAI) { return new NoDrinkTrigger(botAI); } - static Trigger* no_food(PlayerbotAI* botAI) { return new NoFoodTrigger(botAI); } - static Trigger* LightAoe(PlayerbotAI* botAI) { return new LightAoeTrigger(botAI); } - static Trigger* MediumAoe(PlayerbotAI* botAI) { return new MediumAoeTrigger(botAI); } - static Trigger* HighAoe(PlayerbotAI* botAI) { return new HighAoeTrigger(botAI); } - static Trigger* HasAreaDebuff(PlayerbotAI* botAI) { return new HasAreaDebuffTrigger(botAI); } - static Trigger* LoseAggro(PlayerbotAI* botAI) { return new LoseAggroTrigger(botAI); } - static Trigger* HasAggro(PlayerbotAI* botAI) { return new HasAggroTrigger(botAI); } - static Trigger* LowHealth(PlayerbotAI* botAI) { return new LowHealthTrigger(botAI); } - static Trigger* MediumHealth(PlayerbotAI* botAI) { return new MediumHealthTrigger(botAI); } - static Trigger* AlmostFullHealth(PlayerbotAI* botAI) { return new AlmostFullHealthTrigger(botAI); } - static Trigger* CriticalHealth(PlayerbotAI* botAI) { return new CriticalHealthTrigger(botAI); } - static Trigger* TargetCriticalHealth(PlayerbotAI* botAI) { return new TargetCriticalHealthTrigger(botAI); } - static Trigger* LowMana(PlayerbotAI* botAI) { return new LowManaTrigger(botAI); } - static Trigger* MediumMana(PlayerbotAI* botAI) { return new MediumManaTrigger(botAI); } - static Trigger* HighMana(PlayerbotAI* botAI) { return new HighManaTrigger(botAI); } - static Trigger* AlmostFullMana(PlayerbotAI* botAI) { return new AlmostFullManaTrigger(botAI); } - static Trigger* EnoughMana(PlayerbotAI* botAI) { return new EnoughManaTrigger(botAI); } - static Trigger* LightRageAvailable(PlayerbotAI* botAI) { return new LightRageAvailableTrigger(botAI); } - static Trigger* MediumRageAvailable(PlayerbotAI* botAI) { return new MediumRageAvailableTrigger(botAI); } - static Trigger* HighRageAvailable(PlayerbotAI* botAI) { return new HighRageAvailableTrigger(botAI); } - static Trigger* LightEnergyAvailable(PlayerbotAI* botAI) { return new LightEnergyAvailableTrigger(botAI); } - static Trigger* MediumEnergyAvailable(PlayerbotAI* botAI) { return new MediumEnergyAvailableTrigger(botAI); } - static Trigger* HighEnergyAvailable(PlayerbotAI* botAI) { return new HighEnergyAvailableTrigger(botAI); } - static Trigger* LootAvailable(PlayerbotAI* botAI) { return new LootAvailableTrigger(botAI); } - static Trigger* NoAttackers(PlayerbotAI* botAI) { return new NoAttackersTrigger(botAI); } - static Trigger* TankAssist(PlayerbotAI* botAI) { return new TankAssistTrigger(botAI); } - static Trigger* Timer(PlayerbotAI* botAI) { return new TimerTrigger(botAI); } - static Trigger* NoTarget(PlayerbotAI* botAI) { return new NoTargetTrigger(botAI); } - static Trigger* TargetInSight(PlayerbotAI* botAI) { return new TargetInSightTrigger(botAI); } - static Trigger* not_dps_target_active(PlayerbotAI* botAI) { return new NotDpsTargetActiveTrigger(botAI); } - static Trigger* not_dps_aoe_target_active(PlayerbotAI* botAI) { return new NotDpsAoeTargetActiveTrigger(botAI); } - static Trigger* has_nearest_adds(PlayerbotAI* botAI) { return new HasNearestAddsTrigger(botAI); } - static Trigger* enemy_player_near(PlayerbotAI* botAI) { return new EnemyPlayerNear(botAI); } - static Trigger* Random(PlayerbotAI* botAI) { return new RandomTrigger(botAI, "random", 20); } - static Trigger* seldom(PlayerbotAI* botAI) { return new RandomTrigger(botAI, "seldom", 300); } - static Trigger* often(PlayerbotAI* botAI) { return new RandomTrigger(botAI, "often", 5); } - static Trigger* EnemyOutOfMelee(PlayerbotAI* botAI) { return new EnemyOutOfMeleeTrigger(botAI); } - static Trigger* EnemyOutOfSpell(PlayerbotAI* botAI) { return new EnemyOutOfSpellRangeTrigger(botAI); } - static Trigger* enemy_too_close_for_spell(PlayerbotAI* botAI) { return new EnemyTooCloseForSpellTrigger(botAI); } - static Trigger* enemy_too_close_for_auto_shot(PlayerbotAI* botAI) - { - return new EnemyTooCloseForAutoShotTrigger(botAI); - } - static Trigger* enemy_too_close_for_shoot(PlayerbotAI* botAI) { return new EnemyTooCloseForShootTrigger(botAI); } - static Trigger* enemy_too_close_for_melee(PlayerbotAI* botAI) { return new EnemyTooCloseForMeleeTrigger(botAI); } - static Trigger* enemy_is_close(PlayerbotAI* botAI) { return new EnemyIsCloseTrigger(botAI); } - static Trigger* enemy_within_melee(PlayerbotAI* botAI) { return new EnemyWithinMeleeTrigger(botAI); } - static Trigger* party_member_to_heal_out_of_spell_range(PlayerbotAI* botAI) - { - return new PartyMemberToHealOutOfSpellRangeTrigger(botAI); - } - static Trigger* ComboPointsAvailable(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI); } - static Trigger* ComboPoints3Available(PlayerbotAI* botAI) { return new ComboPointsAvailableTrigger(botAI, 3); } - static Trigger* MediumThreat(PlayerbotAI* botAI) { return new MediumThreatTrigger(botAI); } - static Trigger* Dead(PlayerbotAI* botAI) { return new DeadTrigger(botAI); } - static Trigger* corpse_near(PlayerbotAI* botAI) { return new CorpseNearTrigger(botAI); } - static Trigger* PartyMemberDead(PlayerbotAI* botAI) { return new PartyMemberDeadTrigger(botAI); } - static Trigger* CombatPartyMemberDead(PlayerbotAI* botAI) { return new CombatPartyMemberDeadTrigger(botAI); } - static Trigger* PartyMemberLowHealth(PlayerbotAI* botAI) { return new PartyMemberLowHealthTrigger(botAI); } - static Trigger* PartyMemberMediumHealth(PlayerbotAI* botAI) { return new PartyMemberMediumHealthTrigger(botAI); } - static Trigger* PartyMemberAlmostFullHealth(PlayerbotAI* botAI) - { - return new PartyMemberAlmostFullHealthTrigger(botAI); - } - static Trigger* PartyMemberCriticalHealth(PlayerbotAI* botAI) - { - return new PartyMemberCriticalHealthTrigger(botAI); - } - static Trigger* protect_party_member(PlayerbotAI* botAI) { return new ProtectPartyMemberTrigger(botAI); } - static Trigger* no_pet(PlayerbotAI* botAI) { return new NoPetTrigger(botAI); } - static Trigger* has_pet(PlayerbotAI* botAI) { return new HasPetTrigger(botAI); } - static Trigger* pet_attack(PlayerbotAI* botAI) { return new PetAttackTrigger(botAI); } - static Trigger* has_attackers(PlayerbotAI* botAI) { return new HasAttackersTrigger(botAI); } - static Trigger* random_bot_update_trigger(PlayerbotAI* botAI) { return new RandomBotUpdateTrigger(botAI); } - static Trigger* no_non_bot_players_around(PlayerbotAI* botAI) { return new NoNonBotPlayersAroundTrigger(botAI); } - static Trigger* new_player_nearby(PlayerbotAI* botAI) { return new NewPlayerNearbyTrigger(botAI); } - static Trigger* bg_waiting(PlayerbotAI* botAI) { return new BgWaitingTrigger(botAI); } - static Trigger* bg_active(PlayerbotAI* botAI) { return new BgActiveTrigger(botAI); } - static Trigger* bg_invite_active(PlayerbotAI* botAI) { return new BgInviteActiveTrigger(botAI); } - static Trigger* inside_bg(PlayerbotAI* botAI) { return new InsideBGTrigger(botAI); } - static Trigger* player_has_no_flag(PlayerbotAI* botAI) { return new PlayerHasNoFlag(botAI); } - static Trigger* player_has_flag(PlayerbotAI* botAI) { return new PlayerHasFlag(botAI); } - static Trigger* team_has_flag(PlayerbotAI* botAI) { return new TeamHasFlag(botAI); } - static Trigger* enemy_team_has_flag(PlayerbotAI* botAI) { return new EnemyTeamHasFlag(botAI); } - static Trigger* enemy_flagcarrier_near(PlayerbotAI* botAI) { return new EnemyFlagCarrierNear(botAI); } - static Trigger* player_is_in_BATTLEGROUND(PlayerbotAI* botAI) { return new PlayerIsInBattleground(botAI); } - static Trigger* player_is_in_BATTLEGROUND_no_flag(PlayerbotAI* botAI) - { - return new PlayerIsInBattlegroundWithoutFlag(botAI); - } - static Trigger* mounted(PlayerbotAI* botAI) { return new IsMountedTrigger(botAI); } - static Trigger* at_dark_portal_outland(PlayerbotAI* botAI) { return new AtDarkPortalOutlandTrigger(botAI); } - static Trigger* at_dark_portal_azeroth(PlayerbotAI* botAI) { return new AtDarkPortalAzerothTrigger(botAI); } - static Trigger* in_vehicle(PlayerbotAI* botAI) { return new InVehicleTrigger(botAI); } - static Trigger* vehicle_near(PlayerbotAI* botAI) { return new VehicleNearTrigger(botAI); } - static Trigger* near_dark_portal(PlayerbotAI* botAI) { return new NearDarkPortalTrigger(botAI); } - static Trigger* need_world_buff(PlayerbotAI* botAI) { return new NeedWorldBuffTrigger(botAI); } - static Trigger* falling(PlayerbotAI* botAI) { return new IsFallingTrigger(botAI); } - static Trigger* falling_far(PlayerbotAI* botAI) { return new IsFallingFarTrigger(botAI); } - static Trigger* move_stuck(PlayerbotAI* botAI) { return new MoveStuckTrigger(botAI); } - static Trigger* move_long_stuck(PlayerbotAI* botAI) { return new MoveLongStuckTrigger(botAI); } - static Trigger* combat_stuck(PlayerbotAI* botAI) { return new CombatStuckTrigger(botAI); } - static Trigger* combat_long_stuck(PlayerbotAI* botAI) { return new CombatLongStuckTrigger(botAI); } - static Trigger* player_wants_in_bg(PlayerbotAI* botAI) { return new PlayerWantsInBattlegroundTrigger(botAI); } - static Trigger* petition_signed(PlayerbotAI* botAI) { return new PetitionTurnInTrigger(botAI); } - static Trigger* buy_tabard(PlayerbotAI* botAI) { return new BuyTabardTrigger(botAI); } - static Trigger* leave_large_guild(PlayerbotAI* botAI) { return new LeaveLargeGuildTrigger(botAI); } - static Trigger* rpg(PlayerbotAI* botAI) { return new RpgTrigger(botAI); } - static Trigger* rpg_taxi(PlayerbotAI* botAI) { return new RpgTaxiTrigger(botAI); } - static Trigger* rpg_discover(PlayerbotAI* botAI) { return new RpgDiscoverTrigger(botAI); } - static Trigger* rpg_start_quest(PlayerbotAI* botAI) { return new RpgStartQuestTrigger(botAI); } - static Trigger* rpg_end_quest(PlayerbotAI* botAI) { return new RpgEndQuestTrigger(botAI); } - static Trigger* rpg_buy(PlayerbotAI* botAI) { return new RpgBuyTrigger(botAI); } - static Trigger* rpg_sell(PlayerbotAI* botAI) { return new RpgSellTrigger(botAI); } - static Trigger* rpg_repair(PlayerbotAI* botAI) { return new RpgRepairTrigger(botAI); } - static Trigger* rpg_train(PlayerbotAI* botAI) { return new RpgTrainTrigger(botAI); } - static Trigger* rpg_heal(PlayerbotAI* botAI) { return new RpgHealTrigger(botAI); } - static Trigger* rpg_home_bind(PlayerbotAI* botAI) { return new RpgHomeBindTrigger(botAI); } - static Trigger* rpg_queue_bg(PlayerbotAI* botAI) { return new RpgQueueBGTrigger(botAI); } - static Trigger* rpg_buy_petition(PlayerbotAI* botAI) { return new RpgBuyPetitionTrigger(botAI); } - static Trigger* rpg_use(PlayerbotAI* botAI) { return new RpgUseTrigger(botAI); } - static Trigger* rpg_spell(PlayerbotAI* botAI) { return new RpgUseTrigger(botAI); } - static Trigger* rpg_craft(PlayerbotAI* botAI) { return new RpgCraftTrigger(botAI); } - static Trigger* rpg_trade_useful(PlayerbotAI* botAI) { return new RpgTradeUsefulTrigger(botAI); } - static Trigger* rpg_duel(PlayerbotAI* botAI) { return new RpgDuelTrigger(botAI); } -}; + private: + static Trigger* give_food(PlayerbotAI * botAI) { return new GiveFoodTrigger(botAI); } + static Trigger* give_water(PlayerbotAI * botAI) { return new GiveWaterTrigger(botAI); } + static Trigger* no_rti(PlayerbotAI * botAI) { return new NoRtiTrigger(botAI); } + static Trigger* _return(PlayerbotAI * botAI) { return new ReturnTrigger(botAI); } + static Trigger* sit(PlayerbotAI * botAI) { return new SitTrigger(botAI); } + static Trigger* far_from_rpg_target(PlayerbotAI * botAI) { return new FarFromRpgTargetTrigger(botAI); } + static Trigger* near_rpg_target(PlayerbotAI * botAI) { return new NearRpgTargetTrigger(botAI); } + static Trigger* far_from_travel_target(PlayerbotAI * botAI) { return new FarFromTravelTargetTrigger(botAI); } + static Trigger* no_travel_target(PlayerbotAI * botAI) { return new NoTravelTargetTrigger(botAI); } + static Trigger* no_rpg_target(PlayerbotAI * botAI) { return new NoRpgTargetTrigger(botAI); } + static Trigger* has_rpg_target(PlayerbotAI * botAI) { return new HasRpgTargetTrigger(botAI); } + static Trigger* collision(PlayerbotAI * botAI) { return new CollisionTrigger(botAI); } + static Trigger* lfg_proposal_active(PlayerbotAI * botAI) { return new LfgProposalActiveTrigger(botAI); } + static Trigger* unknown_dungeon(PlayerbotAI * botAI) { return new UnknownDungeonTrigger(botAI); } + static Trigger* invalid_target(PlayerbotAI * botAI) { return new InvalidTargetTrigger(botAI); } + static Trigger* critical_aoe_heal(PlayerbotAI * botAI) + { + return new AoeHealTrigger(botAI, "critical aoe heal", "critical", 2); + } + static Trigger* low_aoe_heal(PlayerbotAI * botAI) + { + return new AoeHealTrigger(botAI, "low aoe heal", "low", 2); + } + static Trigger* medium_aoe_heal(PlayerbotAI * botAI) + { + return new AoeHealTrigger(botAI, "medium aoe heal", "medium", 2); + } + static Trigger* almost_full_aoe_heal(PlayerbotAI * botAI) + { + return new AoeHealTrigger(botAI, "almost full aoe heal", "almost full", 2); + } + static Trigger* group_heal_occasion(PlayerbotAI * ai) + { + return new AoeInGroupTrigger(ai, "group heal occasion", "almost full", 0.6); + } + static Trigger* medium_group_heal_occasion(PlayerbotAI * ai) + { + return new AoeInGroupTrigger(ai, "group heal occasion", "medium", 0.6); + } + static Trigger* target_changed(PlayerbotAI * botAI) { return new TargetChangedTrigger(botAI); } + static Trigger* swimming(PlayerbotAI * botAI) { return new IsSwimmingTrigger(botAI); } + static Trigger* no_possible_targets(PlayerbotAI * botAI) { return new NoPossibleTargetsTrigger(botAI); } + static Trigger* possible_adds(PlayerbotAI * botAI) { return new PossibleAddsTrigger(botAI); } + static Trigger* can_loot(PlayerbotAI * botAI) { return new CanLootTrigger(botAI); } + static Trigger* far_from_loot_target(PlayerbotAI * botAI) { return new FarFromCurrentLootTrigger(botAI); } + static Trigger* far_from_master(PlayerbotAI * botAI) { return new FarFromMasterTrigger(botAI); } + static Trigger* behind_target(PlayerbotAI * botAI) { return new IsBehindTargetTrigger(botAI); } + static Trigger* not_behind_target(PlayerbotAI * botAI) { return new IsNotBehindTargetTrigger(botAI); } + static Trigger* not_facing_target(PlayerbotAI * botAI) { return new IsNotFacingTargetTrigger(botAI); } + static Trigger* panic(PlayerbotAI * botAI) { return new PanicTrigger(botAI); } + static Trigger* outnumbered(PlayerbotAI * botAI) { return new OutNumberedTrigger(botAI); } + static Trigger* no_drink(PlayerbotAI * botAI) { return new NoDrinkTrigger(botAI); } + static Trigger* no_food(PlayerbotAI * botAI) { return new NoFoodTrigger(botAI); } + static Trigger* LightAoe(PlayerbotAI * botAI) { return new LightAoeTrigger(botAI); } + static Trigger* MediumAoe(PlayerbotAI * botAI) { return new MediumAoeTrigger(botAI); } + static Trigger* HighAoe(PlayerbotAI * botAI) { return new HighAoeTrigger(botAI); } + static Trigger* HasAreaDebuff(PlayerbotAI * botAI) { return new HasAreaDebuffTrigger(botAI); } + static Trigger* LoseAggro(PlayerbotAI * botAI) { return new LoseAggroTrigger(botAI); } + static Trigger* HasAggro(PlayerbotAI * botAI) { return new HasAggroTrigger(botAI); } + static Trigger* LowHealth(PlayerbotAI * botAI) { return new LowHealthTrigger(botAI); } + static Trigger* MediumHealth(PlayerbotAI * botAI) { return new MediumHealthTrigger(botAI); } + static Trigger* AlmostFullHealth(PlayerbotAI * botAI) { return new AlmostFullHealthTrigger(botAI); } + static Trigger* CriticalHealth(PlayerbotAI * botAI) { return new CriticalHealthTrigger(botAI); } + static Trigger* TargetCriticalHealth(PlayerbotAI * botAI) { return new TargetCriticalHealthTrigger(botAI); } + static Trigger* LowMana(PlayerbotAI * botAI) { return new LowManaTrigger(botAI); } + static Trigger* MediumMana(PlayerbotAI * botAI) { return new MediumManaTrigger(botAI); } + static Trigger* HighMana(PlayerbotAI * botAI) { return new HighManaTrigger(botAI); } + static Trigger* AlmostFullMana(PlayerbotAI * botAI) { return new AlmostFullManaTrigger(botAI); } + static Trigger* EnoughMana(PlayerbotAI * botAI) { return new EnoughManaTrigger(botAI); } + static Trigger* LightRageAvailable(PlayerbotAI * botAI) { return new LightRageAvailableTrigger(botAI); } + static Trigger* MediumRageAvailable(PlayerbotAI * botAI) { return new MediumRageAvailableTrigger(botAI); } + static Trigger* HighRageAvailable(PlayerbotAI * botAI) { return new HighRageAvailableTrigger(botAI); } + static Trigger* LightEnergyAvailable(PlayerbotAI * botAI) { return new LightEnergyAvailableTrigger(botAI); } + static Trigger* MediumEnergyAvailable(PlayerbotAI * botAI) { return new MediumEnergyAvailableTrigger(botAI); } + static Trigger* HighEnergyAvailable(PlayerbotAI * botAI) { return new HighEnergyAvailableTrigger(botAI); } + static Trigger* LootAvailable(PlayerbotAI * botAI) { return new LootAvailableTrigger(botAI); } + static Trigger* NoAttackers(PlayerbotAI * botAI) { return new NoAttackersTrigger(botAI); } + static Trigger* TankAssist(PlayerbotAI * botAI) { return new TankAssistTrigger(botAI); } + static Trigger* Timer(PlayerbotAI * botAI) { return new TimerTrigger(botAI); } + static Trigger* NoTarget(PlayerbotAI * botAI) { return new NoTargetTrigger(botAI); } + static Trigger* TargetInSight(PlayerbotAI * botAI) { return new TargetInSightTrigger(botAI); } + static Trigger* not_dps_target_active(PlayerbotAI * botAI) { return new NotDpsTargetActiveTrigger(botAI); } + static Trigger* not_dps_aoe_target_active(PlayerbotAI * botAI) + { + return new NotDpsAoeTargetActiveTrigger(botAI); + } + static Trigger* has_nearest_adds(PlayerbotAI * botAI) { return new HasNearestAddsTrigger(botAI); } + static Trigger* enemy_player_near(PlayerbotAI * botAI) { return new EnemyPlayerNear(botAI); } + static Trigger* Random(PlayerbotAI * botAI) { return new RandomTrigger(botAI, "random", 20); } + static Trigger* seldom(PlayerbotAI * botAI) { return new RandomTrigger(botAI, "seldom", 300); } + static Trigger* often(PlayerbotAI * botAI) { return new RandomTrigger(botAI, "often", 5); } + static Trigger* EnemyOutOfMelee(PlayerbotAI * botAI) { return new EnemyOutOfMeleeTrigger(botAI); } + static Trigger* EnemyOutOfSpell(PlayerbotAI * botAI) { return new EnemyOutOfSpellRangeTrigger(botAI); } + static Trigger* enemy_too_close_for_spell(PlayerbotAI * botAI) + { + return new EnemyTooCloseForSpellTrigger(botAI); + } + static Trigger* enemy_too_close_for_auto_shot(PlayerbotAI * botAI) + { + return new EnemyTooCloseForAutoShotTrigger(botAI); + } + static Trigger* enemy_too_close_for_shoot(PlayerbotAI * botAI) + { + return new EnemyTooCloseForShootTrigger(botAI); + } + static Trigger* enemy_too_close_for_melee(PlayerbotAI * botAI) + { + return new EnemyTooCloseForMeleeTrigger(botAI); + } + static Trigger* enemy_is_close(PlayerbotAI * botAI) { return new EnemyIsCloseTrigger(botAI); } + static Trigger* enemy_within_melee(PlayerbotAI * botAI) { return new EnemyWithinMeleeTrigger(botAI); } + static Trigger* party_member_to_heal_out_of_spell_range(PlayerbotAI * botAI) + { + return new PartyMemberToHealOutOfSpellRangeTrigger(botAI); + } + static Trigger* ComboPointsAvailable(PlayerbotAI * botAI) { return new ComboPointsAvailableTrigger(botAI); } + static Trigger* ComboPoints3Available(PlayerbotAI * botAI) { return new ComboPointsAvailableTrigger(botAI, 3); } + static Trigger* MediumThreat(PlayerbotAI * botAI) { return new MediumThreatTrigger(botAI); } + static Trigger* Dead(PlayerbotAI * botAI) { return new DeadTrigger(botAI); } + static Trigger* corpse_near(PlayerbotAI * botAI) { return new CorpseNearTrigger(botAI); } + static Trigger* PartyMemberDead(PlayerbotAI * botAI) { return new PartyMemberDeadTrigger(botAI); } + static Trigger* CombatPartyMemberDead(PlayerbotAI * botAI) { return new CombatPartyMemberDeadTrigger(botAI); } + static Trigger* PartyMemberLowHealth(PlayerbotAI * botAI) { return new PartyMemberLowHealthTrigger(botAI); } + static Trigger* PartyMemberMediumHealth(PlayerbotAI * botAI) + { + return new PartyMemberMediumHealthTrigger(botAI); + } + static Trigger* PartyMemberAlmostFullHealth(PlayerbotAI * botAI) + { + return new PartyMemberAlmostFullHealthTrigger(botAI); + } + static Trigger* PartyMemberCriticalHealth(PlayerbotAI * botAI) + { + return new PartyMemberCriticalHealthTrigger(botAI); + } + static Trigger* protect_party_member(PlayerbotAI * botAI) { return new ProtectPartyMemberTrigger(botAI); } + static Trigger* no_pet(PlayerbotAI * botAI) { return new NoPetTrigger(botAI); } + static Trigger* has_pet(PlayerbotAI * botAI) { return new HasPetTrigger(botAI); } + static Trigger* pet_attack(PlayerbotAI * botAI) { return new PetAttackTrigger(botAI); } + static Trigger* has_attackers(PlayerbotAI * botAI) { return new HasAttackersTrigger(botAI); } + static Trigger* random_bot_update_trigger(PlayerbotAI * botAI) { return new RandomBotUpdateTrigger(botAI); } + static Trigger* no_non_bot_players_around(PlayerbotAI * botAI) + { + return new NoNonBotPlayersAroundTrigger(botAI); + } + static Trigger* new_player_nearby(PlayerbotAI * botAI) { return new NewPlayerNearbyTrigger(botAI); } + static Trigger* bg_waiting(PlayerbotAI * botAI) { return new BgWaitingTrigger(botAI); } + static Trigger* bg_active(PlayerbotAI * botAI) { return new BgActiveTrigger(botAI); } + static Trigger* bg_invite_active(PlayerbotAI * botAI) { return new BgInviteActiveTrigger(botAI); } + static Trigger* inside_bg(PlayerbotAI * botAI) { return new InsideBGTrigger(botAI); } + static Trigger* player_has_no_flag(PlayerbotAI * botAI) { return new PlayerHasNoFlag(botAI); } + static Trigger* player_has_flag(PlayerbotAI * botAI) { return new PlayerHasFlag(botAI); } + static Trigger* team_has_flag(PlayerbotAI * botAI) { return new TeamHasFlag(botAI); } + static Trigger* enemy_team_has_flag(PlayerbotAI * botAI) { return new EnemyTeamHasFlag(botAI); } + static Trigger* enemy_flagcarrier_near(PlayerbotAI * botAI) { return new EnemyFlagCarrierNear(botAI); } + static Trigger* player_is_in_BATTLEGROUND(PlayerbotAI * botAI) { return new PlayerIsInBattleground(botAI); } + static Trigger* player_is_in_BATTLEGROUND_no_flag(PlayerbotAI * botAI) + { + return new PlayerIsInBattlegroundWithoutFlag(botAI); + } + static Trigger* mounted(PlayerbotAI * botAI) { return new IsMountedTrigger(botAI); } + static Trigger* at_dark_portal_outland(PlayerbotAI * botAI) { return new AtDarkPortalOutlandTrigger(botAI); } + static Trigger* at_dark_portal_azeroth(PlayerbotAI * botAI) { return new AtDarkPortalAzerothTrigger(botAI); } + static Trigger* in_vehicle(PlayerbotAI * botAI) { return new InVehicleTrigger(botAI); } + static Trigger* vehicle_near(PlayerbotAI * botAI) { return new VehicleNearTrigger(botAI); } + static Trigger* near_dark_portal(PlayerbotAI * botAI) { return new NearDarkPortalTrigger(botAI); } + static Trigger* need_world_buff(PlayerbotAI * botAI) { return new NeedWorldBuffTrigger(botAI); } + static Trigger* falling(PlayerbotAI * botAI) { return new IsFallingTrigger(botAI); } + static Trigger* falling_far(PlayerbotAI * botAI) { return new IsFallingFarTrigger(botAI); } + static Trigger* move_stuck(PlayerbotAI * botAI) { return new MoveStuckTrigger(botAI); } + static Trigger* move_long_stuck(PlayerbotAI * botAI) { return new MoveLongStuckTrigger(botAI); } + static Trigger* combat_stuck(PlayerbotAI * botAI) { return new CombatStuckTrigger(botAI); } + static Trigger* combat_long_stuck(PlayerbotAI * botAI) { return new CombatLongStuckTrigger(botAI); } + static Trigger* player_wants_in_bg(PlayerbotAI * botAI) { return new PlayerWantsInBattlegroundTrigger(botAI); } + static Trigger* petition_signed(PlayerbotAI * botAI) { return new PetitionTurnInTrigger(botAI); } + static Trigger* buy_tabard(PlayerbotAI * botAI) { return new BuyTabardTrigger(botAI); } + static Trigger* leave_large_guild(PlayerbotAI * botAI) { return new LeaveLargeGuildTrigger(botAI); } + static Trigger* rpg(PlayerbotAI * botAI) { return new RpgTrigger(botAI); } + static Trigger* rpg_taxi(PlayerbotAI * botAI) { return new RpgTaxiTrigger(botAI); } + static Trigger* rpg_discover(PlayerbotAI * botAI) { return new RpgDiscoverTrigger(botAI); } + static Trigger* rpg_start_quest(PlayerbotAI * botAI) { return new RpgStartQuestTrigger(botAI); } + static Trigger* rpg_end_quest(PlayerbotAI * botAI) { return new RpgEndQuestTrigger(botAI); } + static Trigger* rpg_buy(PlayerbotAI * botAI) { return new RpgBuyTrigger(botAI); } + static Trigger* rpg_sell(PlayerbotAI * botAI) { return new RpgSellTrigger(botAI); } + static Trigger* rpg_repair(PlayerbotAI * botAI) { return new RpgRepairTrigger(botAI); } + static Trigger* rpg_train(PlayerbotAI * botAI) { return new RpgTrainTrigger(botAI); } + static Trigger* rpg_heal(PlayerbotAI * botAI) { return new RpgHealTrigger(botAI); } + static Trigger* rpg_home_bind(PlayerbotAI * botAI) { return new RpgHomeBindTrigger(botAI); } + static Trigger* rpg_queue_bg(PlayerbotAI * botAI) { return new RpgQueueBGTrigger(botAI); } + static Trigger* rpg_buy_petition(PlayerbotAI * botAI) { return new RpgBuyPetitionTrigger(botAI); } + static Trigger* rpg_use(PlayerbotAI * botAI) { return new RpgUseTrigger(botAI); } + static Trigger* rpg_spell(PlayerbotAI * botAI) { return new RpgUseTrigger(botAI); } + static Trigger* rpg_craft(PlayerbotAI * botAI) { return new RpgCraftTrigger(botAI); } + static Trigger* rpg_trade_useful(PlayerbotAI * botAI) { return new RpgTradeUsefulTrigger(botAI); } + static Trigger* rpg_duel(PlayerbotAI * botAI) { return new RpgDuelTrigger(botAI); } + }; #endif diff --git a/src/strategy/values/LastMovementValue.cpp b/src/strategy/values/LastMovementValue.cpp index 767bc89e..f7b5488e 100644 --- a/src/strategy/values/LastMovementValue.cpp +++ b/src/strategy/values/LastMovementValue.cpp @@ -6,6 +6,7 @@ #include "LastMovementValue.h" #include "Playerbots.h" +#include "Timer.h" LastMovement::LastMovement() { clear(); } @@ -38,17 +39,19 @@ void LastMovement::clear() lastAreaTrigger = 0; lastFlee = 0; nextTeleport = 0; + msTime = 0; + lastdelayTime = 0; } void LastMovement::Set(Unit* follow) { - Set(0, 0.0f, 0.0f, 0.0f, 0.0f); + Set(0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); setShort(WorldPosition()); setPath(TravelPath()); lastFollow = follow; } -void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori) +void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori, float delayTime) { lastMoveToMapId = mapId; lastMoveToX = x; @@ -57,6 +60,8 @@ void LastMovement::Set(uint32 mapId, float x, float y, float z, float ori) lastMoveToOri = ori; lastFollow = nullptr; lastMoveShort = WorldPosition(mapId, x, y, z, ori); + msTime = getMSTime(); + lastdelayTime = delayTime; } void LastMovement::setShort(WorldPosition point) diff --git a/src/strategy/values/LastMovementValue.h b/src/strategy/values/LastMovementValue.h index 89277014..fc073a2a 100644 --- a/src/strategy/values/LastMovementValue.h +++ b/src/strategy/values/LastMovementValue.h @@ -35,7 +35,7 @@ public: void clear(); void Set(Unit* follow); - void Set(uint32 mapId, float x, float y, float z, float ori); + void Set(uint32 mapId, float x, float y, float z, float ori, float delayTime); void setShort(WorldPosition point); void setPath(TravelPath path); @@ -50,7 +50,9 @@ public: float lastMoveToY; float lastMoveToZ; float lastMoveToOri; + float lastdelayTime; WorldPosition lastMoveShort; + uint32 msTime; TravelPath lastPath; time_t nextTeleport; std::future future; diff --git a/src/strategy/values/PartyMemberToHeal.cpp b/src/strategy/values/PartyMemberToHeal.cpp index 31a8f00a..5c158428 100644 --- a/src/strategy/values/PartyMemberToHeal.cpp +++ b/src/strategy/values/PartyMemberToHeal.cpp @@ -82,8 +82,7 @@ bool PartyMemberToHeal::Check(Unit* player) // sServerFacade->GetDistance2d(bot, player) < (player->IsPlayer() && botAI->IsTank((Player*)player) ? 50.0f // : 40.0f); return player->GetMapId() == bot->GetMapId() && !player->IsCharmed() && - bot->GetDistance2d(player) < sPlayerbotAIConfig->healDistance * 2 && - bot->IsWithinLOS(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + bot->GetDistance2d(player) < sPlayerbotAIConfig->healDistance * 2 && bot->IsWithinLOSInMap(player); } Unit* PartyMemberToProtect::Calculate()