ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   auto weapon recharge function help (https://www.esoui.com/forums/showthread.php?t=10466)

sinnereso 02/25/23 08:24 PM

auto weapon recharge function help
 
Hey guys im adding my last feature to my addon auto weapon recharge but run into an issue and cant seem to get the "ChargeItemWithSoulGem" function to actually recharge the weaps but is executing past that line. Its likly a formatting issue as that my biggest headache otherwise everything else is working perfectly.

heres some of the code im working with atm and where i believe the problem lies:

Code:

function RidinDirty.Recharge()
    local weapons = {
        EQUIP_SLOT_MAIN_HAND,
        EQUIP_SLOT_OFF_HAND,
        EQUIP_SLOT_BACKUP_MAIN,
        EQUIP_SLOT_BACKUP_OFF
    }
    local minimumWeaponCharge = 95

        for index = 0, GetBagSize(BAG_BACKPACK) do
                local gemId = GetItemId(BAG_BACKPACK, index)
                if gemId == 33271 then
                        gemIndex = index
                end
        end
        if gemIndex == nil then df("|c9900FF[RidinDirty]|r |ccc0000No Gems To Recharge Weapons|r") return end
        for _, weapon in ipairs(weapons) do
                local charge = GetChargeInfoForItem(BAG_WORN, weapon)
                if charge <= minimumWeaponCharge and IsItemChargeable then
                        ChargeItemWithSoulGem(BAG_WORN, weapon, BAG_BACKPACK, gemIndex)--    <<<<< must be executing this line but doing nothing
                        df("**** should be charging jus sayin but isnt =p")--    <<<<<< executing to here properly and as expected
                end
                local charged = GetChargeInfoForItem(BAG_WORN, weapon)
                if charged > charge then
                        df("**** should have been charged jus sayin but isnt =p")
                end
        end
end


ExoY 02/26/23 04:42 AM

Quote:

Originally Posted by sinnereso (Post 47275)
Hey guys im adding my last feature to my addon auto weapon recharge but run into an issue and cant seem to get the "ChargeItemWithSoulGem" function to actually recharge the weaps but is executing past that line. Its likly a formatting issue as that my biggest headache otherwise everything else is working perfectly.

heres some of the code im working with atm and where i believe the problem lies:

Code:

function RidinDirty.Recharge()
    local weapons = {
        EQUIP_SLOT_MAIN_HAND,
        EQUIP_SLOT_OFF_HAND,
        EQUIP_SLOT_BACKUP_MAIN,
        EQUIP_SLOT_BACKUP_OFF
    }
    local minimumWeaponCharge = 95

        for index = 0, GetBagSize(BAG_BACKPACK) do
                local gemId = GetItemId(BAG_BACKPACK, index)
                if gemId == 33271 then
                        gemIndex = index
                end
        end
        if gemIndex == nil then df("|c9900FF[RidinDirty]|r |ccc0000No Gems To Recharge Weapons|r") return end
        for _, weapon in ipairs(weapons) do
                local charge = GetChargeInfoForItem(BAG_WORN, weapon)
                if charge <= minimumWeaponCharge and IsItemChargeable then
                        ChargeItemWithSoulGem(BAG_WORN, weapon, BAG_BACKPACK, gemIndex)--    <<<<< must be executing this line but doing nothing
                        df("**** should be charging jus sayin but isnt =p")--    <<<<<< executing to here properly and as expected
                end
                local charged = GetChargeInfoForItem(BAG_WORN, weapon)
                if charged > charge then
                        df("**** should have been charged jus sayin but isnt =p")
                end
        end
end


Where is "IsItemChargeable" coming from?
Based on the Code snipped you provided this will always be nil, wouldnt it?

sinnereso 02/26/23 07:59 AM

Quote:

Originally Posted by ExoY (Post 47276)
Where is "IsItemChargeable" coming from?
Based on the Code snipped you provided this will always be nil, wouldnt it?

ya seems your correct. Im new at this so getting mind blown with formatting. I think ive found my 2 issues. the weapons array isnt passing to the chargeweapon line properly for some reason.

ExoY 02/26/23 09:29 AM

Quote:

Originally Posted by sinnereso (Post 47277)
ya seems your correct. Im new at this so getting mind blown with formatting. I think ive found my 2 issues. the weapons array isnt passing to the chargeweapon line properly for some reason.

you dont use your table in that line anyway. You use the respective entry your loop is currently looking at.
So I dont know what you mean with that comment.

Also looks like you forgot to define the gemIndex locally. This can cause issues.

Also for troubleshooting, just use the function in quesiton (here: ChargeItemWithSoulGem) manually with script lines in chat.
That makes it easier to pin point the problem

sinnereso 02/26/23 09:41 AM

Quote:

Originally Posted by ExoY (Post 47278)
you dont use your table in that line anyway. You use the respective entry your loop is currently looking at.
So I dont know what you mean with that comment.

Also looks like you forgot to define the gemIndex locally. This can cause issues.

Also for troubleshooting, just use the function in quesiton (here: ChargeItemWithSoulGem) manually with script lines in chat.
That makes it easier to pin point the problem

Ive been making a huge mess of it here trying everything and putting text messages all over displaying some results and im seeing 0 for gem slot everywhere i test. been at this 3 days now and going krazy lol

sinnereso 02/26/23 09:54 AM

Quote:

Originally Posted by ExoY (Post 47278)
you dont use your table in that line anyway. You use the respective entry your loop is currently looking at.
So I dont know what you mean with that comment.

Also looks like you forgot to define the gemIndex locally. This can cause issues.

Also for troubleshooting, just use the function in quesiton (here: ChargeItemWithSoulGem) manually with script lines in chat.
That makes it easier to pin point the problem

Code:

function RidinDirty.GetGems()
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        gemId = slotId
                        df("found gems %s", gemId) -- <<<<<< returning 0 to chat as well which makes no sense to me.. it should be the slot# i would think
                        return gemId
                end
        end
end


ExoY 02/26/23 11:19 AM

Quote:

Originally Posted by sinnereso (Post 47280)
Code:

function RidinDirty.GetGems()
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        gemId = slotId
                        df("found gems %s", gemId) -- <<<<<< returning 0 to chat as well which makes no sense to me.. it should be the slot# i would think
                        return gemId
                end
        end
end


I just copied your snipped and it does what it is supposed to do. provided slot id of full soul gems.
(Doesnt differentiate between crown and normal though)

Anyhow. Firstly, you again have a global variable leakage with gemId, which is not good practise. Try to always remember to make those variables local.

Secondly, if something isnt working, I dont recommend just putting debug messages anywhere. Properly pin point the problem by testing each function in its most simplest way, e.g. with chat script to make sure you use them correctly etc....

Baertram 02/26/23 11:24 AM

ExoY is right. Especially about the missing local, leaking global variables.

Hint about scripts testing ingame:
MerTorchbug provides a script history and ways to run multiline scripts ingame.
Just type /tbs to open it. All /script entries will be added to that history.
It's easier to test things ingame that way.

sinnereso 02/26/23 12:10 PM

Quote:

Originally Posted by ExoY (Post 47281)
I just copied your snipped and it does what it is supposed to do. provided slot id of full soul gems.
(Doesnt differentiate between crown and normal though)

Anyhow. Firstly, you again have a global variable leakage with gemId, which is not good practise. Try to always remember to make those variables local.

Secondly, if something isnt working, I dont recommend just putting debug messages anywhere. Properly pin point the problem by testing each function in its most simplest way, e.g. with chat script to make sure you use them correctly etc....

so this is working for main hand but if i change "EQUIP_SLOT_MAIN_HAND" back to "weapon" which is directly from the function calling this code it doesnt work. but this does work for main hand:

Code:

function RidinDirty.GetGems(slotId)
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        --local gemSlot = slotId
                        df("found gems %s", slotId) -- <<<<<< returning 0 to chat instead of the slot #
                        ChargeItemWithSoulGem(BAG_WORN, EQUIP_SLOT_MAIN_HAND, BAG_BACKPACK, slotId)
                        --return gemSlot
                end
        end
end


sinnereso 02/26/23 12:37 PM

everything looks like it should be working but I dont see how you could run complex functions on a /script. Heres everything related as it is at this moment.. ill leave it this way and give up later if i cant get it working. im getting a headache.

Code:

function RidinDirty.PlayerActivated()
        if autoRechargeToggle == "enabled" then
                EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, RidinDirty.InventoryUpdate)
        end
