[SOLVED] Summit's Gate Level Help

Hello. Before I finish the rest of my code, how do you get paladins to heal others?

You can find the nearest paladin:
pal = hero.findNearest(hero.findByType(ā€œpaladinā€))
Then it’s just the same as usual:
hero.command(paladin, ā€œcastā€, ā€œhealā€, pal)
The paladins can also heal themselves.
Danny

3 Likes

Thanks. Now my main problem is that I defeat the first bunch of enemies except the two larger ogres and the catapults. Illia just keeps on reflecting for some reason. Here is my code:

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def attack():
    enemy = hero.findNearestEnemy()
    if enemy:
        if hero.isReady("slam"):
            hero.slam(enemy)
        elif hero.isReady("reflect"):
            enemyMissiles = hero.findEnemyMissiles()
            for missile in enemyMissiles:
                if missile:
                    dir = Vector.subtract(missile.pos,hero.pos)
                    hero.reflect(dir)
        elif hero.canCast("chain-lightning"):
            hero.cast("chain-lightning", enemy)
        elif hero.isReady("flash"):
            if hero.distanceTo(enemy) < 10:
                hero.flash()
        else:
            hero.attack(enemy)
    catapult = hero.findNearest(hero.findByType('catapult'))
    if catapult:
        if hero.isReady("slam"):
            hero.slam(enemy)
        elif hero.isReady("reflect"):
            enemyMissiles = hero.findEnemyMissiles()
            for missile in enemyMissiles:
                if missile:
                    dir = Vector.subtract(missile.pos,hero.pos)
                    hero.reflect(dir)
        elif hero.canCast("chain-lightning"):
            hero.cast("chain-lightning", enemy)
        elif hero.isReady("flash"):
            if hero.distanceTo(enemy) < 10:
                hero.flash()
        else:
            hero.attack(enemy)

def command():
    for friend in friends:
        enemy = hero.findNearestEnemy()
        if enemy:
            hero.command(friend, "attack", enemy)

attack()

Why does that happen?

Because reflect has no cooldown (that I know of) then condition not be true? Only if you’re ready to slam, but after that it will get stuck.
Danny

1 Like

Thank you. I have updated my code so that it now attacks the catapults. However, it only attacks them once:

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def attack():
    enemy = hero.findNearestEnemy()
    if enemy:
        if hero.isReady("slam"):
            hero.slam(enemy)
        elif hero.isReady("reflect"):
            enemyMissiles = hero.findEnemyMissiles()
            for missile in enemyMissiles:
                if missile:
                    dir = Vector.subtract(missile.pos,hero.pos)
                    hero.reflect(dir)
        elif hero.canCast("chain-lightning"):
            hero.cast("chain-lightning", enemy)
        elif hero.isReady("flash"):
            if hero.distanceTo(enemy) < 10:
                hero.flash()
        else:
            hero.attack(enemy)
    catapults = hero.findByType('catapult')
    for catapult in catapults:
        if catapult:
            hero.attack(catapult)
        elif catapult.health <= 0:
            hero.moveXY(96, 34)

def command():
    for friend in friends:
        enemy = hero.findNearestEnemy()
        if enemy:
            hero.command(friend, "attack", enemy)

enemy = hero.findNearestEnemy()
attack()

You haven’t actually checked this bit. I would recommend checking for a missile that’s within a certain distance then reflecting. A for loop might not be that good if reflect has a range (I don’t actually know).

A for loop will only attack the enemy once and because you aren’t looping your function attack() it will only do it once. You should put attack() in a while true loop like in previous levels.
Danny

1 Like

@Deadpool198, I do not understand.

Now, I have destroyed the catapult and am on to the beam tower part but Illia just stands there and does nothing. Here is my current code;

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def attack():
    enemy = hero.findNearestEnemy()
    if enemy:
        if hero.isReady("slam"):
            hero.slam(enemy)
        elif hero.isReady("reflect"):
            enemyMissiles = hero.findEnemyMissiles()
            for missile in enemyMissiles:
                if missile and hero.distanceTo(missile) < 5:
                    dir = Vector.subtract(missile.pos,hero.pos)
                    hero.reflect(dir)
        elif hero.canCast("chain-lightning"):
            hero.cast("chain-lightning", enemy)
        elif hero.isReady("flash"):
            if hero.distanceTo(enemy) < 10:
                hero.flash()
                hero.attack(enemy)
        else:
            hero.attack(enemy)
    catapults = hero.findByType("catapult")
    for catapult in catapults:
        if catapult:
            hero.attack(catapult)
        elif catapult.health <= 0:
            hero.moveXY(96, 34)

