Page 1 of 4

Shell.mac ((DISCONTINUED))

Posted: Sun Jun 03, 2007 11:39 am
by jacensolo
** This code is no longer being actively tested by me. I recently donated, and as has been pointed out to me many times, the VIP plugins do most of things this script was written for, and they do it both better and independently. I highly recommend donating to anyone who uses MQ2. As for this script, if someone submits an update and I get confirmation that it works, I'll update this post with the new code, but as this code is rendered nearly useless by the many wonderful plugins in VIP, I will no longer be editting it. **




This is the first beta release of my Shell.mac. Basically, the Shell macro is a macro designed to incorporate many other scripts into one, and to allow customization of scripts for different characters. The Shell is currently set up to run all the provided scripts, though some are currently untested. If anyone wants more scripts added, feel free to add to the macro yourself, or post a request here and I'll see what I can do. Also posted is a sample INI file with basic information to make the macro run.

EDIT: 6/3/07 Fixed a few more parts, added spelltrain.inc to post, had missed it last time.

EDIT: 6/3/07 Thanks to Shin Noir, added the code for Frenzy to INI and skills.inc.

EDIT: 6/4/07 Fixed memspell script to work for 9th spell gem.
Features.txt:
6/3/2007 Beta Version 1.1

Written primarily by Jacen Solo, with some scripts borrowed from others. Code from others is marked as such in it's file. (If you wrote code which I have used and I failed to credit you, please tell me so I can fix it.)

NOTE: I am currently working on fixing up these scripts to work with shell.mac. They are included, and don't stop other functions from running currently.
Also, "Untested" is literal. Some might work perfectly as is, but I haven't tested them enough yet to be able to confidently say they work.

Untested Scripts:
* Assist
* Camp
* Chat
* Drag
* Lang

Untested Features:
* Storing your main and secondary assist's names. Allows use of /assistma and /assistsa, letting you change assists without modding scripts or hotbuttons.
* Watching for specific mobs to spawn. If the specified mob spawns, it beeps, and stores its spawn time in an INI. It also moniters despawns of the specified mob. This can be used to map mob spawn cycles.
* Dragging of an unlimited number of corpses.
* Language script with 3 modes. Spam (spams "a" in gsay), Teach (spams "a" in gsay, auto moves to next language after so many repetitions), and Lang, which accepts the correct tell, invites the sender, spams "a", auto changes to next language, and disbands when done.
* Watch specific chat channels and run commands when chat is recieved.

Untested Commands:
* /ma PlayerName --- Sets PlayerName as your main assist. For use with /assistma.
* /targma --- Sets your current target as your main assist. For use with /assistma.
* /assistma --- Targets whatever your current main assist is targetting.
* /sa PlayerName --- Sets PlayerName as your secondary assist. For use with /assistsa.
* /targsa --- Sets your current target as your secondary assist. For use with /assistsa.
* /assistsa --- Targets whatever your current secondary assist is targetting.
* /campadd MobName --- Adds MobName to the spawn watch list for the zone you are in.
* /drag --- With no parameter, drags your target's corpse until you don't have a target.
* /drag Name1 Name2 Name3 --- With parameters, drags an unlimited number of corpses until you target yourself.
* /spam --- Begins spam of "a" in main chat window. Stops when you target yourself.
* /teach --- Begins spam and automatic cycling of languages. Skips to next language if you target yourself.
* /lang --- Begins language autorun. Accepts tells saying "Teach Me." and invites sender. When sender accepts, spams and cycles languages. When done, disbands. Also accepts tells saying "Teach More LangNumberHere", sends invite, then runs extra repetitions of that language.

Tested Scripts:
* Clickies
* Combine
* Drunk
* EXPTrack
* Farm
* FeedMe
* Fish
* MemSpell
* SelfBuff
* Skills
* Spells
* SpellTrain

Tested Features:
* Automatic refresh of clickies.
* Alcohol Tolerance maxxing tool which uses Brell's Fishing Pole.
* EXP and AA tracker. Stores variables with EXP and AA gain per minute and estimated time till ding or ping. Variables can be displayed in a HUD.
* Drop farmer. Tracks and kills mobs matching the given parameter, looting items which match the table in the INI.
* Fishing script which uses Hargar's Brand Fishing Pail and Fisherman's Companion. Has INI support, and can maintain FD.
* Spell set loader with INI support.
* Automatic refresh of self buffs.
* Skill Routines script for automatically using skills.
* Spell Routines for use in other scripts
* Spell skill trainer, maxes skills for spells you have memmed.
* Loads HUD parts.
* Loads other settings.
* Basic tradeskilling combine/autoinventory script.
* Force feeding tool to conserve stat food.

Tested Commands:
* /clickies --- Toggles automatic clickie refresh
* /drunk --- Starts alcohol tolerance skillup script. Requires Brell's Fishin' Pole in a base level inventory slot.
* /farm MobName --- Kills npcs matching MobName, and loots stuff which matches INI loottable.
* /fish --- Begins fishing script. Requires Hargar Brand Fishing Pail and Fisherman's Companion.
* /memset SetName --- Loads spell set SetName from INI into gems.
* /selfbuff --- Toggles automatic self buffing.
* /spelltrain --- Practices memmed spells until that spells skill is maxed.
* /comb X --- clicks combine X times, autoinventories results, and stops if you run out of material.
* /feedme --- Toggles automatic force feeding.
* /done --- This exits scripts where the correct piece of code is added, returning to the idle loop.
Sample.ini

Code: Select all

** Note: You must remove these comments to make the INI work.

** Name your INI with your character's name. So if your character was named Platpharmer Tosellit, your INI would be Platpharmer.ini

[Setup]
** These are the subs which are called at the start of the macro. Mostly, they set variables and aliases. Remove them to disable those parts.
1=AssistPrep
2=CampPrep
3=ClickiePrep
4=CombinePrep
5=DragPrep
6=DrunkPrep
7=ExpPrep
8=FarmPrep
9=FeedMePrep
10=FishPrep
11=LangPrep
12=MemspellPrep
13=SelfBuffPrep
14=SpellTrainPrep

[Auto]
** These are the subs called on every Idle cycle and everywhere that a macro calls "/call Run". Remove them to disable that script.
1=CampCheck
2=Clickies
3=ExpTrack
4=FeedMe
5=SelfBuff
6=Skill_Routines

[HUD]
** These are the autoloaded HUD parts. Each one is loaded at the start of the macro.
1=Stats
2=Me
3=Pet
4=Target
5=TargetofTarget
6=Group
7=Veterans
8=Spawns
9=Tribute
10=Exp
11=Spells
12=Buffs
13=SDBuffs

[Food]
** These are the foods used by FeedMe.inc
Food1=Ration
Food2=Iron Ration

[Drink]
** These are the drinks used by FeedMe.inc
Drink1=Water Flask
Drink2=Bottle of Milk

[Clickies]
** These are the clickies with are refreshed by clickies.inc
1=Journeyman's Boots
2=Fabled Goblin Skull Earring
3=Eyepatch of Plunder

[SelfBuffs]
**These are the selfbuffs which are refreshed by selfbuff.inc. BuffGem is the gem where the spells are loaded if not already up.
BuffGem=5
1=Shroud of Death
2=Shadow Sight

[Skills]
** Used by skills.inc. These are the auto-used skills.
Backstab=FALSE
Bash=TRUE
Begging=TRUE
Disarm=TRUE
Evade=FALSE
FeignDeath=FALSE
FlyingKick=FALSE
Forage=FALSE
Frenzy=FALSE
Intimidation=FALSE
Kick=FALSE
Mend=FALSE
PickPockets=FALSE
SenseTraps=FALSE
Slam=FALSE
Taunt=TRUE
HitBox=15

[Settings]
** These are the settings which are loaded at the beginning of the macro. Useful to use instead of a config file.
1=/declare textgauge global
2=/varset textgauge ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3=/mapnames normal [%l %c] %N
4=/mapnames target [%l %c] %N - %h%%

[Chat]
** Used by chat.inc. These set what to watch and how to respond.
1=tell|NULL|/beep

[Spell:59]
** This is a spell set for memspell.inc.
Spell1=Drain Spirit
Spell2=Spear of Plague
Spell3=Dooming Darkness
Spell4=Torrent of Pain
Spell5=Torrent of Hate
Spell6=Shroud of Death
Spell7=Gather Shadows
Spell8=Feign Death

[LootTable]
** This is a loot table for farm.inc. Note: You do not need to add things to it manually. It stores names here, defaulting to loot. You can change to Destroy if you want.
High Quality Lion Skin=Loot
High Quality Cat Pelt=Loot
Spider Silk=Loot
Medium Quality Lion Skin=Destroy
Ruined Lion Skin=Destroy
Medium Quality Cat Pelt=Loot
Chunk of Meat=Destroy
Ruined Cat Pelt=Destroy
Lion Meat=Destroy

[The Plane of Knowledge Fishing]
** This is the looting table for fish.inc. Note: This table is autogenerated as loot is found. It defaults to loot, but you can set things to Destroy or Drop if you want.
Rusty Dagger=Destroy
Fish Scales=Destroy
Fresh Fish=Loot
Shell.mac:

Code: Select all

| Shell.mac
| Written by Jacen Solo
| 6/3/07 Beta Version 1.0

