Goto page Previous  1, 2, 3  Next Public Macros Looking for some help on this Cleric macro
Reply
Maybe I need to use ${NetBots[${NBToon${x}}].Buff.Find[ ${spellID} ]} I'll have to try that next time I can sit down with it.
Wed Feb 12, 2014 6:26 am
For me...

/echo ${NetBots[Grumble].Buff}
returns: 2605

/echo ${NetBots[Grumble].Buff.Find[2605])
returns: 1

Your format looks OK.

You'll need to troubleshoot the ${NBToon${x}} stuff and doublecheck that the spell ID matches that buff on that server.

If you still can't get it to work, simplify the /if statement. It's not logically correct as is so you'll have to do it eventually. The InZone, InGroup and Cast.Ready parts are only evaluated if DI is found in the ShortBuff list. Which shouldn't ever happen since DI doesn't go in the ShortBuff list (on most servers).
Wed Feb 12, 2014 12:16 pm
Senior Project Member
Yes, I did realize most of that as I was trying to get some sleep last night. I put /echos in my sub, it returns the name correctly, and buff list, but the find part isn't working right. I should have the right buff id based on what .Buff returns.
Wed Feb 12, 2014 1:29 pm
So I've fixed some stuff up, and cleaned up a few of my subs a bit, it's better than it was, but my problem now is that the cleric will get into the buff loop while my warrior is fighting, and then it seems he is in that sub until it's done. What is a way that I can be sure that I stay in the healing sub while my team is in combat, and then check buffs when I'm not, and at the same time, if I do begin combat, exit the buff routine and focus on healing.

Macro
More +

| Events and Chat and Includes
#turbo          10
#chat           tell
#chat           group
#Event          ImDead          "You have been slain by#*#"
#Event          ImDead          "You died."
#event          Zoned           "You have entered#*#"
#event          Zoned           "LOADING, PLEASE WAIT..."
#event          ImHit           "#*#hits YOU for#*#"
#Event          Thirsty         "#*#are thirsty#*#"
#Event          Hungry          "#*#are hungry#*#"
#Event          Enrageon        "#*#|${Target.CleanName}| has become ENRAGED#*#"
#Event          Enrageoff       "#*#|${Target.CleanName}| is no longer enraged#*#"
#Event          Zoning          "You have entered#*#"
#include        ninjadvloot.inc
#include        spell_routines.inc


Sub Main

/if (${Me.Class.ShortName.NotEqual[CLR]}) {
        /echo Sorry you are not a Cleric.
    /echo I'm afraid this macro to PC relationship just isn't going to work out.
    /echo I do hope we can still be friends though.
    /end
}

| - Detect AA spell gems
| ################## Setup AA Extra gem slot variables

        /if (${Me.AltAbility[Mnemonic Retention]}>=3) /multiline ;      /declare  Gem9 int outer  1 ; /declare Gem9Spell        outer

| name the main tank
/declare tank                           string outer    Feldorn
/varset tank                            ${tank}

| Declare the Spells here
/declare heal                           outer           "Ancient: Hallowed Light"
/declare healGem                        int     outer   1
/declare grpHeal                        outer           "Word of Vivification"
/declare grpHealGem                     int     outer   2
/declare hot                            outer           "Pious Elixir"
/declare hotGem                         int     outer   3
/declare vie                            outer           "Panoply of Vie"
/declare vieGem                         int     outer   4
/declare di                                     outer           "Divine Intervention"
/declare diGem                          int     outer   5
/declare pac                            outer           "Placate"
/declare pagGem                         int     outer   6
/declare ohShit                         outer           "Divine Barrier"
/declare ohShitGem                      int     outer   9
/declare gate                           outer           "Gate"
/declare drink                          outer           "Summon Drink"
/declare food                           outer           "Summon Food"
/declare root                           outer           "Petrifying Earth"
/declare pet                            outer           "Unswerving Hammer of Retribution"
/declare miscGem                        int     outer   8
/declare spellID                        int local

/declare Bot                            bool outer      FALSE
/declare Verbose                        int     outer   1

/declare healAt                         int     outer   65
/declare CastRetryTime          string outer 15s

|Item Clicky Declares
/declare manaOrb                outer   "Orb of Spirits"
/declare orbTimer                       timer outer 0m
/declare epic                           outer   "Ancient Shield of the Divine"
/declare epicTimer                      timer outer 0m

| Declares for NetBots
/declare NBToon1                        outer
/declare NBToon2                        outer
/declare NBToon3                        outer
/declare NBToon4                        outer
/declare NBToon5                        outer
/declare NBToon6                        outer

/echo Tank=${tank}
/echo TankID=${Spawn[=${tank}].ID}


|Main Loop, Add other loop and a connector /if command
:Main
/if (!${Bot}) /call Start1
/call Heal
/doevents
/call GrpHeal
/call OhShit
/call CheckMana

/if ( ${NetBots[${tank}].Attacking} ) /goto :Main
/goto :Buff

:Buff
/call DivineIntervention
/call CheckTankHealth
/call TankVie
/goto :Main

| Subs below here.

Sub Start1
/varset Bot TRUE
/declare x int local
        /for x 1 to ${NetBots.Counts}
        /varset NBToon${x} ${NetBots.Client.Token[${x}, ]}
        /next x
