mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
[Spells] Updates and fixes to targeted focus effects (#1870)
This commit is contained in:
parent
6da7116c66
commit
73acc3310c
@ -674,7 +674,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
|
||||
uint8 focus = IsFocusEffect(0, 0, true, effect);
|
||||
if (focus) {
|
||||
newbon->FocusEffects[focus] = static_cast<uint8>(effect);
|
||||
newbon->FocusEffects[focus] = effect;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1887,7 +1887,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
}
|
||||
}
|
||||
else {
|
||||
new_bonus->FocusEffects[focus] = static_cast<uint8>(spells[spell_id].effect_id[i]);
|
||||
new_bonus->FocusEffects[focus] = spells[spell_id].effect_id[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -4113,9 +4113,9 @@ uint8 Mob::IsFocusEffect(uint16 spell_id,int effect_index, bool AA,uint32 aa_eff
|
||||
case SE_Fc_ResistIncoming:
|
||||
focusFcResistIncoming;
|
||||
case SE_Fc_Amplify_Mod:
|
||||
focusFcResistIncoming;
|
||||
focusFcAmplifyMod;
|
||||
case SE_Fc_Amplify_Amt:
|
||||
focusFcResistIncoming;
|
||||
focusFcAmplifyAmt;
|
||||
case SE_SpellHateMod:
|
||||
return focusSpellHateMod;
|
||||
case SE_ReduceReuseTimer:
|
||||
|
||||
@ -1640,7 +1640,7 @@ protected:
|
||||
void MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message = true);
|
||||
bool client_data_loaded;
|
||||
|
||||
int32 GetFocusEffect(focusType type, uint16 spell_id);
|
||||
int32 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr);
|
||||
uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
||||
|
||||
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost);
|
||||
|
||||
@ -496,7 +496,7 @@ struct StatBonuses {
|
||||
int32 CharmBreakChance; // chance to break charm
|
||||
int32 SongRange; // increases range of beneficial bard songs
|
||||
uint32 HPToManaConvert; // Uses HP to cast spells at specific conversion
|
||||
uint8 FocusEffects[HIGHEST_FOCUS+1]; // Stores the focus effectid for each focustype you have.
|
||||
int32 FocusEffects[HIGHEST_FOCUS+1]; // Stores the focus effectid for each focustype you have.
|
||||
int16 FocusEffectsWorn[HIGHEST_FOCUS+1]; // Optional to allow focus effects to be applied additively from worn slot
|
||||
bool NegateEffects; // Check if you contain a buff with negate effect. (only spellbonuses)
|
||||
int32 SkillDamageAmount2[EQ::skills::HIGHEST_SKILL + 2]; // Adds skill specific damage
|
||||
|
||||
@ -356,8 +356,8 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
if (spells[spell_id].buff_duration < 1) {
|
||||
|
||||
if (target) {
|
||||
value += int(base_value * target->GetFocusEffect(focusFcHealPctIncoming, spell_id)/100); //SPA 393 Add before critical
|
||||
value += int(base_value * target->GetFocusEffect(focusFcHealPctCritIncoming, spell_id)/100); //SPA 395 Add before critical (?)
|
||||
value += int(base_value * target->GetFocusEffect(focusFcHealPctIncoming, spell_id, this)/100); //SPA 393 Add before critical
|
||||
value += int(base_value * target->GetFocusEffect(focusFcHealPctCritIncoming, spell_id, this)/100); //SPA 395 Add before critical (?)
|
||||
}
|
||||
|
||||
value += GetFocusEffect(focusFcHealAmtCrit, spell_id); //SPA 396 Add before critical
|
||||
@ -379,7 +379,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
value += GetFocusEffect(focusFcAmplifyAmt, spell_id); //SPA 508 ? Add after critical
|
||||
|
||||
if (target) {
|
||||
value += target->GetFocusEffect(focusFcHealAmtIncoming, spell_id); //SPA 394 Add after critical
|
||||
value += target->GetFocusEffect(focusFcHealAmtIncoming, spell_id, this); //SPA 394 Add after critical
|
||||
}
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetHealScale()) {
|
||||
|
||||
24
zone/mob.cpp
24
zone/mob.cpp
@ -4477,7 +4477,7 @@ void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
|
||||
}
|
||||
}
|
||||
|
||||
int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||
int32 Mob::GetVulnerability(Mob *caster, uint32 spell_id, uint32 ticsremaining)
|
||||
{
|
||||
/*
|
||||
Modifies incoming spell damage by percent, to increase or decrease damage, can be limited to specific resists.
|
||||
@ -4503,8 +4503,8 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||
innate_mod = Vulnerability_Mod[HIGHEST_RESIST + 1];
|
||||
}
|
||||
|
||||
fc_spell_vulnerability_mod = GetFocusEffect(focusSpellVulnerability, spell_id);
|
||||
fc_spell_damage_pct_incomingPC_mod = GetFocusEffect(focusFcSpellDamagePctIncomingPC, spell_id);
|
||||
fc_spell_vulnerability_mod = GetFocusEffect(focusSpellVulnerability, spell_id, caster);
|
||||
fc_spell_damage_pct_incomingPC_mod = GetFocusEffect(focusFcSpellDamagePctIncomingPC, spell_id, caster);
|
||||
|
||||
total_mod = fc_spell_vulnerability_mod + fc_spell_damage_pct_incomingPC_mod;
|
||||
|
||||
@ -4517,6 +4517,24 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||
return total_mod;
|
||||
}
|
||||
|
||||
bool Mob::IsTargetedFocusEffect(int focus_type) {
|
||||
|
||||
switch (focus_type) {
|
||||
case focusSpellVulnerability:
|
||||
case focusFcSpellDamagePctIncomingPC:
|
||||
case focusFcDamageAmtIncoming:
|
||||
case focusFcSpellDamageAmtIncomingPC:
|
||||
case focusFcCastSpellOnLand:
|
||||
case focusFcHealAmtIncoming:
|
||||
case focusFcHealPctCritIncoming:
|
||||
case focusFcHealPctIncoming:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int32 Mob::GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts)
|
||||
{
|
||||
int skilldmg_mod = 0;
|
||||
|
||||
@ -786,7 +786,7 @@ public:
|
||||
void QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::Options &opts);
|
||||
int32 GetItemStat(uint32 itemid, const char *identifier);
|
||||
|
||||
int32 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false, uint16 casterid=0);
|
||||
int32 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false, uint16 casterid = 0, Mob *caster = nullptr);
|
||||
uint8 IsFocusEffect(uint16 spellid, int effect_index, bool AA=false,uint32 aa_effect=0);
|
||||
void SendIllusionPacket(uint16 in_race, uint8 in_gender = 0xFF, uint8 in_texture = 0xFF, uint8 in_helmtexture = 0xFF,
|
||||
uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF,
|
||||
@ -815,7 +815,7 @@ public:
|
||||
void TrySympatheticProc(Mob *target, uint32 spell_id);
|
||||
bool TryFadeEffect(int slot);
|
||||
uint16 GetSpellEffectResistChance(uint16 spell_id);
|
||||
int32 GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining);
|
||||
int32 GetVulnerability(Mob *caster, uint32 spell_id, uint32 ticsremaining);
|
||||
int32 GetFcDamageAmtIncoming(Mob *caster, int32 spell_id);
|
||||
int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id); //**** This can be removed when bot healing focus code is updated ****
|
||||
int32 GetSkillDmgTaken(const EQ::skills::SkillType skill_used, ExtraAttackOptions *opts = nullptr);
|
||||
@ -861,6 +861,7 @@ public:
|
||||
inline bool HasBaseEffectFocus() const { return (spellbonuses.FocusEffects[focusFcBaseEffects] || aabonuses.FocusEffects[focusFcBaseEffects] || itembonuses.FocusEffects[focusFcBaseEffects]); }
|
||||
int32 GetDualWieldingSameDelayWeapons() const { return dw_same_delay; }
|
||||
inline void SetDualWieldingSameDelayWeapons(int32 val) { dw_same_delay = val; }
|
||||
bool IsTargetedFocusEffect(int focus_type);
|
||||
bool HasPersistDeathIllusion(int32 spell_id);
|
||||
|
||||
bool TryDoubleMeleeRoundEffect();
|
||||
@ -1461,7 +1462,7 @@ protected:
|
||||
virtual
|
||||
#endif
|
||||
int GetBaseSkillDamage(EQ::skills::SkillType skill, Mob *target = nullptr);
|
||||
virtual int32 GetFocusEffect(focusType type, uint16 spell_id) { return 0; }
|
||||
virtual int32 GetFocusEffect(focusType type, uint16 spell_id, Mob *caster = nullptr) { return 0; }
|
||||
void CalculateNewFearpoint();
|
||||
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
|
||||
float FindDestGroundZ(glm::vec3 dest, float z_offset=0.0);
|
||||
|
||||
@ -282,6 +282,8 @@ public:
|
||||
content_db.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction);
|
||||
}
|
||||
|
||||
int32 GetFocusEffect(focusType type, uint16 spell_id, Mob* caster = nullptr);
|
||||
|
||||
glm::vec4 m_SpawnPoint;
|
||||
|
||||
uint32 GetMaxDMG() const {return max_dmg;}
|
||||
|
||||
@ -5218,13 +5218,12 @@ int32 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
|
||||
|
||||
//given an item/spell's focus ID and the spell being cast, determine the focus ammount, if any
|
||||
//assumes that spell_id is not a bard spell and that both ids are valid spell ids
|
||||
int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus, uint16 casterid)
|
||||
int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus, uint16 casterid, Mob *caster)
|
||||
{
|
||||
/*
|
||||
'this' is always the caster of the spell_id, most foci check for effects on the caster, however some check for effects on the target.
|
||||
'casterid' is the casterid of the caster of spell_id, used when spell_id is cast on a target with a focus effect that is checked by incoming spell.
|
||||
*/
|
||||
|
||||
if (!IsValidSpell(focus_id) || !IsValidSpell(spell_id)) {
|
||||
return 0;
|
||||
}
|
||||
@ -5253,6 +5252,7 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
is_from_item_click = true;
|
||||
}
|
||||
|
||||
|
||||
bool LimitInclude[MaxLimitInclude] = {false};
|
||||
/* Certain limits require only one of several Include conditions to be true. Determined by limits being negative or positive
|
||||
Ie. Add damage to fire OR ice spells. If positive we 'Include', by checking each limit of same type to look for match until found. Opposed to
|
||||
@ -5523,23 +5523,25 @@ int32 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
|
||||
case SE_Ff_Same_Caster://hmm do i need to pass casterid from buff slot here
|
||||
if (focus_spell.base_value[i] == 0) {
|
||||
if (casterid == GetID()) {
|
||||
if (caster && casterid == caster->GetID()) {
|
||||
return 0;
|
||||
}//Mob casting is same as target, fail if you are casting on yourself.
|
||||
}
|
||||
else if (focus_spell.base_value[i] == 1) {
|
||||
if (casterid != GetID()) {
|
||||
if (caster && casterid != caster->GetID()) {
|
||||
return 0;
|
||||
}//Mob casting is not same as target, fail if you are not casting on yourself.
|
||||
}
|
||||
break;
|
||||
|
||||
case SE_Ff_CasterClass:
|
||||
case SE_Ff_CasterClass: {
|
||||
|
||||
// Do not use this limit more then once per spell. If multiple class, treat value like items would.
|
||||
if (!PassLimitClass(focus_spell.base_value[i], GetClass())) {
|
||||
if (caster && !PassLimitClass(focus_spell.base_value[i], caster->GetClass())) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Ff_DurationMax:
|
||||
if (focus_spell.base_value[i] > spell.buff_duration) {
|
||||
@ -6247,10 +6249,11 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
int32 Client::GetFocusEffect(focusType type, uint16 spell_id, Mob *caster)
|
||||
{
|
||||
if (IsBardSong(spell_id) && type != focusFcBaseEffects && type != focusSpellDuration && type != focusReduceRecastTime)
|
||||
if (IsBardSong(spell_id) && type != focusFcBaseEffects && type != focusSpellDuration && type != focusReduceRecastTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 realTotal = 0;
|
||||
int32 realTotal2 = 0;
|
||||
@ -6448,7 +6451,7 @@ int32 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
continue;
|
||||
|
||||
if(rand_effectiveness) {
|
||||
focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true);
|
||||
focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true, buffs[buff_slot].casterid, caster);
|
||||
if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) {
|
||||
focus_max_real2 = focus_max2;
|
||||
buff_tracker = buff_slot;
|
||||
@ -6460,7 +6463,7 @@ int32 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
}
|
||||
}
|
||||
else {
|
||||
Total2 = CalcFocusEffect(type, focusspellid, spell_id);
|
||||
Total2 = CalcFocusEffect(type, focusspellid, spell_id, false, buffs[buff_slot].casterid, caster);
|
||||
if (Total2 > 0 && realTotal2 >= 0 && Total2 > realTotal2) {
|
||||
realTotal2 = Total2;
|
||||
buff_tracker = buff_slot;
|
||||
@ -6473,8 +6476,13 @@ int32 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
}
|
||||
}
|
||||
|
||||
uint16 original_caster_id = 0;
|
||||
if (buff_tracker >= 0 && buffs[buff_tracker].casterid > 0) {
|
||||
original_caster_id = buffs[buff_tracker].casterid;
|
||||
}
|
||||
|
||||
if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0)
|
||||
realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id);
|
||||
realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id, false, original_caster_id, caster);
|
||||
|
||||
// For effects like gift of mana that only fire once, save the spellid into an array that consists of all available buff slots.
|
||||
if(buff_tracker >= 0 && buffs[buff_tracker].hit_number > 0) {
|
||||
@ -6523,7 +6531,7 @@ int32 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
return realTotal + realTotal2 + realTotal3 + worneffect_bonus;
|
||||
}
|
||||
|
||||
int32 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
int32 NPC::GetFocusEffect(focusType type, uint16 spell_id, Mob* caster) {
|
||||
|
||||
int32 realTotal = 0;
|
||||
int32 realTotal2 = 0;
|
||||
@ -6586,7 +6594,7 @@ int32 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
|
||||
}
|
||||
|
||||
if (RuleB(Spells, NPC_UseFocusFromSpells) && spellbonuses.FocusEffects[type]){
|
||||
if ((RuleB(Spells, NPC_UseFocusFromSpells) || IsTargetedFocusEffect(type)) && spellbonuses.FocusEffects[type]){
|
||||
|
||||
//Spell Focus
|
||||
int32 Total2 = 0;
|
||||
@ -6604,7 +6612,7 @@ int32 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
continue;
|
||||
|
||||
if(rand_effectiveness) {
|
||||
focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true);
|
||||
focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true, buffs[buff_slot].casterid, caster);
|
||||
if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) {
|
||||
focus_max_real2 = focus_max2;
|
||||
buff_tracker = buff_slot;
|
||||
@ -6616,7 +6624,7 @@ int32 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Total2 = CalcFocusEffect(type, focusspellid, spell_id);
|
||||
Total2 = CalcFocusEffect(type, focusspellid, spell_id, false, buffs[buff_slot].casterid, caster);
|
||||
if (Total2 > 0 && realTotal2 >= 0 && Total2 > realTotal2) {
|
||||
realTotal2 = Total2;
|
||||
buff_tracker = buff_slot;
|
||||
@ -6629,8 +6637,14 @@ int32 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
}
|
||||
}
|
||||
|
||||
if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0)
|
||||
realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id);
|
||||
uint16 original_caster_id = 0;
|
||||
if (buff_tracker >= 0 && buffs[buff_tracker].casterid > 0) {
|
||||
original_caster_id = buffs[buff_tracker].casterid;
|
||||
}
|
||||
|
||||
if (focusspell_tracker && rand_effectiveness && focus_max_real2 != 0) {
|
||||
realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id, false, original_caster_id, caster);
|
||||
}
|
||||
|
||||
// For effects like gift of mana that only fire once, save the spellid into an array that consists of all available buff slots.
|
||||
if(buff_tracker >= 0 && buffs[buff_tracker].hit_number > 0) {
|
||||
@ -7027,8 +7041,8 @@ int32 Mob::GetFcDamageAmtIncoming(Mob *caster, int32 spell_id)
|
||||
{
|
||||
//THIS is target of spell cast
|
||||
int32 dmg = 0;
|
||||
dmg += GetFocusEffect(focusFcDamageAmtIncoming, spell_id); //SPA 297 SE_FcDamageAmtIncoming
|
||||
dmg += GetFocusEffect(focusFcSpellDamageAmtIncomingPC, spell_id); //SPA 484 SE_Fc_Spell_Damage_Amt_IncomingPC
|
||||
dmg += GetFocusEffect(focusFcDamageAmtIncoming, spell_id, caster); //SPA 297 SE_FcDamageAmtIncoming
|
||||
dmg += GetFocusEffect(focusFcSpellDamageAmtIncomingPC, spell_id, caster); //SPA 484 SE_Fc_Spell_Damage_Amt_IncomingPC
|
||||
return dmg;
|
||||
}
|
||||
|
||||
@ -7094,7 +7108,6 @@ bool Mob::PassLimitClass(uint32 Classes_, uint16 Class_)
|
||||
return false;
|
||||
|
||||
Class_ += 1;
|
||||
|
||||
for (int CurrentClass = 1; CurrentClass <= PLAYER_CLASS_COUNT; ++CurrentClass){
|
||||
if (Classes_ % 2 == 1){
|
||||
if (CurrentClass == Class_)
|
||||
@ -8351,7 +8364,7 @@ void Mob::CastSpellOnLand(Mob* caster, int32 spell_id)
|
||||
if ((IsValidSpell(buffs[i].spellid) && (buffs[i].spellid != spell_id) && IsEffectInSpell(buffs[i].spellid, SE_Fc_Cast_Spell_On_Land))) {
|
||||
|
||||
//Step 2: Check if we pass all focus limiters and focus chance roll
|
||||
trigger_spell_id = caster->CalcFocusEffect(focusFcCastSpellOnLand, buffs[i].spellid, spell_id, false, buffs[i].casterid);
|
||||
trigger_spell_id = CalcFocusEffect(focusFcCastSpellOnLand, buffs[i].spellid, spell_id, false, buffs[i].casterid, caster);
|
||||
|
||||
if (IsValidSpell(trigger_spell_id) && (trigger_spell_id != spell_id)) {
|
||||
|
||||
|
||||
@ -4820,7 +4820,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
|
||||
|
||||
resist_modifier -= 2 * focus_resist;
|
||||
|
||||
int focus_incoming_resist = GetFocusEffect(focusFcResistIncoming, spell_id);
|
||||
int focus_incoming_resist = GetFocusEffect(focusFcResistIncoming, spell_id, caster);
|
||||
|
||||
resist_modifier -= focus_incoming_resist;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user