#include assist.inc
#include camp.inc
#include chat.inc
#include clickies.inc
#include combine.inc
#include drag.inc
#include drunk.inc
#include exptrack.inc
#include farm.inc
#include feedme.inc
#include fish.inc
#include lang.inc
#include memspell.inc
#include selfbuff.inc
#include skills.inc
#include spells.inc
#include spelltrain.inc

#define DEBUG /squelch /echo
#event return "[MQ2] End Script."

Sub Main
   /if (${Ini[${Me.CleanName}.ini].Equal[NULL]}) {
      /echo No INI file for  ${Me.CleanName}.
      /echo Instructions for setting up an INI can be found in the ReadMe.
      /endmacro
   }
   /call Load HUD
   /call Load Settings
   /call Load Setup
   /squelch /alias /done /echo End Script.
   :loop
   /call Run
   /doevents
   /goto :loop
/return

Sub Load
   /declare run int
   /for run 1 to ${Math.Calc[${Ini[${Me.CleanName}.ini,${Param0}].Count[|]}-1]}
      /squelch /docommand ${If[${Param0.Equal[Setup]},/call ,${If[${Param0.Equal[HUD]},/loadhud ,]}]}${Ini[${Me.CleanName}.ini,${Param0},${run}]}
   /next run
/return

Sub Run
   /declare run int
   /doevents
   /for run 1 to ${Math.Calc[${Ini[${Me.CleanName}.ini,Auto].Count[|]}-1]}
      /call ${Ini[${Me.CleanName}.ini,Auto,${run}]}
   /next run
/return

Sub Event_return
/return DONE
assist.inc

Code: Select all

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assist.inc
| Written by Jacen Solo
|
| Allows you to set a main and secondary assist on the fly, rather than changing hotkeys every time.
| Use /ma PlayerName or /sa PlayerName to set PlayerName as your main or secondary assist.
| Or use /targma or /targsa to set your current target as your main or secondary assist.
| Then you can use /assistma and /assistsa either by typing or in a hotkey to assist your set MA and SA.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event setAssist "[MQ2] Set #1#: #2#"

Sub AssistPrep
   /squelch /alias /ma /echo Set MA:
   /squelch /noparse /alias /assistma /assist ${MAName}
   /squelch /alias /sa /echo Set SA:
   /squelch /noparse /alias /assistsa /assist ${SAName}
   /squelch /noparse /alias /targma /echo Set MA: ${Target.CleanName}
   /squelch /noparse /alias /targsa /echo Set SA: ${Target.CleanName}
   /declare MAName outer
   /declare SAName outer
/return

Sub Event_setAssist
   /varset ${Param1}Name ${Param2}
/return
camp.inc

Code: Select all

| camp.inc
| #Originally Created by Shin Noir as Track.mac.#
| Modified heavily by Jacen Solo for efficiency use with shell.mac
| Use /campadd MobName to add MobName to the tracking list for your current zone.



#event campadd "[MQ2] Add Spawn: #1#"

Sub CampPrep
   /squelch /alias /campadd /echo Add Spawn:
/return

Sub Event_campadd

 | Blocks against adding the same mob twice for the same zone.
   /declare x int
   /if (${Ini[${Me.CleanName}.ini,${Zone.Name} List].Count[|]}==0) /goto :checkskip
   /for x 1 to ${Ini[${Me.CleanName}.ini,${Zone.Name} List].Count[|]}-1
      /if (${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}].Equal[${Param1}]}) {
         /echo Mob Already Listed
         /return
      }
   /next x
   :checkskip

 | Adds the mob to the Zone's List, adds the current spawn count to the Zone's Counts, adds a date/time stamp of their name and starting spawn count to that Zone's Camp file.
   /ini "${Me.CleanName}.ini" "${Zone.Name} List" "${If[${Ini[${Me.CleanName}.ini,${Zone.Name} List].Count[|]}==0,1,${Ini[${Me.CleanName}.ini,${Zone.Name} List].Count[|]}]}" "${Param1}"
   /ini "${Me.CleanName}.ini" "${Zone.Name} Counts" "${If[${Ini[${Me.CleanName}.ini,${Zone.Name} Counts].Count[|]}==0,1,${Ini[${Me.CleanName}.ini,${Zone.Name} Counts].Count[|]}]}" "${SpawnCount[npc ${Param1}]}"
   /ini "${Me.CleanName}.ini" "${Zone.Name}" "${If[${Ini[${Me.CleanName}.ini,${Zone.Name} Camp].Count[|]}==0,1,${Ini[${Me.CleanName}.ini,${Zone.Name} Camp].Count[|]}]}" "${Time.Date},${Time.Time24} : ${Param1}'s Count Started At ${SpawnCount[npc ${Param1}]}"
   /echo ${Param1} Added.
/return

Sub CampCheck

 | If no mobs are listed for the zone, returns.
   /if (${Ini[${Me.CleanName},${Zone.Name} List].Count[|]}==0) /return

 | Checks each mob to see if the SpawnCount has changed from the one listed in the Zone's Counts list. If it has, it adds a date/time stamp with the mob's name and its new spawn count to the Zone's Camp list and changes the Count list to the new value. It also echo's the new information.
   /declare x int
   /for x 1 to ${Ini[${Me.CleanName}.ini,${Zone.Name} List].Count[|]}-1
      /if (${SpawnCount[npc ${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}]}]}!=${Ini[${Me.CleanName}.ini,${Zone.Name} Counts,${x}]}) {
         /ini "${Me.CleanName}.ini" "${Zone.Name} Camp" "${Ini[${Me.CleanName}.ini,${Zone.Name} Camp].Count[|]}" "${Time.Date},${Time.Time24} : ${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}]}'s Count Became ${SpawnCount[npc ${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}]}]}"
         /ini "${Me.CleanName}.ini" "${Zone.Name} Counts" "${x}" "${SpawnCount[npc ${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}]}]}"
         /echo ${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}]}'s Count Became ${SpawnCount[npc ${Ini[${Me.CleanName}.ini,${Zone.Name} List,${x}]}]}
      }
   /next x
/return
chat.inc

Code: Select all

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chat.inc
| Written by Jacen Solo
|
| Monitors the listed chat channels and does an action specified in the INI if a channel/text match is found.
| The information for this script should be placed in your character's INI under a section called "Chat".
| Proper format for the INI entry is Number=ChannelName|Text|Response
| Where Number is the next number in the list, ChannelName is the channel you want to watch, Text is 
| what you want to look for or is blank, and Response is the command you want to execute if there is a match.
|
| Examples: 
|  1=tell||/beep (This would beep when a tell was received)
|  2=say|virtue|/echo ${Sender} wants virtue
|
| NOTE: If you want to monitor a channel, it must be added below as #chat ChannelToWatch, otherwise the script won't look at it.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#chat tell
#chat say

Sub Event_Chat(Channel,Sender,Text)
   /declare x int
   /for x 1 to ${Ini[${Me.CleanName}.ini,Chat].Count[|]}-1
      /if (${Channel.Equal[${Ini[${Me.CleanName}.ini,Chat,${x}].Token[1,|]}]}) {
         /if (${Text.Find[${Ini[${Me.CleanName}.ini,Chat,${x}].Token[2,|]}]} || ${Ini[${Me.CleanName}.ini,Chat,${x}].Token[2,|].Equal[NULL]}) {
            /docommand ${Ini[${Me.CleanName}.ini,Chat,${x}].Token[3,|]}
         }
      }
   /next x
/return
clickies.inc

Code: Select all

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| clickies.inc
| Written by Jacen Solo
|
| Self buffs with the clickies listed in YourName.ini. Toggle clickie refresh with /clickies.
| List your clickies in a [Clickies] section in your INI, with each clickie in numerically ordered keys.
| Like this:
|	[Clickies]
|	1=Ring of Teh Ownage
|	2=Sword of Noobage
|	3=Boots of Mob Kicking
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event toggleclickies "[MQ2] Toggle Clickie Refresh."

Sub ClickiePrep
   /declare clickies int outer 0
   /squelch /noparse /alias /clickies /echo Toggle Clickie Refresh.
/return

Sub Event_toggleclickies
   /varset clickies ${If[${clickies},0,1]}
   /echo Automatic Clickie Refresh ${If[${clickies},ON,OFF]}
/return

Sub Clickies
   /if (!${clickies}) /return
   /declare x int 0
   /declare oldtarg int 0
   /varset oldtarg ${Target.ID}
   /declare oldstatus int 0
   /if (${Me.Sitting}) /varset oldstatus 1
   /if (${Me.Combat}) /varset oldstatus 2
   /for x 1 to ${Math.Calc[${Ini[${Me.CleanName}.ini,Clickies].Count[|]}-1]}
      /if (!${FindItemCount[${Ini[${Me.CleanName}.ini,Clickies,${x}]}]}) /goto :next
      /if (${Me.Buff[${FindItem[${Ini[${Me.CleanName}.ini,Clickies,${x}]}].Spell.Name}].ID}) /goto :next
      /target me
      /attack off
      /call Cast "${Ini[${Me.CleanName}.ini,Clickies,${x}]}" item
      :next
   /next x
   /squelch /target clear
   /if (${oldtarg}) /target id ${oldtarg}
   /if (${oldstatus}==1 && ${Me.Standing}) /sit
   /if (${oldstatus}==2 && !${Me.Combat}) /attack
