SpellSkill Macro

Post your completed (working) macros here. Only for macros using MQ2Data syntax!

Moderator: MacroQuest Developers

Qhynos
a ghoul
a ghoul
Posts: 81
Joined: Fri Jul 14, 2006 6:19 pm
Location: The Bunker in San Diego, CA

SpellSkill Macro

Post by Qhynos » Wed Apr 20, 2011 11:13 am

This is a simple macro to max out your five casting skills. If someone wants to extend this to other skills, I'll be happy to implement their additional subs, and INI support. Run this once to generate the INI, then supply a spell from each casting skill category. Automatically ends if the skills are maxed or if a spell name is bad, etc.

Use /macro spellskill to work on skills in sequential order
Use /macro spellskill 1 to work on skills in random order

The macro will periodically display your progress.

Some of this code isn't fully tested, I didn't really test the GM, tell, or PC radius checking as I don't really worry about them. If you are paranoid, you can enable the checking and let me know if it pans out.

Code: Select all

|*
SpellSkill, by QHynoS

Supplied as-is, feel free to reuse any code and claim that it is your own
including my INI beautifier.

Simple macro to max out your base casting skills with checking for valid spells,
skill caps, and INI. Summoned items will be deleted and the PC will be targeted
(for spells that need a target). Evocation may be a problem for some classes/levels
due the inability to do self damage. All spells specified must be memmed or 
otherwise available to be cast by name. The macro will end if all you hit all
specified spell skill caps.

If you are paranoid, set I_AM_PARANOID to TRUE. It's probably worthless, but 
it exists for anyone that thinks it will help. It will camp you out if you get
more than 3 tells in 3 minutes or if PCs are within 300 radius and line of
sight for longer than 15 minutes. Casting is effectively suspended while PCs
are in the area. The GM check is there, but it's stupid.

The INI file ( "SpellSkill_INI_yourname.ini" ) generated by default:
[SpellSkill]
I_AM_PARANOID..................=FALSE
Med_To_Full_At_Percent_Mana....=10
Mana_Recover_Spell_Name........=
SpellSkill_Spell_Count.........=
Spell1_Cast_Name...............=
Spell2_Cast_Name...............=
Spell3_Cast_Name...............=
Spell4_Cast_Name...............=
Spell5_Cast_Name...............=

Med to full defaults at 10%, so you will stop casting and med to 100% when 
this threshold is hit. Fill in the spell count, spell names (pick a spell for
each skill category) and priority from each casting skill. Priority is based 
on lowest number If you have a mana recovery spell (e.g. Clarity, Harvest, 
etc), supply the name and it will attempted just prior to medding.

Example INI:
[SpellSkill]
I_AM_PARANOID..................=FALSE
Med_To_Full_At_Percent_Mana....=10
Mana_Recover_Spell_Name........=Harvest
SpellSkill_Spell_Count.........=5
Spell1_Cast_Name...............=O'Keil's Radiation
Spell2_Cast_Name...............=True North
Spell3_Cast_Name...............=Fade
Spell4_Cast_Name...............=Halo of Light
Spell5_Cast_Name...............=Iceflame of E'ci

Usage:

/macro spellskill
Will run SpellSkill in normal mode where it will repeatly cast a spell to the 
skillcap in priority order as specified in the INI file.

/macro spellskill 1
Will run SpellSkill in random mode where it will cast a random spell from the list
in the INI file.
*|

#chat tell

Sub Main(int Arg1)

	/declare	Mode						int			outer	${Arg1}
	/declare	MS_Ini_File					string		outer	SpellSkill_INI_${Me.CleanName}.ini
	/declare	TellCount					int			outer	0
	/declare	TellTimer					timer		outer	0
	/declare	SkillDisplayTimer			timer		outer	0
	
	/echo ${MS_Ini_File}
	/call LoadIni ${MS_Ini_File}
	/if ( !${SpellSkill_Spell_Count} ) {
		/echo No Spell Count, new INI to edit?
		/endmacro
	}
  	
	:MainLoop
	
	/doevents
	/if ( ${I_AM_PARANOID} ) /call CheckForBadShit
	/call CheckSkillCap
	/call Med
	/if ( !${Mode} ) {
		/call DoSpellSkill
		/goto :MainLoop
	}
	/call DoRandomSpellSkill
	/goto :MainLoop
	
/return


Sub DoSpellSkill

	/declare i int local
	
	/for i 1 to ${SpellSkill_Spell_Count}
		/if ( ${Me.Skill[${Spell["${Spell${i}_Cast_Name}"].Skill}]} < ${Me.SkillCap[${Spell["${Spell${i}_Cast_Name}"].Skill}]} ) {
			/call CastSkill ${i}
			/return
		}
	/next i
	
/return

Sub DoRandomSpellSkill

	/declare i int local
	/declare p int local ${Math.Rand[${SpellSkill_Spell_Count}]}
	/varcalc p ${p} + 1
	/call CastSkill ${p}
	
/return

Sub CastSkill(int SpellNumber)

	/if ( !${Me.Skill[${Spell["${Spell${SpellNumber}_Cast_Name}"].Skill}]} ) {
		/echo Cast Skill for ${SpellNumber} ${Spell${SpellNumber}_Cast_Name} not found, valid spell?
		/endmacro
	}
	/if ( !${Me.SpellReady["${Spell${SpellNumber}_Cast_Name}"]} || ${Me.Skill[${Spell["${Spell${SpellNumber}_Cast_Name}"].Skill}]} == ${Me.SkillCap[${Spell["${Spell${SpellNumber}_Cast_Name}"].Skill}]} ) /return
	/if ( ${TargetID} != ${Me.ID} ) /target id ${Me.ID}
	/delay 10 ${Target.ID} == ${Me.ID}
	/cast "${Spell${SpellNumber}_Cast_Name}"
	/delay 100 !${Me.Casting.ID}
	/delay 20 ${Cursor.ID}
	/if ( ${Cursor.ID} ) /destroy

/return

Sub CheckSkillCap

	/declare i int	local 
	/declare b bool local FALSE

	/for i 1 to ${SpellSkill_Spell_Count}
		/if ( !${SkillDisplayTimer} ) /echo ${Spell["${Spell${i}_Cast_Name}"].Skill}: ${Me.Skill[${Spell["${Spell${i}_Cast_Name}"].Skill}]} of ${Me.SkillCap[${Spell["${Spell${i}_Cast_Name}"].Skill}]}
		/if ( ${Me.Skill[${Spell["${Spell${i}_Cast_Name}"].Skill}]} < ${Me.SkillCap[${Spell["${Spell${i}_Cast_Name}"].Skill}]} ) /varset b TRUE
	/next i

	/if ( !${b} ) {
		/echo No Casting skill found to be lower than the cap!
		/endmacro
	}
	/if ( !${SkillDisplayTimer} ) /varset SkillDisplayTimer 300
	
/return

Sub Med

	/if ( ${Me.PctMana} > ${Med_To_Full_At_Percent_Mana} ) /return
	/echo ${Spell[${Mana_Recover_Spell_Name}]} ${Me.SpellReady[${Spell["${Mana_Recover_Spell_Name}"]}]}
	/if ( ${Me.SpellReady[${Spell["${Mana_Recover_Spell_Name}"]}]} ) {
		/cast "${Mana_Recover_Spell_Name}"
		/delay 300 !${Me.State[STUN]}
	}
	/if ( ${Me.Standing} ) /sit
	:MedLoop
	/delay 10
	/if ( ${Me.PctMana} < 100 ) /goto :MedLoop
	/stand
	/delay 10 ${Me.Standing}

/return

Sub CheckForBadShit

	/declare infidelhangingaroundcount int local
	
	:CheckForBadShitLoop
	/if ( ${Spawn[gm].ID} || ${SpawnCount[pc los radius 300 zradius 300].ID} ) {
		/delay 300
		/varcalc infidelhangingaroundcount ${infidelhangingaroundcount} + 1
		/if ( ${infidelhangingaroundcount} > 30 ) {
			/echo Shit, I think someone has their eyes on me!
			/camp
			/endmacro
		}
		/goto :CheckForBadShitLoop
	}
	
	/if ( ${TellCount} > 3 && ${TellTimer} ) {
		/echo OMFG I got more than 3 tells in 3 minutes, aborting!
		/camp
		/endmacro
	}
	/if ( $!{TellTimer} ) /varset TellCount 0
	

/return

Sub LoadIni(string Ini_File)

	/declare i int local
	/declare j int local
	
	/call DeclareIniVar	${Ini_File} 		I_AM_PARANOID..................				int		SpellSkill FALSE
	/call DeclareIniVar	${Ini_File} 		Med_To_Full_At_Percent_Mana....				int		SpellSkill 10
	/call DeclareIniVar	${Ini_File} 		Mana_Recover_Spell_Name........				int		SpellSkill 	
	/call DeclareIniVar	${Ini_File} 		SpellSkill_Spell_Count.........				int		SpellSkill
	/varset j ${SpellSkill_Spell_Count}
	/if ( !${j} ) /varset j 5
	/for i 1 to ${j}
		/call DeclareIniVar	${Ini_File} 	Spell${i}_Cast_Name...............			string	SpellSkill
	/next i

/return

Sub DeclareIniVar(string IniFile, string VarName, string VarType, string SectionName, string VarValue, string Alias)
	
	|*Strips the ... off of the end of an INI variable so the actual var names are clean*|
	/declare CleanVarName string local ${VarName}
	/if ( ${VarName.Find[.]} ) {
		/declare i int local
		/varcalc i ${VarName.Find[.]}-1
		/varset CleanVarName ${VarName.Left[${i}]}
	}
	|*Defines the clean var name if not defined and then writes it to the INI or reads the INI value*|
	/if ( !${Defined[${CleanVarName}]} ) /declare ${CleanVarName} ${VarType} outer   
	/declare TempString string local ${Ini["${IniFile}",${SectionName},${VarName},NOTFOUND]}
	/if ( ${TempString.Equal[NOTFOUND]} ) { 
		/varset ${CleanVarName} ${VarValue} 
		/ini "${IniFile}" "${SectionName}" "${VarName}" "${${CleanVarName}}" 
	} else { 
		/varset ${CleanVarName} ${TempString} 
	}
   
/return

Sub Event_Chat

	/varcalc TellCount ${TellCount} + 1
	/if ( $!{TellTimer} ) /varset TellTimer 1800
	/delay 300
	/doevents
	
/return
Last edited by Qhynos on Thu Apr 21, 2011 11:08 am, edited 1 time in total.

squench
decaying skeleton
decaying skeleton
Posts: 4
Joined: Wed Feb 02, 2011 11:56 am

Re: SpellSkill Macro

Post by squench » Wed Apr 20, 2011 10:47 pm

I get this error when trying the script:

Subroutine CheckSkillCap wasn't found
spellskill.mac@82 (Main(intArg1)): /call CheckSkillCap

This one looked easier than the one that was posted in VIP, so I though I would give it a go... I am sure it's something I am doing.

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Re: SpellSkill Macro

Post by dont_know_at_all » Wed Apr 20, 2011 11:00 pm

Copy and paste failure. Try again.

boxalot
orc pawn
orc pawn
Posts: 22
Joined: Sun Jun 14, 2009 12:26 am

Re: SpellSkill Macro

Post by boxalot » Wed Apr 20, 2011 11:00 pm

there are 3 spaces between "sub" and "checkskillcap". That possibly crashing the macro?

squench
decaying skeleton
decaying skeleton
Posts: 4
Joined: Wed Feb 02, 2011 11:56 am

Re: SpellSkill Macro

Post by squench » Wed Apr 20, 2011 11:35 pm

I am sorry this is going to sound stupid, but is there a way to copy from the EQ chat window? I know how to copy and paste, but not form EQ. Is there a log file that is generated in the MQ release folder? This error isnt crashing the client. I am just getting error in the MQ chat window. Do I need to use something like dbgview?

squench
decaying skeleton
decaying skeleton
Posts: 4
Joined: Wed Feb 02, 2011 11:56 am

Re: SpellSkill Macro

Post by squench » Wed Apr 20, 2011 11:41 pm

boxalot wrote:there are 3 spaces between "sub" and "checkskillcap". That possibly crashing the macro?
You were right there were 3 spaces. That corrected that error, but now getting another error. I need now to go back to
my above question about copying from EQ chat.

Qhynos
a ghoul
a ghoul
Posts: 81
Joined: Fri Jul 14, 2006 6:19 pm
Location: The Bunker in San Diego, CA

Re: SpellSkill Macro

Post by Qhynos » Thu Apr 21, 2011 11:10 am

It looks like a space got converted into a tab for some reason, I edited it out, so three spaces should be gone now.

As far as the cut and paste from MQ2 chat, you can use MQ2Chat to force output to your EQ chat window, which you can log. Be careful!

squench
decaying skeleton
decaying skeleton
Posts: 4
Joined: Wed Feb 02, 2011 11:56 am

Re: SpellSkill Macro

Post by squench » Thu Apr 21, 2011 1:55 pm

Qhynos wrote:It looks like a space got converted into a tab for some reason, I edited it out, so three spaces should be gone now.

As far as the cut and paste from MQ2 chat, you can use MQ2Chat to force output to your EQ chat window, which you can log. Be careful!
Okay, thanks for that info I will be very careful.
I also figured out the error I was getting. It was due to me using a revision of MQ2 behind the current and it didnt include Me.SkillCap. Complied the new version and bam working like a champ! Script is working very well for me now much thanks for the macro and all the help.