• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

Skillup casting

Joined
Aug 8, 2008
RedCents
31¢
Hello all,

I'm a long-time user, long-time lurker, first-time poster.

I have started working on a universal macro for skilling up the casting skills. Not sure if I am reinventing the wheel, but I've never seen any plugin or macro that does this.


It's far from finished, I just started coding this today, but I would like to subject it for review and feedback anyway.

I have only populated the spell list for a few classes: CLR, SHD, WIZ, ENC.

Find a safe place, target your pet or something, then "/mac CastingSkillup"
Let me know what you think please, is it worth finishing this macro? Would anyone use it?

Rich (BB code):
Old code removed, look a few posts down for current version.
 
Last edited:
You are reinventing the wheel, but this is a great macro to get the concept down. The other that is out there, simply goes through your spell gems until you hit your maximum.
 
thank you Alatyami for the feedback.

I wanted to make a more sophisticated version than the other one that just casts five spells blindly over and over.

My script calculates the maximum possible skill, improves the lowest skills first, and shuts itself down when all skills are maxed.

Added some more error-handling and more spells since I posted the script.
If anyone is interested I will gladly post an updated version.

Cheers,
AW
 
Great macro!
Using it now and works perfectly except there doesnt seem to be a med up routine.
 
Hello again,

Sorry about the delay, I have been away from the game for a couple of months.

Here's the current version of my script, I just added a very primitive med routine too.
Hope you like it, let me know if there are errors or problems.
Cheers,
AW

Rich (BB code):
|CastingSkillup.mac 
|Version 0.3
|2010, August 14
| 
| Description: This macro will automatically work on your five casting skills.
|
| Find a safe place (not too safe place if you want to work on evocation), target your pet 
| or groupmate, then run this macro.
|
| Syntax: /mac CastingSkillup 


#turbo
#include spell_routines.inc

#Event RaiseError "#*#Your spell did not take hold.#*#"
#Event RaiseError "#*#Your spell would not have taken hold on your target.#*#"
#Event RaiseError "#*#This spell only works on the undead.#*#"

Sub Main

	/declare ErrorLevel			int outer 0

	/declare SkillName[5]			string outer
	/declare SkillActive[5]			int outer 1
	/declare PracticeSpell[16,5]		string outer UNDEFINED

	/declare DesiredSkillLevel		int outer 0

	/declare ActiveSkill			int outer 1
	/declare ActiveSkillLevelGoal		int outer 10

	/declare SumSpellsCast			int outer 0


	/echo **** CastingSkillup.mac ****

	/if (${Me.Class.Name.Equal[Warrior]} || ${Me.Class.Name.Equal[Berserker]} || ${Me.Class.Name.Equal[Monk]} || ${Me.Class.Name.Equal[Rogue]} || ${Me.Class.Name.Equal[Bard]}) {
		/echo You need to go buy a clue and a spell book.
	}

	/call Init

:MainLoop

|	Start casting in chunks, first all skills to 20, then 30, 40, etc.
	/for ActiveSkill 1 to 5
		/if (${SkillActive[${ActiveSkill}]}) /call Do_Cast

	/next ActiveSkill

	/if (${ActiveSkillLevelGoal} < ${DesiredSkillLevel}) {

		/call UpdateSkillgoal
		/goto :MainLoop
	}

	/echo **** CastingSkillup Finished ****
	/echo **** ${SumSpellsCast} spells cast ****
	/beep
	/beep
	
/return

Sub Do_Cast

	/if (${Me.Skill[${SkillName[${ActiveSkill}]}]} >= ${ActiveSkillLevelGoal}) {
		/return
	}

	/if (${PracticeSpell[${Me.Class.ID},${ActiveSkill}].Equal[UNDEFINED]}) {
|		/echo Spell undefined, cancelling
		/varset SkillActive[${ActiveSkill}] 0
		/return
	}

	|echo Next goal: Abjuration to 250
	/echo Next goal: ${SkillName[${ActiveSkill}]} to ${ActiveSkillLevelGoal}
	/delay 3s

   :Loop

	/if (${Me.Skill[${SkillName[${ActiveSkill}]}]} >= ${ActiveSkillLevelGoal}) {
		/echo Goal reached.
		/return
	}

	/call cast "${PracticeSpell[${Me.Class.ID},${ActiveSkill}]}" gem7

	/if (${Macro.Return.Equal[CAST_SUCCESS]}) /varset SumSpellsCast ${Math.Calc[${SumSpellsCast}+1]}

	/if (${Macro.Return.Equal[CAST_OUTOFMANA]}) {
		/echo OOM, resting a bit.
		/sit
		/delay 120s
	}

	/if (${Macro.Return.NotEqual[CAST_SUCCESS]} && ${Macro.Return.NotEqual[CAST_NOTREADY]} && ${Macro.Return.NotEqual[CAST_OUTOFMANA]}) {
		/echo Unhandled exception: ${Macro.Return}
		/varset SkillActive[${ActiveSkill}] 0
		/return
	}

	/doevents

	/if (${ErrorLevel} > 0) {
		/echo Something went wrong.
		/varset SkillActive[${ActiveSkill}] 0
		/varset ErrorLevel 0
		/return
	}




	/goto :Loop
	
/return


Sub Init

	/echo Initializing...

	/call Init_vars
	/call UpdateSkillGoal

	/declare i int local
	/for i 1 to 5
		/echo ${SkillName[${i}]}: ${Me.Skill[${SkillName[${i}]}]}/${DesiredSkillLevel}
|		/if (${Me.Skill[${SkillName[${i}]}]} < ${DesiredSkillLevel}) {
|			/echo ${SkillName[${i}]} practice will be Spell: ${PracticeSpell[${Me.Class.ID},${i}]}
|		}
	/next i

	

/return

Sub Init_vars

	/varset SkillName[1]			Abjuration
	/varset SkillName[2]			Alteration
	/varset SkillName[3]			Conjuration
	/varset SkillName[4]			Divination
	/varset SkillName[5]			Evocation

| 	WARRIOR = 1

|	CLERIC = 2
	/varset PracticeSpell[2,1]		Endure Poison
	/varset PracticeSpell[2,2]		Minor Healing
	/varset PracticeSpell[2,3]		Halo of Light
	/varset PracticeSpell[2,4]		True North
	/varset PracticeSpell[2,5]		Strike

|	PALADIN = 3
	/varset PracticeSpell[3,1]		UNDEFINED
	/varset PracticeSpell[3,2]		UNDEFINED
	/varset PracticeSpell[3,3]		UNDEFINED
	/varset PracticeSpell[3,4]		UNDEFINED
	/varset PracticeSpell[3,5]		UNDEFINED

|	RANGER = 4
	/varset PracticeSpell[4,1]		UNDEFINED
	/varset PracticeSpell[4,2]		UNDEFINED
	/varset PracticeSpell[4,3]		UNDEFINED
	/varset PracticeSpell[4,4]		UNDEFINED
	/varset PracticeSpell[4,5]		UNDEFINED

|	SHADOW KNIGHT = 5
	/varset PracticeSpell[5,1]		Endure Cold
	/varset PracticeSpell[5,2]		Shadow Step	
	/varset PracticeSpell[5,3]		Spike of Disease	
	/varset PracticeSpell[5,4]		Sense the Dead
	/varset PracticeSpell[5,5]		Ward Undead

|	DRUID = 6
	/varset PracticeSpell[6,1]		Skin like Wood
	/varset PracticeSpell[6,2]		Minor Healing
	/varset PracticeSpell[6,3]		UNDEFINED
	/varset PracticeSpell[6,4]		UNDEFINED
	/varset PracticeSpell[6,5]		UNDEFINED

|	MONK = 7
|	BARD = 8
|	ROGUE= 9

|	SHAMAN = 10
	/varset PracticeSpell[10,1]		UNDEFINED
	/varset PracticeSpell[10,2]		UNDEFINED
	/varset PracticeSpell[10,3]		UNDEFINED
	/varset PracticeSpell[10,4]		UNDEFINED
	/varset PracticeSpell[10,5]		UNDEFINED

|	NECROMANCER = 11
	/varset PracticeSpell[11,1]		Minor Shielding
	/varset PracticeSpell[11,2]		Lifetap
	/varset PracticeSpell[11,3]		Coldlight
	/varset PracticeSpell[11,4]		True North
	/varset PracticeSpell[11,5]		Ward Undead

|	WIZARD = 12
	/varset PracticeSpell[12,1]		Minor Shielding
	/varset PracticeSpell[12,2]		Fade
	/varset PracticeSpell[12,3]		Halo of Light
	/varset PracticeSpell[12,4]		True North
	/varset PracticeSpell[12,5]		Strike

|	MAGICIAN = 13
	/varset PracticeSpell[13,1]		Minor Shielding
	/varset PracticeSpell[13,2]		Renew Elements
	/varset PracticeSpell[13,3]		Summon Brass Choker
	/varset PracticeSpell[13,4]		True North
	/varset PracticeSpell[13,5]		Burst of Flame

|	ENCHANTER = 14
	/varset PracticeSpell[14,1]		Minor Shielding
	/varset PracticeSpell[14,2]		Strengthen
	/varset PracticeSpell[14,3]		Pendril's Animation
	/varset PracticeSpell[14,4]		True North
	/varset PracticeSpell[14,5]		Chaotic Feedback

|	BEASTLORD = 15
	/varset PracticeSpell[15,1]		UNDEFINED
	/varset PracticeSpell[15,2]		UNDEFINED
	/varset PracticeSpell[15,3]		UNDEFINED
	/varset PracticeSpell[15,4]		UNDEFINED
	/varset PracticeSpell[15,5]		UNDEFINED

|	BERSERKER = 16

/return

Sub UpdateSkillGoal

	/if (${Me.Level} <= 50) {
		/call Min 255 ${Math.Calc[5 + ${Me.Level}*5]}
		/varset DesiredSkillLevel	${Macro.Return}
	} else /if (${Me.Level} <= 65) {
		/varset DesiredSkillLevel	${Math.Calc[${Me.Level}*3 + 105]}
	} else {
		/varset DesiredSkillLevel	${Math.Calc[${Me.Level}*2 + 170]}
	}

	/call Min ${DesiredSkillLevel} ${Math.Calc[${ActiveSkillLevelGoal} + 10]}
	/varset ActiveSkillLevelGoal	${Macro.Return}


/return

Sub Min(int A, int B)

	/declare result int local 
	/if (${A} < ${B}) {
		/varset result ${A}
	} else {
		/varset result ${B}
	}
	
/return ${result}

Sub Event_RaiseError(Line, NewSkill)

	/varset ErrorLevel 1
	
/return
 
I realize this is an old thread but I tried the revised macro and it all works well till after the first cast, then I get Unhandled Exception: X. For a quick work around I remove these lines:

Rich (BB code):
/if (${Macro.Return.NotEqual[CAST_SUCCESS]} && ${Macro.Return.NotEqual[CAST_NOTREADY]} && ${Macro.Return.NotEqual[CAST_OUTOFMANA]}) {
		/echo Unhandled exception: ${Macro.Return}
		/varset SkillActive[${ActiveSkill}] 0
		/return
	}

