From 231b0b51e4e5d47ede319569effb69e45132e679 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Wed, 7 Jun 2023 22:58:36 +0800 Subject: [PATCH] movement action --- README.md | 4 +- conf/playerbots.conf.dist | 2 +- src/AiFactory.cpp | 2 +- src/PlayerbotAI.cpp | 10 +- src/strategy/actions/MovementActions.cpp | 1011 +++++++++--------- src/strategy/actions/RaidNaxxAction.cpp | 4 +- src/strategy/deathknight/BloodDKStrategy.cpp | 4 +- src/strategy/generic/RaidStrategy.cpp | 4 +- src/strategy/paladin/PaladinActions.h | 12 +- src/strategy/values/AttackerCountValues.cpp | 68 +- src/strategy/values/AttackerCountValues.h | 2 +- 11 files changed, 567 insertions(+), 556 deletions(-) diff --git a/README.md b/README.md index e28286da..c2545143 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Playerbots Module -This is a WIP Playerbots module for AzerothCore based on IKE3 Playerbots. Code is port from: https://github.com/ZhengPeiRu21/mod-playerbots. +This is a WIP Playerbots module for AzerothCore based on IKE3 Playerbots. Code is port from: https://github.com/ZhengPeiRu21/mod-playerbots I tried to fix many bugs based on the source code, making this playable, and tried to add more interesting functions, such as automatic positioning of the robot to deal with different raid bosses. -You can use this addon to better control the bot and avoid typing a lot of commands: https://github.com/liyunfan1223/unbot-addon. +You can use this addon to better control the bot and avoid typing a lot of commands: https://github.com/liyunfan1223/unbot-addon These Playerbots use actual player data, so it is capable to use own alts and play with own party, level up characters, and more. It is mostly usuable but still has many bugs that need to be resolved. Also please note that including this module will currently significantly increase compilation time for AzerothCore. diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index e58224ac..c6ea7b98 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -104,7 +104,7 @@ AiPlayerbot.MinEnchantingBotLevel = 60 # Randombots checking players gear score level and deny the group invite if it's too low # Default: 1 (enabled) -AiPlayerbot.GearScoreCheck = 1 +AiPlayerbot.GearScoreCheck = 0 # Quest that will be completed and rewarded to all random bots AiPlayerbot.RandomBotQuestIds = "7848,3802,5505,6502,7761" diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index 9a22cd99..c4d9e49a 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -496,7 +496,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const nonCombatEngine->addStrategies("dps assist", "cure", nullptr); break; case CLASS_MAGE: - if (tab == 1) + if (tab == MAGE_TAB_ARCANE || tab == MAGE_TAB_FIRE) nonCombatEngine->addStrategy("bdps"); else nonCombatEngine->addStrategy("bmana"); diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 49af98bf..e114d04c 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -3,6 +3,8 @@ */ #include "ObjectGuid.h" +#include "Player.h" +#include "PlayerbotAI.h" #include "Playerbots.h" #include "AiFactory.h" #include "BudgetValues.h" @@ -1306,22 +1308,22 @@ bool PlayerbotAI::IsTank(Player* player) switch (player->getClass()) { case CLASS_DEATH_KNIGHT: - if (tab == 0) { + if (tab == DEATHKNIGT_TAB_BLOOD) { return true; } break; case CLASS_PALADIN: - if (tab == 1) { + if (tab == PALADIN_TAB_PROTECTION) { return true; } break; case CLASS_WARRIOR: - if (tab == 2) { + if (tab == WARRIOR_TAB_PROTECTION) { return true; } break; case CLASS_DRUID: - if (tab == 1 && HasAnyAuraOf(player, "bear form", "dire bear form", "thick hide", NULL)) { + if (tab == DRUID_TAB_FERAL && HasAnyAuraOf(player, "bear form", "dire bear form", "thick hide", NULL)) { return true; } break; diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 19aeb3e2..1b21ba5a 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -128,403 +128,15 @@ bool MovementAction::MoveToLOS(WorldObject* target, bool ranged) bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bool react) { - // if (!IsMovingAllowed(mapId, x, y, z)) - // return false; - // bot->UpdateGroundPositionZ(x, y, z); - - // float distance = bot->GetDistance2d(x, y); - // if (distance > sPlayerbotAIConfig->contactDistance) - // { - // WaitForReach(distance); - - // if (bot->IsSitState()) - // bot->SetStandState(UNIT_STAND_STATE_STAND); - - // if (bot->IsNonMeleeSpellCast(true)) - // { - // bot->CastStop(); - // botAI->InterruptSpell(); - // } - - // bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && - // !bot->IsFlying() && !bot->IsUnderWater(); - // MotionMaster &mm = *bot->GetMotionMaster(); - // mm.Clear(); - - // // float botZ = bot->GetPositionZ(); - // // if (!bot->InBattleground() && z - botZ > 0.5f && bot->GetDistance2d(x, y) <= 5.0f) - // // { - // // float speed = bot->GetSpeed(MOVE_RUN); - // // mm.MoveJump(x, y, botZ + 0.5f, speed, speed, 1); - // // } - // // else - // mm.MovePoint(mapId, x, y, z, generatePath); - - // AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); - // return true; - // } - - // return false; - UpdateMovementState(); - // LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed()); - if (!IsMovingAllowed()) + if (!IsMovingAllowed(mapId, x, y, z)) return false; + bot->UpdateGroundPositionZ(x, y, z); - bool isVehicle = false; - Unit* mover = bot; - if (Vehicle* vehicle = bot->GetVehicle()) + float distance = bot->GetDistance2d(x, y); + if (distance > sPlayerbotAIConfig->contactDistance) { - VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(bot); - LOG_DEBUG("playerbots", "!seat || !seat->CanControl() {}", !seat || !seat->CanControl()); - if (!seat || !seat->CanControl()) - return false; + WaitForReach(distance); - isVehicle = true; - mover = vehicle->GetBase(); - } - - bool detailedMove = botAI->AllowActivity(DETAILED_MOVE_ACTIVITY); - if (!detailedMove) - { - time_t now = time(nullptr); - if (AI_VALUE(LastMovement&, "last movement").nextTeleport > now) // We can not teleport yet. Wait. - { - LOG_DEBUG("playerbots", "AI_VALUE(LastMovement&, \"last movement\").nextTeleport > now"); - botAI->SetNextCheckDelay((AI_VALUE(LastMovement&, "last movement").nextTeleport - now) * 1000); - return true; - } - } - - float minDist = sPlayerbotAIConfig->targetPosRecalcDistance; //Minium distance a bot should move. - float maxDist = sPlayerbotAIConfig->reactDistance; //Maxium distance a bot can move in one single action. - float originalZ = z; // save original destination height to check if bot needs to fly up - - bool generatePath = !bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater() && !bot->IsUnderWater(); - if (generatePath) - { - z += CONTACT_DISTANCE; - mover->UpdateAllowedPositionZ(x, y, z); - } - - if (!isVehicle && !IsMovingAllowed() && bot->isDead()) - { - bot->StopMoving(); - LOG_DEBUG("playerbots", "!isVehicle && !IsMovingAllowed() && bot->isDead()"); - return false; - } - - if (!isVehicle && bot->isMoving() && !IsMovingAllowed()) - { - if (!bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) - bot->StopMoving(); - LOG_DEBUG("playerbots", "!isVehicle && bot->isMoving() && !IsMovingAllowed()"); - return false; - } - - LastMovement& lastMove = *context->GetValue("last movement"); - - WorldPosition startPosition = WorldPosition(bot); //Current location of the bot - WorldPosition endPosition = WorldPosition(mapId, x, y, z, 0); //The requested end location - WorldPosition movePosition; //The actual end location - - float totalDistance = startPosition.distance(endPosition); //Total distance to where we want to go - float maxDistChange = totalDistance * 0.1; //Maximum change between previous destination before needing a recalulation - - if (totalDistance < minDist) - { - if (lastMove.lastMoveShort.distance(endPosition) < maxDistChange) - AI_VALUE(LastMovement&, "last movement").clear(); - - mover->StopMoving(); - LOG_DEBUG("playerbots", "totalDistance < minDist"); - return false; - } - - TravelPath movePath; - - if (lastMove.lastMoveShort.distance(endPosition) < maxDistChange && startPosition.distance(lastMove.lastMoveShort) < maxDist) //The last short movement was to the same place we want to move now. - movePosition = endPosition; - else if (!lastMove.lastPath.empty() && lastMove.lastPath.getBack().distance(endPosition) < maxDistChange) //The last long movement was to the same place we want to move now. - { - movePath = lastMove.lastPath; - } - else - { - movePosition = endPosition; - - if (startPosition.getMapId() != endPosition.getMapId() || totalDistance > maxDist) - { - if (!sTravelNodeMap->getNodes().empty() && !bot->InBattleground()) - { - if (sPlayerbotAIConfig->tweakValue) - { - if (lastMove.future.valid()) - { - movePath = lastMove.future.get(); - } - else - { - lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot); - LOG_DEBUG("playerbots", "lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot);"); - return true; - } - } - else - movePath = sTravelNodeMap->getFullPath(startPosition, endPosition, bot); - - if (movePath.empty()) - { - //We have no path. Beyond 450yd the standard PathGenerator will probably move the wrong way. - if (sServerFacade->IsDistanceGreaterThan(totalDistance, maxDist * 3)) - { - movePath.clear(); - movePath.addPoint(endPosition); - AI_VALUE(LastMovement&, "last movement").setPath(movePath); - - bot->StopMoving(); - if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) - botAI->TellMasterNoFacing("I have no path"); - LOG_DEBUG("playerbots", "sServerFacade->IsDistanceGreaterThan(totalDistance, maxDist * 3)"); - return false; - } - - movePosition = endPosition; - } - } - else - { - //Use standard PathGenerator to find a route. - movePosition = endPosition; - } - } - } - - if (movePath.empty() && movePosition.distance(startPosition) > maxDist) - { - //Use standard PathGenerator to find a route. - PathGenerator path(mover); - path.CalculatePath(movePosition.getX(), movePosition.getY(), movePosition.getZ(), false); - PathType type = path.GetPathType(); - Movement::PointsArray const& points = path.GetPath(); - movePath.addPath(startPosition.fromPointsArray(points)); - } - - if (!movePath.empty()) - { - if (movePath.makeShortCut(startPosition, maxDist)) - if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) - botAI->TellMasterNoFacing("Found a shortcut."); - - if (movePath.empty()) - { - AI_VALUE(LastMovement&, "last movement").setPath(movePath); - - if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) - botAI->TellMasterNoFacing("Too far from path. Rebuilding."); - LOG_DEBUG("playerbots", "movePath.empty()"); - return true; - } - - TravelNodePathType pathType; - uint32 entry; - movePosition = movePath.getNextPoint(startPosition, maxDist, pathType, entry); - - if (pathType == TravelNodePathType::portal) // && !botAI->isRealPlayer()) - { - //Log bot movement - if (sPlayerbotAIConfig->hasLog("bot_movement.csv")) - { - WorldPosition telePos; - if (entry) - { - if (AreaTriggerTeleport const* at = sObjectMgr->GetAreaTriggerTeleport(entry)) - telePos = WorldPosition(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation); - } - else - telePos = movePosition; - - std::ostringstream out; - out << sPlayerbotAIConfig->GetTimestampStr() << "+00,"; - out << bot->GetName() << ","; - if (telePos && telePos.GetExactDist(movePosition) > 0.001) - startPosition.printWKT({ startPosition, movePosition, telePos }, out, 1); - else - startPosition.printWKT({ startPosition, movePosition }, out, 1); - - out << std::to_string(bot->getRace()) << ","; - out << std::to_string(bot->getClass()) << ","; - out << bot->getLevel() << ","; - out << (entry ? -1 : entry); - - sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str()); - } - - if (entry) - { - AI_VALUE(LastMovement&, "last area trigger").lastAreaTrigger = entry; - } - else { - LOG_DEBUG("playerbots", "!entry"); - return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), movePosition.getO(), 0); - } - } - - if (pathType == TravelNodePathType::transport && entry) - { - if (!bot->GetTransport()) - { - for (auto& transport : movePosition.getTransports(entry)) - if (movePosition.sqDistance2d(WorldPosition((WorldObject*)transport)) < 5 * 5) - transport->AddPassenger(bot, true); - } - WaitForReach(100.0f); - LOG_DEBUG("playerbots", "pathType == TravelNodePathType::transport && entry"); - return true; - } - - if (pathType == TravelNodePathType::flightPath && entry) - { - if (TaxiPathEntry const* tEntry = sTaxiPathStore.LookupEntry(entry)) - { - Creature* unit = nullptr; - - if (!bot->m_taxi.IsTaximaskNodeKnown(tEntry->from)) - { - GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs"); - for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++) - { - Creature* unit = bot->GetNPCIfCanInteractWith(*i, UNIT_NPC_FLAG_FLIGHTMASTER); - if (!unit) - continue; - - bot->GetSession()->SendLearnNewTaxiNode(unit); - - unit->SetFacingTo(unit->GetAngle(bot)); - } - } - - uint32 botMoney = bot->GetMoney(); - if (botAI->HasCheat(BotCheatMask::gold)) - { - bot->SetMoney(10000000); - } - - bool goTaxi = bot->ActivateTaxiPathTo({ tEntry->from, tEntry->to }, unit, 1); - - if (botAI->HasCheat(BotCheatMask::gold)) - { - bot->SetMoney(botMoney); - } - LOG_DEBUG("playerbots", "goTaxi"); - return goTaxi; - } - } - - // if (pathType == TravelNodePathType::teleportSpell && entry) - // { - // if (entry == 8690) - // { - // if (!bot->HasSpellCooldown(8690)) - // { - // return botAI->DoSpecificAction("hearthstone", Event("move action")); - // } - // else - // { - // movePath.clear(); - // AI_VALUE(LastMovement&, "last movement").setPath(movePath); - // LOG_DEBUG("playerbots", "bot->HasSpellCooldown(8690)"); - // return false; - // } - // } - // } - - //if (!isTransport && bot->GetTransport()) - // bot->GetTransport()->RemovePassenger(bot); - } - - AI_VALUE(LastMovement&, "last movement").setPath(movePath); - - if (!movePosition || movePosition.getMapId() != bot->GetMapId()) - { - movePath.clear(); - AI_VALUE(LastMovement&, "last movement").setPath(movePath); - - if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) - botAI->TellMasterNoFacing("No point. Rebuilding."); - LOG_DEBUG("playerbots", "!movePosition || movePosition.getMapId() != bot->GetMapId()"); - return false; - } - - if (movePosition.distance(startPosition) > maxDist) - { - //Use standard pathfinder to find a route. - PathGenerator path(mover); - path.CalculatePath(movePosition.getX(), movePosition.getY(), movePosition.getZ(), false); - PathType type = path.GetPathType(); - Movement::PointsArray const& points = path.GetPath(); - movePath.addPath(startPosition.fromPointsArray(points)); - TravelNodePathType pathType; - uint32 entry; - movePosition = movePath.getNextPoint(startPosition, maxDist, pathType, entry); - } - - if (movePosition == WorldPosition()) - { - movePath.clear(); - - AI_VALUE(LastMovement&, "last movement").setPath(movePath); - - if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) - botAI->TellMasterNoFacing("No point. Rebuilding."); - - return false; - } - - //Visual waypoints - if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) - { - if (!movePath.empty()) - { - float cx = x; - float cy = y; - float cz = z; - for (auto i : movePath.getPath()) - { - CreateWp(bot, i.point.getX(), i.point.getY(), i.point.getZ(), 0.f, 2334); - - cx = i.point.getX(); - cy = i.point.getY(); - cz = i.point.getZ(); - } - } - else - CreateWp(bot, movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0, 2334, true); - } - - //Log bot movement - if (sPlayerbotAIConfig->hasLog("bot_movement.csv") && lastMove.lastMoveShort.GetExactDist(movePosition) > 0.001) - { - std::ostringstream out; - out << sPlayerbotAIConfig->GetTimestampStr() << "+00,"; - out << bot->GetName() << ","; - startPosition.printWKT({ startPosition, movePosition }, out, 1); - out << std::to_string(bot->getRace()) << ","; - out << std::to_string(bot->getClass()) << ","; - out << bot->getLevel(); - out << 0; - - sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str()); - } - // LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(), movePosition.getX(), movePosition.getY()); - if (!react) - if (totalDistance > maxDist) - WaitForReach(startPosition.distance(movePosition) - 10.0f); - else - WaitForReach(startPosition.distance(movePosition)); - - if (!isVehicle) - { - bot->HandleEmoteCommand(0); if (bot->IsSitState()) bot->SetStandState(UNIT_STAND_STATE_STAND); @@ -533,165 +145,534 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, bot->CastStop(); botAI->InterruptSpell(); } + + bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && + !bot->IsFlying() && !bot->IsUnderWater(); + MotionMaster &mm = *bot->GetMotionMaster(); + mm.Clear(); + + // float botZ = bot->GetPositionZ(); + // if (!bot->InBattleground() && z - botZ > 0.5f && bot->GetDistance2d(x, y) <= 5.0f) + // { + // float speed = bot->GetSpeed(MOVE_RUN); + // mm.MoveJump(x, y, botZ + 0.5f, speed, speed, 1); + // } + // else + mm.MovePoint(mapId, x, y, z, generatePath); + + AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation()); + return true; } - /* Why do we do this? - if (lastMove.lastMoveShort.distance(movePosition) < minDist) - { - bot->StopMoving(); - bot->GetMotionMaster()->Clear(); - } - */ + return false; + // UpdateMovementState(); + // // LOG_DEBUG("playerbots", "IsMovingAllowed {}", IsMovingAllowed()); + // if (!IsMovingAllowed()) + // return false; - // Clean movement if not already moving the same way. - // if (mover->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) + // bool isVehicle = false; + // Unit* mover = bot; + // if (Vehicle* vehicle = bot->GetVehicle()) // { - // mover->StopMoving(); - // mover->GetMotionMaster()->Clear(); + // VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(bot); + // LOG_DEBUG("playerbots", "!seat || !seat->CanControl() {}", !seat || !seat->CanControl()); + // if (!seat || !seat->CanControl()) + // return false; + + // isVehicle = true; + // mover = vehicle->GetBase(); // } - // else + + // bool detailedMove = botAI->AllowActivity(DETAILED_MOVE_ACTIVITY); + // if (!detailedMove) // { - // mover->GetMotionMaster()->GetDestination(x, y, z); - // if (movePosition.distance(WorldPosition(movePosition.getMapId(), x, y, z, 0)) > minDist) + // time_t now = time(nullptr); + // if (AI_VALUE(LastMovement&, "last movement").nextTeleport > now) // We can not teleport yet. Wait. // { - // mover->StopMoving(); - // mover->GetMotionMaster()->Clear(); + // LOG_DEBUG("playerbots", "AI_VALUE(LastMovement&, \"last movement\").nextTeleport > now"); + // botAI->SetNextCheckDelay((AI_VALUE(LastMovement&, "last movement").nextTeleport - now) * 1000); + // return true; // } // } - if (totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)) // Why walk if you can fly? - { - time_t now = time(nullptr); + // float minDist = sPlayerbotAIConfig->targetPosRecalcDistance; //Minium distance a bot should move. + // float maxDist = sPlayerbotAIConfig->reactDistance; //Maxium distance a bot can move in one single action. + // float originalZ = z; // save original destination height to check if bot needs to fly up - AI_VALUE(LastMovement&, "last movement").nextTeleport = now + (time_t)MoveDelay(startPosition.distance(movePosition)); - LOG_DEBUG("playerbots", "totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)"); - return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), startPosition.getAngleTo(movePosition)); - } + // bool generatePath = !bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater() && !bot->IsUnderWater(); + // if (generatePath) + // { + // z += CONTACT_DISTANCE; + // mover->UpdateAllowedPositionZ(x, y, z); + // } - // walk if master walks and is close - bool masterWalking = false; - if (botAI->GetMaster()) - { - if (botAI->GetMaster()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING) && sServerFacade->GetDistance2d(bot, botAI->GetMaster()) < 20.0f) - masterWalking = true; - } + // if (!isVehicle && !IsMovingAllowed() && bot->isDead()) + // { + // bot->StopMoving(); + // LOG_DEBUG("playerbots", "!isVehicle && !IsMovingAllowed() && bot->isDead()"); + // return false; + // } - if (masterWalking) - bot->SetWalk(true); + // if (!isVehicle && bot->isMoving() && !IsMovingAllowed()) + // { + // if (!bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) + // bot->StopMoving(); + // LOG_DEBUG("playerbots", "!isVehicle && bot->isMoving() && !IsMovingAllowed()"); + // return false; + // } - bot->SendMovementFlagUpdate(); - // LOG_DEBUG("playerbots", "normal move? {} {} {}", !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY), - // bot->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE), bot->getStandState()); - if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY)) - { - bot->SetWalk(masterWalking); - bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath); - WaitForReach(startPosition.distance(movePosition)); - // LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); - } - else - { - bool needFly = false; - bool needLand = false; - bool isFly = bot->IsFlying(); + // LastMovement& lastMove = *context->GetValue("last movement"); - if (!isFly && originalZ > bot->GetPositionZ() && (originalZ - bot->GetPositionZ()) > 5.0f) - needFly = true; + // WorldPosition startPosition = WorldPosition(bot); //Current location of the bot + // WorldPosition endPosition = WorldPosition(mapId, x, y, z, 0); //The requested end location + // WorldPosition movePosition; //The actual end location - if (needFly && !isFly) - { - WorldPacket data(SMSG_SPLINE_MOVE_SET_FLYING, 9); - data << bot->GetPackGUID(); - bot->SendMessageToSet(&data, true); + // float totalDistance = startPosition.distance(endPosition); //Total distance to where we want to go + // float maxDistChange = totalDistance * 0.1; //Maximum change between previous destination before needing a recalulation - if (!bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING)) - bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING); + // if (totalDistance < minDist) + // { + // if (lastMove.lastMoveShort.distance(endPosition) < maxDistChange) + // AI_VALUE(LastMovement&, "last movement").clear(); - if (!bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) - bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); - } + // mover->StopMoving(); + // LOG_DEBUG("playerbots", "totalDistance < minDist"); + // return false; + // } - if (isFly) - { - float ground = bot->GetPositionZ(); - float height = bot->GetMap()->GetWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), ground); - if (bot->GetPositionZ() > originalZ && (bot->GetPositionZ() - originalZ < 5.0f) && (fabs(originalZ - ground) < 5.0f)) - needLand = true; + // TravelPath movePath; - if (needLand) - { - WorldPacket data(SMSG_SPLINE_MOVE_UNSET_FLYING, 9); - data << bot->GetPackGUID(); - bot->SendMessageToSet(&data, true); + // if (lastMove.lastMoveShort.distance(endPosition) < maxDistChange && startPosition.distance(lastMove.lastMoveShort) < maxDist) //The last short movement was to the same place we want to move now. + // movePosition = endPosition; + // else if (!lastMove.lastPath.empty() && lastMove.lastPath.getBack().distance(endPosition) < maxDistChange) //The last long movement was to the same place we want to move now. + // { + // movePath = lastMove.lastPath; + // } + // else + // { + // movePosition = endPosition; - if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING)) - bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FLYING); + // if (startPosition.getMapId() != endPosition.getMapId() || totalDistance > maxDist) + // { + // if (!sTravelNodeMap->getNodes().empty() && !bot->InBattleground()) + // { + // if (sPlayerbotAIConfig->tweakValue) + // { + // if (lastMove.future.valid()) + // { + // movePath = lastMove.future.get(); + // } + // else + // { + // lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot); + // LOG_DEBUG("playerbots", "lastMove.future = std::async(&TravelNodeMap::getFullPath, startPosition, endPosition, bot);"); + // return true; + // } + // } + // else + // movePath = sTravelNodeMap->getFullPath(startPosition, endPosition, bot); - if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) - bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); - } - } + // if (movePath.empty()) + // { + // //We have no path. Beyond 450yd the standard PathGenerator will probably move the wrong way. + // if (sServerFacade->IsDistanceGreaterThan(totalDistance, maxDist * 3)) + // { + // movePath.clear(); + // movePath.addPoint(endPosition); + // AI_VALUE(LastMovement&, "last movement").setPath(movePath); - bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0.f)); - WaitForReach(startPosition.distance(movePosition)); - LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); - } + // bot->StopMoving(); + // if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) + // botAI->TellMasterNoFacing("I have no path"); + // LOG_DEBUG("playerbots", "sServerFacade->IsDistanceGreaterThan(totalDistance, maxDist * 3)"); + // return false; + // } - AI_VALUE(LastMovement&, "last movement").setShort(movePosition); + // movePosition = endPosition; + // } + // } + // else + // { + // //Use standard PathGenerator to find a route. + // movePosition = endPosition; + // } + // } + // } - if (!idle) - ClearIdleState(); + // if (movePath.empty() && movePosition.distance(startPosition) > maxDist) + // { + // //Use standard PathGenerator to find a route. + // PathGenerator path(mover); + // path.CalculatePath(movePosition.getX(), movePosition.getY(), movePosition.getZ(), false); + // PathType type = path.GetPathType(); + // Movement::PointsArray const& points = path.GetPath(); + // movePath.addPath(startPosition.fromPointsArray(points)); + // } - LOG_DEBUG("playerbots", "return true in the end"); - return true; + // if (!movePath.empty()) + // { + // if (movePath.makeShortCut(startPosition, maxDist)) + // if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) + // botAI->TellMasterNoFacing("Found a shortcut."); + + // if (movePath.empty()) + // { + // AI_VALUE(LastMovement&, "last movement").setPath(movePath); + + // if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) + // botAI->TellMasterNoFacing("Too far from path. Rebuilding."); + // LOG_DEBUG("playerbots", "movePath.empty()"); + // return true; + // } + + // TravelNodePathType pathType; + // uint32 entry; + // movePosition = movePath.getNextPoint(startPosition, maxDist, pathType, entry); + + // if (pathType == TravelNodePathType::portal) // && !botAI->isRealPlayer()) + // { + // //Log bot movement + // if (sPlayerbotAIConfig->hasLog("bot_movement.csv")) + // { + // WorldPosition telePos; + // if (entry) + // { + // if (AreaTriggerTeleport const* at = sObjectMgr->GetAreaTriggerTeleport(entry)) + // telePos = WorldPosition(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation); + // } + // else + // telePos = movePosition; + + // std::ostringstream out; + // out << sPlayerbotAIConfig->GetTimestampStr() << "+00,"; + // out << bot->GetName() << ","; + // if (telePos && telePos.GetExactDist(movePosition) > 0.001) + // startPosition.printWKT({ startPosition, movePosition, telePos }, out, 1); + // else + // startPosition.printWKT({ startPosition, movePosition }, out, 1); + + // out << std::to_string(bot->getRace()) << ","; + // out << std::to_string(bot->getClass()) << ","; + // out << bot->getLevel() << ","; + // out << (entry ? -1 : entry); + + // sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str()); + // } + + // if (entry) + // { + // AI_VALUE(LastMovement&, "last area trigger").lastAreaTrigger = entry; + // } + // else { + // LOG_DEBUG("playerbots", "!entry"); + // return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), movePosition.getO(), 0); + // } + // } + + // if (pathType == TravelNodePathType::transport && entry) + // { + // if (!bot->GetTransport()) + // { + // for (auto& transport : movePosition.getTransports(entry)) + // if (movePosition.sqDistance2d(WorldPosition((WorldObject*)transport)) < 5 * 5) + // transport->AddPassenger(bot, true); + // } + // WaitForReach(100.0f); + // LOG_DEBUG("playerbots", "pathType == TravelNodePathType::transport && entry"); + // return true; + // } + + // if (pathType == TravelNodePathType::flightPath && entry) + // { + // if (TaxiPathEntry const* tEntry = sTaxiPathStore.LookupEntry(entry)) + // { + // Creature* unit = nullptr; + + // if (!bot->m_taxi.IsTaximaskNodeKnown(tEntry->from)) + // { + // GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs"); + // for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++) + // { + // Creature* unit = bot->GetNPCIfCanInteractWith(*i, UNIT_NPC_FLAG_FLIGHTMASTER); + // if (!unit) + // continue; + + // bot->GetSession()->SendLearnNewTaxiNode(unit); + + // unit->SetFacingTo(unit->GetAngle(bot)); + // } + // } + + // uint32 botMoney = bot->GetMoney(); + // if (botAI->HasCheat(BotCheatMask::gold)) + // { + // bot->SetMoney(10000000); + // } + + // bool goTaxi = bot->ActivateTaxiPathTo({ tEntry->from, tEntry->to }, unit, 1); + + // if (botAI->HasCheat(BotCheatMask::gold)) + // { + // bot->SetMoney(botMoney); + // } + // LOG_DEBUG("playerbots", "goTaxi"); + // return goTaxi; + // } + // } + + // // if (pathType == TravelNodePathType::teleportSpell && entry) + // // { + // // if (entry == 8690) + // // { + // // if (!bot->HasSpellCooldown(8690)) + // // { + // // return botAI->DoSpecificAction("hearthstone", Event("move action")); + // // } + // // else + // // { + // // movePath.clear(); + // // AI_VALUE(LastMovement&, "last movement").setPath(movePath); + // // LOG_DEBUG("playerbots", "bot->HasSpellCooldown(8690)"); + // // return false; + // // } + // // } + // // } + + // //if (!isTransport && bot->GetTransport()) + // // bot->GetTransport()->RemovePassenger(bot); + // } + + // AI_VALUE(LastMovement&, "last movement").setPath(movePath); + + // if (!movePosition || movePosition.getMapId() != bot->GetMapId()) + // { + // movePath.clear(); + // AI_VALUE(LastMovement&, "last movement").setPath(movePath); + + // if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) + // botAI->TellMasterNoFacing("No point. Rebuilding."); + // LOG_DEBUG("playerbots", "!movePosition || movePosition.getMapId() != bot->GetMapId()"); + // return false; + // } + + // if (movePosition.distance(startPosition) > maxDist) + // { + // //Use standard pathfinder to find a route. + // PathGenerator path(mover); + // path.CalculatePath(movePosition.getX(), movePosition.getY(), movePosition.getZ(), false); + // PathType type = path.GetPathType(); + // Movement::PointsArray const& points = path.GetPath(); + // movePath.addPath(startPosition.fromPointsArray(points)); + // TravelNodePathType pathType; + // uint32 entry; + // movePosition = movePath.getNextPoint(startPosition, maxDist, pathType, entry); + // } + + // if (movePosition == WorldPosition()) + // { + // movePath.clear(); + + // AI_VALUE(LastMovement&, "last movement").setPath(movePath); + + // if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) + // botAI->TellMasterNoFacing("No point. Rebuilding."); + + // return false; + // } + + // //Visual waypoints + // if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT)) + // { + // if (!movePath.empty()) + // { + // float cx = x; + // float cy = y; + // float cz = z; + // for (auto i : movePath.getPath()) + // { + // CreateWp(bot, i.point.getX(), i.point.getY(), i.point.getZ(), 0.f, 2334); + + // cx = i.point.getX(); + // cy = i.point.getY(); + // cz = i.point.getZ(); + // } + // } + // else + // CreateWp(bot, movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0, 2334, true); + // } + + // //Log bot movement + // if (sPlayerbotAIConfig->hasLog("bot_movement.csv") && lastMove.lastMoveShort.GetExactDist(movePosition) > 0.001) + // { + // std::ostringstream out; + // out << sPlayerbotAIConfig->GetTimestampStr() << "+00,"; + // out << bot->GetName() << ","; + // startPosition.printWKT({ startPosition, movePosition }, out, 1); + // out << std::to_string(bot->getRace()) << ","; + // out << std::to_string(bot->getClass()) << ","; + // out << bot->getLevel(); + // out << 0; + + // sPlayerbotAIConfig->log("bot_movement.csv", out.str().c_str()); + // } + // // LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(), movePosition.getX(), movePosition.getY()); + // if (!react) + // if (totalDistance > maxDist) + // WaitForReach(startPosition.distance(movePosition) - 10.0f); + // else + // WaitForReach(startPosition.distance(movePosition)); + + // if (!isVehicle) + // { + // bot->HandleEmoteCommand(0); + // if (bot->IsSitState()) + // bot->SetStandState(UNIT_STAND_STATE_STAND); + + // if (bot->IsNonMeleeSpellCast(true)) + // { + // bot->CastStop(); + // botAI->InterruptSpell(); + // } + // } + + // /* Why do we do this? + // if (lastMove.lastMoveShort.distance(movePosition) < minDist) + // { + // bot->StopMoving(); + // bot->GetMotionMaster()->Clear(); + // } + // */ + + // // Clean movement if not already moving the same way. + // // if (mover->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) + // // { + // // mover->StopMoving(); + // // mover->GetMotionMaster()->Clear(); + // // } + // // else + // // { + // // mover->GetMotionMaster()->GetDestination(x, y, z); + // // if (movePosition.distance(WorldPosition(movePosition.getMapId(), x, y, z, 0)) > minDist) + // // { + // // mover->StopMoving(); + // // mover->GetMotionMaster()->Clear(); + // // } + // // } + + // if (totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)) // Why walk if you can fly? + // { + // time_t now = time(nullptr); + + // AI_VALUE(LastMovement&, "last movement").nextTeleport = now + (time_t)MoveDelay(startPosition.distance(movePosition)); + // LOG_DEBUG("playerbots", "totalDistance > maxDist && !detailedMove && !botAI->HasPlayerNearby(&movePosition)"); + // return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), startPosition.getAngleTo(movePosition)); + // } + + // // walk if master walks and is close + // bool masterWalking = false; + // if (botAI->GetMaster()) + // { + // if (botAI->GetMaster()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING) && sServerFacade->GetDistance2d(bot, botAI->GetMaster()) < 20.0f) + // masterWalking = true; + // } + + // if (masterWalking) + // bot->SetWalk(true); + + // bot->SendMovementFlagUpdate(); + // // LOG_DEBUG("playerbots", "normal move? {} {} {}", !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY), + // // bot->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE), bot->getStandState()); + // if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY)) + // { + // bot->SetWalk(masterWalking); + // bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(), movePosition.getZ(), generatePath); + // WaitForReach(startPosition.distance(movePosition)); + // // LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); + // } + // else + // { + // bool needFly = false; + // bool needLand = false; + // bool isFly = bot->IsFlying(); + + // if (!isFly && originalZ > bot->GetPositionZ() && (originalZ - bot->GetPositionZ()) > 5.0f) + // needFly = true; + + // if (needFly && !isFly) + // { + // WorldPacket data(SMSG_SPLINE_MOVE_SET_FLYING, 9); + // data << bot->GetPackGUID(); + // bot->SendMessageToSet(&data, true); + + // if (!bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING)) + // bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING); + + // if (!bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) + // bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); + // } + + // if (isFly) + // { + // float ground = bot->GetPositionZ(); + // float height = bot->GetMap()->GetWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), ground); + // if (bot->GetPositionZ() > originalZ && (bot->GetPositionZ() - originalZ < 5.0f) && (fabs(originalZ - ground) < 5.0f)) + // needLand = true; + + // if (needLand) + // { + // WorldPacket data(SMSG_SPLINE_MOVE_UNSET_FLYING, 9); + // data << bot->GetPackGUID(); + // bot->SendMessageToSet(&data, true); + + // if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING)) + // bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FLYING); + + // if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) + // bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); + // } + // } + + // bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0.f)); + // WaitForReach(startPosition.distance(movePosition)); + // LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY()); + // } + + // AI_VALUE(LastMovement&, "last movement").setShort(movePosition); + + // if (!idle) + // ClearIdleState(); + + // LOG_DEBUG("playerbots", "return true in the end"); + // return true; } bool MovementAction::MoveTo(Unit* target, float distance) { - if (!target || !target->IsInWorld()) - { - //botAI->TellError("Seems I am stuck"); + if (!IsMovingAllowed(target)) return false; - } - float bx = bot->GetPositionX(), by = bot->GetPositionY(), bz = bot->GetPositionZ(); - float tx = target->GetPositionX(), ty = target->GetPositionY(), tz = target->GetPositionZ(); + float bx = bot->GetPositionX(); + float by = bot->GetPositionY(); + float bz = bot->GetPositionZ(); - if (bot->IsHostileTo(target)) - { - Stance* stance = AI_VALUE(Stance*, "stance"); + float tx = target->GetPositionX(); + float ty = target->GetPositionY(); + float tz = target->GetPositionZ(); - WorldLocation const& loc = stance->GetLocation(); - if (Formation::IsNullLocation(loc) || loc.GetMapId() == -1) - { - //botAI->TellError("Nowhere to move"); - return false; - } + float distanceToTarget = bot->GetDistance2d(target); + float angle = bot->GetAngle(target); + float needToGo = distanceToTarget - distance; - tx = loc.GetPositionX(); - ty = loc.GetPositionY(); - tz = loc.GetPositionZ(); - } + float maxDistance = sPlayerbotAIConfig->spellDistance; + if (needToGo > 0 && needToGo > maxDistance) + needToGo = maxDistance; + else if (needToGo < 0 && needToGo < -maxDistance) + needToGo = -maxDistance; - float distanceToTarget = sServerFacade->GetDistance2d(bot, tx, ty); - if (sServerFacade->IsDistanceGreaterThan(distanceToTarget, sPlayerbotAIConfig->targetPosRecalcDistance)) - { - float angle = bot->GetAngle(tx, ty); - float needToGo = distanceToTarget - distance; + float dx = cos(angle) * needToGo + bx; + float dy = sin(angle) * needToGo + by; - float maxDistance = botAI->GetRange("spell"); - if (needToGo > 0 && needToGo > maxDistance) - needToGo = maxDistance; - else if (needToGo < 0 && needToGo < -maxDistance) - needToGo = -maxDistance; - - float dx = cos(angle) * needToGo + bx; - float dy = sin(angle) * needToGo + by; - float dz = bz + (tz - bz) * needToGo / distanceToTarget; - return MoveTo(target->GetMapId(), dx, dy, dz); - } - - return false; + return MoveTo(target->GetMapId(), dx, dy, tz); } float MovementAction::GetFollowAngle() diff --git a/src/strategy/actions/RaidNaxxAction.cpp b/src/strategy/actions/RaidNaxxAction.cpp index 752414df..ca4f8307 100644 --- a/src/strategy/actions/RaidNaxxAction.cpp +++ b/src/strategy/actions/RaidNaxxAction.cpp @@ -131,7 +131,7 @@ bool HeiganDanceMeleeAction::Execute(Event event) { return false; } // botAI->TellMaster("Let\'s go " + std::to_string(curr_safe)); - return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), botAI->IsMainTank(bot) ? 0 : 0.5f); + return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), botAI->IsMainTank(bot) ? 0 : 0); } bool HeiganDanceRangedAction::Execute(Event event) { @@ -140,7 +140,7 @@ bool HeiganDanceRangedAction::Execute(Event event) { return MoveTo(bot->GetMapId(), platform.first, platform.second, 276.54f); } botAI->InterruptSpell(); - return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0.5f); + return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0); } // bool ThaddiusAttackNearestPetAction::isUseful() diff --git a/src/strategy/deathknight/BloodDKStrategy.cpp b/src/strategy/deathknight/BloodDKStrategy.cpp index 656bc566..60bfaf3a 100644 --- a/src/strategy/deathknight/BloodDKStrategy.cpp +++ b/src/strategy/deathknight/BloodDKStrategy.cpp @@ -29,7 +29,7 @@ class BloodDKStrategyActionNodeFactory : public NamedObjectFactory //creators["death rune_mastery"] = &death_rune_mastery; //creators["hysteria"] = &hysteria; //creators["dancing weapon"] = &dancing_weapon; - //creators["dark command"] = &dark_command; + creators["dark command"] = &dark_command; creators["taunt spell"] = &dark_command; } @@ -46,7 +46,7 @@ class BloodDKStrategyActionNodeFactory : public NamedObjectFactory { return new ActionNode ("heart strike", /*P*/ NextAction::array(0, new NextAction("frost presence"), nullptr), - /*A*/ NextAction::array(0, new NextAction("death strike"), nullptr), + /*A*/ nullptr, /*C*/ nullptr); } diff --git a/src/strategy/generic/RaidStrategy.cpp b/src/strategy/generic/RaidStrategy.cpp index 51fdf547..126141f9 100644 --- a/src/strategy/generic/RaidStrategy.cpp +++ b/src/strategy/generic/RaidStrategy.cpp @@ -41,7 +41,7 @@ float HeiganDanceMultiplier::GetValue(Action* action) if (dynamic_cast(action) || dynamic_cast(action)) { return 1.0f; } - if (dynamic_cast(action)) + if (dynamic_cast(action) && !dynamic_cast(action)) { uint32 spellId = AI_VALUE2(uint32, "spell id", action->getName()); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); @@ -49,7 +49,7 @@ float HeiganDanceMultiplier::GetValue(Action* action) return 0.0f; } uint32 castTime = spellInfo->CalcCastTime(); - if (castTime == 0) { + if (castTime == 0 && !spellInfo->IsChanneled()) { return 1.0f; } } diff --git a/src/strategy/paladin/PaladinActions.h b/src/strategy/paladin/PaladinActions.h index 00755499..2f89f5d8 100644 --- a/src/strategy/paladin/PaladinActions.h +++ b/src/strategy/paladin/PaladinActions.h @@ -5,6 +5,7 @@ #ifndef _PLAYERBOT_PALADINACTIONS_H #define _PLAYERBOT_PALADINACTIONS_H +#include "AiObject.h" #include "GenericSpellActions.h" #include "SharedDefines.h" @@ -20,10 +21,11 @@ BUFF_ACTION(CastSealOfCommandAction, "seal of command"); BUFF_ACTION(CastSealOfVengeanceAction, "seal of vengeance"); // judgements -DEBUFF_ACTION_R(CastJudgementAction, "judgement", 10.0f); -DEBUFF_ACTION_R(CastJudgementOfLightAction, "judgement of light", 10.0f); -DEBUFF_ACTION_R(CastJudgementOfWisdomAction, "judgement of wisdom", 10.0f); -DEBUFF_ACTION_R(CastJudgementOfJusticeAction, "judgement of justice", 10.0f); +SPELL_ACTION(CastJudgementAction, "judgement"); + +SPELL_ACTION(CastJudgementOfLightAction, "judgement of light"); +SPELL_ACTION(CastJudgementOfWisdomAction, "judgement of wisdom"); +SPELL_ACTION(CastJudgementOfJusticeAction, "judgement of justice"); // auras BUFF_ACTION(CastDevotionAuraAction, "devotion aura"); @@ -39,7 +41,7 @@ SPELL_ACTION(CastHolyShockAction, "holy shock"); HEAL_PARTY_ACTION(CastHolyShockOnPartyAction, "holy shock"); // consecration -SPELL_ACTION(CastConsecrationAction, "consecration"); +MELEE_ACTION(CastConsecrationAction, "consecration"); // repentance SNARE_ACTION(CastRepentanceSnareAction, "repentance"); diff --git a/src/strategy/values/AttackerCountValues.cpp b/src/strategy/values/AttackerCountValues.cpp index 43e548cd..223b6139 100644 --- a/src/strategy/values/AttackerCountValues.cpp +++ b/src/strategy/values/AttackerCountValues.cpp @@ -22,31 +22,57 @@ bool HasAggroValue::Calculate() while( ref ) { - ThreatMgr* threatMgr = ref->GetSource(); - Unit* attacker = threatMgr->GetOwner(); - Unit* victim = attacker->GetVictim(); - if (victim == bot && target == attacker) + ThreatMgr *threatManager = ref->GetSource(); + Unit *attacker = threatManager->GetOwner(); + if (attacker != target) { + ref = ref->next(); + continue; + } + Unit *victim = attacker->GetVictim(); + if (!victim) { + return true; + } + if ((victim == bot || (victim && victim->ToPlayer() && botAI->IsMainTank(victim->ToPlayer()))) && target == attacker) return true; - ref = ref->next(); } - - ref = target->GetThreatMgr().getCurrentVictim(); - if (ref) - { - if (Unit* victim = ref->getTarget()) - { - if (Player* pl = victim->ToPlayer()) - { - if (botAI->IsMainTank(pl)) - { - return true; - } - } - } - } - return false; + + // Unit* target = GetTarget(); + // if (!target) + // return true; + + // HostileReference *ref = bot->getHostileRefMgr().getFirst(); + // if (!ref) + // return true; // simulate as target is not atacking anybody yet + + // while( ref ) + // { + // ThreatMgr* threatMgr = ref->GetSource(); + // Unit* attacker = threatMgr->GetOwner(); + // Unit* victim = attacker->GetVictim(); + // if (victim == bot && target == attacker) + // return true; + + // ref = ref->next(); + // } + + // ref = target->GetThreatMgr().getCurrentVictim(); + // if (ref) + // { + // if (Unit* victim = ref->getTarget()) + // { + // if (Player* pl = victim->ToPlayer()) + // { + // if (botAI->IsMainTank(pl)) + // { + // return true; + // } + // } + // } + // } + + // return false; } uint8 AttackerCountValue::Calculate() diff --git a/src/strategy/values/AttackerCountValues.h b/src/strategy/values/AttackerCountValues.h index d8980469..0c62d97c 100644 --- a/src/strategy/values/AttackerCountValues.h +++ b/src/strategy/values/AttackerCountValues.h @@ -32,7 +32,7 @@ class MyAttackerCountValue : public Uint8CalculatedValue, public Qualified class HasAggroValue : public BoolCalculatedValue, public Qualified { public: - HasAggroValue(PlayerbotAI* botAI, std::string const name = "has agro") : BoolCalculatedValue(botAI, name) { } + HasAggroValue(PlayerbotAI* botAI, std::string const name = "has aggro") : BoolCalculatedValue(botAI, name) { } Unit* GetTarget(); bool Calculate() override;