move & knockback

This commit is contained in:
Yunfan Li
2023-09-02 10:43:13 +08:00
parent 62e49a966d
commit 5f5faf00cd
5 changed files with 103 additions and 75 deletions

View File

@@ -2,6 +2,8 @@
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, 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 <cmath>
#include <string>
std::vector<std::string> 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;
if (player->GetSocial()->HasFriend(bot->GetGUID()))
return true;
}
// HasFriend sometimes cause crash, disable
// for (auto& player : sRandomPlayerbotMgr->GetPlayers())
// {
// if (!player || !player->IsInWorld())
// continue;
// 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())

View File

@@ -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)

View File

@@ -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();

View File

@@ -107,7 +107,7 @@ bool AttackAnythingAction::Execute(Event event)
{
context->GetValue<ObjectGuid>("pull target")->Set(grindTarget->GetGUID());
bot->GetMotionMaster()->Clear();
bot->StopMoving();
// bot->StopMoving();
}
}
}

View File

@@ -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;
}