//::///////////////////////////////////////////////
//:: Wild Mage Spell - Wild Storm Heart Script
//::///////////////////////////////////////////////
/*
Wild Storm

2d2f_sp_wild_storm_heart.nss
*/
//::///////////////////////////////////////////////
//:: Created By: 2DruNk2Frag
//:: Created On: 04-25-2008
//:: Last Update: 04-26-2008
//::///////////////////////////////////////////////

#include "2d2f_includes"
#include "jx_inc_magic"
#include "x2_inc_spellhook" 
#include "jx_inc_magic_info"
#include "nwn2_inc_spells"
#include "nw_i0_spells"
#include "X0_I0_SPELLS"
#include "x0_i0_spells"

void main()
{
		object oPC = GetFirstPC();
		object oCaster = JXGetAOERealCreator();
		object oFakeCaster = GetLocalObject(oPC, "oFakeCasterStorm");
		object oVisPlace = GetLocalObject(oPC, "oVisPlaceStorm");
		float nRadius = RADIUS_SIZE_VAST;//60 ft
		int nDur = d4(1) + 2;
		float fDur = RoundsToSeconds(nDur);
		int nLvl = JXGetCasterLevel(oPC);
				
		if(GetIsDead(oPC) || 
		!GetIsObjectValid(oCaster) 
		|| !GetIsObjectValid(oVisPlace) ||
		GetIsResting(oPC) == TRUE)
    	{
			DestroyObject(oFakeCaster, 0.0);
			DestroyObject(oVisPlace, 0.0);
			DeleteLocalObject(oCaster, "oFakeCaster");
			DeleteLocalObject(oCaster, "oVisPlace");
    	}
		
		object oTarget = GetFirstInPersistentObject();
		
		if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE && oTarget != oFakeCaster)
		{
			while(GetIsObjectValid(oTarget))
			{
				SignalEvent(oTarget, EventSpellCastAt(oPC, SPELL_WILD_STORM));
				
				int nBuffer = nLvl / 3;
				int nReRoll = nLvl / 10;
					       		
				int nPiathansModifier = GetLocalInt(oTarget,"nPiathansModifier");
				
				int nHostile = spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF);
				int nRoll = Random(21) + 1 + nPiathansModifier;
				int nRollValid = FALSE;
				
			while(nRollValid == FALSE || nReRoll > 0)
			{
				if(nHostile == TRUE)
				{
					if(nRoll > (21 - nBuffer))
					{
						nRoll = Random(21) + 1 + nPiathansModifier;
						
						if(nRoll > 21)
						{
							nRoll = 21;
						}
						else if(nRoll < 1)
						{
							nRoll = 1;
						}
					}
					else
					{
						nRollValid = TRUE;
					}
				}
				else // not hostile
				{
					if(nRoll < nBuffer)
					{
						nRoll = Random(21) + 1 + nPiathansModifier;
						
						if(nRoll > 21)
						{
							nRoll = 21;
						}
						else if(nRoll < 1)
						{
							nRoll = 1;
						}
					}
					else
					{
						nRollValid = TRUE;
					}			
				}
			nReRoll = nReRoll - 1;
			}
				
				if(nRoll < 11) // negative effect
				{	
					//make resistance
					if (MyResistSpell(OBJECT_SELF, oTarget))
					{
						return; // no effect applied
					}
					// or Make save
					if(MySavingThrow(SAVING_THROW_FORT, oTarget, JXGetSpellSaveDC(),SAVING_THROW_TYPE_SPELL))
					{					
						return; // no effect applied	
					}
				}
				
				if(nRoll == 1) { // death
					effect eDeath = EffectDeath(TRUE);
					effect eVis = EffectVisualEffect(VFX_HIT_SPELL_FINGER_OF_DEATH);
					effect eLink = EffectLinkEffects(eDeath,eVis);
					ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
				}	
				else if(nRoll == 2) { // really nasty poison
					effect ePoi = EffectPoison(POISON_BLACK_LOTUS_EXTRACT);
					effect eVis = EffectVisualEffect(VFX_DUR_AURA_POISON);
					effect eLink = EffectLinkEffects(ePoi,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
				} 
				else if(nRoll == 3) { // petrified
					effect ePet = EffectPetrify();
					effect eVis = EffectVisualEffect(VFX_HIT_SPELL_TRANSMUTATION);
					ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
					ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePet, oTarget);
				}
				else if(nRoll == 4) { // level drain
					effect eLevel = EffectNegativeLevel(d4(2));
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_ENERGY_DRAIN);
					effect eLink = EffectLinkEffects(eLevel,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);			
				}
				else if(nRoll == 5) { // magic damage
					effect eDam = EffectDamage(d6(nLvl));
					effect eVis = EffectVisualEffect(VFX_HIT_SPELL_MAGIC);
					effect eLink = EffectLinkEffects(eDam,eVis);
					ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
				}
				else if(nRoll ==  6) { // paralyze
					effect ePara = EffectParalyze(-1,SAVING_THROW_FORT,FALSE);
					effect eVis = EffectVisualEffect(VFX_DUR_PARALYZED);
					effect eLink = EffectLinkEffects(ePara,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
				}
				else if(nRoll == 7) { // nasty curse
					effect eCurse = EffectCurse(d3()+1,
												d3()+1,
												d3()+1,
												d3()+1,
												d3()+1,
												d3()+1);
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_BESTOW_CURSE);
					effect eLink = EffectLinkEffects(eCurse,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 8) { // slow
					effect eSlow = EffectSlow();
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_SLOW);
					effect eLink = EffectLinkEffects(eSlow,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
				}
				else if(nRoll == 9) { // blind, deaf, and silenced
					effect eBlind = EffectBlindness();
					effect eDeaf = EffectDeaf();
					effect eSilence = EffectSilence();
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_BLIND_DEAF);
					effect eLink = EffectLinkEffects(eBlind,eDeaf);
					eLink = EffectLinkEffects(eLink,eSilence);
					eLink = EffectLinkEffects(eLink,eVis);			
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
				
				}
				else if(nRoll == 10) { // magic vulnerability
					effect eVuln = EffectDamageImmunityDecrease(DAMAGE_TYPE_MAGICAL, 50);
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_DOOM);
					effect eLink = EffectLinkEffects(eVuln,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
				}
				else if(nRoll == 11) { // greater dispell
					effect eVis = EffectVisualEffect( VFX_HIT_SPELL_ABJURATION );
					effect eImpact;
					spellsDispelMagic(oTarget, nLvl, eVis, eImpact, TRUE);
				}
				else if(nRoll == 12) { // magic immunity 50%
					effect eVuln = EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, 50);
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_DOOM);
					effect eLink = EffectLinkEffects(eVuln,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 13) { // true seeing
					effect eTrue = EffectTrueSeeing();
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_TRUE_SEEING);
					effect eLink = EffectLinkEffects(eTrue,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 14) { // Haste
					effect eHaste = EffectHaste();
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_HASTE);
					effect eLink = EffectLinkEffects(eHaste,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 15) { // nice Ability increase
					effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH,d3()+1);
					effect eDex = EffectAbilityIncrease(ABILITY_DEXTERITY,d3()+1);
					effect eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION,d3()+1);
					effect eInt = EffectAbilityIncrease(ABILITY_INTELLIGENCE,d3()+1);
					effect eWis = EffectAbilityIncrease(ABILITY_WISDOM,d3()+1);
					effect eChr = EffectAbilityIncrease(ABILITY_CHARISMA,d3()+1);
					effect eLink = EffectLinkEffects(eStr,eDex);
					eLink = EffectLinkEffects(eLink,eCon);
					eLink = EffectLinkEffects(eLink,eInt);
					eLink = EffectLinkEffects(eLink,eWis);
					eLink = EffectLinkEffects(eLink,eChr);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
							
					effect eVis = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE);
					ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
				}
				else if(nRoll == 16) { // freedom
					effect eParal = EffectImmunity(IMMUNITY_TYPE_PARALYSIS);
		    		effect eEntangle = EffectImmunity(IMMUNITY_TYPE_ENTANGLE);
		    		effect eSlow = EffectImmunity(IMMUNITY_TYPE_SLOW);
		    		effect eMove = EffectImmunity(IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE);
					effect eHit = EffectVisualEffect(VFX_DUR_FREEDOM_OF_MOVEMENT);
					effect eLink = EffectLinkEffects(eParal, eEntangle);
		    		eLink = EffectLinkEffects(eLink, eSlow);
		    		eLink = EffectLinkEffects(eLink, eMove);
					eLink = EffectLinkEffects(eLink, eHit);
					
					effect eLook = GetFirstEffect(oTarget);
		    		while(GetIsEffectValid(eLook))
				    {
				        if((GetEffectType(eLook) == EFFECT_TYPE_PARALYZE ||
				            GetEffectType(eLook) == EFFECT_TYPE_ENTANGLE ||
				            GetEffectType(eLook) == EFFECT_TYPE_SLOW ||
				            GetEffectType(eLook) == EFFECT_TYPE_MOVEMENT_SPEED_DECREASE) &&
				            GetEffectSpellId(eLook) != SPELL_FOUNDATION_OF_STONE &&
				            GetEffectSpellId(eLook) != SPELL_TORTOISE_SHELL &&
				            GetEffectSpellId(eLook) != SPELL_STONE_BODY &&
				            GetEffectSpellId(eLook) != SPELL_IRON_BODY)
				        {
				            RemoveEffect(oTarget, eLook);
				        }
				        eLook = GetNextEffect(oTarget);
				    }
					
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);
				}
				else if(nRoll == 17) { // stone to flesh
					effect eLook = GetFirstEffect(oTarget);
			
				    while(GetIsEffectValid(eLook))
					{
				    	if(GetEffectType(eLook) == EFFECT_TYPE_PETRIFY)
				        {
				        	SetCommandable(TRUE, oTarget);
				            RemoveEffect(oTarget, eLook);
				        }
				    eLook = GetNextEffect(oTarget);
				    }
				}
				else if(nRoll == 18) { // massive spell absorbtion
					effect eAbsorb = EffectSpellLevelAbsorption(8,8+d8(2),SPELL_SCHOOL_GENERAL);
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_SPELL_MANTLE);
					effect eLink = EffectLinkEffects(eAbsorb,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 19) { // concealment 50 - 100 %
					int nConc = Random(50) + 51;
					effect eConc = EffectConcealment(nConc);
					effect eVis = EffectVisualEffect(VFX_DUR_INVISIBILITY);
					effect eLink = EffectLinkEffects(eConc,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 20) { // nice damage reduction (premonition)
					int nDamageLimit = nLvl * 10;
					effect eStone = EffectDamageReduction(30, GMATERIAL_METAL_ADAMANTINE, nDamageLimit, DR_TYPE_GMATERIAL);
		    		effect eVis = EffectVisualEffect(VFX_DUR_SPELL_PREMONITION);
					effect eLink = EffectLinkEffects(eStone,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				else if(nRoll == 21) { // death magic immunity and  temp hit points on death
					effect eHP = EffectHealOnZeroHP(oTarget, 10 * nLvl);
					effect eDeath = EffectImmunity(IMMUNITY_TYPE_DEATH);
					effect eVis = EffectVisualEffect(VFX_DUR_SPELL_DEATH_WARD);
					effect eLink = EffectLinkEffects(eHP,eDeath);
					eLink = EffectLinkEffects(eLink,eVis);
					ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eLink,oTarget,fDur);		
				}
				
				effect eBeam = EffectBeam(VFX_BEAM_WILD_STORM, oFakeCaster, BODY_NODE_CHEST);
				ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBeam,oTarget,6.0);
				
			oTarget = GetNextInPersistentObject();	
			}
		}
		
		
	
}		