Library Tactician Help (Aug '17)


#1

I suspect this is a bug, but don’t want to jump to conclusions. Just running the premade script for the commandArcher function is giving me an error:

I mean, archer is already defined by the function itself, right? Why wouldn’t the function recognize the archer and use its findNearestEnemy?


#2

I think it meant to be nearest = archer.findNearest(archer.findEnemies()) not
nearest = archer.findNearestEnemy().


#3


#4

Can you post me your full code please.


#5

Whoops, responded to the wrong post. Gimme a minute, I’ll fetch the code.

def commandSoldier(soldier, soldierIndex, numSoldiers):
    angle = Math.PI * 2 * soldierIndex / numSoldiers
    defendPos = {"x": 41, "y": 40}
    defendPos.x += 10 * Math.cos(angle)
    defendPos.y += 10 * Math.sin(angle)
    hero.command(soldier, "defend", defendPos);

# Find the strongest target (most health)
# This function returns something! When you call the function, you will get some value back.
def findStrongestTarget():
    mostHealth = 0
    bestTarget = None
    enemies = hero.findEnemies()
    # Figure out which enemy has the most health, and set bestTarget to be that enemy.
    for e in enemies:
        if e.health > mostHealth:
            mostHealth = e.health
            bestTarget = e
    # Only focus archers' fire if there is a big ogre.
    if bestTarget and bestTarget.health > 15:
        return bestTarget
    else:
        return None


# If the strongestTarget has more than 15 health, attack that target. Otherwise, attack the nearest target.
def commandArcher(a):
    nearest = a.findNearest(a.findEnemies())
    if archerTarget:
        hero.command(a, "attack", archerTarget)
    elif nearest:
        hero.command(a, "attack", nearest)

archerTarget = None

while True:
    # If archerTarget is defeated or doesn't exist, find a new one.
    if not archerTarget or archerTarget.health <= 0:
        # Set archerTarget to be the target that is returned by findStrongestTarget()
        archerTarget = findStrongestTarget()
    
    friends = hero.findFriends()
    soldiers = hero.findByType("soldier")
    # Create a variable containing your archers.
    archers = hero.findByType("archer")
    for i in range(len(soldiers)):
        soldier = soldiers[i]
        commandSoldier(soldier, i, len(soldiers));
    # use commandArcher() to command your archers
    for a in range(len(archers)):
        archer = archers[i]
        commandArcher(archer)
    
    if archerTarget:
        hero.attack(archerTarget)
    else:
        z = hero.findNearestEnemy()
        if z:
            hero.attack(z)

#6

It’s fine.
20 characters


#7

Try changing it to if not archerTarget or archerTarget.health < 1:


#8

I don’t think you need that.


#9

Wouldn’t that have my hero attack the nearest enemy if there’s no archerTarget then? Otherwise, (s)he’d just sit idle.


#10

Your hero is not oppose to attack and also you already command the archers to attack.


#11

But if my hero has long-range capabilities, why shouldn’t I be throwing them in? Also, why should that be making the code crash in a separate part of the code?


#12

You are not meant to use your hero because that is cheating.

I don’t get what you mean.


#13

In your while True: loop:

Rename the variable a in for a in range(len(archers)): to i so it matches up with i in archer = archers[i]


If the target is out of the hero’s attack range and line of sight, then the while True: loop will be stuck on hero.attack(archerTarget) or hero.attack(z) as your hero tries to move to a position so it can attack the target. Either skip the code for your hero attacking enemies entirely or try implementing a check for enemies within your hero’s attack range and line of sight (I don’t have ranged heroes available, so I can’t check if this works).


#14

@byobcello That did the trick. Thanks.