Auto Calculate Abilities to Highest Level

Zandros

Script Author: VGA
I wrote a routine I use im my scripts that automatically calculates an ability to the highest level. It has many potential uses but I prefer to use it so that as your player levels, you don't have to constantly update and reconfigure your scripts.

Code:
;===================================================
;===      GetHighestAbility Routine             ====
;===================================================
function GetHighestAbility(string AbilityName)
{
	declare L int local 20
	declare ABILITY string local ${AbilityName}
	declare AbilityLevels[20] string local

	AbilityLevels[1]:Set[I]
	AbilityLevels[2]:Set[II]
	AbilityLevels[3]:Set[III]
	AbilityLevels[4]:Set[IV]
	AbilityLevels[5]:Set[V]
	AbilityLevels[6]:Set[VI]
	AbilityLevels[7]:Set[VII]
	AbilityLevels[8]:Set[VIII]
	AbilityLevels[9]:Set[IX]
	AbilityLevels[10]:Set[X]
	AbilityLevels[11]:Set[XI]
	AbilityLevels[12]:Set[XII]
	AbilityLevels[13]:Set[XIII]
	AbilityLevels[14]:Set[XIV]
	AbilityLevels[15]:Set[XV]
	AbilityLevels[16]:Set[XVI]
	AbilityLevels[17]:Set[XVII]
	AbilityLevels[18]:Set[XVIII]
	AbilityLevels[19]:Set[XIX]
	AbilityLevels[20]:Set[XX]

	;-------------------------------------------
	; Return if Ability already exists
	;-------------------------------------------
	if ${Me.Ability["${AbilityName}"](exists)}
	{
		return ${AbilityName}
	}

	;-------------------------------------------
	; Find highest Ability level
	;-------------------------------------------	
	do
	{
		if ${Me.Ability["${AbilityName} ${AbilityLevels[${L}]}"](exists)}
		{
			ABILITY:Set["${AbilityName} ${AbilityLevels[${L}]}"]
			break
		}
	}
	while (${L:Dec}>0)

	;-------------------------------------------
	; If Ability exist then return
	;-------------------------------------------
	if ${Me.Ability["${ABILITY}"](exists)}
	{
		return ${ABILITY}
	}

	;-------------------------------------------
	; Otherwise, new Ability is named "None"
	;-------------------------------------------
	return "None"
}
Below, is an example I use in my lvl 19 Disciple script to setup my Abilities to the highest level. Please note that I call this routine only once at the begining of my script.

Code:
;===================================================
;===  Auto Calculate Abilities to Highest Level ====
;===================================================
function SetupAbilities()
{
	;-------------------------------------------
	; Declare Base Abilities - Disciple
	;-------------------------------------------

	declare	Attacks[4]	string	script
	Attacks[1]:Set["Knife Hand"]
	Attacks[2]:Set["Blessed Wind"]
	Attacks[3]:Set["Soul Cutter"]
	Attacks[4]:Set["Cyclone Kick"]
	;
	declare	EndowmentOfLife[3]	string	script
	EndowmentOfLife[1]:Set["Blessed Wind"]
	EndowmentOfLife[2]:Set["Cyclone Kick"]
	EndowmentOfLife[3]:Set["Void Hand"]
	;
	declare	EndowmentOfMastery[3]	string	script
	EndowmentOfMastery[1]:Set["Soul Cutter"]
	EndowmentOfMastery[2]:Set["Void Hand"]
	EndowmentOfMastery[3]:Set["Knife Hand"]
	;
	declare	Heals[5]	string	script
	Heals[1]:Set["Breath of Renewal"]
	Heals[2]:Set["Astral Wind"]
	Heals[3]:Set["Celestial Breeze"]
	Heals[4]:Set["Kiss of Heaven"]
	Heals[5]:Set["Lao'Jin Flare"]
	;
	declare	Buffs[2]	string	script
	Buffs[1]:Set["Wisdom of the Grasshopper"]
	Buffs[2]:Set["Favor of the Crow"]
	;
	declare	Snares[1]	string	script
	Snares[1]:Set["Enfeebling Shuriken"]
	;
	declare	Dots[4]	string	script
	Dots[1]:Set["Enfeebling Shuriken"]
	Dots[2]:Set["Inner Light"]
	Dots[3]:Set["Touch of Woe"]
	Dots[4]:Set["Leech's Grasp"]
	;
	declare	Finishers[5]	string	script
	Finishers[1]:Set["Concordant Hand"]
	Finishers[2]:Set["Falling Petal"]
	Finishers[3]:Set["Touch of Discord"]
	Finishers[4]:Set["Grasp of Discord"]
	Finishers[5]:Set["Kiss of the Slug"]

	;-------------------------------------------
	; Find and set highest abilities
	;-------------------------------------------

	variable int i

	for (i:Set[1] ; ${Attacks[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${Attacks[${i}]}"
		Attacks[${i}]:Set[${Return}]
		echo "Attacks[${i}]:  ${Attacks[${i}]}"
	}
	for (i:Set[1] ; ${EndowmentOfLife[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${EndowmentOfLife[${i}]}"
		EndowmentOfLife[${i}]:Set[${Return}]
		echo "EndowmentOfLife[${i}]:  ${EndowmentOfLife[${i}]}"
	}
	for (i:Set[1] ; ${EndowmentOfMastery[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${EndowmentOfMastery[${i}]}"
		EndowmentOfMastery[${i}]:Set[${Return}]
		echo "EndowmentOfMastery[${i}]:  ${EndowmentOfMastery[${i}]}"
	}
	for (i:Set[1] ; ${Heals[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${Heals[${i}]}"
		Heals[${i}]:Set[${Return}]
		echo "Heals[${i}]:  ${Heals[${i}]}"
	}
	for (i:Set[1] ; ${Buffs[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${Buffs[${i}]}"
		Buffs[${i}]:Set[${Return}]
		echo "Buffs[${i}]:  ${Buffs[${i}]}"
	}
	for (i:Set[1] ; ${Snares[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${Snares[${i}]}"
		Snares[${i}]:Set[${Return}]
		echo "Snares[${i}]:  ${Snares[${i}]}"
	}
	for (i:Set[1] ; ${Dots[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${Dots[${i}]}"
		Dots[${i}]:Set[${Return}]
		echo "Dots[${i}]:  ${Dots[${i}]}"
	}
	for (i:Set[1] ; ${Finishers[${i}].NotEqual[NULL]} ; i:Inc)
	{
		call GetHighestAbility "${Finishers[${i}]}"
		Finishers[${i}]:Set[${Return}]
		echo "Finishers[${i}]:  ${Finishers[${i}]}"
	}
}
Next, is the example I use to cycle through the new abilities. In this case, this is my lame Chains/Counters/Rescues routine I call over and over.

Code:
;===================================================
;===    Lame Chains/Counters/Rescues Routine    ====
;===================================================
function ChainCounterRescue()
{
	;-------------------------------------------
	; Cycle through all the Finishers
	;-------------------------------------------
	variable int i
	for (i:Set[1] ; ${Finishers[${i}].NotEqual[NULL]} ; i:Inc)
	{
		if ${Me.Ability["${Finishers[${i}]}"].IsReady}
		{
			call CastSpell "${Finishers[${i}]}"
		}
	}

	;-------------------------------------------
	; Just incase, lets wrap it up with these commands
	;-------------------------------------------
	VGExecute /reactionautorescue
	VGExecute /reactionautocounter
	VGExecute /reactionautochain
}
Below is my routine I use to use an ability.

Code:
;===================================================
;===         CastSpell Routine                  ====
;===================================================
function:bool CastSpell(string SPELL)
{
	;-------------------------------------------
	; Turn slowly to the target only if outside 85 degrees
	;-------------------------------------------
	call FaceTarget 85

	;-------------------------------------------
	; Make sure we are not already casting or stunned
	;-------------------------------------------
	call IsCasting

	;-------------------------------------------
	; Check to see if the Spell/Ability is ready
	;-------------------------------------------
	call SpellReady "${SPELL}"
	if !${Return}
	{
		return FALSE
	}

	;-------------------------------------------
	; Check to see if yourself or target has buff
	;-------------------------------------------
	call SpellDebuff "${SPELL}"
	if !${Return}
	{
		return FALSE
	}

	;-------------------------------------------
	; Passed all checks so lets use the Spell/Ability
	;-------------------------------------------
	Me.Ability[${SPELL}]:Use
	if ${doDebug}
	{
		echo "[${Time}] --> Casting ${SPELL}"
	}

	;-------------------------------------------
	; Ensure we give the system time to register an ability was used
	;-------------------------------------------
	wait 10
	call IsCasting

	;-------------------------------------------
	; Spell/Ability casted so return TRUE
	;-------------------------------------------	
	return TRUE
}
Below is the routine that checks and waits whenever you are casting a spell/ability, stunned, or in global cooldown. Call it constantly or 3/10ths of a second after using an ability.

Code:
;===================================================
;===          IsCasting Routine                 ====
;===================================================
function IsCasting()
{
	;-------------------------------------------
	; Perform the following only if casting, stunned, or in recovery
	;-------------------------------------------
	if ${Me.IsCasting} || ${Me.ToPawn.IsStunned} || ${VG.InGlobalRecovery}>0
	{
		while ${Me.IsCasting} || ${Me.ToPawn.IsStunned} || ${VG.InGlobalRecovery}>0
		{
			if ${Me.ToPawn.IsStunned}
			{
				if ${doDebug}
				{
					echo "[${Time}] --> STUNNED"
				}
				while ${Me.ToPawn.IsStunned}
				{
					wait 1
				}
			}
		}
		;-------------------------------------------
		; Idea barrowed from mmoadict
		;-------------------------------------------
		while !${Me.Ability["Torch"].IsReady}
			wait 1

		;-------------------------------------------
		; Doesn't hurt to wrap things up with a waitframe
		;-------------------------------------------
		waitframe
	}
}
Below is the routine that checks if spell is ready to cast. False means its not, True means its good.

Code:
;===================================================
;===          SpellReady Routine                ====
;===================================================
function:bool SpellReady(string SPELL)
{
	if !${Me.Ability[${SPELL}].IsReady} || ${SPELL.Find[None]} || ${Me.Ability[${SPELL}].TimeRemaining}>0
	{
		if ${doDebug}
		{
			;echo "[${Time}] --> ${SPELL} is not Ready"
		}
		return FALSE
	}
	if ${Me.ToPawn.IsStunned}
	{
		if ${doDebug}
		{
			echo "[${Time}] --> << Currently Stunned and can't cast ${SPELL} >>"
		}
		while ${Me.ToPawn.IsStunned}
		{
			wait 1
		}
		if ${doDebug}
		echo "[${Time}] --> << No Longer Stunned >>"
	}
	if !${Me.Target.HaveLineOfSightTo} && ${Me.Target(exists)} && (!${Me.Ability[${SPELL}].TargetType.Equal[Self]} && !${SPELL.Equal[Auto Attack]})

	{
		if ${doDebug}
		{
			echo "[${Time}] --> You have no Line of Sight to target to cast ${SPELL}"
		}
		return FALSE
	}
	if ${Me.Ability[${SPELL}].EnergyCost}>${Me.Energy}
	{
		if ${doDebug}
		{
			echo "[${Time}] --> Not enough Energy for ${SPELL}"
		}
		return FALSE
	}
	if ${Me.Ability[${SPELL}].EnduranceCost}>${Me.Endurance}
	{
		if ${doDebug}
		{
			echo "[${Time}] --> Not enough Endurance for ${SPELL}"
		}
		return FALSE
	}
	if ${Me.Ability[${SPELL}].JinCost} > ${Me.Stat[Adventuring,Jin]}
	{
		if ${doDebug}
		{
			;echo "[${Time}] --> Not enough Jin for ${SPELL}"
		}
		return FALSE
	}
	;-------------------------------------------
	; Passed all checks so return TRUE
	;-------------------------------------------
	return TRUE
}
Next is the routine to see if the buff/dot already exists on the target or your self. Returns True if it does not exist.

Code:
;===================================================
;===          SpellDebuff Routine               ====
;===================================================
function:bool SpellDebuff(string SPELL)
{
	if ${Me.Effect["${SPELL}"](exists)}
	{
		if ${doDebug}
		{
			;echo "[${Time}] --> You are already buffed with ${SPELL}"
		}
		return FALSE
	}
	if ${Me.TargetMyDebuff["${SPELL}"](exists)}
	{
		if ${doDebug}
		{
			;echo "[${Time}] --> Your target already has the Debuff ${SPELL}"
		}	
		return FALSE
	}
	;-------------------------------------------
	; Passed all checks so return TRUE
	;-------------------------------------------
	return TRUE
}
 
Top Bottom