Advertisement
MrTrala

Untitled

Oct 8th, 2016
468
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.16 KB | None | 0 0
  1. -----------------------------------------------
  2. -------------------- CONFIG -------------------
  3. -----------------------------------------------
  4.  
  5. LootGold = false
  6. LootAboveValue = 1000000 -- Will loot any item with an NPC price greater or equal to this.
  7. LootAboveValueRatio = 50000 -- Will loot any stackable item with a NPC price to weight ratio greater or equal to this.
  8. LootList = -- Will loot all items on this list even if they don't meet any of the above criteria.
  9. {
  10. "Glooth Capsule",
  11. "Tainted Glooth Capsule",
  12. "Crude Umbral Spellbook",
  13. "Gold Nugget",
  14. 4061,
  15. 11328,
  16. 10027,
  17. 22656
  18.  
  19. }
  20.  
  21. -- You need to open your backpacks on your own. 0 is your main backpack.
  22. BpStacks = 0
  23. BpRares = 0
  24. BpGold = 0 -- Not needed it not looting gold.
  25.  
  26. -- Increase these if the script misses loot. Decrease them to increase speed.
  27. MinWait = 1000
  28. MaxWait = 1100
  29.  
  30. OpenCorpses = true
  31.  
  32. -----------------------------------------------
  33. ----------------- DESCRIPTION -----------------
  34. -----------------------------------------------
  35. --[[
  36. This script will open and loot corpses within 1sqm of your character.
  37. It will also loot any corpse that you open manually.
  38. Known issues:
  39. - The script is only able to open very fresh corpses.
  40. - The script will not retry opening a corpse if you walk away
  41. while it is being looted.
  42. - The script cannot open corpses on top of ladders and rope spots.
  43. ]]
  44. -----------------------------------------------
  45. -----------------------------------------------
  46. -----------------------------------------------
  47.  
  48. -- CONVERT CONFIG
  49. local LootAboveValue = LootAboveValue
  50. local LootAboveValueRatio = LootAboveValueRatio
  51. OldLootList = LootList
  52. local LootList = {}
  53. for _, name in ipairs(OldLootList) do
  54. LootList[Item.GetItemIDFromDualInput(name)] = true
  55. end
  56.  
  57. local BpStacks = BpStacks
  58. local BpRares = BpRares
  59. local BpGold = BpGold
  60.  
  61. -- POSITION HASHING
  62. local function ToNumber(pos)
  63. return 10000000000*pos.x+100000*pos.y+pos.z
  64. end
  65.  
  66. local function ToPos(num)
  67. local x = math.floor(num/10000000000)
  68. local y = math.floor(num/100000)%100000
  69. local z = num%100000
  70. return {x=x, y=y, z=z}
  71. end
  72.  
  73. -- WAITING
  74. local MinWait = MinWait
  75. local MaxWait = MaxWait
  76. local function Wait()
  77. local ping = 0 --Self.Ping()
  78. wait(MinWait + ping, MaxWait + ping)
  79. end
  80.  
  81. -- LOOTER
  82. local Corpses = {}
  83. local Monsters = {}
  84.  
  85. Module("Find Corpses", function(find)
  86. for _, monster in pairs(Monsters) do
  87. if not monster:isAlive() and monster:DistanceFromSelf() <= 1 and Self.Position().z == monster:Position().z then
  88. local posHash = ToNumber(monster:Position())
  89. Corpses[posHash] = (Corpses[posHash] or 0) + 1
  90. end
  91. end
  92.  
  93. Monsters = {}
  94. for _, monster in Creature.iMonsters(7) do
  95. Monsters[ToNumber(monster:Position())] = monster
  96. end
  97. end)
  98.  
  99. local function GetBp(id)
  100. return (id==3031 and BpGold) or (Item.isStackable(id) and BpStacks) or BpRares
  101. end
  102.  
  103. local function GetSlot(id)
  104. local bp = Container(GetBp(id))
  105. if bp:isOpen() then
  106. -- If bp isn't full, place it in the last slot.
  107. if bp:ItemCount() < bp:ItemCapacity() then return bp:Index(), bp:ItemCapacity()-1, (Item.isStackable(id) and 100) or 1 end
  108. -- If it is full and the item is stackable, try to fit it into an existing slot.
  109. if Item.isStackable(id) then
  110. for Spot = 0, bp:ItemCount() - 1 do
  111. local item = bp:GetItemData(Spot)
  112. if id == item.id and item.count ~= 100 then
  113. return bp:Index(), Spot, (100-item.count)
  114. end
  115. end
  116. end
  117. -- If it's full and we couldn't fit it into an existing slot, try open a new bp.
  118. if Item.isContainer(bp:GetItemData(bp:ItemCount()-1).id) then
  119. local tries = 0
  120. while not bp:UseItem(bp:ItemCount()-1, true) and tries < 10 do
  121. Wait()
  122. tries = tries + 1
  123. end
  124. if tries < 10 then
  125. return GetSlot(id)
  126. end
  127. else
  128. print("Error: "..bp:Name().." is full and has no container in its last slot.")
  129. end
  130. else
  131. print("Error: All backpacks aren't open.")
  132. end
  133. end
  134.  
  135. local function MoveToSelf(Corpse, Spot)
  136. local item = Corpse:GetItemData(Spot)
  137. if Self.Cap() >= Item.GetWeight(item.id)*item.count then
  138. local index, slot, count = GetSlot(item.id)
  139. if index then
  140. local tries = 0
  141. local LCount = Corpse:ItemCount()
  142. while Corpse:isOpen() and Corpse:ItemCount() == LCount and tries < 10 do
  143. Corpse:MoveItemToContainer(Spot, index, slot, math.min(item.count, count))
  144. Wait()
  145. tries = tries + 1
  146. end
  147. Wait()
  148. if Corpse:isOpen() and Corpse:ItemCount() ~= LCount and count == item.count then
  149. return true
  150. end
  151. if Corpse:isOpen() and count < item.count then
  152. return MoveToSelf(Corpse, Spot)
  153. end
  154. end
  155. else
  156. print("Error: Not enough capacity.")
  157. end
  158. return false
  159. end
  160.  
  161. local function IsLoot(id)
  162. return ((Item.GetValue(id) >= LootAboveValue) or
  163. (Item.isStackable(id) and (Item.GetValue(id)/Item.GetWeight(id)) > LootAboveValueRatio) or
  164. LootList[id]) and (LootGold or id ~= 3031)
  165. end
  166.  
  167. local CorpseNames = {"The", "Demonic", "Dead", "Slain", "Dissolved", "Remains", "Elemental", "Split", "dead", "a dead"}
  168. local function IsCorpseByName(name)
  169. for _, CPartName in ipairs(CorpseNames) do
  170. if name:find(CPartName) then
  171. return true
  172. end
  173. end
  174. return false
  175. end
  176.  
  177. local function CotainerIsCorpse(c)
  178. return Item.isCorpse(c:ID()) or IsCorpseByName(c:Name())
  179. end
  180.  
  181. local function GrabItems(Corpse)
  182. local success = true
  183. if (Item.isCorpse(Corpse:ID()) or IsCorpseByName(Corpse:Name())) then
  184. for Spot = Corpse:ItemCount() - 1, 0, -1 do
  185. if IsLoot(Corpse:GetItemData(Spot).id) then
  186. success = success and MoveToSelf(Corpse, Spot)
  187. Wait()
  188. end
  189. end
  190. end
  191. return success
  192. end
  193.  
  194. local function OpenCorpse(pos, count)
  195. if Item.isCorpse(Map.GetTopUseItem(pos.x, pos.y, pos.z).id) and count == 1 then
  196. -- We need slightly longer waits when opening corpses, or the script falls apart. However, I'd still like the user to be able to slow down the looter. Thus we use both a static wait and a user configured wait.
  197. local success = Self.UseItemFromGround(pos.x, pos.y, pos.z)
  198. return 0
  199. else
  200. -- Open the browse field container
  201. local Browse = Container.GetByName("Browse Field")
  202. Self.BrowseField(pos.x, pos.y, pos.z)
  203. Wait()
  204. if not Browse:isOpen() then return count end
  205.  
  206. -- For each corpse in the browse, loot it
  207. for Spot = Browse:ItemCount() - 1, 0, -1 do
  208. if Item.isCorpse(Browse:GetItemData(Spot).id) then
  209. if not Browse:UseItem(Spot) then
  210. Browse:Close()
  211. return count
  212. end
  213. wait(40, 50)
  214. Wait()
  215. count = count - 1
  216. end
  217. if count == 0 then break end
  218. end
  219.  
  220. Browse:Close()
  221. return 0
  222. end
  223. end
  224.  
  225. if OpenCorpses then
  226. Module("Open Corpses", function(open)
  227. local UpdatedCorpses = {}
  228. for numPos, count in pairs(Corpses) do
  229. local pos = ToPos(numPos)
  230. if Self.DistanceFromPosition(pos.x, pos.y, pos.z) <= 1 and Self.Position().z == pos.z then
  231. local remaining = OpenCorpse(pos, count)
  232. if remaining > 0 then
  233. UpdatedCorpses[numPos] = remaining
  234. else
  235. GrabItems(Container:GetLast())
  236. end
  237. else
  238. UpdatedCorpses[numPos] = count
  239. end
  240. end
  241. Corpses = UpdatedCorpses
  242. end)
  243. end
  244.  
  245. Module("Loot Corpses", function(loot)
  246. local Browse = Container.GetByName("Browse Field")
  247. for _, c in Container.iContainers() do
  248. if (Item.isCorpse(c:ID()) or IsCorpseByName(c:Name())) and c:isOpen() then
  249. if GrabItems(c) then
  250. Wait()
  251. c:Close()
  252. Browse:Close()
  253. end
  254. end
  255. end
  256. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement