mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 23:01:30 +00:00
Extended Movement Manager to have a FlyTo
This commit is contained in:
parent
855e592d22
commit
2bcaf2a476
@ -263,6 +263,146 @@ protected:
|
|||||||
double m_total_v_dist;
|
double m_total_v_dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FlyToCommand : public IMovementCommand {
|
||||||
|
public:
|
||||||
|
FlyToCommand(float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||||
|
{
|
||||||
|
m_distance_moved_since_correction = 0.0;
|
||||||
|
m_move_to_x = x;
|
||||||
|
m_move_to_y = y;
|
||||||
|
m_move_to_z = z;
|
||||||
|
m_move_to_mode = mob_movement_mode;
|
||||||
|
m_last_sent_time = 0.0;
|
||||||
|
m_last_sent_speed = 0;
|
||||||
|
m_started = false;
|
||||||
|
m_total_h_dist = 0.0;
|
||||||
|
m_total_v_dist = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~FlyToCommand()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mob_movement_manager
|
||||||
|
* @param mob
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob)
|
||||||
|
{
|
||||||
|
if (!mob->IsAIControlled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send a movement packet when you start moving
|
||||||
|
double current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
|
||||||
|
int current_speed = 0;
|
||||||
|
|
||||||
|
if (m_move_to_mode == MovementRunning) {
|
||||||
|
if (mob->IsFeared()) {
|
||||||
|
current_speed = mob->GetFearSpeed();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_speed = mob->GetRunspeed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_speed = mob->GetWalkspeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_started) {
|
||||||
|
m_started = true;
|
||||||
|
//rotate to the point
|
||||||
|
mob->SetMoving(true);
|
||||||
|
mob->SetHeading(mob->CalculateHeadingToTarget(m_move_to_x, m_move_to_y));
|
||||||
|
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
m_total_h_dist = DistanceNoZ(mob->GetPosition(), glm::vec4(m_move_to_x, m_move_to_y, 0.0f, 0.0f));
|
||||||
|
m_total_v_dist = m_move_to_z - mob->GetZ();
|
||||||
|
mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
}
|
||||||
|
|
||||||
|
//When speed changes
|
||||||
|
if (current_speed != m_last_sent_speed) {
|
||||||
|
m_distance_moved_since_correction = 0.0;
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If x seconds have passed without sending an update.
|
||||||
|
if (current_time - m_last_sent_time >= 0.5) {
|
||||||
|
m_distance_moved_since_correction = 0.0;
|
||||||
|
m_last_sent_speed = current_speed;
|
||||||
|
m_last_sent_time = current_time;
|
||||||
|
mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &p = mob->GetPosition();
|
||||||
|
glm::vec2 tar(m_move_to_x, m_move_to_y);
|
||||||
|
glm::vec2 pos(p.x, p.y);
|
||||||
|
double len = glm::distance(pos, tar);
|
||||||
|
if (len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mob->SetMoved(true);
|
||||||
|
|
||||||
|
glm::vec2 dir = tar - pos;
|
||||||
|
glm::vec2 ndir = glm::normalize(dir);
|
||||||
|
double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
|
||||||
|
|
||||||
|
if (distance_moved > len) {
|
||||||
|
if (mob->IsNPC()) {
|
||||||
|
entity_list.ProcessMove(mob->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
mob->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z);
|
||||||
|
|
||||||
|
if (RuleB(Map, FixZWhenPathing)) {
|
||||||
|
mob->FixZ();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glm::vec2 npos = pos + (ndir * static_cast<float>(distance_moved));
|
||||||
|
|
||||||
|
len -= distance_moved;
|
||||||
|
double total_distance_traveled = m_total_h_dist - len;
|
||||||
|
double start_z = m_move_to_z - m_total_v_dist;
|
||||||
|
double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist));
|
||||||
|
|
||||||
|
if (mob->IsNPC()) {
|
||||||
|
entity_list.ProcessMove(mob->CastToNPC(), npos.x, npos.y, z_at_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
mob->SetPosition(npos.x, npos.y, z_at_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Started() const
|
||||||
|
{
|
||||||
|
return m_started;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double m_distance_moved_since_correction;
|
||||||
|
double m_move_to_x;
|
||||||
|
double m_move_to_y;
|
||||||
|
double m_move_to_z;
|
||||||
|
MobMovementMode m_move_to_mode;
|
||||||
|
bool m_started;
|
||||||
|
|
||||||
|
double m_last_sent_time;
|
||||||
|
int m_last_sent_speed;
|
||||||
|
double m_total_h_dist;
|
||||||
|
double m_total_v_dist;
|
||||||
|
};
|
||||||
|
|
||||||
class SwimToCommand : public MoveToCommand {
|
class SwimToCommand : public MoveToCommand {
|
||||||
public:
|
public:
|
||||||
SwimToCommand(float x, float y, float z, MobMovementMode mob_movement_mode) : MoveToCommand(x, y, z, mob_movement_mode)
|
SwimToCommand(float x, float y, float z, MobMovementMode mob_movement_mode) : MoveToCommand(x, y, z, mob_movement_mode)
|
||||||
@ -921,6 +1061,8 @@ void MobMovementManager::FillCommandStruct(
|
|||||||
*/
|
*/
|
||||||
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode)
|
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||||
{
|
{
|
||||||
|
Mob *target=who->GetTarget();
|
||||||
|
|
||||||
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
if (!zone->HasMap() || !zone->HasWaterMap()) {
|
||||||
auto iter = _impl->Entries.find(who);
|
auto iter = _impl->Entries.find(who);
|
||||||
auto &ent = (*iter);
|
auto &ent = (*iter);
|
||||||
@ -936,6 +1078,16 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
|||||||
else if (who->IsUnderwaterOnly()) {
|
else if (who->IsUnderwaterOnly()) {
|
||||||
UpdatePathUnderwater(who, x, y, z, mob_movement_mode);
|
UpdatePathUnderwater(who, x, y, z, mob_movement_mode);
|
||||||
}
|
}
|
||||||
|
// If we can fly, and we have a target and we have LoS, simply fly to them.
|
||||||
|
// if we ever lose LoS we go back to mesh run mode.
|
||||||
|
else if (target && who->GetFlyMode() == GravityBehavior::Flying &&
|
||||||
|
who->CheckLosFN(x,y,z,target->GetSize())) {
|
||||||
|
auto iter = _impl->Entries.find(who);
|
||||||
|
auto &ent = (*iter);
|
||||||
|
|
||||||
|
PushFlyTo(ent.second, x, y, z, mob_movement_mode);
|
||||||
|
PushStopMoving(ent.second);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
UpdatePathGround(who, x, y, z, mob_movement_mode);
|
UpdatePathGround(who, x, y, z, mob_movement_mode);
|
||||||
}
|
}
|
||||||
@ -1275,6 +1427,18 @@ void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to,
|
|||||||
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mob_movement_mode)));
|
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mob_movement_mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ent
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param z
|
||||||
|
* @param mob_movement_mode
|
||||||
|
*/
|
||||||
|
void MobMovementManager::PushFlyTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||||
|
{
|
||||||
|
ent.Commands.push_back(std::unique_ptr<IMovementCommand>(new FlyToCommand(x, y, z, mob_movement_mode)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mob_movement_entry
|
* @param mob_movement_entry
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -85,6 +85,7 @@ private:
|
|||||||
void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading);
|
void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading);
|
||||||
void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
||||||
void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
||||||
|
void PushFlyTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode);
|
||||||
void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode);
|
void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode);
|
||||||
void PushStopMoving(MobMovementEntry &mob_movement_entry);
|
void PushStopMoving(MobMovementEntry &mob_movement_entry);
|
||||||
void PushEvadeCombat(MobMovementEntry &mob_movement_entry);
|
void PushEvadeCombat(MobMovementEntry &mob_movement_entry);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user