PDA

View Full Version : COMMITTED: SE_SpellTrigger(formerly SE_LifeshardChance)


Caryatis
07-06-2010, 08:58 PM
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 (http://lucy.allakhazam.com/spellraw.html?id=8406&source=Live) vs Mana Flare (http://lucy.allakhazam.com/spellraw.html?id=8032&source=Live) ... 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 (http://lucy.allakhazam.com/spell.html?id=11869&source=Test) 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 (http://lucy.allakhazam.com/spell.html?id=10735&source=Live) 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

#define SE_LifeshardChance 340 //chance to create lifeshard

to

#define SE_SpellTrigger 340 //chance to trigger spell

spell_effects.cpp - Line 2814 - add this
case SE_SpellTrigger:

spells.cpp - line 3048 - add this
TrySpellTrigger(spelltar, spell_id);

mob.h - line 781 - add this
void TrySpellTrigger(Mob *target, uint32 spell_id);

mob.cpp - line 3041 - add this
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.

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 (http://lucy.allakhazam.com/spell.html?id=14754&source=Live), Wildmagic Blast (http://lucy.allakhazam.com/spell.html?id=19679&source=Live) & 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
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
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
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
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
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);
+ }
+ }
+ }
+ }
+}
+
+