diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 66641926..02f3af4f 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -2,6 +2,8 @@ * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. */ +#include "MoveSpline.h" +#include "MoveSplineInit.h" #include "ObjectGuid.h" #include "Player.h" #include "PlayerbotAI.h" @@ -23,6 +25,7 @@ #include "PerformanceMonitor.h" #include "PlayerbotDbStore.h" #include "PlayerbotMgr.h" +#include "PointMovementGenerator.h" #include "PositionValue.h" #include "ServerFacade.h" #include "SharedDefines.h" @@ -32,6 +35,8 @@ #include "Vehicle.h" #include "GuildMgr.h" #include "SayAction.h" +#include +#include std::vector PlayerbotAI::dispel_whitelist = { "mutating injection", @@ -187,6 +192,10 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) else nextAICheckDelay = 0; + if (!bot || !bot->IsInWorld()) { + return; + } + // cancel logout in combat if (!bot->GetSession()) { return; @@ -256,7 +265,7 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) if (currentSpell && currentSpell->getState() == SPELL_STATE_CASTING && currentSpell->GetCastTime()) { nextAICheckDelay = currentSpell->GetCastTime() + sPlayerbotAIConfig->reactDelay; - + SetNextCheckDelay(nextAICheckDelay); if (!CanUpdateAI()) return; } @@ -759,8 +768,6 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) } case SMSG_MOVE_KNOCK_BACK: // handle knockbacks { - // Peiru: Disable Knockback handling for now until spline crash can be resolved - /* WorldPacket p(packet); p.rpos(0); @@ -769,64 +776,77 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) float vcos, vsin, horizontalSpeed, verticalSpeed = 0.f; p >> guid.ReadAsPacked() >> counter >> vcos >> vsin >> horizontalSpeed >> verticalSpeed; + if (horizontalSpeed <= 0.1f) { + break; + } verticalSpeed = -verticalSpeed; - // calculate rough knockback time - float moveTimeHalf = verticalSpeed / 19.29f; - - float dis = 2 * moveTimeHalf * horizontalSpeed; - float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -verticalSpeed); - float disHalf = dis / 3.0f; - float ox, oy, oz; - bot->GetPosition(ox, oy, oz); - float fx = ox + dis * vcos; - float fy = oy + dis * vsin; - float fz = oz + 0.5f; - bot->GetMap()->GetObjectHitPos(bot->GetPhaseMask(), ox, oy, oz + max_height, fx, fy, fz, fx, fy, fz, -0.5f); - bot->UpdateAllowedPositionZ(fx, fy, fz); - // stop casting InterruptSpell(); // stop movement bot->StopMoving(); bot->GetMotionMaster()->Clear(); - bot->GetMotionMaster()->MoveIdle(); - // set delay based on actual distance - float newdis = sqrt(sServerFacade->GetDistance2d(bot, fx, fy)); - SetNextCheckDelay((uint32)((newdis / dis) * moveTimeHalf * 4 * IN_MILLISECONDS)); - // add moveflags - bot->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_FALLING); - bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FORWARD); - bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP); - if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION)) - bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); + float moveTimeHalf = horizontalSpeed / Movement::gravity; + float dist = 2 * moveTimeHalf * horizontalSpeed; + Position dest = bot->GetPosition(); - // copy MovementInfo - MovementInfo movementInfo = bot->m_movementInfo; + bot->MovePositionToFirstCollision(dest, dist, bot->GetRelativeAngle(bot->GetPositionX() + vcos, bot->GetPositionY() + vsin)); + float x, y, z; + x = dest.GetPositionX(); + y = dest.GetPositionY(); + z = dest.GetPositionZ(); + // char speak[1024]; + // sprintf(speak, "SMSG_MOVE_KNOCK_BACK: %.2f %.2f, horizontalSpeed: %.2f, verticalSpeed: %.2f, tX: %.2f, tY: %.2f, tZ: %.2f, relativeAngle: %.2f, orientation: %.2f", + // vcos, vsin, horizontalSpeed, verticalSpeed, x, y, z, bot->GetRelativeAngle(vcos, vsin), bot->GetOrientation()); + // bot->Say(speak, LANG_UNIVERSAL); + // bot->GetClosePoint(x, y, z, bot->GetObjectSize(), dist, bot->GetAngle(vcos, vsin)); + bot->GetMotionMaster()->MoveJump(x, y, z, horizontalSpeed, verticalSpeed, 0, bot->GetSelectedUnit()); + // bot->GetMotionMaster()->MoveIdle(); + // Position dest = bot->GetPosition(); + // float moveTimeHalf = verticalSpeed / Movement::gravity; + // float dist = 2 * moveTimeHalf * horizontalSpeed; + // float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -verticalSpeed); - // send ack - WorldPacket ack(CMSG_MOVE_KNOCK_BACK_ACK); - movementInfo.jump.cosAngle = vcos; - movementInfo.jump.sinAngle = vsin; - movementInfo.jump.zspeed = -verticalSpeed; - movementInfo.jump.xyspeed = horizontalSpeed; - ack << bot->GetGUID().WriteAsPacked(); - bot->m_mover->BuildMovementPacket(&ack); - ack << movementInfo.jump.sinAngle; - ack << movementInfo.jump.cosAngle; - ack << movementInfo.jump.xyspeed; - ack << movementInfo.jump.zspeed; - bot->GetSession()->HandleMoveKnockBackAck(ack); + // Use a mmap raycast to get a valid destination. + // bot->GetMotionMaster()->MoveKnockbackFrom(fx, fy, horizontalSpeed, verticalSpeed); - // set jump destination for MSG_LAND packet - SetJumpDestination(Position(fx, fy, fz, bot->GetOrientation())); + // // set delay based on actual distance + // float newdis = sqrt(sServerFacade->GetDistance2d(bot, fx, fy)); + // SetNextCheckDelay((uint32)((newdis / dis) * moveTimeHalf * 4 * IN_MILLISECONDS)); + + // // add moveflags + // bot->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_FALLING); + // bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FORWARD); + // bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP); + // if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION)) + // bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); + + // // copy MovementInfo + // MovementInfo movementInfo = bot->m_movementInfo; + + // // send ack + // WorldPacket ack(CMSG_MOVE_KNOCK_BACK_ACK); + // movementInfo.jump.cosAngle = vcos; + // movementInfo.jump.sinAngle = vsin; + // movementInfo.jump.zspeed = -verticalSpeed; + // movementInfo.jump.xyspeed = horizontalSpeed; + // ack << bot->GetGUID().WriteAsPacked(); + // bot->m_mover->BuildMovementPacket(&ack); + // ack << movementInfo.jump.sinAngle; + // ack << movementInfo.jump.cosAngle; + // ack << movementInfo.jump.xyspeed; + // ack << movementInfo.jump.zspeed; + // bot->GetSession()->HandleMoveKnockBackAck(ack); + + // // set jump destination for MSG_LAND packet + // SetJumpDestination(Position(fx, fy, fz, bot->GetOrientation())); //bot->SendHeartBeat(); - */ + // */ return; } default: @@ -2298,8 +2318,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) return false; } - bot->ClearUnitState(UNIT_STATE_CHASE); - bot->ClearUnitState(UNIT_STATE_FOLLOW); + // bot->ClearUnitState(UNIT_STATE_CHASE); + // bot->ClearUnitState(UNIT_STATE_FOLLOW); bool failWithDelay = false; if (!bot->IsStandState()) @@ -2386,11 +2406,11 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) if (bot->isMoving() && spell->GetCastTime()) { - bot->StopMoving(); -// SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown); -// spell->cancel(); - //delete spell; -// return false; + // bot->StopMoving(); + SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown); + spell->cancel(); + delete spell; + return false; } // spell->m_targets.SetUnitTarget(target); @@ -2481,8 +2501,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, float x, float y, float z, Item* ite if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) return false; - bot->ClearUnitState(UNIT_STATE_CHASE); - bot->ClearUnitState(UNIT_STATE_FOLLOW); + // bot->ClearUnitState(UNIT_STATE_CHASE); + // bot->ClearUnitState(UNIT_STATE_FOLLOW); bool failWithDelay = false; if (!bot->IsStandState()) @@ -2540,7 +2560,7 @@ bool PlayerbotAI::CastSpell(uint32 spellId, float x, float y, float z, Item* ite if (bot->isMoving() && spell->GetCastTime()) { - bot->StopMoving(); + // bot->StopMoving(); SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown); spell->cancel(); delete spell; @@ -3236,14 +3256,16 @@ bool PlayerbotAI::AllowActive(ActivityType activityType) return true; // friends always active - for (auto& player : sRandomPlayerbotMgr->GetPlayers()) - { - if (!player || !player->IsInWorld()) - continue; + + // HasFriend sometimes cause crash, disable + // for (auto& player : sRandomPlayerbotMgr->GetPlayers()) + // { + // if (!player || !player->IsInWorld()) + // continue; - if (player->GetSocial()->HasFriend(bot->GetGUID())) - return true; - } + // if (player->GetSocial()->HasFriend(bot->GetGUID())) + // return true; + // } if (activityType == OUT_OF_PARTY_ACTIVITY || activityType == GRIND_ACTIVITY) //Many bots nearby. Do not do heavy area checks. if (HasManyPlayersNearby()) diff --git a/src/ServerFacade.cpp b/src/ServerFacade.cpp index 5367384e..2c41edfc 100644 --- a/src/ServerFacade.cpp +++ b/src/ServerFacade.cpp @@ -46,13 +46,13 @@ bool ServerFacade::IsDistanceLessOrEqualThan(float dist1, float dist2) void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force) { float angle = bot->GetAngle(wo); - if (!force && bot->isMoving()) - bot->SetFacingTo(bot->GetAngle(wo)); - else - { + // if (!force && bot->isMoving()) + // bot->SetFacingTo(bot->GetAngle(wo)); + // else + // { bot->SetOrientation(angle); bot->SendMovementFlagUpdate(); - } + // } } Unit* ServerFacade::GetChaseTarget(Unit* target) diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 6c6295c4..fdc22d26 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -160,12 +160,12 @@ bool CheckMountStateAction::Mount() { uint32 secondmount = 40; - if (bot->isMoving()) - { - bot->StopMoving(); - bot->GetMotionMaster()->Clear(); - bot->GetMotionMaster()->MoveIdle(); - } + // if (bot->isMoving()) + // { + // bot->StopMoving(); + // bot->GetMotionMaster()->Clear(); + // // bot->GetMotionMaster()->MoveIdle(); + // } Player* master = GetMaster(); botAI->RemoveShapeshift(); diff --git a/src/strategy/actions/ChooseTargetActions.cpp b/src/strategy/actions/ChooseTargetActions.cpp index 7810939d..8bf0faf5 100644 --- a/src/strategy/actions/ChooseTargetActions.cpp +++ b/src/strategy/actions/ChooseTargetActions.cpp @@ -107,7 +107,7 @@ bool AttackAnythingAction::Execute(Event event) { context->GetValue("pull target")->Set(grindTarget->GetGUID()); bot->GetMotionMaster()->Clear(); - bot->StopMoving(); + // bot->StopMoving(); } } } diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 93521494..0057ac36 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -3,6 +3,7 @@ */ #include "MovementActions.h" +#include "MotionMaster.h" #include "MovementGenerator.h" #include "ObjectDefines.h" #include "ObjectGuid.h" @@ -168,9 +169,11 @@ 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->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater(); + // char speak[100]; + // sprintf(speak, "Move to : (%.2f, %.2f, %.2f), generatePath: %d", x, y, z, generatePath); + // bot->Say(speak, LANG_UNIVERSAL); MotionMaster &mm = *bot->GetMotionMaster(); mm.Clear(); mm.MovePoint(mapId, x, y, z, generatePath); @@ -752,6 +755,9 @@ bool MovementAction::IsMovingAllowed() bot->HasUnitState(UNIT_STATE_LOST_CONTROL)) return false; + if (bot->GetMotionMaster()->GetMotionSlot(MOTION_SLOT_CONTROLLED)) { + return false; + } return bot->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLIGHT_MOTION_TYPE; }