diff --git a/changelog.txt b/changelog.txt index 51011d64b..9568f8392 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- + +== 7/14/2017 == +Akkadius: HP Update tuning - HP Updates are now forced when a client is targeted +Akkadius: Client position updates should be smoother (granted the client has a good connection) + - Clients should also no longer randomly disappear + == 7/11/2017 == Akkadius: Raid/Group/XTarget HP/Mana/Endurance updates now only send when percentage changes Akkadius: Raid/Group Mana/Endurance updates should now update real-time once again diff --git a/common/ruletypes.h b/common/ruletypes.h index 397f1a832..fe385b18f 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -150,6 +150,7 @@ RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'h RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation +RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/zone/attack.cpp b/zone/attack.cpp index ee1384b44..4b480f580 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3551,7 +3551,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const Teleport(new_pos); if (position_update_melee_push_timer.Check()) { - SendPosUpdate(); + SendPositionUpdate(); } } } diff --git a/zone/bot.cpp b/zone/bot.cpp index 129cdb9b3..f5a9285a3 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2172,7 +2172,7 @@ void Bot::AI_Process() { } if(IsMoving()) - SendPosUpdate(); + SendPositionUpdate(); else SendPosition(); } @@ -2383,7 +2383,7 @@ void Bot::AI_Process() { // TODO: Test RuleB(Bots, UpdatePositionWithTimer) if(IsMoving()) - SendPosUpdate(); + SendPositionUpdate(); else SendPosition(); } @@ -2505,7 +2505,7 @@ void Bot::AI_Process() { } if(IsMoving()) - SendPosUpdate(); + SendPositionUpdate(); else SendPosition(); } diff --git a/zone/client.cpp b/zone/client.cpp index bc784d415..08eb7e60a 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -159,11 +159,12 @@ Client::Client(EQStreamInterface* ieqs) m_dirtyautohaters(false), npc_close_scan_timer(6000), hp_self_update_throttle_timer(300), - hp_other_update_throttle_timer(500) + hp_other_update_throttle_timer(500), + position_update_timer(0) { - for(int cf=0; cf < _FilterCount; cf++) - ClientFilters[cf] = FilterShow; + for (int client_filter = 0; client_filter < _FilterCount; client_filter++) + ClientFilters[client_filter] = FilterShow; character_id = 0; conn_state = NoPacketsReceived; @@ -196,7 +197,7 @@ Client::Client(EQStreamInterface* ieqs) last_reported_endurance = 0; last_reported_endurance_percent = 0; last_reported_mana_percent = 0; - gmhideme = false; + gm_hide_me = false; AFK = false; LFG = false; LFGFromLevel = 0; @@ -260,7 +261,7 @@ Client::Client(EQStreamInterface* ieqs) memset(&m_epp, 0, sizeof(m_epp)); PendingTranslocate = false; PendingSacrifice = false; - BoatID = 0; + controlling_boat_id = 0; KarmaUpdateTimer = new Timer(RuleI(Chat, KarmaUpdateIntervalMS)); GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS)); @@ -1971,7 +1972,7 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) } bool Client::GMHideMe(Client* client) { - if (gmhideme) { + if (gm_hide_me) { if (client == 0) return true; else if (admin > client->Admin()) @@ -3240,9 +3241,9 @@ void Client::SetHideMe(bool flag) { EQApplicationPacket app; - gmhideme = flag; + gm_hide_me = flag; - if(gmhideme) + if(gm_hide_me) { database.SetHideMe(AccountID(),true); CreateDespawnPacket(&app, false); @@ -6373,7 +6374,7 @@ void Client::LocateCorpse() SetHeading(CalculateHeadingToTarget(ClosestCorpse->GetX(), ClosestCorpse->GetY())); SetTarget(ClosestCorpse); SendTargetCommand(ClosestCorpse->GetID()); - SendPosUpdate(2); + SendPositionUpdate(2); } else if(!GetTarget()) Message_StringID(clientMessageError, SENSE_CORPSE_NONE); diff --git a/zone/client.h b/zone/client.h index d88769ee1..640d9dc98 100644 --- a/zone/client.h +++ b/zone/client.h @@ -320,7 +320,7 @@ public: bool GetRevoked() const { return revoked; } void SetRevoked(bool rev) { revoked = rev; } inline uint32 GetIP() const { return ip; } - inline bool GetHideMe() const { return gmhideme; } + inline bool GetHideMe() const { return gm_hide_me; } void SetHideMe(bool hm); inline uint16 GetPort() const { return port; } bool IsDead() const { return(dead); } @@ -1072,7 +1072,7 @@ public: void Signal(uint32 data); Mob *GetBindSightTarget() { return bind_sight_target; } void SetBindSightTarget(Mob *n) { bind_sight_target = n; } - const uint16 GetBoatID() const { return BoatID; } + const uint16 GetBoatID() const { return controlling_boat_id; } void SendRewards(); bool TryReward(uint32 claim_id); QGlobalCache *GetQGlobals() { return qGlobals; } @@ -1376,7 +1376,7 @@ private: bool duelaccepted; std::list keyring; bool tellsoff; // GM /toggle - bool gmhideme; + bool gm_hide_me; bool LFG; bool LFP; uint8 LFGFromLevel; @@ -1396,7 +1396,7 @@ private: uint32 weight; bool berserk; bool dead; - uint16 BoatID; + uint16 controlling_boat_id; uint16 TrackingID; uint16 CustomerID; uint16 TraderID; @@ -1487,6 +1487,7 @@ private: Timer npc_close_scan_timer; Timer hp_self_update_throttle_timer; /* This is to prevent excessive packet sending under trains/fast combat */ Timer hp_other_update_throttle_timer; /* This is to keep clients from DOSing the server with macros that change client targets constantly */ + Timer position_update_timer; /* Timer used when client hasn't updated within a 10 second window */ glm::vec3 m_Proximity; void BulkSendInventoryItems(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index eb17f4db8..bababb73e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1288,7 +1288,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) lsaccountid = atoi(row[2]); gmspeed = atoi(row[3]); revoked = atoi(row[4]); - gmhideme = atoi(row[5]); + gm_hide_me = atoi(row[5]); account_creation = atoul(row[6]); } @@ -1356,7 +1356,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) if (level) { level = m_pp.level; } /* If GM, not trackable */ - if (gmhideme) { trackable = false; } + if (gm_hide_me) { trackable = false; } /* Set Con State for Reporting */ conn_state = PlayerProfileLoaded; @@ -3882,7 +3882,7 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app) Mob* boat = entity_list.GetMob(boatname); if (!boat || (boat->GetRace() != CONTROLLED_BOAT && boat->GetRace() != 502)) return; - BoatID = boat->GetID(); // set the client's BoatID to show that it's on this boat + controlling_boat_id = boat->GetID(); // set the client's BoatID to show that it's on this boat return; } @@ -4373,7 +4373,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) if (dead) return; - //currently accepting two sizes, one has an extra byte on the end + /* Invalid size check */ if (app->size != sizeof(PlayerPositionUpdateClient_Struct) && app->size != (sizeof(PlayerPositionUpdateClient_Struct) + 1) ) { @@ -4382,30 +4382,30 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) } PlayerPositionUpdateClient_Struct* ppu = (PlayerPositionUpdateClient_Struct*)app->pBuffer; + /* Boat handling */ if (ppu->spawn_id != GetID()) { - // check if the id is for a boat the player is controlling - if (ppu->spawn_id == BoatID) { - Mob* boat = entity_list.GetMob(BoatID); - if (boat == 0) { // if the boat ID is invalid, reset the id and abort - BoatID = 0; + /* If player is controlling boat */ + if (ppu->spawn_id == controlling_boat_id) { + Mob* boat = entity_list.GetMob(controlling_boat_id); + if (boat == 0) { + controlling_boat_id = 0; return; } - // set the boat's position deltas - auto boatDelta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); - boat->SetDelta(boatDelta); - // send an update to everyone nearby except the client controlling the boat - auto outapp = - new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); + boat->SetDelta(boat_delta); + + auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; boat->MakeSpawnUpdate(ppus); entity_list.QueueCloseClients(boat, outapp, true, 300, this, false); safe_delete(outapp); - // update the boat's position on the server, without sending an update + + /* Update the boat's position on the server, without sending an update */ boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ19toFloat(ppu->heading), false); return; } - else return; // if not a boat, do nothing + else return; } float dist = 0; @@ -4416,51 +4416,34 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) dist += tmp*tmp; dist = sqrt(dist); - //the purpose of this first block may not be readily apparent - //basically it's so people don't do a moderate warp every 2.5 seconds - //letting it even out and basically getting the job done without triggering - if (dist == 0) - { - if (m_DistanceSinceLastPositionCheck > 0.0) - { + /* Hack checks */ + if (dist == 0) { + if (m_DistanceSinceLastPositionCheck > 0.0) { uint32 cur_time = Timer::GetCurrentTime(); - if ((cur_time - m_TimeSinceLastPositionCheck) > 0) - { + if ((cur_time - m_TimeSinceLastPositionCheck) > 0) { float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); int runs = GetRunspeed(); - if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) - { - if (IsShadowStepExempted()) - { - if (m_DistanceSinceLastPositionCheck > 800) - { + if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) { + if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { + if (IsShadowStepExempted()) { + if (m_DistanceSinceLastPositionCheck > 800) { CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } - else if (IsKnockBackExempted()) - { - //still potential to trigger this if you're knocked back off a - //HUGE fall that takes > 2.5 seconds - if (speed > 30.0f) - { + else if (IsKnockBackExempted()) { + if (speed > 30.0f) { CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } - else if (!IsPortExempted()) - { - if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) - { - if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { + else if (!IsPortExempted()) { + if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) { + if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) { m_TimeSinceLastPositionCheck = cur_time; m_DistanceSinceLastPositionCheck = 0.0f; CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos); //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); } - else - { + else { CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } @@ -4475,64 +4458,42 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) m_CheatDetectMoved = false; } } - else - { + else { m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); m_CheatDetectMoved = false; } } - else - { + else { m_DistanceSinceLastPositionCheck += dist; m_CheatDetectMoved = true; - if (m_TimeSinceLastPositionCheck == 0) - { + if (m_TimeSinceLastPositionCheck == 0) { m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); } - else - { + else { uint32 cur_time = Timer::GetCurrentTime(); - if ((cur_time - m_TimeSinceLastPositionCheck) > 2500) - { + if ((cur_time - m_TimeSinceLastPositionCheck) > 2500) { float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); int runs = GetRunspeed(); - if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) - { - if (IsShadowStepExempted()) - { - if (m_DistanceSinceLastPositionCheck > 800) - { - //if(!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) - //{ + if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) { + if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { + if (IsShadowStepExempted()) { + if (m_DistanceSinceLastPositionCheck > 800) { CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos); - //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - //} } } - else if (IsKnockBackExempted()) - { - //still potential to trigger this if you're knocked back off a - //HUGE fall that takes > 2.5 seconds - if (speed > 30.0f) - { + else if (IsKnockBackExempted()) { + if (speed > 30.0f) { CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } - else if (!IsPortExempted()) - { - if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) - { - if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { + else if (!IsPortExempted()) { + if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) { + if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) { m_TimeSinceLastPositionCheck = cur_time; m_DistanceSinceLastPositionCheck = 0.0f; CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos); - //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); } - else - { + else { CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos); } } @@ -4551,7 +4512,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) DragCorpses(); } - //Check to see if PPU should trigger an update to the rewind position. + /* Check to see if PPU should trigger an update to the rewind position. */ float rewind_x_diff = 0; float rewind_y_diff = 0; @@ -4560,14 +4521,19 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) rewind_y_diff = ppu->y_pos - m_RewindLocation.y; rewind_y_diff *= rewind_y_diff; - //We only need to store updated values if the player has moved. - //If the player has moved more than units for x or y, then we'll store - //his pre-PPU x and y for /rewind, in case he gets stuck. + /* + We only need to store updated values if the player has moved. + If the player has moved more than units for x or y, then we'll store + his pre-PPU x and y for /rewind, in case he gets stuck. + */ + if ((rewind_x_diff > 750) || (rewind_y_diff > 750)) m_RewindLocation = glm::vec3(m_Position); - //If the PPU was a large jump, such as a cross zone gate or Call of Hero, - //just update rewind coords to the new ppu coords. This will prevent exploitation. + /* + If the PPU was a large jump, such as a cross zone gate or Call of Hero, + just update rewind coordinates to the new ppu coordinates. This will prevent exploitation. + */ if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000)) m_RewindLocation = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos); @@ -4580,7 +4546,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) m_Proximity = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos); } - // Update internal state + /* Update internal state */ m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, ppu->delta_heading); if (IsTracking() && ((m_Position.x != ppu->x_pos) || (m_Position.y != ppu->y_pos))) { @@ -4588,7 +4554,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) CheckIncreaseSkill(EQEmu::skills::SkillTracking, nullptr, -20); } - // Break Hide if moving without sneaking and set rewind timer if moved + /* Break Hide if moving without sneaking and set rewind timer if moved */ if (ppu->y_pos != m_Position.y || ppu->x_pos != m_Position.x) { if ((hidden || improved_hidden) && !sneaking) { hidden = false; @@ -4633,39 +4599,39 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) client_scan_npc_aggro_timer.Start(3000); } } + + /* Update internal server position from what the client has sent */ + m_Position.x = ppu->x_pos; + m_Position.y = ppu->y_pos; + m_Position.z = ppu->z_pos; + m_Position.w = EQ19toFloat(ppu->heading); + + animation = ppu->animation; - // Outgoing client packet - float tmpheading = EQ19toFloat(ppu->heading); - /* The clients send an update at best every 1.3 seconds - * We want to avoid reflecting these updates to other clients as much as possible - * The client also sends an update every 280 ms while turning, if we prevent - * sending these by checking if the location is the same too aggressively, clients end up spinning - * so keep a count of how many packets are the same within a tolerance and stop when we get there */ - - bool pos_same = FCMP(ppu->y_pos, m_Position.y) && FCMP(ppu->x_pos, m_Position.x) && FCMP(tmpheading, m_Position.w) && ppu->animation == animation; - if (!pos_same || (pos_same && position_update_same_count < 6)) - { - if (pos_same) - position_update_same_count++; - else - position_update_same_count = 0; - - m_Position.x = ppu->x_pos; - m_Position.y = ppu->y_pos; - m_Position.z = ppu->z_pos; - m_Position.w = tmpheading; - animation = ppu->animation; - - auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; - MakeSpawnUpdate(ppu); - if (gmhideme) - entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250); - else - entity_list.QueueCloseClients(this, outapp, true, 300, nullptr, false); - safe_delete(outapp); + /* Visual Debugging */ + if (RuleB(Character, OPClientUpdateVisualDebug)) { + Log(Logs::General, Logs::Debug, "ClientUpdate: ppu x: %f y: %f z: %f h: %u", ppu->x_pos, ppu->y_pos, ppu->z_pos, ppu->heading); + this->SendAppearanceEffect(78, 0, 0, 0, 0); + this->SendAppearanceEffect(41, 0, 0, 0, 0); } + /* Broadcast update to other clients */ + auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + PlayerPositionUpdateServer_Struct* position_update = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; + + MakeSpawnUpdate(position_update); + + position_update_timer.Start(10000, true); + + if (gm_hide_me) { + entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250); + } + else { + entity_list.QueueCloseClients(this, outapp, true, 300, nullptr, true); + } + + safe_delete(outapp); + if (zone->watermap) { if (zone->watermap->InLiquid(glm::vec3(m_Position))) CheckIncreaseSkill(EQEmu::skills::SkillSwimming, nullptr, -17); @@ -4675,27 +4641,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) return; } -/* -void Client::Handle_OP_CloseContainer(const EQApplicationPacket *app) -{ -if (app->size != sizeof(CloseContainer_Struct)) { -LogFile->write(EQEMuLog::Error, "Invalid size on CloseContainer_Struct: Expected %i, Got %i", -sizeof(CloseContainer_Struct), app->size); -return; -} - -SetTradeskillObject(nullptr); - -ClickObjectAck_Struct* oos = (ClickObjectAck_Struct*)app->pBuffer; -Entity* entity = entity_list.GetEntityObject(oos->drop_id); -if (entity && entity->IsObject()) { -Object* object = entity->CastToObject(); -object->Close(); -} -return; -} -*/ - void Client::Handle_OP_CombatAbility(const EQApplicationPacket *app) { if (app->size != sizeof(CombatAbility_Struct)) { @@ -8946,12 +8891,12 @@ void Client::Handle_OP_LeaveAdventure(const EQApplicationPacket *app) void Client::Handle_OP_LeaveBoat(const EQApplicationPacket *app) { - Mob* boat = entity_list.GetMob(this->BoatID); // find the mob corresponding to the boat id + Mob* boat = entity_list.GetMob(this->controlling_boat_id); // find the mob corresponding to the boat id if (boat) { if ((boat->GetTarget() == this) && boat->GetHateAmount(this) == 0) // if the client somehow left while still controlling the boat (and the boat isn't attacking them) boat->SetTarget(0); // fix it to stop later problems } - this->BoatID = 0; + this->controlling_boat_id = 0; return; } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 2bf1d5818..11954798d 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -63,64 +63,49 @@ extern EntityList entity_list; bool Client::Process() { bool ret = true; - if (Connected() || IsLD()) - { + if (Connected() || IsLD()) { // try to send all packets that weren't sent before - if (!IsLD() && zoneinpacket_timer.Check()) - { + if (!IsLD() && zoneinpacket_timer.Check()) { SendAllPackets(); } - if (adventure_request_timer) - { - if (adventure_request_timer->Check()) - { + if (adventure_request_timer) { + if (adventure_request_timer->Check()) { safe_delete(adventure_request_timer); } } - if (adventure_create_timer) - { - if (adventure_create_timer->Check()) - { + if (adventure_create_timer) { + if (adventure_create_timer->Check()) { safe_delete(adventure_create_timer); } } - if (adventure_leave_timer) - { - if (adventure_leave_timer->Check()) - { + if (adventure_leave_timer) { + if (adventure_leave_timer->Check()) { safe_delete(adventure_leave_timer); } } - if (adventure_door_timer) - { - if (adventure_door_timer->Check()) - { + if (adventure_door_timer) { + if (adventure_door_timer->Check()) { safe_delete(adventure_door_timer); } } - if (adventure_stats_timer) - { - if (adventure_stats_timer->Check()) - { + if (adventure_stats_timer) { + if (adventure_stats_timer->Check()) { safe_delete(adventure_stats_timer); } } - if (adventure_leaderboard_timer) - { - if (adventure_leaderboard_timer->Check()) - { + if (adventure_leaderboard_timer) { + if (adventure_leaderboard_timer->Check()) { safe_delete(adventure_leaderboard_timer); } } - if (dead) - { + if (dead) { SetHP(-100); if (RespawnFromHoverTimer.Check()) HandleRespawnFromHover(0); @@ -134,6 +119,11 @@ bool Client::Process() { if (hpupdate_timer.Check(false)) SendHPUpdate(); + /* I haven't naturally updated my position in 10 seconds, updating manually */ + if (position_update_timer.Check()) { + SendPositionUpdate(); + } + if (mana_timer.Check()) CheckManaEndUpdate(); @@ -271,15 +261,6 @@ bool Client::Process() { close_mobs.insert(std::pair(mob, distance)); } } - - /* Clients need to be kept up to date for position updates more often otherwise they disappear */ - if (mob->IsClient() && this != mob && !mob->IsMoving() && distance <= client_update_range) { - auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* spawn_update = (PlayerPositionUpdateServer_Struct*)app->pBuffer; - mob->MakeSpawnUpdate(spawn_update); - this->FastQueuePacket(&app, false); - safe_delete(app); - } } } @@ -460,7 +441,7 @@ bool Client::Process() { { animation = 0; m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w); - SendPosUpdate(2); + SendPositionUpdate(2); } } diff --git a/zone/merc.cpp b/zone/merc.cpp index 2b1ef7098..80565c6b4 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1589,7 +1589,7 @@ void Merc::AI_Process() { } if(IsMoving()) - SendPosUpdate(); + SendPositionUpdate(); else SendPosition(); } @@ -1714,7 +1714,7 @@ void Merc::AI_Process() { } if(IsMoving()) - SendPosUpdate(); + SendPositionUpdate(); else SendPosition(); } diff --git a/zone/mob.cpp b/zone/mob.cpp index 0a4a84746..fc7772b8d 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1437,7 +1437,7 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal } } -// this one just warps the mob to the current location +/* Used for NPCs mainly */ void Mob::SendPosition() { @@ -1446,7 +1446,7 @@ void Mob::SendPosition() MakeSpawnUpdateNoDelta(spu); /* When an NPC has made a large distance change - we should update all clients to prevent "ghosts" */ - if (DistanceSquared(last_major_update_position, m_Position) > (100 * 100)) { + if (DistanceSquared(last_major_update_position, m_Position) >= (100 * 100)) { entity_list.QueueClients(this, app, true, true); last_major_update_position = m_Position; } @@ -1458,7 +1458,7 @@ void Mob::SendPosition() } // this one is for mobs on the move, with deltas - this makes them walk -void Mob::SendPosUpdate(uint8 iSendToSelf) { +void Mob::SendPositionUpdate(uint8 iSendToSelf) { auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer; MakeSpawnUpdate(spu); @@ -1496,27 +1496,27 @@ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu) { // this is for SendPosUpdate() void Mob::MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu) { - spu->spawn_id = GetID(); - spu->x_pos = FloatToEQ19(m_Position.x); - spu->y_pos = FloatToEQ19(m_Position.y); - spu->z_pos = FloatToEQ19(m_Position.z); - spu->delta_x = NewFloatToEQ13(m_Delta.x); - spu->delta_y = NewFloatToEQ13(m_Delta.y); - spu->delta_z = NewFloatToEQ13(m_Delta.z); - spu->heading = FloatToEQ19(m_Position.w); - spu->padding0002 =0; - spu->padding0006 =7; - spu->padding0014 =0x7f; - spu->padding0018 =0x5df27; + spu->spawn_id = GetID(); + spu->x_pos = FloatToEQ19(m_Position.x); + spu->y_pos = FloatToEQ19(m_Position.y); + spu->z_pos = FloatToEQ19(m_Position.z); + spu->delta_x = NewFloatToEQ13(m_Delta.x); + spu->delta_y = NewFloatToEQ13(m_Delta.y); + spu->delta_z = NewFloatToEQ13(m_Delta.z); + spu->heading = FloatToEQ19(m_Position.w); + spu->padding0002 = 0; + spu->padding0006 = 7; + spu->padding0014 = 0x7f; + spu->padding0018 = 0x5df27; #ifdef BOTS if (this->IsClient() || this->IsBot()) #else - if(this->IsClient()) + if (this->IsClient()) #endif spu->animation = animation; else spu->animation = pRunAnimSpeed;//animation; - + spu->delta_heading = NewFloatToEQ13(m_Delta.w); } @@ -2745,7 +2745,7 @@ void Mob::FaceTarget(Mob* MobToFace) { if(oldheading != newheading) { SetHeading(newheading); if(moving) - SendPosUpdate(); + SendPositionUpdate(); else { SendPosition(); diff --git a/zone/mob.h b/zone/mob.h index d017d9173..a91975d85 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -542,7 +542,7 @@ public: virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true); void SetDelta(const glm::vec4& delta); void SetTargetDestSteps(uint8 target_steps) { tar_ndx = target_steps; } - void SendPosUpdate(uint8 iSendToSelf = 0); + void SendPositionUpdate(uint8 iSendToSelf = 0); void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu); void SendPosition(); diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 633dde297..a016b98e6 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1006,7 +1006,12 @@ void Mob::AI_Process() { } else if (!this->CheckLosFN(this->GetTarget())) { Mob* target = this->GetTarget(); - this->GMMove(target->GetX(), target->GetY(), target->GetZ(), target->GetHeading()); + + m_Position.x = target->GetX(); + m_Position.y = target->GetY(); + m_Position.z = target->GetZ(); + m_Position.w = target->GetHeading(); + SendPosition(); } } } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 9af0fa43f..f95deb3de 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -1268,7 +1268,7 @@ XS(XS_Mob_SendPosUpdate) iSendToSelf = (uint8)SvUV(ST(1)); } - THIS->SendPosUpdate(iSendToSelf); + THIS->SendPositionUpdate(iSendToSelf); } XSRETURN_EMPTY; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 757098c57..c77e96979 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -215,7 +215,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const glm::vec4& p { npc->AssignWaypoints(grid); } - npc->SendPosUpdate(); + npc->SendPositionUpdate(); return npc; } return nullptr; @@ -237,7 +237,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::v { npc->AssignWaypoints(grid); } - npc->SendPosUpdate(); + npc->SendPositionUpdate(); return npc; } return nullptr; @@ -1660,7 +1660,7 @@ void QuestManager::respawn(int npcTypeID, int grid) { if(grid > 0) owner->CastToNPC()->AssignWaypoints(grid); - owner->SendPosUpdate(); + owner->SendPositionUpdate(); } } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 4d3f1ee1d..4b98eccd1 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -847,7 +847,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove SetHeading(CalculateHeadingToTarget(ClosestMob->GetX(), ClosestMob->GetY())); SetTarget(ClosestMob); CastToClient()->SendTargetCommand(ClosestMob->GetID()); - SendPosUpdate(2); + SendPositionUpdate(2); } else Message_StringID(clientMessageError, SENSE_NOTHING); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index fbbce67b9..61fc7983f 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -614,12 +614,12 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo if (IsClient()) { - SendPosUpdate(1); + SendPositionUpdate(1); CastToClient()->ResetPositionTimer(); } else { - SendPosUpdate(); + SendPositionUpdate(); SetAppearance(eaStanding, false); } @@ -702,7 +702,7 @@ bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ this->SetMoving(true); moved = true; m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f); - SendPosUpdate(); + SendPositionUpdate(); } tar_ndx++;