help me modify this macro

Need help with a macro you are writing? Ask here!

Moderator: MacroQuest Developers

crash4
decaying skeleton
decaying skeleton
Posts: 7
Joined: Sat Dec 27, 2003 12:15 am

help me modify this macro

Post by crash4 » Fri May 21, 2004 4:30 am

I have been using the autobard macro from http://macroquest2.com/phpBB2/viewtopic.php?t=6877 and it works really well as written, but I fight in close quarters some and the movebehind code was causing my bard to spend a lot of time running into a wall and not face the mob. I added a toggle feature that works to an extent, but now my bard spends a lot of time out of melee range. I would like to stick closer to the mob when the get behind code is turned off. Could someone look at my code and tell me if there is an easy fix? Or if I did my switching completely wrong and that is the actual problem. Here is what I have with my changes:

Code: Select all

|AutoBard 2.0l   5-1-2004
|---------------------------------------------------------------------- 
| By Cunning. 
| Original AutoRogue by Jay. 
| Credits to GrimJack for the getbehind and moveto logic from GenBot.
| 
| 
|  I did nothing code wise but add ml2517 Combat/NoCombat Twist macro, remove rogue stuff 
|  Left behind code in, all Credit to them, Omiine 
| 
| Usage: /macro bard.mac Assist HpPct AnchorBit NoCombatSongs CombatSongs Follow 
| 
| Examples: 
|     Assist tank at 95% 
|       /macro bard.mac Happytank 95 0 454 563   (or leave the zero off) 
| 
|     Assist tank at 95%, set anchor at current loc 
|       /macro bard.mac Happytank 95 1 454 563 
| 
|     Same as above but moveto/follow a target between fights 
|       /macro bard.mac Happytank 95 2 454 563 Stationarycleric 
| 
| DON'T FORGET TO VIEW/MODIFY YOUR bard.INC FILE!!! 
| 
| 
| Version History 
|     2.0l -  Changed Target.MaxRange to Target.MaxRangeTo. 
|             Removed some unnecessary delay instances from combat loop. 
|             Upped turbo to 40 for shits/giggles. 
|             Added a new boolean in custom.inc, bUseStrike. 
|           Fixed a logic bug in CheckDefSpecial (was causing a pause in macro if you got hit).            
|     2.0k -  MQ2DataVars conversion. 
|     2.0j -  Getbehind working...again... 
|     2.0i -  Fixed the weird running in circles on anchor. 
|             Fixed the crazy wobble that getbehind would do in certain instances. 
|             Changed all /face nolook fast calls back to /face fast.  Wasn't a good idea. 
|             Tweaked melee distance on chase. 
|     2.0h -  Bugfixes in GetBehind and the zonechange event. 
|     2.0g -  MQ2Data phase 2 conversion. 
|     2.0f -  Added GM detection (script will pause when gm in zone, resume after) 
|     2.0e -  Chase range improved! 
|     2.0d -  Fixed target moveto on engage.  Set sStrikeDisc to 0 also available as option. 
|     2.0c -  Added delays to address crashing issue. 
|     2.0b -  Bugfixes (hopefully).  The iSetAnchor param is changed too (read above). 
|     2.0a -  Added follow distance and replaced depreciated /sendkey's. 
|     2.0  -  Added rogue offensive and defensive discipline usage option. 
|             Lots of code fixes/optimizations.  Options in custom.inc. 
|     1.9  -  Added move to anchor and move to/follow target 
|             options between fights.  Fixed sneak/hide after fight. 
|             Other minor code cleanup. 
|     1.8  -  Cleaned up some of the code, tossed the xp stuff 
|             and fixed events, evade and getbehind. 
|     1.7  -  Base code (Jay's script) 

#turbo 30 

#Event Enraged "has become ENRAGED" 
#Event Offrage "is no longer enraged" 
#Event Slainby "You have been slain by" 
#Event Zonechange "You have entered"
#Event ToggleGBOn "[MQ2] GetBehind On"
#Event ToggleGBOff "[MQ2] GetBehind Off"

Sub Main
    [color=red]/declare GBToggle int outer [/color]   
    /declare bAttackTarget bool outer 
    /declare AnchorX float outer 
    /declare AnchorY float outer 
    /declare fXLoc float outer 
    /declare fYLoc float outer 
    /declare iSetAnchor int outer 
    /declare sFollowTarget string outer 

    /declare iAssistHealthPct int local 
    /declare iTargetId int local 
    /declare iTargetIdTmp int local    
    /declare sAssistName string local 
    /declare sTargetName string local 

    /declare NonCombatGems int outer 
    /declare CombatGems int outer 
    /declare CombatCurSong int outer 
    /declare NonCombatCurSong int outer 
    /declare NNonCombatSongs int outer 
    /declare NCombatSongs int outer 
    /declare NonCombatSongList string outer 
    /declare CombatSongList string outer 
    /declare TwistI int outer 
    /declare DynamicBuffer int outer 
    /declare NonCombatSongArray[30] int outer 
    /declare CombatSongArray[30] int outer 
    /declare SingTime timer outer 

    
    [color=red]/varset GBToggle 0[/color]
    /varset iTargetIdTmp 0 
    
    /echo AutoBard v. 2.0l Started.
    [color=red]/echo Get Behind is set to OFF[/color] 

    /if (${Defined[Param0]}) { 
       /varset sAssistName ${Param0}              
    } else { 
        /echo Error:  The name of your assist is not optional. 
        /echo Usage:  /macro bard.mac AssistName <AssistHpPct> <AnchorFlag>  <NoCombatSongs> <CombatSongs> <sFollowTarget> 
    } 
        
    /if (${Defined[Param1]}) { 
        /varset iAssistHealthPct ${Param1}        
    } else /varset iAssistHealthPct 90 
    
    /if (${Defined[Param2]}) { 
       /varset iSetAnchor ${Param2}              
       /if (${iSetAnchor}==2) { 
           /if (${Defined[Param5]}) { 
              /varset sFollowTarget ${Param5} 
           } else /varset sFollowTarget ${sAssistName} 
         } 
   } else /varset iSetAnchor 0 

    /if (${Defined[Param3]}) { 
        /varset NonCombatGems ${Param3}        
    } else /varset NonCombatGems 8 

    /if (${Defined[Param4]}) { 
        /varset CombatGems ${Param4}        
    } else /varset CombatGems 6      
    
   #include bard.inc 

    /varset CombatCurSong 1 
    /varset NonCombatCurSong 1 
    /varset NNonCombatSongs ${Int[${String[${NonCombatGems}].Length}]} 
    /if (${Defined[CombatGems]}) /varset NCombatSongs ${Int[${String[${CombatGems}].Length}]} 
    /varset NonCombatSongList ${NonCombatGems} 
    /if (${Defined[CombatGems]}) /varset CombatSongList ${CombatGems} 
    /varset DynamicBuffer 5 

    /for TwistI 1 to ${NNonCombatSongs} 
        /varset NonCombatSongArray[${TwistI}] ${String["${NonCombatSongList}"].Mid[${TwistI},1]} 
    /next TwistI 

    /if (${Defined[CombatGems]}) {  
        /for TwistI 1 to ${NCombatSongs} 
            /varset CombatSongArray[${TwistI}] ${String["${CombatSongList}"].Mid[${TwistI},1]} 
        /next TwistI 
    } 

    /echo ${sAssistName} is main assist. 
    /echo Will start combat when MA target is at ${iAssistHealthPct}%. 
    
    /assist off 
    /attack off 
        
    /if (${iSetAnchor}==1) { 
        /varset AnchorX ${Me.X} 
        /varset AnchorY ${Me.Y} 
        /echo Created anchor at Loc: ${AnchorY}, ${AnchorX}. 
    } 
    
    /if (${iSetAnchor}==2) { 
        /target ${sFollowTarget} 
        /delay 5 
        /if (!${Target.ID}) /varset sFollowTarget ${sAssistName} 
        /echo Created MoveToTarget: ${sFollowTarget}. 
    } 
      
    
    /echo Waiting for ${sAssistName} to select a new target... 
    
:Wait 
    /delay 1    

    /doevents 

    /if (${Me.Standing}) { 
        /if ((!${Me.Combat})||(!${Defined[CombatGems]})) /call NonCombatSing ${NonCombatSongArray[${NonCombatCurSong}]} 
    } 
   /if (${Me.State.Equal["DUCK"]}) /keypress DUCK 
   /if (!${Me.Standing}) /stand 
    
    /call CheckAnchor 

    /assist ${sAssistName} 
    /delay 4 
    
    /if (!${Target.ID}) /goto :Wait 
    /if (!${Target.Type.Equal["NPC"]}) /goto :Wait 
    /if (${Target.CleanName.Equal[${Me.Name}]}) /goto :Wait 
    
    /if (${iTargetIdTmp}!=${Target.PctHPs}) /echo ${Target.CleanName} targeted at ${Target.PctHPs} %hp, distance ${Target.Distance}. 
    
    /varset iTargetIdTmp ${Target.PctHPs} 

    /if (${Target.PctHPs}<=${iAssistHealthPct} && ${Target.Distance}<${iEngageDistance}) /goto :Attack 

    /goto :Wait 


:Attack 
    /echo Fighting ${Target.CleanName} | ${Target.Level} ${Target.Class.Name}. 
    /varset sTargetName ${Target.CleanName} 
    /varset iTargetId ${Target.ID} 
    /varset bAttackTarget 1 
      
    /call MoveTo 
    [color=red]/if (${GBToggle} == 1) { [/color]
        /call GetBehind
    [color=red]}[/color]      
    /face nolook fast 


:AttackLoop 
    /assist ${sAssistName} 
    
    /doevents 

    /if (!${Target.ID}) /goto :AttackEnd 
       /if (${Target.ID}!=${iTargetId}) /goto :AttackEnd 

    /if (${Me.Standing}) { 
   /if (${Defined[CombatGems]}) /if (${Me.Combat}) /call CombatSing ${CombatSongArray[${CombatCurSong}]} 
    } 
   /if (${Me.State.Equal["DUCK"]}) /keypress DUCK 
   /if (!${Me.Standing}) /stand     

    [color=red]/if (${GBToggle} == 1) { [/color]
        /call GetBehind
    [color=red]}[/color]
 
   /call CheckMeleeRange  
    
    /if (${bAttackTarget}) { 
        
        /if (${Target.Distance}<${Target.MaxRangeTo} ) { 
        /attack on 
    } 
    
    /doevents        

    /if (!${bAttackTarget}) /Attack off 
    /if (!${bAttackTarget}) /Attack on 

            

    /goto :AttackLoop 

:AttackEnd 
    /echo Combat with ${sTargetName} has ended. 
    /keypress forward 
    /keypress back 
    /varset iTargetIdTmp 0 

    /varset bAttackTarget 0 
    /attack off 

    /echo Waiting for ${sAssistName} to select a new target. 
    
    /goto :Wait 

/endmacro 

Sub CheckMeleeRange 
   /if (!${Target.ID}) /return 

    /face nolook fast 
    
    /if (${Target.Distance}>${Target.MaxRangeTo}*2) /call MoveTo 
    /if (${Target.Distance}>${Target.MaxRangeTo}) /keypress forward hold |If target is farther then MaxRange move forward 
    /if (${Target.Distance}<8) /keypress back hold |If target is closer then 8 move back 
    /if (${Target.Distance}<10) /keypress forward  |If target is closer then 10 stop moving forward 
    /if (${Target.Distance}>9) /keypress back |If target is farther then 9 stop moving back 

    /face nolook fast 
/return 


Sub GetBehind 
    /declare iCount int local 
    
    /varset iCount 0 
    /varset fXLoc ${Me.X} 
    /varset fYLoc ${Me.Y} 

    /if (!${Target.ID}) /goto :noneed 
    /if (${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.DegreesCCW}]}*10]},${Math.Calc[${Target.X}-${Math.Sin[${Target.Heading.DegreesCCW}]}*10]}]}<5) /goto :noneed 
    /if (${Target.Distance}>${Target.MaxRangeTo}*2) /call MoveTo 

    /keypress forward hold 

:gobehindloop 
    /delay 1 
    
    
    /if (!${Target.ID}) { 
       /keypress forward 
       /goto :noneed 
    } 
    
    /if (${iCount}>1) { 
        /if (${fXLoc}==${Me.X} && ${fYLoc}==${Me.Y}) { 
              /keypress forward 
              /goto :noneed 
        } 

        /varset fXLoc ${Me.X} 
        /varset fYLoc ${Me.Y} 
        /varset iCount 0 
    } 
    
    /varcalc iCount ${iCount}+1 
    /doevents 

    /face nolook fast loc ${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.DegreesCCW}]}*10]},${Math.Calc[${Target.X}-${Math.Sin[${Target.Heading.DegreesCCW}]}*10]} 
    /if (${Math.Distance[${Math.Calc[${Target.Y}-${Math.Cos[${Target.Heading.DegreesCCW}]}*10]},${Math.Calc[${Target.X}-${Math.Sin[${Target.Heading.DegreesCCW}]}*10]}]}>3) /goto :gobehindloop 

    /keypress forward 
    /face nolook fast 

:noneed 

/return 


Sub CheckAnchor 
    
    
    /if (${iSetAnchor}==1) /if (${Math.Distance[${AnchorY},${AnchorX}]}>12) /call MoveToAnchor 
    
    /if (${iSetAnchor}==2) { 
        /target ${sFollowTarget} 
        /delay 4 
        /if (${Target.Distance}>${Target.MaxRangeTo} && ${Target.ID} && ${Target.CleanName.NotEqual[${Me.CleanName}]}) /call MoveTo 
    }      
/return 



Sub MoveTo 
    /declare iCount int local 
    
    /varset iCount 0 
    /varset fXLoc ${Me.X} 
    /varset fYLoc ${Me.Y} 

    /if (!${Target.ID}) { 
       /keypress forward 
       /return 
    } 
    
    /if (${Target.Distance}<${Target.MaxRangeTo}) { 
       /keypress forward 
       /return 
    } 
    
    /echo Moving to Target: ${Target.CleanName}. 

:fastmoveloop 
   /delay 1 
   /doevents 
    
    /if (!${Target.ID}) { 
        /keypress forward 
        /return 
    } 
    
    /face nolook fast 

    /if (${Target.Distance}>${Target.MaxRangeTo}) /keypress forward hold 

    /if (${Target.Distance}<${Target.MaxRangeTo}) { 
        /keypress forward 
        /return 
    } 
    
    /if (${iCount}>2) { 
        /call Detectobst 
        /face nolook fast 
        /varset iCount 0 
    } 
    
    /if (${Target.Distance}>${Math.Calc[${Target.MaxRangeTo}*2]}) /varcalc iCount ${iCount}+1 
    /goto :fastmoveloop 
/return 


Sub MoveToAnchor 
    /declare iCount int local 

    /varset fXLoc ${Me.X} 
    /varset fYLoc ${Me.Y} 
    /varset iCount 0 

    /echo Moving to Anchor at Loc: ${AnchorY}, ${AnchorX}. 

:AnchorMoveLoop  
    /delay 1 
    /doevents 
    /face nolook loc ${AnchorY},${AnchorX} 
    
    /if (${Math.Distance[${AnchorY},${AnchorX}]}>12) { 
       /keypress forward hold 
   } else { 
       /keypress forward 
        /return 
    } 

    /if (${iCount}>2) { 
        /call Detectobst 
        /face nolook loc ${AnchorY},${AnchorX} 
        /varset iCount 0 
    } 
    
    /varcalc iCount ${iCount}+1 
    /goto :AnchorMoveLoop 
/return 

Sub Detectobst 
    /delay 2 
    /if (${fXLoc}==${Me.X}) /if (${fYLoc}==${Me.Y}) /call Hitobst 
    /varset fXLoc ${Me.X} 
    /varset fYLoc ${Me.Y} 
/return 

Sub Hitobst 
    /keypress forward 
    /keypress back hold 
    
    /if (${Math.Rand[2]}) {    
        /delay 2s    
        /keypress back 
        /keypress right hold 
        /delay 8 
        /keypress right 
        
        /if (${bUseJump}) { 
           /keypress forward hold 
           /delay 8 
           /keypress jump 
        } 
    } else { 
        /delay 2s 
        /keypress back 
        /keypress left hold 
        /delay 8 
        /keypress left 
        
        /if (${bUseJump}) { 
           /keypress forward hold 
           /delay 8 
           /keypress jump 
        } 
    } 
    /delay 10 
    /keypress forward hold 
/return 

Sub CombatSing(Song) 
     /declare Buffer int local 
     /declare Duration int local 
     /varset Duration 0 

  :CombatSing1 
    /call CheckSong ${Song} 
    /varset Duration ${Macro.Return} 
    /varset SingTime 30 
    /varset Buffer 0    
    /cast "${Me.Gem[${Song}]}" 
  :CombatSing2 
    /delay 1 
    /if (${Me.Casting.ID}) { 
        /if (${SingTime}<=0) /goto :CombatSingBreak 
        /goto :CombatSing2 
    } 
    :CombatSingBreak 
    /if (${SingTime}>0) /goto :CombatSing1 
    /if (${Duration}==0) { 
        /delay ${DynamicBuffer} 
        /stopsong 
    } else { 
      :CombatSing3 
        /varcalc Buffer ${Buffer}+1 
        /delay 1 
        /if (${Buffer}>8) { 
        /stopsong 
        /goto :CombatSing1 
        } 
        /if ((!${Me.Song["${Me.Gem[${Song}]}"].ID})&&(!${Me.Buff["${Me.Gem[${Song}]}"].ID})) /goto :CombatSing3 
        /if ((${Me.Song["${Me.Gem[${Song}]}"].Duration}<${Math.Calc[${Duration}-1]})&&(${Me.Buff["${Me.Gem[${Song}]}"].Duration}<${Math.Calc[${Duration}-1]})) /goto :CombatSing3 
        /varset DynamicBuffer ${Buffer} 
        /stopsong 
    } 
|    /echo Dynamic Buffer: ${DynamicBuffer} 
    /varcalc CombatCurSong ${CombatCurSong}+1 
    /if (${CombatCurSong}>${NCombatSongs}) /varset CombatCurSong 1 
/return 

Sub NonCombatSing(Song) 
     /declare Buffer int local 
     /declare Duration int local 
     /varset Duration 0 

  :NonCombatSing1 
    /call CheckSong ${Song} 
    /varset Duration ${Macro.Return} 
    /varset SingTime 30 
    /varset Buffer 0    
    /cast "${Me.Gem[${Song}]}" 
  :NonCombatSing2 
    /delay 1 
    /if (${Me.Casting.ID}) { 
        /if (${SingTime}<=0) /goto :NonCombatSingBreak 
        /goto :NonCombatSing2 
    } 
    :NonCombatSingBreak 
    /if (${SingTime}>0) /goto :NonCombatSing1 
    /if (${Duration}==0) { 
        /delay ${DynamicBuffer} 
        /stopsong 
    } else { 
      :NonCombatSing3 
        /varcalc Buffer ${Buffer}+1 
        /delay 1 
        /if (${Buffer}>8) { 
        /stopsong 
        /goto :NonCombatSing1 
        } 
        /if ((!${Me.Song["${Me.Gem[${Song}]}"].ID})&&(!${Me.Buff["${Me.Gem[${Song}]}"].ID})) /goto :NonCombatSing3 
        /if ((${Me.Song["${Me.Gem[${Song}]}"].Duration}<${Math.Calc[${Duration}-1]})&&(${Me.Buff["${Me.Gem[${Song}]}"].Duration}<${Math.Calc[${Duration}-1]})) /goto :NonCombatSing3 
        /varset DynamicBuffer ${Buffer} 
        /stopsong 
    } 