def command():
    for friend in friends:
        enemy = hero.findNearestEnemy()
        if enemy:
            hero.command(friend, "attack", enemy)

while True:
    attack()

ahem. Please read my previous two posts. I’m not 100% sure it will fix it, but I’m close, and you should give it a try.

Ok so I have got as far as the beam towers, but I want my troops to move to just outside the outer gate. Here is my code:

stage = 1
paladins = hero.findByType("paladin")

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def summonPaladin():
    if hero.gold >= hero.costOf("paladin"):
        hero.summon("paladin")

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def attack():
    enemy = hero.findNearestEnemy()
    if enemy:
        if hero.isReady("slam"):
            hero.slam(enemy)
        elif hero.isReady("reflect"):
            enemyMissiles = hero.findEnemyMissiles()
            for missile in enemyMissiles:
                if missile and hero.distanceTo(missile) < 5:
                    dir = Vector.subtract(missile.pos,hero.pos)
                    hero.reflect(dir)
        else:
            hero.attack(enemy)
        catapults = hero.findByType("catapult")
        for catapult in catapults:
            if catapult:
                while catapult.health > 0:
                    hero.attack(catapult)
                if len(catapults) == 0:
                    for friend in friends:
                        hero.command(friend, "move", Vector(86, 34))
        towers = hero.findByType("tower")
        for tower in towers:
            if tower:
                while tower.health > 0:
                    hero.attack(tower)
                if len(towers) == 0:
                    for friend in friends:
                        hero.command(friend, "move", Vector(146, 34))

           
def commandPaladin():
    for paladin in paladins:
        if paladin.canCast("heal"):
            if hero.health < hero.maxHealth * 0.8:
                target = hero
            else:
                target = lowestHealthPaladin()
            if target:
                hero.command(paladin, "cast", "heal", target)
        if tower:
            target = tower
        if target:
            hero.command(paladin, "attack", target)
        else:
            if (paladin.health < 100):
                hero.command(paladin, "shield")

def commandSoldier():
    for soldier in soldiers:
        target = hero.findNearestEnemy()
        if warlock:
            hero.command(soldier, "attack", warlock)


while True:
    catapult = hero.findNearest(hero.findByType('catapult'))
    tower = hero.findNearest(hero.findByType('tower'))
    warlock = hero.findNearest(hero.findByType('warlock'))
    attack()
    commandPaladins()    

How do I do this?

Ok, I appreciate you’ve tried to fix this but it hasn’t worked. When you’re code runs all it will do is reflect because reflect has no cooldown. Do you see that? The else statement will never run because your hero is always ready to reflect. You have to check for the missile and the distance on this line. I’ll look at the rest after you’ve changed that.

Oh. You mean to remove this line? I am so sorry. I did not understand what you were going on about.

Like this?

if enemy:
    if hero.isReady("slam"):
        hero.slam(enemy)
    enemyMissile = hero.findNearest(hero.findEnemyMissiles())
    if enemyMissile and hero.distanceTo(enemyMissile) < 5:
        dir = Vector.subtract(enemyMissile.pos,hero.pos)
        hero.reflect(dir)
    else:
        hero.attack(enemy)

@Deadpool198, when I do it like this:

elif hero.isReady("reflect"):
            enemyMissiles = hero.findEnemyMissiles()
            for missile in enemyMissiles:
                if missile and hero.distanceTo(missile) < 5:
                    dir = Vector.subtract(missile.pos,hero.pos)
                    hero.reflect(dir)

Illia just stops after slamming all of the first wave. I have to do it like this to get past the Outer Gate. Maybe I am doing it wrong. Please could you help?

Also, here is my updated code:

stage = 1
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def summonPaladin():
    if hero.gold >= hero.costOf("paladin"):
        hero.summon("paladin")

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def specAttack(enemy):
    if hero.isReady("slam"):
        hero.slam(enemy)
    elif hero.isReady("reflect"):
        enemyMissiles = hero.findEnemyMissiles()
        for missile in enemyMissiles:
            if missile and hero.distanceTo(missile) < 5:
                dir = Vector.subtract(missile.pos,hero.pos)
                hero.reflect(dir)
    else:
        hero.attack(enemy)

def attack():
    enemy = hero.findNearestEnemy()
    if enemy:
        specAttack(enemy)
        catapults = hero.findByType("catapult")
        for catapult in catapults:
            if catapult:
                stage = 1
                while catapult.health > 0:
                    hero.attack(catapult)
                
        towers = hero.findByType("tower")
        for tower in towers:
            if tower:
                stage = 2
                while tower.health > 0:
                    hero.attack(tower)
                if len(towers) == 0:
                    stage = 3


def commandPaladin():
    for paladin in paladins:
        if paladin.canCast("heal"):
            if hero.health < hero.maxHealth * 0.8:
                target = hero
            else:
                target = lowestHealthPaladin()
            if target:
                hero.command(paladin, "cast", "heal", target)
        if tower:
            target = tower
        if len(catapults) == 0 and stage == 2:
            if target:
                hero.command(paladin, "attack", target)
        if len(towers) == 0 and stage == 3:
            hero.command(paladin, "move", Vector(146, 34))
        else:
            if paladin.health < 100:
                hero.command(paladin, "shield")

def commandSoldier():
    for soldier in soldiers:
        target = hero.findNearestEnemy()
        if warlock:
            hero.command(soldier, "attack", warlock)
        if stage == 2:
            hero.command(soldier, "move", Vector(86, 34))
        if stage == 3:
            hero.command(soldier, "move", Vector(146, 34))

def commandArcher():
    for archer in archers:
        target = hero.findNearestEnemy()
        if warlock:
            hero.command(archer, "attack", warlock)
        if stage == 2:
            hero.command(archer, "move", Vector(86, 34))
        if stage == 3:
            hero.command(archer, "move", Vector(146, 34))

while True:
    catapult = hero.findNearest(hero.findByType('catapult'))
    tower = hero.findNearest(hero.findByType('tower'))
    warlock = hero.findNearest(hero.findByType('warlock'))
    if stage == 1:
        attack()
    if stage == 2:
        attack()
        summonPaladin()
        commandPaladin()
        commandSoldier()
        commandArcher()
    if stage == 3:
        for friend in friends:
            if friend.type == "soldier":
                hero.command(friend, "attack", warlock)
            if friend.type == "archer":
                hero.command(friend, "attack", warlock)
            if friend.type == "paladin":
                commandPaladin()

My troops do not move when I command them. Help would be appreciated.

1 Like

Yes! That’s right, you’re next code is wrong. The only thing you absolutely need to avoid is having hero.isReady(ā€œreflectā€) as the only parameter in an if/elif statement, because it means that if statement will always run. ALWAYS. Nothing else will be run (unless it’s an elif statement and there’s an if above it, but in that case nothing below that elif will run).
Do you understand that now?

1 Like

Yes @Deadpool198 I understand now! Thank you for the clarification and I am sorry for the trouble. It works now. My only problem is with my troops not moving to where I command them:

# Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
stage = 1
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def summonPaladin():
    if hero.gold >= hero.costOf("paladin"):
        hero.summon("paladin")

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def specAttack(enemy):
    if hero.isReady("slam"):
        hero.slam(enemy)
    elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
        dir = Vector.subtract(enemyMissile.pos,hero.pos)
        hero.reflect(dir)
    else:
        hero.attack(enemy)

def attack():
    enemy = hero.findNearestEnemy()
    if enemy:
        specAttack(enemy)
        catapults = hero.findByType("catapult")
        for catapult in catapults:
            if catapult:
                while catapult.health > 0:
                    hero.attack(catapult)
                    if len(catapults) == 0:
                        stage = 2
        towers = hero.findByType("tower")
        for tower in towers:
            if tower:
                while tower.health >= 0:
                    hero.attack(tower)
                    if len(towers) == 0:
                        stage = 3


def commandPaladin():
    for paladin in paladins:
        if paladin.canCast("heal"):
            if hero.health < hero.maxHealth * 0.8:
                target = hero
            else:
                target = lowestHealthPaladin()
            if target:
                hero.command(paladin, "cast", "heal", target)
        elif stage < 4:
            hero.command(paladin, "move", {"x": 86, "y": 34})
            if tower:
                target = tower
            if target:
                hero.command(paladin, "attack", target)
            towers = hero.findByType("tower")
            if len(towers) == 0:
                hero.command(paladin, "move", {"x": 146, "y": 34})
        elif paladin.health < 100:
            hero.command(paladin, "shield")

def commandSoldier():
    for soldier in soldiers:
        target = hero.findNearestEnemy()
        if warlock:
            hero.command(soldier, "attack", warlock)
        if stage == 2:
            hero.command(soldier, "move", {"x": 86, "y": 34})
        if stage == 3:
            hero.command(soldier, "move", {"x": 146, "y": 34})

def commandArcher():
    for archer in archers:
        target = hero.findNearestEnemy()
        if warlock:
            hero.command(archer, "attack", warlock)
        if stage == 2:
            hero.command(archer, "move", {"x": 86, "y": 34})
        if stage == 3:
            hero.command(archer, "move", {"x": 146, "y": 34})

