| Puller Macro
| Puller.mac
| Revised: by Maskoi
| Author Alatyami: Ripped by robdawg :Ripped by Jdelpheki :Ripped Again By hakcenter
#turbo 40
#Event Slain "#*# slain#*#"
#Event Slain "#*#You gain#*#experience#*#"
#Event Zoned "LOADING, PLEASE WAIT..."
#Event CantSee "You cannot see your target."
#include spell_routines.inc
#include Ninjadvloot.inc
Sub Main
|-------------------------------------------------------------------------------------
| Select Pull AA (Alt Ability), Disc (Combat Ability) or Weapon
| Pull with 0=melee 1=Alt Ability 2=spell 3=disc/combat ability 4=ranged attacked
|-------------------------------------------------------------------------------------
/declare PullMethod int outer 1
/declare PullAA string outer Boastful Bellow
/declare PullCombatAbility string outer Throw Stone
/declare PullSpell string outer Sha's Revenge
/declare PullSpellGem int outer 7
/declare PullRangedItem string outer Bloodfiend's Throat Gem
/declare DoRangedSwap int outer 0
/declare EquippedRangedItem string outer Tiny Tomes of Understanding
|-------------------------------------------------------------------------------------
| Group Main Assist Name, Mana/Endurance check to stop and resume pulling
|-------------------------------------------------------------------------------------
/declare MainAssist string outer TankName
/declare DoMACheck int outer 0
|-------------------------------------------------------------------------------------
| Group Healer Name, Mana check to stop and resume pulling
|-------------------------------------------------------------------------------------
/declare DoHealerCheck int outer 0
/declare HealerName string outer HealerName
|-------------------------------------------------------------------------------------
| Clickys
|-------------------------------------------------------------------------------------
/declare DoClicky int outer 1
/declare ClickyItem[8] string outer
/varset ClickyItem[1] Phosphorescent Rapier of Dazzling Light
/varset ClickyItem[2] Kemph's Bonded Girdle
/varset ClickyItem[3] Earring of the Attendants
/varset ClickyItem[4] NULL
/varset ClickyItem[5] NULL
/varset ClickyItem[6] NULL
/varset ClickyItem[7] NULL
/varset ClickyItem[8] NULL
/declare DoAura int outer 1
/declare Aura string outer Aura of the Poet
|-------------------------------------------------------------------------------------
| How far would you like to target a mob?
|-------------------------------------------------------------------------------------
/declare MaxRadius int outer 425
|-------------------------------------------------------------------------------------
| What is the minimum Z Value of mobs I should target?
|-------------------------------------------------------------------------------------
/declare MinZRange int outer -10
|-------------------------------------------------------------------------------------
| What is the maximum Z Value of mobs I should target?
|-------------------------------------------------------------------------------------
/declare MaxZRange int outer 10
|-------------------------------------------------------------------------------------
| Attack mob after returning to camp Hps % and distance
|-------------------------------------------------------------------------------------
/declare EngageHPs int outer 97
/declare EngageDistance int outer 85
|-------------------------------------------------------------------------------------
| Variables that you don't need to worry about.
|-------------------------------------------------------------------------------------
/declare DoLoot int outer 0
/declare FastRange int outer 15
/declare Combat_RangeMin int outer 15
/declare Combat_RangeMax int outer 20
/declare HasTarget int outer 0
/declare RandomWait int outer 0
/declare Fighting int outer 0
/declare TargetDead int outer 0
/declare MyXLOC int outer 0
/declare MyYLOC int outer 0
/declare ObstacleCount int outer 0
/declare CampXLoc int outer ${Me.X}
/declare CampYLoc int outer ${Me.Y}
/declare MinRadius int outer 0
/declare TargetChecked int outer
/declare WaitingSpam int outer 1
/declare Exchanged int outer 0
/declare Pulled int outer 0
/declare PullRange int outer
/declare PullWith string outer
/declare PullSub string outer
/declare PullType string outer
/declare LookForward int outer ${Me.Heading.DegreesCCW}
/declare HasAdds int outer 0
/declare LoS int outer 0
/declare MAClass string outer ${Spawn[${MainAssist}].Class.ShortName}
/declare HealerClass string outer ${Spawn[${HealerName}].Class.ShortName}
/call SetupAdvLootVars
/if (${PullMethod}==0) {
/varset PullRange 10
/varset PullSub Pull_Cast
/varset PullWith Melee
/varset PullType 0
} else /if (${PullMethod}==1) {
/varset PullRange ${Math.Calc[${Spell[${Spell["${PullAA}"].ID}].Range}/5]}
/varset PullSub Pull_Cast
/varset PullWith ${PullAA}
/varset PullType alt
} else /if (${PullMethod}==2) {
/varset PullRange ${Math.Calc[${Spell[${Spell["${PullSpell"].ID}].Range}/9]}
/varset PullSub Pull_Cast
/varset PullWith ${PullSpell}
/varset PullType gem${PullSpellGem}
} else /if (${PullMethod}==3) {
/varset Pulling_method ${}
} else /if (${PullMethod}==4) {
/varset Pulling_method ${}
}
/call MainAssist
|-------------------------------------------------------------------------------------
| SUB: Main Loop
|-------------------------------------------------------------------------------------
:Mainloop
/doevents
/call CheckForAdds
/call DoWePause
/call CheckClicky
/call CastAura
/call GetTarget
/call Pull
/call Combat
/call LootStuff
/call MoveToCamp
/call ResetSub
/goto :Mainloop
/return
|-------------------------------------------------------------------------------------
| SUB: MainAssist Sets main Assist for puller if there is one
|-------------------------------------------------------------------------------------
Sub MainAssist
/declare i int local
/if (!${Defined[Param0]}) {
/for i 1 to ${Group}
/if (${Group.Member[${i}].MainTank} && ${Group.Member[${i}].ID}) {
/varset MainAssist ${Group.Member[${i}].CleanName}
/echo +++ Found Main Tank role. +++
/goto :setM_Assist
}
/next i
}
/if (${Defined[Param0]}) {
/varset MainAssist ${Param0}
/goto :setM_Assist
}
/if (!${Spawn[${Target}].ID} || !${Select[${Target.Type},Mercenary,PC,Pet]}) {
/echo You do not have a Mercenary, PC or Pet targeted using default Main Assist: ${MainAssist}.
/goto :setM_Assist
}
/if (${Target.CleanName.Equal[${Me.CleanName}]}) {
/echo You cannot assist yourself!
/goto :setM_Assist
}
/varset MainAssist ${Target.CleanName}
:setM_Assist
/echo Assist set to >> ${MainAssist} <<
/return
|-------------------------------------------------------------------------------------
| SUB: AquireTarget
|-------------------------------------------------------------------------------------
Sub GetTarget
/doevents
/declare CurrentRadius int local
/echo Looking for Close Range Mobs
:Acquire
/doevents
/for CurrentRadius ${Min_Radius} to ${MaxRadius} step 5
/squelch /target radius ${CurrentRadius} npc noalert 1
/if (${Target.ID}) {
/if (${Select[${Target.Type},PC,Pet,CORPSE,CHEST,TRIGGER,TRAP,TIMER,ITEM,MOUNT,Mercenary]} || !${Target.LineOfSight} || ${Target.PctHPs}<=95 || ${SpawnCount[loc ${Target.X} ${Target.Y} radius 25 pc]}>=1) {
/squelch /alert add 1 id ${Target.ID}
/call ResetSub
/goto :Acquire
}
/varset HasTarget 1
/varset LoS 1
/echo Acquired ${Target.CleanName} at range ${Int[${Target.Distance}]}
/return
}
| Reset search radius if it gets larger that MaxRadius
/if (${CurrentRadius}>=${MaxRadius}) {
/if (${SpawnCount[radius ${MaxRadius} npc noalert 1]}==0) /call AlertClear
/varset MinRadius 0
}
/next CurrentRadius
/goto :Acquire
/return
|-------------------------------------------------------------------------------------
| SUB: Pull
|-------------------------------------------------------------------------------------
Sub Pull
/if (!${HasTarget}) /return
/doevents
/echo Pulling Mob
/declare TargDist float local
:PullLoop
/doevents
/call MoveToMob_Pull
/if (!${Target.ID}) /return
/face fast
/if (${Int[${Target.Distance}]}<10 && ${Pulled}) /goto :MoveTo
/if (${Target.PctHPs}==100 ) /goto :PullLoop
/if (${Target.PctHPs}<21) /return
:MoveTo
/call MoveToLoc ${CampYLoc} ${CampXLoc}
/if (!${Target.ID}) /return
/face fast
:Engage
/if (${Spawn[${MainAssist}].ID}) /assist ${MainAssist}
/varset TargDist ${Math.Distance[${Target.Y},${Target.X},0:${Me.Y},${Me.X},0]}
/if (${TargDist}<${EngageDistance} && ${Target.PctHPs}<${EngageHPs}) /return
/goto :Engage
/return
|-------------------------------------------------------------------------------------
| SUB: MovetoMob_Pull
|-------------------------------------------------------------------------------------
Sub MoveToMob_Pull
/doevents
/varset MyXLOC ${Int[${Me.X}]}
/varset MyYLOC ${Int[${Me.Y}]}
/varset ObstacleCount 0
:MovementLoop
/doevents
/if (!${Target.ID}) /return
/face fast
/varcalc ObstacleCount ${ObstacleCount}+1
/if (${Int[${Target.Distance}]}>${PullRange}) /keypress forward hold
/if (${Int[${Target.Distance}]}<${PullRange}) /keypress back
/if (${ObstacleCount}>=15) {
/call CheckObstacle
/goto :Movementloop
}
/if (${Target.LineOfSight}) /call ${PullSub} "${PullWith}" "${PullType}"
/return
|-------------------------------------------------------------------------------------
| SUB: MovetoMob
|-------------------------------------------------------------------------------------
Sub MoveToMob
/doevents
/varset MyXLOC ${Int[${Me.X}]}
/varset MyYLOC ${Int[${Me.Y}]}
/varset ObstacleCount 0
:MovementLoop
/doevents
/if (!${Target.ID}) /return
/face fast
/varcalc ObstacleCount ${ObstacleCount}+1
/if (${Int[${Target.Distance}]}>${FastRange}) /keypress forward hold
/if (${Int[${Target.Distance}]}<${FastRange} && ${Int[${Target.Distance}]}>${Combat_RangeMax}) /keypress forward
/if (${Int[${Target.Distance}]}<${Combat_RangeMin}) /keypress back
/if (${ObstacleCount}>=15) {
/call CheckObstacle
/goto :Movementloop
}
/if (${Int[${Target.Distance}]}>${FastRange}) /goto :MovementLoop
/return
|-------------------------------------------------------------------------------------
| SUB: MoveToLocation
|-------------------------------------------------------------------------------------
Sub MoveToLoc(MoveToY, MoveToX)
/doevents
/declare running int local
/declare distanceNow float local
/declare distanceBefore float local
/declare distanceModifier int local
/declare distanceTimer timer 15
/varset running 0
/varset distanceBefore ${Math.Distance[${Me.Y},${Me.X}:${MoveToY},${MoveToX}]}
/varset distanceModifier 1
/echo Moving to Location: ${MoveToY}, ${MoveToX}.
/echo Distance: ${distanceBefore}
:moveToLocation
/doevents
/face fast nolook loc ${MoveToY},${MoveToX}
/if (${Math.Distance[${Me.Y},${Me.X}:${MoveToY},${MoveToX}]}<10) {
/keypress forward
/return
}
/if (${distanceTimer}==0) {
/if (${Me.Sneaking}) {
/varset distanceModifier 2
} else {
/varset distanceModifier 1
}
/varset distanceNow ${Math.Distance[${Me.Y},${Me.X}:${MoveToY},${MoveToX}]}
/if (${Math.Calc[${distanceBefore}-${distanceNow}]}<${Math.Calc[10/${distanceModifier}]}) {
/call HitObstacle
}
/varset distanceBefore ${Math.Distance[${Me.Y},${Me.X}:${MoveToY},${MoveToX}]}
/varset distanceTimer 15
}
/if (${running}==0) {
/keypress forward
/if (${Math.Distance[${Me.Y},${Me.X}:${MoveToY},${MoveToX}]}>10) {
/varset running 1
/keypress forward hold
}
} else {
/if (${Math.Distance[${Me.Y},${Me.X}:${MoveToY},${MoveToX}]}<11) {
/varset running 0
/keypress forward
}
}
/goto :moveToLocation
/return
|-------------------------------------------------------------------------------------
| SUB: ObstacleCheck
|-------------------------------------------------------------------------------------
Sub CheckObstacle
/doevents
/if ((${MyXLOC}==${Int[${Me.X}]})&&(${MyYLOC}==${Int[${Me.Y}]})) /call HitObstacle
/varset MyXLOC ${Int[${Me.X}]}
/varset MyYLOC ${Int[${Me.Y}]}
/varset ObstacleCount 0
/return
|-------------------------------------------------------------------------------------
| SUB: ObstacleAvoidance
|-------------------------------------------------------------------------------------
Sub HitObstacle
/echo Obstacle hit, moving around it...
/keypress forward
/keypress back hold
/delay 3
/keypress back
/if (${Math.Rand[2]}) {
/keypress strafe_right hold
} else {
/keypress strafe_left hold
}
/delay 5
/keypress strafe_right
/keypress strafe_left
/keypress forward hold
/return
|-------------------------------------------------------------------------------------
| SUB: Combat
|-------------------------------------------------------------------------------------
Sub Combat
/if (!${HasTarget} && !${HasAdds}) /return
/doevents
/varset Fighting 1
/varset TargetDead 0
/echo Attacking Mob NOW!
/if (${Spawn[MainAssist].ID}) /assist ${MainAssist}
/if (!${Me.Combat}) /attack on
:CombatLoop
/doevents Slain
/if (!${Target.ID}) /return
/if (${Target.Distance}>20) /call MoveToMob
/if (!${TargetDead}) /goto :CombatLoop
/return
|-------------------------------------------------------------------------------------
| SUB: Event Slain
|-------------------------------------------------------------------------------------
Sub Event_Slain
/varset TargetDead 1
/varset Fighting 0
/varset Pulled 0
/attack off
/squelch /target clear
/return
|-------------------------------------------------------------------------------------
| SUB: Event Can't See
|-------------------------------------------------------------------------------------
Sub Event_CantSee
/if (${HasTarget} && ${LoS}) /varset PullRange 20
/return
|-------------------------------------------------------------------------------------
| SUB: MovetoCamp
|-------------------------------------------------------------------------------------
Sub MoveToCamp
/if (${HasAdds}) /return
/if (${Math.Distance[${CampYLoc}, ${CampXLoc}]} > 5) /call MoveToLoc ${CampYLoc} ${CampXLoc}
/face fast heading ${LookForward}
/return
|-------------------------------------------------------------------------------------
| SUB: Zoned
|-------------------------------------------------------------------------------------
Sub Event_Zoned
/echo Zoned
/delay 60s
/endmacro
|-------------------------------------------------------------------------------------
| SUB: alert clear
|-------------------------------------------------------------------------------------
Sub AlertClear
/echo Clearing Alert list.
/squelch /alert clear 1
/return
|-------------------------------------------------------------------------------------
| SUB: Reset
|-------------------------------------------------------------------------------------
Sub ResetSub
/doevents
/varset HasTarget 0
/varset TargetDead 0
/varset Fighting 0
/varset Exchanged 0
/varset Pulled 0
/varset LoS 0
/squelch /target clear
/delay 1s
/return
|-------------------------------------------------------------------------------------
| SUB: CheckHealerMana
|-------------------------------------------------------------------------------------
Sub CheckHealerMana
/if (!${DoHealerCheck} || ${Group.Member[${Spawn.[group clr]}].CurrentMana}>${HealerManaPause}) /return
:wait_for_healer
/if (${Group.Member[${Group.Member[${HealerName}]}].CurrentMana}<${HealerManaResume}) /goto :wait_for_healer
/return
|-------------------------------------------------------------------------------------
| SUB: CheckMAEnd
|-------------------------------------------------------------------------------------
Sub CheckMAEnd
/if (!${DoMACheck} || ${Group.Member[${Group.Member[${MainAssist}]}].CurrentEndurance}>${MAEndPause}) /return
/declare WaitingSpam int local 0
:wait_for_ma
/if (${WaitingSpam}) {
/echo Waiting for MA to med up. ${MainAssist} has ${Group.Member[${Group.Member[${MainAssist}]}].CurrentEndurance}% End
/varset WaitingSpam 0
/timed 600 /varset WaitingSpam 1
}
/if (${Group.Member[${Group.Member[${MainAssist}]}].CurrentEndurance}<${MAEndResume}) /goto :wait_for_ma
/return
|--------------------------------------------------------------------------------
| SUB: Pull_Cast
|--------------------------------------------------------------------------------
Sub Pull_Cast
/if (${Pull_With}=1 && ${Me.AltAbilityReady[${Pull_Alt_Ability}]}) {
/alt act ${Me.AltAbility[${Pull_Alt_Ability}].ID}
} else /if (${Pull_With}=2 && ${Me.CombatAbilityReady[${Pull_Combat_Ability}]}) {
/ability ${Me.CombatAbility[${Pull_Combat_Ability}].ID}
} else /if (${Pull_With}=3 && ${Me.SpellReady[${Pull_Spell}]}) {
/call cast ${Pull_Spell} ${PullSpellGem} 3s
}
/varset Pulled 1
/return
|-------------------------------------------------------------------------------------
| SUB: Equip_Ranged
|-------------------------------------------------------------------------------------
Sub Equip_Ranged
/if (${String[${Me.Inventory[ranged]}].NotEqual[${PullRangedItem}]}) {
/exchange "${PullRangedItem}" ranged
/varset Exchanged 1
}
/delay 5s
/if (${Exchanged}) /exchange "${EquippedRangedItem}" ranged
/return
|-------------------------------------------------------------------------------------
| SUB: CheckClicky
|-------------------------------------------------------------------------------------
Sub CheckClicky
| /echo enter clicky
/if (!${DoClicky}) /return
/declare i int local 1
| /echo leave clicky
/if (${Me.Pet.CleanName.Equal[${Me.Name}`s familiar]}) /pet get lost
/for i 1 to ${ClickyItem.Size}
| /echo ${i} ${ClickyItem[${i}]} && ${NearestSpawn[NPC].Distance}>=25 Kemph's Bonded Girdle
/if (${FindItemCount[${ClickyItem[${i}]}]}<=0) /next i
| /if (${FindItemCount[${ClickyItem[${i}]}]}) /keypress OPEN_INV_BAGS
/delay 1s
/if (${FindItem[${ClickyItem[${i}]}].Spell.Stacks[0]} && !${Me.Buff[${FindItem[${ClickyItem[${i}]}].Spell}].ID}) {
/call SwapItem "${ClickyItem[${i}]}" ${FindItem[${ClickyItem[${i}]}].WornSlot[1]}
/delay 1s
/autoinventory
/squelch /if (${Me.Class.ShortName.Equal[BRD]}) /twist off
/target myself
/delay 1s
/call Cast "${ClickyItem[${i}]}" item 5s
}
/next i
/squelch /if (${Me.Class.ShortName.Equal[BRD]}) /twist
/return
|-------------------------------------------------------------------------------------
| SUB: Cast Aura
|-------------------------------------------------------------------------------------
Sub CastAura
/if (!${DoAura}) /return
| - Mutant Bards do this
/if (!${Me.Song[${Aura} Effect].ID}) {
/if (${Me.Class.ShortName.Equal[BRD]}) {
/if ( !${Me.Gem[${Aura}]} ) {
/memspell 8 "${Aura}"
/delay 30
}
/twist once ${Me.Gem[${Aura}]}
/return
}
| - Normal casting
/call cast "${Aura}" gem8 5s
/delay 5s
}
/return
|-------------------------------------------------------------------------------------
| SUB: Check for adds
|-------------------------------------------------------------------------------------
Sub CheckForAdds
/if (${Me.XTarget} < 1) /return
/varset HasAdds 1
/popup Add in camp detected
:moreadds
/delay 5
/if (${Spawn[${MainAssist}].ID}) {
/assist ${MainAssist}
} else {
/target id ${Me.XTarget[1].ID}
}
/call Combat
/if (${Me.XTarget} > 0) /goto :moreadds
/varset HasAdds 0
/return
|-------------------------------------------------------------------------------------
| SUB: Loot Stuff
|-------------------------------------------------------------------------------------
Sub LootStuff
/if (!${DoLoot}) /return
/call Lootmobs
/return
|-------------------------------------------------------------------------------------
| SUB: DoWePause
|-------------------------------------------------------------------------------------
Sub DoWePause
/call CheckStats ${DoMACheck} "${MainAssist}" "${MAClass}" Endurance 80 90
/call CheckStats ${DoHealerCheck} "${HealerName}" "${HealerClass}" Mana 20 90
/return
|-------------------------------------------------------------------------------------
| SUB: CheckStats
|-------------------------------------------------------------------------------------
Sub CheckStats(int statcheck, charname, ckclass, stat, int pause,int resume)
/if (!${statcheck} || !${Spawn[${ckclass} ${charname}].ID} || ${Group.Member[${Group.Member[${Spawn[Group ${ckclass} ${charname}]}]}].Current${stat}}>${pause}) /return
/echo Waiting for ${charname} to med up to ${resume}% ${stat}
:wait_for_resume
/if (${Group.Member[${Group.Member[${Spawn[Group ${ckclass} ${charname}]}]}].Current${stat}}<${resume}) /goto :wait_for_resume
/echo ${charname} is now above ${resume}% ${stat} resuming macro
/return