[Improvement] Filtered Messages Extension (#4435)

* [Improvment] Filtered Messages Extension

Added:
ItemSpeech 25
Strikethrough 26
Stuns 27
BardSongsOnPets 28

I wired up Strikethrough and Stuns as they already had message entries.

ItemSpeech and BardSongsOnPets do not appear to be currently used in the source.

Note: There are still 5 unknown Filters in RoF2 that need to be investigated:

Achievments
Fellowships
Mercenary Messages
PVP Messages
Spam

* Spelling Error

* Missed some stun calls
This commit is contained in:
Fryguy 2024-07-31 18:28:45 -04:00 committed by GitHub
parent 421767e1e5
commit 2feb05be18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 86 additions and 33 deletions

View File

@ -758,10 +758,10 @@ typedef enum {
FilterFocusEffects = 22, //0=show, 1=hide FilterFocusEffects = 22, //0=show, 1=hide
FilterPetSpells = 23, //0=show, 1=hide FilterPetSpells = 23, //0=show, 1=hide
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
FilterUnknown25 = 25, FilterItemSpeech = 25, //0=show, 1=hide // RoF2 Confirmed
FilterUnknown26 = 26, FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed
FilterUnknown27 = 27, FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed
FilterUnknown28 = 28, FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed
_FilterCount _FilterCount
} eqFilterType; } eqFilterType;

View File

@ -725,6 +725,7 @@ RULE_INT(Range, SpellParticles, 135, "The packet range in which spell particles
RULE_INT(Range, DamageMessages, 50, "The packet range in which damage messages are sent (non-crit)") RULE_INT(Range, DamageMessages, 50, "The packet range in which damage messages are sent (non-crit)")
RULE_INT(Range, SpellMessages, 75, "The packet range in which spell damage messages are sent") RULE_INT(Range, SpellMessages, 75, "The packet range in which spell damage messages are sent")
RULE_INT(Range, SongMessages, 75, "The packet range in which song messages are sent") RULE_INT(Range, SongMessages, 75, "The packet range in which song messages are sent")
RULE_INT(Range, StunMessages, 75, "The packet range in which stun messages are sent")
RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients") RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients")
RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent") RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent")
RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance") RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance")

View File

@ -1478,8 +1478,10 @@ int64 Mob::DoDamageCaps(int64 base_damage)
//SYNC WITH: tune.cpp, mob.h TuneDoAttack //SYNC WITH: tune.cpp, mob.h TuneDoAttack
void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool FromRiposte) void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, bool FromRiposte)
{ {
if (!other) if (!other) {
return; return;
}
LogCombat("[{}]::DoAttack vs [{}] base [{}] min [{}] offense [{}] tohit [{}] skill [{}]", GetName(), LogCombat("[{}]::DoAttack vs [{}] base [{}] min [{}] offense [{}] tohit [{}] skill [{}]", GetName(),
other->GetName(), hit.base_damage, hit.min_damage, hit.offense, hit.tohit, hit.skill); other->GetName(), hit.base_damage, hit.min_damage, hit.offense, hit.tohit, hit.skill);
@ -1491,14 +1493,22 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
if (!FromRiposte && other->AvoidDamage(this, hit)) { if (!FromRiposte && other->AvoidDamage(this, hit)) {
if (int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough; if (int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough;
strike_through && zone->random.Roll(strike_through)) { strike_through && zone->random.Roll(strike_through)) {
MessageString(Chat::StrikeThrough,
STRIKETHROUGH_STRING); // You strike through your opponents defenses! FilteredMessageString(
this, /* Sender */
Chat::StrikeThrough, /* Type: 339 */
FilterStrikethrough, /* FilterType: 12 */
STRIKETHROUGH_STRING /* You strike through your opponent's defenses! */
);
hit.damage_done = 1; // set to one, we will check this to continue hit.damage_done = 1; // set to one, we will check this to continue
} }
if (hit.damage_done == DMG_RIPOSTED) { if (hit.damage_done == DMG_RIPOSTED) {
DoRiposte(other); DoRiposte(other);
return; return;
} }
LogCombat("Avoided/strikethrough damage with code [{}]", hit.damage_done); LogCombat("Avoided/strikethrough damage with code [{}]", hit.damage_done);
} }
@ -1510,9 +1520,19 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
int stun_resist2 = other->spellbonuses.FrontalStunResist + other->itembonuses.FrontalStunResist + other->aabonuses.FrontalStunResist; int stun_resist2 = other->spellbonuses.FrontalStunResist + other->itembonuses.FrontalStunResist + other->aabonuses.FrontalStunResist;
int stun_resist = other->spellbonuses.StunResist + other->itembonuses.StunResist + other->aabonuses.StunResist; int stun_resist = other->spellbonuses.StunResist + other->itembonuses.StunResist + other->aabonuses.StunResist;
if (zone->random.Roll(stun_resist2)) { if (zone->random.Roll(stun_resist2)) {
other->MessageString(Chat::Stun, AVOID_STUNNING_BLOW); other->FilteredMessageString(
this,
Chat::Stun,
FilterStuns,
AVOID_STUNNING_BLOW
);
} else if (zone->random.Roll(stun_resist)) { } else if (zone->random.Roll(stun_resist)) {
other->MessageString(Chat::Stun, SHAKE_OFF_STUN); other->FilteredMessageString(
this,
Chat::Stun,
FilterStuns,
SHAKE_OFF_STUN
);
} else { } else {
other->Stun(3000); // yuck -- 3 seconds other->Stun(3000); // yuck -- 3 seconds
} }
@ -4506,34 +4526,61 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
Stun(RuleI(Combat, StunDuration)); Stun(RuleI(Combat, StunDuration));
if (RuleB(Combat, ClientStunMessage) && attacker->IsClient()) { if (RuleB(Combat, ClientStunMessage) && attacker->IsClient()) {
if (attacker) { if (attacker) {
entity_list.MessageClose(this, true, 500, Chat::Emote, "%s is stunned after being bashed by %s.", GetCleanName(), attacker->GetCleanName()); entity_list.FilteredMessageClose(
} this,
else { true,
entity_list.MessageClose(this, true, 500, Chat::Emote, "%s is stunned by a bash to the head.", GetCleanName()); RuleI(Range, StunMessages),
Chat::Stun,
FilterStuns,
"%s is stunned after being bashed by %s.",
GetCleanName(),
attacker->GetCleanName()
);
} else {
entity_list.FilteredMessageClose(
this,
true,
RuleI(Range, StunMessages),
Chat::Stun,
FilterStuns,
"%s is stunned by a bash to the head.",
GetCleanName()
);
} }
} }
} } else {
else {
// stun resist passed! // stun resist passed!
if (IsClient()) if (IsClient()) {
MessageString(Chat::Stun, SHAKE_OFF_STUN); FilteredMessageString(
this,
Chat::Stun,
FilterStuns,
SHAKE_OFF_STUN
);
} }
} }
else { } else {
// stun resist 2 passed! // stun resist 2 passed!
if (IsClient()) if (IsClient()) {
MessageString(Chat::Stun, AVOID_STUNNING_BLOW); FilteredMessageString(
this,
Chat::Stun,
FilterStuns,
AVOID_STUNNING_BLOW
);
} }
} }
else { } else {
// main stun failed -- extra interrupt roll // main stun failed -- extra interrupt roll
if (IsCasting() && // these spells are excluded
!EQ::ValueWithin(casting_spell_id, 859, 1023)) // these spells are excluded
// 90% chance >< -- stun immune won't reach this branch though :( // 90% chance >< -- stun immune won't reach this branch though :(
if (zone->random.Int(0, 9) > 1) if (IsCasting() && !EQ::ValueWithin(casting_spell_id, 859, 1023)) {
if (zone->random.Int(0, 9) > 1) {
InterruptSpell(); InterruptSpell();
} }
} }
}
}
if (IsValidSpell(spell_id) && !iBuffTic) { if (IsValidSpell(spell_id) && !iBuffTic) {
//see if root will break //see if root will break

View File

@ -3403,6 +3403,11 @@ void Client::ServerFilter(SetServerFilter_Struct* filter){
} else { // these clients don't have a 'self only' filter } else { // these clients don't have a 'self only' filter
Filter1(FilterHealOverTime); Filter1(FilterHealOverTime);
} }
Filter1(FilterItemSpeech);
Filter1(FilterStrikethrough);
Filter1(FilterStuns);
Filter1(FilterBardSongsOnPets);
} }
// this version is for messages with no parameters // this version is for messages with no parameters

View File

@ -7256,10 +7256,10 @@ luabind::scope lua_register_filters() {
luabind::value("FocusEffects", FilterFocusEffects), luabind::value("FocusEffects", FilterFocusEffects),
luabind::value("PetSpells", FilterPetSpells), luabind::value("PetSpells", FilterPetSpells),
luabind::value("HealOverTime", FilterHealOverTime), luabind::value("HealOverTime", FilterHealOverTime),
luabind::value("Unknown25", FilterUnknown25), luabind::value("ItemSpeech", FilterItemSpeech),
luabind::value("Unknown26", FilterUnknown26), luabind::value("Strikethrough", FilterStrikethrough),
luabind::value("Unknown27", FilterUnknown27), luabind::value("Stuns", FilterStuns),
luabind::value("Unknown28", FilterUnknown28) luabind::value("BardSongsOnPets", FilterBardSongsOnPets)
)]; )];
} }