mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
move & knockback
This commit is contained in:
@@ -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.
|
* 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 "ObjectGuid.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "PlayerbotAI.h"
|
#include "PlayerbotAI.h"
|
||||||
@@ -23,6 +25,7 @@
|
|||||||
#include "PerformanceMonitor.h"
|
#include "PerformanceMonitor.h"
|
||||||
#include "PlayerbotDbStore.h"
|
#include "PlayerbotDbStore.h"
|
||||||
#include "PlayerbotMgr.h"
|
#include "PlayerbotMgr.h"
|
||||||
|
#include "PointMovementGenerator.h"
|
||||||
#include "PositionValue.h"
|
#include "PositionValue.h"
|
||||||
#include "ServerFacade.h"
|
#include "ServerFacade.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
@@ -32,6 +35,8 @@
|
|||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
#include "GuildMgr.h"
|
#include "GuildMgr.h"
|
||||||
#include "SayAction.h"
|
#include "SayAction.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
std::vector<std::string> PlayerbotAI::dispel_whitelist = {
|
std::vector<std::string> PlayerbotAI::dispel_whitelist = {
|
||||||
"mutating injection",
|
"mutating injection",
|
||||||
@@ -187,6 +192,10 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
|
|||||||
else
|
else
|
||||||
nextAICheckDelay = 0;
|
nextAICheckDelay = 0;
|
||||||
|
|
||||||
|
if (!bot || !bot->IsInWorld()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// cancel logout in combat
|
// cancel logout in combat
|
||||||
if (!bot->GetSession()) {
|
if (!bot->GetSession()) {
|
||||||
return;
|
return;
|
||||||
@@ -256,7 +265,7 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
|
|||||||
if (currentSpell && currentSpell->getState() == SPELL_STATE_CASTING && currentSpell->GetCastTime())
|
if (currentSpell && currentSpell->getState() == SPELL_STATE_CASTING && currentSpell->GetCastTime())
|
||||||
{
|
{
|
||||||
nextAICheckDelay = currentSpell->GetCastTime() + sPlayerbotAIConfig->reactDelay;
|
nextAICheckDelay = currentSpell->GetCastTime() + sPlayerbotAIConfig->reactDelay;
|
||||||
|
SetNextCheckDelay(nextAICheckDelay);
|
||||||
if (!CanUpdateAI())
|
if (!CanUpdateAI())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -759,8 +768,6 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
|
|||||||
}
|
}
|
||||||
case SMSG_MOVE_KNOCK_BACK: // handle knockbacks
|
case SMSG_MOVE_KNOCK_BACK: // handle knockbacks
|
||||||
{
|
{
|
||||||
// Peiru: Disable Knockback handling for now until spline crash can be resolved
|
|
||||||
/*
|
|
||||||
WorldPacket p(packet);
|
WorldPacket p(packet);
|
||||||
p.rpos(0);
|
p.rpos(0);
|
||||||
|
|
||||||
@@ -769,64 +776,77 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
|
|||||||
float vcos, vsin, horizontalSpeed, verticalSpeed = 0.f;
|
float vcos, vsin, horizontalSpeed, verticalSpeed = 0.f;
|
||||||
|
|
||||||
p >> guid.ReadAsPacked() >> counter >> vcos >> vsin >> horizontalSpeed >> verticalSpeed;
|
p >> guid.ReadAsPacked() >> counter >> vcos >> vsin >> horizontalSpeed >> verticalSpeed;
|
||||||
|
if (horizontalSpeed <= 0.1f) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
verticalSpeed = -verticalSpeed;
|
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
|
// stop casting
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
|
|
||||||
// stop movement
|
// stop movement
|
||||||
bot->StopMoving();
|
bot->StopMoving();
|
||||||
bot->GetMotionMaster()->Clear();
|
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
|
float moveTimeHalf = horizontalSpeed / Movement::gravity;
|
||||||
bot->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_FALLING);
|
float dist = 2 * moveTimeHalf * horizontalSpeed;
|
||||||
bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FORWARD);
|
Position dest = bot->GetPosition();
|
||||||
bot->m_movementInfo.AddMovementFlag(MOVEMENTFLAG_PENDING_STOP);
|
|
||||||
if (bot->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
|
|
||||||
bot->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
|
|
||||||
|
|
||||||
// copy MovementInfo
|
bot->MovePositionToFirstCollision(dest, dist, bot->GetRelativeAngle(bot->GetPositionX() + vcos, bot->GetPositionY() + vsin));
|
||||||
MovementInfo movementInfo = bot->m_movementInfo;
|
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
|
// Use a mmap raycast to get a valid destination.
|
||||||
WorldPacket ack(CMSG_MOVE_KNOCK_BACK_ACK);
|
// bot->GetMotionMaster()->MoveKnockbackFrom(fx, fy, horizontalSpeed, verticalSpeed);
|
||||||
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
|
// // set delay based on actual distance
|
||||||
SetJumpDestination(Position(fx, fy, fz, bot->GetOrientation()));
|
// 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();
|
//bot->SendHeartBeat();
|
||||||
|
|
||||||
*/
|
// */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -2298,8 +2318,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bot->ClearUnitState(UNIT_STATE_CHASE);
|
// bot->ClearUnitState(UNIT_STATE_CHASE);
|
||||||
bot->ClearUnitState(UNIT_STATE_FOLLOW);
|
// bot->ClearUnitState(UNIT_STATE_FOLLOW);
|
||||||
|
|
||||||
bool failWithDelay = false;
|
bool failWithDelay = false;
|
||||||
if (!bot->IsStandState())
|
if (!bot->IsStandState())
|
||||||
@@ -2386,11 +2406,11 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
|
|||||||
|
|
||||||
if (bot->isMoving() && spell->GetCastTime())
|
if (bot->isMoving() && spell->GetCastTime())
|
||||||
{
|
{
|
||||||
bot->StopMoving();
|
// bot->StopMoving();
|
||||||
// SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
|
SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
|
||||||
// spell->cancel();
|
spell->cancel();
|
||||||
//delete spell;
|
delete spell;
|
||||||
// return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// spell->m_targets.SetUnitTarget(target);
|
// 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))
|
if (bot->IsFlying() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bot->ClearUnitState(UNIT_STATE_CHASE);
|
// bot->ClearUnitState(UNIT_STATE_CHASE);
|
||||||
bot->ClearUnitState(UNIT_STATE_FOLLOW);
|
// bot->ClearUnitState(UNIT_STATE_FOLLOW);
|
||||||
|
|
||||||
bool failWithDelay = false;
|
bool failWithDelay = false;
|
||||||
if (!bot->IsStandState())
|
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())
|
if (bot->isMoving() && spell->GetCastTime())
|
||||||
{
|
{
|
||||||
bot->StopMoving();
|
// bot->StopMoving();
|
||||||
SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
|
SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
|
||||||
spell->cancel();
|
spell->cancel();
|
||||||
delete spell;
|
delete spell;
|
||||||
@@ -3236,14 +3256,16 @@ bool PlayerbotAI::AllowActive(ActivityType activityType)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// friends always active
|
// friends always active
|
||||||
for (auto& player : sRandomPlayerbotMgr->GetPlayers())
|
|
||||||
{
|
|
||||||
if (!player || !player->IsInWorld())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (player->GetSocial()->HasFriend(bot->GetGUID()))
|
// HasFriend sometimes cause crash, disable
|
||||||
return true;
|
// 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 (activityType == OUT_OF_PARTY_ACTIVITY || activityType == GRIND_ACTIVITY) //Many bots nearby. Do not do heavy area checks.
|
||||||
if (HasManyPlayersNearby())
|
if (HasManyPlayersNearby())
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ bool ServerFacade::IsDistanceLessOrEqualThan(float dist1, float dist2)
|
|||||||
void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force)
|
void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force)
|
||||||
{
|
{
|
||||||
float angle = bot->GetAngle(wo);
|
float angle = bot->GetAngle(wo);
|
||||||
if (!force && bot->isMoving())
|
// if (!force && bot->isMoving())
|
||||||
bot->SetFacingTo(bot->GetAngle(wo));
|
// bot->SetFacingTo(bot->GetAngle(wo));
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
bot->SetOrientation(angle);
|
bot->SetOrientation(angle);
|
||||||
bot->SendMovementFlagUpdate();
|
bot->SendMovementFlagUpdate();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* ServerFacade::GetChaseTarget(Unit* target)
|
Unit* ServerFacade::GetChaseTarget(Unit* target)
|
||||||
|
|||||||
@@ -160,12 +160,12 @@ bool CheckMountStateAction::Mount()
|
|||||||
{
|
{
|
||||||
uint32 secondmount = 40;
|
uint32 secondmount = 40;
|
||||||
|
|
||||||
if (bot->isMoving())
|
// if (bot->isMoving())
|
||||||
{
|
// {
|
||||||
bot->StopMoving();
|
// bot->StopMoving();
|
||||||
bot->GetMotionMaster()->Clear();
|
// bot->GetMotionMaster()->Clear();
|
||||||
bot->GetMotionMaster()->MoveIdle();
|
// // bot->GetMotionMaster()->MoveIdle();
|
||||||
}
|
// }
|
||||||
|
|
||||||
Player* master = GetMaster();
|
Player* master = GetMaster();
|
||||||
botAI->RemoveShapeshift();
|
botAI->RemoveShapeshift();
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ bool AttackAnythingAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
context->GetValue<ObjectGuid>("pull target")->Set(grindTarget->GetGUID());
|
context->GetValue<ObjectGuid>("pull target")->Set(grindTarget->GetGUID());
|
||||||
bot->GetMotionMaster()->Clear();
|
bot->GetMotionMaster()->Clear();
|
||||||
bot->StopMoving();
|
// bot->StopMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MovementActions.h"
|
#include "MovementActions.h"
|
||||||
|
#include "MotionMaster.h"
|
||||||
#include "MovementGenerator.h"
|
#include "MovementGenerator.h"
|
||||||
#include "ObjectDefines.h"
|
#include "ObjectDefines.h"
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
@@ -168,9 +169,11 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
|
|||||||
bot->CastStop();
|
bot->CastStop();
|
||||||
botAI->InterruptSpell();
|
botAI->InterruptSpell();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
bool generatePath = !bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) &&
|
||||||
!bot->IsFlying() && !bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !bot->IsInWater();
|
!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();
|
MotionMaster &mm = *bot->GetMotionMaster();
|
||||||
mm.Clear();
|
mm.Clear();
|
||||||
mm.MovePoint(mapId, x, y, z, generatePath);
|
mm.MovePoint(mapId, x, y, z, generatePath);
|
||||||
@@ -752,6 +755,9 @@ bool MovementAction::IsMovingAllowed()
|
|||||||
bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
|
bot->HasUnitState(UNIT_STATE_LOST_CONTROL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (bot->GetMotionMaster()->GetMotionSlot(MOTION_SLOT_CONTROLLED)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return bot->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLIGHT_MOTION_TYPE;
|
return bot->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLIGHT_MOTION_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user