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