• 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

Lua No Continue?

Joined
Feb 24, 2005
RedCents
2,154¢
The lack of a continue statement is insane IMO.
I was able to figure out how to emulate it like this... Anyone else got a solution? Using a goto feels dirty.

Code:
    for i = 1, mq.TLO.Me.XTarget() do
        if mq.TLO.Me.XTarget(i).ID() then
            xtarget = mq.TLO.Me.XTarget(i).ID()
        if mq.TLO.Spawn(xtarget).Type() ~= 'NPC' then goto continue end
            if mq.TLO.Spawn(xtarget).PctHPs() <= LowestHps and mq.TLO.Spawn(xtarget).LineOfSight() then
                LowestHps = mq.TLO.Spawn(xtarget).PctHPs()
                LowestHpsID  = xtarget
            end
        end
        ::continue::
    end
 
Last edited:
Isnt this just the same as?

if mq.TLO.Spawn(xtarget).Type() == 'NPC' and (mq.TLO.Spawn(xtarget).PctHPs() <= LowestHps and mq.TLO.Spawn(xtarget).LineOfSight()[BGCOLOR=initial]) then[/BGCOLOR]

I'm guessing not since you've been at this a long time and are probably genius level :-P
 
goto is a really bad practice, but the code you have right there doesn't need it at all. I'm assuming you simplified something for demonstration, but I would suggest changing the logic to not require goto (or continue or break, but that's a hill I'll die on and not everyone feels that way)
 
Yea, that's why I posted ... goto is terrible and it is insane to me that Lua has no continue.

I pruned down what I was doing to make it easier for an out of context example.

The idea is the same though, I'm in a loop and if a condition is met skip over to the next item.
goto continue seems to be one of the workarounds out there.

More context -- it is within my core class (C# noob doing Lua, I make everything look OOP / have interfaces lol)
I've been doing MQLua for like < 24 hours... converted about 2000 lines of my core macro engine that I've been maintaining for years.

Code:
core.TargetLowestHPMob = function()
    Write.Debug('Target Lowest HP Mob');
    local LowestHps = 100;
    local LowestHpsID = 0;
    local xtarget = 0;
    if mq.TLO.Me.XTarget() == 0 then return end
    for i = 1, mq.TLO.Me.XTarget() do
        if mq.TLO.Me.XTarget(i).ID() then
            xtarget = mq.TLO.Me.XTarget(i).ID();
        if mq.TLO.Spawn(xtarget).Type() ~= 'NPC' then goto continue end
            if mq.TLO.Spawn(xtarget).PctHPs() <= LowestHps and mq.TLO.Spawn(xtarget).LineOfSight() then
                LowestHps = mq.TLO.Spawn(xtarget).PctHPs();
                LowestHpsID  = xtarget;
            end
        end
        ::continue::
    end
    if mq.TLO.Target.ID() ~= LowestHpsID then
        mq.cmdf('/mqtarget id %s', LowestHpsID);
        mq.delay('1s');
        local newMob = mq.TLO.Spawn(LowestHpsID).CleanName();
        local newMobHP = mq.TLO.Spawn(LowestHpsID).PctHPs();
        Write.Info(string.format('Targeting %s at %s',newMob,newMobHP));
    end

end
 
Last edited:
so, you're kind of forcing the need for a continue there, just put that into the if check. continue is (IMO) an anti-pattern because it force interrupts flow control. In your case, all you have to do is this:


Lua:
function core.TargetLowestHPMob()
    Write.Debug("Target Lowest HP Mob")
    local LowestHps = 100
    local LowestHpsID = 0
    local xtarget = 0
    if mq.TLO.Me.XTarget() == 0 then return end
    for i = 1, mq.TLO.Me.XTarget() do
        if mq.TLO.Me.XTarget(i).ID() then
            xtarget = mq.TLO.Me.XTarget(i).ID()
            if mq.TLO.Spawn(xtarget).Type() == "NPC" and mq.TLO.Spawn(xtarget).PctHPs() <= LowestHps and mq.TLO.Spawn(xtarget).LineOfSight() then
                LowestHps = mq.TLO.Spawn(xtarget).PctHPs()
                LowestHpsID = xtarget
            end
        end
    end
    if mq.TLO.Target.ID() ~= LowestHpsID then
        mq.cmdf("/mqtarget id %s", LowestHpsID)
        mq.delay("1s")
        local newMob = mq.TLO.Spawn(LowestHpsID).CleanName()
        local newMobHP = mq.TLO.Spawn(LowestHpsID).PctHPs()
        Write.Info(string.format("Targeting %s at %s", newMob, newMobHP))
    end
end

EDIT: If you'll notice I also changed your function signature... it's preferable to do it this way because it give you better debug info in stack traces. The way you had it is an anonymous function which is super useful for functions you don't want to name, but in this case you are naming your function.
 
Last edited:
In general though, you can _always_ change the pattern of:
Lua:
if x then continue end
into
Lua:
if not x then
  ... -- rest of code here
end

but often you don't even need to do that.
 
Thanks dude... solid feedback.
I'll get rid of all the anonymous functions (all of them) lmao
 
Is there a way to make this better? I've seen snippets where I thought it might be possible...

Is there a way to set a local variable to the actual TLO data type, then access it's members later?

Code:
        local newMob = mq.TLO.Spawn(LowestHpsID).CleanName()
        local newMobHP = mq.TLO.Spawn(LowestHpsID).PctHPs()
        Write.Info(string.format("Targeting %s at %s", newMob, newMobHP))

something like this:
Code:
      local spawnInfo = mq.TLO.Spawn(LowestHPsID)
      Write.Info(string.format("Targeting %s at %s",spawnInfo.CleanName(), spawnInfo.PctHPs())
 
That will work, but I think what might be happening is that you evaluate LowestHPsID only when you declare spawnInfo there. So you'll always get the lowest HP spawn from whenever you declared the variable. Try something like this:

Lua:
local function spawnInfo() return mq.TLO.Spawn(LowestHPsID) end
Write.Info(string.format("Targeting %s at %s", spawnInfo().CleanName(), spawnInfo().PctHPs())

I have made some assumptions about your intention here, so correct me if I'm off.
 
Yea, this was exactly what I was looking for, and wanted to understand how to reuse calling an MQ tlo once, but access its members many times.

Thanks
 
Lua No Continue?

Users who are viewing this thread

Back
Top
Cart