Week 5
Your First Last One Standing - Because "Last One Standing" Sounds Better Than "Last Person Of Non-Specific Race, Gender, Religion, Ethnicity, or Sexual Preference Standing"
Alright, it's time to put all of the knowledge you've learned so far into this first test! It's time to make your first fully-functional multiplayer game!
I want you to start fresh from the template this time, okay?
Here's what I want you to start with:
-Code to handle morale steady on/off
-Code to handle day/night on/off
-Code to handle disasters on/off (don't actually add the disasters yet)
-Setup initial resources for all players
-Standard LoS victory condition
Now go create some bases. Before I forget:
Player[#].CenterViewOn(X, Y); // Focus a player's view on a location.
Want some bonus points? If not, skip down to (END EXTRA EFFORT).
(BEGIN EXTRA EFFORT)[/b][/size]
Randomized Starting Locations:
Scroll up to the top of your file. You should see a bunch of lines that say #include <etc.h>. Add a blank line underneath those lines and add this:
// Used below to randomize bases
#define numof(array) (sizeof(array)/sizeof(array[0]))
#define autosize(array) numof(array), array
We're not done yet though. In InitProc:
// Randomized Base code. Thanks for the suggestions, Arklon!
int i[6] = { 0, 1, 2, 3, 4, 5 };
RandomizeList(autosize(i) );
// Create bases - check to make sure owner is active first!
if (Player[i[0]].IsHuman() )
{
SetupBase1(i[0]);
}
if (Player[i[1]].IsHuman() )
{
SetupBase2(i[1]);
}
if (Player[i[2]].IsHuman() )
{
SetupBase3(i[2]);
}
if (Player[i[3]].IsHuman() )
{
SetupBase4(i[3]);
}
if (Player[i[4]].IsHuman() )
{
SetupBase5(i[4]);
}
if (Player[i[5]].IsHuman() )
{
SetupBase6(i[5]);
}
This code assumes you have six players and one base per player. If you have less, remove if statements as needed, and change int i[6] = { 0, 1, 2, 3, 4, 5 } to int i[number of Players] = { 0, 1, ... (number of players - 1) }. Since after reading that and confusing myself, here's an example for only 4P:
// Randomized Base code, 4P example.
int i[4] = { 0, 1, 2, 3 };
RandomizeList(autosize(i) );
// Create bases - check to make sure owner is active first!
if (Player[i[0]].IsHuman() )
{
SetupBase1(i[0]);
}
if (Player[i[1]].IsHuman() )
{
SetupBase2(i[1]);
}
if (Player[i[2]].IsHuman() )
{
SetupBase3(i[2]);
}
if (Player[i[3]].IsHuman() )
{
SetupBase4(i[3]);
}
Are we done yet? Sorry, not quite. You'll notice these are all functions, right? That means we'll have to create functions for base creation above InitProc.
// Base Creation Functions
void SetupBase1(int i);
{
Player[i].CenterViewOn(X, Y); // Focus a player's view on a location.
Unit x;
TethysGame::CreateUnit(x, mapCommandCenter, LOCATION(X, Y), i, mapNone, 0);
// More units here...
}
Notice that we're now using i for the player number. That's because we, the programmer, no longer know which player is getting this base. Rest assured, though, that OP2 does. Anyways, repeat this for all player bases. You probably want to give the bases slightly different layouts, but make sure everybody has the same stuff!
(END EXTRA EFFORT)[/b][/size]
Done yet? Good. Say, want to make it so the Structure Factories start with structure kits in them? Of course you do! So go find where you create each player's Structure Factory.
TethysGame::CreateUnit(x, mapStructureFactory, ...);
Now, immediately under that line:
x.SetFactoryCargo(0, mapNursery, mapNone);
Doesn't that remind you of something? Yup, it's just like setting the lights on for units. We tell OP2 to look at unit x (in this case, a Structure Factory) and add cargo to its cargo bays. Let's look at it in detail.
SetFactoryCargo(Cargo Bay, Unit Type, Cargo Type);
You understand that, right? Just remember that cargo bay numbers are like player numbers, so Bay 1 = 0 in code, Bay 2 = 1 in code, ...
Anyways, what if we want different kits in the factory based on resource settings? Easy! Same thing we did for initial resources:
// Structure Factory Cargo Set By Resource Settings
switch (Player[i].Difficulty() )
{
case 0:
Unit1.SetFactoryCargo(0, mapTokamak, mapNone);
Unit1.SetFactoryCargo(1, mapNursery, mapNone);
Unit1.SetFactoryCargo(2, mapUniversity, mapNone);
Unit1.SetFactoryCargo(3, mapVehicleFactory, mapNone);
Unit1.SetFactoryCargo(4, mapRobotCommandCenter, mapNone);
Unit1.SetFactoryCargo(5, mapResidence, mapNone);
break;
case 1:
Unit1.SetFactoryCargo(0, mapTokamak, mapNone);
Unit1.SetFactoryCargo(1, mapNursery, mapNone);
Unit1.SetFactoryCargo(2, mapUniversity, mapNone);
break;
case 2:
// None.
break;
}
Okay, so that's game setup, base design, and victory conditions set up. Add ore in good locations all around the map. Include a healthy mix of bar yield and type. Don't forget to add Fumaroles and Magma Vents (if the terrain allows it)!
So, what's left? Disasters, right? Well, go add some! Don't make them too powerful or frequent; this is an LoS and people tend to complain if an uberquake owns them just before they were about to win. Also, no Blight! Volcanoes are not recommended, but if you feel like it, go for it.
Congratulations! You've got a working Last One Standing! There's just one thing you still need...
Initial Vehicles
I told you we'd get to 'em, didn't I? Stick this in each player's base creation:
short numSoFar = 0; // Number of units created so far
while (numSoFar <= TethysGame::InitialUnits() );
{
if (Player[#].IsEden() )
{
TethysGame::CreateUnit(x, mapLynx, LOCATION( (xPos + numSoFar), yPos), Player#, mapLaser, 0);
x.DoSetLights(1);
}
else
{
TethysGame::CreateUnit(x, mapLynx, LOCATION( (xPos + numSoFar), yPos), Player#, mapMicrowave, 0);
x.DoSetLights(1);
}
numSoFar++; // Increment the counter by 1
}
numSoFar = 0; // Reset for next attempt
That should work... Anyways, that may require some tweaking based on how you're creating the bases.
If you're using functions to create the bases, as demonstrated in the random bases code above:-Delete the numSoFar++ line.
If you're creating all of the bases in the same function (in InitProc):-Only include the short numSoFar = 0 line the first time you use that code.
A note of caution: This code will create a line of units up to 12 tiles long. Make sure you have enough space on the map for that! Pick your location carefully.
That should do it then! Your first LoS, in all its glory! Compile it, test it, and play it on IRC! Post it here for everyone to see!
Questions, comments, results? Post 'em!
Special Bonus: I've attached a (near-perfect) recreation of the original Pie Chart. Feel free to look it over if you need help.