Raid/Group/XTarget HP/Mana/Endurance updates now only send when percentage changes

Raid/Group Mana/Endurance updates should now update real-time once again
Fixed an issue with clients looking like they are 'skipping' when they are moving in view of another client
Fixed an issue with NPC's who are ghosted in plain view of a client when they are not really there
This commit is contained in:
Akkadius 2017-07-11 17:54:46 -05:00
parent d47daa2857
commit 855796448c
18 changed files with 289 additions and 150 deletions

View File

@ -1,5 +1,11 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 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
Akkadius: Fixed an issue with clients looking like they are 'skipping' when they are moving in view of another client
Akkadius: Fixed an issue with NPC's who are ghosted in plain view of a client when they are not really there
== 7/9/2017 ==
Akkadius: Fix HP update issues, rework logic for more accurate HP updates
Akkadius: Massive reductions in unnecessary network traffic especially during high spam combat fights

View File

@ -84,7 +84,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
GenerateBaseStats();
// Calculate HitPoints Last As It Uses Base Stats
cur_hp = GenerateBaseHitPoints();
cur_mana = GenerateBaseManaPoints();
current_mana = GenerateBaseManaPoints();
cur_end = CalcBaseEndurance();
hp_regen = CalcHPRegen();
mana_regen = CalcManaRegen();
@ -129,7 +129,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
_baseRace = npcTypeData.race;
_baseGender = npcTypeData.gender;
cur_hp = npcTypeData.cur_hp;
cur_mana = npcTypeData.Mana;
current_mana = npcTypeData.Mana;
RestRegenHP = 0;
RestRegenMana = 0;
RestRegenEndurance = 0;
@ -206,8 +206,8 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
SpellOnTarget(756, this); // Rezz effects
}
if(cur_mana > max_mana)
cur_mana = max_mana;
if(current_mana > max_mana)
current_mana = max_mana;
cur_end = max_end;
}
@ -5557,8 +5557,8 @@ int32 Bot::CalcMaxMana() {
}
}
if(cur_mana > max_mana)
cur_mana = max_mana;
if(current_mana > max_mana)
current_mana = max_mana;
else if(max_mana < 0)
max_mana = 0;

View File