|    /echo Dynamic Buffer: ${DynamicBuffer} 
    /varcalc NonCombatCurSong ${NonCombatCurSong}+1 
    /if (${NonCombatCurSong}>${NNonCombatSongs}) /varset NonCombatCurSong 1 
/return 

Sub CheckSong(GemNumber) 
/if (${Me.Gem[${GemNumber}].SpellType.Find["Beneficial"]}) { 
    /if (${Me.Gem[${GemNumber}].TargetType.Find["Group"]} || ${Me.Gem[${GemNumber}].TargetType.Find["Self"]} || ${Me.Gem[${GemNumber}].TargetType.Find["PC"]}) { 
        /return ${Me.Gem[${GemNumber}].Duration} 
    } else { 
        /return 0 
    } 
} else { 
    /return 0 
} 
/return 

| ----- Events called by /DoEvents ----- 

Sub Event_Enraged 
    /varset bAttackTarget 0 
    /attack off 
/return 

Sub Event_Offrage 
    /varset bAttackTarget 1 
    /attack on 
/return 

Sub Event_Zonechange 
   /keypress up 
   /stopsong  
   /endmacro 
/return 

Sub Event_Slainby 
    /keypress up 
    /stopsong 
    /endmacro 
/return 

[color=red]Sub Event_ToggleGBOn
    /varset GBToggle 1
    /echo Get Behind is now set to ON
/return

Sub Event_ToggleGBOff
    /varset GBToggle 0
    /echo Get Behind is now set to OFF
/return[/color]

Code: Select all

| bard.inc 
| Example include file for AutoBard 2.0l 


/declare bUseJump bool outer          | Adds a jump when in collision detection loop.  0 = off 
/declare iEngageDistance int outer   | How close the mob must be to engage 

| <<< Custom Vars:  Modify these according to your taste. >>> 

/varset bUseJump 1 
/varset iEngageDistance 300 
-Crash4

Preocts
a snow griffon
a snow griffon
Posts: 312
Joined: Thu Jan 29, 2004 1:02 pm

Post by Preocts » Fri May 21, 2004 6:04 am

This is the sub you are looking at to adjust the distance at which your bard fights in melee.

Code: Select all

Sub CheckMeleeRange 
   /if (!${Target.ID}) /return 

    /face nolook fast 
    
    /if (${Target.Distance}>${Target.MaxRangeTo}*2) /call MoveTo 
    /if (${Target.Distance}>${Target.MaxRangeTo}) /keypress forward hold |If target is farther then MaxRange move forward 
   [color=red] /if (${Target.Distance}<8) /keypress back hold |If target is closer then 8 move back 
    /if (${Target.Distance}<10) /keypress forward  |If target is closer then 10 stop moving forward 
    /if (${Target.Distance}>9) /keypress back |If target is farther then 9 stop moving back[/color] 

    /face nolook fast 
/return 
Looking at it, it would seem it keeps you pretty damn close to the target, by design. You might try a few things, I personally think the entire sub could use a rewrite for a little more effiecant movement. The /ifs in red, if any, are going to be the cause of your woes. Dunno, I'll see about scanning it later and maybe coming up with some solid ideas.

crash4
decaying skeleton
decaying skeleton
Posts: 7
Joined: Sat Dec 27, 2003 12:15 am

Post by crash4 » Mon May 24, 2004 1:46 am

Thanks for the help Preocts. Even with adjusting those lines it still isn't working like i want it to. I think I'm going to have to just try to rewrite the whole macro to my tastes. Will be good practice for me anyway since I'm trying to teach myself how to write these things :)

-Crash4