and it seems to work so far although it might be too early since my skills are pretty low and I am doing this on a power leveled 75.

I like the way it this macro calculates the maximum and incrementally skills the casting skills up; much better then my vbscript mouse clicker.

Thanks Arneweise.
 
Hello Reverent,

Thanks for the feedback.

I'm currently back in the game and been using this macro without problems on a couple of characters.


What is the X in the "Unhandled Exception: X" and which class are you?
I'll try to debug your problems.

Cheers,
AW
 
Hello Reverent,
Thanks for the feedback.
I'm currently back in the game and been using this macro without problems on a couple of characters.
What is the X in the "Unhandled Exception: X" and which class are you?
I'll try to debug your problems.
Cheers,
AW

Thanks for checking. It actually says "Unhandled Exception: X". It doesn't substitute anything for X as X is apparently the value of ${Macro.Return}. Since it works with the code removed (and works very well btw, thank you) I haven't tried it with the old code for a long while. If I remember correctly it gets through listing all the skills, determines the skills that need updated and it casts one time from each skill and then it stops, like it has met its goal. Once it casts five times it stops and echos the Unhandled Exception: X.

I used it on an enchanter and a mage, both had the same issue. They were both level 75 and had been powerleveled as most of their casting skills were around 10-20.

I obviously assume that (${Macro.Return.NotEqual[CAST_SUCCESS]} and ${Macro.Return.NotEqual[CAST_NOTREADY]} and ${Macro.Return.NotEqual[CAST_OUTOFMANA]}) are all true and that triggers the echo of the X, however, I am not sure why you are checking these conditions to begin with; I would note that most of my macros are very simple and I consider myself a beginner when it comes to macros so there is likely a good reason you are checking. It does work though without this portion of your code.
 
We probably have different versions of "Spell_Routines.inc",
the macro return values I use come from that file:


Rich (BB code):
| Returns these values:
|----------------------+----------------------------------------------------------------------+
| CAST_CANCELLED       | Spell was cancelled by ducking (either manually or because mob died) |
| CAST_CANNOTSEE       | You can't see your target                                            |
| CAST_IMMUNE          | Target is immune to this spell                                       |
| CAST_INTERRUPTED     | Casting was interrupted and exceeded the given time limit            |
| CAST_INVIS           | You were invis, and noInvis is set to true                           |
| CAST_NOTARGET        | You don't have a target selected for this spell                      |
| CAST_NOTMEMMED       | Spell is not memmed and you gem to mem was not specified             |
| CAST_NOTREADY        | AA ability or spell is not ready yet                                 |
| CAST_OUTOFMANA       | You don't have enough mana for this spell!                           |
| CAST_OUTOFRANGE      | Target is out of range                                               |
| CAST_RESISTED        | Your spell was resisted!                                             |
| CAST_SUCCESS         | Your spell was cast successfully! (yay)                              |
| CAST_UNKNOWNSPELL    | Spell/Item/Ability was not found                                     |
|----------------------+----------------------------------------------------------------------+

That section you removed is just a check to see that everything went well before trying to cast the spell again,
so you don't go into an endless loop if you for example don't even have that spell in your book
or chaincasting a nuke that "would not take hold" in the guild hall.

Without the Macro return values you will also not have the "med break if OOM" functionality or the counting of total number of spells cast,
but I am glad it works anyway.

Try copying the Spell_Routines.inc file from the official NA compile into your Macros folder, and see if that fixes it?
 
We probably have different versions of "Spell_Routines.inc",
the macro return values I use come from that file:


Rich (BB code):
| Returns these values:
|----------------------+----------------------------------------------------------------------+
| CAST_CANCELLED       | Spell was cancelled by ducking (either manually or because mob died) |
| CAST_CANNOTSEE       | You can't see your target                                            |
| CAST_IMMUNE          | Target is immune to this spell                                       |
| CAST_INTERRUPTED     | Casting was interrupted and exceeded the given time limit            |
| CAST_INVIS           | You were invis, and noInvis is set to true                           |
| CAST_NOTARGET        | You don't have a target selected for this spell                      |
| CAST_NOTMEMMED       | Spell is not memmed and you gem to mem was not specified             |
| CAST_NOTREADY        | AA ability or spell is not ready yet                                 |
| CAST_OUTOFMANA       | You don't have enough mana for this spell!                           |
| CAST_OUTOFRANGE      | Target is out of range                                               |
| CAST_RESISTED        | Your spell was resisted!                                             |
| CAST_SUCCESS         | Your spell was cast successfully! (yay)                              |
| CAST_UNKNOWNSPELL    | Spell/Item/Ability was not found                                     |
|----------------------+----------------------------------------------------------------------+

That section you removed is just a check to see that everything went well before trying to cast the spell again,
so you don't go into an endless loop if you for example don't even have that spell in your book
or chaincasting a nuke that "would not take hold" in the guild hall.

Without the Macro return values you will also not have the "med break if OOM" functionality or the counting of total number of spells cast,
but I am glad it works anyway.

Try copying the Spell_Routines.inc file from the official NA compile into your Macros folder, and see if that fixes it?

I ran into the same problem reverent had, and checked my spell_routines.inc file, it has those same exact options listed in it. My theory was it seemed like it was attempting to recast just an instant before it was ready, (occasionally some spells would recast, typically the summon food/drink spells for conjuration) then after following his method of removingthat portion of the macro it worked and seems like it has enough time between each cast to cast twice, which seems to reinforce that idea, Perhaps there's a way to make the macro wait even a tenth of a second before trying to cast? that should fix the error. Unfortunately I'm still pretty new with these. when I'm less busy trying to play as well I'll probably look at the code closer and try to figure it out. (unless someone here beats me to the punch.)
 
I will look at it as well. We should have a working spell trainer
 
One note, when I took out the error check like reverant suggested and added /delay 1s to the first line of the Sub Do_Cast it chopped the cast time down a lot like it was waiting an extra second before recasting, after reverting back to the original script and adding that delay it still had the same problem of Unhandled Exception X:
 
I just used my macro on the progression server character, and it worked fully automaticly exactly as intended, maxing all five skills.

I don't understand where the Macro.Return variable can be set to "X",
still leaning towards a different version of Spell_Routines.inc?

Or maybe something else, a plugin or something sets the Macro.Return variable outside this scope?
 
One note, when I took out the error check like reverant suggested and added /delay 1s to the first line of the Sub Do_Cast it chopped the cast time down a lot like it was waiting an extra second before recasting, after reverting back to the original script and adding that delay it still had the same problem of Unhandled Exception X:

What class are you experiencing problems on?
 
druid for mine, using minor healing, skin like wood, summon drink, camouflage, and flame lick as the 5 different skills.

also here is what i have for my spell_routines.inc

Rich (BB code):
| spell_routines.inc v2.41
| Originally Written by Rusty~
| Upkeep performed by A_Druid_00
| 
| Includes MQ2Exchange integration for item swapping by BrainDeath
| Also includes FD fix that would cause an endless loop if you were hit by FD mid-cast by A_Druid_00
| 
| Features:
| - Casts spells, clicks items, or uses AA abilities for you
| - Allows back to back casting without waiting on spell gems to pop all the way up
| - Will interrupt spell if target dies while casting. If on a mount, it will dismount and duck if the time left
|   is greater than 7 seconds, else it will move forward a bit to interrupt, then move you back
|
|    ** IMPORTANT: if you don't want to interrupt a spell while mounted, put this at the top of your macro: **
|    **   /declare noInterrupt int outer 1                                                                  **
|
| - Allows you to use items in bags. Equips item, clicks it, then returns it to its previous location
| - Lets you set how long you want to keep trying to cast the spell (defaults to 0)
|   If the spell is interrupted before the given time, it will recast, else it will return CAST_INTERRUPTED
| - Lets you call a custom subroutine while waiting for spell to finish casting
|   Try to keep custom subroutines very small. A common use would be to interrupt the spell if a certain condition is true
| - This file also includes a sub named Interrupt. You can call this to interrupt any spell you're casting instantly.
| - You can also use the SwapItem sub included in this to swap items to certain slots
| - Added EquipItem sub to easily equip items in your main Inventory slots.
|
| - Note: if you don't want this to cast spells while you're invis, in your main macro have this at the top:
|      /declare noInvis int outer 1
|   This will make it return CAST_INVIS if you're invis
| 
|  Below is a list of outer scope variables you can access in your macros:
|      refreshTime        - How much time is left till you're done recovering from casting
|      castEndTime        - How much time left till you're done casting the current spell... usable in custom spell Subs
|      spellNotHold       - 1 if your last spell didn't take hold, 0 otherwise
|      spellRecastTime1-9 - How much time left till that spell is back up
| 
|======================================================================================================================
|  EquipItem:  An easier way to equip items you have in bags ( useful for weapons or focus items )
|              slot name is optional. If not given, it will equip it in the first possible spot
| 
|    Usage:
|        /call EquipItem "item name|slotname"
| 
|        Returns: "old item name|slotname"
|    Examples:
|    
|    To Equip Sharp Ended Broken Lever when you have Serpent of Vindication equiped:
|        /call EquipItem "Sharp Ended Broken Lever"
|    It will return "Staff of Vindication|mainhand"
|    To reequip the original item, you can save the return in a variable, and then use it later like this:
|       /varset oldPrimary ${Macro.Return}
|       | ... do stuff here with your new item equiped
|       /call EquipItem ${oldPrimary}
| 
|======================================================================================================================
|  SwapItem:  a subroutine which is used in the Cast sub itself. You don't need to do this to cast an item in a bag
|             but you can call it in your macro to SwapItems (such as weapons or focus items)
|    Usage:
|        /call SwapItem "item name" slotname|slotID 
|    Examples:
|    
|    To swap Darkblade of the Warlord to your main hand:
|        /call SwapItem "Darkblade of the Warlord" mainhand
| 
|    To swap stat food in one bag with other food in another bag:
|        /call SwapItem "Bristlebanes Party Platter" ${FindItem[halas 10lb meat pie].InvSlot}
| 
|======================================================================================================================
|  Cast: the main subroutine that casts spells or items for you
|     Usage:
|        /call Cast "spellname|itemname|AAname|AA#" [item|alt|gem#] [give up time][s|m] [custom subroutine name] [Number of resist recasts]
|     Examples:
| 
|     To cast Howl of Tashan and mem it in slot 3 if not memmed:
|       /call Cast "Howl of Tashan" gem3
| 
|     To cast Arcane Rune and keep trying for 7 seconds, in case of interrupts.
|       /call Cast "Arcane Rune" gem5 7s
| 
|     To click Grim Aura earring that's in a bag:
|       /call Cast "Shrunken Goblin Skull Earring" item
| 
|     To use AA ability Eldritch Rune:
|       /call Cast "Eldritch Rune" alt
|         or
|       /call Cast "173" alt
| 
|     To call a subroutine that interrupts CH if target gets healed before it lands:
|       /call Cast "Complete Healing" gem1 0 CheckHP
|     Then in your macro have somewhere:
|       Sub CheckHP
|          /if ( ${Target.PctHPs}>=80 ) /call Interrupt
|       /return
| 
| Returns these values:
|----------------------+----------------------------------------------------------------------+
| CAST_CANCELLED       | Spell was cancelled by ducking (either manually or because mob died) |
| CAST_CANNOTSEE       | You can't see your target                                            |
| CAST_IMMUNE          | Target is immune to this spell                                       |
| CAST_INTERRUPTED     | Casting was interrupted and exceeded the given time limit            |
| CAST_INVIS           | You were invis, and noInvis is set to true                           |
| CAST_NOTARGET        | You don't have a target selected for this spell                      |
| CAST_NOTMEMMED       | Spell is not memmed and you gem to mem was not specified             |
| CAST_NOTREADY        | AA ability or spell is not ready yet                                 |
| CAST_OUTOFMANA       | You don't have enough mana for this spell!                           |
| CAST_OUTOFRANGE      | Target is out of range                                               |
| CAST_RESISTED        | Your spell was resisted!                                             |
| CAST_SUCCESS         | Your spell was cast successfully! (yay)                              |
| CAST_UNKNOWNSPELL    | Spell/Item/Ability was not found                                     |
| CAST_NOTHOLD         | Spell woundn't take hold on target                                   | 
|----------------------+----------------------------------------------------------------------+
#Event BeginCast "You begin casting#*#" 
#Event Collapse "Your gate is too unstable, and collapses.#*#" 
#Event FDFail "#1# has fallen to the ground.#*#" 
#Event Fizzle "Your spell fizzles#*#" 
#Event Immune "Your target is immune to changes in its attack speed#*#" 
#Event Immune "Your target is immune to changes in its run speed#*#" 
#Event Immune "Your target cannot be mesmerized#*#" 
#Event Interrupt "Your casting has been interrupted#*#" 
#Event Interrupt "Your spell is interrupted#*#" 
#Event NoHold "Your spell did not take hold#*#" 
#Event NoHold "Your spell would not have taken hold#*#" 
#Event NoHold "You must first target a group member#*#" 
#Event NoHold "Your spell is too powerful for your intended target#*#" 
#Event NoLOS "You cannot see your target.#*#" 
#Event NoMount "#*#You can not summon a mount here.#*#" 
#Event NoTarget "You must first select a target for this spell!#*#" 
#Event NotReady "Spell recast time not yet met.#*#" 
#Event OutOfMana "Insufficient Mana to cast this spell!#*#" 
#Event OutOfRange "Your target is out of range, get closer!#*#" 
#Event Recover "You haven't recovered yet...#*#" 
#Event Recover "Spell recovery time not yet met#*#" 
#Event Resisted "Your target resisted the #1# spell#*#" 
#Event Resisted2 "You resist the #1# spell#*#" 
#Event Standing "You must be standing to cast a spell#*#" 
#Event Stunned "You are stunned#*#" 
#Event Stunned "You can't cast spells while stunned!#*#" 
#Event Stunned "You *CANNOT* cast spells, you have been silenced!#*#"

Sub Cast(spellName,spellType,giveUpValue,mySub,int ResistTotal)
/declare castTime float local
/if (!${Defined[castReturn]}) /declare castReturn string outer CAST_CANCELLED
/call DoCastingEvents
/varset castReturn X
/if (${Me.Invis} && ${noInvis}) /return
/if (${spellType.Equal[item]}) {
  /if (!${FindItem[${spellName}].ID}) /return CAST_UNKNOWNSPELL
  /varset castTime ${FindItem[${spellName}].CastTime}
} else /if (${spellType.Equal[alt]}) {
  /if (!${Me.AltAbilityReady[${spellName}]}) /return CAST_NOTREADY
  /varset castTime ${Me.AltAbility[${spellName}].Spell.CastTime}
} else {
  /if (!${Me.Book[${spellName}]}) /return CAST_UNKNOWNSPELL
  /declare spellID int local ${Me.Book[${Me.Book[${spellName}]}].ID}
  /varset castTime ${Spell[${spellName}].CastTime}
  /if (${Me.CurrentMana}<${Spell[${spellID}].Mana}) /return CAST_OUTOFMANA
}
/if (${castTime}>0.1) {
  /if (${Stick.Status.Equal[ON]}) /stick pause
  /if (${FollowFlag}) /call PauseFunction
  /if (${Me.Moving}) /keypress back
}
/if (!${Defined[spellType]}) /declare spellType string local spell
/if (!${Defined[spellRecastTime1]}) {
  /if (!${Defined[noInterrupt]}) /declare noInterrupt int outer 0
  /declare ResistCounter int outer
  /declare moveBack bool outer false
  /declare selfResist int outer
  /declare selfResistSpell string outer
  /declare giveUpTimer timer outer
  /declare castEndTime timer outer
  /declare refreshTime timer outer
  /declare itemRefreshTime float outer
  /declare i int local
  /declare spellNotHold int outer
  /delay 5
  |---- Spell Gem Slots
  /for i 1 to 12
  /declare spellRecastTime${i} timer outer
  /if (${Me.SpellReady[${i}]}) {
    /varset spellRecastTime${i} 0
  } else {
    /varcalc spellRecastTime${i} 10*${Me.Gem[${i}].RecastTime}
  }
  /next i
  |---- Spell Gem Slots
}
/if (${Defined[giveUpValue]}) /varset giveUpTimer ${giveUpValue}
/if (${Defined[ResistTotal]}) /varset ResistCounter ${ResistTotal}
/varset spellNotHold 0
/varset selfResist 0
:wait_for_stop
/if (${Me.Casting.ID} || ((!${Me.Class.ShortName.Equal[BRD]} && ${Me.Moving}) && ${castTime}>0.1)) {
  /if (${Bool[${mySub}]}) /call ${mySub} ${spellID}
  /goto :wait_for_stop
}
/if (${Window[SpellBookWnd].Open}) /keypress spellbook
/if (${Me.Ducking}) /keypress duck
/if (${spellType.Equal[item]}) /call ItemCast "${spellName}" "${mySub}"
/if (${spellType.Equal[alt]}) /call AltCast "${spellName}" "${mySub}"
/if (${spellType.NotEqual[item]} && ${spellType.NotEqual[alt]}) /call SpellCast "${spellType}" "${spellName}" "${mySub}" "${spellID}" "${giveUpValue}"
/if (${Stick.Status.Equal[PAUSED]}) /squelch /stick unpause
/if (${PauseFlag}) /call PauseFunction
/varset giveUpTimer 0
/varset ResistCounter 0
/return ${castReturn}

Sub SpellCast(spellType,spellName,mySub,int spellID,giveUpValue)
:cast_spell
/if (!${Me.Gem[${spellName}]}) {
  /if (${Cursor.ID}) /call ClearCursor
  /if (${spellType.Left[3].Equal[gem]}) {
    /if (${spellType.Length}==4) /memspell ${spellType.Right[1]} "${spellName}"
    /if (${spellType.Length}==5) /memspell ${spellType.Right[2]} "${spellName}"
  } else {
    /return CAST_NOTMEMMED
  }
  /if (${Bool[${mySub}]}) /call ${mySub} ${spellID}
  /delay 6s ${Me.Gem[${spellName}]}
  /if (${Me.Gem[${spellName}]}) /varcalc spellRecastTime${Me.Gem[${spellName}]} 10*${Spell[${spellID}].RecastTime}
  /if (!${Me.Gem[${spellName}]}) /return CAST_INTERRUPTED
  :wait_for_mem
  /if (${Bool[${mySub}]}) /call ${mySub} ${spellID}
  /delay 21s ${Me.SpellReady[${spellName}]}
  /if (!${Me.SpellReady[${spellName}]}) {
    /if (${giveUpTimer}) /goto :wait_for_mem
    /return CAST_NOTREADY
  }
}
/varset spellType spell
/if (${spellName.Find[illusion: ]} && ${Me.AltAbilityReady[project illusion]}) /call Cast "project illusion" alt
/varset giveUpTimer ${giveUpValue}
/declare recoverWaitTime timer local 30
:cast_spell_loop
/if (!${Me.SpellReady[${spellName}]} && (${spellRecastTime${Me.Gem[${spellName}]}}<${giveUpTimer} || ${refreshTime}>0 || ${castReturn.Equal[CAST_RESISTED]})) {
  /if (${Bool[${mySub}]}) /call ${mySub} ${spellID}
  /goto :cast_spell_loop
} else {
  /if (!${Me.SpellReady[${spellName}]} && !${castReturn.Equal[CAST_RESISTED]}) /return CAST_NOTREADY
}
/cast "${spellName}"
/if (${Me.Casting.ID}) {
  /varset spellID ${Me.Casting.ID}
  /varcalc castEndTime ${Me.Casting.CastTime}*10
  /if (${castEndTime}<${Math.Calc[${Me.Casting.CastTime}*5]}) /varcalc castEndTime ${Me.Casting.CastTime}*5
}
/varset moveBack false
/call WaitCast ${mySub} ${spellID}
/if (${moveBack}) {
  /keypress back hold
  /delay 4
  /keypress back
  /delay 15 !${Me.Moving}
}
/if (${castReturn.Equal[CAST_CANCELLED]}) /return CAST_CANCELLED
/call DoCastingEvents
/if (!${castReturn.Equal[CAST_SUCCESS]}) {
  /if (${castReturn.Equal[CAST_RECOVER]}) {
    /if (!${recoverWaitTime}) {
      /varcalc spellRecastTime${Me.Gem[${spellName}]} 10*${Spell[${spellID}].RecastTime}
      /if (!${giveUpTimer}) /return CAST_NOTREADY
    }
    /goto :cast_spell_loop
  }
  /if (${castReturn.Equal[CAST_RESTART]} || ${castReturn.Equal[CAST_STUNNED]} || ${castReturn.Equal[CAST_FIZZLE]} || ${castReturn.Equal[CAST_COLLAPSE]} || (${castReturn.Equal[CAST_INTERRUPTED]} && ${giveUpTimer}) || (${castReturn.Equal[CAST_RESISTED]} && ${ResistCounter})) /goto :cast_spell_loop
}
/if (!${castReturn.Equal[CAST_CANNOTSEE]} && !${castReturn.Equal[CAST_OUTOFRANGE]} && !${castReturn.Equal[CAST_OUTOFMANA]} && !${castReturn.Equal[CAST_NOTARGET]} && !${castReturn.Equal[CAST_INTERRUPTED]}) {
  /varcalc refreshTime 10*${Spell[${spellID}].RecoveryTime}
  /varcalc spellRecastTime${Me.Gem[${spellName}]} 10*${Spell[${spellID}].RecastTime}
}
/return

Sub ItemCast(spellName,mySub)
/declare charges int local
/declare oldItemName string local
/declare slotName string local
/declare swapItemBack 		bool 	local 	FALSE
/declare needSwap		bool 	local 	FALSE
/declare itemInBag		bool 	local 	FALSE
/declare eqLoop			int 	local 	0
/declare equippedArray[33]	string 	local

	/varset equippedArray[1] head
	/varset equippedArray[2] face
	/varset equippedArray[3] neck
	/varset equippedArray[4] rightear
	/varset equippedArray[5] leftear
	/varset equippedArray[6] arms
	/varset equippedArray[7] hands
	/varset equippedArray[8] rightwrist
	/varset equippedArray[9] leftwrist
	/varset equippedArray[10] rightfinger
	/varset equippedArray[11] leftfinger
	/varset equippedArray[12] shoulder
	/varset equippedArray[13] back
	/varset equippedArray[14] chest
	/varset equippedArray[15] waist
	/varset equippedArray[16] legs
	/varset equippedArray[17] feet
	/varset equippedArray[18] mainhand
	/varset equippedArray[19] offhand
	/varset equippedArray[20] ranged
	/varset equippedArray[21] ammo
	/varset equippedArray[22] charm
	/varset equippedArray[23] powersource
	/varset equippedArray[24] pack1
	/varset equippedArray[25] pack2
	/varset equippedArray[26] pack3
	/varset equippedArray[27] pack4
	/varset equippedArray[28] pack5
	/varset equippedArray[29] pack6
	/varset equippedArray[30] pack7
	/varset equippedArray[31] pack8
	/varset equippedArray[32] pack9
	/varset equippedArray[33] pack10
	
:cast_item
/varset itemInBag TRUE
/varset needSwap FALSE
/varset swapItemBack FALSE

/for eqLoop 1 to 33
     /if (${Me.Inventory[${equippedArray[${eqLoop}]}].ID}==${FindItem[${spellName}].ID} && !${Me.Inventory[${equippedArray[${eqLoop}]}].Container}) {
	 /varset itemInBag FALSE
	 /varset slotName ${equippedArray[${eqLoop}]}
	 /if (${eqLoop}>23 && ${FindItem[${spellName}].WornSlot[1]} && ${FindItem[${spellName}].EffectType.Find[worn]}) {
             /varset slotName ${FindItem[${spellName}].WornSlot[1].Name}
             /varset swapItemBack TRUE
	     /varset needSwap TRUE
         }
     }
/next eqLoop

/if (${itemInBag}) {
  /if (${FindItem[${spellName}].WornSlot[1]} && ${FindItem[${spellName}].EffectType.Find[worn]}) {
    /varset slotName ${FindItem[${spellName}].WornSlot[1].Name}
    } else {
	/varset slotName pack8
    }
	/varset swapItemBack TRUE
	/varset needSwap TRUE
}

/if (${needSwap}) {
	/varset oldItemName ${Me.Inventory[${slotName}].Name}
  /call SwapItem "${spellName}" ${slotName}
}
:wait_item_loop
/if (${itemRefreshTime}>${MacroQuest.Running}) /goto :wait_item_loop
/varset itemRefreshTime ${Math.Calc[${MacroQuest.Running}+000]}
/varset charges ${FindItem[${spellName}].Charges}
/nomodkey /cast item "${spellName}"
/if (${Me.Casting.ID}) /varcalc castEndTime ${FindItem[${spellName}].CastTime}*10
/delay 1s ${FindItem[${spellName}].Charges}!=${charges}
/call WaitCast ${mySub}
/if (${FindItem[${spellName}].CastTime}<0.5) /delay 5
/if (${swapItemBack} && ${FindItem[${oldItemName}].ID}) /call SwapItem "${oldItemName}" ${slotName}
/if (${castReturn.Equal[CAST_CANCELLED]}) /return CAST_CANCELLED
/call DoCastingEvents
/if (${castReturn.Equal[CAST_RESTART]} || ${castReturn.Equal[CAST_STUNNED]} || (${castReturn.Equal[CAST_INTERRUPTED]} && ${giveUpTimer}) || ${castReturn.Equal[CAST_COLLAPSE]} || (${castReturn.Equal[CAST_RESISTED]} && ${ResistCounter})) /goto :cast_item
/return

Sub AltCast(spellName,mySub)
:cast_alt
/varset castReturn X
/nomodkey /alt activate ${Me.AltAbility[${spellName}].ID}
/delay 5 ${Me.Casting.ID}
/call WaitCast ${mySub}
/if (${castReturn.Equal[CAST_CANCELLED]}) /return CAST_CANCELLED
/call DoCastingEvents
/if (${castReturn.Equal[CAST_RESTART]} || ${castReturn.Equal[CAST_STUNNED]} || (${castReturn.Equal[CAST_INTERRUPTED]} && ${giveUpTimer}) || (${castReturn.Equal[CAST_RESISTED]} && ${ResistCounter})) /goto :cast_alt
/return

Sub ClearCursor
/declare i int local
:auto_inv
/if (${Cursor.ID}) {
  /if (${Cursor.Container}) {
    |---- Inventory Bag Slots
    /for i 1 to 10    
    /if (!${InvSlot[pack${i}].Item.Container}) /nomodkey /itemnotify pack${i} leftmouseup
    /next i
    |---- Inventory Bag Slots    
  } else {
    /timed 5 /autoinventory
  }
  /goto :auto_inv
}
/return

Sub DoCastingEvents
/doevents Recover
/doevents BeginCast
/doevents Fizzle
/doevents Interrupt
/doevents Standing
/doevents FDFail
/doevents OutOfRange
/doevents OutOfMana
/doevents NoLOS
/doevents Resisted2
/doevents Resisted
/doevents Immune
/doevents Stunned
/doevents Collapse
/doevents NoTarget
/doevents NotReady
/doevents NoHold
/return

Sub EquipItem(WhatWhere)
/declare DestName string local
/declare ItemName string local ${WhatWhere.Arg[1,|]}
/declare SlotName string local ${WhatWhere.Arg[2,|]}
/if (${SlotName.Equal[NULL]}) /varset SlotName ${InvSlot[${FindItem[=${ItemName}].WornSlot[1]}].Name}
/if (${FindItem[=${ItemName}].InvSlot}<23 || !${FindItem[=${ItemName}].WornSlot[${SlotName}]}) /return
/if (!${InvSlot[${SlotName}].Item.Name.Equal[NULL]}) /varset DestName "${InvSlot[${SlotName}].Item.Name}|${SlotName}"
/call SwapItem "${ItemName}" "${SlotName}"
/return ${DestName}

Sub Interrupt
/if (${Me.Mount.ID}) /dismount
/stopcast
/if (${Defined[castReturn]}) /varset castReturn CAST_CANCELLED
/return ${castReturn}

Sub SwapItem(itemName,slotName)
/declare i int local
/if (${Cursor.ID}) /call ClearCursor
/exchange "${itemName}" ${slotName}
|/delay 5s ${InvSlot[${slotName}].Item.Name.Equal[${itemName}]}
/delay 5s ${Me.Inventory[${slotName}].Name.Equal[${itemName}]}
/if (${Cursor.ID}) /call ClearCursor
/return

Sub WaitCast(mySub,int spellID)
/declare currentTarget int local ${Target.ID}
/declare currentTargetType string local ${Target.Type}
:wait_cast_loop
/if (${Bool[${mySub}]}) /call ${mySub} ${spellID}
/if (${Me.Casting.ID}) {
  /if (${currentTarget} && !${Spawn[${currentTarget}].Type.Equal[${currentTargetType}]}) {
    /if (!${Me.Casting.TargetType.Equal[PB AE]} && !${Me.Casting.TargetType.Equal[self]} && !${moveBack} && (!${Me.Mount.ID} || !${noInterrupt})) {
      /if (!${Me.Mount.ID} || ${castEndTime}>70) {
        /call Interrupt
      } else /if (${Me.Casting.RecastTime}>3) {
        /varset castReturn CAST_CANCELLED
        /keypress forward hold
        /delay 6
        /keypress forward
        /varset moveBack true
      }
    }
  }
  /if (${Me.State.Equal[DUCK]}) /varset castReturn CAST_CANCELLED
  /goto :wait_cast_loop
}
/return

Sub Event_BeginCast
/if (${Defined[castReturn]}) /varset castReturn CAST_SUCCESS
/return

Sub Event_Collapse
/if (${Defined[castReturn]}) /varset castReturn CAST_COLLAPSE
/varset giveUpTimer 200
/return

Sub Event_FDFail(line,name)
/if (${name.Equal[${Me.Name}]} && ${Defined[castReturn]}) {
  /if (!${Me.Standing}) /stand
  /varset castReturn CAST_RESTART
}
/return

Sub Event_Fizzle
/if (${Defined[castReturn]}) /varset castReturn CAST_FIZZLE
/return

Sub Event_Immune
/if (${Defined[castReturn]}) /varset castReturn CAST_IMMUNE
/return

Sub Event_Interrupt
/if (${Defined[castReturn]}) /varset castReturn CAST_INTERRUPTED
/return

Sub Event_NoHold
/if (${Defined[spellNotHold]}) /varset spellNotHold 1
/if (${Defined[castReturn]}) /varset castReturn CAST_NOTHOLD
/return

Sub Event_NoLOS
/if (${Defined[castReturn]}) /varset castReturn CAST_CANNOTSEE
/return

Sub Event_NoMount 
/if (${Defined[castReturn]}) /varset castReturn CAST_NOMOUNT 
/return 

Sub Event_NoTarget
/if (${Defined[castReturn]}) /varset castReturn CAST_NOTARGET
/return

Sub Event_NotReady
/if (${Defined[castReturn]}) /varset castReturn CAST_NOTREADY
/return

Sub Event_OutOfMana
/if (${Defined[castReturn]}) /varset castReturn CAST_OUTOFMANA
/return

Sub Event_OutOfRange
/if (${Defined[castReturn]}) /varset castReturn CAST_OUTOFRANGE
/return

Sub Event_Recover
/if (${Defined[castReturn]}) /varset castReturn CAST_RECOVER
/return

Sub Event_Resisted(line,name)
/if (${selfResist} && ${name.Equal[${selfResistSpell}]}) /varset selfResist 0
/if (${ResistCounter}) /varcalc ResistCounter ${ResistCounter}-1
/if (${Defined[castReturn]}) /varset castReturn CAST_RESISTED
/return

Sub Event_Resisted2(line,name)
/if (${Defined[selfResist]}) {
  /varset selfResist 1
  /varset selfResistSpell ${name}
}
/return

Sub Event_Standing
/stand
/if (${Defined[castReturn]}) /varset castReturn CAST_RESTART
/return

Sub Event_Stunned
/if (${Me.Stunned}) {
  /delay 3s !${Me.Stunned}
} else {
  /delay 7
}
/if (${Defined[castReturn]}) /varset castReturn CAST_STUNNED
/return
 
Sorry Bro,

I played with you macro but I just couldn't follow the logic. I was getting a lot of weirdness and it quit after like 2 skillups and I couldn't figure out where it was failing.

I liked a lot of the code in it though compared to other trainers. I am whipping up a new spell casting skillup macro a little more basic yours than but based on a lot of your code. I will post it in a day or 2.
 
yep, that's what's happening to me, except when I cut out that one section of code, then it works, when I add the extra delay it works even better...
 
yep, that's what's happening to me, except when I cut out that one section of code, then it works, when I add the extra delay it works even better...

I just rewrote the macro using a lot of the same code. Its at the top of this forum if you wan to try it as well.
 
Skillup casting

Users who are viewing this thread

Back
Top
Cart