@ -161,8 +161,10 @@ Client::Client(EQStreamInterface* ieqs)
npc_close_scan_timer(6000),
hp_self_update_throttle_timer(500)
{
for(int cf=0; cf < _FilterCount; cf++)
ClientFilters[cf] = FilterShow;
character_id = 0;
conn_state = NoPacketsReceived;
client_data_loaded = false;
@ -191,7 +193,9 @@ Client::Client(EQStreamInterface* ieqs)
strcpy(account_name, "");
tellsoff = false;
last_reported_mana = 0;
last_reported_endur = 0;
last_reported_endurance = 0;
last_reported_endurance_percent = 0;
last_reported_mana_percent = 0;
gmhideme = false;
AFK = false;
LFG = false;
@ -269,7 +273,7 @@ Client::Client(EQStreamInterface* ieqs)
RestRegenMana = 0;
RestRegenEndurance = 0;
XPRate = 100;
cur_end = 0;
current_endurance = 0;
m_TimeSinceLastPositionCheck = 0;
m_DistanceSinceLastPositionCheck = 0.0f;
@ -287,7 +291,7 @@ Client::Client(EQStreamInterface* ieqs)
HideCorpseMode = HideCorpseNone;
PendingGuildInvitation = false;
cur_end = 0;
current_endurance = 0;
InitializeBuffSlots();
@ -599,8 +603,8 @@ bool Client::Save(uint8 iCommitNow) {
m_pp.cur_hp = GetHP();
}
m_pp.mana = cur_mana;
m_pp.endurance = cur_end;
m_pp.mana = current_mana;
m_pp.endurance = current_endurance;
/* Save Character Currency */
database.SaveCharacterCurrency(CharacterID(), &m_pp);
@ -1820,20 +1824,20 @@ const int32& Client::SetMana(int32 amount) {
amount = 0;
if (amount > GetMaxMana())
amount = GetMaxMana();
if (amount != cur_mana)
if (amount != current_mana)
update = true;
cur_mana = amount;
current_mana = amount;
if (update)
Mob::SetMana(amount);
SendManaUpdatePacket();
return cur_mana;
CheckManaEndUpdate();
return current_mana;
}
void Client::SendManaUpdatePacket() {
void Client::CheckManaEndUpdate() {
if (!Connected())
return;
if (last_reported_mana != cur_mana || last_reported_endur != cur_end) {
if (last_reported_mana != current_mana || last_reported_endurance != current_endurance) {
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
SendManaUpdate();
@ -1841,46 +1845,65 @@ void Client::SendManaUpdatePacket() {
}
auto outapp = new EQApplicationPacket(OP_ManaChange, sizeof(ManaChange_Struct));
ManaChange_Struct* manachange = (ManaChange_Struct*)outapp->pBuffer;
manachange->new_mana = cur_mana;
manachange->stamina = cur_end;
manachange->spell_id = casting_spell_id;
manachange->keepcasting = 1;
ManaChange_Struct* mana_change = (ManaChange_Struct*)outapp->pBuffer;
mana_change->new_mana = current_mana;
mana_change->stamina = current_endurance;
mana_change->spell_id = casting_spell_id;
mana_change->keepcasting = 1;
outapp->priority = 6;
QueuePacket(outapp);
safe_delete(outapp);
Group *g = GetGroup();
/* Let others know when our mana percent has changed */
if (this->GetManaPercent() != last_reported_mana_percent) {
Group *group = this->GetGroup();
Raid *raid = this->GetRaid();
if(g)
{
outapp = new EQApplicationPacket(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
auto outapp2 =
new EQApplicationPacket(OP_MobEnduranceUpdate, sizeof(MobEnduranceUpdate_Struct));
if (raid) {
raid->SendManaPacketFrom(this);
}
else if (group) {
group->SendManaPacketFrom(this);
}
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp->pBuffer;
MobEnduranceUpdate_Struct *meus = (MobEnduranceUpdate_Struct *)outapp2->pBuffer;
auto mana_packet = new EQApplicationPacket(OP_ManaUpdate, sizeof(ManaUpdate_Struct));
ManaUpdate_Struct* mana_update = (ManaUpdate_Struct*)mana_packet->pBuffer;
mana_update->cur_mana = GetMana();
mana_update->max_mana = GetMaxMana();
mana_update->spawn_id = GetID();
QueuePacket(mana_packet);
entity_list.QueueClientsByXTarget(this, mana_packet, false);
safe_delete(mana_packet);
mmus->spawn_id = meus->spawn_id = GetID();
mmus->mana = GetManaPercent();
meus->endurance = GetEndurancePercent();
for(int i = 0; i < MAX_GROUP_MEMBERS; ++i)
if (g->members[i] && g->members[i]->IsClient() && (g->members[i] != this) && (g->members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD))
{
g->members[i]->CastToClient()->QueuePacket(outapp);
g->members[i]->CastToClient()->QueuePacket(outapp2);
}
safe_delete(outapp);
safe_delete(outapp2);
last_reported_mana_percent = this->GetManaPercent();
}
/* Let others know when our endurance percent has changed */
if (this->GetEndurancePercent() != last_reported_endurance_percent) {
Group *group = this->GetGroup();
Raid *raid = this->GetRaid();
last_reported_mana = cur_mana;
last_reported_endur = cur_end;
if (raid) {
raid->SendEndurancePacketFrom(this);
}
else if (group) {
group->SendEndurancePacketFrom(this);
}
auto endurance_packet = new EQApplicationPacket(OP_EnduranceUpdate, sizeof(EnduranceUpdate_Struct));
EnduranceUpdate_Struct* endurance_update = (EnduranceUpdate_Struct*)endurance_packet->pBuffer;
endurance_update->cur_end = GetEndurance();
endurance_update->max_end = GetMaxEndurance();
endurance_update->spawn_id = GetID();
QueuePacket(endurance_packet);
entity_list.QueueClientsByXTarget(this, endurance_packet, false);
safe_delete(endurance_packet);
last_reported_endurance_percent = this->GetEndurancePercent();
}
last_reported_mana = current_mana;
last_reported_endurance = current_endurance;
}
}
@ -1888,12 +1911,11 @@ void Client::SendManaUpdatePacket() {
void Client::SendManaUpdate()
{
auto mana_app = new EQApplicationPacket(OP_ManaUpdate, sizeof(ManaUpdate_Struct));
ManaUpdate_Struct* mus = (ManaUpdate_Struct*)mana_app->pBuffer;
mus->cur_mana = GetMana();
mus->max_mana = GetMaxMana();
mus->spawn_id = GetID();
ManaUpdate_Struct* mana_update = (ManaUpdate_Struct*)mana_app->pBuffer;
mana_update->cur_mana = GetMana();
mana_update->max_mana = GetMaxMana();
mana_update->spawn_id = GetID();
QueuePacket(mana_app);
entity_list.QueueClientsByXTarget(this, mana_app, false);
safe_delete(mana_app);
}
@ -1901,12 +1923,11 @@ void Client::SendManaUpdate()
void Client::SendEnduranceUpdate()
{
auto end_app = new EQApplicationPacket(OP_EnduranceUpdate, sizeof(EnduranceUpdate_Struct));
EnduranceUpdate_Struct* eus = (EnduranceUpdate_Struct*)end_app->pBuffer;
eus->cur_end = GetEndurance();
eus->max_end = GetMaxEndurance();
eus->spawn_id = GetID();
EnduranceUpdate_Struct* endurance_update = (EnduranceUpdate_Struct*)end_app->pBuffer;
endurance_update->cur_end = GetEndurance();
endurance_update->max_end = GetMaxEndurance();
endurance_update->spawn_id = GetID();
QueuePacket(end_app);
entity_list.QueueClientsByXTarget(this, end_app, false);
safe_delete(end_app);
}
@ -3769,8 +3790,8 @@ void Client::SetEndurance(int32 newEnd)
newEnd = GetMaxEndurance();
}
cur_end = newEnd;
SendManaUpdatePacket();
current_endurance = newEnd;
CheckManaEndUpdate();
}
void Client::SacrificeConfirm(Client *caster)
@ -4376,7 +4397,7 @@ bool Client::GroupFollow(Client* inviter) {
}
database.RefreshGroupFromDB(this);
group->SendHPPacketsTo(this);
group->SendHPManaEndPacketsTo(this);
//send updates to clients out of zone...
group->SendGroupJoinOOZ(this);
return true;

View File

@ -540,11 +540,11 @@ public:
void CalcMaxEndurance(); //This calculates the maximum endurance we can have
int32 CalcBaseEndurance(); //Calculates Base End
int32 CalcEnduranceRegen(); //Calculates endurance regen used in DoEnduranceRegen()
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
int32 GetEndurance() const {return current_endurance;} //This gets our current endurance
int32 GetMaxEndurance() const {return max_end;} //This gets our endurance from the last CalcMaxEndurance() call
int32 CalcEnduranceRegenCap();
int32 CalcHPRegenCap();
inline uint8 GetEndurancePercent() { return (uint8)((float)cur_end / (float)max_end * 100.0f); }
inline uint8 GetEndurancePercent() { return (uint8)((float)current_endurance / (float)max_end * 100.0f); }
void SetEndurance(int32 newEnd); //This sets the current endurance to the new value
void DoEnduranceRegen(); //This Regenerates endurance
void DoEnduranceUpkeep(); //does the endurance upkeep
@ -661,7 +661,7 @@ public:
void RefreshGuildInfo();
void SendManaUpdatePacket();
void CheckManaEndUpdate();
void SendManaUpdate();
void SendEnduranceUpdate();
uint8 GetFace() const { return m_pp.face; }
@ -1411,7 +1411,7 @@ private:
int Haste; //precalced value
int32 max_end;
int32 cur_end;
int32 current_endurance;
PlayerProfile_Struct m_pp;
ExtendedProfile_Struct m_epp;
@ -1502,7 +1502,10 @@ private:
bool tgb;
bool instalog;
int32 last_reported_mana;
int32 last_reported_endur;
int32 last_reported_endurance;
int8 last_reported_mana_percent;
int8 last_reported_endurance_percent;
unsigned int AggroCount; // How many mobs are aggro on us.

View File

@ -1046,14 +1046,14 @@ int32 Client::CalcMaxMana()
if (max_mana < 0) {
max_mana = 0;
}
if (cur_mana > max_mana) {
cur_mana = max_mana;
if (current_mana > max_mana) {
current_mana = max_mana;
}
int mana_perc_cap = spellbonuses.ManaPercCap[0];
if (mana_perc_cap) {
int curMana_cap = (max_mana * mana_perc_cap) / 100;
if (cur_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && cur_mana > spellbonuses.ManaPercCap[1])) {
cur_mana = curMana_cap;
if (current_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && current_mana > spellbonuses.ManaPercCap[1])) {
current_mana = curMana_cap;
}
}
Log(Logs::Detail, Logs::Spells, "Client::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
@ -2034,14 +2034,14 @@ void Client::CalcMaxEndurance()
if (max_end < 0) {
max_end = 0;
}
if (cur_end > max_end) {
cur_end = max_end;
if (current_endurance > max_end) {
current_endurance = max_end;
}
int end_perc_cap = spellbonuses.EndPercCap[0];
if (end_perc_cap) {
int curEnd_cap = (max_end * end_perc_cap) / 100;
if (cur_end > curEnd_cap || (spellbonuses.EndPercCap[1] && cur_end > spellbonuses.EndPercCap[1])) {
cur_end = curEnd_cap;
if (current_endurance > curEnd_cap || (spellbonuses.EndPercCap[1] && current_endurance > spellbonuses.EndPercCap[1])) {
current_endurance = curEnd_cap;
}
}
}

View File

@ -584,14 +584,14 @@ void Client::CompleteConnect()
if (raid->IsLocked())
raid->SendRaidLockTo(this);
raid->SendHPPacketsTo(this);
raid->SendHPManaEndPacketsTo(this);
}
}
else {
Group *group = nullptr;
group = this->GetGroup();
if (group)
group->SendHPPacketsTo(this);
group->SendHPManaEndPacketsTo(this);
}

View File

@ -135,7 +135,7 @@ bool Client::Process() {
SendHPUpdate();
if (mana_timer.Check())
SendManaUpdatePacket();
CheckManaEndUpdate();
if (dead && dead_timer.Check()) {
database.MoveCharacterToZone(GetName(), database.GetZoneName(m_pp.binds[0].zoneId));
@ -273,10 +273,10 @@ bool Client::Process() {
}
/* Clients need to be kept up to date for position updates more often otherwise they disappear */
if (mob->IsClient() && this != mob && distance <= client_update_range) {
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->MakeSpawnUpdateNoDelta(spawn_update);
mob->MakeSpawnUpdate(spawn_update);
this->FastQueuePacket(&app, false);
safe_delete(app);
}
@ -1832,7 +1832,7 @@ void Client::DoManaRegen() {
return;
SetMana(GetMana() + CalcManaRegen() + RestRegenMana);
SendManaUpdatePacket();
CheckManaEndUpdate();
}

View File

@ -7197,7 +7197,7 @@ void command_ginfo(Client *c, const Seperator *sep)
void command_hp(Client *c, const Seperator *sep)
{
c->SendHPUpdate();
c->SendManaUpdatePacket();
c->CheckManaEndUpdate();
}
void command_aggro(Client *c, const Seperator *sep)

View File

@ -341,7 +341,7 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
Group* group = newmember->CastToClient()->GetGroup();
if (group) {
group->SendHPPacketsTo(newmember);
group->SendHPManaEndPacketsTo(newmember);
group->SendHPPacketsFrom(newmember);
}
@ -394,7 +394,7 @@ void Group::QueuePacket(const EQApplicationPacket *app, bool ack_req)
// Sends the rest of the group's hps to member. this is useful when someone
// first joins a group, but otherwise there shouldn't be a need to call it
void Group::SendHPPacketsTo(Mob *member)
void Group::SendHPManaEndPacketsTo(Mob *member)
{
if(member && member->IsClient()) {
EQApplicationPacket hpapp;
@ -410,14 +410,14 @@ void Group::SendHPPacketsTo(Mob *member)
if (member->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
mmus->spawn_id = members[i]->GetID();
mmus->mana = members[i]->GetManaPercent();
MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer;
mana_update->spawn_id = members[i]->GetID();
mana_update->mana = members[i]->GetManaPercent();
member->CastToClient()->QueuePacket(&outapp, false);
MobEnduranceUpdate_Struct *meus = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
outapp.SetOpcode(OP_MobEnduranceUpdate);
meus->endurance = members[i]->GetEndurancePercent();
endurance_update->endurance = members[i]->GetEndurancePercent();
member->CastToClient()->QueuePacket(&outapp, false);
}
}
@ -436,19 +436,58 @@ void Group::SendHPPacketsFrom(Mob *member)
uint32 i;
for(i = 0; i < MAX_GROUP_MEMBERS; i++) {
if(members[i] && members[i] != member && members[i]->IsClient())
{
if(members[i] && members[i] != member && members[i]->IsClient()) {
members[i]->CastToClient()->QueuePacket(&hp_app);
if (members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
{
if (members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
mmus->spawn_id = member->GetID();
mmus->mana = member->GetManaPercent();
MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer;
mana_update->spawn_id = member->GetID();
mana_update->mana = member->GetManaPercent();
members[i]->CastToClient()->QueuePacket(&outapp, false);
MobEnduranceUpdate_Struct *meus = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
outapp.SetOpcode(OP_MobEnduranceUpdate);
meus->endurance = member->GetEndurancePercent();
endurance_update->endurance = member->GetEndurancePercent();
members[i]->CastToClient()->QueuePacket(&outapp, false);
}
}
}
}
void Group::SendManaPacketFrom(Mob *member)
{
if (!member)
return;
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] && members[i] != member && members[i]->IsClient()) {
if (members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer;
mana_update->spawn_id = member->GetID();
mana_update->mana = member->GetManaPercent();
members[i]->CastToClient()->QueuePacket(&outapp, false);
}
}
}
}
void Group::SendEndurancePacketFrom(Mob* member)
{
if (!member)
return;
EQApplicationPacket outapp(OP_MobEnduranceUpdate, sizeof(MobManaUpdate_Struct));
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] && members[i] != member && members[i]->IsClient()) {
if (members[i]->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
endurance_update->spawn_id = member->GetID();
endurance_update->endurance = member->GetEndurancePercent();
members[i]->CastToClient()->QueuePacket(&outapp, false);
}
}

View File

@ -80,8 +80,10 @@ public:
inline void SetLeader(Mob* newleader){ leader=newleader; };
inline Mob* GetLeader() { return leader; };
const char* GetLeaderName() { return membername[0]; };
void SendHPPacketsTo(Mob* newmember);
void SendHPPacketsFrom(Mob* newmember);
void SendHPManaEndPacketsTo(Mob* newmember);
void SendHPPacketsFrom(Mob* member);
void SendManaPacketFrom(Mob* member);
void SendEndurancePacketFrom(Mob* member);
bool UpdatePlayer(Mob* update);
void MemberZoned(Mob* removemob);
inline bool IsLeader(Mob* leadertest) { return leadertest==leader; };

View File

@ -906,15 +906,15 @@ int32 Merc::CalcMaxMana()
max_mana = 0;
}
if (cur_mana > max_mana) {
cur_mana = max_mana;
if (current_mana > max_mana) {
current_mana = max_mana;
}
int mana_perc_cap = spellbonuses.ManaPercCap[0];
if(mana_perc_cap) {
int curMana_cap = (max_mana * mana_perc_cap) / 100;
if (cur_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && cur_mana > spellbonuses.ManaPercCap[1]))
cur_mana = curMana_cap;
if (current_mana > curMana_cap || (spellbonuses.ManaPercCap[1] && current_mana > spellbonuses.ManaPercCap[1]))
current_mana = curMana_cap;
}
#if EQDEBUG >= 11
@ -4987,7 +4987,7 @@ void Merc::ScaleStats(int scalepercent, bool setmax) {
max_mana = (int)((float)base_mana * scalerate);
base_mana = max_mana;
if (setmax)
cur_mana = max_mana;
current_mana = max_mana;
}
if (base_end)

View File

@ -125,7 +125,7 @@ Mob::Mob(const char* in_name,
last_z = 0;
last_major_update_position = m_Position;
AI_Init();
SetMoving(false);
@ -249,7 +249,7 @@ Mob::Mob(const char* in_name,
bEnraged = false;
shield_target = nullptr;
cur_mana = 0;
current_mana = 0;
max_mana = 0;
hp_regen = in_hp_regen;
mana_regen = in_mana_regen;
@ -1357,24 +1357,24 @@ void Mob::SendHPUpdate(bool skip_self)
last_hp_percent = current_hp_percent;
}
EQApplicationPacket hp_app;
EQApplicationPacket hp_packet;
Group *group = nullptr;
CreateHPPacket(&hp_app);
CreateHPPacket(&hp_packet);
/* Update those who have use targeted */
entity_list.QueueClientsByTarget(this, &hp_app, false, 0, false, true, EQEmu::versions::bit_AllClients);
entity_list.QueueClientsByTarget(this, &hp_packet, false, 0, false, true, EQEmu::versions::bit_AllClients);
/* Update those who have us on x-target */
entity_list.QueueClientsByXTarget(this, &hp_app, false);
entity_list.QueueClientsByXTarget(this, &hp_packet, false);
/* Update groups using Group LAA health name tag counter */
entity_list.QueueToGroupsForNPCHealthAA(this, &hp_app);
entity_list.QueueToGroupsForNPCHealthAA(this, &hp_packet);
/* Update group */
if(IsGrouped()) {
group = entity_list.GetGroupByMob(this);
if(group) //not sure why this might be null, but it happens
if(group)
group->SendHPPacketsFrom(this);
}
@ -1387,7 +1387,7 @@ void Mob::SendHPUpdate(bool skip_self)
/* Pet - Update master - group and raid if exists */
if(GetOwner() && GetOwner()->IsClient()) {
GetOwner()->CastToClient()->QueuePacket(&hp_app, false);
GetOwner()->CastToClient()->QueuePacket(&hp_packet, false);
group = entity_list.GetGroupByClient(GetOwner()->CastToClient());
if(group)
@ -1400,7 +1400,7 @@ void Mob::SendHPUpdate(bool skip_self)
/* Send to pet */
if(GetPet() && GetPet()->IsClient()) {
GetPet()->CastToClient()->QueuePacket(&hp_app, false);
GetPet()->CastToClient()->QueuePacket(&hp_packet, false);
}
/* Destructible objects */
@ -1439,10 +1439,20 @@ void Mob::SendHPUpdate(bool skip_self)
// this one just warps the mob to the current location
void Mob::SendPosition()
{
auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
MakeSpawnUpdateNoDelta(spu);
entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false);
/* When an NPC has made a large distance change - we should update all clients to prevent "ghosts" */
if (DistanceNoZ(last_major_update_position, m_Position) > 100) {
entity_list.QueueClients(this, app, true, true);
last_major_update_position = m_Position;
}
else {
entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false);
}
safe_delete(app);
}
@ -2270,13 +2280,13 @@ const int32& Mob::SetMana(int32 amount)
{
CalcMaxMana();
int32 mmana = GetMaxMana();
cur_mana = amount < 0 ? 0 : (amount > mmana ? mmana : amount);
current_mana = amount < 0 ? 0 : (amount > mmana ? mmana : amount);
/*
if(IsClient())
LogFile->write(EQEMuLog::Debug, "Setting mana for %s to %d (%4.1f%%)", GetName(), amount, GetManaRatio());
*/
return cur_mana;
return current_mana;
}

View File

@ -466,14 +466,14 @@ public:
inline int32 GetMaxHP() const { return max_hp; }
virtual int32 CalcMaxHP();
inline int32 GetMaxMana() const { return max_mana; }
inline int32 GetMana() const { return cur_mana; }
inline int32 GetMana() const { return current_mana; }
virtual int32 GetEndurance() const { return 0; }
virtual void SetEndurance(int32 newEnd) { return; }
int32 GetItemHPBonuses();
int32 GetSpellHPBonuses();
virtual const int32& SetMana(int32 amount);
inline float GetManaRatio() const { return max_mana == 0 ? 100 :
((static_cast<float>(cur_mana) / max_mana) * 100); }
((static_cast<float>(current_mana) / max_mana) * 100); }
virtual int32 CalcMaxMana();
uint32 GetNPCTypeID() const { return npctype_id; }
void SetNPCTypeID(uint32 npctypeid) { npctype_id = npctypeid; }
@ -998,7 +998,7 @@ public:
Timer GetAttackTimer() { return attack_timer; }
Timer GetAttackDWTimer() { return attack_dw_timer; }
inline bool IsFindable() { return findable; }
inline uint8 GetManaPercent() { return (uint8)((float)cur_mana / (float)max_mana * 100.0f); }
inline uint8 GetManaPercent() { return (uint8)((float)current_mana / (float)max_mana * 100.0f); }
virtual uint8 GetEndurancePercent() { return 0; }
inline virtual bool IsBlockedBuff(int16 SpellID) { return false; }
@ -1145,7 +1145,7 @@ protected:
int32 cur_hp;
int32 max_hp;
int32 base_hp;
int32 cur_mana;
int32 current_mana;
int32 max_mana;
int32 hp_regen;
int32 mana_regen;
@ -1184,6 +1184,8 @@ protected:
uint8 orig_level;
uint32 npctype_id;
glm::vec4 m_Position;
/* Used to determine when an NPC has traversed so many units - to send a zone wide pos update */
glm::vec4 last_major_update_position;
uint16 animation;
float base_size;
float size;

View File

@ -1990,7 +1990,7 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
else if(id == "int" || id == "_int") { INT = atoi(val.c_str()); CalcMaxMana(); return; }
else if(id == "cha") { CHA = atoi(val.c_str()); return; }
else if(id == "max_hp") { base_hp = atoi(val.c_str()); CalcMaxHP(); if (cur_hp > max_hp) { cur_hp = max_hp; } return; }
else if(id == "max_mana") { npc_mana = atoi(val.c_str()); CalcMaxMana(); if (cur_mana > max_mana){ cur_mana = max_mana; } return; }
else if(id == "max_mana") { npc_mana = atoi(val.c_str()); CalcMaxMana(); if (current_mana > max_mana){ current_mana = max_mana; } return; }
else if(id == "mr") { MR = atoi(val.c_str()); return; }
else if(id == "fr") { FR = atoi(val.c_str()); return; }
else if(id == "cr") { CR = atoi(val.c_str()); return; }

View File

@ -389,7 +389,7 @@ XS(XS_Group_SendHPPacketsTo)
if(newmember == nullptr)
Perl_croak(aTHX_ "newmember is nullptr, avoiding crash.");
THIS->SendHPPacketsTo(newmember);
THIS->SendHPManaEndPacketsTo(newmember);
}
XSRETURN_EMPTY;
}

View File

@ -145,11 +145,11 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
}
}
Group *group_update = nullptr;
group_update = c->GetGroup();
if (group_update) {
group_update->SendHPPacketsTo(c);
group_update->SendHPPacketsFrom(c);
Raid *raid_update = nullptr;
raid_update = c->GetRaid();
if (raid_update) {
raid_update->SendHPManaEndPacketsTo(c);
raid_update->SendHPPacketsFrom(c);
}
auto pack = new ServerPacket(ServerOP_RaidAdd, sizeof(ServerRaidGeneralAction_Struct));
@ -1546,7 +1546,7 @@ void Raid::MemberZoned(Client *c)
group_mentor[gid].mentoree = nullptr;
}
void Raid::SendHPPacketsTo(Client *client)
void Raid::SendHPManaEndPacketsTo(Client *client)
{
if(!client)
return;
@ -1583,35 +1583,89 @@ void Raid::SendHPPacketsTo(Client *client)
}
}
void Raid::SendHPPacketsFrom(Mob *m)
void Raid::SendHPPacketsFrom(Mob *mob)
{
if(!m)
if(!mob)
return;
uint32 gid = 0;
if(m->IsClient())
gid = this->GetGroup(m->CastToClient());
uint32 group_id = 0;
if(mob->IsClient())
group_id = this->GetGroup(mob->CastToClient());
EQApplicationPacket hpapp;
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
m->CreateHPPacket(&hpapp);
for(int x = 0; x < MAX_RAID_MEMBERS; x++)
{
if(members[x].member)
{
if(!m->IsClient() || ((members[x].member != m->CastToClient()) && (members[x].GroupNumber == gid)))
{
mob->CreateHPPacket(&hpapp);
for(int x = 0; x < MAX_RAID_MEMBERS; x++) {
if(members[x].member) {
if(!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
members[x].member->QueuePacket(&hpapp, false);
if (members[x].member->ClientVersion() >= EQEmu::versions::ClientVersion::SoD)
{
if (members[x].member->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mmus = (MobManaUpdate_Struct *)outapp.pBuffer;
mmus->spawn_id = m->GetID();
mmus->mana = m->GetManaPercent();
MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer;
mana_update->spawn_id = mob->GetID();
mana_update->mana = mob->GetManaPercent();
members[x].member->QueuePacket(&outapp, false);
outapp.SetOpcode(OP_MobEnduranceUpdate);
MobEnduranceUpdate_Struct *meus = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
meus->endurance = m->GetEndurancePercent();
MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
endurance_update->endurance = mob->GetEndurancePercent();
members[x].member->QueuePacket(&outapp, false);
}
}
}
}
}
void Raid::SendManaPacketFrom(Mob *mob)
{
if (!mob)
return;
uint32 group_id = 0;
if (mob->IsClient())
group_id = this->GetGroup(mob->CastToClient());
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
if (members[x].member) {
if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
if (members[x].member->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobManaUpdate);
MobManaUpdate_Struct *mana_update = (MobManaUpdate_Struct *)outapp.pBuffer;
mana_update->spawn_id = mob->GetID();
mana_update->mana = mob->GetManaPercent();
members[x].member->QueuePacket(&outapp, false);
}
}
}
}
}
void Raid::SendEndurancePacketFrom(Mob *mob)
{
if (!mob)
return;
uint32 group_id = 0;
if (mob->IsClient())
group_id = this->GetGroup(mob->CastToClient());
EQApplicationPacket outapp(OP_MobManaUpdate, sizeof(MobManaUpdate_Struct));
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
if (members[x].member) {
if (!mob->IsClient() || ((members[x].member != mob->CastToClient()) && (members[x].GroupNumber == group_id))) {
if (members[x].member->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
outapp.SetOpcode(OP_MobEnduranceUpdate);
MobEnduranceUpdate_Struct *endurance_update = (MobEnduranceUpdate_Struct *)outapp.pBuffer;
endurance_update->spawn_id = mob->GetID();
endurance_update->endurance = mob->GetEndurancePercent();
members[x].member->QueuePacket(&outapp, false);
}
}

View File

@ -172,8 +172,10 @@ public:
bool LearnMembers();
void VerifyRaid();
void MemberZoned(Client *c);
void SendHPPacketsTo(Client *c);
void SendHPPacketsFrom(Mob *m);
void SendHPManaEndPacketsTo(Client *c);
void SendHPPacketsFrom(Mob *mob);
void SendManaPacketFrom(Mob *mob);
void SendEndurancePacketFrom(Mob *mob);
void RaidSay(const char *msg, Client *c);
void RaidGroupSay(const char *msg, Client *c);

View File

@ -989,7 +989,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
database.RefreshGroupFromDB(client);
group->SendHPPacketsTo(client);
group->SendHPManaEndPacketsTo(client);
// If the group leader is not set, pull the group leader information from the database.
if (!group->GetLeader())