diff --git a/changelog.txt b/changelog.txt index 073827861..9514c812c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,21 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 03/12/2017 == +Akkadius: +- Implemented range rules for packets and other functions + RULE_INT ( Range, Say, 135 ) + RULE_INT ( Range, Emote, 135 ) + RULE_INT ( Range, BeginCast, 200) + RULE_INT ( Range, Anims, 135) + RULE_INT ( Range, SpellParticles, 135) + RULE_INT ( Range, DamageMessages, 50) + RULE_INT ( Range, SpellMessages, 75) + RULE_INT ( Range, SongMessages, 75) + RULE_INT ( Range, MobPositionUpdates, 600) + RULE_INT ( Range, CriticalDamage, 80) + + - (Readability) Also cleaned up some formatting in messaging and packets so it is easier to understand what is going on with the code + == 03/09/2017 == Uleat: Fixed a few glitches related to bot trading and other affected code - Added a temporary fail clause for partial stack transfers to prevent client item overwrites diff --git a/common/ruletypes.h b/common/ruletypes.h index fbb6f17bd..4b6823114 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -548,11 +548,15 @@ RULE_INT(Range, Say, 135) RULE_INT(Range, Emote, 135) RULE_INT(Range, BeginCast, 200) RULE_INT(Range, Anims, 135) +RULE_INT(Range, SpellParticles, 135) RULE_INT(Range, DamageMessages, 50) RULE_INT(Range, SpellMessages, 75) RULE_INT(Range, SongMessages, 75) +RULE_INT(Range, MobPositionUpdates, 600) +RULE_INT(Range, CriticalDamage, 80) RULE_CATEGORY_END() + #ifdef BOTS RULE_CATEGORY(Bots) RULE_INT(Bots, AAExpansion, 8) // Bots get AAs through this expansion diff --git a/zone/attack.cpp b/zone/attack.cpp index ee212ba78..7f5efa933 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1480,9 +1480,18 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk } if(killerMob && killerMob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) { - char val1[20]={0}; - entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE, - killerMob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1)); + char val1[20] = { 0 }; + + entity_list.MessageClose_StringID( + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, DamageMessages), + MT_NonMelee, /* 283 */ + HIT_NON_MELEE, /* %1 hit %2 for %3 points of non-melee damage. */ + killerMob->GetCleanName(), /* Message1 */ + GetCleanName(), /* Message2 */ + ConvertArray(damage, val1)/* Message3 */ + ); } int exploss = 0; @@ -2009,8 +2018,17 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil if (killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) { char val1[20] = { 0 }; - entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE, - killer_mob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1)); + + entity_list.MessageClose_StringID( + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, DamageMessages), + MT_NonMelee, /* 283 */ + HIT_NON_MELEE, /* %1 hit %2 for %3 points of non-melee damage. */ + killer_mob->GetCleanName(), /* Message1 */ + GetCleanName(), /* Message2 */ + ConvertArray(damage, val1) /* Message3 */ + ); } } else { @@ -3229,7 +3247,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const //we used to do a message to the client, but its gone now. // emote goes with every one ... even npcs - entity_list.MessageClose(this, true, 300, MT_Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName() ); + entity_list.MessageClose(this, true, RuleI(Range, SpellMessages), MT_Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName() ); } } //end `if there is some damage being done and theres anattacker person involved` @@ -3309,8 +3327,15 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const //fade mez if we are mezzed if (IsMezzed() && attacker) { Log.Out(Logs::Detail, Logs::Combat, "Breaking mez due to attack."); - entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), MT_WornOff, - HAS_BEEN_AWAKENED, GetCleanName(), attacker->GetCleanName()); + entity_list.MessageClose_StringID( + this, /* Sender */ + true, /* Skip Sender */ + RuleI(Range, SpellMessages), + MT_WornOff, /* 284 */ + HAS_BEEN_AWAKENED, // %1 has been awakened by %2. + GetCleanName(), /* Message1 */ + attacker->GetCleanName() /* Message2 */ + ); BuffFadeByEffect(SE_Mez); } @@ -3454,8 +3479,8 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const else filter = FilterPetMisses; - if(!FromDamageShield) - owner->CastToClient()->QueuePacket(outapp,true,CLIENT_CONNECTED,filter); + if (!FromDamageShield) + owner->CastToClient()->QueuePacket(outapp, true, CLIENT_CONNECTED, filter); } } skip = owner; @@ -3469,9 +3494,18 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const char val1[20] = {0}; if (FromDamageShield) { if (attacker->CastToClient()->GetFilter(FilterDamageShields) != FilterHide) - attacker->Message_StringID(MT_DS,OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); + attacker->Message_StringID(MT_DS, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); } else { - entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), MT_NonMelee, HIT_NON_MELEE, attacker->GetCleanName(), GetCleanName(), ConvertArray(damage, val1)); + entity_list.MessageClose_StringID( + this, /* Sender */ + true, /* Skip Sender */ + RuleI(Range, SpellMessages), + MT_NonMelee, /* 283 */ + HIT_NON_MELEE, /* %1 hit %2 for %3 points of non-melee damage. */ + attacker->GetCleanName(), /* Message1 */ + GetCleanName(), /* Message2 */ + ConvertArray(damage, val1) /* Message3 */ + ); } } else { if(damage > 0) { @@ -3505,7 +3539,17 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const // If this is Damage Shield damage, the correct OP_Damage packets will be sent from Mob::DamageShield, so // we don't send them here. if(!FromDamageShield) { - entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, SpellMessages), skip, true, filter); + + entity_list.QueueCloseClients( + this, /* Sender */ + outapp, /* packet */ + true, /* Skip Sender */ + RuleI(Range, SpellMessages), + skip, /* Skip this mob */ + true, /* Packet ACK */ + filter /* eqFilterType filter */ + ); + //send the damage to ourself if we are a client if(IsClient()) { //I dont think any filters apply to damage affecting us @@ -3521,10 +3565,20 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const //might filter on (attack_skill>200 && attack_skill<250), but I dont think we need it attacker->FilteredMessage_StringID(attacker, MT_DoTDamage, FilterDOT, YOUR_HIT_DOT, GetCleanName(), itoa(damage), spells[spell_id].name); - // older clients don't have the below String ID, but it will be filtered - entity_list.FilteredMessageClose_StringID(attacker, true, RuleI(Range, SpellMessages), - MT_DoTDamage, FilterDOT, OTHER_HIT_DOT, GetCleanName(), - itoa(damage), attacker->GetCleanName(), spells[spell_id].name); + + /* older clients don't have the below String ID, but it will be filtered */ + entity_list.FilteredMessageClose_StringID( + attacker, /* Sender */ + true, /* Skip Sender */ + RuleI(Range, SpellMessages), + MT_DoTDamage, /* Type: 325 */ + FilterDOT, /* FilterType: 19 */ + OTHER_HIT_DOT, /* MessageFormat: %1 has taken %2 damage from %3 by %4. */ + GetCleanName(), /* Message1 */ + itoa(damage), /* Message2 */ + attacker->GetCleanName(), /* Message3 */ + spells[spell_id].name /* Message4 */ + ); } } //end packet sending @@ -3932,8 +3986,18 @@ void Mob::TryPetCriticalHit(Mob *defender, DamageHitInfo &hit) critMod += GetCritDmgMob(hit.skill); hit.damage_done += 5; hit.damage_done = (hit.damage_done * critMod) / 100; - entity_list.FilteredMessageClose_StringID(this, false, 200, MT_CritMelee, FilterMeleeCrits, - CRITICAL_HIT, GetCleanName(), itoa(hit.damage_done + hit.min_damage)); + + entity_list.FilteredMessageClose_StringID( + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + CRITICAL_HIT, /* MessageFormat: %1 scores a critical hit! (%2) */ + GetCleanName(), /* Message1 */ + itoa(hit.damage_done + hit.min_damage) /* Message2 */ + ); + } } } @@ -3971,14 +4035,33 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * {aabonuses.SlayUndead[1], itembonuses.SlayUndead[1], spellbonuses.SlayUndead[1]}); hit.damage_done = std::max(hit.damage_done, hit.base_damage) + 5; hit.damage_done = (hit.damage_done * SlayDmgBonus) / 100; - if (GetGender() == 1) // female + + /* Female */ + if (GetGender() == 1) { entity_list.FilteredMessageClose_StringID( - this, false, 200, MT_CritMelee, FilterMeleeCrits, FEMALE_SLAYUNDEAD, - GetCleanName(), itoa(hit.damage_done + hit.min_damage)); - else // males and neuter I guess + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + FEMALE_SLAYUNDEAD, /* MessageFormat: %1's holy blade cleanses her target!(%2) */ + GetCleanName(), /* Message1 */ + itoa(hit.damage_done + hit.min_damage) /* Message2 */ + ); + } + /* Males and Neuter */ + else { entity_list.FilteredMessageClose_StringID( - this, false, 200, MT_CritMelee, FilterMeleeCrits, MALE_SLAYUNDEAD, - GetCleanName(), itoa(hit.damage_done + hit.min_damage)); + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + MALE_SLAYUNDEAD, /* MessageFormat: %1's holy blade cleanses his target!(%2) */ + GetCleanName(), /* Message1 */ + itoa(hit.damage_done + hit.min_damage) /* Message2 */ + ); + } return; } } @@ -4047,9 +4130,17 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * return; } hit.damage_done = hit.damage_done * 200 / 100; + entity_list.FilteredMessageClose_StringID( - this, false, 200, MT_CritMelee, FilterMeleeCrits, DEADLY_STRIKE, - GetCleanName(), itoa(hit.damage_done + hit.min_damage)); + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + DEADLY_STRIKE, /* MessageFormat: %1 scores a Deadly Strike!(%2) */ + GetCleanName(), /* Message1 */ + itoa(hit.damage_done + hit.min_damage) /* Message2 */ + ); return; } } @@ -4067,9 +4158,18 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * if (IsBerserk() || berserk) { hit.damage_done += og_damage * 119 / 100; Log.Out(Logs::Detail, Logs::Combat, "Crip damage %d", hit.damage_done); + entity_list.FilteredMessageClose_StringID( - this, false, 200, MT_CritMelee, FilterMeleeCrits, CRIPPLING_BLOW, GetCleanName(), - itoa(hit.damage_done + hit.min_damage)); + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + CRIPPLING_BLOW, /* MessageFormat: %1 lands a Crippling Blow!(%2) */ + GetCleanName(), /* Message1 */ + itoa(hit.damage_done + hit.min_damage) /* Message2 */ + ); + // Crippling blows also have a chance to stun // Kayen: Crippling Blow would cause a chance to interrupt for npcs < 55, with a // staggers message. @@ -4079,10 +4179,18 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * } return; } - // okay, critted but didn't do anything else, just normal message now - entity_list.FilteredMessageClose_StringID(this, false, 200, MT_CritMelee, FilterMeleeCrits, - CRITICAL_HIT, GetCleanName(), - itoa(hit.damage_done + hit.min_damage)); + + /* Normal Critical hit message */ + entity_list.FilteredMessageClose_StringID( + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + CRITICAL_HIT, /* MessageFormat: %1 scores a critical hit! (%2) */ + GetCleanName(), /* Message1 */ + itoa(hit.damage_done + hit.min_damage) /* Message2 */ + ); } } } @@ -4108,7 +4216,18 @@ bool Mob::TryFinishingBlow(Mob *defender, int &damage) if (FB_Level && FB_Dmg && (defender->GetLevel() <= FB_Level) && (ProcChance >= zone->random.Int(1, 1000))) { - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FINISHING_BLOW, GetName()); + + /* Finishing Blow Critical Message */ + entity_list.FilteredMessageClose_StringID( + this, /* Sender */ + false, /* Skip Sender */ + RuleI(Range, CriticalDamage), + MT_CritMelee, /* Type: 301 */ + FilterMeleeCrits, /* FilterType: 12 */ + FINISHING_BLOW, /* MessageFormat: %1 scores a Finishing Blow!!) */ + GetCleanName() /* Message1 */ + ); + damage = FB_Dmg; return true; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index b214c477f..4b3817e9a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4372,7 +4372,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) 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); + entity_list.QueueCloseClients(boat, outapp, true, 300, this, false); safe_delete(outapp); // 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); diff --git a/zone/mob.cpp b/zone/mob.cpp index 256f9f715..e7b248dd5 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1426,7 +1426,7 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) { } else if(move_tic_count % 2 == 0) { - entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), 700, nullptr, false); + entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false); move_tic_count++; } else { @@ -1529,15 +1529,26 @@ void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter) auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct)); Animation_Struct* anim = (Animation_Struct*)outapp->pBuffer; anim->spawnid = GetID(); + if(type == 0){ anim->action = animnum; anim->speed = 10; } - else{ + else { anim->action = animnum; anim->speed = type; } - entity_list.QueueCloseClients(this, outapp, false, RuleI(Range, Anims), 0, ackreq, filter); + + entity_list.QueueCloseClients( + this, /* Sender */ + outapp, /* Packet */ + false, /* Ignore Sender */ + RuleI(Range, Anims), + 0, /* Skip this mob */ + ackreq, /* Packet ACK */ + filter /* eqFilterType filter */ + ); + safe_delete(outapp); } @@ -1581,7 +1592,7 @@ void Mob::ShowBuffList(Client* client) { client->Message(0, "Buffs on: %s", this->GetCleanName()); uint32 i; uint32 buff_count = GetMaxTotalSlots(); - for (i=0; i < buff_count; i++) { + for (i = 0; i < buff_count; i++) { if (buffs[i].spellid != SPELL_UNKNOWN) { if (spells[buffs[i].spellid].buffdurationformula == DF_Permanent) client->Message(0, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); diff --git a/zone/spells.cpp b/zone/spells.cpp index deec22b82..60ca016ff 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -363,9 +363,22 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, StopCasting(); Message_StringID(MT_SpellFailure, fizzle_msg); + + /* Song Failure Messages */ entity_list.FilteredMessageClose_StringID( - this, true, RuleI(Range, SpellMessages), MT_SpellFailure, IsClient() ? FilterPCSpells : FilterNPCSpells, - fizzle_msg == MISS_NOTE ? MISSED_NOTE_OTHER : SPELL_FIZZLE_OTHER, GetName()); + this, /* Sender */ + true, /* Skip Sender */ + RuleI(Range, SpellMessages), + MT_SpellFailure, /* Type: 289 */ + (IsClient() ? FilterPCSpells : FilterNPCSpells), /* FilterType: 8 or 9 depending on client/npc */ + (fizzle_msg == MISS_NOTE ? MISSED_NOTE_OTHER : SPELL_FIZZLE_OTHER), + /* + MessageFormat: You miss a note, bringing your song to a close! (if missed note) + MessageFormat: A missed note brings %1's song to a close! + MessageFormat: %1's spell fizzles! + */ + GetName() /* Message1 */ + ); TryTriggerOnValueAmount(false, true); return(false); @@ -469,7 +482,14 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, begincast->spell_id = spell_id; begincast->cast_time = orgcasttime; // client calculates reduced time by itself outapp->priority = 3; - entity_list.QueueCloseClients(this, outapp, false, RuleI(Range, BeginCast), 0, true); //IsClient() ? FILTER_PCSPELLS : FILTER_NPCSPELLS); + entity_list.QueueCloseClients( + this, /* Sender */ + outapp, /* Packet */ + false, /* Ignore Sender */ + RuleI(Range, BeginCast), + 0, /* Skip this Mob */ + true /* Packet ACK */ + ); //IsClient() ? FILTER_PCSPELLS : FILTER_NPCSPELLS); safe_delete(outapp); } @@ -3486,7 +3506,15 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r CastToClient()->QueuePacket(action_packet); // send to people in the area, ignoring caster and target - entity_list.QueueCloseClients(spelltar, action_packet, true, RuleI(Range, SpellMessages), this, true, spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells); + entity_list.QueueCloseClients( + spelltar, /* Sender */ + action_packet, /* Packet */ + true, /* Ignore Sender */ + RuleI(Range, SpellMessages), + this, /* Skip this Mob */ + true, /* Packet ACK */ + (spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells) /* EQ Filter Type: (8 or 9) */ + ); /* Send the EVENT_CAST_ON event */ if(spelltar->IsNPC()) @@ -3955,9 +3983,16 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r cd->spellid = action->spell; cd->meleepush_xy = action->sequence; cd->damage = 0; - if(!IsEffectInSpell(spell_id, SE_BindAffinity)) - { - entity_list.QueueCloseClients(spelltar, message_packet, false, RuleI(Range, SpellMessages), 0, true, spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells); + if(!IsEffectInSpell(spell_id, SE_BindAffinity)){ + entity_list.QueueCloseClients( + spelltar, /* Sender */ + message_packet, /* Packet */ + false, /* Ignore Sender */ + RuleI(Range, SpellMessages), + 0, /* Skip this mob */ + true, /* Packet ACK */ + (spelltar->IsClient() ? FilterPCSpells : FilterNPCSpells) /* Message Filter Type: (8 or 9) */ + ); } safe_delete(action_packet); safe_delete(message_packet); @@ -5611,7 +5646,7 @@ void Client::SendSpellAnim(uint16 targetid, uint16 spell_id) a->sequence = 231; app.priority = 1; - entity_list.QueueCloseClients(this, &app); + entity_list.QueueCloseClients(this, &app, false, RuleI(Range, SpellParticles)); } void Mob::CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ)