Send HP updates when mobs update regen hp internally

This commit is contained in:
Akkadius 2018-10-09 08:38:35 -05:00
parent a836baac32
commit 72bf4b7e3c
3 changed files with 108 additions and 78 deletions

View File

@ -253,7 +253,7 @@ Mob::Mob(const char* in_name,
max_mana = 0; max_mana = 0;
hp_regen = in_hp_regen; hp_regen = in_hp_regen;
mana_regen = in_mana_regen; mana_regen = in_mana_regen;
oocregen = RuleI(NPC, OOCRegen); //default Out of Combat Regen ooc_regen = RuleI(NPC, OOCRegen); //default Out of Combat Regen
maxlevel = in_maxlevel; maxlevel = in_maxlevel;
scalerate = in_scalerate; scalerate = in_scalerate;
invisible = false; invisible = false;
@ -1303,14 +1303,17 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
} }
} }
// sends hp update of this mob to people who might care void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/) {
void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/)
{
/* If our HP is different from last HP update call - let's update ourself */ /**
* If our HP is different from last HP update call - let's update selves
*/
if (IsClient()) { if (IsClient()) {
if (cur_hp != last_hp || force_update_all) { if (cur_hp != last_hp || force_update_all) {
/* This is to prevent excessive packet sending under trains/fast combat */
/**
* This is to prevent excessive packet sending under trains/fast combat
*/
if (this->CastToClient()->hp_self_update_throttle_timer.Check() || force_update_all) { if (this->CastToClient()->hp_self_update_throttle_timer.Check() || force_update_all) {
Log(Logs::General, Logs::HP_Update, Log(Logs::General, Logs::HP_Update,
"Mob::SendHPUpdate :: Update HP of self (%s) HP: %i last: %i skip_self: %s", "Mob::SendHPUpdate :: Update HP of self (%s) HP: %i last: %i skip_self: %s",
@ -1322,7 +1325,8 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
if (!skip_self || this->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) { if (!skip_self || this->CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::SoD) {
auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct));
SpawnHPUpdate_Struct* hp_packet_client = (SpawnHPUpdate_Struct*)client_packet->pBuffer;
SpawnHPUpdate_Struct *hp_packet_client = (SpawnHPUpdate_Struct *) client_packet->pBuffer;
hp_packet_client->cur_hp = CastToClient()->GetHP() - itembonuses.HP; hp_packet_client->cur_hp = CastToClient()->GetHP() - itembonuses.HP;
hp_packet_client->spawn_id = GetID(); hp_packet_client->spawn_id = GetID();
@ -1335,7 +1339,9 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
ResetHPUpdateTimer(); ResetHPUpdateTimer();
} }
/* Used to check if HP has changed to update self next round */ /**
* Used to check if HP has changed to update self next round
*/
last_hp = cur_hp; last_hp = cur_hp;
} }
} }
@ -1343,7 +1349,12 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
int8 current_hp_percent = (max_hp == 0 ? 0 : static_cast<int>(cur_hp * 100 / max_hp)); int8 current_hp_percent = (max_hp == 0 ? 0 : static_cast<int>(cur_hp * 100 / max_hp));
Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: SendHPUpdate %s HP is %i last %i", this->GetCleanName(), current_hp_percent, last_hp_percent); Log(Logs::General,
Logs::HP_Update,
"Mob::SendHPUpdate :: SendHPUpdate %s HP is %i last %i",
this->GetCleanName(),
current_hp_percent,
last_hp_percent);
if (current_hp_percent == last_hp_percent && !force_update_all) { if (current_hp_percent == last_hp_percent && !force_update_all) {
Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: Same HP - skipping update"); Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: Same HP - skipping update");
@ -1352,8 +1363,9 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
} }
else { else {
if (IsClient() && RuleB(Character, MarqueeHPUpdates)) if (IsClient() && RuleB(Character, MarqueeHPUpdates)) {
this->CastToClient()->SendHPUpdateMarquee(); this->CastToClient()->SendHPUpdateMarquee();
}
Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: HP Changed - Send update"); Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: HP Changed - Send update");
@ -1365,48 +1377,65 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
CreateHPPacket(&hp_packet); CreateHPPacket(&hp_packet);
/* Update those who have us targeted */ /**
* Update those who have us targeted
*/
entity_list.QueueClientsByTarget(this, &hp_packet, 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 */ /**
* Update those who have us on x-target
*/
entity_list.QueueClientsByXTarget(this, &hp_packet, false); entity_list.QueueClientsByXTarget(this, &hp_packet, false);
/* Update groups using Group LAA health name tag counter */ /**
* Update groups using Group LAA health name tag counter
*/
entity_list.QueueToGroupsForNPCHealthAA(this, &hp_packet); entity_list.QueueToGroupsForNPCHealthAA(this, &hp_packet);
/* Update group */ /**
if(IsGrouped()) { * Group
*/
if (IsGrouped()) {
group = entity_list.GetGroupByMob(this); group = entity_list.GetGroupByMob(this);
if(group) if (group) {
group->SendHPPacketsFrom(this); group->SendHPPacketsFrom(this);
} }
/* Update Raid */
if(IsClient()){
Raid *raid = entity_list.GetRaidByClient(CastToClient());
if (raid)
raid->SendHPManaEndPacketsFrom(this);
} }
/* Pet - Update master - group and raid if exists */ /**
if(GetOwner() && GetOwner()->IsClient()) { * Raid
*/
if (IsClient()) {
Raid *raid = entity_list.GetRaidByClient(CastToClient());
if (raid) {
raid->SendHPManaEndPacketsFrom(this);
}
}
/**
* Pet
*/
if (GetOwner() && GetOwner()->IsClient()) {
GetOwner()->CastToClient()->QueuePacket(&hp_packet, false); GetOwner()->CastToClient()->QueuePacket(&hp_packet, false);
group = entity_list.GetGroupByClient(GetOwner()->CastToClient()); group = entity_list.GetGroupByClient(GetOwner()->CastToClient());
if(group) if (group) {
group->SendHPPacketsFrom(this); group->SendHPPacketsFrom(this);
Raid *raid = entity_list.GetRaidByClient(GetOwner()->CastToClient());
if(raid)
raid->SendHPManaEndPacketsFrom(this);
} }
/* Send to pet */ Raid *raid = entity_list.GetRaidByClient(GetOwner()->CastToClient());
if(GetPet() && GetPet()->IsClient()) { if (raid) {
raid->SendHPManaEndPacketsFrom(this);
}
}
if (GetPet() && GetPet()->IsClient()) {
GetPet()->CastToClient()->QueuePacket(&hp_packet, false); GetPet()->CastToClient()->QueuePacket(&hp_packet, false);
} }
/* Destructible objects */ /**
* Destructible objects
*/
if (IsNPC() && IsDestructibleObject()) { if (IsNPC() && IsDestructibleObject()) {
if (GetHPRatio() > 74) { if (GetHPRatio() > 74) {
if (GetAppearance() != eaStanding) { if (GetAppearance() != eaStanding) {

View File

@ -421,7 +421,7 @@ public:
bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) = 0; bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) = 0;
inline virtual void SetHP(int32 hp) { if (hp >= max_hp) cur_hp = max_hp; else cur_hp = hp;} inline virtual void SetHP(int32 hp) { if (hp >= max_hp) cur_hp = max_hp; else cur_hp = hp;}
bool ChangeHP(Mob* other, int32 amount, uint16 spell_id = 0, int8 buffslot = -1, bool iBuffTic = false); bool ChangeHP(Mob* other, int32 amount, uint16 spell_id = 0, int8 buffslot = -1, bool iBuffTic = false);
inline void SetOOCRegen(int32 newoocregen) {oocregen = newoocregen;} inline void SetOOCRegen(int32 newoocregen) {ooc_regen = newoocregen;}
virtual void Heal(); virtual void Heal();
virtual void HealDamage(uint32 ammount, Mob* caster = nullptr, uint16 spell_id = SPELL_UNKNOWN); virtual void HealDamage(uint32 ammount, Mob* caster = nullptr, uint16 spell_id = SPELL_UNKNOWN);
virtual void SetMaxHP() { cur_hp = max_hp; } virtual void SetMaxHP() { cur_hp = max_hp; }
@ -1223,7 +1223,7 @@ protected:
int32 max_mana; int32 max_mana;
int32 hp_regen; int32 hp_regen;
int32 mana_regen; int32 mana_regen;
int32 oocregen; int32 ooc_regen;
uint8 maxlevel; uint8 maxlevel;
uint32 scalerate; uint32 scalerate;
Buffs_Struct *buffs; Buffs_Struct *buffs;

View File

@ -667,77 +667,78 @@ bool NPC::Process()
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0); parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
BuffProcess(); BuffProcess();
if (currently_fleeing) if (currently_fleeing) {
ProcessFlee(); ProcessFlee();
uint32 sitting_bonus = 0;
uint32 petbonus = 0;
uint32 bestregen = 0;
int32 dbregen = GetNPCHPRegen();
if (GetAppearance() == eaSitting)
sitting_bonus += 3;
int32 OOCRegen = 0;
if (oocregen > 0) { //should pull from Mob class
OOCRegen += GetMaxHP() * oocregen / 100;
} }
// Fixing NPC regen.NPCs should regen to full during uint32 npc_sitting_regen_bonus = 0;
// a set duration, not based on their HPs.Increase NPC's HPs by uint32 pet_regen_bonus = 0;
// % of total HPs / tick. uint32 npc_regen = 0;
// int32 npc_hp_regen = GetNPCHPRegen();
// If oocregen set in db, apply to pets as well.
// This allows the obscene #s for pets in the db to be tweaked
// while maintaining a decent ooc regen.
bestregen = std::max(dbregen,OOCRegen); if (GetAppearance() == eaSitting) {
npc_sitting_regen_bonus += 3;
}
int32 ooc_regen_calc = 0;
if (ooc_regen > 0) { //should pull from Mob class
ooc_regen_calc += GetMaxHP() * ooc_regen / 100;
}
/**
* Use max value between two values
*/
npc_regen = std::max(npc_hp_regen, ooc_regen_calc);
if ((GetHP() < GetMaxHP()) && !IsPet()) { if ((GetHP() < GetMaxHP()) && !IsPet()) {
if (!IsEngaged()) if (!IsEngaged()) {
SetHP(GetHP() + bestregen + sitting_bonus); SetHP(GetHP() + npc_regen + npc_sitting_regen_bonus);
else }
SetHP(GetHP() + dbregen); else {
SetHP(GetHP() + npc_hp_regen);
}
} }
else if (GetHP() < GetMaxHP() && GetOwnerID() != 0) { else if (GetHP() < GetMaxHP() && GetOwnerID() != 0) {
if (!IsEngaged()) { if (!IsEngaged()) {
if (oocregen > 0) { if (ooc_regen > 0) {
petbonus = std::max(OOCRegen,dbregen); pet_regen_bonus = std::max(ooc_regen_calc, npc_hp_regen);
} }
else { else {
petbonus = dbregen + (GetLevel() / 5); pet_regen_bonus = npc_hp_regen + (GetLevel() / 5);
} }
SetHP(GetHP() + sitting_bonus + petbonus); SetHP(GetHP() + npc_sitting_regen_bonus + pet_regen_bonus);
} }
else else {
SetHP(GetHP() + dbregen); SetHP(GetHP() + npc_hp_regen);
}
}
else {
SetHP(GetHP() + npc_hp_regen + npc_sitting_regen_bonus);
} }
else
SetHP(GetHP() + dbregen + sitting_bonus);
if (GetMana() < GetMaxMana()) { if (GetMana() < GetMaxMana()) {
SetMana(GetMana() + mana_regen + sitting_bonus); SetMana(GetMana() + mana_regen + npc_sitting_regen_bonus);
} }
SendHPUpdate();
if (zone->adv_data && !p_depop) if (zone->adv_data && !p_depop) {
{ ServerZoneAdventureDataReply_Struct *ds = (ServerZoneAdventureDataReply_Struct *) zone->adv_data;
ServerZoneAdventureDataReply_Struct* ds = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; if (ds->type == Adventure_Rescue && ds->data_id == GetNPCTypeID()) {
if (ds->type == Adventure_Rescue && ds->data_id == GetNPCTypeID())
{
Mob *o = GetOwner(); Mob *o = GetOwner();
if (o && o->IsClient()) if (o && o->IsClient()) {
{
float x_diff = ds->dest_x - GetX(); float x_diff = ds->dest_x - GetX();
float y_diff = ds->dest_y - GetY(); float y_diff = ds->dest_y - GetY();
float z_diff = ds->dest_z - GetZ(); float z_diff = ds->dest_z - GetZ();
float dist = ((x_diff * x_diff) + (y_diff * y_diff) + (z_diff * z_diff)); float dist = ((x_diff * x_diff) + (y_diff * y_diff) + (z_diff * z_diff));
if (dist < RuleR(Adventure, DistanceForRescueComplete)) if (dist < RuleR(Adventure, DistanceForRescueComplete)) {
{
zone->DoAdventureCountIncrease(); zone->DoAdventureCountIncrease();
Say("You don't know what this means to me. Thank you so much for finding and saving me from" Say(
" this wretched place. I'll find my way from here."); "You don't know what this means to me. Thank you so much for finding and saving me from"
" this wretched place. I'll find my way from here."
);
Depop(); Depop();
} }
} }