Hmm, this commanding code is a little patchy.
The first thing I’d do is include the stage variable as an argument in the brackets of your command function.
That may sound confusing, but all you need to do is put this in the brackets of each command function. This example is from the archer command function:
def commandArcher(archer, stage).
Make sure you also put in the stage variable when you call the variable. That is to say, when you write the name of the function without the def
. When you execute the code inside the function.
Make sure you also put in the stage variable in the brackets of commandFriends(), both when you’re defining it (def) and when you’re calling it in the while True loop (no def). You need to have the updated stage variable inside the commandFriends() function, so you can put it in the brackets of the other command functions when you call them.
The overall reason for this is that you can’t always access variables outside your function, like stage. Sometimes you need to manually insert it into the function by putting it in the brackets as on of the arguments of the function. If that doesn’t work I have quite a few other things you could fix. But try that first.
Danny
@Deadpool198 I have tried that out but there is also this error:
Here is my code in response to what you said:
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", Vector(0, 38))
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(target):
if target:
if hero.isReady("slam"):
hero.slam(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
elif hero.isReady("flash") and hero.distanceTo(target) > 5:
hero.flash()
else:
hero.attack(target)
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:
specAttack(target)
while tower.health >= 0:
specAttack(tower)
if len(towers) == 0:
stage = 3
def commandPaladin(paladin, stage):
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, stage):
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, stage):
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(stage):
stage = 2
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
stage = 1
while True:
attack(target)
catapult = hero.findNearest(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)
stage = 2
elif stage == 2:
commandFriends(stage)
if tower:
target = tower
attack(target)
elif stage == 3:
warlock = target
if target:
attack(target)
When I run that code I don’t get an error. This is the first time I’ve actually tried your code and Illia is ruthless!
Really well done with putting in stage, you did it perfectly. It still needs changing though.
You need to make a fundamental change you your stage system. At the moment it’s spread out and you’re changing the stage number at different points. That’s not good. We want to update stage in one place and one place only: the while true loop. This code:
Is largely unnecessary. You’re already calling the variable attack() and the nearest enemy will be the right one anyway. You could also summonPaladin() whenever you want. You always want them, not just in stage 1.
Instead of updating the stage variable at different points, use hero.time. If you run the code you’ll know what will happen and at what time, so use something like:
if hero.time > x and hero.time < y:
stage = 2
elif hero.time > y and hero.time < z:
stage = 3
Then, if the stage is either 2, 3 or greater, call the commandFriends(stage) function.
Then get rid of the bits where you define stage in the attack(function). Do you see why that makes more sense?
You need to remove stage = 2, because it means the stage will also be 2 in that function. Because you’ve got stage in the parameters you don’t need it again.
You also need to define friends inside that function, because you haven’t defined it since the very start.
Firstly you’ve used paladin in the archer function, and secondly you need to make your troops move to the right to join you in the fight on the right side of the map. So maybe include and else: in that function and the soldier function telling your troops to move to the right.
Make sure you do all of those things, then it should work better. But it won’t work completely yet I don’t think.
Danny
Thanks so much @Deadpool198!
At one point before I added the hero.time bit, all of my troops except my paladins responded but they stopped when I added it which is a problem because without my troops, I won’t be able to defeat the warlocks.
Overall, I did make it to the Inner Sanctum. I just need to be able to command my troops. Here is my updated code:
# 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")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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(target):
if target:
if hero.isReady("slam"):
hero.slam(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
catapults = hero.findByType("catapult")
for catapult in catapults:
if catapult:
while catapult.health > 0:
hero.attack(catapult)
towers = hero.findByType("tower")
for tower in towers:
if tower:
specAttack(target)
while tower.health >= 0:
specAttack(tower)
def commandPaladin(paladin, stage):
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, stage):
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, stage):
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(archer, "attack", target)
elif stage == 4:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
while True:
attack(target)
catapult = hero.findNearest(hero.findByType("catapult"))
tower = hero.findNearest(hero.findByType("tower"))
warlock = hero.findNearest(hero.findByType("warlock"))
target = hero.findNearest(hero.findEnemies())
x = 11
y = 13
z = 56
if stage == 1:
summonPaladin()
if target:
attack(target)
elif hero.time > x and hero.time < y:
stage = 2
elif stage == 2:
summonPaladin()
commandFriends(stage)
if tower:
target = tower
attack(target)
elif hero.time > y and hero.time < z:
stage = 3
elif stage >= 2:
summonPaladin()
commandFriends(stage)
warlock = target
if target:
attack(target)
Right I am back now but my troops aren’t responding to my commands. What is wrong:
# 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")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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(target):
if target:
if hero.isReady("slam"):
hero.slam(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
catapults = hero.findByType("catapult")
for catapult in catapults:
if catapult:
while catapult.health > 0:
hero.attack(catapult)
towers = hero.findByType("tower")
for tower in towers:
if tower:
specAttack(target)
while tower.health >= 0:
specAttack(tower)
def commandPaladin(paladin, stage):
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, stage):
target = hero.findNearestEnemy()
if warlock:
target = warlock
if stage == 2:
hero.command(soldier, "move", Vector(92, 34))
elif stage == 3:
if warlock:
target = warlock
if target:
hero.command(soldier, "attack", target)
elif stage == 4:
hero.command(soldier, "attack", target)
def commandArcher(archer, stage):
target = hero.findNearestEnemy()
if warlock:
target = warlock
if stage == 2:
hero.command(archer, "move", Vector(92, 34))
elif stage == 3:
if warlock:
target = warlock
if target:
hero.command(archer, "attack", target)
elif stage == 4:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
while True:
attack(target)
catapult = hero.findNearest(hero.findByType("catapult"))
tower = hero.findNearest(hero.findByType("tower"))
warlock = hero.findNearest(hero.findByType("warlock"))
target = hero.findNearest(hero.findEnemies())
w = 61
x = 11
y = 13
z = 56
if stage == 1:
summonPaladin()
if target:
attack(target)
elif hero.time > x and hero.time < y:
stage = 2
elif stage == 2:
summonPaladin()
commandFriends(stage)
if tower:
target = tower
attack(target)
elif hero.time > y and hero.time < z:
stage = 3
elif stage >= 2:
summonPaladin()
commandFriends(stage)
warlock = target
if target:
attack(target)
You have taken this quite literally
Do you think I meant to actually use x and y? No, they’re just examples because I don’t want to give you actual times that you could use. You have to work it out yourself.
That bit looks quite good though. If you replace x, y and z with real relevant times like 20 (you should no when your stages end, that is not a correct time).
After you’ve got the troops moving again you’ll need and else after this:
And include some kind of moving to the right, otherwise they just stay there because they can’t see any enemies. That goes for the soldiers as well. Put the else inside the if stage == 3.
Danny
Hello @Deadpool198.
No, obviously, but the idea of using x and y was a good one so I decided to define them.
That’s the problem that if solved, will really wrap this up; I don’t know how to get them moving again. As for the else, I already did that.
Elijah
Goodness me, that’s embarrassing! Very sorry, I didn’t read your code carefully enough. I’ll take your code and figure out what’s wrong.
Danny
That’s alright. I updated my code too:
# Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
stage = 1
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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(target):
if target:
while target.health >= 0:
if hero.isReady("slam"):
hero.slam(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
else:
commandFriends()
def commandPaladin(paladin, stage):
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()
if target:
hero.command(paladin, "attack", target)
elif stage == 3:
hero.command(soldier, "move", hero.pos)
elif stage == 4:
target = hero.findNearestEnemy()
if warlock:
target = warlock
if target:
hero.command(paladin, "attack", target)
else:
enemy = paladin.findNearestEnemy()
if enemy:
hero.command(paladin, "attack", enemy)
elif stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(paladin, "attack", target)
def commandSoldier(soldier, stage):
target = hero.findNearestEnemy()
if stage == 2:
hero.command(soldier, "move", Vector(92, 34))
elif stage == 3:
hero.command(soldier, "move", hero.pos)
elif stage == 4:
if warlock:
target = warlock
if target:
hero.command(soldier, "attack", target)
else:
enemy = soldier.findNearestEnemy()
if enemy:
hero.command(soldier, "attack", enemy)
elif stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(soldier, "attack", target)
def commandArcher(archer, stage):
target = hero.findNearestEnemy()
if stage == 2:
hero.command(archer, "move", Vector(92, 34))
elif stage == 3:
hero.command(archer, "move", hero.pos)
elif stage == 4:
if warlock:
target = warlock
if target:
hero.command(archer, "attack", target)
else:
enemy = archer.findNearestEnemy()
if enemy:
hero.command(archer, "attack", enemy)
elif stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
commandFriends()
while True:
catapult = hero.findNearest(hero.findByType("catapult"))
tower = hero.findNearest(hero.findByType("towers"))
warlock = hero.findNearest(hero.findByType("warlock"))
target = hero.findNearest(hero.findEnemies())
time = hero.time
summonPaladin()
if target:
attack(target)
elif time >= 15.6:
stage = 2
summonPaladin()
commandFriends(stage)
if tower:
target = tower
attack(target)
elif not tower:
commandFriends(stage)
hero.moveXY(171, 15)
elif time >= 60:
stage = 3
summonPaladin()
commandFriends(stage)
elif time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
The problem now is your use of elifs when defining stage. What if there’s always a target? You could use if for all of them… You will need to change your code, but the troops will respond to your commands.
@Deadpool198 so you mean to wrap every place where I am using elifs for stage in an if statement that checks for the target?
No. This section:
if target:
attack(target)
elif time >= 15.6:
stage = 2
summonPaladin()
commandFriends(stage)
if tower:
target = tower
attack(target)
elif not tower:
commandFriends(stage)
hero.moveXY(171, 15)
elif time >= 60:
stage = 3
summonPaladin()
commandFriends(stage)
elif time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
Won’t work. Why? Because there’s always a target isn’t there? There are always enemies. And what does elif mean: else if. Your code will only update the stage variable if there isn’t a target. This is not the right time to use elif. Instead you could use if for all of them, maybe even put and and elif on the target.
@Deadpool198 so I shouldn’t put the if target there but everywhere else is fine and I should do something like this:
if target:
attack(target)
if time >= 15.6:
stage = 2
summonPaladin()
commandFriends(stage)
if tower:
target = tower
attack(target)
elif not tower:
commandFriends(stage)
hero.moveXY(171, 15)
if time >= 60:
stage = 3
summonPaladin()
commandFriends(stage)
if time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
@Deadpool198 my troops are finally responding to me! Thanks so much! but after destroying both of the towers, my hero starts bumping into the wall and doesn’t stop:
Here is my code:
# Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
stage = 1
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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(target):
if target:
while target.health >= 0:
if hero.isReady("slam"):
hero.slam(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
else:
commandFriends()
def commandPaladin(paladin, stage):
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 paladin.health < 100:
hero.command(paladin, "shield")
if stage == 2:
target = paladin.findNearestEnemy()
if target:
hero.command(paladin, "attack", target)
if stage == 3:
hero.command(paladin, "attack", target)
if stage == 4:
target = paladin.findNearestEnemy()
if warlock:
target = warlock
if target:
hero.command(paladin, "attack", target)
else:
enemy = paladin.findNearestEnemy()
if enemy:
hero.command(paladin, "attack", enemy)
if stage == 5:
target = paladin.findNearestEnemy()
if target:
hero.command(paladin, "attack", target)
def commandSoldier(soldier, stage):
target = soldier.findNearestEnemy()
if target:
if stage == 2:
hero.command(soldier, "move", Vector(92, 34))
if stage == 3:
hero.command(soldier, "move", hero.pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(soldier, "attack", target)
else:
enemy = soldier.findNearestEnemy()
if enemy:
hero.command(soldier, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(soldier, "attack", target)
def commandArcher(archer, stage):
target = hero.findNearestEnemy()
if target:
if stage == 2:
hero.command(archer, "move", Vector(92, 34))
if stage == 3:
hero.command(archer, "move", hero.pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(archer, "attack", target)
else:
enemy = archer.findNearestEnemy()
if enemy:
hero.command(archer, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
commandFriends()
while True:
catapult = hero.findNearest(hero.findByType("catapult"))
towers = hero.findByType("towers")
warlock = hero.findNearest(hero.findByType("warlock"))
target = hero.findNearest(hero.findEnemies())
time = hero.time
summonPaladin()
if time >= 0:
stage = 1
if target:
attack(target)
if time >= 15.6:
stage = 2
summonPaladin()
commandFriends(stage)
for tower in towers:
if tower:
while tower.health >= 0:
attack(tower)
if not tower:
commandFriends(stage)
hero.moveXY(171, 15)
if time >= 60:
stage = 3
summonPaladin()
commandFriends(stage)
if time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
Ok my only problem now is that my paladins don’t heal me and that I don’t know how to command my troops to attack in stage 4. I will leave you @Deadpool198 with my updated code as I have to go now:
# Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
stage = 1
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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.type != "paladin":
continue
if friend.health < lowestHealth and friend.health < friend.maxHealth or hero.health < lowestHealth and hero.health < hero.maxHealth:
lowestHealth = friend.health
lowestFriend = friend
return lowestFriend
def specAttack(target):
if target:
while target.health >= 0:
if hero.isReady("slam"):
hero.slam(target)
elif hero.isReady("bash"):
hero.bash(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
else:
commandFriends()
def commandPaladin(paladin, stage):
for paladin in paladins:
if paladin.canCast("heal"):
if hero.health <= 1000:
target = hero
if target:
hero.command(paladin, "cast", "heal", target)
else:
target = lowestHealthPaladin()
if target:
hero.command(paladin, "cast", "heal", target)
if paladin.health < 100:
hero.command(paladin, "shield")
if stage == 2:
target = paladin.findNearestEnemy()
if target:
for tower in towers:
if tower:
while tower.health >= 0:
hero.command(paladin, "attack", tower)
if stage == 3:
if target:
hero.command(paladin, "attack", target)
if stage == 4:
target = paladin.findNearestEnemy()
if warlock:
target = warlock
if target:
hero.command(paladin, "attack", target)
else:
enemy = paladin.findNearestEnemy()
if enemy:
hero.command(paladin, "attack", enemy)
if stage == 5:
target = paladin.findNearestEnemy()
if target:
hero.command(paladin, "attack", target)
def commandSoldier(soldier, stage):
target = soldier.findNearestEnemy()
if target:
if stage == 2:
hero.command(soldier, "move", Vector(92, 34))
if stage == 3:
pos = {"x": hero.pos.x, "y": hero.pos.y}
hero.command(soldier, "move", pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(soldier, "attack", target)
else:
enemy = soldier.findNearestEnemy()
if enemy:
hero.command(soldier, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(soldier, "attack", target)
def commandArcher(archer, stage):
target = hero.findNearestEnemy()
if target:
if stage == 2:
hero.command(archer, "move", Vector(92, 34))
if stage == 3:
pos = {"x": hero.pos.x, "y": hero.pos.y}
hero.command(archer, "move", pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(archer, "attack", target)
else:
enemy = archer.findNearestEnemy()
if enemy:
hero.command(archer, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
commandFriends()
while True:
catapult = hero.findNearest(hero.findByType("catapult"))
towers = hero.findByType("towers")
warlock = hero.findNearest(hero.findByType("warlock"))
target = hero.findNearest(hero.findEnemies())
time = hero.time
summonPaladin()
if time >= 0:
stage = 1
if target:
attack(target)
if time >= 15.6:
stage = 2
summonPaladin()
commandFriends(stage)
for tower in towers:
if tower:
while tower.health >= 0:
attack(tower)
if not tower:
commandFriends(stage)
if time >= 60:
stage = 3
summonPaladin()
commandFriends(stage)
hero.moveXY(148, 34)
hero.moveXY(169, 34)
hero.moveXY(183, 15)
if time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
Hi Falcon!
I’m a big fan of Jenny’s ( jka2706) help posts and her advice is worth trying:
I’ve seen this method from her and other people in the Leader Boards in different levels and it’s an easy way to simplify seemingly very difficult problems. You have the first 2 stages done, break them in 2 while loops and forget about them. Then finish the next stage in the next loop and so on…
Hello @xython. Do you and @jka2706 mean something like this?
# Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
paladins = hero.findByType("paladin")
soldiers = hero.findByType("soldier")
archers = hero.findByType("archer")
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
stage = 1
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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.type != "paladin":
continue
if friend.health < lowestHealth and friend.health < friend.maxHealth or hero.health < lowestHealth and hero.health < hero.maxHealth:
lowestHealth = friend.health
lowestFriend = friend
return lowestFriend
def specAttack(target):
if target:
while target.health >= 0:
if hero.isReady("slam"):
hero.slam(target)
elif hero.isReady("bash"):
hero.bash(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
else:
commandFriends()
def commandPaladin(paladin, stage):
for paladin in paladins:
if paladin.canCast("heal"):
if hero.health <= 1000:
target = hero
if target:
hero.command(paladin, "cast", "heal", target)
else:
target = lowestHealthPaladin()
if target:
hero.command(paladin, "cast", "heal", target)
if paladin.health < 100:
hero.command(paladin, "shield")
if stage == 2:
target = paladin.findNearestEnemy()
if target:
for tower in towers:
if tower:
while tower.health >= 0:
hero.command(paladin, "attack", tower)
if stage == 3:
if target:
hero.command(paladin, "attack", target)
if stage == 4:
target = paladin.findNearestEnemy()
if warlock:
target = warlock
if target:
hero.command(paladin, "attack", target)
else:
enemy = paladin.findNearestEnemy()
if enemy:
hero.command(paladin, "attack", enemy)
if stage == 5:
target = paladin.findNearestEnemy()
if target:
hero.command(paladin, "attack", target)
def commandSoldier(soldier, stage):
target = soldier.findNearestEnemy()
if target:
if stage == 2:
hero.command(soldier, "move", Vector(92, 34))
if stage == 3:
pos = {"x": hero.pos.x, "y": hero.pos.y}
hero.command(soldier, "move", pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(soldier, "attack", target)
else:
enemy = soldier.findNearestEnemy()
if enemy:
hero.command(soldier, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(soldier, "attack", target)
def commandArcher(archer, stage):
target = hero.findNearestEnemy()
if target:
if stage == 2:
hero.command(archer, "move", Vector(92, 34))
if stage == 3:
hero.command(archer, "move", Vector(173, 14))
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(archer, "attack", target)
else:
enemy = archer.findNearestEnemy()
if enemy:
hero.command(archer, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
commandFriends()
while True:
catapult = hero.findNearest(hero.findByType("catapult"))
target = hero.findNearest(hero.findEnemies())
time = hero.time
summonPaladin()
if time >= 0:
stage = 1
if target:
attack(target)
else:
break
while True:
target = hero.findNearest(hero.findEnemies())
time = hero.time
towers = hero.findByType("towers")
if time >= 15.6:
stage = 2
summonPaladin()
commandFriends(stage)
for tower in towers:
if tower:
while tower.health >= 0:
attack(tower)
if not tower:
commandFriends(stage)
else:
break
while True:
target = hero.findNearest(hero.findEnemies())
time = hero.time
if time >= 60:
stage = 3
summonPaladin()
hero.moveXY(148, 34)
hero.moveXY(169, 34)
hero.moveXY(183, 15)
commandFriends(stage)
else:
break
while True:
target = hero.findNearest(hero.findEnemies())
time = hero.time
warlock = hero.findNearest(hero.findByType("warlock"))
if time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
else:
break
while True:
target = hero.findNearest(hero.findEnemies())
time = hero.time
if time >= 120:
stage = 5
if target:
commandFriends(stage)
attack(target)
My hero just keeps on bumping into the wall:
@Deadpool198 I have decided to skip the second stage in terms of my troops so to minimise the risk of them dying when I call them to just outside the Outer Gate. However, Illia just bumps into the wall:
I am trying to get Illia to move below that, call her troops towards herself and consecrate
. Can you help me accomplish this please @Deadpool198? The help would be really appreciated:
# Fight your way into the Inner Sanctum of the ogre chieftain, and defeat her.
enemyMissile = hero.findNearest(hero.findEnemyMissiles())
stage = 1
friends = hero.findFriends()
for friend in friends:
hero.command(friend, "move", Vector(0, 38))
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.type != "paladin":
continue
if friend.health < lowestHealth and friend.health < friend.maxHealth:
lowestHealth = friend.health
lowestFriend = friend
return lowestFriend
def specAttack(target):
if target:
while target.health >= 0:
if hero.isReady("slam"):
hero.slam(target)
elif hero.isReady("bash"):
hero.bash(target)
elif enemyMissile and hero.distanceTo(enemyMissile) < 5:
dir = Vector.subtract(enemyMissile.pos,hero.pos)
hero.reflect(dir)
else:
hero.attack(target)
def attack(target):
if target:
specAttack(target)
else:
commandFriends()
def commandPaladin(paladin, stage):
target = paladin.findNearestEnemy()
if target:
if paladin.canCast("heal"):
if hero.health <= 1000:
target = hero
if target:
hero.command(paladin, "cast", "heal", target)
else:
target = lowestHealthPaladin()
if target:
hero.command(paladin, "cast", "heal", target)
if paladin.health < 100:
hero.command(paladin, "shield")
if stage == 3:
pos = {"x": hero.pos.x, "y": hero.pos.y}
hero.command(paladin, "move", pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(paladin, "attack", target)
else:
enemy = paladin.findNearestEnemy()
if enemy:
hero.command(paladin, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(paladin, "attack", target)
def commandSoldier(soldier, stage):
target = soldier.findNearestEnemy()
if target:
if stage == 3:
pos = {"x": hero.pos.x, "y": hero.pos.y}
hero.command(soldier, "move", pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(soldier, "attack", target)
else:
enemy = soldier.findNearestEnemy()
if enemy:
hero.command(soldier, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(soldier, "attack", target)
def commandArcher(archer, stage):
target = hero.findNearestEnemy()
if target:
if stage == 3:
pos = {"x": hero.pos.x, "y": hero.pos.y}
hero.command(archer, "move", pos)
if stage == 4:
if warlock:
target = warlock
if target:
hero.command(archer, "attack", target)
else:
enemy = archer.findNearestEnemy()
if enemy:
hero.command(archer, "attack", enemy)
if stage == 5:
target = hero.findNearestEnemy()
if target:
hero.command(archer, "attack", target)
def commandFriends(stage):
friends = hero.findFriends()
for friend in friends:
if friend.type == "paladin":
commandPaladin(friend, stage)
if friend.type == "soldier":
commandSoldier(friend, stage)
if friend.type == "archer":
commandArcher(friend, stage)
while True:
catapult = hero.findNearest(hero.findByType("catapult"))
target = hero.findNearest(hero.findEnemies())
time = hero.time
summonPaladin()
if time >= 0:
stage = 1
if target:
attack(target)
tower = hero.findNearest(hero.findByType("towers"))
if time >= 15.6:
stage = 2
summonPaladin()
if tower:
attack(tower)
if not tower:
continue
if time >= 54:
stage = 3
summonPaladin()
commandFriends(stage)
hero.moveXY(183, 15)
hero.wait(3)
hero.consecrate()
hero.wait(1)
warlock = hero.findNearest(hero.findByType("warlock"))
if time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
if time >= 120:
stage = 5
if target:
commandFriends(stage)
attack(target)
Ok. I’ve made only four changes and it gives full success, so listen carefully to what I’m going to say:
Why do you think Illia was running into the wall? What was she doing? Well, I can tell you this line was highlighted (that means it’s currently running):
hero.attack(target)
From the specAttack(target) function. How could you avoid this? Maybe use hero.distanceTo(target). To not interfere with any other part of the level check the distance is less than 100 or another big number that will only apply to that section of the level.
Now onto this section:
if time >= 0:
stage = 1
if target:
attack(target)
tower = hero.findNearest(hero.findByType("towers"))
if time >= 15.6:
stage = 2
summonPaladin()
if tower:
attack(tower)
if not tower:
continue
if time >= 54:
stage = 3
summonPaladin()
commandFriends(stage)
hero.moveXY(183, 15)
hero.wait(3)
hero.consecrate()
hero.wait(1)
warlock = hero.findNearest(hero.findByType("warlock"))
if time >= 80:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
if time >= 120:
stage = 5
if target:
commandFriends(stage)
attack(target)
What’s to stop all these conditions being true at the same time. What if the time is 130? Check all your if statements… Won’t they all be true? The time will still be >= 0, >= 15.6, >= 54, >= 80 and >= 120. So it will end up doing something weird. How would you fix this? No elifs are required, just maybe a < symbol…
I’ll leave you to figure that out.
N.B. I don’t have the consecrate ring so I removed that part, but I think your code will still work with it.
Danny
Using the hint you gave me @Deadpool198, I used compound inequalities to create a range of seconds from which the stages can run in. However, it brought up an infinite loop but I don’t understand why it is there. Here is just the while true section:
if time >= 0 and time <= 54:
stage = 1
if target:
attack(target)
tower = hero.findNearest(hero.findByType("towers"))
if time >= 15.6 and time <= 54:
stage = 2
summonPaladin()
if tower:
attack(tower)
if not tower:
continue
if time >= 54 and time <= 100:
stage = 3
summonPaladin()
commandFriends(stage)
hero.moveXY(183, 15)
hero.wait(3)
hero.consecrate()
hero.wait(1)
warlock = hero.findNearest(hero.findByType("warlock"))
if time >= 100 and time <= 140:
stage = 4
if warlock:
target = warlock
if target:
commandFriends(stage)
attack(target)
if time >= 140 and time <= 190:
stage = 5
if target:
commandFriends(stage)
attack(target)
I have to go now but I’ll be back tomorrow.