end

-- Auto recharge weapons with soulgems
function RidinDirty.InventoryUpdate(eventCode, bagId, slotId, isNewItem, itemSoundCategory, inventoryUpdateReason, stackCountChange)
        if bagId ~= BAG_WORN then return end
        if inventoryUpdateReason == 3 and not IsUnitDead(PLAYER) then
                RidinDirty.GetGems()
        end
end

function RidinDirty.GetGems()
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        local gemSlot = slotId
                        RidinDirty.Recharge()
                end
        end
end

function RidinDirty.Recharge()
    local minimumWeaponCharge = 97
        local weapons = {
        EQUIP_SLOT_MAIN_HAND,
        EQUIP_SLOT_OFF_HAND,
        EQUIP_SLOT_BACKUP_MAIN,
        EQUIP_SLOT_BACKUP_OFF
    }
        for _, weapon in ipairs(weapons) do
                df("found weapon %s", weapon)
                local charge, maxCharge = GetChargeInfoForItem(BAG_WORN, weapon)
                if charge <= minimumWeaponCharge then --and IsItemChargeable(BAG_WORN, weapon) then --and not maxCharge == 0 then
                        ChargeItemWithSoulGem(BAG_WORN, weapon, BAG_BACKPACK, gemSlot)
                end
                local charged, maxCharged = GetChargeInfoForItem(BAG_WORN, weapon)
                if charged > charge then
                        df("should have been charged")
                end
        end