/return
combine.inc

Code: Select all

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| combine.inc
| Written by Jacen Solo
|
| Use "/comb Number" to do Number combines. Stops when that many are done or when you run out of materials.
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event Combine "[MQ2] Start Combine: #1#"
#event comb_check "You lacked#*#"
#event comb_check "You have fashioned#*#"
#event comb_lack "You are missing#*#"

Sub CombinePrep
   /squelch /alias /comb /echo Start Combine:
/return

Sub Event_Combine(line,int combines)
   /if (!${Defined[comb_check]}) /declare comb_check int outer
   /varset comb_check 0
   /declare x int 0
   :Loop
   /call Run
   /doevents return
   /if (${Macro.Return.Equal[Done]}) /return RESET
   /if (${Window[TradeskillWnd].Child[CombineButton].Enabled}) /notify TradeskillWnd CombineButton leftmouseup
   /if (${Cursor.ID}) {
      /autoinventory
      /delay 5
      /goto :Loop
   }
   /doevents
   /if (${comb_check}==1) {
      /varcalc x ${x}+1
      /varset comb_check 0
   }
   /if (${Macro.Return.Equal[RETURN]}) /return
   /autoinventory
   /if (${x}<${combines}) /goto :Loop
   /autoinventory
   /beep
/return

Sub Event_comb_check
   /varset comb_check 1
/return

Sub Event_comb_lack
/return RETURN
drag.inc

Code: Select all

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Corpse Dragging Script
|
| Written by Diggler, updated by Dirx
| Updated, modified, and shredded by Jacen Solo for use with my shell macro.
| Use "/drag Name1 Name2 Name3" to drag all named corpses, or "/drag" to drag your target.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event Drag "[MQ2] Drag corpses: #1#"

Sub DragPrep
   /squelch /alias /drag /echo Drag corpses:
/return