/g NetBots Array loaded and ready!
/return


Sub Heal
/if (${Me.Casting.ID} || ${Me.Moving}) /return
/if (${NetBots[${tank}].PctHPs}<=${healAt} && ${Target.Type.Equal[PC]} && ${NetBots[${tank}].InZone}) {
        /echo Healing ${Target}
        /g Incoming << ${heal} >> for ${Target} ...
        /casting ${heal} gem${healGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
        /if ( ${NetBots[${tank}].PctHPs}>=92 ) /interrupt
        }
/return


Sub GrpHeal
/if (${Me.Casting.ID} || ${Me.Moving}) /return
/declare i int local
/declare x int local
/for x 0 to 5
/for i 0 to 5
/if (${x} == ${i}) /next i
/if (${Group.Member[${i}].Distance}<=100 && ${Group.Member[${i}].PctHPs}<70 && ${Group.Member[${i}].Type.Equal[PC]} && ${Group.Member[${x}].Distance}<=100 && ${Group.Member[${x}].PctHPs}<70 && ${Group.Member[${x}].Type.Equal[PC]}) /call CastGrpHeal
/next i
/next x
/return


Sub CastGrpHeal
/if ( ${epicTimer}==0 ) {
/casting "Ancient Shield of Divinity" item ${CastRetryTime}
/g Epic 1.5 Balance
/varset epicTimer 5m
}
/if (${AltAbilityReady[Divine Arbitration]} && !${FindItem[Ancient Shield of Divinity].Timer}==0) {
/casting "Divine Arbitration" alt
/g AA Balance
}
/casting ${grpHeal} gem${grpHealGem} -maxtries|5
/echo Gheal Inc
/gsay Grp Heal Inc, Hang in there dudes!
/return


Sub DivineIntervention
/if (${NetBots[${tank}].Attacking} || !${Cast.Ready[${di}]} || ${Me.Casting.ID} || ${Me.Moving}) /return
/if (${Me.PctMana}>40) {
        /declare x int local
        /declare spellID int local 1546
        /for x 1 to ${NetBots.Counts}
                /if ( !${NetBots[${NBToon${x}}].Buff.Find[${Spell[${di}].ID}]} && ${NetBots[${NBToon${x}}].InZone} && ${NetBots[${NBToon${x}}].InGroup} ) {
                        /delay 1s
                        /g Buffing << ${di} on ${Target} >>
                        /echo ${di} for ${Target}
                        /casting ${di} gem${diGem} -maxtries|5 -targetid|${NetBots[${NBToon${x}}].ID}
                }
        /next x
}
/return

Sub TankVie
/if (${NetBots[${tank}].Attacking} || ${Me.Casting.ID} || ${Me.Moving}) /return
/if (${Me.PctMana}>30) {
        /if ( !${NetBots[${tank}].Buff.Find[${Spell[${vie}].ID}]} && !${NetBots[${tank}].Attacking} && ${NetBots[${tank}].InZone} && ${NetBots[${tank}].InGroup} ) {
                /delay 1
                /g Buffing << ${vie} on ${tank} >>
                /casting ${vie} gem${vieGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
        }
}
/return

Sub CheckTankHealth
 /if (${NetBots[${tank}].PctHPs}<=50 && ${Target.Type.Equal[PC]} && ${NetBots[${tank}].Attacking}) {
  /call Interrupt
  /casting ${heal} gem${healGem} -maxtries|5 -targetid|${tank}
  }
/return

Sub CheckMana
/if ( ${Me.PctMana}<=18 && ${orbTimer}==0 ) {
        /g Need, mana, using Orb of Spirits, 10 second cast!
        /casting "Orb of Spirits" item 15s
        /varset orbTimer 5m
        /g I now have ${Me.PctMana} % Mana
        }
/return

Sub OhShit
/if ( ${Me.PctHPs}<=30 && ${CombatOn} && ${Engaged} ) {
        /g Help me ${tank}, you're my only hope!
        /interrupt
        /delay 1
        /casting ${ohShit} gem${ohShitGem} -maxtries|5 -targetid|${Me.ID}
        }
/return


|Chat Trigger events check #chat {Setting
Sub Event_Chat(string ChatType,string ChatSender,string ChatText)
/if (${Select[${ChatText},tank]}) {
    /varset tank ${ChatSender.Right[-2].Left[-1]}
    /echo Main Assist Changed to ${tank}
    }
/if (${Select[${ChatText},vie]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${vie} gem${vieGem} -maxtries|4
    /echo Casting ${vie} on ${Target.ID}
    }
/if (${Select[${ChatText},di]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${di} gem${diGem} -maxtries|4
    /echo Casting ${di} on ${Target.ID}
    }
/if (${Select[${ChatText},pacify]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${pac} gem${pacGem} -maxtries|4
    /echo Casting ${pac} on ${Target.ID}
    }
/return


|Events
Sub Event_ImHit
        /g I'm under attack!
/return

Sub Event_Zoned
   /delay 40s
/return

| ################## Hungry
Sub Event_Hungry
  /if (${Engaged}) /return
  /echo I am Hungry
  /if (${Verbose}) /gsay Summoning Food, hold pulls for 30 secs.
  /declare i int local
  /for i 1 to 8
     /call cast "${food}" gem${miscGem} ${CastRetryTime}
        /delay 1
           /autoinventory
    /delay 1
  /next i
  /if (${Verbose}) /gsay Ready for pulls again.
/return
| ################## Thirsty
Sub Event_Thirsty
  /if (${Engaged}) /return
  /echo I am Thirsty
  /if (${Verbose}) /gsay Summoning Drink, hold pulls for 30 secs.
  /declare i int local
  /for i 1 to 8
    /call cast "${drink}" gem${miscGem} ${CastRetryTime}
        /delay 1
    /autoinventory
    /delay 1
  /next i
  /if (${Verbose}) /gsay Ready for pulls again.
/return
| ##################  ENRAGE ON
Sub Event_Enrageon
   /if (${PetOn}) {
     /echo Mob is ENRAGED!
     /pet back off
     /if (${DoPetHold} && ${Me.AltAbility[Pet Discipline]}) {
       /pet hold on
       /varset PetHeld 1
     }
   }
/return

Sub Event_ImDead
/end


Thanks for the pointers.
Sun Feb 16, 2014 4:52 pm
Macro
More +

/call Start1

:Main
/call Heal
/doevents
/call GrpHeal
/call OhShit
/call CheckMana
/if ( !${NetBots[${tank}].Attacking}) /call DivineIntervention
/if ( !${NetBots[${tank}].Attacking}) /call TankVie
/goto :Main

| this next line is important in any macro - you are missing it
/return


Step 1 is to fix the main loop. It's two separate loops that aren't really separate.

/call Start1 doesn't need to be in the :Main loop at all. Put it before :Main.

The /goto :Buff and :Buff parts do nothing but take up time. Each line takes 1/10 of a second since you used #Turbo 10. They add up. Same with the first /goto :Main line. Take em out. By the way, up the Turbo to 40.

/call CheckTankHealth looks like it was put in as an attempt to fix the healing issue. I left it out because I think it's better to improve the flow and responsiveness of the macro rather than double and triple check things.

/call DI and /call TankVie should only fire "when not in combat." Notice the ! in the above.

Aside: There are other methods in addition to or in place of the ${NetBots[${tank}].Attacking} method. You can count the number of NPCs in the area - a number greater than 0 means you might not want to buff. You can check HP of your tank or others - HP too low means you shouldn't take time buffing. If you still aren't happy with the macro after these changes, this is one place you can look at.

Your macro is missing a /return. You technically don't need it with an endless loop as written but it's still good to put one in. A simple typo or flow error will give you an error message completely and totally unrelated to the actual problem because the macro expects the /return. Every time you have a Sub BlahBlahBlah you want a corresponding /return. Sub Main is no exception.

Step 2 is to make your various Subroutines quick and responsive.

Sub DI has a 1s delay that's unneeded.

As written, Sub DI checks everyone and buffs everyone before leaving the sub to check for heals. This isn't a good thing, as this is part of the problem. Solution: break out of the Sub after buffing a single buff. It's OK. Buffs take an eternity to cast compared to the time it takes to check if they are up.
Macro
More +

/casting ${di} gem${diGem} -maxtries|5 -targetid|${NetBots[${NBToon${x}}].ID} /return


Sub TankVie also has an unneeded delay.

Sub Heal and Sub GrpHeal contain what may be the real problem. Both will skip their subroutines if the cleric is already casting a spell - such as the buffs you don't want to be casting while in combat. If your cleric isn't casting a heal spell, it shouldn't ignore the rest of the Sub Heal routine (and similar for the GrpHeal sub). You will also need to interrupt the current spell if you detect you need to cast a heal. The CheckTankHealth sub looks a lot like that.

Try...
Macro
More +
Sub Heal
/if (${Me.Casting.ID == <the spell ID of your heal spell>} || ${Me.Moving}) /return
/if (${NetBots[${tank}].PctHPs}<=${healAt} && ${Target.Type.Equal[PC]} && ${NetBots[${tank}].InZone}) {
        /if (${Me.Casting.ID != <the spell ID of your heal spell>) /call Interrupt
        /echo Healing ${Target}
        /g Incoming << ${heal} >> for ${Target} ...
        /casting ${heal} gem${healGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
        /if ( ${NetBots[${tank}].PctHPs}>=92 ) /interrupt
}
/return


Further optimization is possible. Perhaps you don't want to interrupt a group heal spell to cast a heal spell.
Sun Feb 16, 2014 9:46 pm
Senior Project Member
Grumble, thank you for that, it was very helpful and informative. I fixed up the macro and it was running much better. There are still a couple things I want to add with the heal subs, but it appeared to be working now.

one problem I saw a couple times last night, after healing, the tank is at 90% but the cleric heals again. Any idea why it would do that?
Tue Feb 18, 2014 12:13 pm
Very rough guess...

MQ2Cast can queue up spells. Issue a /casting command and MQ2Cast will make a good faith attempt to cast it "soon." If unable to cast the spell, MQ2Cast will remove the spell from the queue.

That window of opportunity to queue up spells is surprisingly large considering how fast macros can blaze by. It's several seconds. Maybe 4? 8?

The heal spell cast when the tank is at 90% may have been queued when the tank was at 40%.

Aside: Why does MQ2Cast use a queue? Among other things, a queue lets MQ2Cast swap bandolier sets for certain spells, allows time to stop a moving horse before casting and allows time to change targets when using the -target option.

And now a not so rough guess... Even if you haven't ran into this yet, you probably will sometime.

The already-healed interrupt check occurs in the /if statement showing you want to be healing the tank. They contradict each other. When one is true, the other is not.

The already-healed interrupt check should also come before the am-I-casting-my-heal-spell check. The latter exits Sub Heal before the former has a chance to check.
Tue Feb 18, 2014 8:12 pm
Senior Project Member
Now that you mention it, I see what you mean.

I don't see a good way to interrupt the heal if he gets healed by another source, since the macro would be in the heal sub until the heal finishes. I'll just take it out for now. I'm going to play around with a couple more things tonight, and then I think i'll be pretty well done with this. it's been a learning experience.

also, I noticed that the ${NetBots[character].Attacking} isn't a good way to check for combat, because of enrage... I'm experimenting with a veriable for that, unless there is a ${NetBots[character].Engaged} or ${NetBots[character].Combat}. I tested with ${NetBots[].CombatState} but it always returned 3. no matter what I was doing.
Tue Feb 18, 2014 11:12 pm
Well, since I'm tired of working on the macro, it's functional, and I want to just play for awhile, this is my final version for the time being.

Macro
More +

| Events and Chat and Includes
#turbo          40
#chat           tell
#chat           group
#Event          ImDead          "You have been slain by#*#"
#Event          ImDead          "You died."
#event          Zoned           "You have entered#*#"
#event          Zoned           "LOADING, PLEASE WAIT..."
#event          ImHit           "#*#hits YOU for#*#"
#Event          Thirsty         "#*#are thirsty#*#"
#Event          Hungry          "#*#are hungry#*#"
#Event          EnrageOn        "#*#|${Target.CleanName}| has become ENRAGED#*#"
#Event          EnrageOff       "#*#|${Target.CleanName}| is no longer enraged#*#"
#Event          Zoning          "You have entered#*#"
#include        ninjadvloot.inc


Sub Main

/if (${Me.Class.ShortName.NotEqual[CLR]}) {
        /echo Sorry you are not a Cleric.
    /echo I'm afraid this macro to PC relationship just isn't going to work out.
    /echo I do hope we can still be friends though.
    /end
}

| - Detect AA spell gems
| ################## Setup AA Extra gem slot variables

        /if (${Me.AltAbility[Mnemonic Retention]}>=3) /multiline ;      /declare  Gem9 int outer  1 ; /declare Gem9Spell        outer

| name the main tank
/declare tank                           string outer    Feldorn

| Declare the Spells here
/declare heal                           outer           "Ancient: Hallowed Light"
/declare healGem                        int     outer   1
/declare grpHeal                        outer           "Word of Vivification"
/declare grpHealGem                     int     outer   2
/declare hot                            outer           "Pious Elixir"
/declare hotGem                         int     outer   3
/declare vie                            outer           "Panoply of Vie"
/declare vieGem                         int     outer   4
/declare di                                     outer           "Divine Intervention"
/declare diGem                          int     outer   5
/declare pac                            outer           "Placate"
/declare pagGem                         int     outer   6
/declare ohShit                         outer           "Divine Barrier"
/declare ohShitGem                      int     outer   9
/declare gate                           outer           "Gate"
/declare drink                          outer           "Summon Drink"
/declare food                           outer           "Summon Food"
/declare root                           outer           "Petrifying Earth"
/declare pet                            outer           "Unswerving Hammer of Retribution"
/declare miscGem                        int     outer   8
/declare spellID                        int local

/declare Bot                            bool outer      FALSE
/declare Verbose                        int     outer   1
/declare Enraged                        bool outer      FALSE
/declare enrageTimer            timer outer 0s

/declare healAt                         int     outer   65
/declare CastRetryTime          string outer 15s

|Item Clicky Declares
/declare manaOrb                outer   "Orb of Spirits"
/declare orbTimer                       timer outer 0m
/declare epic                           outer   "Ancient Shield of the Divine"
/declare epicTimer                      timer outer 0m

| Declares for NetBots
/declare NBToon1                        outer
/declare NBToon2                        outer
/declare NBToon3                        outer
/declare NBToon4                        outer
/declare NBToon5                        outer
/declare NBToon6                        outer

/echo Tank=${tank}
/echo TankID=${Spawn[=${tank}].ID}

/if (!${Bot}) /call Start1

|Main Loop, Add other loop and a connector /if command
:Main
/call Heal
/doevents
/call GrpHeal
/call OhShit
/call CheckMana
/if ( !${NetBots[${tank}].Attacking} && !${Enraged} ) /call DivineIntervention
/if ( !${NetBots[${tank}].Attacking} && !${Enraged} ) /call TankVie
/if ( ${Enraged} && ${NetBots[${tank}].TargetID}==NULL || ${enrageTimer}==0 ) /varset Enraged FALSE
/goto :Main

/return

| Subs below here.

Sub Start1
/varset Bot TRUE
/declare x int local
        /for x 1 to ${NetBots.Counts}
        /varset NBToon${x} ${NetBots.Client.Token[${x}, ]}
        /next x
/g NetBots Array loaded and ready!
/return


Sub Heal
/if (${Me.Casting[${Spell[${heal}].ID}].ID} || ${Me.Casting[${Spell[${grpHeal}].ID}].ID} || ${Me.Moving}) /return
/if (${NetBots[${tank}].PctHPs}<=${healAt} && ${NetBots[${tank}].InZone}) {
        /if (!${Me.Casting[${Spell[${heal}].ID}].ID}) /interrupt
        /g Incoming << ${heal} >> for ${Target} ...
        /casting ${heal} gem${healGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
        }
/return


Sub GrpHeal
/if (${Me.Casting[${Spell[${heal}].ID}].ID} || ${Me.Casting[${Spell[${grpHeal}].ID}].ID} || ${Me.Moving}) /return
/declare i int local
/declare x int local
/for x 0 to 5
/for i 0 to 5
/if (${x} == ${i}) /next i
/if (${Group.Member[${i}].Distance}<=100 && ${Group.Member[${i}].PctHPs}<70 && ${Group.Member[${i}].Type.Equal[PC]} && ${Group.Member[${x}].Distance}<=100 && ${Group.Member[${x}].PctHPs}<70 && ${Group.Member[${x}].Type.Equal[PC]}) /call CastGrpHeal
/next i
/next x
/return


Sub CastGrpHeal
/if ( ${epicTimer}==0 ) {
/casting "Ancient Shield of Divinity" item ${CastRetryTime}
/g Epic 1.5 Balance
/varset epicTimer 5m
/return
}
/if (${AltAbilityReady[Divine Arbitration]} && !${FindItem[Ancient Shield of Divinity].Timer}==0) {
/casting "Divine Arbitration" alt
/g AA Balance
/return
}
/casting ${grpHeal} gem${grpHealGem} -maxtries|5
/echo Gheal Inc
/gsay Grp Heal Inc, Hang in there dudes!
/return


Sub DivineIntervention
/if (${NetBots[${tank}].Attacking} || ${Enraged} || !${Cast.Ready[${di}]} || ${Me.Casting.ID} || ${Me.Moving}) /return
/if (${Me.PctMana}>40) {
        /declare x int local
        /for x 1 to ${NetBots.Counts}
                /if ( !${NetBots[${NBToon${x}}].Buff.Find[${Spell[${di}].ID}]} && ${NetBots[${NBToon${x}}].InZone} && ${NetBots[${NBToon${x}}].InGroup} ) {
                        /g Buffing << ${di} on ${Target} >>
                        /casting ${di} gem${diGem} -maxtries|5 -targetid|${NetBots[${NBToon${x}}].ID} /return
                }
        /next x
}
/return

Sub TankVie
/if (${NetBots[${tank}].Attacking} || ${Enraged} || !${Cast.Ready[${vie}]} || ${Me.Casting.ID} || ${Me.Moving}) /return
/if (${Me.PctMana}>30) {
        /if ( !${NetBots[${tank}].Buff.Find[${Spell[${vie}].ID}]} && !${NetBots[${tank}].Attacking} && ${NetBots[${tank}].FreeBuffSlots}>=1 && ${NetBots[${tank}].InZone} && ${NetBots[${tank}].InGroup} ) {
                /g Buffing << ${vie} on ${tank} >>
                /casting ${vie} gem${vieGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
        }
}
/return

Sub CheckMana
/if ( ${Me.PctMana}<=18 && ${orbTimer}==0 ) {
        /g Need, mana, using Orb of Spirits, 10 second cast!
        /casting "Orb of Spirits" item 15s
        /varset orbTimer 5m
        /g I now have ${Me.PctMana} % Mana
        }
/return

Sub OhShit
/if ( ${Me.PctHPs}<=30 ) {
        /g Help me ${tank}, you're my only hope!
        /interrupt
        /delay 1
        /casting ${ohShit} gem${ohShitGem} -maxtries|5 -targetid|${Me.ID}
        }
/return


|Chat Trigger events check #chat {Setting
Sub Event_Chat(string ChatType,string ChatSender,string ChatText)
/if (${Select[${ChatText},tank]}) {
    /varset tank ${ChatSender.Right[-2].Left[-1]}
    /echo Main Assist Changed to ${tank}
    }
/if (${Select[${ChatText},vie]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${vie} gem${vieGem} -maxtries|4
    /echo Casting ${vie} on ${Target.CleanName}
    }
/if (${Select[${ChatText},di]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${di} gem${diGem} -maxtries|4
    /echo Casting ${di} on ${Target.CleanName}
    }
/if (${Select[${ChatText},pacify]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${pac} gem${pacGem} -maxtries|4 -targetid|${NetBots[${tank}].TargetID}
    /echo Casting ${pac} on ${Target.CleanName}
    }
/return


|Events
Sub Event_ImHit
        /g I'm under attack!
/return

Sub Event_Zoned
        /delay 40s
/return

Sub Event_EnrageOn
        /varset Enraged TRUE
        /varset enrageTimer 10s
/return

Sub Event_EnrageOff
        /varset Enraged FALSE
/return

| ################## Hungry
Sub Event_Hungry
  /if (${Engaged}) /return
  /echo I am Hungry
  /if (${Verbose}) /gsay Summoning Food, hold pulls for 30 secs.
  /declare i int local
  /for i 1 to 8
     /call cast "${food}" gem${miscGem} ${CastRetryTime}
        /delay 1
           /autoinventory
    /delay 1
  /next i
  /if (${Verbose}) /gsay Ready for pulls again.
/return
| ################## Thirsty
Sub Event_Thirsty
  /if (${Engaged}) /return
  /echo I am Thirsty
  /if (${Verbose}) /gsay Summoning Drink, hold pulls for 30 secs.
  /declare i int local
  /for i 1 to 8
    /call cast "${drink}" gem${miscGem} ${CastRetryTime}
        /delay 1
    /autoinventory
    /delay 1
  /next i
  /if (${Verbose}) /gsay Ready for pulls again.
/return


Sub Event_ImDead
/end


It would be a little cleaner if I could find out how to test if my tank or group is in combat, but I'm not sure how to do that, so the ${Enraged} variable was added as a Band-Aid.

Hopefully someone gets some use out of this, Grumble gave a lot of awesome pointers.
Wed Feb 19, 2014 12:46 am
In some instances you can check ${Me.Combat} and in others you can check through NetBots.
For a helper macro I define who my main assist is and declare that as ${MA}
/if (${NetBots[${MA}].InZone} && ${NetBots[${MA}].Attacking})
Wed Feb 19, 2014 10:15 am
Listen to This Guy
Thanks for the suggestion warmonger, but I use .Attacking. The issue is that fails during Enrage. ${Me.Combat} seems to return the same as .Attacking
Wed Feb 19, 2014 5:20 pm
${Melee.Combat} can be used by your warrior and works during enrage but I don't think there is a way for your cleric to check the warrior's ${Melee.Combat} status.

While the warrior is attacking, you can save the targetID of the target and check to see if that mob is still up.

You can also check your warrior's targetID and targetHP. If targetHP is 10% or below, assume enrage even if combat isn't on.

It would be a little cleaner if I could find out how to test if my tank or group is in combat, but I'm not sure how to do that, so the ${Enraged} variable was added as a Band-Aid.


Dedicated botting macros use several methods:
1. Explicit message sent via /bca - /bca AwesomeMacroMessageThatWon'tAccidentallyBeDetected Assist=${Target.ID}. Use an event to check for that message which parses the targetID. The message can be sent manually (like an assist me hotkey) or via macro run by your tank.
2. Continuously track the tank's targetID and HP. If there is a target and it's HP is below a certain threshold, assume it's beating on you and you on it.
3. Keep track of the number of mobs in the area. Not really a standalone check, but can be a good double check.
4. Use/read the group/raid target icons from leadership AAs. Not sure if these are fully functioning on emulator servers though.

edit:
Option 3 is powerful enough to prevent entering the DI and Vie buffing subs. You just have to remember that when your cleric isn't buffing while standing next to non-aggro NPCs.
Wed Feb 19, 2014 7:19 pm
Senior Project Member
http://www.macroquest2.com/wiki/index.php/TLO:Me
http://www.macroquest2.com/wiki/index.php/MQ2Melee
http://www.macroquest2.com/wiki/index.php/MQ2NetBots

So you have
1) TLO:Me
2) MQ2Melee
3) MQ2NetBots

Just depends on what method you want to use or will work depending on the situation.
I do not use melee so can not offer advice there, but I do use netbots.
Considering you said you wanted to basically be able to check from your cleric if your tank was in combat, its the method I would go with.

If there is another method or a preferred way people have I would love to see examples. When we get going on discussions here on the forums we all learn something.
Wed Feb 19, 2014 10:39 pm
Listen to This Guy
Macro
More +

| Events and Chat and Includes
#turbo          40
#chat           tell
#chat           group
#Event          ImDead          "You have been slain by#*#"
#Event          ImDead          "You died."
#event          Zoned           "You have entered#*#"
#event          Zoned           "LOADING, PLEASE WAIT..."
#event          ImHit           "#*#hits YOU for#*#"
#Event          Thirsty         "#*#are thirsty#*#"
#Event          Hungry          "#*#are hungry#*#"
#Event          EnrageOn        "#*#|${Target.CleanName}| has become ENRAGED#*#"
#Event          EnrageOff       "#*#|${Target.CleanName}| is no longer enraged#*#"
#Event          Zoning          "You have entered#*#"
#include        ninjadvloot.inc


Sub Main

/if (${Me.Class.ShortName.NotEqual[CLR]}) {
        /echo Sorry you are not a Cleric.
    /echo I'm afraid this macro to PC relationship just isn't going to work out.
    /echo I do hope we can still be friends though.
    /end
}

| - Detect AA spell gems
| ################## Setup AA Extra gem slot variables

        /if (${Me.AltAbility[Mnemonic Retention]}>=3) /multiline ;      /declare  Gem9 int outer  1 ; /declare Gem9Spell        outer

| name the main tank
/declare tank                           string outer    Feldorn

| Declare the Spells here
/declare heal                           outer           "Ancient: Hallowed Light"
/declare healGem                        int     outer   1
/declare grpHeal                        outer           "Word of Vivification"
/declare grpHealGem                     int     outer   2
/declare hot                            outer           "Pious Elixir"
/declare hotGem                         int     outer   3
/declare vie                            outer           "Panoply of Vie"
/declare vieGem                         int     outer   4
/declare di                                     outer           "Divine Intervention"
/declare diGem                          int     outer   5
/declare pac                            outer           "Placate"
/declare pagGem                         int     outer   6
/declare ohShit                         outer           "Divine Barrier"
/declare ohShitGem                      int     outer   9
/declare gate                           outer           "Gate"
/declare drink                          outer           "Summon Drink"
/declare food                           outer           "Summon Food"
/declare root                           outer           "Petrifying Earth"
/declare pet                            outer           "Unswerving Hammer of Retribution"
/declare miscGem                        int     outer   8
/declare spellID                        int local

/declare Bot                            bool outer      FALSE
/declare Verbose                        int     outer   1
/declare Enraged                        bool outer      FALSE
/declare enrageTimer            timer outer 0s

/declare healAt                         int     outer   65
/declare CastRetryTime          string outer 15s

|Item Clicky Declares
/declare manaOrb                outer   "Orb of Spirits"
/declare orbTimer                       timer outer 0m
/declare epic                           outer   "Ancient Shield of the Divine"
/declare epicTimer                      timer outer 0s

| Declares for NetBots
/declare NBToon1                        outer
/declare NBToon2                        outer
/declare NBToon3                        outer
/declare NBToon4                        outer
/declare NBToon5                        outer
/declare NBToon6                        outer

/echo Tank=${tank}
/echo TankID=${Spawn[=${tank}].ID}

/if (!${Bot}) /call Start1

|Main Loop, Add other loop and a connector /if command
:Main
/call Heal
/doevents
/call GrpHeal
/call OhShit
/call CheckMana
/if ( !${NetBots[${tank}].Attacking} && !${Enraged} ) /call DivineIntervention
/if ( !${NetBots[${tank}].Attacking} && !${Enraged} ) /call TankVie
/if ( ${Enraged} && ${enrageTimer}==0 ) /varset Enraged FALSE
/goto :Main

/return

| Subs below here.

Sub Start1
/varset Bot TRUE
/declare x int local
/echo Building NetBots Array
        /for x 1 to ${NetBots.Counts}
        /varset NBToon${x} ${NetBots.Client.Token[${x}, ]}
                /echo ${NetBots[${NBToon${x}}].Name}
        /next x
/g NetBots Array loaded and ready!
/return


Sub Heal
/if (${Me.Casting[${Spell[${heal}].ID}].ID} || ${Me.Casting[${Spell[${grpHeal}].ID}].ID} || ${Me.Moving}) /return
/if (${NetBots[${tank}].PctHPs}<=${healAt} && ${NetBots[${tank}].InZone}) {
        /if (!${Me.Casting[${Spell[${heal}].ID}].ID}) /interrupt
        /casting ${heal} gem${healGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
        /g Incoming << ${heal} >> for ${Target} ...
        }
/return


Sub GrpHeal
/if (${Me.Casting[${Spell[${heal}].ID}].ID} || ${Me.Casting[${Spell[${grpHeal}].ID}].ID} || ${Me.Moving}) /return
/declare i int local
/declare x int local
/for x 0 to 5
/for i 0 to 5
/if (${x} == ${i}) /next i
/if (${Group.Member[${i}].Distance}<=100 && ${Group.Member[${i}].PctHPs}<70 && ${Group.Member[${i}].Type.Equal[PC]} && ${Group.Member[${x}].Distance}<=100 && ${Group.Member[${x}].PctHPs}<70 && ${Group.Member[${x}].Type.Equal[PC]}) /call CastGrpHeal
/next i
/next x
/return


Sub CastGrpHeal
/if ( ${epicTimer}==0 ) {
/casting ${epic} item
/g Epic 1.5 Balance
/varset epicTimer 150s
/return
}
/if (${AltAbilityReady[Divine Arbitration]} && !${FindItem[${epic}].Timer}==0) {
/casting "Divine Arbitration" alt
/g AA Balance
/return
}
/casting ${grpHeal} gem${grpHealGem} -maxtries|5
/echo Gheal Inc
/gsay Grp Heal Inc, Hang in there dudes!
/return


Sub DivineIntervention
/if (${NetBots[${tank}].Attacking} || ${Enraged} || !${Cast.Ready[${di}]} || ${Me.Casting.ID} || ${Me.Moving}) /return
/if (${Me.PctMana}>40) {
        /declare x int local
        /for x 1 to ${NetBots.Counts}
                /if ( !${NetBots[${NBToon${x}}].Buff.Find[${Spell[${di}].ID}]} && ${Spawn[${NetBots[${NBToon${x}}]}].Distance}<90 && ${NetBots[${NBToon${x}}].InGroup} ) {
                        /g Buffing << ${di} on ${NetBots[${NBToon${x}}].Name} >>
                        /casting ${di} gem${diGem} -maxtries|5 -targetid|${NetBots[${NBToon${x}}].ID}
                        /return
                }
        /next x
}
/return

Sub TankVie
/if (${NetBots[${tank}].Attacking} || ${Enraged} || !${Cast.Ready[${vie}]} || ${Me.Casting.ID} || ${Me.Moving}) /return
/if ( ${Me.PctMana}>30 && !${NetBots[${tank}].Buff.Find[${Spell[${vie}].ID}]} && !${NetBots[${tank}].Attacking} && ${NetBots[${tank}].FreeBuffSlots}>=1 && ${Spawn[${NetBots[${tank}]}].Distance}<90 && ${NetBots[${tank}].InGroup} ) {
        /g Buffing << ${vie} on ${tank} >>
        /casting ${vie} gem${vieGem} -maxtries|5 -targetid|${NetBots[${tank}].ID}
               
}
/return

Sub CheckMana
/if ( ${Me.PctMana}<=18 && ${orbTimer}==0 ) {
        /g Need, mana, using Orb of Spirits, 10 second cast!
        /casting "Orb of Spirits" item 15s
        /varset orbTimer 5m
        /g I now have ${Me.PctMana} % Mana
        }
/return

Sub OhShit
/if ( ${Me.PctHPs}<=30 && ${Cast.Ready[${ohShit}]} && !${Me.Moving} ) {
        /if ( !{${Me.Casting[${Spell[${ohShit}].ID}].ID} || !{${Me.Casting[${Spell[${heal}].ID}].ID} || !{${Me.Casting[${Spell[${grpHeal}].ID}].ID} ) /interrupt
        /g Help me ${tank}, you're my only hope!
        /casting ${ohShit} gem${ohShitGem} -maxtries|5 -targetid|${Me.ID}
}
/return


|Chat Trigger events check #chat {Setting
Sub Event_Chat(string ChatType,string ChatSender,string ChatText)
/if (${Select[${ChatText},tank]}) {
    /varset tank ${ChatSender.Right[-2].Left[-1]}
    /echo Main Assist Changed to ${tank}
    }
/if (${Select[${ChatText},vie]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${vie} gem${vieGem} -maxtries|4
    /echo Casting ${vie} on ${Target.CleanName}
    }
/if (${Select[${ChatText},hot]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${hot} gem${hotGem} -maxtries|4
    /echo Casting ${hot} on ${Target.CleanName}
    }
/if (${Select[${ChatText},di]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${di} gem${diGem} -maxtries|4
    /echo Casting ${di} on ${Target.CleanName}
    }
/if (${Select[${ChatText},pacify]}) {
    /target ${ChatSender.Right[-2].Left[-1]}
    /casting ${pac} gem${pacGem} -maxtries|4 -targetid|${NetBots[${tank}].TargetID}
    /echo Casting ${pac} on ${Target.CleanName}
    }
/return


|Events
Sub Event_ImHit
        /g I'm under attack!
/return

Sub Event_Zoned
        /delay 40s
/return

Sub Event_EnrageOn
        /varset Enraged TRUE
        /varset enrageTimer 10s
/return

Sub Event_EnrageOff
        /varset Enraged FALSE
/return

| ################## Hungry
Sub Event_Hungry
  /if (${Engaged}) /return
  /echo I am Hungry
  /if (${Verbose}) /gsay Summoning Food, hold pulls for 30 secs.
  /declare i int local
  /for i 1 to 5
     /call cast "${food}" gem${miscGem} ${CastRetryTime}
        /delay 1
           /autoinventory
    /delay 1
  /next i
  /if (${Verbose}) /gsay Ready for pulls again.
/return
| ################## Thirsty
Sub Event_Thirsty
  /if (${Engaged}) /return
  /echo I am Thirsty
  /if (${Verbose}) /gsay Summoning Drink, hold pulls for 30 secs.
  /declare i int local
  /for i 1 to 5
    /call cast "${drink}" gem${miscGem} ${CastRetryTime}
        /delay 1
    /autoinventory
    /delay 1
  /next i
  /if (${Verbose}) /gsay Ready for pulls again.
/return

Sub Event_ImDead
/end


Cleaned up some minor errors, seems to be functioning pretty well though.
Wed Feb 26, 2014 12:16 am
I recommend modifying your event for handling Enrage.

As it stands:

Macro
More +
#Event          EnrageOn        "#*#|${Target.CleanName}| has become ENRAGED#*#"
#Event          EnrageOff       "#*#|${Target.CleanName}| is no longer enraged#*#"


calls the respective subs
Macro
More +
Sub Event_EnrageOn
        /varset Enraged TRUE
        /varset enrageTimer 10s
/return

Sub Event_EnrageOff
        /varset Enraged FALSE
/return


But that has the potential to return false positives in an instance where multiple mobs share the same CleanName (which is very often in EQ). Perhaps you should add a check in your event subs to make sure your assist target is below the enrage threshold before doing a /varset on Enraged. [/syntax]
Sun Mar 23, 2014 3:24 pm
Goto page Previous  1, 2, 3  Next Public Macros Looking for some help on this Cleric macro
Reply