Code Snippets & Functions

Started by Aeg1s, March 04, 2010, 08:45:04 PM

Previous topic - Next topic

Aeg1s


Post any code snippets or functions you have that other people might find useful.


Pretty simple, but useful (it should probably check for the protoss string but I was lazy and didn't run my test until I figured out what PlayerRace returned for protoss.)

int GetRace(int player) {
    string oppRace = PlayerRace(player);
    if (oppRace == "Terr") {
    return c_raceTerran;
    } else if (oppRace == "Zerg") {
    return c_raceZerg;
    } else {
    return c_raceProtoss;
    }
}



A function that will produce up to ToMake # of units but will only queue at most MaxQueued at a single time; this can be used to prevent the standard AISetStock from blocking anything below it from being produced. MakeUnitsPrereq is the same but it checks if you have at least one of prereqBuilding completed first.

void MakeUnits(int player, int ToMake, int MaxQueued, string unitClass) {
    int queue = TechTreeUnitCount(player, unitClass, c_techCountQueuedOrBetter);
    int count = AIKnownUnitCount(player, player, unitClass);
    int inQueue = queue - count;
    int thisCount = ToMake - queue;
    if (queue >= ToMake || inQueue >= MaxQueued) {
        return;
    }
    if (thisCount > MaxQueued) {
        thisCount = MaxQueued;
    }
    AISetStock(player, count + thisCount, unitClass);
}


void MakeUnitsPrereq(int player, int ToMake, int MaxQueued, string unitClass, string prereqBuilding) {
    if (TechTreeUnitCount(player, prereqBuilding, c_techCountCompleteOnly) > 0) {
        MakeUnits(player, ToMake, MaxQueued, unitClass);
    }
}



Here's a sample that will fully use two barracks (1 tech lab, 1 reactor) production in a Marine/Marauder push (the script that uses this pushes before 10/30 but this is used a little longer than that; 10 & 30 were more upper limits to its expected usage. For all intents & purposes they could be 200 to constantly use the barracks until it hits max supply):


MakeUnits(player, 10, 1, c_TU_Marauder);
MakeUnitsPrereq(player, 30, 2, c_TU_Marine, c_TB_BarracksReactor);



This function will build supplyObject until you have at least 10 over your current supply. Note that this isn't useful until you've gotten out of the early game where precise supply timing is important in build orders.


void BuildSupply(int player, string supplyObject) {
    int used = PlayerGetPropertyInt(player, c_playerPropSuppliesUsed);
    //int created = PlayerGetPropertyInt(player, c_playerPropSuppliesMade); // doesn't account for queued units
       
    if (GetRace(player) == c_raceZerg) {
    created = TechTreeUnitCount(player, c_ZU_Overlord, c_techCountQueuedOrBetter) * 8 + TechTreeUnitCount(player, c_ZU_Overseer, c_techCountQueuedOrBetter) * 8;
        created += TechTreeUnitCount(player, c_ZB_Hatchery, c_techCountQueuedOrBetter) * 2 + TechTreeUnitCount(player, c_ZB_Lair, c_techCountQueuedOrBetter) * 2 + TechTreeUnitCount(player, c_ZB_Hive, c_techCountQueuedOrBetter) * 2;
    } else if (GetRace(player) == c_raceProtoss) {
    created = TechTreeUnitCount(player, c_PB_Pylon, c_techCountQueuedOrBetter) * 8 + TechTreeUnitCount(player, c_PB_Nexus, c_techCountQueuedOrBetter) * 10;
    } else if (GetRace(player) == c_raceTerran) {
    created = TechTreeUnitCount(player, c_TB_SupplyDepot, c_techCountQueuedOrBetter) * 8 + TechTreeUnitCount(player, c_TB_CommandCenter, c_techCountQueuedOrBetter) * 11;
        created += TechTreeUnitCount(player, c_TB_OrbitalCommand, c_techCountQueuedOrBetter) * 11 + TechTreeUnitCount(player, c_TB_PlanetaryFortress, c_techCountQueuedOrBetter) * 11;
        created += TechTreeUnitCount(player, "SupplyDepotLowered", c_techCountQueuedOrBetter) * 8;
        // Alias doesn't seem to work right here...
    }
       
    if (created < used + 10) {
        if (created > 60 && GetRace(player) == c_raceProtoss) {
            // Don't clutter up the map making power grids
            // Place them near factories to keep them powered
            AISetStockEx(player, c_townMain, AIKnownUnitCount(player, player, supplyObject) + 1, supplyObject, c_nearCloseFactory, 0);
        } else {
            AISetStock(player, AIKnownUnitCount(player, player, supplyObject) + 1, supplyObject);           
        }
    }
}



AddTech & AddBuilding only create a building/tech if you have a prerequisite building completed (useful for teching up).

void AddTech(int player, string tech, string prereqBuilding) {
    // Don't fill up the SetStock queue if we don't need to (Keep things simple)
    if (AITechCount(player, tech, c_techCountQueuedOrBetter) < 1 && TechTreeUnitCount(player, prereqBuilding, c_techCountCompleteOnly) > 0) {
        AISetStock(player, 1, tech);
    }   
}


void AddBuilding(int player, string building, string prereqBuilding) {
    // Don't fill up the SetStock queue if we don't need to (Keep things simple)
    if (TechTreeUnitCount(player, building, c_techCountQueuedOrBetter) < 1 && TechTreeUnitCount(player, prereqBuilding, c_techCountCompleteOnly) > 0) {
        AISetStock(player, AIKnownUnitCount(player, player, building) + 1, building);
    }   
}



BuildAt checks for a certain supply consumption before making the object


void BuildAt(int player, int count, string unitClass, int supplyCount) {
    if (PlayerGetPropertyInt(player, c_playerPropSuppliesUsed) >= supplyCount && AITechCount(player, unitClass, c_techCountQueuedOrBetter) < count) {
        AISetStock(player, count, unitClass);   
    }
}

Kernel64

Where do I insert these codes? Do I insert them at [race]0.galaxy?

Yuna_Q


Aeg1s

Quote from: Kernel64 on March 05, 2010, 01:06:28 AM
Where do I insert these codes? Do I insert them at [race]0.galaxy?


Personally I put them in a seperate file that I just include in the [race]0.galaxy files but they can go directly in the race files if you want.

Kernel64

Quote from: Aeg1s on March 05, 2010, 05:04:52 PM
Quote from: Kernel64 on March 05, 2010, 01:06:28 AM
Where do I insert these codes? Do I insert them at [race]0.galaxy?


Personally I put them in a seperate file that I just include in the [race]0.galaxy files but they can go directly in the race files if you want.

Okay, thanks. I'm also wondering how exactly you got the ChronoBoost func running without having errors. Would love to know where you put it and where you call it. And if there are other files you had to modify for it to work?

apriores

Anyone knows code for Banshee's Cloaking Filed upgrade?

Heinermann


apriores


kblood

I would like to place an order for some code snippets please  :P (Thats not me licking you, its just doggie eyes)
But bad jokes aside, I would really like if someone could find some codes to change menus, or come up with interactive choices. If that could be found we could make some kind of in game control panel with cheat functions, AI control and such for map testing. Spawning mobs somewhere to make and army and test tactics against them, or just watch them get moved by your army :)
Well, that could end up being what it could do, to begin with I think it could be nice to make a change in the gameinit scripts. Would be easier to make mod maps, and maybe even make a menu before the game starts where race of each player can be chosen.