end

function RidinDirty.RechargeToggle()
        local autoRechargeToggle = RidinDirty.savedVariables.autoRecharge
        if autoRechargeToggle == nil or autoRechargeToggle == "" or autoRechargeToggle == "disabled" then
                autoRechargeToggle = "enabled"
                RidinDirty.savedVariables.autoRecharge = autoRechargeToggle
                EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, RidinDirty.InventoryUpdate)
                df("|c9900FF[RidinDirty]|r Auto Recharge: %s", autoRechargeToggle)
        else
                autoRechargeToggle = "disabled"
                RidinDirty.savedVariables.autoRecharge = autoRechargeToggle
                EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
                df("|c9900FF[RidinDirty]|r Auto Recharge: %s", autoRechargeToggle)
        end
end

SLASH_COMMANDS["/ridindirty_recharge"] = RidinDirty.RechargeToggle


sinnereso 02/26/23 01:01 PM

I changed the structure a bit there just messin but my primary issue is the chargeitemwithsoulgem line.. it just wont charge unless i manually enter the weapon slot and gem slot. i cant seem to get the weapon slot and gem slot to pass to make it to that line.

Baertram 02/26/23 01:53 PM

I had read that others notified you about that already so here, once again:
Code:

inventoryUpdateReason == 3
Do not use hardcoded numbers like 3 if there are constants provided by the game already which should be used, like BAG_BACKPACK instead of 1 there exists contants for the INVENTORY_UPDATE_REASON_*.
Code:

INVENTORY_UPDATE_REASON_DEFAULT = 0
INVENTORY_UPDATE_REASON_DURABILITY_CHANGE = 1
INVENTORY_UPDATE_REASON_DYE_CHANGE = 2
INVENTORY_UPDATE_REASON_ITEM_CHARGE = 3
INVENTORY_UPDATE_REASON_PLAYER_LOCKED = 4
INVENTORY_UPDATE_REASON_ARMORY_BUILD_CHANGED = 5

To find the constants check the API documentation for the events/functions where those are used and you'll find the type used in there, defied in [typeHere].
Then search for that type in the same API documentation txt file and you'll see the constants that are available.


It's also possible to use merTorchbug ingame and type /tb to show the global inspector, then change to tab "Constants". It provides a search too.

Baertram 02/26/23 01:54 PM

Quote:

Originally Posted by sinnereso (Post 47284)
everything looks like it should be working but I dont see how you could run complex functions on a /script. Heres everything related as it is at this moment.. ill leave it this way and give up later if i cant get it working. im getting a headache.

Code:

function RidinDirty.PlayerActivated()
        if autoRechargeToggle == "enabled" then
                EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, RidinDirty.InventoryUpdate)
        end
end

-- Auto recharge weapons with soulgems
function RidinDirty.InventoryUpdate(eventCode, bagId, slotId, isNewItem, itemSoundCategory, inventoryUpdateReason, stackCountChange)
        if bagId ~= BAG_WORN then return end
        if inventoryUpdateReason == 3 and not IsUnitDead(PLAYER) then
                RidinDirty.GetGems()
        end
end

function RidinDirty.GetGems()
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        local gemSlot = slotId
                        RidinDirty.Recharge()
                end
        end
end

function RidinDirty.Recharge()
    local minimumWeaponCharge = 97
        local weapons = {
        EQUIP_SLOT_MAIN_HAND,
        EQUIP_SLOT_OFF_HAND,
        EQUIP_SLOT_BACKUP_MAIN,
        EQUIP_SLOT_BACKUP_OFF
    }
        for _, weapon in ipairs(weapons) do
                df("found weapon %s", weapon)
                local charge, maxCharge = GetChargeInfoForItem(BAG_WORN, weapon)
                if charge <= minimumWeaponCharge then --and IsItemChargeable(BAG_WORN, weapon) then --and not maxCharge == 0 then
                        ChargeItemWithSoulGem(BAG_WORN, weapon, BAG_BACKPACK, gemSlot)
                end
                local charged, maxCharged = GetChargeInfoForItem(BAG_WORN, weapon)
                if charged > charge then
                        df("should have been charged")
                end
        end
end

function RidinDirty.RechargeToggle()
        local autoRechargeToggle = RidinDirty.savedVariables.autoRecharge
        if autoRechargeToggle == nil or autoRechargeToggle == "" or autoRechargeToggle == "disabled" then
                autoRechargeToggle = "enabled"
                RidinDirty.savedVariables.autoRecharge = autoRechargeToggle
                EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, RidinDirty.InventoryUpdate)
                df("|c9900FF[RidinDirty]|r Auto Recharge: %s", autoRechargeToggle)
        else
                autoRechargeToggle = "disabled"
                RidinDirty.savedVariables.autoRecharge = autoRechargeToggle
                EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_INVENTORY_SINGLE_SLOT_UPDATE)
                df("|c9900FF[RidinDirty]|r Auto Recharge: %s", autoRechargeToggle)
        end
end

SLASH_COMMANDS["/ridindirty_recharge"] = RidinDirty.RechargeToggle



The function ChargeItemWithSoulGem uses the bagId and slotIndex of BAG_WORN that you want to charge, and the bagId and slotIndex of the soulgem in your bags.

Lua Code:
  1. ChargeItemWithSoulGem(bagId,slotIndex,gem.bag,gem.index)

Your code should work fine if the function is called properly and the soulgem bagId and slotIndex are correct!
I'd check the soulgems tuff to be the correct ones, via debug messages!

In your function RidinDirty.Recharge() gemSlot is not known! Ths cannot work.
You specify it in your function RidinDirty.GetGems() as local so it's ONLY known inside that function.


You should do it like this instead:
Pass in the slotId as "gemSlot" to your function RidinDirty.Recharge
or define 1 local gemslot at the top of your lua file and then set it at function RidinDirty.GetGems() and use it at RidinDirty.Recharge

local variables are only available in their closure, means inside the if ... end or inside the function ... end or inside a for ... do end loop etc.
If you want it to be avaialable in all functions of a file you need to define it at the top of the file, outside of all functions etc.
Or use it as RidinDirty.gemSlot, added to your global variable!

Lua Code:
  1. function RidinDirty.GetGems()
  2.     for slotId = 0, GetBagSize(BAG_BACKPACK) do
  3.         if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
  4.              
  5.             return RidinDirty.Recharge(slotId)
  6.  
  7.         end
  8.     end
  9. end
  10.  
  11. function RidinDirty.Recharge(gemSlot)
  12.  if gemSlot == nil then return false end
  13.  ...--your other code here
  14.   --optional: if everything went well return true after charging
  15.   return true
  16. end

I personally would NOT combine GetGems and Recharge so they always will be run together. Just run GetGems once before usage, from e.g. function RidinDirty.Recharge, and then recharge the items that you want to.
Not the other way around: Call Recharge from GetGems.

sinnereso 02/26/23 05:30 PM

had a quick nap.. thank you bro ill give that stuff a whirl.. ill liklly have issues with the bag_worn,bag part and how to achieve it but ill see what i can figure out.

sinnereso 02/26/23 05:41 PM

i also did try it this way initially cuz i wanted to be sure it was checking and found a gem for each repair to be sure.. ill restructure it that way again and see.