while True:
    catapult = hero.findNearest(hero.findByType('catapult'))
    tower = hero.findNearest(hero.findByType('tower'))
    warlock = hero.findNearest(hero.findByType('warlock'))
    if stage == 1:
        attack()
    if stage == 2:
        summonPaladin()
        commandPaladin()
        commandSoldier()
        commandArcher()
    if stage == 3:
        for friend in friends:
            hero.command(friend, "move", hero)
            if friend.type == "soldier":
                hero.command(friend, "attack", warlock)
            if friend.type == "archer":
                hero.command(friend, "attack", warlock)
            if friend.type == "paladin":
                commandPaladin()

Hang on a minute … this throws up an error:

Elif needs to be directly below and if statement with nothing inbetween. Just define enemy Missile above the if hero.isReady(ā€˜slam’).
Danny

1 Like

Thank you it works now but my troops aren’t responding to my commands. Why is this? I think it might be something to do with the different stages:

stage = 1
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())

friends = hero.findFriends()
for friend in friends:
    hero.command(friend, "move", {"x": 0, "y": 39})

def summonPaladin():
    if hero.gold >= hero.costOf("paladin"):
        hero.summon("paladin")

def lowestHealthPaladin():
    lowestHealth = 99999
    lowestFriend = None
    friends = hero.findFriends()
    for friend in friends:
        if friend.health < lowestHealth and friend.health < friend.maxHealth:
            lowestHealth = friend.health
            lowestFriend = friend
    return lowestFriend

def specAttack(enemy):
    if hero.isReady("slam"):
        hero.slam(enemy)
    elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
        dir = Vector.subtract(enemyMissile.pos,hero.pos)
        hero.reflect(dir)
    else:
        hero.attack(enemy)

def attack(target):
    if target:
        specAttack(target)
        #     catapults = hero.findByType("catapult")
        #     for catapult in catapults:
        #         if catapult:
        #             while catapult.health > 0:
        #                 hero.attack(catapult)
        #                 if len(catapults) == 0:
        #                     stage = 2
        #     towers = hero.findByType("tower")
        #     for tower in towers:
        #         if tower:
        #             while tower.health >= 0:
        #                 hero.attack(tower)
        #                 if len(towers) == 0:
        #                     stage = 3


def commandPaladin():
    summonPaladin()
    for paladin in paladins:
        if paladin.canCast("heal"):
            if hero.health < hero.maxHealth * 0.8:
                target = hero
            else:
                target = lowestHealthPaladin()
            if target:
                hero.command(paladin, "cast", "heal", target)
        elif paladin.health < 100:
            hero.command(paladin, "shield")
        elif stage == 2:
            target = paladin.findNearestEnemy()
            hero.command(paladin, "attack", target)
        elif stage == 3:
            hero.command(paladin, "move", {'x': 162, 'y': 34})
        else:
            target = hero.findNearestEnemy()
            if warlock:
                target = warlock
            if target:
                hero.command(paladin, "attack", target)
            else:
                enemy = paladin.findNearestEnemy()
                hero.command(paladin, "attack", enemy)
        

def commandSoldier(soldier):
    target = hero.findNearestEnemy()
    if warlock:
        target = warlock
    if stage == 2:
        hero.command(soldier, "move", {'x': 84, 'y': 34})
    elif stage == 3:
        if warlock:
            target = warlock
        if target:
            hero.command(soldier, "attack", target)
    elif stage == 4:
        hero.command(soldier)


def commandArcher(archer):
    target = hero.findNearestEnemy()
    if warlock:
        target = warlock
    if stage == 2:
        hero.command(archer, "move", {'x': 84, 'y': 34})
    elif stage == 3:
        if warlock:
            target = warlock
        if target:
            hero.command(paladin, "attack", target)
    elif stage == 4:
        hero.command(archer, "attack", target)


def commandFriends():
    for friend in friends:
        if friend.type == "paladin":
            commandPaladin(friend)
        if friend.type == "soldier":
            commandSoldier(friend)
        if friend.type == "archer":
            commandArcher(friend)

stage = 1
while True:
    attack(target)
    catapults = hero.findByType("catapult")
    tower = hero.findNearest(hero.findByType("tower"))
    warlock = hero.findNearest(hero.findByType("warlock"))
    target = hero.findNearest(hero.findEnemies())
    if stage == 1:
        summonPaladin()
        if target:
            attack(target)
        elif len(hero.findEnemies) == 0:
            for catapult in catapults:
                attack(catapult)
                if len(catapults) == 0:
                    stage = 2
    elif stage == 2:
        if tower:
            attack(tower)
    elif stage == 3:
        warlock = target
        if target:
            attack(target)
    commandFriends()

I made it to the Inner Sanctum @Deadpool198 ! But my troops still aren’t responding. Can you help please?