1148 lines
33 KiB
Plaintext
1148 lines
33 KiB
Plaintext
|
//Generic script Version 1.0
|
||
|
//For standard campaign maps
|
||
|
|
||
|
/* ******************** */
|
||
|
/* Declared Variables */
|
||
|
/* ******************** */
|
||
|
|
||
|
/* Next Level stuff */
|
||
|
public LEVEL NextLev;
|
||
|
|
||
|
|
||
|
/* Define Players/Enemies */
|
||
|
public int numEnemies, enemy[2];
|
||
|
private int targetCount[2], targetX[2][5], targetY[2][5]; //MAX targets = 4, need array one bigger!
|
||
|
public BOOL allianceFlag;
|
||
|
|
||
|
|
||
|
/* Starting Enemy Power */
|
||
|
public int power[2];
|
||
|
|
||
|
/* Structure Limits */
|
||
|
public int numStrucStats, strucLimit[5];
|
||
|
public STRUCTURESTAT strucStat[5];
|
||
|
|
||
|
/* Initialisation */
|
||
|
public int centreX, centreY;
|
||
|
public int scrollX1, scrollX2, scrollY1, scrollY2;
|
||
|
public int zoomLevel;
|
||
|
public int numLZ, LZX[1], LZY[1];
|
||
|
public int numTechs[2];
|
||
|
public RESEARCHSTAT startTech[2][10];
|
||
|
|
||
|
|
||
|
/* Briefings */
|
||
|
public int numBriefs;
|
||
|
public INTMESSAGE brief[2];
|
||
|
public INTMESSAGE endMsg, winMsg;
|
||
|
|
||
|
/* Victory Conditions */
|
||
|
public int numVictory, victoryX[2], victoryY[2];
|
||
|
public BOOL victory[2];
|
||
|
|
||
|
/* Objectives */
|
||
|
public int numObjectives, objectiveX[3], objectiveY[3];
|
||
|
public INTMESSAGE objective[3];
|
||
|
private BOOL objectiveFlag[3];
|
||
|
private int objectivesDone;
|
||
|
|
||
|
/* Artifacts */
|
||
|
public SOUND artSnd1, artSnd2;
|
||
|
public int numArt, victoryArt, artType[6], artVal[6], artX[6], artY[6];
|
||
|
//public INTMESSAGE artMsg[6];
|
||
|
public RESEARCHSTAT artComp[6];
|
||
|
private FEATURE artID[6];
|
||
|
private int artFlag[6];
|
||
|
private int artCollected;
|
||
|
|
||
|
/* Enemy Base Blips */
|
||
|
public int numBases, basePlayer[5];
|
||
|
public int baseRegion[5], baseWav1[5], baseWav2[5];
|
||
|
public INTMESSAGE baseMsg[5];
|
||
|
private int baseFlag[5];
|
||
|
private int basesDead;
|
||
|
private int iMidX, iMidY;
|
||
|
|
||
|
/* Groups */
|
||
|
//these can be for any player!
|
||
|
public int numGroups;
|
||
|
public int grpType[10], grpPlayer[10], grpRegion[10], grpTimeGo[10], grpRegionGo[10], grpWhoGo[10];
|
||
|
public int grpMorale[10], grpLeadership[10], grpRetreatXY[10], grpIdealSize[10];
|
||
|
public int grpPosStart[10], grpPosMin[10], grpPosMax[10], grpPosStep[10], grpPosType[10];
|
||
|
public int grpFactory[10];
|
||
|
private BOOL grpFlagGo[10]; //keep track of already triggered groups
|
||
|
private GROUP grpGroup[10], grpReinforce[10]; //the actual groups are stored in this, based on region.
|
||
|
private int grpPosCurrent[10]; //keep track of current waypoint
|
||
|
private BOOL grpBusy[10]; //keep track of already ordered
|
||
|
private int timeGroup; //keeps track of time since started level, for triggering groups
|
||
|
|
||
|
/* Factories */
|
||
|
//these can be for any player!
|
||
|
public int numFactories;
|
||
|
public int factID[10], factAssXY[10], factTimeGo[10];
|
||
|
public int factRegionGo[10], factTempMin[10], factTempMax[10];
|
||
|
private BOOL factFlagGo[10]; //stores whether producing or not
|
||
|
|
||
|
/* LISTS OF STUFF (INDEXED BY ARRAY) */
|
||
|
|
||
|
public STRUCTURE structures[10];
|
||
|
public FEATURE features[10];
|
||
|
public DROID droids[10];
|
||
|
public TEMPLATE templates[20];
|
||
|
public int coordsX[10], coordsY[10];
|
||
|
public int regionsX1[20], regionsY1[20], regionsX2[20], regionsY2[20];
|
||
|
public int sectorsX1[20], sectorsY1[20], sectorsX2[20], sectorsY2[20];
|
||
|
|
||
|
|
||
|
|
||
|
/* 'Globals' */
|
||
|
public int player;
|
||
|
public FEATURESTAT crate;
|
||
|
public int artRange, objectiveRange; //artifact pickup/obj blip removal
|
||
|
public int wayRange, targetRange; //range to waypoints/range for targets
|
||
|
public int targetMax; //maximum number of targets (4)
|
||
|
public SOUND wonSnd; //mission won
|
||
|
public SOUND lostSnd; //mission lost
|
||
|
public SOUND attackSnd1; //Base Under Attack Sound
|
||
|
public SOUND baseSnd[5]; //base detected/dead
|
||
|
|
||
|
|
||
|
/* General variables */
|
||
|
private int count, count2; //for while loops
|
||
|
private DROID testDroid, newDroid;
|
||
|
private STRUCTURE newDroidFactory; //new droid built
|
||
|
private int countBriefs, temp, temp1, temp2, tempX, tempY;
|
||
|
private STRUCTURE hitStruc; //Base Under Attack
|
||
|
private BASEOBJ attackerObj; //Base Under Attack
|
||
|
private int t; //Base Under Attack time delay for next warning
|
||
|
private int enemyCount; //for enemy base attack stuff!
|
||
|
|
||
|
/* ******************** */
|
||
|
/* Triggers */
|
||
|
/* ******************** */
|
||
|
trigger winTrig(artCollected == victoryArt, 25);
|
||
|
trigger lostTrig(not anyDroidsLeft(player), 25);
|
||
|
trigger objTrig (every, 15);
|
||
|
trigger artTrig (every, 10);
|
||
|
trigger baseTrig (every, 15);
|
||
|
trigger nextLevTrig (every, 20);
|
||
|
trigger gameLostTrig (every, 20);
|
||
|
trigger checkGroupsTrig (every, 35); //every 4 seconds
|
||
|
trigger wayGroupsTrig (every, 100); //every 4 seconds
|
||
|
trigger sectorGroupsTrig(every, 75); //every 8 seconds
|
||
|
trigger attackGroupsTrig(every, 83); //every 8 seconds
|
||
|
trigger targetGroupsTrig(every, 43); //every 4 seconds
|
||
|
trigger regionGroupsTrig(every, 11); //every second
|
||
|
trigger timeGroupsTrig (every, 100); //every 10 seconds
|
||
|
trigger updateEnemyTrig (every, 21); //every 2 seconds
|
||
|
trigger factoryProdTrig (every, 450); //every 45 seconds
|
||
|
trigger droidBuiltTrig (wait, 1); //very quickly
|
||
|
|
||
|
/* ******************** */
|
||
|
/* Events */
|
||
|
/* ******************** */
|
||
|
|
||
|
/* Declared Events */
|
||
|
event wonYetEvnt;
|
||
|
event lostYetEvnt;
|
||
|
event timeUp;
|
||
|
|
||
|
/* Initialisation */
|
||
|
event start(CALL_GAMEINIT)
|
||
|
{
|
||
|
//centre view
|
||
|
centreViewPos(centreX, centreY);
|
||
|
//set alliances
|
||
|
if (allianceFlag and numEnemies > 1)
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numEnemies)
|
||
|
{
|
||
|
count2 = 0;
|
||
|
while (count2 < numEnemies)
|
||
|
{
|
||
|
if (count != count2)
|
||
|
{
|
||
|
createAlliance(enemy[count], enemy[count2]);
|
||
|
}
|
||
|
count2 = count2 + 1;
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//set scroll limits
|
||
|
setScrollParams(scrollX1, scrollY1, scrollX2, scrollY2);
|
||
|
|
||
|
//set radar zoom level
|
||
|
setRadarZoom(zoomLevel);
|
||
|
|
||
|
//set LZ and no go areas
|
||
|
initAllNoGoAreas();
|
||
|
count = 0;
|
||
|
while (count < numLZ)
|
||
|
{
|
||
|
setNoGoArea(LZX[count] - 1, LZY[count] - 1, LZX[count] + 1, LZY[count] + 1, count);
|
||
|
count = count + 1;
|
||
|
}
|
||
|
|
||
|
//set structure limits
|
||
|
count = 0;
|
||
|
while (count < numStrucStats)
|
||
|
{
|
||
|
setStructureLimits (strucStat[count], strucLimit[count], player);
|
||
|
enableStructure(strucStat[count], player);
|
||
|
count = count + 1;
|
||
|
}
|
||
|
|
||
|
//set power levels
|
||
|
count = 0;
|
||
|
while (count < numEnemies)
|
||
|
{
|
||
|
//also set technology for each enemy
|
||
|
count2 = 0;
|
||
|
while (count2 < numTechs[count])
|
||
|
{
|
||
|
completeResearch(startTech[count][count2], enemy[count]);
|
||
|
count2 = count2 + 1;
|
||
|
}
|
||
|
setPowerLevel(power[count], enemy[count]);
|
||
|
count = count + 1;
|
||
|
}
|
||
|
|
||
|
//show player start objectives
|
||
|
count = 0;
|
||
|
while (count < numObjectives)
|
||
|
{
|
||
|
addMessage(objective[count], PROX_MSG, player, false);
|
||
|
count = count + 1;
|
||
|
}
|
||
|
|
||
|
//Setup Artifacts already on map (NOT TESTED YET!)
|
||
|
//setting flags incorrectly in VLO could break game!
|
||
|
count = 0;
|
||
|
while (count < numArt)
|
||
|
{
|
||
|
if (artType[count] >= 4) //deal with no object to get artifact from
|
||
|
{ //eg for extra topics given at the end?
|
||
|
artFlag[count] = 4;
|
||
|
}
|
||
|
if (artType[count] == 0) //deal with artifact already on map
|
||
|
{
|
||
|
artID[count] = features[artVal[count]];
|
||
|
artFlag[count] = 1;
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
|
||
|
//setup groups
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
groupAddArea(grpGroup[count], grpPlayer[count], regionsX1[grpRegion[count]], regionsY1[grpRegion[count]],
|
||
|
regionsX2[grpRegion[count]], regionsY2[grpRegion[count]]);
|
||
|
grpPosCurrent[count] = grpPosStart[count];
|
||
|
//set morale levels
|
||
|
if (grpMorale[count] >= 0)
|
||
|
{
|
||
|
/*
|
||
|
//set repair for now (run away not good enough!?)
|
||
|
setGroupSecondary(grpGroup[count], DSO_REPAIR_LEVEL, DSS_REPLEV_HIGH);
|
||
|
*/
|
||
|
//to get hill attackers to work properly
|
||
|
//setGroupSecondary(grpGroup[count], DSO_ATTACK_RANGE, DSS_ARANGE_LONG);
|
||
|
|
||
|
setGroupRetreatForce(grpGroup[count], grpMorale[count]);
|
||
|
setGroupRetreatLeadership(grpGroup[count], grpLeadership[count]);
|
||
|
if (grpType[count] < 2) //use coords for patrol/ambush/defence
|
||
|
{
|
||
|
setGroupRetreatPoint(grpGroup[count], coordsX[grpRetreatXY[count]], coordsY[grpRetreatXY[count]]);
|
||
|
}
|
||
|
else //use sectors for scout/attack
|
||
|
{
|
||
|
temp = grpRetreatXY[count];
|
||
|
//order scout/attack forces to random position in this sector
|
||
|
tempX = sectorsX1[temp] + random(sectorsX2[temp] - sectorsX1[temp]);
|
||
|
tempY = sectorsY1[temp] + random(sectorsY2[temp] - sectorsY1[temp]);
|
||
|
setGroupRetreatPoint(grpGroup[count], tempX, tempY);
|
||
|
}
|
||
|
}
|
||
|
//set time = 0 groups going
|
||
|
if (grpTimeGo[count] == timeGroup)
|
||
|
{
|
||
|
grpFlagGo[count] = TRUE;
|
||
|
if (grpType[count] < 2) //use coords for patrol/ambush/defence
|
||
|
{
|
||
|
if (grpPosStart[count] >= 0) //cope with no start position defined
|
||
|
{
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, coordsX[grpPosStart[count]], coordsY[grpPosStart[count]]);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
temp = grpPosCurrent[count];
|
||
|
//order scout/attack forces to random position in this sector
|
||
|
tempX = sectorsX1[temp] + random(sectorsX2[temp] - sectorsX1[temp]);
|
||
|
tempY = sectorsY1[temp] + random(sectorsY2[temp] - sectorsY1[temp]);
|
||
|
orderGroupLoc(grpGroup[count], DORDER_MOVE, tempX, tempY);
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
//set time = 0 factories going
|
||
|
count = 0;
|
||
|
while (count < numFactories)
|
||
|
{
|
||
|
//set assembly points, if desired
|
||
|
if (factAssXY[count] != -1)
|
||
|
{
|
||
|
setAssemblyPoint (structures[factID[count]], coordsX[factAssXY[count]], coordsY[factAssXY[count]]);
|
||
|
}
|
||
|
if ((factTimeGo[count] == timeGroup) and (not factFlagGo[count]))
|
||
|
{
|
||
|
factFlagGo[count] = TRUE; //set factory to produce
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//play mission brief(s)
|
||
|
if (numBriefs > 0)
|
||
|
{
|
||
|
addMessage(brief[0], MISS_MSG, 0, true);
|
||
|
countBriefs = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
event briefings(CALL_VIDEO_QUIT) //need to rework this better!!
|
||
|
{
|
||
|
if (countBriefs >= numBriefs) //last briefing?
|
||
|
{
|
||
|
setEventTrigger(briefings, inactive);
|
||
|
}
|
||
|
if (countBriefs < numBriefs) //remove last, add next?
|
||
|
{
|
||
|
removeMessage(brief[countBriefs - 1], MISS_MSG, 0);
|
||
|
addMessage(brief[countBriefs], MISS_MSG, 0, true);
|
||
|
countBriefs = countBriefs + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Base Under Attack */
|
||
|
event baseHit(CALL_STRUCT_ATTACKED, selectedPlayer, ref hitStruc, ref attackerObj)
|
||
|
{
|
||
|
if (t>=10)
|
||
|
{
|
||
|
t=0;
|
||
|
playSoundPos(attackSnd1, player, hitStruc.x, hitStruc.y, hitStruc.z);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
event everySec(every, 20) //update time delay before told again (about 20 seconds)
|
||
|
{
|
||
|
t=t+1;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Remove Objective Blips */
|
||
|
event removeObjectives(objTrig)
|
||
|
{
|
||
|
if (objectivesDone == numObjectives) //all blips gone?
|
||
|
{
|
||
|
setEventTrigger(removeObjectives, inactive);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numObjectives)
|
||
|
{
|
||
|
if ((not objectiveFlag[count]) and
|
||
|
(droidInRange(player, objectiveX[count], objectiveY[count], objectiveRange)))
|
||
|
{
|
||
|
objectiveFlag[count] = TRUE;
|
||
|
objectivesDone = objectivesDone + 1;
|
||
|
removeMessage(objective[count], PROX_MSG, player);
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Artifacts */
|
||
|
//This works for artifacts from STRUCTURES, FEATURES or DROIDS as well as crates already on map!
|
||
|
//tested for STRUCTURES, FEATURES, DROIDS and starting CRATES
|
||
|
event artLoop(artTrig) //update artifact list
|
||
|
{
|
||
|
if (artCollected == numArt) //all artifacts collected?
|
||
|
{
|
||
|
setEventTrigger(artLoop, inactive);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numArt)
|
||
|
{
|
||
|
if (artFlag[count] == 0)
|
||
|
{
|
||
|
temp = 0;
|
||
|
//might be a better way to do this check?
|
||
|
if (artType[count] == 1)
|
||
|
{
|
||
|
if (structures[artVal[count]] == NULLOBJECT) //from dead structure
|
||
|
{
|
||
|
temp = 1;
|
||
|
}
|
||
|
}
|
||
|
if (artType[count] == 2)
|
||
|
{
|
||
|
if (features[artVal[count]] == NULLOBJECT) //from dead feature
|
||
|
{
|
||
|
temp = 1;
|
||
|
}
|
||
|
}
|
||
|
if (artType[count] == 3)
|
||
|
{
|
||
|
if (droids[artVal[count]] == NULLOBJECT) //from dead droid
|
||
|
{
|
||
|
temp = 1;
|
||
|
}
|
||
|
}
|
||
|
if (temp == 1) //OK to place crate?
|
||
|
{
|
||
|
//place artifact crate, and allow check for prox
|
||
|
artID[count] = addFeature(crate, artX[count], artY[count]);
|
||
|
artFlag[count] = 1;
|
||
|
}
|
||
|
}
|
||
|
if (artFlag[count] == 1)
|
||
|
{
|
||
|
artFlag[count] = 2; //hack since don't use script for detected.wav
|
||
|
}
|
||
|
if (artFlag[count] == 2)
|
||
|
{
|
||
|
if (droidInRange(player, artX[count], artY[count], artRange))
|
||
|
{
|
||
|
artCollected = artCollected + 1;
|
||
|
artFlag[count] = 3;
|
||
|
playSoundPos(artSnd2, player, artID[count].x, artID[count].y, artID[count].z);
|
||
|
destroyFeature(artID[count]);
|
||
|
//removeMessage(artMsg[count], PROX_MSG, player);
|
||
|
enableResearch(artComp[count], player);
|
||
|
}
|
||
|
}
|
||
|
if (artType[count] == 3)
|
||
|
{
|
||
|
if (droids[artVal[count]] != NULLOBJECT)
|
||
|
{
|
||
|
//keep track of droid position for crate when it dies
|
||
|
artX[count] = droids[artVal[count]].x;
|
||
|
artY[count] = droids[artVal[count]].y;
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/* Enemy Base Blips */
|
||
|
event baseLoop(baseTrig) //update base blips
|
||
|
{
|
||
|
if (basesDead == numBases) //all bases gone?
|
||
|
{
|
||
|
setEventTrigger(baseLoop, inactive);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numBases)
|
||
|
{
|
||
|
if (baseFlag[count] == 0)
|
||
|
{
|
||
|
if (seenStructInArea(player, basePlayer[count], FALSE,
|
||
|
regionsX1[baseRegion[count]], regionsY1[baseRegion[count]],
|
||
|
regionsX2[baseRegion[count]], regionsY2[baseRegion[count]]))
|
||
|
{
|
||
|
addMessage(baseMsg[count], PROX_MSG, player, false);
|
||
|
if (baseWav1[count] >= 0)
|
||
|
{
|
||
|
iMidX = (regionsX1[baseRegion[count]]+regionsX2[baseRegion[count]])/2;
|
||
|
iMidY = (regionsY1[baseRegion[count]]+regionsY2[baseRegion[count]])/2;
|
||
|
playSoundPos(baseSnd[baseWav1[count]], player, iMidX, iMidY, 0 );
|
||
|
}
|
||
|
baseFlag[count] = 1;
|
||
|
}
|
||
|
}
|
||
|
if (baseFlag[count] == 1)
|
||
|
{
|
||
|
if (numStructsButNotWallsInArea(basePlayer[count],
|
||
|
regionsX1[baseRegion[count]], regionsY1[baseRegion[count]],
|
||
|
regionsX2[baseRegion[count]], regionsY2[baseRegion[count]])== 0)
|
||
|
{
|
||
|
basesDead = basesDead + 1;
|
||
|
baseFlag[count] = 2;
|
||
|
if (baseWav2[count] >= 0)
|
||
|
{
|
||
|
iMidX = (regionsX1[baseRegion[count]]+regionsX2[baseRegion[count]])/2;
|
||
|
iMidY = (regionsY1[baseRegion[count]]+regionsY2[baseRegion[count]])/2;
|
||
|
playSoundPos(baseSnd[baseWav2[count]], player, iMidX, iMidY, 0 );
|
||
|
//playSound(baseSnd[baseWav2[count]], player);
|
||
|
}
|
||
|
removeMessage(baseMsg[count], PROX_MSG, player);
|
||
|
killStructsInArea(basePlayer[count], REF_WALL, //remove walls and building features in base
|
||
|
regionsX1[baseRegion[count]], regionsY1[baseRegion[count]],
|
||
|
regionsX2[baseRegion[count]], regionsY2[baseRegion[count]],
|
||
|
TRUE, TRUE);
|
||
|
killStructsInArea(basePlayer[count], REF_WALLCORNER, //remove corner walls in base
|
||
|
regionsX1[baseRegion[count]], regionsY1[baseRegion[count]],
|
||
|
regionsX2[baseRegion[count]], regionsY2[baseRegion[count]],
|
||
|
TRUE, FALSE);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Events: Win or Lose */
|
||
|
event nextLevEvnt(inactive) //assumes victory already checked
|
||
|
{
|
||
|
flushConsoleMessages();
|
||
|
playSound(wonSnd,0);
|
||
|
pause(20);
|
||
|
// give all research
|
||
|
count = 0;
|
||
|
while (count < numArt)
|
||
|
{
|
||
|
enableResearch(artComp[count], 0);
|
||
|
count = count +1;
|
||
|
}
|
||
|
// *required for sub missions*
|
||
|
//setLandingZone(10, 51, 12, 53);
|
||
|
// *no longer need to remove briefings?*
|
||
|
//removeMessage(MissionBrief, MISS_MSG, player);
|
||
|
//startMission(CAMP_EXPAND, NextLev);
|
||
|
//End game here for now! (don't try next mission)
|
||
|
gameOverMessage(winMsg, MISS_MSG, 0, true);
|
||
|
|
||
|
setEventTrigger(nextLevEvnt, inactive);
|
||
|
}
|
||
|
|
||
|
//skip to end of level
|
||
|
event cheatEvnt(CALL_MISSION_START) //cheat button ctrl M
|
||
|
{
|
||
|
setEventTrigger(nextLevEvnt, nextLevTrig);
|
||
|
setEventTrigger(cheatEvnt, inactive);
|
||
|
}
|
||
|
event gameLost(inactive)
|
||
|
{
|
||
|
// addMessage(endMsg, MISS_MSG, 0, true);
|
||
|
// gameOver(false);
|
||
|
gameOverMessage(endMsg, MISS_MSG, 0, FALSE);
|
||
|
setEventTrigger(gameLost, inactive);
|
||
|
}
|
||
|
|
||
|
event lostYetEvnt(lostTrig) //triggered on (not anyDroidsLeft(player))
|
||
|
{
|
||
|
if (not anyStructButWallsLeft(player))
|
||
|
{
|
||
|
setEventTrigger(wonYetEvnt,inactive);
|
||
|
setEventTrigger(timeUp, inactive);
|
||
|
setEventTrigger(gameLost, gameLostTrig); //waits 2 seconds before ending
|
||
|
//playSound(lostSnd,0);
|
||
|
setEventTrigger(lostYetEvnt, inactive);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//out of time?
|
||
|
event timeUp(CALL_MISSION_TIME)
|
||
|
{
|
||
|
setEventTrigger(wonYetEvnt,inactive);
|
||
|
setEventTrigger(lostYetEvnt,inactive);
|
||
|
playSound(lostSnd,0); //may want different sound, eg "Out of Time"
|
||
|
setEventTrigger(gameLost, gameLostTrig); //waits 2 seconds before ending
|
||
|
setEventTrigger(timeUp, inactive);
|
||
|
}
|
||
|
|
||
|
event wonYetEvnt(winTrig) //triggered on (artCollected == victoryArt)
|
||
|
{
|
||
|
temp2 = 0; //stores number of conditions met
|
||
|
//needs to check various victory conditions setup in VLO
|
||
|
|
||
|
//check all enemy vehicles and structures destroyed
|
||
|
if (victory[0])
|
||
|
{
|
||
|
count = 0;
|
||
|
temp = 0;
|
||
|
while (count < numEnemies)
|
||
|
{
|
||
|
if ((not anyDroidsLeft(enemy[count]))
|
||
|
and (not anyStructButWallsLeft(enemy[count])))
|
||
|
{
|
||
|
temp = temp + 1;
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
if (temp == numEnemies)
|
||
|
{
|
||
|
temp2 = temp2 + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//check all player vehicles in specific area (eg LZ)
|
||
|
if (victory[1])
|
||
|
{
|
||
|
temp = numDroidsInArea(player, 0, 0, scrollX1 * 128, scrollY1 * 128);
|
||
|
if (temp == numDroidsInArea(player, victoryX[0], victoryY[0], victoryX[1], victoryY[1]))
|
||
|
{
|
||
|
if (temp != 0)
|
||
|
{
|
||
|
temp2 = temp2 + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (temp2 == numVictory) //victory reached?
|
||
|
{
|
||
|
setEventTrigger(lostYetEvnt, inactive);
|
||
|
setEventTrigger(timeUp, inactive);
|
||
|
setEventTrigger(nextLevEvnt, nextLevTrig);
|
||
|
setEventTrigger(wonYetEvnt, inactive);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Enemy AI */
|
||
|
|
||
|
event wayGroups(wayGroupsTrig)
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
//update groups position
|
||
|
if ((grpFlagGo[count]) and (grpType[count] < 2) and (grpPosStart[count] >= 0)) //been triggered and ambush/patrol/defence?
|
||
|
{
|
||
|
//simple predefined waypoints
|
||
|
//has the group got to waypoint or are they mainly idle?
|
||
|
/*
|
||
|
if ((grpGroup[count].members > 0) and (
|
||
|
(grpGroup[count].x >= coordsX[grpPosCurrent[count]] - wayRange) and
|
||
|
(grpGroup[count].y >= coordsY[grpPosCurrent[count]] - wayRange) and
|
||
|
(grpGroup[count].x <= coordsX[grpPosCurrent[count]] + wayRange) and
|
||
|
(grpGroup[count].y <= coordsY[grpPosCurrent[count]] + wayRange)) or
|
||
|
(idleGroup(grpGroup[count]) >= grpGroup[count].members/2))
|
||
|
*/
|
||
|
if (grpGroup[count].members > 0) //idle stuff taken out FOR DEMO
|
||
|
{
|
||
|
grpBusy[count] = FALSE; //no longer 'busy'
|
||
|
temp = grpPosCurrent[count]; //store for checking difference later
|
||
|
if (grpPosType[count] == 3) //random choice
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosMin[count] + grpPosStep[count] * random(grpPosMax[count] - grpPosMin[count]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosCurrent[count] + grpPosStep[count]; //get next waypoint
|
||
|
}
|
||
|
if ((grpPosCurrent[count] > grpPosMax[count]) or (grpPosCurrent[count] < grpPosMin[count]))
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosCurrent[count] - grpPosStep[count]; //stop at last one
|
||
|
if (grpPosType[count] == 1) //loop
|
||
|
{
|
||
|
if (grpPosStep[count] > 0) //+ve loop
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosMin[count];
|
||
|
}
|
||
|
else //-ve loop
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosMax[count];
|
||
|
}
|
||
|
}
|
||
|
if (grpPosType[count] == 2) //ping pong
|
||
|
{
|
||
|
grpPosStep[count] = - grpPosStep[count];
|
||
|
grpPosCurrent[count] = grpPosCurrent[count] + grpPosStep[count];
|
||
|
}
|
||
|
}
|
||
|
if (grpPosCurrent[count] != temp) //don't order again if already there!
|
||
|
{
|
||
|
//orderGroupLoc(grpGroup[count], DORDER_SCOUT, coordsX[grpPosCurrent[count]], coordsY[grpPosCurrent[count]]);
|
||
|
orderGroupLoc(grpGroup[count], DORDER_MOVE, coordsX[grpPosCurrent[count]], coordsY[grpPosCurrent[count]]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* SCOUTS AND TARGET FINDING DISABLED FOR DEMO
|
||
|
event checkGroups(checkGroupsTrig)
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
initIterateGroup(grpGroup[count]);
|
||
|
count2 = 0;
|
||
|
while (count2 < grpGroup[count].members)
|
||
|
{
|
||
|
//check for morale failed, and make retreat fully
|
||
|
testDroid = iterateGroup(grpGroup[count]);
|
||
|
if (testDroid.order == DORDER_RUN)
|
||
|
{
|
||
|
if (grpType[count] >= 2) //scout and attack type uses sectors
|
||
|
{
|
||
|
grpPosCurrent[count] = grpRetreatXY[count]; //flag retreat sector as current?
|
||
|
temp = grpRetreatXY[count];
|
||
|
//order scout forces to random position in this sector
|
||
|
tempX = sectorsX1[temp] + random(sectorsX2[temp] - sectorsX1[temp]);
|
||
|
tempY = sectorsY1[temp] + random(sectorsY2[temp] - sectorsY1[temp]);
|
||
|
orderGroupLoc(grpGroup[count], DORDER_MOVE, tempX, tempY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
orderGroupLoc(grpGroup[count], DORDER_MOVE, coordsX[grpRetreatXY[count]], coordsY[grpRetreatXY[count]]);
|
||
|
}
|
||
|
grpBusy[count] = TRUE; //mark busy (will become idle when at retreat point)
|
||
|
count2 = grpGroup[count].members; //exit loop
|
||
|
}
|
||
|
count2 = count2 + 1;
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// not finished yet! Now includes attack groups as well as scout groups
|
||
|
event sectorGroups(sectorGroupsTrig)
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
if ((grpFlagGo[count]) and (grpType[count] >= 2) and (grpGroup[count].members != 0) //set going and scout/attack type only
|
||
|
and (idleGroup(grpGroup[count]) > (grpGroup[count].members / 2))) //also not busy!
|
||
|
{
|
||
|
grpBusy[count] = FALSE; //no longer 'busy'?
|
||
|
//attack group stuff
|
||
|
temp1 = 0; //just in case don't find an enemy match
|
||
|
if ((allianceFlag)) // and (random(numEnemies + 1) < 1))
|
||
|
{
|
||
|
temp1 = random(numEnemies); //allow allies targets as well!
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
count2 = 0;
|
||
|
while (count2 < numEnemies)
|
||
|
{
|
||
|
if (grpPlayer[count] == enemy[count2])
|
||
|
{
|
||
|
temp1 = count2; //this should be enemy index number!
|
||
|
}
|
||
|
count2 = count2 + 1;
|
||
|
}
|
||
|
}
|
||
|
if ((grpType[count] == 3) and (targetCount[temp1] > 0)) //any targets for attack groups
|
||
|
{
|
||
|
temp2 = random(targetCount[temp1]);
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, targetX[temp1][temp2], targetY[temp1][temp2]);
|
||
|
}
|
||
|
else //otherwise next sector
|
||
|
{
|
||
|
//scout/next sector stuff
|
||
|
temp = grpPosCurrent[count]; //current scout sector
|
||
|
//10% chance of scouting past an occupied sector (even if valid targets exist there!)
|
||
|
//put in temp1 and temp2 for legibility!
|
||
|
temp1 = numStructsButNotWallsInArea(player, sectorsX1[temp], sectorsY1[temp], sectorsX2[temp], sectorsY2[temp]);
|
||
|
temp2 = numDroidsInArea(player, sectorsX1[temp], sectorsY1[temp], sectorsX2[temp], sectorsY2[temp]);
|
||
|
//next sector if clear of droids and structures or 10% chance
|
||
|
if ((random(100) < 10) or ((temp1 == 0) and (temp2 ==0)))
|
||
|
{
|
||
|
//sector clear so use as a retreat point 50% chance
|
||
|
if (random(100) < 50)
|
||
|
{
|
||
|
grpRetreatXY[count] = grpPosCurrent[count];
|
||
|
}
|
||
|
//get new sector (like wayGroups above!)
|
||
|
if (grpPosType[count] == 3) //random choice
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosMin[count] + grpPosStep[count] * random(grpPosMax[count] - grpPosMin[count]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosCurrent[count] + grpPosStep[count]; //get next waypoint
|
||
|
}
|
||
|
if ((grpPosCurrent[count] > grpPosMax[count]) or (grpPosCurrent[count] < grpPosMin[count]))
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosCurrent[count] - grpPosStep[count]; //stop at last one
|
||
|
if (grpPosType[count] == 1) //loop
|
||
|
{
|
||
|
if (grpPosStep[count] > 0) //+ve loop
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosMin[count];
|
||
|
}
|
||
|
else //-ve loop
|
||
|
{
|
||
|
grpPosCurrent[count] = grpPosMax[count];
|
||
|
}
|
||
|
}
|
||
|
if (grpPosType[count] == 2) //ping pong
|
||
|
{
|
||
|
grpPosStep[count] = - grpPosStep[count];
|
||
|
grpPosCurrent[count] = grpPosCurrent[count] + grpPosStep[count];
|
||
|
}
|
||
|
}
|
||
|
//playSound(lostSnd,0); //test
|
||
|
//now order to new sector
|
||
|
temp = grpPosCurrent[count];
|
||
|
//order scout forces to random position in this sector
|
||
|
tempX = sectorsX1[temp] + random(sectorsX2[temp] - sectorsX1[temp]);
|
||
|
tempY = sectorsY1[temp] + random(sectorsY2[temp] - sectorsY1[temp]);
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, tempX, tempY); //why was this on DORDER_MOVE?
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//not finished yet!
|
||
|
event targetGroups(targetGroupsTrig)
|
||
|
{
|
||
|
//clear targets if any gone (by shuffling down array)
|
||
|
count = 0;
|
||
|
while (count < numEnemies)
|
||
|
{
|
||
|
if (targetCount[count] > 0)
|
||
|
{
|
||
|
temp = 0;
|
||
|
while (temp < targetCount[count])
|
||
|
{
|
||
|
if (numStructsButNotWallsInArea(player, targetX[count][temp] - targetRange, targetY[count][temp] - targetRange,
|
||
|
targetX[count][temp] + targetRange, targetY[count][temp] + targetRange) == 0)
|
||
|
//(not (objectInRange(player, targetX[count][temp], targetY[count][temp], targetRange)))
|
||
|
|
||
|
{
|
||
|
count2 = temp;
|
||
|
while (count2 < targetCount[count])
|
||
|
{
|
||
|
targetX[count][count2] = targetX[count][count2 + 1];
|
||
|
targetY[count][count2] = targetY[count][count2 + 1];
|
||
|
count2 = count2 + 1;
|
||
|
}
|
||
|
targetCount[count] = targetCount[count] - 1; //reduce total for this enemy
|
||
|
}
|
||
|
temp = temp + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//flag new targets, if any (structures and droids but not walls!), at the moment for any group (not just scouts)
|
||
|
count2 = 0;
|
||
|
while (count2 < numGroups)
|
||
|
{
|
||
|
temp1 = numStructsButNotWallsInArea(player, grpGroup[count2].x - targetRange, grpGroup[count2].y - targetRange,
|
||
|
grpGroup[count2].x + targetRange, grpGroup[count2].y + targetRange);
|
||
|
temp2 = numDroidsInArea(player, grpGroup[count2].x - targetRange, grpGroup[count2].y - targetRange,
|
||
|
grpGroup[count2].x + targetRange, grpGroup[count2].y + targetRange);
|
||
|
|
||
|
//make sure correct player, and targets exist before logging a new one
|
||
|
if ((grpPlayer[count2] == enemy[count]) and (targetCount[count] < targetMax) and ((temp1 > 0) or (temp2 > 0)))
|
||
|
//(objectInRange(player, grpGroup[count2].x, grpGroup[count2].y, targetRange)))
|
||
|
{
|
||
|
//playSound(lostSnd,1);
|
||
|
targetX[count][targetCount[count]] = grpGroup[count2].x;
|
||
|
targetY[count][targetCount[count]] = grpGroup[count2].y;
|
||
|
//order group to attack! (should be following heavies)
|
||
|
//orderGroupLoc(grpGroup[count2], DORDER_SCOUT, targetX[count][targetCount[count]], targetY[count][targetCount[count]]);
|
||
|
|
||
|
if ((grpGroup[count2].members <= temp1 + temp2) and (grpType[count2] == 2))
|
||
|
//if more objects than scouts, run away!!!
|
||
|
{
|
||
|
//playSound(lostSnd,0); //test!
|
||
|
|
||
|
//use retreat stuff instead
|
||
|
orderGroup(grpGroup[count2], DORDER_RUN); //run away for a bit (will only work with initial retreat pos?)
|
||
|
}
|
||
|
else if (grpType[count2] == 2)
|
||
|
{
|
||
|
orderGroup(grpGroup[count2], DORDER_STOP); //stay where you are (and hopefully kill stuff) if scout group
|
||
|
}
|
||
|
targetCount[count] = targetCount[count] +1;
|
||
|
}
|
||
|
count2 = count2 +1;
|
||
|
}
|
||
|
count = count +1;
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
event factoryProdEvnt(factoryProdTrig)
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numFactories)
|
||
|
{
|
||
|
//turn off dead factories
|
||
|
if (structures[factID[count]] == NULLOBJECT)
|
||
|
{
|
||
|
factFlagGo[count] = FALSE;
|
||
|
}
|
||
|
//switched on and not producing anything?
|
||
|
if (factFlagGo[count])
|
||
|
{
|
||
|
if (structureIdle(structures[factID[count]]))
|
||
|
{
|
||
|
//need to update template with technology!
|
||
|
//use min and max to get random build template
|
||
|
temp = random(factTempMax[count] - factTempMin[count]) + factTempMin[count];
|
||
|
temp2 = random(factTempMax[count] - temp) + 1; //build random number (less for better stuff)
|
||
|
buildDroid (templates[temp], structures[factID[count]], structures[factID[count]].player, temp2);
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
event droidBuilt(inactive) //triggered by later callbacks
|
||
|
{
|
||
|
/*
|
||
|
//check for New Truck Built!!!!
|
||
|
if (newDroid.droidType == DROID_CONSTRUCT)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
*/
|
||
|
//find factory number
|
||
|
temp2 = 0; //flagged if group match found
|
||
|
temp = -1; //in case not found
|
||
|
if (newDroidFactory != NULLOBJECT)
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numFactories)
|
||
|
{
|
||
|
if (newDroidFactory == structures[factID[count]])
|
||
|
{
|
||
|
temp = factID[count]; //count; //use factory index, not structure index
|
||
|
}
|
||
|
count = count +1;
|
||
|
}
|
||
|
}
|
||
|
//check thru groups to reinforce
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
if (((temp == grpFactory[count]) or (grpFactory[count] == -1)) //got match, or any factory OK?
|
||
|
and (grpGroup[count].members < grpIdealSize[count])) //and needs reinforcing?
|
||
|
{
|
||
|
//add to reinforcement group
|
||
|
groupAddDroid(grpReinforce[count], newDroid);
|
||
|
//orderGroupLoc(grpReinforce[count], DORDER_MOVE, 8000, 13000); //test for now
|
||
|
|
||
|
//if ideal size, add to main group!
|
||
|
if ((grpGroup[count].members + grpReinforce[count].members) >= grpIdealSize[count])
|
||
|
{
|
||
|
groupAddGroup(grpGroup[count], grpReinforce[count]);
|
||
|
//grpPosCurrent[count] = grpPosMin[count]; //test for now so can see if added to group
|
||
|
}
|
||
|
//if group dead, add to group and reset starting sector?
|
||
|
if (grpGroup[count].members == 0)
|
||
|
{
|
||
|
groupAddGroup(grpGroup[count], grpReinforce[count]);
|
||
|
//set back to start sector...?
|
||
|
grpPosCurrent[count] = grpPosMin[count]; //go back to min sector if starting group from scratch
|
||
|
}
|
||
|
//test order only!!!
|
||
|
//orderGroupLoc(grpGroup[count], DORDER_SCOUT, coordsX[grpPosCurrent[count]], coordsY[grpPosCurrent[count]]);
|
||
|
count = numGroups; //exit early
|
||
|
temp2 = 1;
|
||
|
}
|
||
|
count = count +1;
|
||
|
}
|
||
|
//if temp2 != 0, ie not assigned to a group, put in a special group for that player, and pull out if a group can take from any and
|
||
|
//needs reinforcing. (another event to check thru pooled group?)
|
||
|
//still to be done!
|
||
|
|
||
|
}
|
||
|
|
||
|
//hack to allow CALL_NEWDROID to work with unspecified enemy players!!!!
|
||
|
event droidBuilt1(CALL_NEWDROID, 1, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
event droidBuilt2(CALL_NEWDROID, 2, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
event droidBuilt3(CALL_NEWDROID, 3, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
event droidBuilt4(CALL_NEWDROID, 4, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
event droidBuilt5(CALL_NEWDROID, 5, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
event droidBuilt6(CALL_NEWDROID, 6, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
event droidBuilt7(CALL_NEWDROID, 7, ref newDroid, ref newDroidFactory)
|
||
|
{
|
||
|
setEventTrigger(droidBuilt, droidBuiltTrig);
|
||
|
}
|
||
|
|
||
|
|
||
|
event regionGroupsEvnt(regionGroupsTrig)
|
||
|
{
|
||
|
//check for groups
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
//region triggered? (NOT used if grpType = 1 (DEFENSIVE group). RegionGo defines area to defend instead!)
|
||
|
if ((not grpFlagGo[count]) and (grpType[count] != 1) and (grpRegionGo[count] >= 0))
|
||
|
{
|
||
|
if (droidInArea(grpWhoGo[count],
|
||
|
regionsX1[grpRegionGo[count]], regionsY1[grpRegionGo[count]],
|
||
|
regionsX2[grpRegionGo[count]], regionsY2[grpRegionGo[count]]))
|
||
|
{
|
||
|
grpFlagGo[count] = TRUE;
|
||
|
//scouts and attack forces don't use coords array, so don't bother with initial order!
|
||
|
if (grpType[count] < 2)
|
||
|
{
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, coordsX[grpPosStart[count]], coordsY[grpPosStart[count]]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
//check for factories
|
||
|
count = 0;
|
||
|
while (count < numFactories)
|
||
|
{
|
||
|
//region triggered?
|
||
|
if ((not factFlagGo[count]) and (factRegionGo[count] >= 0))
|
||
|
{
|
||
|
if (droidInArea(player, //assume Player to trigger region, rather than WhoGo[]
|
||
|
regionsX1[factRegionGo[count]], regionsY1[factRegionGo[count]],
|
||
|
regionsX2[factRegionGo[count]], regionsY2[factRegionGo[count]]))
|
||
|
{
|
||
|
factFlagGo[count] = TRUE;
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//update time count for triggering groups and factories...
|
||
|
event timeGroupsEvnt(timeGroupsTrig)
|
||
|
{
|
||
|
timeGroup = timeGroup + 1;
|
||
|
count = 0;
|
||
|
//update groups
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
if ((grpTimeGo[count] == timeGroup) and (not grpFlagGo[count]))
|
||
|
{
|
||
|
grpFlagGo[count] = TRUE;
|
||
|
//scouts don't use coords array, so don't bother with initial order!
|
||
|
if (grpType[count] < 2)
|
||
|
{
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, coordsX[grpPosStart[count]], coordsY[grpPosStart[count]]);
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
//update factories
|
||
|
count = 0;
|
||
|
while (count < numFactories)
|
||
|
{
|
||
|
if ((factTimeGo[count] == timeGroup) and (not factFlagGo[count]))
|
||
|
{
|
||
|
factFlagGo[count] = TRUE; //set factory to produce
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
event enemyBaseHit(CALL_STRUCT_ATTACKED, enemy[enemyCount], ref hitStruc, ref attackerObj)
|
||
|
{
|
||
|
//playSoundPos(attackSnd1, enemy[enemyCount], hitStruc.x, hitStruc.y, hitStruc.z); //quick check
|
||
|
//store attacked structure for repairing by trucks later (when no enemies nearby!)
|
||
|
/* still to be done
|
||
|
if (hitStruc != NULLOBJECT)
|
||
|
{
|
||
|
//store damaged Structure for repair/rebuild later...
|
||
|
temp = 0;
|
||
|
count = 0;
|
||
|
while (count < numDamaged[enemyCount])
|
||
|
{
|
||
|
if
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
if ((attackerObj != NULLOBJECT) and (hitStruc != NULLOBJECT))
|
||
|
{
|
||
|
count = 0;
|
||
|
while (count < numGroups)
|
||
|
{
|
||
|
//check for defense forces that cover this region
|
||
|
//but only if this structure belongs to same player as defensive group
|
||
|
//and isn't already 'busy'
|
||
|
if ((grpType[count] == 1) and (grpPlayer[count] == enemy[enemyCount]) and (not grpBusy[count]))
|
||
|
{
|
||
|
if (grpRegionGo[count] < 0) //cope with no region specified
|
||
|
{
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, attackerObj.x, attackerObj.y);
|
||
|
grpBusy[count] = TRUE;
|
||
|
count = numGroups; //break out of loop, since found
|
||
|
}
|
||
|
else if ((hitStruc.x >= regionsX1[grpRegionGo[count]])
|
||
|
and (hitStruc.x <= regionsX2[grpRegionGo[count]])
|
||
|
and (hitStruc.y >= regionsY1[grpRegionGo[count]])
|
||
|
and (hitStruc.y <= regionsY2[grpRegionGo[count]]))
|
||
|
{
|
||
|
orderGroupLoc(grpGroup[count], DORDER_SCOUT, attackerObj.x, attackerObj.y);
|
||
|
grpBusy[count] = TRUE;
|
||
|
count = numGroups; //break out of loop, since found
|
||
|
}
|
||
|
}
|
||
|
count = count + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//Updates enemyCount for enemyBaseHit event.
|
||
|
event updateEnemy(updateEnemyTrig)
|
||
|
{
|
||
|
/*
|
||
|
enemyCount = enemyCount + 1;
|
||
|
if (enemyCount >= numEnemies)
|
||
|
{
|
||
|
enemyCount = 0;
|
||
|
}
|
||
|
*/
|
||
|
//done this way so never invalid!
|
||
|
if (enemyCount < numEnemies - 1)
|
||
|
{
|
||
|
enemyCount = enemyCount + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
enemyCount = 0;
|
||
|
}
|
||
|
}
|