Week 10
Your First Colony Game with an AI - 'Cuz Watching Your Population Grow While Doing Nothing Else Is REALLY BORING
This tutorial will be divided into two halves. In the first half we will build the colony game. In the second, we will work on AI some more.
Part I: Creating a Working Colony GameWhat, you thought all you had to do was set the gametype to Colony in the DescBlock and run it! No! It's much more complicated than that!
"Nonsense! I'm only working with
one human player! It's gotta be easier than multiplayer you moron!"
You forgot about saving the game.
"Oh, right... Okay, you win."
Of course I do! After all, I'm writing the tutorial, so I win be default! Now let's stop messing around and setup your colony game.
Saving The GameSadly, merely clicking the "Save Game" button doesn't really save everything you want to save. All the special unit handles, triggers, and other variables you want/need to keep track of are NOT saved by default, and with an AI those things are awfully important! So how do we force OP2 to save our variables?
With a Save Data struct, of course! You're probably asking what a struct is (people with programming experience outside of C/++ may know it as a "record" instead). Basically, it's a big super-variable that can hold lots of other little variables. It kinda looks like this:
// Generic Example
// Define the struct
struct structType
{
// Stuff goes here
}; // NOTE: You MUST have that semi-colon after the struct definition
// Declare the struct
structType structName;
// OP2-specific Example
struct SaveData
{
// Triggers
Trigger Meteor, // Meteor time trigger
Vortex; // Vortex time trigger
// AI Units
Unit AI_CC, // AI Command Center
AI_SF, // AI Structure Factory
AI_VF; // AI Vehicle Factory
// AI FightGroups
FightGroup LynxRush, // Microwave Lynx Rush attack group
Defenses; // Base defense group
// Misc. Data
int numAI; // AI player number
};
SaveData SD;
// Usage
TethysGame::CreateUnit(SD.AI_CC, mapCommandCenter, LOCATION(47+31, 98-1), SD.numAI, mapNone, 0);
Here's a list of things that DO NOT work:
struct SaveData
{
int numAI = 2; // Can't assign data to variables in struct definition
Unit AI_Smelter;
TethysGame::CreateUnit(AI_Smelter, ...); // Can't have code in structs
} // Forgot the semi-colon here
SaveData; // SaveData is a new variable type you've created. It needs a name, just like an int or a Trigger or a Unit. (You probably meant SaveData SD;)
SD; // Did not specify type. (You probably meant SaveData SD;)
Meteor = CreateTimeTrigger(1, 0, 1500, "SpawnMeteors"); // "Meteors" does not exist (you probably meant SD.Meteor)
A good rule of thumb is that any trigger you create should be assigned to a variable stored in your SaveData struct. Any variables your AI references (units, groups, locations, integers, etc.) should also be stored in the SaveData struct. Triggers used by mission objectives MUST be stored in the struct.
Things that DON'T need to be put in the struct include generic variables (Unit1, for example).
Go write a struct that holds a trigger for a disaster, a trigger for a mission objective, a unit handle for an AI unit, and a unit group. Write code that uses all of those variables. Come back when you're done and I'll show you how we get OP2 to actually
use our struct.
You're back! That was fast. Nice work. Ready for this? This will take hours upon hours of hard work and if you mess up at all you have to start all over.
1) Go to the bottom of your code file.
2) Look for these lines of code:
void __cdecl GetSaveRegions(struct BufferDesc &bufDesc)
{
bufDesc.bufferStart = 0; // Pointer to a buffer that needs to be saved
bufDesc.length = 0; // sizeof(buffer)
}
3) Replace it with this (assuming you named your save data struct SD):
void __cdecl GetSaveRegions(struct BufferDesc &bufDesc)
{
bufDesc.bufferStart = &SD; // Pointer to a buffer that needs to be saved
bufDesc.length = sizeof(SD); // sizeof(buffer)
}
Whoa, that was hard! And to make it worse, we have to do that for every single colony game and/or campaign mission we write! Don't forget or your mission won't work right!
That should be all for SaveData. If you have any problems let me know. Now let's look at our AI again!