• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

Question - Any way to get the XTarget(i)'s target?

Joined
Mar 20, 2024
RedCents
1,051¢
I am trying to cycle through the XTarget list to determine how many of those mobs are targeting one (any) of my group members. The idea is that if it's more than one mob targeting a (any) of my group members, the enchanter would cast an AoE mez instead of a single mez.

I have tried mq.TLO.Me.XTarget(1).Target.CleanName() but it doesnt work. Any suggestion?
 
I am trying to cycle through the XTarget list to determine how many of those mobs are targeting one (any) of my group members. The idea is that if it's more than one mob targeting a (any) of my group members, the enchanter would cast an AoE mez instead of a single mez.

I have tried mq.TLO.Me.XTarget(1).Target.CleanName() but it doesnt work. Any suggestion?
You cannot get the target of an xtarget afaik.
You could have all the characters you're boxing checking their aggro percentage and then use something to tell the enchanter if they have aggro. Sounds like it could be good for something like Actors.
 
Ugh, so that means that I need to... 1) have a designated character doing FOR loop cycle going through all the mobs in XTarget, 2) target each of them individually, 3) check their respective TargetOfTarget, and finally 4) tell the enchanter the mobs to mez.

Super inefficient :( I wish there was a better way. That constant change on targets pretty much renders that designated character useless for other tasks.
 
Ugh, so that means that I need to... 1) have a designated character doing FOR loop cycle going through all the mobs in XTarget, 2) target each of them individually, 3) check their respective TargetOfTarget, and finally 4) tell the enchanter the mobs to mez.

Super inefficient :( I wish there was a better way. That constant change on targets pretty much renders that designated character useless for other tasks.
Doesn't the XTarget window have the aggro of each XTarget?

TBH unless you're low level I'd just use the AOE. Enchanter wait times for AoE are pretty much non-existent and preferring single when there is more than two critters doesn't make sense in most situations that come to mind. I'd just assume if you have 3 or more on XTarget that you should use an AoE and save yourself all this headache.

With automation you have to find the happy medium between the bot thinking and the bot taking the action that requires the least amount of overhead. But at the end of the day it's all up to you on how you want to handle it.
 
Doesn't the XTarget window have the aggro of each XTarget?

Yes it does, but I need to save into a Lua table the ID of the mobs in XTarget that are currently aggroing one of my toons. As per your previous response (if I understood correctly), the only way to do it is to cycle through the Xtarget list, target each mob individually and query their respective Target. Did I misunderstand your previous comment?
 
Last edited:
Are you trying to overcomplicate things? You can just check the number of Mobs on Xtarget and if its >= 2 then Use AOE - And dont forget to put a Distance check in there. You could get a mob on xtarget from 1 mile away.

Code:
        if mq.TLO.Me.XTargetSlots() ~= nil then
            max_targets = mq.TLO.Me.XTargetSlots()
            if max_targets >=2 then 
                  Use AOE
            else
                  Use Single
            end
        end
 
Yes it does, but I need to save into a Lua table the ID of the mobs in XTarget that are currently aggroing one of my toons. As per your previous response (if I understood correctly), the only way to do it is to cycle through the Xtarget list, target each mob individually and query their respective Target. Did I misunderstand your previous comment?
yeah basically you either cycle through the list to find the target.
Or use Actors and have the other characters notify when they have agro and what the mobs info is.
you can stuff all the info you care about into a table and send the message with actors, without having to rapid cycle targets.
 
yeah basically you either cycle through the list to find the target.
Or use Actors and have the other characters notify when they have agro and what the mobs info is.
you can stuff all the info you care about into a table and send the message with actors, without having to rapid cycle targets.

This seems like a winner!

I have used the search function but I dont find anything related to "Actors". Could you share a link please? Thanks again :)
 
Well you can use the window TLO to read the element that holds the aggro information to get the percentage of aggro you have. If it's 100, then you have aggro from the mob.
I don't Lua. So someone can translate for me.

${Window[Name of XTarget Window].Child[Child Element that holds the aggro % number].Text} or something of the like. It may not be "Text" at the end. But that's the jist of what I was suggesting if you were going to cycle.

There are some existing scripts that use actors, though an example script would probably be best to look at. Perhaps just make a standalone script to test the functionality of what you're wanting and then incorporate it into your existing logic once you've confirmed it's working as intended.

But again I'm of the mind that sometimes more is less and would just AoE if you have more than 2 xtargets.
 
Lua:
local function ScanXtarAggro()
    local xCount = mq.TLO.Me.XTarget() or 0 -- get count from xtarget window
    if xCount > 0 then                                     -- if have items on xtarget  continue
        for i = 1, mq.TLO.Me.XTargetSlots() do  -- cycle through our total xtarg slots
            if mq.TLO.Me.XTarget(i).ID() ~= 0 then   -- if there is a target there ID should be greater than 0
                if mq.TLO.Me.XTarget(i).PctAggro() < 100 then -- check PCT Aggro if not 100% we don't have it

                    -- someone else has aggro do a thing

                end
            end
        end
    end
