Bunch of bug fixes, guard behavior works again

This commit is contained in:
KimLS 2018-10-13 23:53:16 -07:00
parent 18ec09a79e
commit d0685556e8
14 changed files with 120 additions and 129 deletions

View File

@ -280,7 +280,7 @@ void Bot::ChangeBotArcherWeapons(bool isArcher) {
void Bot::Sit() { void Bot::Sit() {
if(IsMoving()) { if(IsMoving()) {
moved = false; moved = false;
SetCurrentSpeed(0); StopNavigation();
} }
SetAppearance(eaSitting); SetAppearance(eaSitting);
@ -2999,7 +2999,7 @@ void Bot::PetAIProcess() {
botPet->SetHeading(botPet->GetTarget()->GetHeading()); botPet->SetHeading(botPet->GetTarget()->GetHeading());
if(moved) { if(moved) {
moved = false; moved = false;
SetCurrentSpeed(0); StopNavigation();
botPet->SendPosition(); botPet->SendPosition();
botPet->SetMoving(false); botPet->SetMoving(false);
} }
@ -3027,7 +3027,7 @@ void Bot::PetAIProcess() {
botPet->SetHeading(botPet->GetTarget()->GetHeading()); botPet->SetHeading(botPet->GetTarget()->GetHeading());
if(moved) { if(moved) {
moved = false; moved = false;
SetCurrentSpeed(0); StopNavigation();
botPet->SendPosition(); botPet->SendPosition();
botPet->SetMoving(false); botPet->SetMoving(false);
} }

View File

@ -10041,7 +10041,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
mypet->SetPetOrder(SPO_Guard); mypet->SetPetOrder(SPO_Guard);
mypet->CastToNPC()->SaveGuardSpot(); mypet->CastToNPC()->SaveGuardSpot();
if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down
mypet->SetCurrentSpeed(0); mypet->StopNavigation();
if (mypet->IsPetStop()) { if (mypet->IsPetStop()) {
mypet->SetPetStop(false); mypet->SetPetStop(false);
SetPetCommandState(PET_BUTTON_STOP, 0); SetPetCommandState(PET_BUTTON_STOP, 0);
@ -10343,7 +10343,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
mypet->SetPetStop(false); mypet->SetPetStop(false);
} else { } else {
mypet->SetPetStop(true); mypet->SetPetStop(true);
mypet->SetCurrentSpeed(0); mypet->StopNavigation();
mypet->SetTarget(nullptr); mypet->SetTarget(nullptr);
if (mypet->IsPetRegroup()) { if (mypet->IsPetRegroup()) {
mypet->SetPetRegroup(false); mypet->SetPetRegroup(false);
@ -10359,7 +10359,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
mypet->SetPetStop(true); mypet->SetPetStop(true);
mypet->SetCurrentSpeed(0); mypet->StopNavigation();
mypet->SetTarget(nullptr); mypet->SetTarget(nullptr);
mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING); mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING);
if (mypet->IsPetRegroup()) { if (mypet->IsPetRegroup()) {

View File

@ -1271,48 +1271,11 @@ void command_movement(Client *c, const Seperator *sep)
if (strcasecmp(sep->arg[1], "stats") == 0) if (strcasecmp(sep->arg[1], "stats") == 0)
{ {
//mgr.DumpStats(c); mgr.DumpStats(c);
} }
else if (strcasecmp(sep->arg[1], "clearstats") == 0) else if (strcasecmp(sep->arg[1], "clearstats") == 0)
{ {
//mgr.ClearStats(); mgr.ClearStats();
}
if (strcasecmp(sep->arg[1], "test") == 0)
{
auto target = c->GetTarget();
if (!target) {
c->Message(0, "Requires target");
}
mgr.NavigateTo(target, c->GetX(), c->GetY(), c->GetZ(), false, MovementRunning);
//auto heading = target->CalculateHeadingToTarget(c->GetX(), c->GetY());
//mgr.SendCommandToClients(target, 0.0f, 0.0f, 0.0f, atof(sep->arg[2]), 0, ClientRangeAny);
//mgr.RotateTo(target, heading);
//double a1 = atof(sep->arg[2]);
//double a2 = atof(sep->arg[3]);
//double a3 = atof(sep->arg[4]);
//double a4 = atof(sep->arg[5]);
//int a5 = atoi(sep->arg[6]);
//
////PlayerPositionUpdateServer_Struct
//EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
//PlayerPositionUpdateServer_Struct *spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer;
//
//memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct));
//spu->spawn_id = target->GetID();
//spu->x_pos = FloatToEQ19(target->GetX());
//spu->y_pos = FloatToEQ19(target->GetY());
//spu->z_pos = FloatToEQ19(target->GetZ());
//spu->heading = FloatToEQ12(target->GetHeading());
//spu->delta_x = FloatToEQ13(a1);
//spu->delta_y = FloatToEQ13(a2);
//spu->delta_z = FloatToEQ13(a3);
//spu->delta_heading = FloatToEQ10(a4);
//spu->animation = a5;
//
//c->QueuePacket(&outapp);
} }
else { else {
c->Message(0, "Usage: #movement stats/clearstats"); c->Message(0, "Usage: #movement stats/clearstats");

View File

@ -1471,7 +1471,7 @@ void Merc::AI_Process() {
if(moved) { if(moved) {
moved = false; moved = false;
SetCurrentSpeed(0); StopNavigation();
} }
} }
@ -1513,7 +1513,7 @@ void Merc::AI_Process() {
SetRunAnimSpeed(0); SetRunAnimSpeed(0);
if(moved) { if(moved) {
SetCurrentSpeed(0); StopNavigation();
} }
} }
@ -1771,7 +1771,7 @@ void Merc::AI_Process() {
else { else {
if (moved) { if (moved) {
moved = false; moved = false;
SetCurrentSpeed(0); StopNavigation();
} }
} }
} }

View File

@ -1434,16 +1434,14 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
} }
void Mob::StopMoving() { void Mob::StopMoving() {
FixZ(); StopNavigation();
SetCurrentSpeed(0);
if (moved) if (moved)
moved = false; moved = false;
} }
void Mob::StopMoving(float new_heading) { void Mob::StopMoving(float new_heading) {
SetHeading(new_heading); StopNavigation();
FixZ(); RotateTo(new_heading);
SetCurrentSpeed(0);
if (moved) if (moved)
moved = false; moved = false;
} }
@ -2706,10 +2704,10 @@ void Mob::FaceTarget(Mob* mob_to_face /*= 0*/) {
float new_heading = CalculateHeadingToTarget(faced_mob->GetX(), faced_mob->GetY()); float new_heading = CalculateHeadingToTarget(faced_mob->GetX(), faced_mob->GetY());
if(current_heading != new_heading) { if(current_heading != new_heading) {
if (IsEngaged() || IsRunning()) { if (IsEngaged() || IsRunning()) {
mMovementManager->RotateTo(this, new_heading); RotateToRunning(new_heading);
} }
else { else {
mMovementManager->RotateTo(this, new_heading, MovementWalking); RotateToWalking(new_heading);
} }
} }
@ -5765,18 +5763,6 @@ void Mob::SendRemovePlayerState(PlayerState old_state)
safe_delete(app); safe_delete(app);
} }
void Mob::SetCurrentSpeed(int in){
if (current_speed != in)
{
current_speed = in;
if (in == 0) {
SetRunAnimSpeed(0);
SetMoving(false);
SendPosition();
}
}
}
int32 Mob::GetMeleeMitigation() { int32 Mob::GetMeleeMitigation() {
int32 mitigation = 0; int32 mitigation = 0;
mitigation += spellbonuses.MeleeMitigationEffect; mitigation += spellbonuses.MeleeMitigationEffect;

View File

@ -549,7 +549,6 @@ public:
virtual void Gate(uint8 bindnum = 0); virtual void Gate(uint8 bindnum = 0);
int GetWalkspeed() const { return(_GetWalkSpeed()); } int GetWalkspeed() const { return(_GetWalkSpeed()); }
int GetRunspeed() const { return(_GetRunSpeed()); } int GetRunspeed() const { return(_GetRunSpeed()); }
void SetCurrentSpeed(int in);
int GetBaseRunspeed() const { return base_runspeed; } int GetBaseRunspeed() const { return base_runspeed; }
int GetBaseWalkspeed() const { return base_walkspeed; } int GetBaseWalkspeed() const { return base_walkspeed; }
int GetBaseFearSpeed() const { return base_fearspeed; } int GetBaseFearSpeed() const { return base_fearspeed; }
@ -972,6 +971,9 @@ public:
void WalkTo(float x, float y, float z); void WalkTo(float x, float y, float z);
void RunTo(float x, float y, float z); void RunTo(float x, float y, float z);
void NavigateTo(float x, float y, float z); void NavigateTo(float x, float y, float z);
void RotateTo(float new_heading);
void RotateToWalking(float new_heading);
void RotateToRunning(float new_heading);
void StopNavigation(); void StopNavigation();
float CalculateDistance(float x, float y, float z); float CalculateDistance(float x, float y, float z);
float GetGroundZ(float new_x, float new_y, float z_offset=0.0); float GetGroundZ(float new_x, float new_y, float z_offset=0.0);

View File

@ -372,7 +372,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
//stop moving if were casting a spell and were not a bard... //stop moving if were casting a spell and were not a bard...
if(!IsBardSong(AIspells[i].spellid)) { if(!IsBardSong(AIspells[i].spellid)) {
SetCurrentSpeed(0); StopNavigation();
} }
return CastSpell(AIspells[i].spellid, tar->GetID(), EQEmu::CastingSlot::Gem2, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, &(AIspells[i].resist_adjust)); return CastSpell(AIspells[i].spellid, tar->GetID(), EQEmu::CastingSlot::Gem2, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, &(AIspells[i].resist_adjust));
@ -715,7 +715,7 @@ void Client::AI_SpellCast()
{ {
if(!IsBardSong(spell_to_cast)) if(!IsBardSong(spell_to_cast))
{ {
SetCurrentSpeed(0); StopNavigation();
} }
CastSpell(spell_to_cast, tar->GetID(), slot_to_use); CastSpell(spell_to_cast, tar->GetID(), slot_to_use);
return; return;
@ -729,7 +729,7 @@ void Client::AI_SpellCast()
{ {
if(!IsBardSong(spell_to_cast)) if(!IsBardSong(spell_to_cast))
{ {
SetCurrentSpeed(0); StopNavigation();
} }
CastSpell(spell_to_cast, tar->GetID(), slot_to_use); CastSpell(spell_to_cast, tar->GetID(), slot_to_use);
return; return;
@ -787,9 +787,8 @@ void Client::AI_Process()
if (IsRooted()) { if (IsRooted()) {
//make sure everybody knows were not moving, for appearance sake //make sure everybody knows were not moving, for appearance sake
if (IsMoving()) { if (IsMoving()) {
if (GetTarget()) FaceTarget();
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); StopNavigation();
SetCurrentSpeed(0);
} }
//continue on to attack code, ensuring that we execute the engaged code //continue on to attack code, ensuring that we execute the engaged code
engaged = true; engaged = true;
@ -797,7 +796,7 @@ void Client::AI_Process()
else { else {
if (AI_movement_timer->Check()) { if (AI_movement_timer->Check()) {
// Check if we have reached the last fear point // Check if we have reached the last fear point
if(IsPositionEqual(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget)) { if(IsPositionEqualWithinCertainZ(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget, 5.0f)) {
CalculateNewFearpoint(); CalculateNewFearpoint();
} }
@ -844,10 +843,8 @@ void Client::AI_Process()
if (AI_movement_timer->Check()) { if (AI_movement_timer->Check()) {
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) !=
m_Position.w) { m_Position.w) {
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); FaceTarget();
SendPosition();
} }
SetCurrentSpeed(0);
} }
if (GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) { if (GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
if (attack_timer.Check()) { if (attack_timer.Check()) {
@ -874,8 +871,7 @@ void Client::AI_Process()
} }
else if(IsMoving()) else if(IsMoving())
{ {
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY())); FaceTarget();
SetCurrentSpeed(0);
} }
} }
AI_SpellCast(); AI_SpellCast();
@ -1070,9 +1066,8 @@ void Mob::AI_Process() {
!IsPetRegroup()) { !IsPetRegroup()) {
//make sure everybody knows were not moving, for appearance sake //make sure everybody knows were not moving, for appearance sake
if (IsMoving()) { if (IsMoving()) {
if (target) FaceTarget();
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY())); StopNavigation();
SetCurrentSpeed(0);
moved = false; moved = false;
} }
//continue on to attack code, ensuring that we execute the engaged code //continue on to attack code, ensuring that we execute the engaged code
@ -1081,7 +1076,7 @@ void Mob::AI_Process() {
else { else {
if (AI_movement_timer->Check()) { if (AI_movement_timer->Check()) {
// Check if we have reached the last fear point // Check if we have reached the last fear point
if (IsPositionEqual(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget)) { if (IsPositionEqualWithinCertainZ(glm::vec3(GetX(), GetY(), GetZ()), m_FearWalkTarget, 5.0f)) {
// Calculate a new point to run to // Calculate a new point to run to
CalculateNewFearpoint(); CalculateNewFearpoint();
} }
@ -1403,8 +1398,7 @@ void Mob::AI_Process() {
} }
else if (IsMoving()) { else if (IsMoving()) {
SetHeading(CalculateHeadingToTarget(target->GetX(), target->GetY())); FaceTarget();
SetCurrentSpeed(0);
} }
} }
} }
@ -1490,9 +1484,7 @@ void Mob::AI_Process() {
* Distance: >= 450 (Snap to owner) * Distance: >= 450 (Snap to owner)
*/ */
if (distance_to_owner >= 202500 || z_distance > 100) { if (distance_to_owner >= 202500 || z_distance > 100) {
m_Position = pet_owner_position; Teleport(pet_owner_position);
SendPositionUpdate();
moved = true;
} }
else { else {
@ -1562,7 +1554,7 @@ void Mob::AI_Process() {
} }
else { else {
moved = false; moved = false;
SetCurrentSpeed(0); StopNavigation();
} }
} }
} }
@ -1688,9 +1680,6 @@ void NPC::AI_DoMovement() {
if (m_Position.x == roambox_destination_x && m_Position.y == roambox_destination_y) { if (m_Position.x == roambox_destination_x && m_Position.y == roambox_destination_y) {
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
SetMoving(false);
this->FixZ();
SendPosition();
} }
return; return;
@ -1721,14 +1710,10 @@ void NPC::AI_DoMovement() {
SetWaypointPause(); SetWaypointPause();
SetAppearance(eaStanding, false); SetAppearance(eaStanding, false);
SetMoving(false);
if (m_CurrentWayPoint.w >= 0.0) { if (m_CurrentWayPoint.w >= 0.0) {
SetHeading(m_CurrentWayPoint.w); RotateTo(m_CurrentWayPoint.w);
} }
this->FixZ();
SendPosition();
//kick off event_waypoint arrive //kick off event_waypoint arrive
char temp[16]; char temp[16];
sprintf(temp, "%d", cur_wp); sprintf(temp, "%d", cur_wp);
@ -1771,7 +1756,7 @@ void NPC::AI_DoMovement() {
} }
else if (IsGuarding()) { else if (IsGuarding()) {
bool at_gp = IsPositionEqual(m_Position, m_GuardPoint); bool at_gp = IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f);
if (at_gp) { if (at_gp) {
@ -1786,12 +1771,11 @@ void NPC::AI_DoMovement() {
ClearFeignMemory(); ClearFeignMemory();
moved = false; moved = false;
if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5 * 5) { if (GetTarget() == nullptr || DistanceSquared(m_Position, GetTarget()->GetPosition()) >= 5 * 5) {
SetHeading(m_GuardPoint.w); RotateTo(m_GuardPoint.w);
} }
else { else {
FaceTarget(GetTarget()); FaceTarget(GetTarget());
} }
SetCurrentSpeed(0);
SetAppearance(GetGuardPointAnim()); SetAppearance(GetGuardPointAnim());
} }
} }
@ -1925,8 +1909,7 @@ void Mob::AI_Event_NoLongerEngaged() {
// except if we're a pet, then we might run into some issues with pets backing off when they should immediately be moving // except if we're a pet, then we might run into some issues with pets backing off when they should immediately be moving
if(!IsPet()) if(!IsPet())
{ {
SetRunAnimSpeed(0); StopNavigation();
SendPosition();
} }
ClearRampage(); ClearRampage();

View File

@ -48,6 +48,7 @@ public:
if (!m_started) { if (!m_started) {
m_started = true; m_started = true;
m->SetMoving(true);
if (rotate_to_speed > 0.0 && rotate_to_speed <= 25.0) { //send basic rotation if (rotate_to_speed > 0.0 && rotate_to_speed <= 25.0) { //send basic rotation
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, m_rotate_to_dir * rotate_to_speed, 0, ClientRangeClose); mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, m_rotate_to_dir * rotate_to_speed, 0, ClientRangeClose);
@ -71,7 +72,8 @@ public:
if (td >= dist) { if (td >= dist) {
m->SetHeading(to); m->SetHeading(to);
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); m->SetMoving(false);
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium);
return true; return true;
} }
@ -129,6 +131,7 @@ public:
if (!m_started) { if (!m_started) {
m_started = true; m_started = true;
//rotate to the point //rotate to the point
m->SetMoving(true);
m->SetHeading(m->CalculateHeadingToTarget(m_move_to_x, m_move_to_y)); m->SetHeading(m->CalculateHeadingToTarget(m_move_to_x, m_move_to_y));
m->TryFixZ(); m->TryFixZ();
@ -165,6 +168,7 @@ public:
glm::vec2 pos(p.x, p.y); glm::vec2 pos(p.x, p.y);
double len = glm::distance(pos, tar); double len = glm::distance(pos, tar);
if (len == 0) { if (len == 0) {
m->SetMoving(false);
return true; return true;
} }
@ -172,7 +176,7 @@ public:
glm::vec2 dir = tar - pos; glm::vec2 dir = tar - pos;
glm::vec2 ndir = glm::normalize(dir); glm::vec2 ndir = glm::normalize(dir);
double distance_moved = frame_time * current_speed * 0.4f * 1.4f; double distance_moved = frame_time * current_speed * 0.4f * 1.45f;
if (distance_moved > len) { if (distance_moved > len) {
m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z); m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z);
@ -182,6 +186,7 @@ public:
} }
m->TryFixZ(); m->TryFixZ();
m->SetMoving(false);
return true; return true;
} }
else { else {
@ -272,7 +277,7 @@ public:
return true; return true;
} }
mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium);
return true; return true;
} }
@ -284,12 +289,14 @@ public:
struct MovementStats struct MovementStats
{ {
MovementStats() { MovementStats() {
LastResetTime = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
TotalSent = 0ULL; TotalSent = 0ULL;
TotalSentMovement = 0ULL; TotalSentMovement = 0ULL;
TotalSentPosition = 0ULL; TotalSentPosition = 0ULL;
TotalSentHeading = 0ULL; TotalSentHeading = 0ULL;
} }
double LastResetTime;
uint64_t TotalSent; uint64_t TotalSent;
uint64_t TotalSentMovement; uint64_t TotalSentMovement;
uint64_t TotalSentPosition; uint64_t TotalSentPosition;
@ -302,12 +309,14 @@ struct NavigateTo
navigate_to_x = 0.0; navigate_to_x = 0.0;
navigate_to_y = 0.0; navigate_to_y = 0.0;
navigate_to_z = 0.0; navigate_to_z = 0.0;
navigate_to_heading = 0.0;
last_set_time = 0.0; last_set_time = 0.0;
} }
double navigate_to_x; double navigate_to_x;
double navigate_to_y; double navigate_to_y;
double navigate_to_z; double navigate_to_z;
double navigate_to_heading;
double last_set_time; double last_set_time;
}; };
@ -417,24 +426,28 @@ void MobMovementManager::Teleport(Mob *who, float x, float y, float z, float hea
PushTeleportTo(ent.second, x, y, z, heading); PushTeleportTo(ent.second, x, y, z, heading);
} }
void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, bool force, MobMovementMode mode) void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode)
{ {
auto iter = _impl->Entries.find(who); auto iter = _impl->Entries.find(who);
auto &ent = (*iter); auto &ent = (*iter);
auto &nav = ent.second.NavigateTo; auto &nav = ent.second.NavigateTo;
double current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0; double current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
if (force || (current_time - nav.last_set_time) > 0.5) { if ((current_time - nav.last_set_time) > 0.5) {
//Can potentially recalc //Can potentially recalc
auto within = IsPositionWithinSimpleCylinder(glm::vec3(x, y, z), glm::vec3(nav.navigate_to_x, nav.navigate_to_y, nav.navigate_to_z), 1.5f, 6.0f); auto within = IsPositionWithinSimpleCylinder(glm::vec3(x, y, z), glm::vec3(nav.navigate_to_x, nav.navigate_to_y, nav.navigate_to_z), 1.5f, 6.0f);
auto heading_match = IsHeadingEqual(0.0, nav.navigate_to_heading);
if (false == within) {
if (false == within || false == heading_match) {
ent.second.Commands.clear();
//Path is no longer valid, calculate a new path //Path is no longer valid, calculate a new path
UpdatePath(who, x, y, z, mode); UpdatePath(who, x, y, z, mode);
nav.navigate_to_x = x; nav.navigate_to_x = x;
nav.navigate_to_y = y; nav.navigate_to_y = y;
nav.navigate_to_z = z; nav.navigate_to_z = z;
nav.navigate_to_heading = 0.0;
nav.last_set_time = current_time; nav.last_set_time = current_time;
} }
} }
@ -455,7 +468,7 @@ void MobMovementManager::StopNavigation(Mob *who) {
} }
who->TryFixZ(); who->TryFixZ();
SendCommandToClients(who, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); SendCommandToClients(who, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium);
ent.second.Commands.clear(); ent.second.Commands.clear();
} }
@ -492,19 +505,19 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float
bool match = false; bool match = false;
if (range & ClientRangeClose) { if (range & ClientRangeClose) {
if (dist < 200.0f) { if (dist < 250.0f) {
match = true; match = true;
} }
} }
if (!match && range & ClientRangeMedium) { if (!match && range & ClientRangeMedium) {
if (dist >= 200.0f && dist < 1000.0f) { if (dist >= 250.0f && dist < 1500.0f) {
match = true; match = true;
} }
} }
if (!match && range & ClientRangeLong) { if (!match && range & ClientRangeLong) {
if (dist >= 1000.0f) { if (dist >= 1500.0f) {
match = true; match = true;
} }
} }
@ -542,6 +555,27 @@ float MobMovementManager::FixHeading(float in)
return h; return h;
} }
void MobMovementManager::DumpStats(Client *to)
{
auto current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
auto total_time = current_time - _impl->Stats.LastResetTime;
to->Message(MT_System, "Dumping Movement Stats:");
to->Message(MT_System, "Total Sent: %u (%.2f / sec)", _impl->Stats.TotalSent, static_cast<double>(_impl->Stats.TotalSent) / total_time);
to->Message(MT_System, "Total Heading: %u (%.2f / sec)", _impl->Stats.TotalSentHeading, static_cast<double>(_impl->Stats.TotalSentHeading) / total_time);
to->Message(MT_System, "Total Movement: %u (%.2f / sec)", _impl->Stats.TotalSentMovement, static_cast<double>(_impl->Stats.TotalSentMovement) / total_time);
to->Message(MT_System, "Total Position: %u (%.2f / sec)", _impl->Stats.TotalSentPosition, static_cast<double>(_impl->Stats.TotalSentPosition) / total_time);
}
void MobMovementManager::ClearStats()
{
_impl->Stats.LastResetTime = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
_impl->Stats.TotalSent = 0;
_impl->Stats.TotalSentHeading = 0;
_impl->Stats.TotalSentMovement = 0;
_impl->Stats.TotalSentPosition = 0;
}
void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim) void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim)
{ {
memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct));

