XenoBot Forums - Powered by vBulletin

User Tag List

Results 1 to 8 of 8

Thread: Open Corpses & Close Corpses [$ Incentive]

  1. #1

    Join Date
    Jun 2015
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Open Corpses & Close Corpses [$ Incentive]

    I am looking for a Lua Script that:

    Open Corpses
    • Around me in the range of 1 (Does not move char)
    • If there is a corpse outside of my immediate range, it will open it if I am next to it. (Does not move char)
    • Contains items from a specified list (With an option to ignore the list)
    • Loot the item (Optional as I already have a script does that does this efficiently.)
    • Close Corpses if does not contain item from a specified list.


    I am not looking for alternative solutions such as "use the built-in looter" as there is no "loot range" and the built-in delays in the looter is too high.
    (@DarkstaR , perhaps an option to have loot range and modifiable delays in the looter? I understand that delays are non-modifiable because of reasons that you have stated in the past, stupid people doing stupid things and blaming Xenobot for deletions, etc.)

    Neither is placing special areas around the area as, if a party member steps into the sqm around me and there is a corpse outside of my immediate range, it will stack onto him in an attempt to loot the corpse.
    (I don't know if it is intentional or not but I am not interested in debating that.)


    In short, I am looking for a script that emulates Magebot in the aspect of looting without it's shortcomings.

    I am aware that such scripts were publicly available but they were obviously not working for me, thus I am posting this.

    As an incentive, I am willing to pay Tibia Coins or USD in Paypal for this script.
    Last edited by botterzeralz; 11-15-2015 at 11:23 PM.

  2. #2
    Moderator shadowart's Avatar
    Join Date
    Dec 2014
    Location
    Sweden
    Posts
    1,985
    Mentioned
    225 Post(s)
    Tagged
    3 Thread(s)
    Writing a perfect corpse opener in lua is not possible. This one has some limitation:
    • It cannot open corpses on ladders and rope holes (unless two creature both die there before you can loot either - then browse field looting will trigger).
    • It cannot open too old corpses as Xeno's Item.IsCorpse function only counts corpses in their first phase of decay as corpses.
    • It will open every corpse within 1 sqm regardless of what it contains as there's no way to tie a specific corpse to a specific loot message using lua.
    • If you walk away (so that the corpse closes) while it is being looted, it will not be re-opened.

    lua code:

    -----------------------------------------------
    -------------------- CONFIG -------------------
    -----------------------------------------------

    LootGold = true
    LootAboveValue = 1000 -- Will loot any item with an NPC price greater or equal to this.
    LootAboveValueRatio = 5 -- Will loot any stackable item with a NPC price to weight ratio greater or equal to this.
    LootList = -- Will loot all items on this list even if they don't meet any of the above criteria.
    {
    "Great Spirit Potion",
    "Crude Umbral Spellbook",
    "Meat"
    }

    -- You need to open your backpacks on your own. 0 is your main backpack.
    BpStacks = 1
    BpRares = 2
    BpGold = 3 -- Not needed if not looting gold.

    -- Increase these if the script misses loot. Decrease them to increase speed.
    MinWait = 20
    MaxWait = 50

    OpenCorpses = true
    CloseCorpses = true -- The corpse opener works better if you also let it close corpses.
    LootFirst = true -- Only relevant if OpenCorpses is true.

    -----------------------------------------------
    ----------------- DESCRIPTION -----------------
    -----------------------------------------------
    --[[
    This script will open and loot corpses within 1sqm of your character.
    It will also loot any corpse that you open manually.
    Known issues:
    - The script is only able to open very fresh corpses.
    - The script will not retry opening a corpse if you walk away
    while it is being looted.
    - The script cannot open corpses on top of ladders and rope spots.
    ]]
    -----------------------------------------------
    -----------------------------------------------
    -----------------------------------------------

    -- CONVERT CONFIG
    local LootAboveValue = LootAboveValue
    local LootAboveValueRatio = LootAboveValueRatio
    OldLootList = LootList
    local LootList = {}
    for _, name in ipairs(OldLootList) do
    LootList[Item.GetItemIDFromDualInput(name)] = true
    end

    local BpStacks = BpStacks
    local BpRares = BpRares
    local BpGold = BpGold

    -- POSITION HASHING
    local function ToNumber(pos)
    return 10000000000*pos.x+100000*pos.y+pos.z
    end

    local function ToPos(num)
    local x = math.floor(num/10000000000)
    local y = math.floor(num/100000)%100000
    local z = num%100000
    return {x=x, y=y, z=z}
    end

    -- WAITING
    local MinWait = MinWait
    local MaxWait = MaxWait
    local function Wait()
    wait(MinWait, MaxWait)
    end

    -- LOOTER
    local Corpses = {}
    local Monsters = {}


    Module("Find Corpses", function(find)
    local UpdatedMonsters = {}
    for pos, monster in pairs(Monsters) do
    if monster:isAlive() and monster:DistanceFromSelf() < 20 then
    UpdatedMonsters[ToNumber(monster:Position())] = monster
    elseif Corpses[ToNumber(monster:Position())] then
    Corpses[ToNumber(monster:Position())] = Corpses[ToNumber(monster:Position())] + 1
    else
    Corpses[ToNumber(monster:Position())] = 1
    end
    end

    for _, monster in Creature.iMonsters(7) do
    UpdatedMonsters[ToNumber(monster:Position())] = monster
    end

    Monsters = UpdatedMonsters
    end)

    local function GetBp(id)
    return (id==3031 and BpGold) or (Item.isStackable(id) and BpStacks) or BpRares
    end

    local function GetSlot(id)
    local bp = Container(GetBp(id))
    if bp:isOpen() then
    if Item.isStackable(id) then
    for Spot = 0, bp:ItemCount() - 1 do
    local item = bp:GetItemData(Spot)
    if id == item.id and item.count ~= 100 then
    return bp:Index(), Spot, (100-item.count)
    end
    end
    end
    if bp:isFull() then
    if Item.isContainer(bp:GetItemData(bp:ItemCount()-1).id) then
    local tries = 0
    while not bp:UseItem(bp:ItemCount()-1, true) and tries < 10 do
    Wait()
    tries = tries + 1
    end
    if tries < 10 then
    return GetSlot(id)
    end
    else
    print("Error: "..bp:Name().." is full and has no container in its last slot.")
    end
    else
    return bp:Index(), bp:ItemCount(), (Item.isStackable(id) and 100) or 1
    end
    else
    print("Error: All backpacks aren't open.")
    end
    end

    local function MoveToSelf(Corpse, Spot)
    local item = Corpse:GetItemData(Spot)
    if Self.Cap() >= Item.GetWeight(item.id)*item.count then
    local index, slot, count = GetSlot(item.id)
    if index then
    local tries = 0
    local LCount = Corpse:ItemCount()
    while Corpse:isOpen() and Corpse:ItemCount() == LCount and tries < 10 do
    Corpse:MoveItemToContainer(Spot, index, slot, math.min(item.count, count))
    Wait()
    tries = tries + 1
    end
    Wait()
    if Corpse:isOpen() and Corpse:ItemCount() ~= LCount and count == item.count then
    return true
    end
    if Corpse:isOpen() and count < item.count then
    return MoveToSelf(Corpse, Spot)
    end
    end
    else
    print("Error: Not enough capacity.")
    end
    return false
    end

    local function IsLoot(id)
    return ((Item.GetValue(id) >= LootAboveValue) or
    (Item.isStackable(id) and (Item.GetValue(id)/Item.GetWeight(id)) > LootAboveValueRatio) or
    LootList[id]) and (LootGold or id ~= 3031)
    end

    local CorpseNames = {"The", "Demonic", "Dead", "Slain", "Dissolved", "Remains", "Elemental"}
    local function IsCorpseByName(name)
    for _, CPartName in ipairs(CorpseNames) do
    if name:find(CPartName) then
    return true
    end
    end
    return false
    end

    local function GrabItems(Corpse)
    local success = true
    if (Item.isCorpse(Corpse:ID()) or IsCorpseByName(Corpse:Name())) then
    for Spot = Corpse:ItemCount() - 1, 0, -1 do
    if IsLoot(Corpse:GetItemData(Spot).id) then
    success = success and MoveToSelf(Corpse, Spot)
    Wait()
    end
    end
    end
    return success
    end

    local function OpenCorpse(pos, count)
    if Item.isCorpse(Map.GetTopUseItem(pos.x, pos.y, pos.z).id) and count == 1 then
    local tries = 0
    -- 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.
    while tries < 10 and not (Self.UseItemFromGround(pos.x, pos.y, pos.z) and (wait(40, 50) or Wait() or true) and Item.isCorpse(Container.GetLast():ID())) do
    tries = tries + 1
    end
    Wait()
    return tries < 10
    else
    local Browse = Container.GetByName("Browse Field")
    local tries = 0
    while (not Browse:isOpen() and tries < 10) do
    Self.BrowseField(pos.x, pos.y, pos.z)
    Wait()
    Browse = Container.GetByName("Browse Field")
    tries = tries + 1
    end
    Wait()
    local success = true
    for Spot = Browse:ItemCount() - 1, 0, -1 do
    if Item.isCorpse(Browse:GetItemData(Spot).id) then
    local tries = 0
    while tries < 10 and not (Browse:UseItem(Spot) and (wait(40, 50) or Wait() or true) and Item.isCorpse(Container.GetLast():ID())) do
    tries = tries + 1
    end
    Wait()
    success = success and tries < 10
    count = count - 1
    end
    if count == 0 then break end
    end
    return success
    end
    end

    if OpenCorpses then
    Module("Open Corpses", function(open)
    local UpdatedCorpses = {}
    for numPos, count in pairs(Corpses) do
    local pos = ToPos(numPos)
    if Self.DistanceFromPosition(pos.x, pos.y, pos.z) <= 1 and (LootFirst or Self.TargetID() == 0) then
    if not OpenCorpse(pos, count) then
    UpdatedCorpses[ToNumber(pos)] = count
    else
    GrabItems(Container.GetLast())
    end
    else
    UpdatedCorpses[ToNumber(pos)] = count
    end
    Corpses = UpdatedCorpses
    end
    end)
    end

    Module("Loot Corpses", function(loot)
    for _, c in Container.iContainers() do
    if (Item.isCorpse(c:ID()) or IsCorpseByName(c:Name())) and c:isOpen() then
    if GrabItems(c) then
    Wait()
    if CloseCorpses then c:Close() end
    end
    end
    end
    end)

  3. #3
    Rif's Avatar
    Join Date
    Dec 2014
    Location
    Poland
    Posts
    284
    Mentioned
    37 Post(s)
    Tagged
    0 Thread(s)
    @shadowart, You know that this code is unuseful? xD Should be removed. A few days ago i wrote quite-good looter, if u need i can share for you just pm me.

  4. #4
    Moderator shadowart's Avatar
    Join Date
    Dec 2014
    Location
    Sweden
    Posts
    1,985
    Mentioned
    225 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by Rif View Post
    @shadowart, You know that this code is unuseful? xD Should be removed. A few days ago i wrote quite-good looter, if u need i can share for you just pm me.
    I can assure you that it works quite well on real Tibia. If you're playing on an OT with a bugged Container.GetLast on the other hand... well then it breaks.

  5. #5
    Rif's Avatar
    Join Date
    Dec 2014
    Location
    Poland
    Posts
    284
    Mentioned
    37 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by shadowart View Post
    I can assure you that it works quite well on real Tibia. If you're playing on an OT with a bugged Container.GetLast on the other hand... well then it breaks.
    Jup it works on real but little crazy
    Basic:
    #Don't work if kill monsters with aoe rune or spell
    #6/10 times don't close monsters body and browse filed(tested with many waits)
    #Items sorter don't collect all items, worng indexs or something(even if i setup sorter to one and two's bp)
    #Don't open body under killed another body
    #Sometimes goup with leaders or use rope places.
    Advanced:
    #Don't ignore monsters with loot: nothing or without message e.g "snake"
    #Sometimes don't open trashed body(2/10)
    #There is no function to select cropses with special item from list
    #limited loot range to 1 sqm
    #Try open another players body.

  6. #6
    Moderator shadowart's Avatar
    Join Date
    Dec 2014
    Location
    Sweden
    Posts
    1,985
    Mentioned
    225 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by Rif View Post
    #Don't work if kill monsters with aoe rune or spell
    Works perfectly with aoe attacks on real Tibia.
    #6/10 times don't close monsters body and browse filed(tested with many waits)
    Works on real Tibia.

    #Items sorter don't collect all items, worng indexs or something(even if i setup sorter to one and two's bp)
    Works with every single item I've tried on real Tibia.
    #Don't open body under killed another body
    Works on real Tibia.
    #Sometimes goup with leaders or use rope places.
    Know and documented issue.
    #Don't ignore monsters with loot: nothing or without message e.g "snake"
    Cannot be worked around perfectly in lua. Considering its speed I'd rather open every body and than risk not opening one with valuable loot.
    #Sometimes don't open trashed body(2/10)
    Works in real Tibia.
    #There is no function to select cropses with special item from list
    I have no idea what you're trying to say with that.
    #limited loot range to 1 sqm
    This is a feature, use the built in looter if you want to loot from the entire screen.
    #Try open another players body.
    There are no perfect workarounds for this in lua.

  7. #7
    Rif's Avatar
    Join Date
    Dec 2014
    Location
    Poland
    Posts
    284
    Mentioned
    37 Post(s)
    Tagged
    0 Thread(s)
    Bro i tested this script over 1h couse i created better so i see difference, don't tell me if it work, maybe if specific condition who cannot be uset by simple xeno user.

  8. #8
    Senior Member
    Join Date
    Jul 2014
    Posts
    788
    Mentioned
    62 Post(s)
    Tagged
    0 Thread(s)
    @Rif, you are simple xeno user, proves:

    lua code:

    local indexs = {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {-1, 0}, {-2, 0}, {-3, 0}, {-4, 0}, {-5, 0}, {-6, 0}, {-7, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, -1}, {0, -2}, {0, -3}, {0, -4}, {0, -5}, {1, -1}, {1, -2}, {1, -3}, {1, -4}, {1, -5}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, -1}, {2, -2}, {2, -3}, {2, -4}, {2, -5}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {3, -1}, {3, -2}, {3, -3}, {3, -4}, {3, -5}, {3, 1}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {4, -1}, {4, -2}, {4, -3}, {4, -4}, {4, -5}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {4, 5}, {5, -1}, {5, -2}, {5, -3}, {5, -4}, {5, -5}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {6, -1}, {6, -2}, {6, -3}, {6, -4}, {6, -5}, {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {7, -1}, {7, -2}, {7, -3}, {7, -4}, {7, -5}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {-1, -1}, {-1, -2}, {-1, -3}, {-1, -4}, {-1, -5}, {-1, 1}, {-1, 2}, {-1, 3}, {-1, 4}, {-1, 5}, {-2, -1}, {-2, -2}, {-2, -3}, {-2, -4}, {-2, -5}, {-2, 1}, {-2, 2}, {-2, 3}, {-2, 4}, {-2, 5}, {-3, -1}, {-3, -2}, {-3, -3}, {-3, -4}, {-3, -5}, {-3, 1}, {-3, 2}, {-3, 3}, {-3, 4}, {-3, 5}, {-4, -1}, {-4, -2}, {-4, -3}, {-4, -4}, {-4, -5}, {-4, 1}, {-4, 2}, {-4, 3}, {-4, 4}, {4, 5}, {-5, -1}, {-5, -2}, {-5, -3}, {-5, -4}, {-5, -5}, {-5, 1}, {-5, 2}, {-5, 3}, {-5, 4}, {-5, 5}, {-6, -1}, {-6, -2}, {-6, -3}, {-6, -4}, {-6, -5}, {-6, 1}, {-6, 2}, {-6, 3}, {-6, 4}, {-6, 5}, {-7, -1}, {-7, -2}, {-7, -3}, {-7, -4}, {-7, -5}, {-7, 1}, {-7, 2}, {-7, 3}, {-7, 4}, {-7, 5},}

    function getColor()
    if color == 'white' then
    r, g, b = 255, 255, 255
    elseif color == 'azure' then
    r, g, b = 140, 255, 230
    elseif color == 'pink' then
    r, g, b = 230, 20, 230
    elseif color == 'red' then
    r, g, b = 255, 20, 10
    elseif color == 'orange' then
    r, g, b = 255, 80, 10
    elseif color == 'yellow' then
    r, g, b = 255, 220, 10
    elseif color == 'green' then
    r, g, b = 300, 255, 10
    end
    end

    it's from your pseudo MW Timer.

    Shadowarts script working like a charm.

    btw.
    @DarkstaR
    https://www.dropbox.com/s/6j1oshdrke2uq15/rif.png?dl=0

    Enjoy.


    Google's Cache never forgets.
    Last edited by HjugO; 11-18-2015 at 06:19 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •