warzone2100/data/script/fastplay/fastdemo.slo

1148 lines
33 KiB
Plaintext
Raw Normal View History

//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;
}
}