Question Loot function gets stuck

Fridgecritter

Premium Member
Joined
May 14, 2011
Messages
49
Reaction score
6
Points
8
I know I've asked about this macro before, but now the loot function is going into an endless loop on me, but only sometimes. It will give me the message, "You must first target a corpse to loot" and I think it's happening when the corpse has no loot but I'm not sure. I watch it while it works and I look over when I hear no more sounds, and it's scrolling up the chat box and won't move on.

You must first target a corpse to loot
You must first target a corpse to loot
You must first target a corpse to loot
You must first target a corpse to loot
You must first target a corpse to loot

Code:
sub main
	/declare longKill timer
	/declare lootTimeOut timer
	/declare curZone string
	/declare notValid string
|	/declare named string
	/declare altCurrency string
	/declare lootItems string
	/declare lootWildcard1 string
	/declare lootWildcard2 string
	/declare lootWildcard3 string
	/declare lootWildcard4 string
	/declare lootWildcard5 string
	/declare lootWildcard6 string
	/declare lootWildcard7 string
	/declare lootWildcard8 string
	/declare lootWildcard9 string
	/declare lootWildcard10 string
	/declare lootWildcard11 string
	/declare lootWildcard12 string
	/declare lootWildcard13 string
	/declare lootName string
	/declare lootCount int
	/declare minLootValue int
	/declare npcID int
	/declare i int
	/declare ii int

	/declare noloot int
	
	/varset minLootValue 4p

	/varset altCurrency /Ebon Crystal/Dream Mote/

	/varset lootItems /Blue Diamond/Diamond/Raw Diamond/

	/varset lootWildcard1 item1
	/varset lootWildcard2 item2
	/varset lootWildcard3 item3
	/varset lootWildcard4 item4
	/varset lootWildcard5 item5
	/varset lootWildcard6 item6
	/varset lootWildcard7 item7
	/varset lootWildcard8 item8
	/varset lootWildcard9 item9
	/varset lootWildcard10 item10
	/varset lootWildcard11 item11
	/varset lootWildcard12 item12
	/varset lootWildcard13 item13
	
	/varset notValid /NPCname1/NPCname2/

|	/varset named /NPCname1/NPCname2/

	/varset curZone ${Zone}

	/call doHideCorpses

	:WaitForRespawns

	/if (${SpawnCount[npc]}>0) {
		:NextSpawn

		/if (!${String[${Zone}].Equal[${curZone}]}) /return

		/for i 1 to ${SpawnCount}
			/vardata npcID NearestSpawn[${i}].ID

			/if ((${npcID}!=${Me.ID}) && (${Spawn[${npcID}].Type.Equal[NPC]})) {
				/if ((${notValid.Find[/${Spawn[${npcID}].CleanName}/]}==NULL) && (${Spawn[${npcID}].CleanName.Length}>0)) {
					/target id ${npcID}

					/if (!${longKill}) {
						/call warpTarget 0
					} else {
						/call warpTarget 1
					}

					:Retarget

					/target clear
					/delay 5
					/target id ${npcID}
					/delay 1s ${Target.Distance}<10
					/stick 7 moveback
					/delay 3
					/keypress 6
					|/delay 5
					|/keypress 6
					/delay 3
					/attack on

					/varset longKill 40s

					:WaitForDead

					/face fast nolook

					/doevents

					/if (${String[${Me.Class}].Equal[Rogue]}) {
						/if (${Me.AbilityReady[Backstab]}) /doability Backstab
						/if (${String[${Me.Song[Thief's Eyes]}].Equal[NULL]}) /doability "Thief's Eyes"
					}
					
					/if (${String[${Me.Class}].Equal[Druid]}) {
						/casting "Galatine"
						/delay 4
					}
					
					/if (${String[${Me.Class}].Equal[Warrior]}) {
						/if (${Window[CombatAbilityWnd].Open}) {
							/if (${Window[CombatAbilityWnd].Child[CAW_CombatEffectLabel].Text.Equal[No Effect]}) /casting "Blade of Hatred"
						}
					}

|					/if ((${Target.Type.Equal[CORPSE]}) || (!${longKill})) /target clear
					/if (!${longKill}) /goto :Retarget
					/if (${Target.Distance}>50) /call warpTarget 0

|					/if (${Target.ID}==${npcID}) /goto :WaitForDead

					:NearbyCorpseFound

/if (!${noloot}) {
					/if (${Spawn[${npcID}].Type.Equal[CORPSE]}) {
						/if (!${Me.FreeInventory}) {
							/beep
						} else {
							/target id ${npcID}
							/call warpTarget 0
							/delay 2s ${Target.Distance}<10

							/if (${Target.Distance}<10) {
								/varset lootTimeOut 5s
								
								/delay 2
								/loot

								:WaitForLootWndOpen
								/delay 5
								/if ((!${NearestSpawn[corpse].LineOfSight}) || (!${lootTimeOut})) :NextSpawn
								/delay 1s ${Window[LootWnd].Open}
								/loot
								/if (!${Window[LootWnd].Open}) /goto :WaitForLootWndOpen

								/vardata lootCount Corpse.Items

								/if (${lootCount}) {
									/for ii 1 to ${lootCount}
										/if (!${Me.FreeInventory}) /goto :DoneLooting

										/if (${Corpse.Item[${ii}].ID}) {
											/varset lootName ${Corpse.Item[${ii}].Name}

											/if (${altCurrency.Find[/${lootName}/]}) {
												/call lootItem ${ii}
												/call reclaimCurrency ${lootName}
											} else {
												/if ((${Corpse.Item[${ii}].Name.Find[${lootWildcard1}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard2}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard3}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard4}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard5}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard6}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard7}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard8}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard9}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard10}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard11}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard12}]} || ${Corpse.Item[${ii}].Name.Find[${lootWildcard13}]} || ... || ${lootItems.Find[/${lootName}/]} || ${Corpse.Item[${ii}].Value}>${Math.Calc[${minLootValue}*1000]}) && (!${Corpse.Item[${ii}].Lore} || !${FindItem[${Corpse.Item[${ii}].Name}].ID})) {
													/call lootItem ${ii}
												}
											}
											
											/if (${lootName.Find[EPIC]}) {
												/call lootItem ${ii}
											}
										}
									/next ii
								}

								:DoneLooting

								/notify LootWnd DoneButton leftmouseup

								:WaitForLootWndClose
								/delay 5
								/if ((!${NearestSpawn[corpse].LineOfSight}) || (!${lootTimeOut})) :NextSpawn
								/if (${Window[LootWnd].Open}) /goto :WaitForLootWndClose

								/if (${NearestSpawn[corpse].LineOfSight}) {
									/vardata npcID NearestSpawn[corpse].ID
									/goto :NearbyCorpseFound
								}
							}
						}
					} else {
						/if (!${String[${Spawn[${npcID}].ID}].Equal[NULL]}) /goto :WaitForDead
					}
}
						/if (!${String[${Spawn[${npcID}].ID}].Equal[NULL]}) /goto :WaitForDead
					/goto :NextSpawn
				}
			}
		/next i
	}

	/delay 5s

	/goto :WaitForRespawns
/return


sub doHideCorpses
	/hidec all
	/hidec looted
	/delay 5
/return

sub warpTarget(boolWithDistance)
	/if (${boolWithDistance}) {
		/warp loc ${Math.Calc[${Target.Y}-2]} ${Math.Calc[${Target.X}-2]} ${Target.Z}
	} else {
		/warp target
	}
/return

sub reclaimCurrency(strCurrencyName)
	/declare itemIndex int local
	/declare itemTotal int local

	/if (${Window[IW_AltCurrPage].Open}) {
		/varset itemIndex ${Window[IW_AltCurrPage].Child[IW_AltCurr_PointList].List[=${strCurrencyName},2]}

		/if (${itemIndex}) {
			/notify IW_AltCurrPage IW_AltCurr_PointList listselect ${itemIndex}
			/notify IW_AltCurrPage IW_AltCurr_ReclaimButton leftmouseup
			/delay 5
		}
	}
/return

sub lootItem(intLootSlot)
	/shift /itemnotify loot${intLootSlot} rightmouseup

	:WaitLootItem
	/delay 5
	/if (${Corpse.Item[${intLootSlot}].ID}) /goto :WaitLootItem
/return


sub Event_Backstab(strText, strMobName, strDamage)	
	/declare formattedDamage string local
	
	|/if (${Group.Members}==NULL) /return
	
	/if (!${strDamage}==NULL) {
		/if (${strDamage}>500000) {
			|/popup ${strDamage}
			/if (${strDamage}<1000000) {
				/varset formattedDamage ${String[${strDamage}].Left[3]},${String[${strDamage}].Right[3]}
			} else {
				/varset formattedDamage ${String[${strDamage}].Left[4]},${String[${strDamage}].Right[3]}
				/varset formattedDamage ${String[${formattedDamage}].Left[1]},${String[${formattedDamage}].Right[7]}
			}
			/guildsay Backstab (${strMobName}) for ${formattedDamage} points of damage.
		}
	}
/return
 
For one, you have a command that isn't actually doing what you want:
Code:
/if ((!${NearestSpawn[corpse].LineOfSight}) || (!${lootTimeOut})) :NextSpawn

You need to change :NextSpawn to: /goto :NextSpawn

Another WAG would be that Target.Distance evals to NULL (or 0 / false) when you don't have a valid target, so it can potentially get stuck. A better check before trying to warp to target, or delay target.distance only, would be to also check ${Target.ID}. If that's true (non-zero), then you have a valid target.
E.g.:
Old: /delay 1s ${Target.Distance}<10
New: /delay 1s (${Target.ID} && ${Target.Distance}<10)
Etc.

Only took a quick look, so YMMV.

htw