[Solved] Can't target new summon as a variable - why?

This issue has been driving me crazy for several levels, because I want to do the following:

  1. Summon a unit
  2. Add new unit to an existing array at the end of the array
  3. Provide instruction to array of units, based upon their (permanent) position in the array

At first, I thought I was messing up the array or somehow not using .push properly, but that definitely isn’t it. I managed to isolate at least part of the issue

var soldiers = [];

var friend = hero.summon("soldier");
hero.command(friend, "move", {x: friend.pos.x + 10, y: friend.pos.y +10});
soldiers.push(friend);

I included the “hero.command… move” order as a test, and it breaks right there, saying that the hero has nothing to command, or that the friend.pos is undefined. In other words, the variable I set to equal the brand new summon doesn’t capture the new unit.

It is no good to just summon a unit and then create a new array each time of all similar units. Not only is that profoundly inefficient, it changes the index place assigned to a given unit, which means that their individual instructions keep changing based upon their place in the index.

Using ‘findNearestFriend’ sometimes returns my pet, or an alternate unit, also no good.

So how do I capture new summons as a variable directly? Is this intended behavior (and if so, why?!)?

To save time, the code is a snippet. There are 100% no problems ensuring enough money to summon, that the arrays are set up correctly, that all the variables are called, etc. It took me many days to isolate the problem to the variable not actually grabbing the unit object, so trust me when I say I tried many other things and worked around them first. It never occurred to me that a variable wouldn’t actually accept the input of a method, until I ran this last test.

What is the soldier.push(friend) part

that is the command to add to the array, it has this format: array.push(thing-to-add)

‘soldiers’ is the array, ‘.push’ is a standard method, built into the language to add something to the end of an array, and ‘(friend)’ is the variable defined in the line before, to be added to the array.

I think you should put this piece of code in and if statement to check whether there is a friend. And the reason is that the code might be running before having time to summon the soldier. (You might need to put the snippet, or maybe the last two line, in a while True loop so that if it didn’t do it successfully the first time, the code will run properly once the friend is summoned)

And I think there isn’t any problem with summoning a unit as a variable and storing it. The same concept is used in Game Development, you spawn stuff and and they are saved in a variable.

That seems like a good idea, but maybe I don’t fully understand. To be absolutely certain I wasn’t mistaking who went into my array, I changed the variable names. I put it in a loop, and added a condition that soldier exist before trying to push it to the array. As a sanity check, I also added a condition that the hero have enough money, and that the hero say “New loop # …”, calling out each loop.

var mySoldiers = [];
var l = 1;

while(true) {
    if (hero.gold >= hero.costOf("soldier")) {
        var newSoldier = hero.summon("soldier");
        }
    if (newSoldier) {
        hero.command(newSoldier, "move", {x: newSoldier.pos.x + 10, y: newSoldier.pos.y +10});
        mySoldiers.push(newSoldier);
        hero.say (mySoldiers.length);
    }
    hero.say("New loop # " + l);
    hero.say(mySoldiers.length);
    l++;
}

The hero created several soldiers. None of them moved. The hero never called out the array length for anything but 0. The loops kept increasing.

Then I added the “hero.findNearest(hero.findFriends())” cludge to try to recognize my new soldiers, and they all moved, and the array length increased.

var mySoldiers = [];
var l = 1;

while(true) {
    if (hero.gold >= hero.costOf("soldier")) {
        var unknownSoldier = hero.summon("soldier");
        var newSoldier = hero.findNearest(hero.findFriends());
        }
    if (newSoldier) {
        hero.command(newSoldier, "move", {x: newSoldier.pos.x + 10, y: newSoldier.pos.y +10});
        mySoldiers.push(newSoldier);
        hero.say (mySoldiers.length);
    }
    hero.say("New loop # " + l);
    hero.say(mySoldiers.length);
    l++;
}

Would you please tell me what I should change or add to make the first version work, so I don’t have to “findFriends”?

That is as much as I know, I have no idea (I don’t know much JavaScript) but maybe someone else can help, like @abc, @JoPro_8000 or @Deadpool198 as they might know

1 Like

I’m still super grateful for your help. You’re a star. :slight_smile:

2 Likes

So, does anyone know what is wrong here? How do I capture my new summon in a variable? Please?

(See my third post in string - it has two separate bits of formatted code. This post shows precisely what is not working.)

I don’t know if you can target a newly spawned soldier. Even if you could do it, I think you need to know the index of that soldier in the friends array.

If you can’t target a new summon, is that the intended behavior? (If so, why?) Or is it a bug?

You can target the new summons:

Example - put the code in mountain mercenaries

while(true) {
    var gold = hero.findNearest(hero.findItems());
    if (gold) hero.move(gold.pos);
    if (hero.gold > hero.costOf("soldier"))
        hero.summon("soldier");
    for ( var i = 0, len = hero.built.length; i < len; i ++ ){
        // var soldier = hero.built[i];
         var enemy = hero.built[i].findNearestEnemy();
         if (hero.built[i].health < 0) pet.debug("hero is commanding #",i, " the dead", hero.built[i].id);
         if (enemy){ 
          if (i < 10) hero.command(hero.built[i], "attack", enemy);
          else hero.command(hero.built[i], "move", Vector(17, 28));
         } 
    }
}

You can command even the dead units and i think this is a bug - screenshot:

3 Likes

Thank you! This is a great method. I suppose if I choose the index number to be i = (hero.built.length - 1), it will always capture the most recent summon. (Or is it just index[0]? I don’t know if it adds the new summon to the hero.built array at beginning or end, but I can figure that out. Probably end, I expect.)

I really appreciate you taking the time to help me. :slight_smile:

This topic was automatically closed 12 hours after the last reply. New replies are no longer allowed.