Week 3
Basic Triggers and Intro to Disasters - Warning: Meteor approaching!
Outpost 2 has a whole bunch of triggers that allow you to react to various circumstances. You'll probably never use most of them, so for now I'll just cover some of the basic, most-used triggers.
CreateOnePlayerLeftTrigger(1, 0, "Trigger Function");
This trigger fires when only one player is left in the game. Standard LoS/LR victory condition.
Notice that I simply set the first two settings to 1 and 0, respectively. The first setting is "enabled". It will always be 1, since there's no sense creating a disabled trigger. The second setting, dictates whether the trigger fires multiple times, or only once. Set it to 1 for a one-time trigger. Usually, however, you want the trigger to fire multiple times.
CreateTimeTrigger(1, 0, Minimum Ticks, Maximum Ticks, "Trigger Function");
This is the "interval" time trigger. Notice that you specify a minimum and maximum amount. The trigger will fire at a random time between the minimum and maximum time. Note that the unit of measurement is ticks,
not marks. Ticks = marks * 100.
CreateTimeTrigger(1, 0, Time, "Trigger Function");
Same as the first time trigger, except this one always fires after a set amount of time.
I'm only explaining these few triggers for now because I'd rather tell you how triggers in general work, rather than get into the specifics of each individual trigger. As you can see all of these have a "Trigger Function" setting. These specify which function is called when the trigger fires. In layman terms, you tell OP2 the name of a book and it goes and reads the book. Note that this DOES NOT go in InitProc!
Here's an example function:
SCRIPT_API void MyTriggerCode()
{
// Code goes here
}
Not too bad, right? Granted, that function doesn't actually do anything, and there's no trigger that invokes it. I'll show you a full example later, after I explain disasters. Note that disasters have a 10-mark delay before they spawn after they are "created" to allow time for the two disaster warning messages.
Let's only look at the basic disasters for now:
TethysGame::SetEarthquake(X, Y, Strength); // Seismic Event (quake)
TethysGame::SetLightning(originX, originY, Strength, destinationX, destinationY); // Electrical Storm
TethysGame::SetTornado(originX, originY, Duration, destX, destY, No Delay); // Vortex
TethysGame::SetMeteor(X, Y, Size); // Meteor
IMPORTANT NOTE: Never, under any circumstances, set the duration of a vortex to zero! It will result in a vortex that never dissipates (a permavortex)!!!As you may have noticed, you'll want most of these values to be random. Otherwise your disasters will always be in the same place and of the same strength. Here are my recommendations for some of those values:
Any x/y position: The size of the map is a good idea; that way disasters can stike anywhere!
TethysGame::SetLightning(TethysGame::GetRand(128)+31, TethysGame::GetRand(64)-1, ...); // Assuming the map is 128x64
Earthquake Strength: Depends on how powerful you want, but don't go above 7. Anything higher is ridiculously destructive.
TethysGame::SetEarthquake(..., TethysGame::GetRand(7) );
Electrical Storm Strength: I recommend a maximum value of 50~60.
TethysGame::SetLightning(..., TethysGame::GetRand(55), ...);
Meteor Strength: 3 is a good value. I don't recommend going higher than 5.
TethysGame::SetMeteor(..., TethysGame::GetRand(3) );
Vortex duration: As I mentioned, you don't want this to be zero. So let's add a minimum value to this after we generate the random number.
TethysGame::SetTornado(..., TethysGame::GetRand(45)+10, ... );
Okay, so now we've got all kinds of disasters all over the map. There's just one problem: we have the pieces, but they're not arranged properly! You should be able to figure out how to do this yourself. If you want to try doing it on your own, that'd be amazing! If you can't though, the solution is posted below.
// Setup the triggers in InitProc:
int InitProc()
{
// Code from previous lessons here
// Disaster Time Triggers
TethysGame::CreateTimeTrigger(1, 0, 1200, 4300, "Quakes"); // Earthquake trigger
TethysGame::CreateTimeTrigger(1, 0, 5600, 12700, "Vortex"); // Vortex trigger
TethysGame::CreateTimeTrigger(1, 0, 3900, 9800, "Storms"); // Electrical Storm trigger
TethysGame::CreateTimeTrigger(1, 0, 2300, 5100, "Meteor"); // Meteor trigger
// Some more code may or may not be here
}
void AIProc()
{
// We'll talk about AIProc later
}
// ---------- Define the trigger functions here ----------
// Quakes
SCRIPT_API void Quakes()
{
TethysGame::SetEarthquake( TethysGame::GetRand(128)+31, TethysGame::GetRand(128)-1, TethysGame::GetRand(4) );
}
// Vortexes (Vortices?)
SCRIPT_API void Vortex()
{
TethysGame::SetTornado( TethysGame::GetRand(128)+31, TethysGame::GetRand(128)-1, TethysGame::GetRand(20)+10, TethysGame::GetRand(128)+31, TethysGame::GetRand(128)-1 );
}
// Electrical Storms
SCRIPT_API void Storms()
{
TethysGame::SetLightning( TethysGame::GetRand(128)+31, TethysGame::GetRand(128)-1, TethysGame::GetRand(25), TethysGame::GetRand(128)+31, TethysGame::GetRand(128)-1 );
}
// Meteors
SCRIPT_API void Meteor()
{
TethysGame::SetMeteor( TethysGame::GetRand(128)+31, TethysGame::GetRand(128)-1, TethysGame::GetRand(3) );
}
// ---------- End of trigger functions ----------
Notice how we deal with x/y offset after we generate a random value.
You should play around with the various disaster settings. Try to figure out settings you like!
One last thing: What if disasters are disabled?
if(TethysGame::CanHaveDisasters() == 1)
{
// All triggers that spawn disasters go here
}
There you have it! As always, feel free to post results, questions, and comments!
Next week: More Disasters; Victory and Defeat
BONUS LESSON: THE BLIGHT IS APPROACHING!
This is gonna be one of those triggers you don't want repeated!
CreateTimeTrigger(1, 1, 1000, "Blight");
SCRIPT_API void Blight()
{
// Setup Blight
GameMap::SetVirusUL(LOCATION(8+31, 19-1), 1); // Spawn the Blight
TethysGame::SetMicrobeSpreadSpeed(60); // Set the Blight's spread speed
// Warning Message
TethysGame::AddMessage(1248, 576, "Microbe growth detected!", -1, 152);
}
AddMessage is needed because the Blight isn't a "normal" disaster and no warning message is played when it spawns. So be sure to warn people if you use it! Or not... :evil laugh: For those curious about AddMessage:
TethysGame::AddMessage(X*32, Y*32, "Message", Receiving Player, Sound ID);
The x/y values allow you to "jump" to a specific location. The values must be multiplied by 32 (or set them to -1 to disable jumping). The rest is fairly self-explanitory. A list of sounds can be found in the EnumSoundId.h file in your SDK's Include directory.
Okay, that's it.
2020 update: Check out my Disaster Creator, which makes it significantly easier to add all kinds of disasters (including volcanoes!) to your levels!