CneoC

Just had to write a function to property output a fixed value since i couldn't find one anywhere... ugly as hell but it does the job ;)

string FixedToString(fixed f) {
    int d = FixedToInt(f);
    int r = FixedToInt((f - d) * 100);
    string rs = IntToString(r);
    if (r <= 0) { r = 1; }
    while (r < 10) { rs = "0" + rs; r *= 10; }
    return IntToString(d) + "." + rs;
}

Astazha

I believe this function would allow you to do away with the need to pass the required building as an argument.


http://galaxywiki.com/wiki/AIGetFirstUnfinishedReq

vjeux


A FixedToString that allows you to set the precision (number of decimal to show up). (Source: http://www.sc2mapster.com/api-docs/types/fixed/ )string FixedToString(fixed f, int precision) {
  string s = "";
  int g;


  if (precision < 0) {
    precision = 0;
  }


  //Negative case
  if (f < 0) {
    s = "-";
    f = -f;
  }


  // Integer part
  g = FixedToInt(f);
  s = s + IntToString(g);
  f = f - g;


  if (precision != 0 && f != 0) {
    s = s + ".";


    // Decimal part
    do {
      f = f * 10;
      g = FixedToInt(f);
      s = s + IntToString(g);
      f = f - g;
      precision = precision - 1;
    } while (f != 0 && precision != 0);
  }


  return s;
}



If you want to use basic math functions, I've recoded "cos, sin, tan, round, floor, ceil, isInt, mod". You can find the file here: http://www.sc2mapster.com/assets/basic-mathematic-functions/


Aeg1s

Quote from: Astazha on March 12, 2010, 12:28:36 AM
I believe this function would allow you to do away with the need to pass the required building as an argument.

http://galaxywiki.com/wiki/AIGetFirstUnfinishedReq


Yeah it would; except I'm not always using the functions to check the building/tech requirements but other conditions.

Aeg1s

Quote from: vjeux on March 12, 2010, 05:42:40 AM
If you want to use basic math functions, I've recoded "cos, sin, tan, round, floor, ceil, isInt, mod". You can find the file here: http://www.sc2mapster.com/assets/basic-mathematic-functions/


Thanks for the link to the math file; the PointX & PointY functions are very much appreciated. I almost got to the point of writing something similar myself after getting frustrated trying to get the x & y variables from a point. I recently had a problem including your math file in MeleeAI.galaxy though; I'm not sure what the problem was because I was able to remove the include (it was buried 3 files deep) because I wasn't actually using it.