This is not meant for submission (yet) just some code I wrote that I wanted feedback on.
The objective is to improve the way we do focus checks.
Currently the way focus effects work is every time you cast a spell that can be effected by a particular foci the source checks all items/spells/aa for it, common spells like damage will do this about 8-10 times for every cast/proc. Overtime as more spell foci from live are added the amount of these checks will increase.
I thought it might streamline the process if we had a way to check if the focus effect existed at all on the client before iterating through all items/spells/aa to Get and Calculate the values every time a spell is cast/proc.
Below is written as such.
Added an array FocusEffects[HIGHEST_FOCUS] to bonuses struct
:: HIGHEST_FOCUS is the highest value from enum focusType
::Thus creating an array to hold each possible focus.
Added uint8 IsFocusEffect(int16 spellid, int effect_index);
::This returns focusType value that correlates to its Spell Effect
::This is placed in Mob::ApplySpellBonuses to be checked when its
iterating through all the effects in each spell to calculate other bonuses.
If the effect is a focus effect the value returned in IsFocusEffect will determine the position in the array FocusEffects with the value being the spell effect id.
Therefore we can now when running GetFocusEffect do a check
if (spellbonuses.FocusEffect[focusType]) exists before running the entire loop for the focus every time you cast a spell ect.
Bottom line
- Store a list of each focusType the client has when checking bonuses
so you can avoid unnecessarily checking every cast for effects that don't exist.
My question is if this is really any more efficient then how we are doing it?
Kayen
GM Storm Haven
Code:
Index: bonuses.cpp
===================================================================
--- bonuses.cpp (revision 2156)
+++ bonuses.cpp (working copy)
@@ -406,6 +406,11 @@
if (item->Worn.Effect>0 && (item->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, true);
}
+
+ if (item->Focus.Effect>0 && (item->Focus.Type == ET_Focus)) { // focus effects - Kayen
+ ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0, true);
+ }
+
switch(item->BardType)
{
case 51: /* All (e.g. Singing Short Sword) */
@@ -917,6 +922,14 @@
if(IsBlankSpellEffect(spell_id, i))
continue;
+ uint8 focus = IsFocusEffect(spell_id, i);
+ if (focus)
+ {
+ newbon->FocusEffects[focus] = spells[spell_id].effectid[i];
+ Shout("Focus Test %i [Spell %i] [Item %i]", focus, spellbonuses.FocusEffects[focus],itembonuses.FocusEffects[focus]);
+ continue;
+ }
+
effect_value = CalcSpellEffectValue(spell_id, i, casterlevel, caster, ticsremaining);
switch (spells[spell_id].effectid[i])
@@ -1853,3 +1866,53 @@
}
return changed;
}
+
+uint8 Mob::IsFocusEffect(int16 spell_id,int effect_index)
+{
+ switch (spells[spell_id].effectid[effect_index])
+ {
+ case SE_ImprovedDamage:
+ return focusImprovedDamage;
+ case SE_ImprovedHeal:
+ return focusImprovedHeal;
+ case SE_ReduceManaCost:
+ return focusManaCost;
+ case SE_IncreaseSpellHaste:
+ return focusSpellHaste;
+ case SE_IncreaseSpellDuration:
+ return focusSpellDuration;
+ case SE_SpellDurationIncByTic:
+ return focusSpellDurByTic;
+ case SE_SwarmPetDuration:
+ return focusSwarmPetDuration;
+ case SE_IncreaseRange:
+ return focusRange;
+ case SE_ReduceReagentCost:
+ return focusReagentCost;
+ case SE_PetPowerIncrease:
+ return focusPetPower;
+ case SE_SpellResistReduction:
+ return focusResistRate;
+ case SE_SpellHateMod:
+ return focusSpellHateMod;
+ case SE_ReduceReuseTimer:
+ return focusReduceRecastTime;
+ case SE_TriggerOnCast:
+ return focusTriggerOnCast;
+ case SE_SpellVulnerability:
+ return focusSpellVulnerability;
+ case SE_BlockNextSpellFocus:
+ return focusBlockNextSpell;
+ case SE_Twincast:
+ return focusTwincast;
+ case SE_SympatheticProc:
+ return focusSympatheticProc;
+ case SE_SpellDamage:
+ return focusSpellDamage;
+ case SE_FF_Damage_Amount:
+ return focusFF_Damage_Amount;
+ case SE_AdditionalHeal:
+ return focusAdditionalHeal;
+ }
+ return 0;
+}
\ No newline at end of file
Index: mob.h
===================================================================
--- mob.h (revision 2156)
+++ mob.h (working copy)
@@ -105,6 +105,7 @@
focusBlockNextSpell,
focusAdditionalHeal,
} focusType;
+#define HIGHEST_FOCUS focusAdditionalHeal
/*
Used:
@@ -328,7 +329,8 @@
int16 BlockSpellEffect[EFFECT_COUNT]; // Prevents spells with certain effects from landing on you
bool ImmuneToFlee; // Bypass the fleeing flag
int16 VoiceGraft; // Stores the ID of the mob with which to talk through
-
+ sint16 FocusEffects[HIGHEST_FOCUS+1]; // Stores value related to your focus effects - Kayen
+
// AAs
sint8 Packrat; //weight reduction for items, 1 point = 10%
int8 BuffSlotIncrease; // Increases number of available buff slots
@@ -854,6 +856,7 @@
//effect related
sint16 CalcFocusEffect(focusType type, int16 focus_id, int16 spell_id, bool best_focus=false);
+ uint8 IsFocusEffect(int16 spellid, int effect_index); //Kayen
void SendIllusionPacket(int16 in_race, int8 in_gender = 0xFF, int8 in_texture = 0xFF, int8 in_helmtexture = 0xFF, int8 in_haircolor = 0xFF, int8 in_beardcolor = 0xFF, int8 in_eyecolor1 = 0xFF, int8 in_eyecolor2 = 0xFF, int8 in_hairstyle = 0xFF, int8 in_luclinface = 0xFF, int8 in_beard = 0xFF, int8 in_aa_title = 0xFF, int32 in_drakkin_heritage = 0xFFFFFFFF, int32 in_drakkin_tattoo = 0xFFFFFFFF, int32 in_drakkin_details = 0xFFFFFFFF, float in_size = 0xFFFFFFFF);
virtual void Stun(int duration);
virtual void UnStun();
Index: spell_effects.cpp
===================================================================
--- spell_effects.cpp (revision 2156)
+++ spell_effects.cpp (working copy)
@@ -4194,189 +4194,198 @@
sint16 Client::GetFocusEffect(focusType type, int16 spell_id) {
if (IsBardSong(spell_id))
return 0;
-
- const Item_Struct* TempItem = 0;
- const Item_Struct* UsedItem = 0;
- int16 UsedFocusID = 0;
- sint16 Total = 0;
- sint16 realTotal = 0;
- sint16 focus_max = 0;
- sint16 focus_max_real = 0;
+
+ sint16 realTotal = 0; //Item total
+ sint16 realTotal2 = 0;//Spell total
bool rand_effectiveness = false;
//Improved Healing, Damage & Mana Reduction are handled differently in that some are random percentages
//In these cases we need to find the most powerful effect, so that each piece of gear wont get its own chance
if((type == focusManaCost || type == focusImprovedHeal || type == focusImprovedDamage)
- && RuleB(Spells, LiveLikeFocusEffects))
+ && RuleB(Spells, LiveLikeFocusEffects))
{
rand_effectiveness = true;
}
- //item focus
- for(int x=0; x<=21; x++)
- {
- TempItem = NULL;
- ItemInst* ins = GetInv().GetItem(x);
- if (!ins)
- continue;
- TempItem = ins->GetItem();
- if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
- if(rand_effectiveness) {
- focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true);
- if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
- focus_max_real = focus_max;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
- } else if (focus_max < 0 && focus_max < focus_max_real) {
- focus_max_real = focus_max;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
+ //Check if focus exists on items
+ if (itembonuses.FocusEffects[type]){
+
+ const Item_Struct* TempItem = 0;
+ const Item_Struct* UsedItem = 0;
+ int16 UsedFocusID = 0;
+ sint16 Total = 0;
+ sint16 focus_max = 0;
+ sint16 focus_max_real = 0;
+
+ //item focus
+ for(int x=0; x<=21; x++)
+ {
+ TempItem = NULL;
+ ItemInst* ins = GetInv().GetItem(x);
+ if (!ins)
+ continue;
+ TempItem = ins->GetItem();
+ if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
+ if(rand_effectiveness) {
+ focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true);
+ if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
+ focus_max_real = focus_max;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
+ } else if (focus_max < 0 && focus_max < focus_max_real) {
+ focus_max_real = focus_max;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
+ }
}
+ else {
+ Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id);
+ if (Total > 0 && realTotal >= 0 && Total > realTotal) {
+ realTotal = Total;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
+ } else if (Total < 0 && Total < realTotal) {
+ realTotal = Total;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
+ }
+ }
}
- else {
- Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id);
- if (Total > 0 && realTotal >= 0 && Total > realTotal) {
- realTotal = Total;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
- } else if (Total < 0 && Total < realTotal) {
- realTotal = Total;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
+
+ for(int y = 0; y < MAX_AUGMENT_SLOTS; ++y)
+ {
+ ItemInst *aug = NULL;
+ aug = ins->GetAugment(y);
+ if(aug)
+ {
+ const Item_Struct* TempItemAug = aug->GetItem();
+ if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) {
+ if(rand_effectiveness) {
+ focus_max = CalcFocusEffect(type, TempItemAug->Focus.Effect, spell_id, true);
+ if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
+ focus_max_real = focus_max;
+ UsedItem = TempItem;
+ UsedFocusID = TempItemAug->Focus.Effect;
+ } else if (focus_max < 0 && focus_max < focus_max_real) {
+ focus_max_real = focus_max;
+ UsedItem = TempItem;
+ UsedFocusID = TempItemAug->Focus.Effect;
+ }
+ }
+ else {
+ Total = CalcFocusEffect(type, TempItemAug->Focus.Effect, spell_id);
+ if (Total > 0 && realTotal >= 0 && Total > realTotal) {
+ realTotal = Total;
+ UsedItem = TempItem;
+ UsedFocusID = TempItemAug->Focus.Effect;
+ } else if (Total < 0 && Total < realTotal) {
+ realTotal = Total;
+ UsedItem = TempItem;
+ UsedFocusID = TempItemAug->Focus.Effect;
+ }
+ }
+ }
}
}
}
-
- for(int y = 0; y < MAX_AUGMENT_SLOTS; ++y)
+
+
+ //Tribute Focus
+ for(int x = TRIBUTE_SLOT_START; x < (TRIBUTE_SLOT_START + MAX_PLAYER_TRIBUTES); ++x)
{
- ItemInst *aug = NULL;
- aug = ins->GetAugment(y);
- if(aug)
- {
- const Item_Struct* TempItemAug = aug->GetItem();
- if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) {
- if(rand_effectiveness) {
- focus_max = CalcFocusEffect(type, TempItemAug->Focus.Effect, spell_id, true);
- if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
- focus_max_real = focus_max;
- UsedItem = TempItem;
- UsedFocusID = TempItemAug->Focus.Effect;
- } else if (focus_max < 0 && focus_max < focus_max_real) {
- focus_max_real = focus_max;
- UsedItem = TempItem;
- UsedFocusID = TempItemAug->Focus.Effect;
- }
+ TempItem = NULL;
+ ItemInst* ins = GetInv().GetItem(x);
+ if (!ins)
+ continue;
+ TempItem = ins->GetItem();
+ if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
+ if(rand_effectiveness) {
+ focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true);
+ if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
+ focus_max_real = focus_max;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
+ } else if (focus_max < 0 && focus_max < focus_max_real) {
+ focus_max_real = focus_max;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
}
- else {
- Total = CalcFocusEffect(type, TempItemAug->Focus.Effect, spell_id);
- if (Total > 0 && realTotal >= 0 && Total > realTotal) {
- realTotal = Total;
- UsedItem = TempItem;
- UsedFocusID = TempItemAug->Focus.Effect;
- } else if (Total < 0 && Total < realTotal) {
- realTotal = Total;
- UsedItem = TempItem;
- UsedFocusID = TempItemAug->Focus.Effect;
- }
+ }
+ else {
+ Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id);
+ if (Total > 0 && realTotal >= 0 && Total > realTotal) {
+ realTotal = Total;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
}
+ else if (Total < 0 && Total < realTotal) {
+ realTotal = Total;
+ UsedItem = TempItem;
+ UsedFocusID = TempItem->Focus.Effect;
+ }
}
}
}
+
+ if(UsedItem && rand_effectiveness && focus_max_real != 0)
+ realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
+
+ if (realTotal != 0 && UsedItem)
+ Message_StringID(MT_Spells, BEGINS_TO_GLOW, UsedItem->Name);
}
- //Tribute Focus
- for(int x = TRIBUTE_SLOT_START; x < (TRIBUTE_SLOT_START + MAX_PLAYER_TRIBUTES); ++x)
- {
- TempItem = NULL;
- ItemInst* ins = GetInv().GetItem(x);
- if (!ins)
- continue;
- TempItem = ins->GetItem();
- if (TempItem && TempItem->Focus.Effect > 0 && TempItem->Focus.Effect != SPELL_UNKNOWN) {
+ //Spell Focus
+ if (spellbonuses.FocusEffects[type]){
+
+ sint16 Total2 = 0;
+ sint16 focus_max2 = 0;
+ sint16 focus_max_real2 = 0;
+
+ int buff_tracker = -1;
+ int buff_slot = 0;
+ int16 focusspellid = 0;
+ int16 focusspell_tracker = 0;
+ uint32 buff_max = GetMaxTotalSlots();
+ for (buff_slot = 0; buff_slot < buff_max; buff_slot++) {
+ focusspellid = buffs[buff_slot].spellid;
+ if (focusspellid == 0 || focusspellid >= SPDAT_RECORDS)
+ continue;
+
if(rand_effectiveness) {
- focus_max = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id, true);
- if (focus_max > 0 && focus_max_real >= 0 && focus_max > focus_max_real) {
- focus_max_real = focus_max;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
- } else if (focus_max < 0 && focus_max < focus_max_real) {
- focus_max_real = focus_max;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
+ focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true);
+ if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) {
+ focus_max_real2 = focus_max2;
+ buff_tracker = buff_slot;
+ focusspell_tracker = focusspellid;
+ } else if (focus_max2 < 0 && focus_max2 < focus_max_real2) {
+ focus_max_real2 = focus_max2;
+ buff_tracker = buff_slot;
+ focusspell_tracker = focusspellid;
}
}
else {
- Total = CalcFocusEffect(type, TempItem->Focus.Effect, spell_id);
- if (Total > 0 && realTotal >= 0 && Total > realTotal) {
- realTotal = Total;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
+ Total2 = CalcFocusEffect(type, focusspellid, spell_id);
+ if (Total2 > 0 && realTotal2 >= 0 && Total2 > realTotal2) {
+ realTotal2 = Total2;
+ buff_tracker = buff_slot;
+ focusspell_tracker = focusspellid;
+ } else if (Total2 < 0 && Total2 < realTotal2) {
+ realTotal2 = Total2;
+ buff_tracker = buff_slot;
+ focusspell_tracker = focusspellid;
}
- else if (Total < 0 && Total < realTotal) {
- realTotal = Total;
- UsedItem = TempItem;
- UsedFocusID = TempItem->Focus.Effect;
- }
}
}
- }
-
- if(UsedItem && rand_effectiveness && focus_max_real != 0)
- realTotal = CalcFocusEffect(type, UsedFocusID, spell_id);
-
- if (realTotal != 0 && UsedItem)
- Message_StringID(MT_Spells, BEGINS_TO_GLOW, UsedItem->Name);
-
- //Spell Focus
- sint16 Total2 = 0;
- sint16 realTotal2 = 0;
- sint16 focus_max2 = 0;
- sint16 focus_max_real2 = 0;
-
- int buff_tracker = -1;
- int buff_slot = 0;
- int16 focusspellid = 0;
- int16 focusspell_tracker = 0;
- uint32 buff_max = GetMaxTotalSlots();
- for (buff_slot = 0; buff_slot < buff_max; buff_slot++) {
- focusspellid = buffs[buff_slot].spellid;
- if (focusspellid == 0 || focusspellid >= SPDAT_RECORDS)
- continue;
- if(rand_effectiveness) {
- focus_max2 = CalcFocusEffect(type, focusspellid, spell_id, true);
- if (focus_max2 > 0 && focus_max_real2 >= 0 && focus_max2 > focus_max_real2) {
- focus_max_real2 = focus_max2;
- buff_tracker = buff_slot;
- focusspell_tracker = focusspellid;
- } else if (focus_max2 < 0 && focus_max2 < focus_max_real2) {
- focus_max_real2 = focus_max2;
- buff_tracker = buff_slot;
- focusspell_tracker = focusspellid;
- }
+ if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0)
+ realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id);
+
+ // 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].numhits > 0) {
+ m_spellHitsLeft[buff_tracker] = focusspell_tracker;
}
- else {
- Total2 = CalcFocusEffect(type, focusspellid, spell_id);
- if (Total2 > 0 && realTotal2 >= 0 && Total2 > realTotal2) {
- realTotal2 = Total2;
- buff_tracker = buff_slot;
- focusspell_tracker = focusspellid;
- } else if (Total2 < 0 && Total2 < realTotal2) {
- realTotal2 = Total2;
- buff_tracker = buff_slot;
- focusspell_tracker = focusspellid;
- }
- }
}
- if(focusspell_tracker && rand_effectiveness && focus_max_real2 != 0)
- realTotal2 = CalcFocusEffect(type, focusspell_tracker, spell_id);
-
- // 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].numhits > 0) {
- m_spellHitsLeft[buff_tracker] = focusspell_tracker;
- }
-
// AA Focus
sint16 Total3 = 0;
sint16 realTotal3 = 0;