I'm digging into the SDK and putting together a colony map. Using Visual Studio 2015, the SDK compiled the test map without any fiddeling, which was awesome. I am comfortable programming in C#, but this is my first time using C++. I suspect this is a C++ syntax question, but not sure?
I added a failure condition to the map so if you do not have a Command Center you lose. My question is, how can I add an and statement to the failure trigger so it checks all of the following conditions before failing the scenario?
* You do not have a constructed CC
* You do not have a CC in a ConVec
* You do not have a CC kit in the structure factory
Below is the code I have so far.
Trigger trigMissingCC = CreateCountTrigger(1, 0, -1, mapCommandCenter, mapNone, 1, cmpLower, "NoResponseToTrigger");
Trigger trigMissingConVecCC = CreateCountTrigger(1, 0, -1, mapConVec, mapCommandCenter, 1, cmpLower, "NoResponseToTrigger");
Trigger trigMissingStructFactoryCCKit = CreateCountTrigger(1, 0, -1, mapStructureFactory, mapCommandCenter, 1, cmpLower, "NoResponseToTrigger");
CreateFailureCondition(1, 0, trigMissingCC, "NoCommandCenter");
Okay,
I read through more of SirBombers tutorials on mapmaking and they answered half of my question. You can use a SetTrigger to combine triggers. So the triggers are combined now into one SetTrigger.
I think I'm using one of the triggers incorrectly though. If all command centers on the map are destroyed and there are no command center kits on the map, the game will not fail until you blow up the structure factory. I'm guessing the CountTrigger I'm using for checking the Structure Factory contents is incorrect?
Perhaps the solution is to use the CreateKitTrigger function instead, but I don't see how to use this function to check if the kit doesn't exist.
CreateKitTrigger syntax:
CreateKitTrigger(enabled, one-time, Player Number, Structure Kit Type, Minimum Amount Needed, "Trigger Function");
Current Code I'm using:
Trigger trigMissingCC = CreateCountTrigger(1, 0, -1, mapCommandCenter, mapNone, 1, cmpLower, "NoResponseToTrigger");
Trigger trigMissingConVecCC = CreateCountTrigger(1, 0, -1, mapConVec, mapCommandCenter, 1, cmpLower, "NoResponseToTrigger");
Trigger trigMissingStructFactoryCCKit = CreateCountTrigger(1, 0, -1, mapStructureFactory, mapCommandCenter, 1, cmpLower, "NoResponseToTrigger");
Trigger setTriggerCCs = CreateSetTrigger(1, 1, 3, 3, "NoResponseToTrigger", trigMissingCC, trigMissingConVecCC, trigMissingStructFactoryCCKit);
CreateFailureCondition(1, 0, setTriggerCCs, "NoCommandCenter");
As far as I'm aware there is no way to set a comparison type on a Kit Trigger - it's always "player has at least this many", which is useless for your purposes. I think Hooman is right, and you will have to "fake" it by checking in AIProc. Something like this (untested):
Trigger t1, t2, t3, t4;
int InitProc()
{
...
t1 = (CC count trigger)
t2 = (ConVec kit count trigger)
t3 = CreateTimeTrigger(0, 0, 10, "NoResponseToTrigger"); // Note that this trigger is disabled by default.
t4 = CreateSetTrigger(1, 1, 3, 3, "NoResponseToTrigger", t1, t2, t3);
CreateFailureCondition(1, 0, t4, "Ignored");
...
}
void AIProc()
{
// Not possible with vanilla SDK. Requires HFL/UnitEx for GetFactoryCargo.
UnitEx nextSF;
bool foundKit = false;
PlayerBuildEnum FindAllSFs(-1, mapStructureFactory);
while (FindAllSFs.GetNext(nextSF) && !foundKit)
{
for (int i = 0; i < 6; i++)
{
if (nextSF.GetFactoryCargo(i) == mapCommandCenter)
{
foundKit = true;
break;
}
}
if (!foundKit)
{
t3.Enable();
}
else
{
t3.Disable();
}
}
I managed to include HFL into SDK solution without trouble. I also learned the C++ compiler reads code sequentially, requiring me to pay attention to the order Functions are declared.
I had trouble using the triggers. I think the timeTrigger watching for a CC kit in the Structure Factory would fire when the scenario was loaded, so later on you would fail if your CC was destroyed even if you had a backup kit the Structure Factory. I just pulled the SetTrigger out and started manually checking for each failure condition.
Okay, the current version is below which I have tested and seems to be working correctly. Thank you for everyone's help.
Trigger trigFailureWaitTime;
int InitProc()
{
HFLInit();
trigFailureWaitTime = CreateTimeTrigger(0, 0, 100, "NoResponseToTrigger");
CreateFailureCondition(1, 0, trigFailureWaitTime, "Ignored");
}
bool BuildingConstructed(int player, map_id buildingType)
{
Unit structure;
PlayerBuildingEnum findAllStructures(player, buildingType);
while (findAllStructures.GetNext(structure))
{
return true;
}
return false;
}
bool KitInConVec(int player, map_id structureKitType)
{
Unit vehicle;
PlayerUnitEnum findAllVehicles(player);
while (findAllVehicles.GetNext(vehicle))
{
if (vehicle.GetType() == mapConVec && vehicle.GetCargo() == structureKitType)
{
return true;
}
}
return false;
}
bool KitInStructFactory(int player, map_id structureKitType)
{
// Below Requires HFL/UnitEx for GetFactoryCargo.
UnitEx nextSF;
PlayerBuildingEnum findAllSFs(player, mapStructureFactory);
while (findAllSFs.GetNext(nextSF))
{
for (int i = 0; i < 6; i++)
{
if (nextSF.GetFactoryCargo(i) == structureKitType)
{
return true;
}
}
}
return false;
}
bool BuildingOrKitAvailable(int player, map_id buildingType)
{
return BuildingConstructed(player, buildingType) ||
KitInConVec(player, buildingType) ||
KitInStructFactory(player, buildingType);
}
bool CheckIfGameFailed()
{
if (!BuildingOrKitAvailable(0, mapCommandCenter))
{
return true;
}
if (!BuildingOrKitAvailable(0, mapStructureFactory))
{
if (!BuildingOrKitAvailable(0, mapSpaceport))
{
return true;
}
//TODO: Check if Phonix module not researched. If not, and no AdvLab, fail game.
//if (!hasBuildingOrKitAvailable(0, mapAdvancedLab))
//{
// return true;
//}
}
return false;
}
void AIProc()
{
if (CheckIfGameFailed())
{
TrigFailureWaitTime.Enable();
}
}