View File

@ -39,13 +39,12 @@ public:
void RotateTo(Mob *who, float to, MobMovementMode mode = MovementRunning); void RotateTo(Mob *who, float to, MobMovementMode mode = MovementRunning);
void Teleport(Mob *who, float x, float y, float z, float heading); void Teleport(Mob *who, float x, float y, float z, float heading);
void NavigateTo(Mob *who, float x, float y, float z, bool force = false, MobMovementMode mode = MovementRunning); void NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode = MovementRunning);
void StopNavigation(Mob *who); void StopNavigation(Mob *who);
void SendCommandToClients(Mob *m, float dx, float dy, float dz, float dh, int anim, ClientRange range); void SendCommandToClients(Mob *m, float dx, float dy, float dz, float dh, int anim, ClientRange range);
float FixHeading(float in); float FixHeading(float in);
//void Dump(Mob *m, Client *to); void DumpStats(Client *to);
//void DumpStats(Client *to); void ClearStats();
//void ClearStats();
static MobMovementManager &Get() { static MobMovementManager &Get() {
static MobMovementManager inst; static MobMovementManager inst;

View File

@ -772,9 +772,8 @@ bool NPC::Process()
DoGravityEffect(); DoGravityEffect();
} }
if(reface_timer->Check() && !IsEngaged() && (m_GuardPoint.x == GetX() && m_GuardPoint.y == GetY() && m_GuardPoint.z == GetZ())) { if(reface_timer->Check() && !IsEngaged() && IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f)) {
SetHeading(m_GuardPoint.w); RotateTo(m_GuardPoint.w);
SendPosition();
reface_timer->Disable(); reface_timer->Disable();
} }

View File

@ -163,6 +163,11 @@ float GetReciprocalHeading(const float heading)
return result; return result;
} }
bool IsHeadingEqual(const float h1, const float h2)
{
return std::abs(h2 - h1) < 0.01f;
}
bool IsPositionEqual(const glm::vec2 &p1, const glm::vec2 &p2) bool IsPositionEqual(const glm::vec2 &p1, const glm::vec2 &p2)
{ {
return std::abs(p1.x - p2.x) < position_eps && std::abs(p1.y - p2.y) < position_eps; return std::abs(p1.x - p2.x) < position_eps && std::abs(p1.y - p2.y) < position_eps;

View File

@ -50,6 +50,8 @@ float DistanceSquaredNoZ(const glm::vec4& point1, const glm::vec4& point2);
float GetReciprocalHeading(const glm::vec4& point1); float GetReciprocalHeading(const glm::vec4& point1);
float GetReciprocalHeading(const float heading); float GetReciprocalHeading(const float heading);
bool IsHeadingEqual(const float h1, const float h2);
bool IsPositionEqual(const glm::vec2 &p1, const glm::vec2 &p2); bool IsPositionEqual(const glm::vec2 &p1, const glm::vec2 &p2);
bool IsPositionEqual(const glm::vec3 &p1, const glm::vec3 &p2); bool IsPositionEqual(const glm::vec3 &p1, const glm::vec3 &p2);
bool IsPositionEqual(const glm::vec4 &p1, const glm::vec4 &p2); bool IsPositionEqual(const glm::vec4 &p1, const glm::vec4 &p2);

View File

@ -4898,12 +4898,11 @@ void Client::UnStun() {
void NPC::Stun(int duration) { void NPC::Stun(int duration) {
Mob::Stun(duration); Mob::Stun(duration);
SetCurrentSpeed(0); StopNavigation();
} }
void NPC::UnStun() { void NPC::UnStun() {
Mob::UnStun(); Mob::UnStun();
SetCurrentSpeed(GetRunspeed());
} }
void Mob::Mesmerize() void Mob::Mesmerize()

View File

@ -428,12 +428,11 @@ void NPC::SaveGuardSpot(bool iClearGuardSpot) {
void NPC::NextGuardPosition() { void NPC::NextGuardPosition() {
NavigateTo(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z); NavigateTo(m_GuardPoint.x, m_GuardPoint.y, m_GuardPoint.z);
if ((m_Position.x == m_GuardPoint.x) && (m_Position.y == m_GuardPoint.y) && (m_Position.z == m_GuardPoint.z)) if (IsPositionEqualWithinCertainZ(m_Position, m_GuardPoint, 5.0f))
{ {
if (moved) if (moved)
{ {
moved = false; moved = false;
SetCurrentSpeed(0);
} }
} }
} }
@ -444,24 +443,44 @@ float Mob::CalculateDistance(float x, float y, float z) {
void Mob::WalkTo(float x, float y, float z) void Mob::WalkTo(float x, float y, float z)
{ {
mMovementManager->NavigateTo(this, x, y, z, false, MovementWalking); mMovementManager->NavigateTo(this, x, y, z, MovementWalking);
} }
void Mob::RunTo(float x, float y, float z) void Mob::RunTo(float x, float y, float z)
{ {
mMovementManager->NavigateTo(this, x, y, z, false, MovementRunning); mMovementManager->NavigateTo(this, x, y, z, MovementRunning);
} }
void Mob::NavigateTo(float x, float y, float z) void Mob::NavigateTo(float x, float y, float z)
{ {
if (IsRunning()) { if (IsRunning()) {
mMovementManager->NavigateTo(this, x, y, z, false, MovementRunning); RunTo(x, y, z);
} }
else { else {
mMovementManager->NavigateTo(this, x, y, z, false, MovementWalking); WalkTo(x, y, z);
} }
} }
void Mob::RotateTo(float new_heading)
{
if (IsRunning()) {
RotateToRunning(new_heading);
}
else {
RotateToWalking(new_heading);
}
}
void Mob::RotateToWalking(float new_heading)
{
mMovementManager->RotateTo(this, new_heading, MovementWalking);
}
void Mob::RotateToRunning(float new_heading)
{
mMovementManager->RotateTo(this, new_heading, MovementRunning);
}
void Mob::StopNavigation() { void Mob::StopNavigation() {
mMovementManager->StopNavigation(this); mMovementManager->StopNavigation(this);
} }