Ok, so create a bunch of rect triggers, each of which turns on some GP(s). There are two ways I can se this working. One is to just create a bunch of different callbacks that would turn on the GPs in some region, and set each rect trigger callback accordingly.
The other would be to reuse the same callback for each rect trigger, but then to figure out which trigger fired yourself. That's one of the weaknesses of the trigger system. The callback isn't passed any information about which trigger caused it to be called. If you kept around a global array of triggers, and trigger rects, then this would allow you to iterate over all the GPs in that region and turn them on if the trigger has fired.
The second way is probably more complicated from a source code perspective, and less efficient from a runtime perspective, but more easily extensible. It would be possible to get the second way to work without hardcoding a bunch of things. Plus, you could also setup the triggers in an automated way. Such as using an enum to find all GPs for that player, and for each one found (that is turned off), it can generate a rect trigger around that region, and mark which unit that region turns on.
The system might work something like this (untested code):
struct GpActivateStruct
{
Trigger activateTrigger;
Unit gp;
};
struct ScriptGlobal
{
GpActivateStruct gpActivate[32]; // ** Set appropriate array size **
int numActivateGp;
};
ScriptGlobal scriptGlobal;
int InitProc()
{
Unit unit;
LOCATION loc;
PlayerBuildingEnum buildingEnum(aiPlayer, mapGuardPost);
int i = 0;
while (buildingEnum.GetNext(unit))
{
// ** Might want to add a debug check here to ensure the end of the array isn't passed, and possibly warn the level designer **
//if (i >= numof(scriptGlobal.gpActivate)) ...
// Should probably check the GP is disabled here (using an extension library)
scriptGlobal.gpActivate[i].gp = unit;
loc = unit.Location();
scriptGlobal.gpActivate[i].activateTrigger = CreateRectTrigger(true, true, playerNum, loc.x-10, loc.y-10, 20, 20, "EnableGP"); // ** Set approptiate Rect size. This sets the rect to be 10 tiles in any direction from the GP **
i++;
}
scriptGlobal.numActivateGp = i;
}
SCRIPT_API void EnableGP()
{
int i;
// Find out which GPs need to be activated
for (i = 0; i < scriptGlobal.numActivateGp; i++)
{
if (scriptGlobal.gpActivate[i].activateTrigger.HasFired(playerNum))
{
scriptGlobal.gpActivate[i].gp.DoUnIdle();
// Delete the trigger and unit, so we can free ScStubs, and don't accidentally call DoUnidle on a different unit if the GP is destroyed and another unit is built that uses the same unit index
scriptGlobal.gpActivate[i].activateTrigger.Destroy(); // Free ScStub
// If not last item in list, swap current item with last item
if (i != scriptGlobal.numActivateGp)
{
scriptGlobal.gpActivate[i] = scriptGlobal.gpActivate[scriptGlobal.numActivateGp-1];
i--; // Need to recheck current slot, since it contains a new value now
}
scriptGlobal.numActivateGp--; // Dump the last item on the list
}
}
}
You of course need to define aiPlayer, and playerNum yourself. You might also need to write the numof macro, which was written in Hooville (BaseData.h) like this:
#define numof(array) (sizeof(array)/sizeof(array[0]))