EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   COMMITTED: SE_SpellTrigger(formerly SE_LifeshardChance) (https://www.eqemulator.org/forums/showthread.php?t=31610)

Caryatis 07-06-2010 08:58 PM

COMMITTED: SE_SpellTrigger(formerly SE_LifeshardChance)
 
Spell Effect 340, incorrectly labeled LifeshardChance from when lucy reported all the effects that way is actually very similiar to TriggerOnCast however they don't rely on a buff.

Mana Reiterate(upgraded flare line) has a 100% chance to proc Mana Reiterate Strike on cast, and then Mana Reiterate Strike has a 10% chance to proc Mana Re-Reiterate strike which in turn has 10% chance to proc Mana Re-Re-Reiterate Strike, etc. (incidently KLS this is why I believe the TriggerOnCast code should be 100, not 1000, as Mana Flares always proc, they have a proc limit but they proc every time... ie Pyromancy vs Mana Flare ... Pyromancy is 5% chance to proc(base1) vs 100 for mana flare.)

Anyway, the code...

edit.. changed the mob.cpp function to align with these 2 spells... Bark at the Moon which has a 95% chance to proc 1 pet however if that fails then you get the 5% proc of 4 pets. Previous code didnt allow that, you could miss both checks. However a spell like Annihilate the Unnatural has 2 chances to proc but you arent guaranteed the second proc if the first fails. New code should address this.

spdat.h - line 478 - alter this

Code:

#define SE_LifeshardChance                    340        //chance to create lifeshard
to

Code:

#define SE_SpellTrigger                    340        //chance to trigger spell
spell_effects.cpp - Line 2814 - add this
Code:

case SE_SpellTrigger:
spells.cpp - line 3048 - add this
Code:

TrySpellTrigger(spelltar, spell_id);
mob.h - line 781 - add this
Code:

void TrySpellTrigger(Mob *target, uint32 spell_id);
mob.cpp - line 3041 - add this
Code:

void Mob::TrySpellTrigger(Mob *target, uint32 spell_id)
{
        if(target == NULL || !IsValidSpell(spell_id))
        {
                return;
        }
        int spell_trig = 100;
        for(int i = 0; i < EFFECT_COUNT; i++)
        {
                if (spells[spell_id].effectid[i] == SE_SpellTrigger)
                {
                        if (spells[spell_id].base[i] + spell_trig == 100)
                        {
                                spell_trig = 1;
                        }
                        else {
                                spell_trig = 100;
                        }
                        if(MakeRandomInt(0, spell_trig) <= spells[spell_id].base[i])
                        {
                                SpellOnTarget(spells[spell_id].base2[i], target);
                        }
                        else {
                                spell_trig = spells[spell_id].base[i];
                        }
                }
        }
}


Caryatis 07-06-2010 10:09 PM

wish we could edit longer... there was a slight error in that you could trigger bark at the moon type spells twice if lucky... this should fix that while allowing spells like annhilate to proc twice.

Code:

void Mob::TrySpellTrigger(Mob *target, uint32 spell_id)
{
        if(target == NULL || !IsValidSpell(spell_id))
        {
                return;
        }
        int spell_trig = 100;
        int triggered = 0;
        for(int i = 0; i < EFFECT_COUNT; i++)
        {
                if (spells[spell_id].effectid[i] == SE_SpellTrigger)
                {
                        // If we have failed a check already, the spell_trig variable will be set lower than 100, so if they add to 100 then the second chance is guaranteed.
                        if (spells[spell_id].base[i] + spell_trig == 100)
                        {
                                SpellOnTarget(spells[spell_id].base2[i], target);
                                break;
                        }
                        // if we have successfully cast a spell that has 2 chances that add to 100% then stop here
                        else if (triggered == 1 && spells[spell_id].base[i] + spell_trig == 100) {
                                break;
                        }
                        if(MakeRandomInt(0, 100) <= spells[spell_id].base[i])
                        {
                                SpellOnTarget(spells[spell_id].base2[i], target);
                                int triggered = 1;
                        }
                        else {
                                spell_trig = spells[spell_id].base[i];
                        }
                }
        }
}


Caryatis 07-14-2010 09:32 PM

OK redid this code as well as a few spells threw a wrench in the previous code, namely Cauldron Summoning, Wildmagic Blast & the annihilate line I linked earlier. In order to get all those working, required new logic so hopefully this is alittle more robust.

spdat.h
Code:

Index: spdat.h
===================================================================
--- spdat.h        (revision 1600)
+++ spdat.h        (working copy)
@@ -475,7 +475,7 @@
 #define SE_PercentXPIncrease                337        //not implemented
 #define SE_SummonAndResAllCorpses        338        //not implemented
 #define SE_TriggerOnCast                        339        //not implemented
-#define SE_LifeshardChance                        340        //chance to create lifeshard
+#define SE_SpellTrigger                    340        //chance to trigger spell
 //#define SE_Unknown341                                341        //not used
 #define SE_ImmuneFleeing                        342        //not implemented
 #define SE_InterruptCasting                        343        //not implemented. % chance to interrupt spells being cast every tic. Cacophony (8272)

spell effects
Code:

Index: spell_effects.cpp
===================================================================
--- spell_effects.cpp        (revision 1600)
+++ spell_effects.cpp        (working copy)
@@ -2812,6 +2812,7 @@
                        case SE_LimitCastTime:
                        case SE_NoCombatSkills:
                        case SE_TriggerOnCast:
+                        case SE_SpellTrigger:
                        {
                                break;
                        }

spells
Code:

Index: spells.cpp
===================================================================
--- spells.cpp        (revision 1600)
+++ spells.cpp        (working copy)
@@ -3045,6 +3045,8 @@
                }
 
        TryTriggerOnCast(spelltar, spell_id);
+       
+        TrySpellTrigger(spelltar, spell_id);
 
        if(spell_id == 982)        // Cazic Touch, hehe =P
        {

mob.h
Code:

Index: mob.h
===================================================================
--- mob.h        (revision 1600)
+++ mob.h        (working copy)
@@ -778,6 +778,7 @@
        bool TryDeathSave();
        void DoBuffWearOffEffect(uint32 index);
        void TryTriggerOnCast(Mob *target, uint32 spell_id);
+        void TrySpellTrigger(Mob *target, uint32 spell_id);
 
        static int32 GetAppearanceValue(EmuAppearance iAppearance);
        void SendAppearancePacket(int32 type, int32 value, bool WholeZone = true, bool iIgnoreSelf = false, Client *specific_target=NULL);

mob.cpp
Code:

Index: mob.cpp
===================================================================
--- mob.cpp        (revision 1600)
+++ mob.cpp        (working copy)
@@ -3036,4 +3036,58 @@
                        }
                }
        }
-}
\ No newline at end of file
+}
+
+void Mob::TrySpellTrigger(Mob *target, uint32 spell_id)
+{
+        if(target == NULL || !IsValidSpell(spell_id))
+        {
+                return;
+        }
+        int spell_trig = 0;
+        // Count all the percentage chances to trigger for all effects
+        for(int i = 0; i < EFFECT_COUNT; i++)
+        {
+                if (spells[spell_id].effectid[i] == SE_SpellTrigger)
+                        spell_trig += spells[spell_id].base[i];
+        }
+        // If all the % add to 100, then only one of the effects can fire but one has to fire.
+        if (spell_trig == 100)
+        {
+                int trig_chance = 100;
+                for(int i = 0; i < EFFECT_COUNT; i++)
+                {
+                        if (spells[spell_id].effectid[i] == SE_SpellTrigger)
+                        {
+                                if(MakeRandomInt(0, trig_chance) <= spells[spell_id].base[i])
+                                {
+                                        // If we trigger an effect then its over.
+                                        SpellOnTarget(spells[spell_id].base2[i], target);
+                                        break;
+                                }
+                                else
+                                {
+                                        // Increase the chance to fire for the next effect, if all effects fail, the final effect will fire.
+                                        trig_chance -= spells[spell_id].base[i];
+                                }
+                        }
+               
+                }
+        }
+        // if the chances don't add to 100, then each effect gets a chance to fire, chance for no trigger as well.
+        else
+        {
+                for(int i = 0; i < EFFECT_COUNT; i++)
+                {
+                        if (spells[spell_id].effectid[i] == SE_SpellTrigger)
+                        {
+                                if(MakeRandomInt(0, 100) <= spells[spell_id].base[i])
+                                {
+                                        SpellOnTarget(spells[spell_id].base2[i], target);
+                                }
+                        }
+                }
+        }
+}
+
+



All times are GMT -4. The time now is 02:57 PM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.