Code:

function RidinDirty.GetGems()
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        local gemSlot = slotId
                        --return gemSlot
                        RidinDirty.Recharge(slotId)
                        --if RidinDirty.Recharge == true then return end
                end
        end
end


sinnereso 02/26/23 05:52 PM

ok I readjusted it and and reaplced the 3 with INVENTORY_UPDATE_REASON_ITEM_CHARGE as well.. not gonna use the return true stuff yet as im trying to keep it basic untill i see recharge actually happening. heres the brint of it and if your correct then I just need to work on the "ChargeItemWithSoulGem(BAG_WORN, weapon, BAG_BACKPACK, gemSlot)" line again which is pretty much all ive been doing.

Code:

function RidinDirty.GetGems()
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        local gemSlot = slotId
                        RidinDirty.Recharge(gemSlot)
                end
        end
end

function RidinDirty.Recharge(gemSlot)
    local minimumWeaponCharge = 97
        local weapons = {
        EQUIP_SLOT_MAIN_HAND,
        EQUIP_SLOT_OFF_HAND,
        EQUIP_SLOT_BACKUP_MAIN,
        EQUIP_SLOT_BACKUP_OFF
    }
        if gemSlot == nil then return false end
        for _, weapon in ipairs(weapons) do
                df("found weapon %s", weapon)
                local charge, maxCharge = GetChargeInfoForItem(BAG_WORN, weapon)
                if charge <= minimumWeaponCharge then --and IsItemChargeable(BAG_WORN, weapon) then --and not maxCharge == 0 then
                        --local gemSlot = RidinDirty.GetGems()
                        ChargeItemWithSoulGem(BAG_WORN, weapon, BAG_BACKPACK, gemSlot)
                end
                local charged, maxCharged = GetChargeInfoForItem(BAG_WORN, weapon)
                if charged > charge then
                        df("should have been charged %s", weapon)
                        --return true
                end
        end
end


sinnereso 02/26/23 06:04 PM

do you think i can merge the "for _, weapon in ipairs(weapons) do" code into the "if isitemsoulgem...." in the getgems() function? it might work there cuz so far thats the only place I can get the soul gem slotID to actually work.

or merge the getgems code into the recharge function? either way? So like I dont have 2 functions?

sinnereso 02/26/23 06:20 PM

what im seeing right now is the text output after "chargeitemwithsoulgem" for ONLY off_hand, backup_main and backup_off and NOT the MAIN_HAND which is the one that needs charging.. Suggesting its not even trying to charge the main hand but trying all others which are empty slots.. im ok with that for the moment untill i can get MAIN_HAND charging but why not MAIN_HAND?

sinnereso 02/26/23 07:12 PM

i appreciate all the help but nothing has helped at all and its still doing the exactly the same thing.. recharging everything but main hand that needs it. Ive even resorted to try this and not charging it..

Code:

function RidinDirty.GetGems()
        local minimumWeaponCharge = 97
       
        for slotId = 0, GetBagSize(BAG_BACKPACK) do
                if IsItemSoulGem(SOUL_GEM_TYPE_FILLED, BAG_BACKPACK, slotId) then
                        local gemSlot = slotId
                        local charge, maxCharge = GetChargeInfoForItem(BAG_WORN, EQUIP_SLOT_MAIN_HAND)
                        if charge <= minimumWeaponCharge then --and IsItemChargeable(BAG_WORN, weapon) then --and maxCharge ~= 0 then
                                ChargeItemWithSoulGem(BAG_WORN, EQUIP_SLOT_MAIN_HAND, BAG_BACKPACK, gemSlot)
                                df("CHARGING WORN:" .. BAG_WORN .. " Weap:" .. EQUIP_SLOT_MAIN_HAND .. " BAG:" .. BAG_BACKPACK .. " GEMSLOT:" .. gemSlot)
                        end
                end
        end
end


sinnereso 02/26/23 08:38 PM

ok i think i got it and as expected was something soo stupid.. my minimumweaponcharge i set to 97 assuming that was like a % for some reason when weaps have 500max charges.. my main wasnt down that far to be charged!!! omg but the rest of all your help was great and managed to get it all working under getgems... out testing it now in the real world.. thank you guys!


All times are GMT -6. The time now is 10:34 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI