Chrono Boost working

Started by Aeg1s, March 03, 2010, 01:59:11 PM

Previous topic - Next topic

Aeg1s

After doing some digging I've been able to get the AI using Chrono Boost; here's a simple example that will find the player's original Nexus and have it cast Chrono Boost on itself:



static void ChronoBoost(int player) {
    unit u = AIGrabUnit(player, c_PB_Nexus, c_prioScriptControlled, AIGetTownLocation(player, c_townOne));
    order o;
    if (u) {
        o = AICreateOrder(player, "TimeWarp", 0);
        OrderSetTargetUnit(o, u);
        if (UnitOrderIsValid(u, o)) {
            DebugOutput("TimeWarp", false);           
            AICast(u, o, c_noMarker, c_castHold);
        }
    }
}


itsarabbit

Remember that it should do it just when the 1st pylon is up.
Want Beta key! :D

Kernel64

Wow! awesome, Aeg1s! Maybe I can add and change this to a function that returns bool. If an error occurs, this means the ability cannot be cast for some reason like lack of energy.

I've got a lot of people to add into the credits section now.

Aeg1s

Quote from: Kernel64 on March 04, 2010, 02:51:08 AM
Wow! awesome, Aeg1s! Maybe I can add and change this to a function that returns bool. If an error occurs, this means the ability cannot be cast for some reason like lack of energy.

I've got a lot of people to add into the credits section now.


If you want to check for energy required here's how:



fixed energy = UnitGetPropertyFixed(u, c_unitPropEnergy, c_unitPropCurrent);
if (energy >= AIAbilityFixed(player, "TimeWarp", c_fieldEnergyCost))

Kernel64

#4
I'll definitely buy you a drink. You're awesome!

We should have a compilation or the sort of everything galaxy AI. That would be great.

edit:

I've edited the function to Boolean, should return false if the cast failed, and true if it has been cast. Also, added a town variable, so that we can use this as a called function for multiple nexus:

Quote
static bool ChronoBoost(int player, int CTown) {
    unit u = AIGrabUnit(player, c_PB_Nexus, c_prioScriptControlled, AIGetTownLocation (player, CTown));
    order o;
    if (u) {
        o = AICreateOrder(player, "TimeWarp", 0);
        OrderSetTargetUnit(o, u);
        if (UnitOrderIsValid(u, o)) {
            //DebugOutput("TimeWarp", false);           
            AICast(u, o, c_noMarker, c_castHold);
       return true;
        }
        else {return false;}
    }
}

I don't know what's missing though, or which file to put this in. Where did you place this function, Aeg1s?

edit 2:
Another modification: (not tested. please correct)

Quote
static bool ChronoBoost(int player, int CTownNexLoc, string aliasUnitType, int TTownTarLoc) {
    unit castunit = AIGrabUnit(player, c_PB_Nexus, c_prioScriptControlled, AIGetTownLocation (player, CTownNexLoc));
    unit tgtunit = AIGrabUnit(player, aliasUnitType, c_prioScriptControlled, AIGetTownLocation (player, TTownTarLoc));
    order ord;
    if (castunit) {
       if (tgtunit) {
          ord = AICreateOrder(player, "TimeWarp", 0);
          OrderSetTargetUnit(ord, tgtunit);
       
          if (UnitOrderIsValid(castunit, ord)) {
            //DebugOutput("TimeWarp", false);           
            AICast(castunit, ord, c_noMarker, c_castHold);
       return true;
          }
          else {return false;}
       }
       else {return false;} //target error
    }
    else {return false;} //caster error
}

-- Returns true if successful cast.
-- false if: target error, caster error, cast failed
-- requires CasterUnit, and which town (for multiple nexus)
-- requires Target Unit (must be structure?)
Overall idea is to make a function that will allow us to utilize a Nexus' Chrono boost on buildings such as Forges, Cybernetics core, Gateway, etc.

This isn't working though. Some help? I don't know where to put this, or if there's error in the code.

Aeg1s

That code looks fine at a quick glance.


I've actually hacked together a queue using a static array to which targets for chrono boost can be added. The top n items in the queue get chrono boosted where n=the number of Nexuses. Items can also be added for a one time boost or a continuous boost. The downside is this won't work if there are multiple Protoss AI's in a game since they'll both try to use the same static queue :/ I'm making my AI solely for 1v1 though so its an acceptable downside for me. I can post the code if anyone is interested in it.

Override Impulse

An easy work around would be to create a double array for the static queue, since you don't have more than eight players, assign each player 0-7 for the starting queue, that way you can also use the queue for other items as well.

IE:
switch(player#)
{
switch(player race)
{
queen enhance larva / protoss chrono boost / other terran mule | scanner sweep | supply upgrade...


Seems like you should get the most out of your code to reduce load and increase efficiency / easier to work with in the long run.

Aeg1s

Quote from: Override Impulse on March 04, 2010, 09:49:19 PM
An easy work around would be to create a double array for the static queue, since you don't have more than eight players, assign each player 0-7 for the starting queue, that way you can also use the queue for other items as well.

IE:
switch(player#)
{
switch(player race)
{
queen enhance larva / protoss chrono boost / other terran mule | scanner sweep | supply upgrade...


Seems like you should get the most out of your code to reduce load and increase efficiency / easier to work with in the long run.


Mmm good point, I hadn't thought about it too much. I did think of using a 2d array but wasn't sure if galaxy would support that; of course I can pack that into a 1d array. As for using it for other abilities I'm not sure if there's anything else that would need a queue like this since queens should just stay by one hatchery and the mule can check mineral counts at expansions for example.

Kernel64

#8
Can you post them? I'd like to see.

edit: Oh, and Aeg1s, where did you put the ChronoBoost code? The one you posted on the opening post of this thread.

Aeg1s

Alright, here's the code for the queue; I meant to modify it so it would work with multiple AI's but have been working on other stuff lately.


http://pastebin.com/VLaeVdBt


I have moved it into its own separate file but it used to sit at the top of the protoss0 file.

DarkZeros

These are the chrono boost funcs i'm using right now. I build them myself, looking at your code.

http://pastebin.com/XzMtgdEs

ChronoBoost(int player, int CTown, string aliasUnitType, string type)
This one to cast chrono boost to a specific building (that does NOT have already crono efect). It will cast from the nexus in town CTown.

ChronoBoostPriority(int player, int CTown)
This will cast cronoboost to the structures that are producing something. With some priorities (first Nexus, then gateway, ...). It will cast from the nexus in town CTown.

ChronoBoostRun(int player)
Same as above but cast from all the nexus.

Kernel64

Cool. I hope we can finally find that function which checks if a specific structure is actually doing something and what.

Like for example,

Gateway:

Does it have 1 queued zealot in it? Cast CB.

Does it have 2 stalkers queued, and we're not researching ground weapons, and we have < 26 energy, and we have only 1 nexus, and our priority is research? CB forge that is researching ground weapons. Not the shield one.

DarkZeros

That will be the best solution, but we don't have a call to check that.

Instead, I check if there is any unit in production, is not 100% efective, but at least is working quite fine.

Kernel64

Indeed. I'm loving the way your function works. At least through it, we can call CB at calculated moments within the script. Much better than the automated Nexus think.

DarkZeros

This one: http://pastebin.com/Rg5etGhY

With all the code done (no //TODO parts :P). Working better since it uses c_inProductionOnly.