Summits Gate, Functions, and Lazy Troops (Help?)

My code does not work. Its purpose is to iterate over my commandable allies and command them to do whatever it is they’re supposed to do. However, whenever it is called, it only commands one ally to do its job before appearing to end the for loop. Now, when called individually (outside the concentrateFire function), each of the sub functions work perfectly. The issue is somehow here in this code, and I can’t figure out why it won’t work. Can anyone help?

function concentrateFire(fType)
    local associates = self:findFriends()
    for i=1, #associates do
        local friend = associates[i]
        if friend.type == "soldier" and friend.team == "humans" then
            killType(fType)
        elseif friend.type == "archer" and friend.team == "humans" then
            killType(fType)
        elseif friend.type == "paladin" and friend.team == "humans" then
            paladinFollow()
        end
    end
end

it should be noted i’m using lua

the sub functions are as follows:

function killType(eType)
    local fFriend = friend
    if eType then
        local enemy = fFriend:findNearest(fFriend:findByType(eType, enemies))
        if enemy then  
            self:command(fFriend, "attack", enemy)
        end
    else
        local enemy = fFriend:findNearestEnemy()
        if enemy then
            self:command(fFriend, "attack", enemy)
        end
    end
end
function lowestHealthPaladin()
    local lowestHealth = 99999
    local lowestPaladin = nil
    local paladins = self:findByType("paladin", friends)
    for i=1, #paladins do
        local paladin = paladins[i]
        if paladin.health < lowestHealth and paladin.health < paladin.maxHealth then
            lowestHealth = paladin.health
            lowestPaladin = paladin
        end
    end
    return paladin
end

function paladinHeal()
    if friend.type == "paladin" then
        if friend:canCast("heal") and self.health < self.maxHealth then
            self:command(friend, "cast", "heal", self)
        elseif friend:canCast("heal") and self.health == self.maxHealth then
            local healMe = lowestHealthPaladin()
            self:command(friend, "cast", "heal", healMe)
        else
            self:command(friend, "shield")
        end
    end
end

function paladinFollow()
    if self:distanceTo(friend) >= 30 then
        self:command(friend, "move", {x=self.pos.x - 20, y=self.pos.y})
    else
        paladinHeal()
    end
end
for i,#associates do
        local friend = associates[i]

I find it interesting that the syntax highlighting in the forum is treating #associates (which is the length of the associates array) as a comment. I imagine the game parser doesn’t make the same mistake, but it’s odd. An alternate way to do that loop in standard Lua is:

for i,friend in ipairs(associates) do

However, I don’t have enough Lua experience here on Code Academy to tell you if that will work…

Thanks for the input! Unfortunately it didn’t solve my problem, which makes me think it must have something to do with the way Lua on here handles for loops inside of functions called in the program. When I added that function and cut my code size down is when my problems started. I’m gonna try moving my for loops outside my functions. if then statements don’t seem to cause issues inside functions, just for loops.

Edit: for the record, that’s the most progress i’ve made all week. Thanks!

1 Like

As an update, I switched to JavaScript and finally managed to beat it. Thank you for your help! For those who arrive here by searching, I had to redesign my code heavily in structure to make it work. It should be noted that for loops absolutely won’t work inside of functions on a level this big (and memory intensive) for the purpose of commanding troops. If you use a function to command your troops, put all of the logic inside the function, then make a for loop with a call to the function inside it. Don’t put the for loop inside the function!