end
 
Lua:
local function ScanXtarAggro()
    local xCount = mq.TLO.Me.XTarget() or 0 -- get count from xtarget window
    if xCount > 0 then                                     -- if have items on xtarget  continue
        for i = 1, mq.TLO.Me.XTargetSlots() do  -- cycle through our total xtarg slots
            if mq.TLO.Me.XTarget(i).ID() ~= 0 then   -- if there is a target there ID should be greater than 0
                if mq.TLO.Me.XTarget(i).PctAggro() < 100 then -- check PCT Aggro if not 100% we don't have it

                    -- someone else has aggro do a thing

                end
            end
        end
    end
end
Hey, nice didn't know if there was a member for the pctaggro. That is even better if you're going that route.
 
Lua:
local function ScanXtarAggro()
    local xCount = mq.TLO.Me.XTarget() or 0 -- get count from xtarget window
    if xCount > 0 then                                     -- if have items on xtarget  continue
        for i = 1, mq.TLO.Me.XTargetSlots() do  -- cycle through our total xtarg slots
            if mq.TLO.Me.XTarget(i).ID() ~= 0 then   -- if there is a target there ID should be greater than 0
                if mq.TLO.Me.XTarget(i).PctAggro() < 100 then -- check PCT Aggro if not 100% we don't have it

                    -- someone else has aggro do a thing

                end
            end
        end
    end
end

Thank you for this, very much appreciated.

Question: Wouldnt we need to add a second FOR loop inside in order to cycle through all characters? Something like this...

Code:
local function ScanXtarAggro()

    local xCount = mq.TLO.Me.XTarget() or 0 -- get count from xtarget window
    local aggroCount = 0 -- how many mobs are aggrod on any of our characters
 
    if xCount > 0 then -- if have items on xtarget  continue
        for i = 1, mq.TLO.Me.XTargetSlots() do  -- cycle through our total xtarg slots
            if mq.TLO.Me.XTarget(i).ID() ~= 0 then   -- if there is a target there ID should be greater than 0

                for ii = 0, 5 do --- Cycle through all 6 group members
                    if mq.TLO.Group.Member(ii).XTarget(i).PctAggro() == 100 then -- check PCT Aggro. If 100% it means that mob(i) is aggroed on character(ii)
                        aggroCount = aggroCount + 1
                    end
                end

            end
        end
    end

    -- Now that we know how many mobs are aggrod on any group member (aggroCount), lets do some crowd control.
    if aggroCount == 0 then
        -- Nobody is aggroed. Dont do anything.
    elseif aggroCount == 1 then
        -- DO SINGLE MEZZ
    elseif aggroCount > 1 then
        -- DO AoE MEZZ
    end

end
 
Last edited:
Thank you for this, very much appreciated.

Question: Wouldnt we need to add a second FOR loop inside in order to cycle through all characters? Something like this...

Code:
local function ScanXtarAggro()

    local xCount = mq.TLO.Me.XTarget() or 0 -- get count from xtarget window
    local aggroCount = 0 -- how many mobs are aggrod on any of our characters
 
    if xCount > 0 then -- if have items on xtarget  continue
        for i = 1, mq.TLO.Me.XTargetSlots() do  -- cycle through our total xtarg slots
            if mq.TLO.Me.XTarget(i).ID() ~= 0 then   -- if there is a target there ID should be greater than 0

                for ii = 0, 5 do --- Cycle through all 6 group members
                    if mq.TLO.Group.Member(ii).XTarget(i).PctAggro() == 100 then -- check PCT Aggro. If 100% it means that mob(i) is aggroed on character(ii)
                        aggroCount = aggroCount + 1
                    end
                end

            end
        end
    end

    -- Now that we know how many mobs are aggrod on any group member (aggroCount), lets do some crowd control.
    if aggroCount == 0 then
        -- Nobody is aggroed. Dont do anything.
    elseif aggroCount == 1 then
        -- DO SINGLE MEZZ
    elseif aggroCount > 1 then
        -- DO AoE MEZZ
    end

end
That information isn't available to a client. You would have to make each character check themselves and relay it back to the enchanter.

Basically the server only transmits information the client needs. So another spawns target isn't normally transmitted unless you have them targeted. In which case you get target of target.
The same applies for buffs. So you don't know what buffs another spawn has without a target. So you would need to use dannet or actors to get the information from the other client.
 
That information isn't available to a client. You would have to make each character check themselves and relay it back to the enchanter.

Good point!

However, if each character were to individually relay back to the enchanter in case of aggro, the enchanter would always compute them as single action points (single mezz) as opposed to a combined action point (AoE mezz). What I am trying to say is that the Enchanter would need to somehow assemble all incoming requests from all group members so, if more than one character sends out a "distress signal" within a short period of time (say 1 second), the enchanter would know that he needs to cast AoE mezz instead of single mezz.

Do you know what I mean?
 
simple actors setup.

require actors and set your Actor Variable for later.

Lua:
local actors = require('actors')
local Actor -- preloaded variable outside of the function

setup the mailbox to receive the messages from everyone running script
the example below is pulling information from everyone's AA window and sending it in the message

Lua:
--create mailbox for actors to send messages to
function RegisterActor()
    Actor = actors.register('aa_party', function(message) -- aa_party is the name of the mailbox
    -- Table to hold message details
local MemberEntry = message()
-- variables for the message details for later use
        local aaXP = MemberEntry.PctExp or 0
        local aaSetting = MemberEntry.Setting or '0'
        local who = MemberEntry.Name
        local pts = MemberEntry.Pts or 0
        local ptsTotal = MemberEntry.PtsTotal or 0
        local ptsSpent = MemberEntry.PtsSpent or 0
        local found = false
        for i = 1, #groupData do
        -- if the sender is already in table just update the data and not create a new row.
            if groupData[i].Name == who then
            groupData[i].XP = aaXP
            groupData[i].Setting = aaSetting
            groupData[i].Pts = pts
            groupData[i].PtsTotal = ptsTotal
            groupData[i].PtsSpent = ptsSpent
            found = true
            break
            end
        end
        if not found then
            -- if new character then add data to the table.
            table.insert(groupData, {Name = who, XP = aaXP, Setting = aaSetting, Pts = pts, PtsTotal = ptsTotal, PtsSpent = ptsSpent})
        end
    end)
end

Send messages
you are going to be updating these variables somewhere and calling this inside your loop if your conditions are met. no need to spam actors messages on duplicate data.
Lua:
    --send message to the mailbox from this character
    Actor:send({mailbox='aa_party'}, {PctExp = PctAA, Setting = SettingAA, Name = ME, Pts = PtsAA, PtsTotal = PtsTotal, PtsSpent = PtsSpent})

Using the data

Lua:
 -- Snippet of parsing data from the table
 if #groupData > 0 then
            for i = 1, #groupData do
                if groupData[i] ~= nil then
                    --local tmpName = mq.TLO.Spawn(groupData[i].Name).Class.ShortName() --used for videos
                    ImGui.SeparatorText("%s", groupData[i].Name)
                    -- local yPos = ImGui.GetCursorPosY()
                    ImGui.PushStyleColor(ImGuiCol.PlotHistogram,ImVec4(0.2, 0.9, 0.9, 0.5))
                    ImGui.ProgressBar(groupData[i].XP/100,ImVec2(165,8),"##AAXP"..groupData[i].Name)
                    ImGui.PopStyleColor()
                end
            end
end

Hope this helps.
 
Good point!

However, if each character were to individually relay back to the enchanter in case of aggro, the enchanter would always compute them as single action points (single mezz) as opposed to a combined action point (AoE mezz). What I am trying to say is that the Enchanter would need to somehow assemble all incoming requests from all group members so, if more than one character sends out a "distress signal" within a short period of time (say 1 second), the enchanter would know that he needs to cast AoE mezz instead of single mezz.

Do you know what I mean?
What about a table that keeps track of the current status of group members. They relay a change only. Either they have aggro or they do not.

So at first it is setup as nobody has aggro. If no xtargets it's skipped and all are false. If a group member gets aggro they send once that they have aggro. If they lose aggro then they send once they no longer have aggro.

This way it's clear after each fight and it's only sending changes,not a constant report.

Then the enchanter can look at the table when checking mezzes and determine when to use it at that time that it's being checked.
 
you could also just compare # of xtargets vs number the tank has agro on.
and only have the tank send the messages if its below a threshold.
 
I have been trying to learn how to implement Actors (via SharedDataClient), and I am half way there.

I have created a custom Lua script to collect all the data I need from my characters, and I have linked it into the SharedDataClient UI:

Screenshot 2024-05-22 211239.png

The script works great, and it relays in real time all that data to the UI without a problem:

Screenshot 2024-05-22 211413.png

In fact, all other characters in the group can also see this data through the UI, so the Actors "network" is indeed keeping the communication flowing among all characters. YAY!

However... where I am stuck now is in the second part of the equation: I cannot figure out how to bring the data back down from the UI so I utilize it in my other Lua scripts. Can anyone share some feedback on how to capture all that shared data back down into the code?

Thanks!
 
Question - Any way to get the XTarget(i)'s target?

Users who are viewing this thread

Back
Top
Cart