//::///////////////////////////////////////////////
//:: Wild Mage Spell - Discombobulation
//::///////////////////////////////////////////////
/*

Discombobulation

Caster Level(s): Wizard / Sorcerer 5
Innate Level: 5
School: Transmutation
Descriptor(s): Wild Magic
Component(s): Verbal, Somatic
Range: Medium
Area of Effect / Target: One Creature
Duration: 1d10 + 1 round / 2 levels
Save: Will Negates
Spell Resistance: Yes

!!! This is a Wild Magic Spell and can only be cast by a Wild Mage !!!

     At the core of every creature lies certain aspects.  These traits define the creatures 
strength and weaknesses.  The spell Discombobulation causes erratic derangement of these 
capabilities.  A creature that was once exceptionally strong but dismally dim witted once 
discombobulated may find that they have new insight into many things yet can barley stand 
from weakness.
     The target of Discombobulation is allowed a Will save to negates its effects.  If 
failed, all of the creature’s ability scores are randomly shuffled.  For example, a 
human sorcerer with the following ability scores, Str-8, Dex-14, Con-12, Int-10, Wis-10, 
Chr-18 could possibly end up with the following after the discombobulation, Str-12, Dex-10, 
Con- 18, Int- 8, Wis- 14, Chr- 10.  In this particular case the sorcerer’s spellcasting will 
suffer considerably, but it should be noted that it was possible that his charisma score 
could have got his Dex of 14 or even got its own score of 18, but chances (5 in 6) were that 
this particular caster was going to have to make due with one of his lesser attributes.
     Discombobulation is most effective against creatures that rely heavily on only one or 
two attributes such as casters, warriors, and rogues.  Creatures with a balanced set of 
abilities may hardly even notice the effects of Discombobulation.


2d2f_sp_discombobulation.nss
*/
//::///////////////////////////////////////////////
//:: Created By: 2DruNk2Frag
//:: Created On: 02-18-2008
//:: Last Update: 03-24-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"



void mainSpell();
void main()
{
	AssignCommand(JXGetCaster(), mainSpell());
}

void mainSpell()
{
	object oCaster = JXGetCaster();
	int nWMLvl = GetLevelByClass(CLASS_WILDMAGE, oCaster);
	if(nWMLvl >= 9)
	{
/* 
  Spellcast Hook Code 
  Added 2003-06-23 by GeorgZ
  If you want to make changes to all spells,
  check x2_inc_spellhook.nss to find out more
  
*/

    if (!X2PreSpellCastCode())
    {
	// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
        { JXPostSpellCastCode(); return; }
    }
	//:://////////////////////////////////////////
	
	object oTarget = JXGetSpellTargetObject();
	int nLvl = JXGetCasterLevel();
	int nDur = d10(1) + (nLvl / 2);
	float fDuration = RoundsToSeconds(nDur);

	

	//Check for metamagic extend
    fDuration = ApplyMetamagicDurationMods(fDuration);
    int nDurType = ApplyMetamagicDurationTypeMods(DURATION_TYPE_TEMPORARY);
	
	if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))
	{
        //Fire cast spell at event for the specified target
        SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_DISCOMBOBULATION));
       //Make SR check
       if (!MyResistSpell(OBJECT_SELF, oTarget))
	   {
            //Make Will save
            if (!/*Will Save*/ MySavingThrow(SAVING_THROW_WILL, oTarget, JXGetSpellSaveDC(),SAVING_THROW_TYPE_SPELL ))
            {	
				if(GetHasSpellEffect(SPELL_DISCOMBOBULATION, oTarget) == TRUE)
				{
					RemoveSpellEffects(SPELL_DISCOMBOBULATION, oCaster, oTarget);
				}	
			
				int nS = GetAbilityScore(oTarget,ABILITY_STRENGTH,TRUE);
				int nD = GetAbilityScore(oTarget,ABILITY_DEXTERITY,TRUE);
				int nCo = GetAbilityScore(oTarget,ABILITY_CONSTITUTION,TRUE);
				int nI = GetAbilityScore(oTarget,ABILITY_INTELLIGENCE,TRUE);
				int nW = GetAbilityScore(oTarget,ABILITY_WISDOM,TRUE);
				int nCh = GetAbilityScore(oTarget,ABILITY_CHARISMA,TRUE);
				
				int nCheckStr	= 0;
				int nCheckDex	= 0;
				int nCheckCon	= 0;
				int nCheckInt	= 0;
				int nCheckWis	= 0;
				int nCheckChr	= 0;
				
				int nSetStr;
				int nSetDex;
				int nSetCon;
				int nSetInt;
				int nSetWis;
				int nSetChr;
				
				int check1 = 0;
				int check2 = 0;
				int check3 = 0;
				int check4 = 0;
				int check5 = 0;
				int check6 = 0;			
				
				int i = 1;
				int lastI = 1;
				
				while(check1 == 0 ||
				check2 == 0 ||
				check3 == 0 ||
				check4 == 0 ||
				check5 == 0 ||
				check6 == 0)
				{
				//while(i < 7)
				//{
				
					int nRand = d6(1);
					switch(nRand)
					{
						case 1 :
							if(check1 == 0){
								i++;
								check1 = 1;
								break;							
							}
							else{
								break;
							}						
						case 2 :
							if(check2 == 0){
								i++;
								check2 = 1;
								break;							
							}
							else{
								break;
							}
						case 3 :
							if(check3 == 0){
								i++;
								check3 = 1;
								break;							
							}
							else{
								break;
							}
						case 4 :
							if(check4 == 0){
								i++;
								check4 = 1;
								break;							
							}
							else{
								break;
							}
						case 5 :
							if(check5 == 0){
								i++;
								check5 = 1;
								break;							
							}
							else{
								break;
							}
						case 6 :
							if(check6 == 0){
								i++;
								check6 = 1;
								break;							
							}
							else{
								break;
							}
						default : break;	
					
					}
					
					//SendMessageToPC(oCaster, "Loop number" + IntToString(i));
					
					if(i > lastI)
					{
						if(i == 2 && nCheckStr == 0)
						{
							switch(nRand)
							{
								case 1 : nSetStr = nS; break;
								case 2 : nSetStr = nD; break;
								case 3 : nSetStr = nCo; break;
								case 4 : nSetStr = nI; break;
								case 5 : nSetStr = nW; break;
								case 6 : nSetStr = nCh; break;
								default : break;
							}
							nCheckStr = 1;
						}
						if(i == 3 && nCheckDex == 0)
						{
							switch(nRand)
							{
								case 1 : nSetDex = nS; break;
								case 2 : nSetDex = nD; break;
								case 3 : nSetDex = nCo; break;
								case 4 : nSetDex = nI; break;
								case 5 : nSetDex = nW; break;
								case 6 : nSetDex = nCh; break;
								default : break;
							}
							nCheckDex = 1;
						}
						if(i == 4 && nCheckCon == 0)
						{
							switch(nRand)
							{
								case 1 : nSetCon = nS; break;
								case 2 : nSetCon = nD; break;
								case 3 : nSetCon = nCo; break;
								case 4 : nSetCon = nI; break;
								case 5 : nSetCon = nW; break;
								case 6 : nSetCon = nCh; break;
								default : break;
							}
							nCheckCon = 1;
						}
						if(i == 5 && nCheckInt == 0)
						{
							switch(nRand)
							{
								case 1 : nSetInt = nS; break;
								case 2 : nSetInt = nD; break;
								case 3 : nSetInt = nCo; break;
								case 4 : nSetInt = nI; break;
								case 5 : nSetInt = nW; break;
								case 6 : nSetInt = nCh; break;
								default : break;
							}
							nCheckInt = 1;
						}
						if(i == 6 && nCheckWis == 0)
						{
							switch(nRand)
							{
								case 1 : nSetWis = nS; break;
								case 2 : nSetWis = nD; break;
								case 3 : nSetWis = nCo; break;
								case 4 : nSetWis = nI; break;
								case 5 : nSetWis = nW; break;
								case 6 : nSetWis = nCh; break;
								default : break;
							}
							nCheckWis = 1;
						}
						if(i == 7 && nCheckChr == 0)
						{
							switch(nRand)
							{
								case 1 : nSetChr = nS; break;
								case 2 : nSetChr = nD; break;
								case 3 : nSetChr = nCo; break;
								case 4 : nSetChr = nI; break;
								case 5 : nSetChr = nW; break;
								case 6 : nSetChr = nCh; break;
								default : break;
							}
							nCheckChr = 1;
						}
					
					} // end i > lastI
				
				lastI = i;				
				
				} //end while
				
				int nSDiff = nSetStr - nS;
				int nDDiff = nSetDex - nD;
				int nCoDiff = nSetCon - nCo;
				int nIDiff = nSetInt - nI;
				int nWDiff = nSetWis - nW;
				int nChDiff = nSetChr - nCh;
				
				effect eStr;
				effect eDex;
				effect eCon;
				effect eInt;
				effect eWis;
				effect eChr;
				
				//SendMessageToPC(oCaster, "Old STR = " + IntToString(nS));
				//SendMessageToPC(oCaster, "New STR = " + IntToString(nS + nSDiff));
				if(nSDiff >= 0)
				{
					
					eStr = EffectAbilityIncrease(ABILITY_STRENGTH,nSDiff);
				}
				else
				{
					nSDiff = nSDiff * -1;
					eStr = EffectAbilityDecrease(ABILITY_STRENGTH,nSDiff);
				}
							
				//SendMessageToPC(oCaster, "Old Dex = " + IntToString(nD));
				//SendMessageToPC(oCaster, "New Dex = " + IntToString(nD + nDDiff));
				if(nDDiff >= 0)
				{
					eDex = EffectAbilityIncrease(ABILITY_DEXTERITY,nDDiff);
				}
				else
				{
					nDDiff = nDDiff * -1;
					eDex = EffectAbilityDecrease(ABILITY_DEXTERITY,nDDiff);					
				}				
				
				//SendMessageToPC(oCaster, "Old Con = " + IntToString(nCo));
				//SendMessageToPC(oCaster, "New Con = " + IntToString(nCo + nCoDiff));
				if(nCoDiff >= 0)
				{
					eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION,nCoDiff);
				}
				else
				{
					nCoDiff = nCoDiff * -1;
					eCon = EffectAbilityDecrease(ABILITY_CONSTITUTION,nCoDiff);					
				}				
				
				//SendMessageToPC(oCaster, "Old Int = " + IntToString(nI));
				//SendMessageToPC(oCaster, "New Int = " + IntToString(nI + nIDiff));
				if(nIDiff >= 0)
				{
					eInt = EffectAbilityIncrease(ABILITY_INTELLIGENCE,nIDiff);
				}
				else
				{
					nIDiff = nIDiff * -1;
					eInt = EffectAbilityDecrease(ABILITY_INTELLIGENCE,nIDiff);
					
				}				
				
				//SendMessageToPC(oCaster, "Old Wis = " + IntToString(nW));
				//SendMessageToPC(oCaster, "New Wis = " + IntToString(nW + nWDiff));
				if(nWDiff >= 0)
				{
					eWis = EffectAbilityIncrease(ABILITY_WISDOM,nWDiff);					
				}
				else
				{
					nWDiff = nWDiff * -1;
					eWis = EffectAbilityDecrease(ABILITY_WISDOM,nWDiff);				
				}				
								
				//SendMessageToPC(oCaster, "Old Chr = " + IntToString(nCh));
				//SendMessageToPC(oCaster, "New Chr = " + IntToString(nCh + nChDiff));
				if(nChDiff >= 0)
				{
					eChr = EffectAbilityIncrease(ABILITY_CHARISMA,nChDiff);
				}
				else
				{
					nChDiff = nChDiff * -1;
					eChr = EffectAbilityDecrease(ABILITY_CHARISMA,nChDiff);				
				}				
				
				
				effect eVis = EffectVisualEffect(VFX_DUR_DISCOMBOBULATION);
				effect eIcon = EffectVisualEffect(VFX_DUR_DISCOMBOBULATION_ICON);
				effect eLink = EffectLinkEffects(eStr,eDex);
				eLink = EffectLinkEffects(eLink,eCon);
				eLink = EffectLinkEffects(eLink,eInt);
				eLink = EffectLinkEffects(eLink,eWis);
				eLink = EffectLinkEffects(eLink,eChr);
				eLink = EffectLinkEffects(eLink,eVis);
				eLink = EffectLinkEffects(eLink,eIcon);
				eLink = SetEffectSpellId(eLink, SPELL_DISCOMBOBULATION);
									
            	JXApplyEffectToObject(nDurType, eLink, oTarget, fDuration);
			}
        }
    }
	
	
	}
	else
	{
	SendMessageToPC(oCaster, "You must be at least a level 9 Wild Mage to use this spell");
	}
	
	
	JXPostSpellCastCode();
	return;
}