Sub Event_Drag
   /declare ParamCount int
   /declare ParamString
   /declare MaxParam int -1

   /if (!${Defined[Param0]}) {
      /if (${Target.State.Equal[DEAD]}) {
         :loop3
         /cor
         /delay 1
         /if (${Target.ID}) /goto :loop3
         /return
      }

   :loop
   /if (${Defined[Param${ParamCount}]}) {
      /varcalc MaxParam ${MaxParam}+1
      /varcalc ParamCount ${ParamCount}+1
      /goto :loop
   }

   :loop2
   /for ParamCount 0 to ${MaxParam}
      /if (${Target.ID}==${Me.ID}) /return
      /squelch /tar ${Param${ParamCount}}'s
      /cor
      /delay 1
   /next ParamCount
   /goto :loop2
/return
drunk.inc

Code: Select all

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| drunk.inc
| Written by Jacen Solo
|
| Raise Alcohol Tolerance
| Uses Brell's Fishin' Pole. Just put it in a base inventory slot or equip it, and run the script. Will stop at max skill.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event Drunk "[MQ2] Start Drinking!"

Sub DrunkPrep
   /squelch /alias /drunk /echo Start Drinking!
/return

Sub Event_Drunk
   :Start
   /call Run
   /cast item "Brell's fishin' Pole"
   /delay 10s ${Cursor.ID}
   /itemnotify pack8 leftmouseup
   /delay 5
   /itemnotify pack8 rightmouseup
   /delay 5
   /itemnotify pack8 leftmouseup
   /if (${Me.Skill[Alcohol Tolerance]}==${Skill[Alcohol Tolerance].SkillCap}) {
      /beep
      /return
   }
   /doevents return
   /if (${Macro.Return.Equal[DONE]}) /return RESET
   /goto :Start
/return
exptrack.inc

Code: Select all

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Records Exp and AA gain, and estimated time till ding/ping (Designed for use with EXPGain, AAGain, EXPTime, and AATime displayed in HUD)
| To use, add lines in your HUD to display the EXPGain, AAGain, EXPTime, and AATime.
|
| Created by Neolesh
| Updated, modified, and shredded by Jacen Solo for use with my shell macro.
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Sub ExpPrep
   /declare Exper float outer ${Me.PctExp}
   /declare AAExp float outer ${Me.PctAAExp}
   /declare TotalAAExp float outer 0.00
   /declare TotalExp float outer 0.00
   /declare EXPGain float outer 0.00
   /declare AAGain float outer 0.00
   /declare EXPTime float outer 0.00
   /declare AATime float outer 0.00
/return

Sub ExpTrack
   /if (${Me.PctAAExp}>=${AAExp}) {
   /varset AAExp ${Math.Calc[${Me.PctAAExp}-${AAExp}]}
   } else {
   /varset AAExp ${Math.Calc[${Me.PctAAExp}-${AAExp}+100]}
   }
   /if (${Me.PctExp}>=${Exper}) {
   /varset Exper ${Math.Calc[${Me.PctExp}-${Exper}]}
   } else {
   /varset Exper ${Math.Calc[${Me.PctExp}-${Exper}+100]}
   }
   /varcalc TotalAAExp ${TotalAAExp}+${AAExp}
   /varcalc TotalExp ${TotalExp}+${Exper}
   /varset EXPGain ${Math.Calc[${TotalExp}/${Math.Calc[${Macro.RunTime}/60]}]}
   /varset AAGain ${Math.Calc[${TotalAAExp}/${Math.Calc[${Macro.RunTime}/60]}]}
   /if (${TotalExp}==0) {
      /varset EXPTime 0
   } else {
      /varset EXPTime ${Math.Calc[${Math.Calc[${Math.Calc[${Macro.RunTime}/60]}/${TotalExp}]}*${Math.Calc[100-${Me.PctExp}]}]} minutes
   }
   /if (${TotalAAExp}==0) {
      /varset AATime 0
   } else {
      /varset AATime ${Math.Calc[${Math.Calc[${Math.Calc[${Macro.RunTime}/60]}/${TotalAAExp}]}*${Math.Calc[100-${Me.PctAAExp}]}]} minutes
   }
   /varset Exper ${Me.PctExp}
   /varset AAExp ${Me.PctAAExp}
/return
farm.inc

Code: Select all

| farm.inc
| Written by Jacen Solo
|
| Use "/farm MobName" to begin farming. Will hunt anything matching MobName.
| The script builds an INI of loot found in YourName.ini. It defaults to Loot, but you can set items to Destroy.

#define FARMDEBUG /squelch /echo
#event Farm "[MQ2] Start Farming: #1#"

Sub FarmPrep
   /squelch /alias /farm /echo Start Farming:
/return

Sub Event_Farm
   /echo Mob: ${Param1}
   /declare lootslot int 1
   /if (!${Me.AFK}) /afk

   :LoopMain
   /doevents return
   /if (${Macro.Return.Equal[Done]}) /return RESET
   /if (${Me.FreeInventory}==0) /goto :End
   /if (${SpawnCount[gm]}) /goto :End
   /if (${SpawnCount[pc]}>1) /goto :Pause
   /call Run Auto
   /doability Hide
   /if (${Me.PctHPs}<70) {
      /sit
      :LoopMed
      /doevents return
      /delay 5
      /if (${Me.PctHPs}<95 && ${Me.Sitting}) /goto :LoopMed
   }
   /if (${Target.ID}) /goto :LoopMove
   /squelch /target npc ${Param1}
   /delay 5
   /if (!${Target.ID}) /goto :LoopMain

   :LoopMove
   /doevents return
   /if (${Macro.Return.Equal[Done]}) /return RESET
   /face fast nolook
   /if (${Target.Distance}>10) {
      /keypress forward hold
      /goto :LoopMove
   }
   /if (${Me.Speed}) /keypress forward

   :LoopCombat
   /doevents return
   /if (${Macro.Return.Equal[Done]}) /return RESET
   /if (${Target.Distance}<${Math.Calc[${Target.MaxRangeTo}*2]} && !${Me.Combat}) /attack
   /call Skill_Routines
   /if (${Target.ID}) {
      /if (${Target.Distance}<10) {
         /goto :LoopCombat
      } else {
         /goto :LoopMove
      }
   }

   /if (${Me.Speed}) /keypress forward 
   FARMDEBUG Mob is Dead
   /doevents return
   /if (${Macro.Return.Equal[Done]}) /return RESET
   /target corpse ${Param1}
   FARMDEBUG Corpse Targetted
   /face fast nolook
   /click right target
   /delay 10m ${Window[LootWnd].Open}
   /delay 2s
   FARMDEBUG Loot Window Open
   /if (!${Corpse.Items}) {
      FARMDEBUG No Items On Corpse
      /goto :corpsedone
   }
   :cursorloop1
   /itemnotify loot${lootslot} leftmouseup
   /if (!${Cursor.ID}) /goto :cursorloop1
   :lootretry
   FARMDEBUG Checking Item ${lootslot} : ${Cursor.Name}
   /if (${Ini[${Me.CleanName}.ini,LootTable,${Cursor.Name}].Equal[Loot]}) {
      FARMDEBUG Item ${Cursor.Name} Is Set To Loot
      :cursorloop2
      /autoinventory
      /if (${Cursor.ID}) /goto :cursorloop2
   } else /if (${Ini[${Me.CleanName}.ini,LootTable,${Cursor.Name}].Equal[Destroy]}) {
      FARMDEBUG Item ${Cursor.Name} Is Set To Destroy
      :cursorloop3
      /destroy
      /if (${Cursor.ID}) /goto :cursorloop3
   } else {
      FARMDEBUG Item ${Cursor.Name} Is Not Listed
      /ini "${Me.CleanName}.ini" "LootTable" "${Cursor.Name}" "Loot"
      FARMDEBUG ${Cursor.Name} Added.
      /goto :lootretry
   }
   /if (${Corpse.Items}>0) {
      /varcalc lootslot ${lootslot}+1
      /goto :cursorloop1
   }
   :corpsedone
   /varset lootslot 1
   FARMDEBUG Done Checking Loot
   /delay 5
   /notify LootWnd DoneButton leftmouseup
   FARMDEBUG Loot Window Closed
   /delay 10m !${Window[LootWnd].Open}
   /goto :LoopMain

   :Pause
   /doability Hide
   /delay 10000m ${SpawnCount[pc]}<2 || !${Me.AFK} || ${Me.HPs}<60
   /goto :LoopMain

   :End
   /doability Hide
   /camp
   /endmacro
/return

Posted: Sun Jun 03, 2007 11:39 am
by jacensolo
feedme.inc

Code: Select all

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Checks if you are hungry or thirsty, if you are, automatically eats or drinks
|
| Created by A_Druid_00 and modified by onetimehero
| Updated and modified by Jacen Solo for use with my shell macro.
| Use /feedme to toggle Auto Force Feeding.
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event togglefeedme "[MQ2] Toggle Force Feeding."

Sub FeedMePrep
   /declare doFeedMe int outer 1
   /squelch /noparse /alias /feedme /echo Toggle Force Feeding.
/return

Sub Event_togglefeedme
   /varset doFeedMe ${If[${doFeedMe},0,1]}
   /echo Automatic Force Feeding ${If[${doFeedMe},ON,OFF]}
/return

Sub FeedMe
/if (${Me.Casting.ID} || ${Cursor.ID} || !${doFeedMe}) /return
/if (${Me.Hunger}<=5000) /call Consume Food
/if (${Me.Thirst}<=5000) /call Consume Drink
/return

Sub Consume(what)
/declare mypack         string local
/declare myslot         string local
/declare i              int    local
/declare foodcount      int    local
/declare food       string local

/autoinventory
/varset foodcount ${Ini[${Me.CleanName}.ini,${what}].Count[${what}]}
/for i 1 to ${foodcount}
/varset food ${Ini[${Me.CleanName}.ini,${what},${what}${i}]}
/if (${FindItemCount[${food}]}>0) {
  /varset mypack ${FindItem[${food}].InvSlot.Pack}
  /varset myslot ${FindItem[${food}].InvSlot}
  /if (${mypack}) {
    /if (!${Window[${InvSlot[${mypack}].Name}].Open}) /nomodkey /itemnotify ${mypack} rightmouseup
    :WaitForBagOpen
    /nomodkey /ctrl /itemnotify ${myslot} leftmouseup
    /if (!${Cursor.ID}) /goto :WaitForBagOpen
    /nomodkey /itemnotify ${mypack} leftmouseup
    /nomodkey /itemnotify ${mypack} rightmouseup
    /nomodkey /itemnotify ${mypack} leftmouseup
  } else {
    /nomodkey /itemnotify ${myslot} rightmouseup
  }
} else {
  /next i
}
/return
fish.inc

Code: Select all

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Auto Fisher
| Written by Jacen Solo
| Code borrowed originally from panther's script
| Use /fish to begin fishing.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event Fish "[MQ2] Start Fishing!"
#event FeignFail "|${Me.DisplayName}| has fallen to the ground."
#event BaitMissing "You can't fish without fishing bait, go buy some."
#event PoleMissing "You can't fish without a fishing pole, go buy one."
#event PoleMissing "#*#in your primary hand."

Sub FishPrep
   /squelch /alias /fish /echo Start Fishing!
/return

Sub Event_Fish
   /if (!${Ini[${Me.CleanName}.ini,${Zone.Name} Fishing,Range].Equal[NULL]}) {
      /ini "${Me.CleanName}.ini" "${Zone.Name} Fishing" "Range" "80"
   }
   /echo It's fishin time!
   /if (!${Defined[fish_status]}) {
      /declare fish_status int outer
      /declare fish_failed int outer
      /declare baitpail int outer
   }
   /varset baitpail 1
   /if (!${FindItemCount[Hargar Brand Fishing Pail]}) /varset baitpail 0
   /varset fish_status 0
   /varset fish_failed 0
   /if (${Me.Feigning}) /varset fish_status 1
   :Start
   /doevents return
   /if (${Macro.Return.Equal[DONE]}) /return RESET
   /call Run
   /if (${Me.AbilityReady[Fishing]} && !${Cursor.ID}) {
      /delay 10
      /doability Fishing
   }
   /doevents
   /if (${Cursor.ID}) {
      /if (${Ini[${Me.CleanName}.ini,${Zone.Name} Fishing,${Cursor.Name}].Equal[Loot]}) {
         /autoinventory
         /delay 1s
      }
      /if (${Ini[${Me.CleanName}.ini,${Zone.Name} Fishing,${Cursor.Name}].Equal[Drop]}) /drop
      /if (${Ini[${Me.CleanName}.ini,${Zone.Name} Fishing,${Cursor.Name}].Equal[Destroy]}) /destroy
      /delay 1s
      /if (${Cursor.ID}) {
         /ini "${Me.CleanName}.ini" "${Zone.Name} Fishing" "${Cursor.Name}" "Loot"
         /delay 15
      }
   }
   /if (${baitpail}) {
      /if (!${FindItem[A Hargar Brand Fishing Pail].Timer}) /call Event_BaitMissing
   }
   /delay 2s
   /goto :Start
/return

Sub Event_PoleMissing
   :PoleStart
   /if (${fish_status}) {
      /if (${Spawn[npc radius 80].ID}) /goto :PoleStart
      /sit
   }
   /autoinventory
   /itemnotify ${FindItem[Fisherman's Companion].InvSlot} leftmouseup
   /itemnotify pack8 leftmouseup
   /cast item "Fisherman's Companion"
   /delay 110
   /itemnotify pack8 leftmouseup
   /delay 10
   /autoinventory
   /delay 10
   /autoinventory
   /if (${fish_status}) {
      :feignloop
      /if (${Me.Class.Name.Equal[Monk]}) /doability "Feign Death"
      /if (${Me.Class.ShortName.Equal[NEC]} || ${Me.Class.ShortName.Equal[SHD]}) /cast "Feign Death"
      /delay 4s
      /doevents FeignFail
      /if (${fish_failed} || !${Me.Feigning}) /goto :feignloop
      /varset fish_failed 0
   }
/return

Sub Event_BaitMissing
   :BaitStart
   /if (!${baitpail}) {
      /echo You're Out Of Bait.
      /done
      /return
   }
   /if (${FindItem[A Hargar Brand Fishing Pail].Timer}) {
      /delay 5s
      /goto :BaitStart
   }
   /if (${fish_status}) {
      /if (${Spawn[npc radius 80].ID}) /goto :BaitStart
      /sit
   }
   /autoinventory
   /itemnotify ${FindItem[A Hargar Brand Fishing Pail].InvSlot} leftmouseup
   /itemnotify pack8 leftmouseup
   /cast item "A Hargar Brand Fishing Pail"
   /delay 110
   /if (${Cursor.Name.Equal[Hargar's Special Bait]}) {
      /autoinventory
   } else {
      /itemnotify pack8 leftmouseup
      /delay 10
      /autoinventory
      /delay 10
      /autoinventory
   }
   /if (${fish_status}) {
      :feignloop
      /if (${Me.Class.Name.Equal[Monk]}) /doability "Feign Death"
      /if (${Me.Class.ShortName.Equal[NEC]} || ${Me.Class.ShortName.Equal[SHD]}) /cast "Feign Death"
      /delay 4s
      /doevents FeignFail
      /if (${fish_failed} || !${Me.Feigning}) /goto :feignloop
      /varset fish_failed 0
   }
/return

Sub Event_FeignFail
   /varset fish_failed 1
/return
lang.inc

Code: Select all

| lang.inc
| Written by Jacen Solo
| 
| Use /spam to spam "a" in chat window.
| Use /teach to spam "a" in chat window and cycle through languages.
| Use /lang to idle, accept "Teach Me." as a tell, invite sender, spam "a" and cycle languages, then disband.
| /lang also accepts tells of "Teach More LangName", which triggers sender invite, and spamming LangName.




#event Spam "[MQ2] Start Spam."
#event Teach "[MQ2] Start Teach."
#event Lang "[MQ2] Start Lang."

Sub LangPrep
   /squelch /alias /lang /echo Start Lang.
   /squelch /alias /spam /echo Start Spam.
   /squelch /alias /teach /echo Start Teach.
/return

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Language Spammer
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Sub Event_Spam
   :spamloop
   /call Run Auto
   {
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
   }
   /if (${Me.ID}==${Target.ID}) /return
   /goto :spamloop
/return

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Language Teacher
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Sub Event_Teach
   /declare lang_current int 2
   /declare x int
   :Teachloop
   /lang ${lang_current}
   /echo Now teaching ${lang_current}
   /for x 0 to 1000
      /if (${Target.Name.Equal[${Me.Name}]}) /goto :nextlang
      /call Run Auto
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      }
   /next x
   :nextlang
   /squelch /target clear
   /varcalc lang_current ${lang_current}+1
   /if (${lang_current}>25) {
      /beep
      /return
   }
   /goto :Teachloop
/return

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Language Trainer
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event called "#1# tells you, 'Teach me.'"
#event teachmore "#1# tells you, 'Teach More #2#'"

Sub Event_Lang
   /declare lang_current int outer 2
   /declare lang_start int outer 0
   /echo Now running Language Master
   /call Idle
/return

Sub Idle
   :Idle
   /if (${lang_start}=1) /call Teaching
   /call Run Auto
   /doevents
   /delay 20
   /if (${Me.Sitting}) /endm
   /goto :Idle
/return

Sub Teaching
   :Teachloop
   /lang ${lang_current}
   /echo Now teaching ${lang_current}
   /call TeachLoop 1000
   /varcalc lang_current ${lang_current}+1
   /if (${lang_current}>25) {
      /lang 1
      /varset lang_current 2
      /varset lang_start 0
      /target clear
      /disband
      /beep
      /return
   }
   /goto :Teachloop
/return

Sub TeachLoop(int reps1)
   /for x 0 to ${reps1}
      /if (${Target.Name.Equal[${Me.Name}]}) /call Idle
      /call Run Auto
      {
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      /keypress enter
      /keypress a chat
      /keypress enter chat
      }
   /next x
/return

Sub Event_called(line,learner)
   /invite ${learner}
   /varset lang_start 1
   /delay 10m ${Group.Member[1].ID}
/return

Sub Event_teachmore(line,learner,langname)
   /if (${langname.Equal[Barbarian]}) /lang 2
   /if (${langname.Equal[Erudian]}) /lang 3
   /if (${langname.Equal[Elvish]}) /lang 4
   /if (${langname.Equal[Dark Elvish]}) /lang 5
   /if (${langname.Equal[Dwarvish]}) /lang 6
   /if (${langname.Equal[Troll]}) /lang 7
   /if (${langname.Equal[Ogre]}) /lang 8
   /if (${langname.Equal[Gnomish]}) /lang 9
   /if (${langname.Equal[Halfling]}) /lang 10
   /if (${langname.Equal[Thieves Cant]}) /lang 11
   /if (${langname.Equal[Old Erudian]}) /lang 12
   /if (${langname.Equal[Elder Elvish]}) /lang 13
   /if (${langname.Equal[Froglok]}) /lang 14
   /if (${langname.Equal[Goblin]}) /lang 15
   /if (${langname.Equal[Gnoll]}) /lang 16
   /if (${langname.Equal[Combine Tongue]}) /lang 17
   /if (${langname.Equal[Elder Teir'Dal]}) /lang 18
   /if (${langname.Equal[Lizardman]}) /lang 19
   /if (${langname.Equal[Orcish]}) /lang 20
   /if (${langname.Equal[Faerie]}) /lang 21
   /if (${langname.Equal[Dragon]}) /lang 22
   /if (${langname.Equal[Elder Dragon]}) /lang 23
   /if (${langname.Equal[Dark Speech]}) /lang 24
   /if (${langname.Equal[Vah Shir]}) /lang 25
   /invite ${learner}
   /delay 10m ${Group.Member[1].ID}
   /call TeachLoop 200
/return
memspell.inc

Code: Select all

|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Loads the spell set you send it from YourName.ini
| Originally written by Vayeco Dynn, modified by Jacen Solo
|
| Store spellsets in your INI in the following format:
| [Spell:YourSetName]
| 1=SpellName1
| 2=SpellName2
| 3=SpellName3
| 4=SpellName4
| 5=SpellName5
| ...
|
| Then load a set ingame by using "/memset YourSetName".
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event Memset "[MQ2] Load Spell Set: #1#"

Sub MemspellPrep
   /squelch /alias /memset /echo Load Spell Set:
/return

Sub Event_Memset(line,set)
   /echo Loading Set: ${set}
   /if (!${Defined[set]} || ${Ini[${Me.CleanName}.ini,Spell:${set},Spell1].Equal[NULL]}) /return
   /declare x int
   /for x 1 to 9
      /if (${Ini[${Me.CleanName},Spell:${set},Spell${x}].Equal[NULL]}) /goto :next
      /if (${Me.Gem[${Ini[${Me.CleanName}.ini,Spell:${set},Spell${x}]}]} == ${x}) /goto :next
      /memspell ${x} "${Ini[${Me.CleanName},Spell:${set},Spell${x}]}"
      /delay 60m ${Me.Gem[${x}].ID}
      :next
   /next x
   /echo Done
/return
selfbuff.inc

Code: Select all

| selfbuff.inc
| Written by Jacen Solo
|
| Use /selfbuff to toggle self buffing. Store self buffs in your INI file in the following format:
| [SelfBuffs]
| 1=Uber Shielding
| 2=Endure Noob
| 3=Shroud of Ownage

#event toggleselfbuff "[MQ2] Toggle Self Buff Refresh."

Sub SelfBuffPrep
   /declare selfbuff int outer 0
   /squelch /alias /selfbuff /echo Toggle Self Buff Refresh.
/return

Sub Event_toggleselfbuff
   /varset selfbuff ${If[${selfbuff},0,1]}
   /echo Automatic Self Buff Refresh ${If[${selfbuff},ON,OFF]}
/return

Sub SelfBuff
   /if (!${selfbuff}) /return
   /declare x int
   /declare oldtarg int 0
   /varset oldtarg ${Target.ID}
   /declare oldstatus int 0
   /if (${Me.Sitting}) /varset oldstatus 1
   /if (${Me.Combat}) /varset oldstatus 2
   /for x 1 to ${Math.Calc[${Ini[${Me.CleanName}.ini,SelfBuffs].Count[|]}-2]}
      /if (${Me.Buff[${Ini[${Me.CleanName}.ini,SelfBuffs,${x}]}].ID}) /goto :next
      /target me
      /attack off
      /call Cast "${Ini[${Me.CleanName}.ini,SelfBuffs,${x}]}" gem${Ini[${Me.CleanName}.ini,SelfBuffs,BuffGem]}
      :next
   /next x
   /squelch /target clear
   /if (${oldtarg}) /target id ${oldtarg}
   /if (${oldstatus}==1 && ${Me.Standing}) /sit
   /if (${oldstatus}==2 && !${Me.Combat}) /attack
/return
skills.inc

Code: Select all

|Skill_Routines.inc
|By Kambic
|Version 1.1.2
|August 25th, 2004
|
| Updated and modified by Jacen Solo for use with shell.mac

Sub Skill_Routines
/if (${Ini[${Me.CleanName}.ini,Skills,Backstab]}) /call Backstab
/if (${Ini[${Me.CleanName}.ini,Skills,Bash]}) /call Bash
/if (${Ini[${Me.CleanName}.ini,Skills,Begging]}) /call Begging
/if (${Ini[${Me.CleanName}.ini,Skills,Disarm]}) /call Disarm
/if (${Ini[${Me.CleanName}.ini,Skills,Evade]}) /call Evade
/if (${Ini[${Me.CleanName}.ini,Skills,FeignDeath]}) /call FeignDeath
/if (${Ini[${Me.CleanName}.ini,Skills,FlyingKick]}) /call FlyingKick
/if (${Ini[${Me.CleanName}.ini,Skills,Forage]}) /call Forage
/if (${Ini[${Me.CleanName}.ini,Skills,Frenzy]}) /call Frenzy 
/if (${Ini[${Me.CleanName}.ini,Skills,Intimidation]}) /call Intimidation
/if (${Ini[${Me.CleanName}.ini,Skills,Kick]}) /call Kick
/if (${Ini[${Me.CleanName}.ini,Skills,Mend]}) /call Mend
/if (${Ini[${Me.CleanName}.ini,Skills,PickPockets]}) /call PickPockets
/if (${Ini[${Me.CleanName}.ini,Skills,SenseTraps]}) /call SenseTraps
/if (${Ini[${Me.CleanName}.ini,Skills,Slam]}) /call Slam
/if (${Ini[${Me.CleanName}.ini,Skills,Taunt]}) /call Taunt
/return

Sub Backstab
/if (! ${Me.AbilityReady["Backstab"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]) /return
/if (${If[${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})}]) /return
/declare BehindIt bool local FALSE
/declare Dir float local
/for i -1 to 1
   /varcalc Dir (${Target.Heading.Clock}+${i})%12
   /if (${Dir}<1) /varcalc Dir ${Dir}+12
   /if (${Dir}>12) /varcalc Dir ${Dir}-12
   /if (${Dir} == ${Me.Heading.Clock}) /varset BehindIt TRUE
/next i
/face fast nolook
/if (! ${BehindIt}) /return
/doability "Backstab"
/return



Sub Bash
/if (! ${Me.AbilityReady["Bash"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me.CleanName}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/if (${InvSlot[offhand].Item.Type.NotEqual["Shield"]}) /return
/if (${Me.Casting.ID}) /return
/face fast nolook
/doability "Bash"
/return



Sub Begging
/if (! ${Me.AbilityReady["Begging"]}) /return
/if (${Window[BigBankWnd].Open}) /return
/if (${Merchant.Open}) /return
/if (${Window[TradeWnd].Open}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/if (${Me.Casting.ID}) /return
/declare CombatBefore bool local FALSE
/if (${Me.Combat}) {
   /varset CombatBefore TRUE
   /attack off
   /delay 1
}
/doability "Begging"
/if (${CombatBefore}) /attack on
/return
     


Sub Disarm
/if (! ${Me.AbilityReady["Disarm"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/face fast nolook
/doability "Disarm"
/if (${Cursor.ID}) /autoinv
/return



Sub Evade
/if (! ${Me.AbilityReady["Hide"]}) /return
/if (! ${Me.Class["Rogue"]}) /return
/if (! ${Me.Combat}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/if (! ${Me.Speed}==0)) /return
/attack off
/delay 1
/doability "Hide"
/delay 1
/face fast nolook
/attack on
/return


Sub FeignDeath
/if (! ${Me.AbilityReady["Feign Death"]}) /return
/if (! ${Me.Combat}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/delay 3s
/attack off
/delay 1
/doability "Feign Death"
/delay 1
/if (! ${Me.Standing}) /stand
/face fast nolook
/attack on
/return


Sub FlyingKick
/if (! ${Me.AbilityReady["Flying Kick"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/face fast nolook
/doability "Flying Kick"
/return



Sub Forage
/if (! ${Me.AbilityReady["Forage"]}) /return
/if (${Window[BigBankWnd].Open}) /return
/if (${Merchant.Open}) /return
/if (${Window[TradeWnd].Open}) /return
/if (${Window[SpellBookWnd].Open}) /return
/if (${Me.Stunned}) /return
/declare SittingBefore bool local FALSE
/declare CombatBefore bool local FALSE
/if (${Me.Sitting}) {
   /varset SittingBefore TRUE
   /stand
}
/if (${Me.Combat}) {
   /varset CombatBefore TRUE
   /attack off
   /delay 1
}
:emptycursor
/if (${Cursor.ID}) {
   /autoinv
   /goto :emptycursor
}
/doability "Forage"
|If you want some custom foraging check code, put it in between here yourself :)
/if (${Cursor.ID}) /autoinv
|If you want some custom foraging check code, put it in between here yourself :)
/if (${SittingBefore}) /sit
/if (${CombatBefore}) /attack on
/return

Sub Frenzy
/if (! ${Me.AbilityReady["Frenzy"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]) /return
/if (${If[${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})}]) /return
/if (${Me.Casting.ID}) /return
/face fast nolook
/doability "Frenzy"
/return

Sub Intimidation
/if (! ${Me.AbilityReady["Intimidation"]}) /return
/if (! ${Me.Combat}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/doability "Intimidation"
/return



Sub Kick
/if (! ${Me.AbilityReady["Kick"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/face fast nolook
/doability "Kick"
/return



Sub Mend
/if (! ${Me.AbilityReady["Mend"]}) /return
/if (${Me.PctHPs}>80) /return
/doability Mend
/return



Sub PickPockets
/if (! ${Me.AbilityReady["Pick Pockets"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/attack off
/delay 1
/doability "Pick Pockets"
/delay 1
/if (${Cursor.ID}) /autoinv
/face fast nolook
/attack on
/return

     

Sub SenseTraps
/if (! ${Me.AbilityReady["Sense Traps"]}) /return
/doability "Sense Traps"
/return



Sub Slam
/if (! ${Me.AbilityReady["Slam"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/face fast nolook
/doability "Slam"
/return



Sub Taunt
/if (! ${Me.AbilityReady["Taunt"]}) /return
/if (! ${Me.Combat}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]}) /return
/if (${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})) /return
/face fast nolook
/doability "Taunt"
/return
spells.inc

Code: Select all

| spell_routines.inc
|
| Written by Rusty~
| Last Modified 02/18/2007
|
| 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]
|     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                                     |
|----------------------+----------------------------------------------------------------------+

#define SpellTalkBack /squelch /echo
#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 NoLOS "You cannot see your target.#*#"
#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!#*#"
#event NoMount "#*#You can not summon a mount here.#*#"

Sub Cast(string spellName,string spellType,timer giveUpTimer,string mySub)
   /declare castTime float local
   /if ( ${spellType.Equal[item]} ) {
      /varset castTime ${FindItem[${spellName}].CastTime}
   } else /if ( ${spellType.Equal[alt]} ) {
      /varset castTime ${AltAbility[${spellName}].Spell.MyCastTime}
   } else {
      /varset castTime ${Spell[${spellName}].MyCastTime}
   }
   /if ( ${Me.Invis} && ${noInvis} ) {
      /return
   }
   :wait_for_stop
   /if ( !${Defined[spellType]} ) /declare spellType string local spell
   /if ( ${Me.Casting.ID} ) {
      /if ( ${Defined[mySub]} ) /call ${mySub}
      /goto :wait_for_stop
   } 
   /if ( ${Me.Speed} ) {
   :wait_for_stop2
      /if ( ${Defined[mySub]} ) /call ${mySub}
      /if ( ${Me.Moving} && ${castTime}>0.1 ) /goto :wait_for_stop2
   }
   /if ( !${Defined[giveUpTimer]} ) /declare giveUpTimer timer local 0
   /if ( !${Defined[spellRecastTime1]} ) {
      /if ( !${Defined[noInterrupt]} ) /declare noInterrupt int outer 0
      /declare moveBack bool outer false
      /declare selfResist int outer
      /declare selfResistSpell string outer
      /declare castEndTime timer outer
      /declare refreshTime timer outer 0
      /declare itemRefreshTime float outer 0
      /declare startCastingLoc string outer
      /declare i int local
      /declare castReturn string outer
      /declare spellNotHold string outer
      /delay 5
      /for i 1 to 9
         /declare spellRecastTime${i} timer outer
         /if ( ${Me.SpellReady[${i}]} ) {
            /varset spellRecastTime${i} 0
         } else {
            /varcalc spellRecastTime${i} 10*${Me.Gem[${i}].RecastTime}
         }
      /next i
   }
   /varset spellNotHold 0
   /varset selfResist 0
   /declare delayTime timer local
   /declare swapItemBack bool local false
   /declare slotName int local
   /declare oldItemName string local
   /declare slotID int local
   /declare oldSlotID int local
   /declare spellID int local
   /declare charges int local

   /if ( ${Window[SpellBookWnd].Open} ) /keypress spellbook
   /if ( ${Me.Ducking} ) /keypress duck
   /if ( !${Me.Standing} ) /stand

   /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
   /varset castReturn CAST_SUCCESS
   
      /if ( ${spellType.Equal[item]} ) /goto :cast_item
   /if ( ${spellType.Equal[alt]} ) /goto :cast_alt

:cast_spell
   /if ( !${Int[${Me.Book[${spellName}]}]} ) {
      SpellTalkBack Spell: "${spellName}" was not found in your book
      /return CAST_UNKNOWNSPELL
   }
   /if ( !${Me.Gem[${spellName}]} ) {
   :mem_spell
      /if ( ${Cursor.ID} ) {
         /autoinventory
         /delay 5
         /goto :mem_spell 
      }
      /if ( ${spellType.Left[3].Equal[gem]} ) {
         /memspell ${spellType.Right[1]} "${spellName}"
      } else {
         /return CAST_NOTMEMMED
      }
      /delay 6s ${Me.Gem[${spellName}]}
      /if ( !${Me.Gem[${spellName}]} ) {
         SpellTalkBack Spell mem interrupted...
         /return CAST_INTERRUPTED
      }
      :wait_for_mem
     
      /delay 15s ${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 ${giveUpTimer.OriginalValue}
   /declare recoverWaitTime timer local 30

:cast_spell_loop
:wait_for_spell
   /if ( ${Me.SpellReady[${spellName}]} ) {
      /varset spellRecastTime${Me.Gem[${spellName}]} 0
      /goto :skip_delay 
   }
   /if ( ${spellRecastTime${Me.Gem[${spellName}]}}  ) {
      /if ( !${giveUpTimer} ) /return CAST_NOTREADY
      /if ( ${Defined[mySub]} ) /call ${mySub}
      /goto :wait_for_spell
   }
   /if ( !${refreshTime} ) /goto :skip_delay
:wait_on_refresh
   /if ( ${Me.SpellReady[${spellName}]} ) /varset refreshTime 0
   /if ( ${refreshTime}>0 ) {
      /if ( ${Defined[mySub]} ) /call ${mySub}
      /goto :wait_on_refresh
   }
   /varcalc delayTime 10*(1.5-${Spell[${spellName}].MyCastTime})
:cast_delay_loop
   /if ( ${delayTime}>0 ) {
      /if ( ${Defined[mySub]} ) /call ${mySub}
      /goto :cast_delay_loop
   }
:skip_delay
   /varset startCastingLoc ${Me.X} ${Me.Y} ${Me.Z}
   /cast "${spellName}"

   /if ( ${Me.Casting.ID} ) {
      /varset spellID ${Me.Casting.ID}
      /varcalc castEndTime ${Me.Casting.MyCastTime}*10
      /if ( ${castEndTime}<${Math.Calc[${Me.Casting.CastTime}*5]} ) /varcalc castEndTime ${Me.Casting.CastTime}*5
      SpellTalkBack Casting: ${Me.Casting.Name}${If[!${Me.Casting.TargetType.Equal[PB AE]} && !${Me.Casting.TargetType.Equal[self]} && ${Target.ID}, on >> ${Target.CleanName} <<,]}
   }

   /varset moveBack false

   /call WaitCast ${mySub}

   /if ( ${moveBack} ) {
      /keypress back hold
      /delay 4
      /keypress back
      /delay 15 !${Me.Moving}
   }

   /if ( ${castReturn.Equal[CAST_CANCELLED]} ) {
      SpellTalkBack Spell was cancelled...
      /return CAST_CANCELLED
   }

   /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
   
   /if ( !${spellID} ) /varset spellID ${Spell[${spellName}].ID}
   /if ( !${castReturn.Equal[CAST_SUCCESS]} ) {
      /if ( ${castReturn.Equal[CAST_NOTREADY]} ) /return CAST_NOTREADY
      /if ( ${castReturn.Equal[CAST_FIZZLE]} ) {
         SpellTalkBack Spell Fizzled. Recasting...
         /goto :cast_spell_loop
      }
      /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]} ) /goto :cast_spell_loop
      /if ( ${castReturn.Equal[CAST_STUNNED]} ) {
         /if ( ${Me.Stunned} ) {
            /delay 3s !${Me.Stunned}
         } else {
            /delay 7
         }
         /goto :cast_spell_loop
      }
      /if ( ${castReturn.Equal[CAST_INTERRUPTED]} ) {
         /if ( ${giveUpTimer} ) {
            SpellTalkBack Spell was interrupted. Recasting...
            /goto :cast_spell_loop
         }
         SpellTalkBack Spell was interrupted...
         /return CAST_INTERRUPTED
      }
   }
   /if ( !${castReturn.Equal[CAST_CANNOTSEE]} && !${castReturn.Equal[CAST_OUTOFRANGE]} && !${castReturn.Equal[CAST_OUTOFMANA]} && !${castReturn.Equal[CAST_NOTARGET]} ) {
      /varcalc refreshTime 10*${Spell[${spellID}].RecoveryTime}
      /varcalc spellRecastTime${Me.Gem[${spellName}]} 10*${Spell[${spellID}].RecastTime}
   }
   /if ( ${castReturn.Equal[CAST_COLLAPSE]} ) {
      /varset giveUpTimer 200
      /goto :cast_spell_loop
   }
/return ${castReturn}


:cast_item
   /if ( !${FindItem[${spellName}].InvSlot} ) {
      SpellTalkBack Cannot find item: ${spellName}
      /return CAST_UNKNOWNSPELL
   } 
   /if ( ${FindItem[${spellName}].InvSlot}>22 ) {
      /varset swapItemBack true
      /if ( ${FindItem[${spellName}].WornSlot[1]} && ${FindItem[${spellName}].EffectType.Find[worn]} ) {
         /varset slotName ${FindItem[${spellName}].WornSlot[1]}
      } else /if ( ${FindItem[${spellName}].InvSlot}>30 ) {
         /varset slotName 30
      } else {
         /varset slotName ${FindItem[${spellName}].InvSlot}
      }
      /varset slotID ${InvSlot[${slotName}].ID}     
      /varset oldSlotID ${FindItem[${spellName}].InvSlot.ID}
      /varset oldItemName ${InvSlot[${slotID}].Item.Name}
      /call SwapItem "${spellName}" ${slotID}
   }
:cast_item_loop
:wait_item_loop
   /if ( ${itemRefreshTime} > ${MacroQuest.Running} ) {
      /delay 1
      /goto :wait_item_loop
   }
   /varset itemRefreshTime ${Math.Calc[${MacroQuest.Running}+000]}
   /varset charges ${FindItem[${spellName}].Charges}
   /varset startCastingLoc ${Me.X} ${Me.Y} ${Me.Z}
   /cast item "${spellName}"
   /if ( ${Me.Casting.ID} ) {
      /varcalc castEndTime ${FindItem[${spellName}].CastTime}*10
      SpellTalkBack Casting: ${FindItem[${spellName}].Spell.Name}${If[!${FindItem[${spellName}].Spell.TargetType.Equal[PB AE]} && !${FindItem[${spellName}].Spell.TargetType.Equal[self]} && ${Target.ID}, on >> ${Target.CleanName} <<,]}
   }
   /if ( ${charges}>0 ) /delay 1s ${FindItem[${spellName}].Charges}!=${charges}

   /call WaitCast ${mySub}
   
   /if ( ${swapItemBack} ) {
      /if ( ${FindItem[${spellName}].ID} ) {
         /call SwapItem "${spellName}" ${oldSlotID}
      } else /if ( ${FindItem[${oldItemName}].ID} ) {
         /call SwapItem "${oldItemName}" ${slotID}         
      }
      /if ( ${Cursor.Container} ) /autoinventory
   }

   /if ( ${castReturn.Equal[CAST_CANCELLED]} ) {
      SpellTalkBack Spell was cancelled...
      /return CAST_CANCELLED
   }

   /doevents BeginCast
   /doevents Interrupt
   /doevents Standing
   /doevents FDFail
   /doevents OutOfRange
   /doevents NoLOS
   /doevents Resisted2
   /doevents Resisted
   /doevents Immune
   /doevents Stunned
   /doevents Collapse
   /doevents NoTarget
   /doevents NotReady

   /if ( !${castReturn.Equal[CAST_SUCCESS]} ) {
      /if ( ${castReturn.Equal[CAST_NOTREADY]} ) /return CAST_NOTREADY
      /if ( ${castReturn.Equal[CAST_RESTART]} ) /goto :cast_item
      /if ( ${castReturn.Equal[CAST_STUNNED]} ) {
         /if ( ${Me.Stunned} ) {
            /delay 3s !${Me.Stunned}
         } else {
            /delay 7
         }
         /goto :cast_item
      }
      /if ( ${castReturn.Equal[CAST_INTERRUPTED]} ) {
         /if ( ${giveUpTimer} ) {
            SpellTalkBack Spell was interrupted. Recasting...
            /goto :cast_item
         }
         SpellTalkBack Spell was interrupted...
         /return CAST_INTERRUPTED
      }
   }
   /if ( ${castReturn.Equal[CAST_COLLAPSE]} ) {
      /varset giveUpTimer 200
      /goto :cast_item
   }
/return ${castReturn}


:cast_alt
   /if ( !${Me.AltAbilityReady[${spellName}]} ) /return CAST_NOTREADY
   SpellTalkBack Using AA Ability: ${AltAbility[${spellName}].Name}
   /alt activate ${AltAbility[${spellName}].ID}
   /if ( ${AltAbility[${spellName}].Spell.MyCastTime}>=0.5 ) /delay 1s ${Me.Casting.ID}
   /call WaitCast ${mySub}
   
   /if ( ${castReturn.Equal[CAST_CANCELLED]} ) {
      SpellTalkBack Spell was cancelled...
      /return CAST_CANCELLED
   }
   
   /doevents BeginCast
   /doevents Interrupt
   /doevents Standing
   /doevents FDFail
   /doevents OutOfRange
   /doevents NoLOS
   /doevents Resisted2
   /doevents Resisted
   /doevents Immune
   /doevents Stunned
   /doevents NoTarget
     
   /if ( !${castReturn.Equal[CAST_SUCCESS]} ) {
      /if ( ${castReturn.Equal[CAST_RESTART]} ) /goto :cast_alt
      /if ( ${castReturn.Equal[CAST_STUNNED]} ) {
         /if ( ${Me.Stunned} ) {
            /delay 3s !${Me.Stunned}
         } else {
            /delay 7
         }
         /goto :cast_alt
      }
      /if ( ${castReturn.Equal[CAST_INTERRUPTED]} ) {
         /if ( ${giveUpTimer} ) {
            SpellTalkBack Spell was interrupted. Recasting...
            /goto :cast_alt
         }
         SpellTalkBack Spell was interrupted...
         /return CAST_INTERRUPTED
      }
   }
/return ${castReturn}


Sub EquipItem(string WhatWhere)
   /declare DestName string local
   /declare ItemName string local ${String[${WhatWhere}].Arg[1,|]}
   /declare SlotName string local ${String[${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 EquipItem(string itemName,string slotName)
   /if ( !${Defined[slotName]} ) /declare slotName string local ${FindItem[${itemName}].WornSlot[1]}
   /declare oldItem string local ${Me.Inventory[${slotName}].Name}
   /call SwapItem "${itemName}" ${slotName}
/return "${oldItem}" ${slotName}

Sub SwapItem(string itemName,string slotName)
   /if ( ${InvSlot[${slotName}].Item.Name.Equal[${itemName}]} ) /return
   /declare slotID int local
   /declare oldSlotID int local
   /declare oldItem string local
   /declare i int local
   /varset slotID ${InvSlot[${slotName}].ID}           | slotID = slot you're swapping item to
   /varset oldSlotID ${FindItem[${itemName}].InvSlot.ID} | oldSlotID = slot the item was originally in
   /varset oldItem ${InvSlot[${slotName}].Item.Name}     | oldItem = name of item in the slot you're swapping WITH
   /if ( !${slotID} ) {
      SpellTalkBack Invalid slot name: ${slotName}
      /return
   }
   /if ( !${oldSlotID} ) {
      SpellTalkBack Could not find item ${itemName}
      /return
   }
:auto_inv
   /if ( ${Cursor.ID} && !${Cursor.Name.Equal[${itemName}]} ) {
      /if ( ${Cursor.Container} ) {
         /for i 1 to 8
            /if ( !${InvSlot[pack${i}].Item.Container} ) {
               /nomodkey /itemnotify pack${i} leftmouseup
            }
         /next i
      } else {
         /autoinventory
      }
      /goto :auto_inv
   }
   

:pick_up_item
 | if the item is in a bag and it's not open, then open it!
   /if ( ${InvSlot[${oldSlotID}].Pack} && !${Window[${InvSlot[${oldSlotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${oldSlotID}].Pack} rightmouseup

 | if the slot you're putting it in is inside a bag and it's not open, then open it!
   /if ( ${InvSlot[${slotID}].Pack} && !${Window[${InvSlot[${slotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${slotID}].Pack} rightmouseup

 | ok.. pick up the item now!
   /squelch /nomodkey /shiftkey /itemnotify ${InvSlot[${oldSlotID}]} leftmouseup

 | if item isn't on your cursor, try again!
   /if ( !${Cursor.Name.Equal[${itemName}]} ) {
      /if ( ${Cursor.ID} && !${Cursor.Container} ) /autoinventory
      /goto :pick_up_item
   }
:exchange_items
   /if ( ${InvSlot[${oldSlotID}].Pack} && !${Window[${InvSlot[${oldSlotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${oldSlotID}].Pack} rightmouseup
   /if ( ${InvSlot[${slotID}].Pack} && !${Window[${InvSlot[${slotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${slotID}].Pack} rightmouseup

 | put the item in the new slot, and pick up whatever item was there
   /squelch /nomodkey /shiftkey /itemnotify ${slotID} leftmouseup

 | if it didnt get exchanged, try again!
   /if ( ${Cursor.ID} && !${Cursor.Name.Equal[${oldItem}]} && !${Cursor.Name.Equal[${itemName}]} && !${Cursor.Container} ) /autoinventory
   /if ( !${InvSlot[${slotID}].Item.Name.Equal[${itemName}]} ) /goto :exchange_items
:drop_item
   /if ( !${Cursor.Container} || ( ${InvSlot[${oldSlotID}]}<30 && ${InvSlot[${oldSlotID}]}>=23 ) ) {
      /if ( ${InvSlot[${oldSlotID}].Pack} && !${Window[${InvSlot[${oldSlotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${oldSlotID}].Pack} rightmouseup
      /if ( ${InvSlot[${slotID}].Pack} && !${Window[${InvSlot[${slotID}].Pack.Name}].Open} ) /nomodkey /itemnotify ${InvSlot[${slotID}].Pack} rightmouseup
      /squelch /nomodkey /itemnotify ${oldSlotID} leftmouseup
      /if ( ${Cursor.ID} ) {
         /if ( !${Cursor.Name.Equal[${oldItem}]} ) /autoinventory
         /goto :drop_item
      }
   }
:close_pack
   /if ( ${InvSlot[${oldSlotID}].Pack} && ${Window[${InvSlot[${oldSlotID}].Pack.Name}].Open} && ( ${Cursor.Name.Equal[${itemName}]} || ${FindItem[${itemName}].ID} ) ) {
      /squelch /nomodkey /itemnotify ${InvSlot[${oldSlotID}].Pack} rightmouseup
      /goto :close_pack
   }
   /if ( ${InvSlot[${slotID}].Pack} && ${Window[${InvSlot[${slotID}].Pack.Name}].Open} && ( ${Cursor.Name.Equal[${itemName}]} || ${FindItem[${itemName}].ID} ) ) {
      /squelch /nomodkey /itemnotify ${InvSlot[${slotID}].Pack} rightmouseup
      /goto :close_pack
   }
/return

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


Sub WaitCast(string mySub)
   /declare currentTarget int local ${Target.ID}
   /declare currentTargetType string local ${Target.Type}
:wait_cast_loop
   /if ( ${Bool[${mySub}]} ) /call ${mySub}
   /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
      /delay 1
      /goto :wait_cast_loop
   }
/return

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

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

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

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

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

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

Sub Event_Stunned
   /if ( ${Defined[castReturn]} ) /varset castReturn CAST_STUNNED
/return

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

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

Sub Event_Collapse
   /if ( ${Defined[castReturn]} ) /varset castReturn CAST_COLLAPSE
/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_NoTarget
   /if ( ${Defined[castReturn]} ) /varset castReturn CAST_NOTARGET
/return

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

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

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

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

Sub Event_NoMount
/return CAST_NOMOUNT
spelltrain.inc

Code: Select all

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Spell Skill Trainer
| Originally from lorad's script, modified slightly by Jacen Solo for effectiveness and for shell.mac
|
| Load the spells you want to train, then use /spelltrain.
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

#event SpellTrain "[MQ2] Start Spell Trainer."
#define DEBUG /squelch /echo

Sub SpellTrainPrep
   /squelch /alias /spelltrain /echo Start Spell Trainer.
/return

Sub Event_SpellTrain
   DEBUG Spell Trainer Started.
   /declare currentSpell int 0
   /target myself
   :nextSpell
   /varcalc currentSpell ${currentSpell}+1
   DEBUG Current Spell: ${currentSpell}
   /if (${currentSpell}==10) {
      /beep
      /return
   }
   /if (!${Me.Gem[${currentSpell}].ID}) /goto :nextSpell
   :castSpell
   /doevents return
   /if (${Macro.Return.Equal[DONE]}) /return
   DEBUG Casting Spell.
   /call Run
   /if ( ${Me.PctMana}<20) {
      /if (${Me.Standing}) /sit
      /delay 5000000000000m ${Me.PctMana}==100
   }
   /if ( ${Me.Skill[${Me.Gem[${currentSpell}].Skill}]} >= ${Skill[Abjuration].SkillCap} ) /goto :nextSpell
   /cast ${currentSpell}
   /delay 20m ${Me.SpellReady[${Int[${currentSpell}]}]}
   /goto :castSpell
/return

Posted: Sun Jun 03, 2007 2:32 pm
by Shin Noir
you forgot to add Spelltrain.inc

Posted: Sun Jun 03, 2007 3:00 pm
by jacensolo
Whoops, you're right. I had missed that include. It is now added to the list of include files. Also, I fixed a glitch in clickies.inc, selfbuff.inc, and feedme.inc, and tested feedme.inc and combine.inc

Posted: Sun Jun 03, 2007 3:39 pm
by Shin Noir
Also maybe add this one:

Code: Select all

|In PlayerName.ini
[Skills]
Backstab=FALSE
Bash=FALSE
Begging=FALSE
Disarm=TRUE
Evade=FALSE
FeignDeath=FALSE
FlyingKick=FALSE
Forage=FALSE
Frenzy=TRUE
Intimidation=FALSE
Kick=FALSE
Mend=FALSE
PickPockets=FALSE
SenseTraps=FALSE
Slam=FALSE
Taunt=TRUE
HitBox=15
in Skills.inc

Code: Select all

/if (${Ini[${Me.CleanName}.ini,Skills,Frenzy]}) /call Frenzy

Sub Frenzy
/if (! ${Me.AbilityReady["Frenzy"]}) /return
/if (! ${Me.Combat}) /return
/if (${Me.Stunned}) /return
/if (! ${Target.ID}) /return
/if (${Target.CleanName.Equal[${Me}]) /return
/if (${If[${Target.Distance}>(${Ini[${Me.CleanName}.ini,Skills,Hitbox]})}]) /return
/if (${Me.Casting.ID}) /return
/face fast nolook
/doability "Frenzy"
/return


Also code was erroring out..
subroutine skills wasn't found
shell.mac@56
Looks like you have the name "Skills" in the ini file but the sub is called Skill_Routines ....

renamed Skill_Routines sub to Skills and now divide by zero calc
exptrack.inc@33
/varset failed, EXPGain not found

Posted: Mon Jun 04, 2007 5:07 pm
by Nightmare327
I'll try to check it out this week, but did notice one issue. It appears that you will only do 8 spell slots when memming spell set. I think theres a way to see if you have the AA for the 9th spell slot, that would probably be a good change to make.

Posted: Mon Jun 04, 2007 7:56 pm
by jacensolo
It has now been updated so that it *should* work for 9 spells. I just changed it to try to load 9 spells, so since it had a check in it for if a gem was undefined in the INI, it should load just fine, unless you don't have the 9th gem and put a 9th gem setting in the INI.

Posted: Wed Jun 06, 2007 8:40 pm
by jacensolo
I've been trying to replicate the other problems you experience Shin Noir. As for the first problem, the only way I could replicate it was to name the INI entry under [Auto] as 1=Skills instead of 1=Skill_Routines. For the second problem, the problem was one which I experienced randomly, and seemed unrelated to any code changes I did. What I eventually discovered was that It was loading too quickly, and it was running the first pulse of EXPTrack before 1 second had elapsed, causing it to divide 0 exp gained by 0 time elapsed, which caused the error when it tried to divide by zero. The solution seems to be adding a delay at the end of EXPPrep if your computer loads to fast.

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:13 am
by xyilla

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:14 am
by xyilla

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:15 am
by xyilla

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:16 am
by xyilla

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:17 am
by xyilla

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:18 am
by xyilla

Re: Shell.mac ((DISCONTINUED))

Posted: Thu Aug 14, 2025 2:20 am
by xyilla