//------------------------------------------------------
// Public variables
//------------------------------------------------------
public STRUCTURESTAT legoSt[11],derrick,powGen,factory,resLab,powModule,facModule,resModule,vtolFactory,
repairFacility,extraStructs[5],defenses[4],structChoice[5],baseStructs[10],vtolPad,vtolDefStruct[5],sens[2],arty[2],wallStruct,defStructs[26];
public FEATURESTAT oilRes;
public INT numLego,player,numTemplates,numExtraStructs,numDefenses,numBaseStructs,numSVtolTemplates,numTVtolTemplates,sPref[6],numVtolDefStr,numDefStructs;
public TEMPLATE tmpl[18],constructor,sVtols[3],tVtols[3];
public WEAPON sVtolWeapon[3],tVtolWeapon[3];
public TEXTSTRING ai_ally_msg[5];
//------------------------------------------------------
// Private variables
//------------------------------------------------------
private GROUP buildGroup,tempGroup,sendAttackGr,attackGroup,scoutGroup[2],oilGr,sVtolGr,tVtolGr,defendGr;
private INT count,count2,result,result2,result3,result4,temp,buildX,buildY,baseX,baseY,tempX,tempY,maxy,maxx,miny,minx,outpostDist;
private INT minAttackH,numRepairing,maxOilGr,attackOilX,attackOilY,scoutX[2],scoutY[2],stuckX,stuckY,stuckTimes,maxTVtols,maxSVtols,maxDefenders;
private DROID droid,tempDroid,outpostDroid;
private BOOL boolResult,boolResult2,haveOutpost,powerSaving,MovingBase;
private FEATURE feature,feature2;
private TEMPLATE tmplChoice[4];
private STRUCTURE structure,structure2;
private BOOL debugMode;
private BASEOBJ baseobj,baseobj2,defendObject,tVtolObject,sVtolObject;
private INT numEnemies,Enemies[8],EnemyX[8],EnemyY[8];
//------------------------------------------------------
// Static private variables
//------------------------------------------------------
private INT mainPhase,curLegoStr,TemplDepth,maxTrucks,numTrucks,curEnemy,curEnemyX,curEnemyY,
attackPhase,maxScouts,extraStruct,curEnEdgeX,curEnEdgeY,KeepDist,numRushers;
//===============================================================================================
//
// Triggers
//
//===============================================================================================
//------------------------------------------------------
// Lego
//------------------------------------------------------
trigger StartGameTr (wait, 5);
trigger LegoBuildTr (every, 10);
//------------------------------------------------------
// Rush
//------------------------------------------------------
trigger RushTr (every, 30);
trigger RushControlTr (every, 80);
//------------------------------------------------------
// Rush preparations
//------------------------------------------------------
trigger BuildAttackForceTr (every, 15);
trigger buildVtolsTr (every, 100); //(every, 40);
trigger doResearchTr (every, 50);
trigger buildDerricksTr (every, 80);
trigger sendScoutsTr (every, 20);
trigger expandBaseTr (every, 150);
trigger buildDefensesTr (every, 400);
trigger buildVtolPadsTr (every, 70);
trigger basedetailsTr (every, 50);
trigger oilDefensesTr (every, 100);
//------------------------------------------------------
// Other
//------------------------------------------------------
trigger droidDestroyedTr (CALL_DROID_DESTROYED, player, ref droid);
trigger nowTr (wait, 0);
trigger keepTrackTr (every, 60);
trigger chooseEnemyTr (every, 70);
trigger LegoTrucksTr (every, 20);
trigger buildPowerGeneratorsTr (every, 60);
trigger droidBuiltTr (CALL_NEWDROID,player, ref droid,ref structure);
trigger difficultyModTr (every, 600);
trigger upgradeStructuresTr (every, 50);
trigger moveIfAttackedTr (CALL_DROID_ATTACKED, player, ref droid, ref baseobj);
trigger BuildOutpostTr (every, 100);
trigger updateDetailsTr (every, 40);
trigger savePowerTr (every, 20);
trigger destroyOilTr (every, 60);
trigger stuckTr (every, 70);
trigger vtolAttackTr (every, 50);
trigger vtolDefendTr (CALL_STRUCT_ATTACKED, player, ref structure, ref baseobj);
trigger defendTr (CALL_ATTACKED, player, ref baseobj, ref baseobj2);
trigger formAllianceEventTr (every, 120);
trigger humanAllianceTr (CALL_ALLIANCEOFFER,ref count, ref count2);
trigger MoveBaseTr (every, 50);
//trigger OrganizeSendsTr (every, 350); //(every, 100);
//===============================================================================================
//
// Events
//
//===============================================================================================
event endPhaseOne;
event initializeRushPrep;
event BuildAttackForce;
event doResearch;
event buildDerricks;
event chooseEnemy;
event RushControl;
event sendScouts;
event expandBase;
event buildDefenses;
event basedetails;
event oilDefenses;
event LegoTrucks;
event stopAttack;
event BuildOutpost;
event updateDetails;
event savePower;
event destroyOil;
event buildVtolPads;
event StartGame;
event defend;
event MoveBase;
event activate;
event deactivate;
//===============================================================================================
//
// [LEGO PHASE]
//
//===============================================================================================
//------------------------------------------------------
// Initialize
//------------------------------------------------------
event StartGame(StartGameTr)
{
//Initialize variables
//--------------------
mainPhase = 0;
curLegoStr = 0;
numTrucks = 0;
maxTrucks = 3;
numRushers = 6;
curEnemy = -1;
curEnemyX = -1;
curEnemyY = -1;
attackPhase = 0;
TemplDepth = 1; //From how many different templates to choose a template randomly, depends on res phase
maxScouts = 0;
extraStruct = 0;
curEnEdgeX = -1;
KeepDist = (20 * 128); //Distance to keep of the enemy base when sending attackGr for regrouping
minAttackH = 65; //Min attack health. Retreat if < minAttackH
numRepairing = 0; //How many attackers are repairing at the moment
haveOutpost = FALSE; //Outpost to retreat to and where to repair damadged units
powerSaving = FALSE; //If we are in power saving mode
MovingBase = FALSE;
maxOilGr = 4; //Number of droids in the oilGr
attackOilX = -1; //Coordinates of enemy derrick
attackOilY = -1; //Coordinates of enemy derrick
maxTVtols = 8; //Max number of antitank VTOLs
maxSVtols = 10; //Max number of antistructure VTOLs
maxDefenders = 0; //Max number of defenders
outpostDist = 0; //Remember the distance between the enemy base and the outpost
scoutX[0] = (4 * 128); //Top left
scoutY[0] = (4 * 128);
scoutX[1] = (4 * 128); //Bottom left
scoutY[1] = (128 * mapHeight) - (4 * 128);
//Prepair features for future use
//-------------------------------
initGetFeature(oilRes,player,player);
//Temp base
//---------
baseX = (128*mapWidth)/2;
baseY = (128*mapHeight)/2;
//Add all droids to a group and sort out constructors
//---------------------------------------------------
groupAddArea(tempGroup, player, 0, 0, (mapWidth*128), (mapHeight*128));
initIterateGroup(tempGroup);
droid = iterateGroup(tempGroup);
while(droid != NULLOBJECT)
{
if(droid.droidType == DROID_CONSTRUCT) //If a constructor
{
baseX = droid.x; //Base coordinates
baseY = droid.y;
droidLeaveGroup(droid);
groupAddDroid(buildGroup,droid);
}
droid = iterateGroup(tempGroup);
}
numTrucks = buildGroup.members;
//Send one truck to build factory
//-------------------------------
boolResult = FALSE;
buildX = baseX;
buildY = baseY;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while((boolResult == FALSE) and (droid != NULLOBJECT))
{
if(droid.order == DORDER_NONE)
{
boolResult2 = pickStructLocation(factory, ref buildX, ref buildY,player);
if(boolResult2 == TRUE)
{
orderDroidStatsLoc(droid, DORDER_BUILD, factory, buildX,buildY);
boolResult = TRUE;
}
}
droid = iterateGroup(buildGroup);
}
}
//------------------------------------------------------
// Build all necessary structures
//------------------------------------------------------
event LegoBuild(LegoBuildTr)
{
//DERRICKS
//--------
initGetFeature(oilRes,player,player);
feature = getFeature(player);
if(feature != NULLOBJECT)
{
buildX = feature.x;
buildY = feature.y;
//If no no trucks already trying to build the same derrick
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
count = 0;
while((droid != NULLOBJECT) and (count == 0))
{
if((droid.orderx == buildX) and (droid.ordery == buildY))
{
count = count + 1; //Count trucks
}
droid = iterateGroup(buildGroup);
}
if(count == 0) //Send only 1 truck to each derrick
{
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
boolResult = FALSE;
while((boolResult == FALSE) and (droid != NULLOBJECT))
{
if(droid.order == DORDER_NONE)
{
orderDroidStatsLoc(droid, DORDER_BUILD,derrick, buildX,buildY);
boolResult = TRUE;
}
droid = iterateGroup(buildGroup);
}
}
}
//STRUCTURES
//----------
if(curLegoStr < numLego)
{
buildX = baseX;
buildY = baseY;
droid = NULLOBJECT;
boolResult = FALSE;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while((droid != NULLOBJECT) and (boolResult == FALSE))
{
if(droid.order == DORDER_NONE)
{
boolResult2 = pickStructLocation(legoSt[curLegoStr], ref buildX, ref buildY,player);
if(boolResult2 == TRUE)
{
tempDroid = droid;
boolResult = TRUE;
}
}
droid = iterateGroup(buildGroup); //Next droid
}
//Find out if a truck is already building on the spot where another truck might try to build and will fail
if(boolResult)
{
//boolResult = TRUE;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while((droid != NULLOBJECT) and (boolResult == TRUE))
{
if(droid != tempDroid)
{
if(droid.order == DORDER_BUILD)
{
if((buildX == droid.orderx) and (buildY == droid.ordery))
{
boolResult = FALSE;
}
}
}
droid = iterateGroup(buildGroup);
}
}
//Build
if(boolResult)
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD,legoSt[curLegoStr], buildX,buildY);
curLegoStr = curLegoStr + 1;
}
}
//End Lego phase, start rush preparations
//---------------------------------------
if(mainPhase == 0) //If not already activated
{
if(curLegoStr == (numLego - 1)) // (numLego - HQ)
{
setEventTrigger(endPhaseOne,nowTr);
}
}
//Now that HQ is built we can deactivate it
//-----------------------------------------
if(curLegoStr == numLego)
{
setEventTrigger(LegoBuild, inactive);
}
}
//------------------------------------------------------
// End Lego phase, start rush preparations
//------------------------------------------------------
event endPhaseOne(inactive)
{
//Start rush preparation phase
//----------------------------
//if(MovingBase)
//{
// setEventTrigger(MoveBase,MoveBaseTr); //Activate MoveBase event again if we have just finished building a new Base after MoveBase
//}
MovingBase = FALSE; //We have a base, no threat exists anymore (after moving base)
setEventTrigger(buildDerricks,buildDerricksTr);
setEventTrigger(initializeRushPrep,nowTr);
setEventTrigger(RushControl,RushControlTr);
setEventTrigger(sendScouts,sendScoutsTr);
setEventTrigger(expandBase,expandBaseTr);
setEventTrigger(buildDefenses,buildDefensesTr);
setEventTrigger(oilDefenses,oilDefensesTr);
setEventTrigger(updateDetails,updateDetailsTr);
setEventTrigger(savePower,savePowerTr);
setEventTrigger(destroyOil,destroyOilTr);
setEventTrigger(buildVtolPads,buildVtolPadsTr);
setEventTrigger(LegoTrucks,inactive);
setEventTrigger(endPhaseOne, inactive);
}
//=============================================================================================
// [RUSH]
//=============================================================================================
//------------------------------------------------------
// Send units to the enemy base
//------------------------------------------------------
event Rush(RushTr)
{
if((sendAttackGr.members + attackGroup.members) > numRushers)
{
if(curEnemy != -1) //We have an enemy and not already on our way
{
if((curEnEdgeX > 0) and (attackPhase == 0))
{
maxTrucks = 9; //Maximum number of the trucks to be built in this phase
maxScouts = 2;
//Add units from defend group to attack group one
//by one to refresh defend group with new templates
//-------------------------------------------------
//if(defendGr.members > (maxDefenders / 2)) //If we have enough defenders
//{
// boolResult = TRUE;
// initIterateGroup(defendGr);
// droid = iterateGroup(defendGr);
// while((droid != NULLOBJECT) and (boolResult))
// {
// if(droid.order == DORDER_NONE)
// {
// droidLeaveGroup(droid);
// groupAddDroid(sendAttackGr,droid);
// boolResult = FALSE; //Stop adding
// }
// droid = iterateGroup(defendGr);
// }
//}
groupAddGroup(sendAttackGr, attackGroup); //From attackGroup to sendAttackGr
setGroupSecondary(sendAttackGr, DSO_HALTTYPE, DSS_HALT_HOLD); //Don't start attacking the base
orderGroupLoc(sendAttackGr, DORDER_MOVE, curEnEdgeX, curEnEdgeY);
attackPhase = 1; //On our way
setEventTrigger(BuildOutpost,BuildOutpostTr); //Start building outpost
setEventTrigger(Rush,inactive);
}
}
}
}
//------------------------------------------------------
// Cancel current attack
//------------------------------------------------------
event stopAttack(inactive)
{
attackPhase = 0;
curEnemy = -1;
curEnEdgeX = -1;
curEnEdgeY = -1;
curEnemyX = -1;
curEnemyY = -1;
setGroupSecondary(attackGroup, DSO_HALTTYPE, DSS_HALT_GUARD);
orderGroupLoc(attackGroup, DORDER_MOVE,attackGroup.x,attackGroup.y); //Collect them a bit
setEventTrigger(Rush,RushTr);
setEventTrigger(stopAttack,inactive);
}
//------------------------------------------------------
// Control the attack
//------------------------------------------------------
event RushControl(inactive)
{
//=====================================================================
// attackPhase explaination:
// 0: idle
// 1: on our way to the enemy 'edge' (waiting for regrouping)
// 2: on our way to the base
// 3: attacking
//=====================================================================
temp = (KeepDist / 2); //Enemy base range
//------------------------
//Stop attack if necessary
//------------------------
if((attackPhase > 0) and (curEnemy != -1)) //If dead
{
//if(not actPlayer[curEnemy])
if(not anyFactoriesLeft(curEnemy))
{
//Retreat if enemy is dead
//------------------------
setEventTrigger(stopAttack,nowTr); //Cancel attack, clear variables
attackPhase = 0;
}
}
//-------------------------------------------------------------
//Add units to attack group after they have reached the outpost
//-------------------------------------------------------------
if(attackPhase > 0) //If on our way to the outpost
{
//Send newly-built units to the edge
//----------------------------------
boolResult = FALSE;
if(((attackGroup.members + sendAttackGr.members) > (numRushers / 2)) and (sendAttackGr.members > 5)) //Check this condition only one time //was 5
{
boolResult = TRUE;
}
initIterateGroup(sendAttackGr);
droid = iterateGroup(sendAttackGr);
while(droid != NULLOBJECT)
{
if(distBetweenTwoPoints(droid.x, droid.y, curEnEdgeX, curEnEdgeY) > temp) //If not in the outpost
{
if(distBetweenTwoPoints(droid.orderx, droid.ordery, curEnEdgeX, curEnEdgeY) > temp) //If not going to the outpost
{
if(boolResult == TRUE) //Condition checked before
{
setDroidSecondary(droid, DSO_HALTTYPE, DSS_HALT_HOLD);
result = (6 * 128);
orderDroidLoc(droid, DORDER_MOVE, curEnEdgeX + random(result) - (result/2), curEnEdgeY + random(result) - (result/2));
}
}
}
else //Add to attackers if reached outpost
{
droidLeaveGroup(droid);
groupAddDroid(attackGroup,droid);
}
droid = iterateGroup(sendAttackGr); //Next droid
}
}
//-----------------------------------------------------------------
//Start attacking enemy base if most of the units are at the 'edge'
//-----------------------------------------------------------------
if(attackPhase == 1) //If on our way to the outpost
{
//Check if we can start our invasion
//----------------------------------
if(attackGroup.members > numRushers) //If we have enough units
{
boolResult = FALSE;
if(numRepairing == 0)
{
if(haveOutpost == TRUE)
{
boolResult = TRUE; //Repair units with light damage
}
}
//Count idle units
//----------------
result = 0;
initIterateGroup(attackGroup);
droid = iterateGroup(attackGroup);
while(droid != NULLOBJECT)
{
if(droid.order != DORDER_MOVE) //Not moving
{
result = result + 1;
//Repair units with light damage
//------------------------------
if((droid.health < 99) and (boolResult == TRUE)) //If it's damaged a bit and can repair
{
orderDroid(droid, DORDER_RTR); //Repair unit
}
}
droid = iterateGroup(attackGroup);
}
boolResult = FALSE;
if(isHumanPlayer(curEnemy)) //Move instead of scout if attacking human
{
boolResult = TRUE;
}
result = (result * 100 / attackGroup.members);
if((result >= 55) or (result >= numRushers)) // > 55% waiting
{
if(((haveOutpost) and (attackGroup.health >= minAttackH)) or (haveOutpost == FALSE))
{
if(numRepairing < (attackGroup.members / 2)) //If not too many attackers repairing
{
//Send to the enemy base
//----------------------
attackPhase = 2;
setGroupSecondary(attackGroup, DSO_HALTTYPE, DSS_HALT_GUARD);
if(boolResult == TRUE) //If human
{
orderGroupLoc(attackGroup, DORDER_MOVE, curEnemyX, curEnemyY);
}
else //AI
{
orderGroupLoc(attackGroup, DORDER_SCOUT, curEnemyX, curEnemyY);
}
}
}
}
}
}
//-------------------------------
//Sending to the enemy base rules
//-------------------------------
if(attackPhase > 1)
{
//If attack failed
if((attackGroup.members < (numRushers * 2 / 3)) or ((haveOutpost) and (attackGroup.health < minAttackH)) or (numRepairing >= (attackGroup.members / 2))) //If not enough units available
{
attackPhase = 1;
setGroupSecondary(attackGroup, DSO_HALTTYPE, DSS_HALT_GUARD);
orderGroupLoc(attackGroup, DORDER_MOVE, curEnEdgeX, curEnEdgeY); //Retreat
numRushers = numRushers + 2; //Increase number of attackers
if(numRushers > 20)
{
//numRushers = 38;
//if(not isHumanPlayer(curEnemy))
//{
numRushers = 20;
//}
}
}
else //If enough units available
{
boolResult = FALSE;
if(isHumanPlayer(curEnemy)) //Move instead of scout if attacking human
{
boolResult = TRUE;
}
//Send newly-built units to attack
//--------------------------------
initIterateGroup(attackGroup);
droid = iterateGroup(attackGroup);
while(droid != NULLOBJECT)
{
if(distBetweenTwoPoints(droid.x, droid.y, curEnemyX, curEnemyY) > temp + (3 * 128)) //If not there
{
if((droid.order == DORDER_NONE) or ((droid.orderx != curEnemyX) and (droid.ordery != curEnemyY))) //Not moving
{
setDroidSecondary(droid, DSO_HALTTYPE, DSS_HALT_GUARD);
if(boolResult == TRUE) //Human
{
orderDroidLoc(droid, DORDER_MOVE, curEnemyX, curEnemyY);
}
else //AI
{
orderDroidLoc(droid, DORDER_SCOUT, curEnemyX, curEnemyY);
}
}
}
else //If there
{
attackPhase = 3;
setDroidSecondary(droid,DSO_HALTTYPE, DSS_HALT_PERSUE); //Persue. For more efficient structure targeting.
}
droid = iterateGroup(attackGroup); //Next droid
}
}
}
//------------
//Attack rules
//------------
if(attackPhase == 3) //If attacking
{
//They are repairing bunker we attack! Eliminate the truck
//--------------------------------------------------------
result = (13 * 128);
boolResult = FALSE;
resetDroidTargets();
setDroidTarPref(DT_CONSTRUCT);
tempDroid = droidTargetInArea(curEnemy, player, curEnemyX - result, curEnemyY - result, curEnemyX + result, curEnemyY + result);
if(tempDroid != NULLOBJECT)
{
if(tempDroid.droidType == DROID_CONSTRUCT)
{
//Order droid close to the truck to attack it
//-------------------------------------------
boolResult = TRUE;
initIterateGroup(attackGroup);
droid = iterateGroup(attackGroup);
while(droid != NULLOBJECT)
{
if(distBetweenTwoPoints(droid.x, droid.y, tempDroid.x, tempDroid.y) < result)
{
orderDroidObj(droid, DORDER_ATTACK,tempDroid);
//setFogColour(1, random(200) + 55, 1);
//attackObject = tempDroid;
}
droid = iterateGroup(attackGroup);
}
}
}
if(boolResult == FALSE) //Factories
{
resetStructTargets();
setStructTarPref(ST_FACTORY);
structure = structTargetInArea(curEnemy, player, curEnemyX - result, curEnemyY - result, curEnemyX + result, curEnemyY + result);
if(structure != NULLOBJECT)
{
//Order droid close to the factory to attack it
initIterateGroup(attackGroup);
droid = iterateGroup(attackGroup);
while(droid != NULLOBJECT)
{
if(distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < result)
{
orderDroidObj(droid, DORDER_ATTACK,structure);
//setFogColour(1, 1, random(200) + 55);
//attackObject = structure;
}
droid = iterateGroup(attackGroup);
}
}
}
}
//--------------------------------------------------------
//Allow repairing if we have repair facilities in outposts
//--------------------------------------------------------
if(haveOutpost)
{
setGroupSecondary(attackGroup, DSO_REPAIR_LEVEL, DSS_REPLEV_HIGH);
}
else
{
setGroupSecondary(attackGroup, DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER);
}
}
//-------------------------------------------------------------------
//Make attack units on their way to outpost stay closer to each other
//(don't let them go one by one)
//-------------------------------------------------------------------
//event OrganizeSends(OrganizeSendsTr)
//{
// if((sendAttackGr.members > 1) and (attackPhase > 0)) //If enough units and already started sending to the edge (don't regroup in the base, could dtuck)
// {
// orderGroupLoc(sendAttackGr, DORDER_MOVE, sendAttackGr.x, sendAttackGr.y); //Stay together
// setFogColour(1, 1, random(255));
// }
//}
//------------------------------------------------------
//Destroy enemy derricks
//------------------------------------------------------
event destroyOil(inactive)
{
if(idleGroup(oilGr) > (oilGr.members / 2))
{
if(oilGr.members >= maxOilGr)
{
boolResult = FALSE;
if(attackOilX > 0)
{
temp = (4 * 128);
count = 0;
while((count < numEnemies) and (boolResult == FALSE))
{
boolResult = structInArea(Enemies[count], attackOilX - temp, attackOilY - temp, attackOilX + temp, attackOilY + temp);
count = count + 1;
}
}
//Find new derrick
if(boolResult == FALSE) //No structures found in the area
{
//Find closest enemy derrick
//--------------------------
result = 999999;
structure2 = NULLOBJECT;
count = 0;
while(count < numEnemies)
{
initEnumStruct(FALSE,derrick,Enemies[count],Enemies[count]);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if(EnemyX[count] > 0)
{
if(distBetweenTwoPoints(structure.x, structure.y, EnemyX[count], EnemyY[count]) > (14 * 128)) //Not in the base
{
result2 = distBetweenTwoPoints(baseX, baseY, structure.x,structure.y);
if(result2 < result)
{
result = result2;
structure2 = structure;
}
}
}
structure = enumStruct();
}
count = count + 1;
}
//Assign to the found object
//--------------------------
if(structure2 != NULLOBJECT)
{
attackOilX = structure2.x;
attackOilY = structure2.y;
boolResult = TRUE;
}
}
if(boolResult == TRUE)
{
orderGroupLoc(oilGr, DORDER_MOVE, attackOilX, attackOilY);
}
}
}
}
//------------------------------------------------------
// Find most suitabe enemy
//------------------------------------------------------
event chooseEnemy(chooseEnemyTr)
{
//if((curEnemy == -1) and (numEnemies > 0))
if(numEnemies > 0)
{
if((sendAttackGr.members + attackGroup.members) > numRushers)
{
temp = -1; //Temp enemy
count = 0;
result = 999999;
while(count < numEnemies)
{
if((isHumanPlayer(Enemies[count])) and (EnemyX[count] > 0))
{
result2 = distBetweenTwoPoints(baseX, baseY, EnemyX[count], EnemyY[count]);
if(result2 < result)
{
result = result2;
temp = Enemies[count];
}
}
count = count + 1;
}
//If no human players, find the closest AI
if(temp == -1)
{
result = 999999;
count = 0;
while(count < numEnemies)
{
if(EnemyX[count] > 0)
{
result2 = distBetweenTwoPoints(baseX, baseY, EnemyX[count], EnemyY[count]);
if(result2 < result)
{
result = result2;
temp = Enemies[count];
}
}
count = count + 1;
}
}
//Remember 'best' enemy
curEnemy = temp;
}
}
//Find bases again even if (curEnemy != -1) so that attackers could find next factory if its far away
//---------------------------------------------------------------------------------------------------
count = 0;
while(count < numEnemies)
{
//-----------------------
// Find enemy's base
//-----------------------
tempX = baseX;
tempY = baseY;
//Store enemy base coords, find closest structure
//-----------------------------------------------
EnemyX[count] = -1;
EnemyY[count] = -1;
result = 99999;
count2 = 0;
while(count2 < numBaseStructs) //For all base structures
{
initEnumStruct(FALSE,baseStructs[count2],Enemies[count],Enemies[count]);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if(structureComplete(structure))
{
result2 = distBetweenTwoPoints(tempX, tempY, structure.x, structure.y);
if(result2 < result)
{
result = result2;
EnemyX[count] = structure.x;
EnemyY[count] = structure.y;
}
}
structure = enumStruct();
}
count2 = count2 + 1;
}
//Remember coordinates of the enemy
//---------------------------------
if(Enemies[count] == curEnemy)
{
if((EnemyX[count] != -1) and (EnemyY[count] != -1))
{
curEnemyX = EnemyX[count];
curEnemyY = EnemyY[count];
}
result = distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, curEnemyX, curEnemyY); //If base moved too much
if((curEnEdgeX == -1) or ((result + (6 * 128)) < outpostDist) or ((result - (6 * 128)) > outpostDist) )
{
//Find 'edge' of the base
//-----------------------
curEnEdgeX = -1;
curEnEdgeY = -1;
result = 99999;
count2 = 0;
tempX = baseX;
tempY = baseY;
curEnEdgeX = curEnemyX;
curEnEdgeY = curEnemyY;
//Calculate destination point of the attack group for regrouping
//--------------------------------------------------------------
if(curEnEdgeX != -1)
{
result = KeepDist;
result2 = KeepDist;
if(curEnEdgeX > maxx)
{
result = result * (-1);
}
else if(curEnEdgeX > minx) //Almost on the same X level
{
result = 0;
}
if(curEnEdgeY > maxy)
{
result2 = result2 * (-1);
}
else if(curEnEdgeY > miny) //Almost on the same Y level
{
result2 = 0;
}
/*
if(tempX < curEnEdgeX)
{
result = result * (-1);
}
if(tempY < curEnEdgeY)
{
result2 = result2 * (-1);
}
*/
curEnEdgeX = curEnEdgeX + result;
curEnEdgeY = curEnEdgeY + result2;
//Check limits
if(curEnEdgeX < 0)
{
curEnEdgeX = (4 * 128);
}
if(curEnEdgeY < 0)
{
curEnEdgeY = (4 * 128);
}
if(curEnEdgeX > (128 * mapWidth))
{
curEnEdgeX = ((128 * mapWidth) - (4 * 128));
}
if(curEnEdgeY > (128 * mapHeight))
{
curEnEdgeY = ((128*mapHeight) - (4 * 128));
}
outpostDist = distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, curEnemyX, curEnemyY);
boolResult = pickStructLocation(factory, ref curEnEdgeX, ref curEnEdgeY,player);
if(boolResult == FALSE)
{
curEnEdgeX = -1;
curEnEdgeY = -1;
}
}
}
}
count = count + 1;
}
}
//==============================================================================================
//
// [RUSH PREPARATION]
//
//==============================================================================================
//------------------------------------------------------
// Initialize rush preparation phase.
//------------------------------------------------------
event initializeRushPrep(inactive)
{
mainPhase = 1; //Next phase became active
}
//------------------------------------------------------
// Build attack units
//------------------------------------------------------
event BuildAttackForce(BuildAttackForceTr)
{
//Manage truck production
//-----------------------
result2 = 0; //Number of trucks we started building (don't build too many at one time since we can't count how many of them will get built)
temp = 2; //How many trucks to build at a time
if(buildGroup.members == 0)
{
temp = 4; //Build more trucks at a time
}
//Build units
//-----------
initEnumStruct(FALSE,factory,player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if((structureIdle(structure) == TRUE) and (structureComplete(structure)))
{
//Fill array with best templates
count = numTemplates - 1;
count2 = 0;
while((count2 < TemplDepth) and (count >= 0))
{
if(skCanBuildTemplate(player,structure, tmpl[count]))
{
tmplChoice[count2] = tmpl[count];
count2 = count2 + 1;
if(count > 8) //If we have Trck Python HC
{
mainPhase = 2;
}
if(count > 10) //If we have all templates available
{
TemplDepth = 3; //Allow more different units
}
}
count = count - 1;
}
//We have not enough trucks
if((numTrucks < maxTrucks) and (result2 < temp)) //Only <temp> trucks at a time
{
buildDroid(constructor, structure, player, 1); //Normal one
result2 = result2 + 1; //Count trucks
}
else if(count2 > 0) //Any templates found
{
if(getDroidCount(player) < 85) //Let it build VTOLs and trucks
{
buildDroid(tmplChoice[random(count2)],structure,player,1);
}
}
}
structure = enumStruct();
}
}
//------------------------------------------------------
// Research Stuff
//------------------------------------------------------
event doResearch(doResearchTr)
{
//Count how many are already researching
//--------------------------------------
initEnumStruct(FALSE,resLab,player,player);
structure = enumStruct();
result = 0;
while(structure != NULLOBJECT)
{
if(not structureIdle(structure)) //Max 3 res fac if low on power
{
result = result + 1;
}
structure = enumStruct();
}
//Research
//--------
initEnumStruct(FALSE,resLab,player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if((not powerSaving) or (powerSaving and (result < 2))) //Max 2 res fac if low on power
{
if(not ((mainPhase == 2) and (result >= 3))) //If we already have Trck Python HC template then don't use more then 3 res fac
{
skDoResearch(structure,player,0);
result = result + 1;
}
}
structure = enumStruct();
}
}
//------------------------------------------------------
// Build derricks with nearest truck
//------------------------------------------------------
event buildDerricks(inactive)
{
//''DERRICKS''
initGetFeature(oilRes,player,player);
feature = getFeature(player);
while(feature != NULLOBJECT)
{
buildX = feature.x;
buildY = feature.y;
//If no trucks already trying to build the same derrick
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
result = 0;
while((droid != NULLOBJECT) and (result == 0))
{
if(droid.order == DORDER_BUILD)
{
if((droid.orderx == buildX) and (droid.ordery == buildY))
{
result = result + 1; //Count trucks
}
}
droid = iterateGroup(buildGroup);
}
//Check if there are any enemy defenses near oil
//----------------------------------------------
count = 0;
structure = NULLOBJECT;
boolResult = TRUE;
while((count < numEnemies) and (boolResult)) //While no dangerous structures found
{
count2 = 0;
while((count2 < numDefStructs) and (boolResult)) //Check all defensive structures
{
structure = structureBuiltInRange(defStructs[count2], buildX, buildX,(6*128), Enemies[count]);
if(structure != NULLOBJECT) //If found a defense
{
boolResult = FALSE; //Found defenses
}
count2 = count2 + 1;
}
count = count + 1;
}
if((result == 0) and (boolResult)) //If no trucks already building it and no enemy defenses near it
{
result = 999999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT) //Find truck who is near the oil resource
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
//Build it!
if(tempDroid != NULLOBJECT)
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD,derrick, buildX,buildY);
}
}
feature = getFeature(player);
}
}
//------------------------------------------------------
// Send scouts to look for oil resources
//------------------------------------------------------
event sendScouts(inactive)
{
count = 0;
while(count < maxScouts)
{
if(scoutGroup[count].members > 0)
{
if(idleGroup(scoutGroup[count]) > (scoutGroup[count].members /2))
{
temp = (random(20) * 128) + (20 * 128); //Step
//From left top to the bottom
if(count == 0)
{
scoutY[count] = scoutY[count] + temp; //Move down
if(scoutY[count] > (128 * mapHeight)) //If reached bottom
{
scoutY[count] = (128 * mapHeight) - (4 * 128);
scoutX[count] = scoutX[count] + temp; //Move right
}
if(scoutX[count] > (mapWidth * 128)) //If reached right border
{
scoutX[count] = (4 * 128); //Start from the left
}
}
else //From bottom the left to the right
{
scoutX[count] = scoutX[count] + temp; //Move right
if(scoutX[count] > (mapWidth * 128)) //If reached right border
{
scoutX[count] = (4 * 128); //Start from left
scoutY[count] = scoutY[count] - temp; //Move line up
}
if(scoutY[count] < 1) //If reached top
{
scoutY[count] = (128 * mapHeight) - (4 * 128); //Start from bottom
}
}
//Send to scout
tempX = scoutX[count];
tempY = scoutY[count];
boolResult = pickStructLocation(vtolPad, ref tempX, ref tempY,player);
if(boolResult == TRUE)
{
orderGroupLoc(scoutGroup[count], DORDER_MOVE, tempX, tempY);
}
}
}
count = count + 1;
}
}
//------------------------------------------------------
// Build base
//------------------------------------------------------
event expandBase(inactive)
{
//if(not powerSaving)
//{
if(extraStruct == numExtraStructs) // loop round
{
extraStruct = 0;
}
//We have all vital structures, expand the base
//---------------------------------------------
boolResult = FALSE;
if(isStructureAvailable(extraStructs[extraStruct],player))
{
buildX = baseX;
buildY = baseY;
boolResult2 = pickStructLocation(extraStructs[extraStruct], ref buildX, ref buildY,player);
if(boolResult2 == TRUE)
{
boolResult = TRUE;
}
}
if(boolResult == TRUE)
{
result = 99999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
if(tempDroid != NULLOBJECT)
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD,extraStructs[extraStruct], buildX,buildY);
}
}
extraStruct = extraStruct + 1; //Next structure
//}
}
//------------------------------------------------------
// Build base defenses
//------------------------------------------------------
event buildDefenses(inactive)
{
if(not powerSaving)
{
count = numDefenses - 1;
count2 = 0;
boolResult = TRUE;
while((boolResult == TRUE) and (count >= 0))
{
if(isStructureAvailable(defenses[count],player))
{
structChoice[0] = defenses[count];
boolResult = FALSE;
}
count = count - 1;
}
if(boolResult == FALSE)
{
buildX = baseX;
buildY = baseY;
boolResult2 = pickStructLocation(powGen, ref buildX, ref buildY,player);
if(boolResult2 == TRUE)
{
result = 999999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT) //Find truck who is near the oil resource
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
if(tempDroid != NULLOBJECT)
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD,structChoice[0], buildX,buildY);
}
}
}
}
}
//------------------------------------------------------
// Build oil defenses
//------------------------------------------------------
event oilDefenses(inactive)
{
if(not powerSaving)
{
temp = (4 * 128); //Defenses range
result = 99999;
boolResult = TRUE;
structure2 = NULLOBJECT;
initEnumStruct(FALSE,derrick,player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
result2 = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y);
if(result2 < result)
{
boolResult = TRUE;
//If not within a base
//--------------------
if((structure.x > minx) and (structure.y > miny) and (structure.x < maxx) and (structure.y <maxy))
{
boolResult = FALSE;
}
//If not to many defenses already
//-------------------------------
if(boolResult == TRUE)
{
if(numStructsInArea(player, structure.x - temp, structure.y - temp, structure.x + temp, structure.y + temp) > 3)
{
boolResult = FALSE;
}
}
//Choose best defense
//-------------------
if(boolResult == TRUE)
{
count = numDefenses - 1;
boolResult = FALSE;
while((count >= 0) and (boolResult == FALSE))
{
if(isStructureAvailable(defenses[count], player))
{
structChoice[0] = defenses[count];
boolResult = TRUE; //Stop
}
count = count - 1;
}
}
if(boolResult == TRUE)
{
//If we have a derrick to defend
//------------------------------
boolResult = FALSE;
result3 = 99999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_NONE)
{
result4 = distBetweenTwoPoints(structure.x, structure.y, droid.x, droid.y);
if(result4 < result3)
{
boolResult = TRUE;
result3 = result4;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
}
//If we have a droid
//------------------
if(boolResult == TRUE)
{
buildX = structure.x;
buildY = structure.y;
boolResult = pickStructLocation(structChoice[0], ref buildX, ref buildY,player);
if(boolResult == TRUE)
{
boolResult = FALSE;
if((buildX > structure.x - temp) and (buildY > structure.y - temp) and (buildX < structure.x + temp) and (buildY < structure.y + temp)) //If in the range
{
boolResult = TRUE;
}
}
}
if(boolResult == TRUE)
{
result = result2;
structure2 = structure;
}
}
structure = enumStruct();
}
//If we can build it now
//----------------------
if((structure2 != NULLOBJECT) and (tempDroid != NULLOBJECT))
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
}
}
}
//------------------------------------------------------
// Keep details about the size and position of the
// ai players base
//------------------------------------------------------
event basedetails(basedetailsTr)
{
// clear old extremities
//----------------------
temp = (3 * 128);
maxy = baseY + temp;
maxx = baseX + temp;
miny = baseY - temp;
minx = baseX - temp;
//Now find the extremities of our vital structures
//------------------------------------------------
count = 0;
while(count < numBaseStructs)
{
initEnumStruct(FALSE,baseStructs[count],player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if(distBetweenTwoPoints(baseX, baseY, structure.x, structure.y) < (15 * 128)) //If not too far away from the base (usefull when just moved base)
{
if(structure.x < minx)
{
minx = structure.x - 384;
}
if(structure.x > maxx)
{
maxx = structure.x + 384;
}
if(structure.y < miny)
{
miny = structure.y - 384;
}
if(structure.y > maxy)
{
maxy = structure.y + 384;
}
}
structure = enumStruct();
}
count = count + 1;
}
}
//==============================================================================================
//
// [Other stuff important for all phases]
//
//==============================================================================================
//------------------------------------------------------
// Keep track on the other players
//------------------------------------------------------
event keepTrack(keepTrackTr)
{
numEnemies = 0;
count = 0;
while(count < 8)
{
if(count != player) //Not me
{
//allyPlayer[count] = FALSE;
//actPlayer[count] = FALSE;
//Not Dead
if(anyFactoriesLeft(count))
{
//actPlayer[count] = TRUE;
//Not enemy
//if(allianceExistsBetween(player,count))
//{
// allyPlayer[count] = TRUE; //FALSE;
//}
if(not allianceExistsBetween(player,count)) //Enemy
{
//Find enemy's base by finding its base structures
Enemies[numEnemies] = count; //Remember all enemies
numEnemies = numEnemies + 1;
}
}
}
count = count + 1;
}
}
//------------------------------------------------------
// Deal with a droid being destroyed
//------------------------------------------------------
event droidDestroyed(droidDestroyedTr)
{
if(droid.droidType == DROID_CONSTRUCT)
{
numTrucks = numTrucks - 1;
}
}
//------------------------------------------------------
// Build a power gen for every 4 derricks
//------------------------------------------------------
event buildPowerGenerators(buildPowerGeneratorsTr)
{
count = 0;
initEnumStruct(FALSE,derrick,player,player); // count = numderricks
structure = enumStruct();
while(structure != NULLOBJECT)
{
count = count + 1;
structure = enumStruct();
}
count2 = 0;
initEnumStruct(FALSE,powGen,player,player); // count2 = numpowgens
structure= enumStruct();
while(structure != NULLOBJECT)
{
count2 = count2 + 1;
structure= enumStruct();
}
if((count2 * 4) < count) // if we need powergen
{
buildX = baseX; // try build powergen
buildY = baseY;
boolResult = pickStructLocation(powGen, ref buildX, ref buildY,player);
if(boolResult == TRUE)
{
result = 999999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT) //Find truck who is near the oil resource
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
if(tempDroid != NULLOBJECT)
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD,powGen, buildX,buildY);
}
}
}
}
//------------------------------------------------------
// Build trucks if necessary
//------------------------------------------------------
event LegoTrucks(LegoTrucksTr)
{
initEnumStruct(FALSE,factory,player,player);
structure = enumStruct();
if((structure != NULLOBJECT) and (numTrucks < maxTrucks))
{
if(structureIdle(structure))
{
buildDroid(constructor, structure, player, 1);
numTrucks = numTrucks + 1;
}
}
}
//------------------------------------------------------
// Deal with a droid being built
//------------------------------------------------------
event droidBuilt(droidBuiltTr)
{
if(droid.droidType == DROID_CONSTRUCT) // if constructor droid
{
groupAddDroid(buildGroup, droid);
numTrucks = numTrucks + 1;
}
else
{
setDroidSecondary(droid, DSO_ATTACK_RANGE, DSS_ARANGE_LONG);
if(isVtol(droid))
{
orderDroid(droid, DORDER_RTB); //Move away
//Cheak weapon
count = 0;
boolResult = FALSE;
while((count < numSVtolTemplates) and (boolResult == FALSE))
{
if(droid.weapon == sVtolWeapon[count])
{
boolResult = TRUE;
groupAddDroid(sVtolGr, droid); //Antistructure
}
count = count + 1;
}
//Antitank
if(boolResult == FALSE)
{
groupAddDroid(tVtolGr, droid);
}
}
else
{
//Scouts
count = 0;
boolResult = TRUE;
while((count < maxScouts) and (boolResult))
{
if(scoutGroup[count].members == 0)
{
groupAddDroid(scoutGroup[count], droid);
boolResult = FALSE;
}
count = count + 1;
}
//Defenders
if(boolResult and (attackGroup.members > numRushers))
{
if(defendGr.members < maxDefenders)
{
if(mainPhase > 0)
{
groupAddDroid(defendGr, droid);
boolResult = FALSE;
}
}
//If we have enough defenders, refresh defendGr with newest units, pick a random units and remove it from defendGr
//---------------------------------
if( (defendGr.members > 3) and (defendGr.members > (maxDefenders / 2))) //If we have enough defenders
{
randomiseSeed();
count = random(defendGr.members); //Stop at random unit
count2 = 0;
initIterateGroup(defendGr);
droid = iterateGroup(defendGr);
while((count2 < defendGr.members) and (droid != NULLOBJECT))
{
if(count2 == count) //If we found the random unit we were looking for
{
droidLeaveGroup(droid); //Leave defendGr
groupAddDroid(sendAttackGr,droid); //Add to sendAttackGr
count2 = defendGr.members; //Break loop
//setFogColour(1, random(200) + 55, 1);
}
count2 = count2 + 1;
droid = iterateGroup(defendGr); //Next droid
}
}
}
//Oil
if(boolResult and (attackGroup.members > numRushers))
{
if(oilGr.members < maxOilGr)
{
groupAddDroid(oilGr, droid);
boolResult = FALSE;
}
}
//Attackers
if(boolResult)
{
groupAddDroid(sendAttackGr, droid);
}
//Increase number of defenders
if(attackGroup.members > numRushers)
{
//if((defendGr.members >= maxDefenders) and (maxDefenders < 10))
if(maxDefenders < 10)
{
maxDefenders = maxDefenders + 1;
}
}
}
}
}
//------------------------------------------------------
// Cheat a bit, like Pumpkin AI, not more
//------------------------------------------------------
event difficultyMod(difficultyModTr)
{
skDifficultyModifier(player);
}
//------------------------------------------------------
// Upgrade structures
//------------------------------------------------------
event upgradeStructures(upgradeStructuresTr)
{
//Find closest truck
//-------------------
tempX = baseX;
tempY = baseY;
result = 999999;
tempDroid = NULLOBJECT;
boolResult = TRUE;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(tempX, tempY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
//------------------
// Factory
//-----------------
initEnumStruct(FALSE,factory,player,player);
structure= enumStruct();
while(structure != NULLOBJECT)
{
if(isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 2 ))
{
if(tempDroid != NULLOBJECT)
{
boolResult = FALSE;
orderDroidStatsLoc(tempDroid, DORDER_BUILD,facModule, structure.x,structure.y);
}
}
structure= enumStruct();
}
//------------------
// Powergen
//------------------
initEnumStruct(FALSE,powGen,player,player);
structure= enumStruct();
while(structure != NULLOBJECT)
{
// If upgrade is available and struct is not upgraded
//------------------------------------------------------
if(isStructureAvailable(powModule,player) and (not testStructureModule(player, structure, 0)))
{
// Build it
//----------------
if((tempDroid != NULLOBJECT) and (boolResult == TRUE))
{
boolResult = FALSE;
orderDroidStatsLoc(tempDroid,DORDER_BUILD,powModule, structure.x,structure.y); //Upgrade it.
}
}
structure= enumStruct();
}
//-----------------
// Research
//-----------------
if(not powerSaving)
{
initEnumStruct(FALSE,resLab,player,player);
structure= enumStruct();
while(structure != NULLOBJECT)
{
if( isStructureAvailable(resModule,player) and (not testStructureModule(player, structure, 0)))
{
if((tempDroid != NULLOBJECT) and (boolResult == TRUE))
{
boolResult = FALSE;
orderDroidStatsLoc(tempDroid, DORDER_BUILD,resModule, structure.x,structure.y);
}
}
structure= enumStruct();
}
//-------------------
// VTOL Factory
//-------------------
initEnumStruct(FALSE,vtolFactory,player,player);
structure= enumStruct();
while(structure != NULLOBJECT)
{
if(isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 2 ))
{
if((tempDroid != NULLOBJECT) and (boolResult == TRUE))
{
boolResult = FALSE;
orderDroidStatsLoc(tempDroid, DORDER_BUILD,facModule, structure.x,structure.y);
}
}
structure = enumStruct();
}
}
}
//------------------------------------------------------
// Run for a bit when attacked
//------------------------------------------------------
event moveIfAttacked(moveIfAttackedTr)
{
//If unit is still alive and is still under attack
if((droid != NULLOBJECT) and (baseobj != NULLOBJECT))
{
//If during the attack
if(attackPhase >= 2)
{
if(groupMember(attackGroup, droid))
{
if(distBetweenTwoPoints(curEnemyX, curEnemyY, baseobj.x, baseobj.y) < (KeepDist / 2))
{
orderDroidLoc(droid, DORDER_MOVE, curEnEdgeX, curEnEdgeY); //Retreat
}
}
}
if(droid.order == DORDER_NONE)
{
temp = (3 * 128);
temp = random(temp * 2) - temp;
orderDroidLoc(droid, DORDER_MOVE, droid.x + temp, droid.y + temp);
}
}
}
//---------------------------------------------------------------
// Build an outpost to retreat to and to repair damaged units
//---------------------------------------------------------------
event BuildOutpost(inactive)
{
//Find trucks to build the outpost
//--------------------------------
count2 = (KeepDist / 2);
//Reduce number of defenses temporary if low on power
temp = 6;
if(powerSaving)
{
temp = 2;
}
if(outpostDroid == NULLOBJECT)
{
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while((droid != NULLOBJECT) and (outpostDroid == NULLOBJECT))
{
if(droid.order == DORDER_NONE)
{
droidLeaveGroup(droid);
outpostDroid = droid;
orderDroidLoc(outpostDroid, DORDER_MOVE, curEnEdgeX, curEnEdgeY);
}
droid = iterateGroup(buildGroup);
}
}
//--------------------------------------------------------
//Check if we have all necessary structures in the outpost
//--------------------------------------------------------
if((outpostDroid != NULLOBJECT) and (curEnEdgeX > 0)) //If we have trucks and outpost coords
{
boolResult = TRUE;
//-------------------------
//Remove old rep facilities
//-------------------------
initEnumStruct(FALSE,repairFacility,player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
//Demolish if outside of the new edge
if(distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, structure.x, structure.y) > count2)
{
if((outpostDroid.order == DORDER_NONE) or (outpostDroid.order == DORDER_MOVE)) //Not busy
{
orderDroidObj(outpostDroid, DORDER_DEMOLISH, structure);
}
}
structure = enumStruct();
}
//-----------------------
//Check repair facilities
//-----------------------
result = numStructsByTypeInArea(player, REF_REPAIR_FACILITY, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2);
if(result == 0) //We need repair facilities
{
boolResult = FALSE; //Not done building outpost yet
buildX = curEnEdgeX; //Outpost coords = build coords
buildY = curEnEdgeY;
boolResult2 = pickStructLocation(repairFacility, ref buildX, ref buildY, player);
if(boolResult2 == TRUE) //If we can build
{
//Not outside of the outpost
//--------------------------
if(distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, buildX, buildY) < count2)
{
if((outpostDroid.order == DORDER_NONE) or (outpostDroid.order == DORDER_MOVE)) //Not busy
{
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, repairFacility, buildX,buildY);
}
}
}
}
//---------------------------------------------------
//Build some defenses in the outpost if we are idling
//---------------------------------------------------
if(outpostDroid.order == DORDER_NONE) //Not busy
{
//Count defenses
//--------------
result = 0;
count = 0;
while(count < numDefenses)
{
initEnumStruct(FALSE,defenses[count],player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if(distBetweenTwoPoints(structure.x, structure.y, curEnEdgeX, curEnEdgeY) < count2) //In the outpost
{
result = result + 1;
}
structure = enumStruct();
}
count = count + 1;
}
//if(numStructsInArea(player, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2) < count)
if(result < temp)
{
//Choose best defense
//-------------------
count = numDefenses - 1;
boolResult = FALSE;
while((count >= 0) and (boolResult == FALSE))
{
if(isStructureAvailable(defenses[count], player))
{
structChoice[0] = defenses[count];
boolResult = TRUE; //Stop
}
count = count - 1;
}
if(boolResult == TRUE) //If we have a defense we can build
{
buildX = curEnEdgeX;
buildY = curEnEdgeY;
boolResult = pickStructLocation(powGen, ref buildX, ref buildY, player);
if(boolResult == TRUE)
{
if(distBetweenTwoPoints(buildX, buildY, curEnEdgeX, curEnEdgeY) < count2)
{
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
}
}
}
}
}
//---------------
//Build some arty
//---------------
if(outpostDroid.order == DORDER_NONE)
{
//Arty
if(numStructsByTypeInArea(player, REF_DEFENSE, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2) < (temp + 6)) //Max 5 arty def
{
//Check if we have arty tech available
count = 1;
boolResult = FALSE;
while((count >= 0) and (boolResult == FALSE))
{
if(isStructureAvailable(arty[count], player))
{
structChoice[0] = arty[count];
boolResult = TRUE; //Stop
}
count = count - 1;
}
if(boolResult == TRUE) //If we have arty tech
{
buildX = curEnEdgeX;
buildY = curEnEdgeY;
boolResult = pickStructLocation(powGen, ref buildX, ref buildY, player);
if(boolResult == TRUE)
{
if(distBetweenTwoPoints(buildX, buildY, curEnEdgeX, curEnEdgeY) < count2)
{
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
}
}
}
}
//-------
//Sensors
//-------
//Count sensors
//-------------
result = 0;
count = 0;
while(count < 2)
{
initEnumStruct(FALSE,sens[count],player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if(distBetweenTwoPoints(structure.x, structure.y, curEnEdgeX, curEnEdgeY) < count2) //In the outpost
{
result = result + 1;
}
structure = enumStruct();
}
count = count + 1;
}
if(result == 0)
{
//Check if we have sensor tech available
count = 1;
boolResult = FALSE;
while((count >= 0) and (boolResult == FALSE))
{
if(isStructureAvailable(sens[count], player))
{
structChoice[0] = sens[count];
boolResult = TRUE; //Stop
}
count = count - 1;
}
if(boolResult == TRUE) //If we have sensor tech available
{
buildX = curEnEdgeX;
buildY = curEnEdgeY;
boolResult = pickStructLocation(powGen, ref buildX, ref buildY, player);
if(boolResult == TRUE)
{
if(distBetweenTwoPoints(buildX, buildY, curEnEdgeX, curEnEdgeY) < count2)
{
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
}
}
}
}
}
}
}
//-------------------------------------------------------------
// Check for some important details we need for the script
//-------------------------------------------------------------
event updateDetails(inactive)
{
//----------------------------------------------------
//Count how many attackers are repairing at the moment
//----------------------------------------------------
numRepairing = 0;
initIterateGroup(attackGroup);
droid = iterateGroup(attackGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_RTR)
{
numRepairing = numRepairing + 1;
}
droid = iterateGroup(attackGroup);
}
//------------------------------------------
//Check if we have an outpost and can repair
//------------------------------------------
haveOutpost = FALSE;
if(curEnEdgeX > 0)
{
//Find rep facilities
//-------------------
count2 = (KeepDist / 2);
if(numStructsByTypeInArea(player, REF_REPAIR_FACILITY, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2) > 0)
{
haveOutpost = TRUE;
}
}
//-----------------------------------------------
//Fix number of defendGr members (after MoveBase)
//-----------------------------------------------
if(not MovingBase)
{
if(defendGr.members > maxDefenders)
{
initIterateGroup(defendGr);
droid = iterateGroup(defendGr);
while((defendGr.members > maxDefenders) and (droid != NULLOBJECT))
{
groupAddDroid(attackGroup, droid); //Add them back to attack group
droid = iterateGroup(defendGr);
}
}
}
}
//------------------
// Power saving
//------------------
event savePower(inactive)
{
//------------
//Power saving
//------------
powerSaving = FALSE;
if(playerPower(player) < 40) //Low on power
{
powerSaving = TRUE;
}
}
//------------------------------------
// Units stuck, do something!
//------------------------------------
event stuck(stuckTr)
{
//Most of them have an order
if(idleGroup(attackGroup) < (attackGroup.members / 2))
{
//If we moved
temp = (7 * 128);
if(distBetweenTwoPoints(attackGroup.x, attackGroup.y, stuckX, stuckY) > temp)
{
stuckX = attackGroup.x; //Store new coordinates
stuckY = attackGroup.y;
stuckTimes = 0; //Reset
}
else
{
stuckTimes = stuckTimes + 1;
}
//If they are really stuck
if((stuckTimes > 40) and (stuckTimes < 65))
{
count = 0;
while(count < 25)
{
//Run a bit
initIterateGroup(attackGroup);
droid = iterateGroup(attackGroup);
while(droid != NULLOBJECT)
{
orderDroid(droid, DORDER_RUN);
droid = iterateGroup(attackGroup);
}
//Run a bit
initIterateGroup(sendAttackGr);
droid = iterateGroup(sendAttackGr);
while(droid != NULLOBJECT)
{
orderDroid(droid, DORDER_RUN);
droid = iterateGroup(sendAttackGr);
}
pause(25);
count = count + 1;
}
}
else if(stuckTimes > 64)
{
//Wipe out any structure near the group or some units if there are no structures
resetStructTargets();
structure = structTargetInArea(player, player, attackGroup.x - temp, attackGroup.y - temp, attackGroup.x + temp, attackGroup.y + temp);
if(structure == NULLOBJECT)
{
setStructTarPref(ST_WALL);
structure = structTargetInArea(player, player, attackGroup.x - temp, attackGroup.y - temp, attackGroup.x + temp, attackGroup.y + temp);
}
if(structure != NULLOBJECT)
{
orderGroupObj(attackGroup, DORDER_ATTACK, structure);
}
else
{
resetDroidTargets();
tempDroid = droidTargetInArea(player, player, attackGroup.x - temp, attackGroup.y - temp, attackGroup.x + temp, attackGroup.y + temp);
if(tempDroid != NULLOBJECT)
{
orderGroupObj(attackGroup, DORDER_ATTACK, tempDroid);
}
}
}
}
}
//=============================================================================================
// VTOLs
//=============================================================================================
//---------------------
// Build rearm pads
//---------------------
event buildVtolPads(inactive)
{
if(getStructure(vtolFactory,player) != NULLOBJECT) //If we have VTOL factory
{
//Count rearm pads
//----------------
initEnumStruct(FALSE,vtolPad,player,player);
structure= enumStruct();
count = 0;
while(structure != NULLOBJECT)
{
count = count + 1;
structure= enumStruct();
}
//Do we have enough rearm pads?
//-----------------------------
if(count < ((maxTVtols + maxSVtols) / 2))
{
//Find nearest truck
//------------------
buildX = baseX;
buildY = baseY;
result = 99999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
//Build vtol rearm pads
//---------------------
boolResult = pickStructLocation(vtolPad, ref buildX, ref buildY,player);
if((boolResult == TRUE) and (tempDroid != NULLOBJECT))
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolPad, buildX, buildY);
}
}
}
else //Build VTOL Factory
{
if(isStructureAvailable(vtolFactory,player))
{
//Find nearest truck
//------------------
buildX = baseX;
buildY = baseY;
result = 99999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
//Build VTOL Facrory
//------------------
boolResult = pickStructLocation(vtolFactory, ref buildX, ref buildY,player);
if((boolResult == TRUE) and (tempDroid != NULLOBJECT))
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolFactory, buildX, buildY);
}
}
}
}
//----------------------
// Build VTOLs
//----------------------
event buildVtols(buildVtolsTr)
{
structure = getStructure(vtolPad,player); //Got vtol pads?
if(structure != NULLOBJECT)
{
structure = getStructure(vtolFactory,player);
if(structure != NULLOBJECT)
{
//Check if we have any antitank template
boolResult = FALSE;
count = numTVtolTemplates - 1;
count2 = 0;
while((count >= 0) and (boolResult == FALSE))
{
if(skCanBuildTemplate(player,structure, tVtols[count]))
{
boolResult = TRUE;
}
count = count - 1;
}
//Check if we have any antistructure template
boolResult2 = FALSE;
count = numSVtolTemplates - 1;
count2 = 0;
while((count >= 0) and (boolResult2 == FALSE))
{
if(skCanBuildTemplate(player,structure, sVtols[count]) )
{
boolResult2 = TRUE;
}
count = count - 1;
}
//Decide for which group to build VTOLs
result = 0;
if((tVtolGr.members < maxTVtols) and ((tVtolGr.members <= sVtolGr.members) or (not boolResult2)))
{
result = 1;
}
else if((sVtolGr.members < maxSVtols) and ((sVtolGr.members < tVtolGr.members) or (not boolResult)))
{
result = 2;
}
if(result > 0)
{
if(structureIdle(structure) == TRUE) // if factory idle
{
if(result == 2) //sVtolGr
{
count = numSVtolTemplates - 1;
count2 = 0;
while((count2 < numSVtolTemplates) and (count >= 0))
{
if(skCanBuildTemplate(player,structure, sVtols[count]) )
{
tmplChoice[count2] = sVtols[count];
count2 = count2 + 1;
}
count = count - 1;
}
}
else //tVtolGr
{
count = numTVtolTemplates - 1;
count2 = 0;
while((count2 < numTVtolTemplates) and (count >= 0))
{
if(skCanBuildTemplate(player,structure, tVtols[count]) )
{
tmplChoice[count2] = tVtols[count];
count2 = count2 + 1;
}
count = count - 1;
}
}
//Build it
if(count2 > 0)
{
buildDroid(tmplChoice[random(count2)],structure,player,1);
}
}
structure = enumStruct();
}
}
}
}
//------------------------
// Defend attacked object
//------------------------
event defend(defendTr)
{
if(baseobj2 != NULLOBJECT) //If attacker still alive
{
if(baseobj2.type == OBJ_DROID) //If attacker is a droid
{
if(not isVtol(objToDroid(baseobj2))) //If attacker is not a VTOL
{
//Check if base was attacked
//--------------------------
if(baseobj != NULLOBJECT) //If object that was attacked still exist
{
if((baseobj.x > minx) and (baseobj.x < maxx) and (baseobj.y > miny) and (baseobj.y < maxy))
{
if(idleGroup(defendGr) > (defendGr.members / 2)) //If defend group not already defending
{
defendObject = baseobj2;
orderGroupLoc(defendGr, DORDER_SCOUT, defendObject.x, defendObject.y);
//setFogColour(random(200) + 50, 1, 1); //Test
}
//Defend with Vtols
if(idleGroup(tVtolGr) > (tVtolGr.members / 2)) //If tVtolGr not busy
{
orderGroupLoc(tVtolGr, DORDER_SCOUT, defendObject.x, defendObject.y);
}
if(idleGroup(sVtolGr) > (sVtolGr.members / 2)) //If sVtolGr not busy
{
orderGroupLoc(sVtolGr, DORDER_SCOUT, defendObject.x, defendObject.y);
}
}
else //If outpost is under attack
{
if(curEnEdgeX > 0) //If it is initialized
{
if(distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, baseobj.x, baseobj.y) < (KeepDist / 2))
{
if(attackGroup.members > 4)
{
orderGroupLoc(attackGroup, DORDER_SCOUT, baseobj2.x, baseobj2.y);
}
}
}
}
}
}
}
}
}
//----------------------------
// Build VTOL defenses
//----------------------------
event vtolDefend(vtolDefendTr)
{
if(baseobj != NULLOBJECT)
{
if(baseobj.type == OBJ_DROID)
{
if(isVtol(objToDroid(baseobj)))
{
if(structure != NULLOBJECT) //Attacked structure still exists
{
buildX = structure.x;
buildY = structure.y;
result = 999999;
tempDroid = NULLOBJECT;
initIterateGroup(buildGroup);
droid = iterateGroup(buildGroup);
while(droid != NULLOBJECT)
{
if(droid.order == DORDER_NONE)
{
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
if(result2 < result)
{
result = result2;
tempDroid = droid;
}
}
droid = iterateGroup(buildGroup);
}
if(tempDroid != NULLOBJECT) //If we have a truck
{
//Find best defense we can build
//------------------------------
count = 0;
count2 = -1;
while(count < numVtolDefStr)
{
if(isStructureAvailable(vtolDefStruct[count],player))
{
count2 = count;
}
count = count + 1;
}
if(count2 != (-1) ) //If we have a structure to build
{
boolResult = pickStructLocation(vtolDefStruct[count2], ref buildX, ref buildY,player);
if(boolResult == TRUE)
{
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolDefStruct[count2],buildX,buildY);
}
}
}
}
}
else //Attacked by a tank
{
tVtolObject = baseobj;
}
}
else //Attacked by a structure
{
sVtolObject = baseobj;
}
/*
//Defend group
if(structure != NULLOBJECT) //Attacked structure still exists
{
//If structure is in the base
if((structure.x > minx) and (structure.x < maxx) and (structure.y > miny) and (structure.y < maxy))
{
if(baseobj.type == OBJ_STRUCTURE)
{
defendObject = baseobj;
}
else if(baseobj.type == OBJ_DROID) //If it's
{
if(not isVtol(objToDroid(baseobj)))
{
defendObject = baseobj;
}
}
}
}
//Attack
if(defendObject != NULLOBJECT)
{
if(idleGroup(defendGr) > (defendGr.members / 2))
{
orderGroupLoc(defendGr, DORDER_SCOUT, defendObject.x, defendObject.y);
//setFogColour(random(200) + 50, 1, 1); //Test
}
}
//If outpost is under attack
boolResult = TRUE;
if(baseobj.type == OBJ_DROID)
{
if(isVtol(objToDroid(baseobj))) //If not attacked by a VTOL
{
boolResult = FALSE;
}
}
if((structure != NULLOBJECT) and (boolResult == TRUE)) //Attacked structure still exists
{
if(distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, baseobj.x, baseobj.y) < (KeepDist / 2))
{
if(attackGroup.members > (numRushers / 2))
{
orderGroupObj(attackGroup, DORDER_ATTACK, baseobj);
}
}
}
*/
}
}
//-------------------------
// Attack with VTOLs
//-------------------------
event vtolAttack(vtolAttackTr)
{
temp = (KeepDist / 2); //Enemy base range
//if(attackPhase > 1)
if(curEnemy != -1)
{
//-------------------------
//Attack with anitank VTOLs
//-------------------------
boolResult = FALSE;
if(tVtolObject == NULLOBJECT) //No target
{
boolResult = TRUE;
}
//else if(tVtolObject.player != curEnemy) //Attacking another player
//{
// boolResult = TRUE;
//}
//If we can attack
if(boolResult)
{
resetDroidTargets();
setDroidTarPref(DT_CONSTRUCT); //Find truck to attack
tempDroid = droidTargetInArea(curEnemy, curEnemy, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
if(tempDroid == NULLOBJECT) //No trucks in the enemy base, expand search area
{
tempDroid = droidTargetOnMap(curEnemy, curEnemy);
}
/*
if(tempDroid == NULLOBJECT) //No truck, find another unit
{
resetDroidTargets();
setDroidTarPref(DT_WEAP_ALL); //Ground,air,idf units
tempDroid = droidTargetInArea(curEnemy, curEnemy, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
}
*/
if(tempDroid != NULLOBJECT) //Attack
{
tVtolObject = tempDroid; //Remember
}
}
//-------------------------------
//Attack with antistructure VTOLs
//-------------------------------
boolResult = FALSE;
if(sVtolObject == NULLOBJECT) //No target
{
boolResult = TRUE;
}
//else if(sVtolObject.player != curEnemy) //Attacking another player
//{
// boolResult = TRUE;
//}
//If we can attack
if(boolResult)
{
count = 0;
structure = NULLOBJECT;
while((count < 6) and (structure == NULLOBJECT))
{
resetStructTargets();
setStructTarPref(sPref[count]); //Find structure to attack
structure = structTargetInArea(curEnemy, curEnemy, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
count = count + 1;
}
if(structure == NULLOBJECT) //No structure, find another structure
{
resetStructTargets();
setStructTarPref(ST_DEF_ALL); //Ground,air,idf
structure = structTargetOnMap(curEnemy, curEnemy);
}
if(structure != NULLOBJECT) //Attack
{
sVtolObject = structure; //Remember
}
}
}
if((curEnemy < 0) or ((sVtolObject == NULLOBJECT) or (tVtolObject == NULLOBJECT))) //No enemy or no target found
{
//-------------------------
//Attack with anitank VTOLs
//-------------------------
if(tVtolObject == NULLOBJECT)
{
//Find truck
resetDroidTargets();
setDroidTarPref(DT_CONSTRUCT);
count = 0;
droid = NULLOBJECT;
while((count < numEnemies) and (droid == NULLOBJECT))
{
droid = droidTargetOnMap(Enemies[count], Enemies[count]);
count = count + 1;
}
/*
//No truck, find another unit
if(droid == NULLOBJECT)
{
resetDroidTargets();
setDroidTarPref(DT_WEAP_ALL); //Any weapon unit
count = 0;
droid = NULLOBJECT;
while((count < numEnemies) and (droid == NULLOBJECT))
{
droid = droidTargetOnMap(Enemies[count], Enemies[count]);
count = count + 1;
}
}
*/
if(droid != NULLOBJECT)
{
tVtolObject = droid;
}
}
//-------------------------------
//Attack with antistructure VTOLs
//-------------------------------
if(sVtolObject == NULLOBJECT)
{
//Find structure
count = 0;
structure = NULLOBJECT;
while((count < numEnemies) and (structure == NULLOBJECT))
{
count2 = 0;
while((count2 < 6) and (structure == NULLOBJECT))
{
resetStructTargets();
setStructTarPref(sPref[count2]); //Find structure to attack
structure = structTargetOnMap(Enemies[count], Enemies[count]);
count2 = count2 + 1;
}
count = count + 1;
}
if(structure != NULLOBJECT)
{
sVtolObject = structure;
}
}
}
//------
//Attack
//------
//Antitank
if(tempDroid != NULLOBJECT)
{
if((idleGroup(tVtolGr) >= (tVtolGr.members - 1)) and (tVtolGr.members >= maxTVtols)) //Enough VTOLs?
{
orderGroupObj(tVtolGr, DORDER_ATTACK, tVtolObject); //Attack
}
else if((idleGroup(tVtolGr) <= (tVtolGr.members / 2)) and (tVtolGr.members <= (maxTVtols / 2)))
{
orderGroup(tVtolGr, DORDER_RTB);
}
}
//Antistructure
if(sVtolObject != NULLOBJECT)
{
if((idleGroup(sVtolGr) >= (sVtolGr.members - 1)) and (sVtolGr.members >= maxSVtols)) //Enough VTOLs?
{
orderGroupObj(sVtolGr, DORDER_ATTACK, sVtolObject); //Attack
}
else if((idleGroup(sVtolGr) <= (sVtolGr.members / 2)) and (sVtolGr.members <= (maxSVtols / 2)))
{
orderGroup(sVtolGr, DORDER_RTB);
}
}
}
//-------------------------
//Form alliances
//-------------------------
event formAllianceEvent(formAllianceEventTr)
{
count = 0;
while(count<8)
{
if(count != player ) // if not the only other player and rand2
{
if((getDroidCount(player) > 1) and (getDroidCount(count) > 1) ) // not dead
{
if(random(28) == 1) // bit random
{
if(not isHumanPlayer(count)) // not human
{
createAlliance(player,count);
}
}
}
}
count = count + 1;
}
}
//--------------------
//Human alliances
//--------------------
event formHumanAlliances(humanAllianceTr)
{
if(count2 == player) //If offered to me
{
randomiseSeed();
if(random(2) == 1)
{
showConsoleText(ai_ally_msg[random(4)],count);
}
}
}
//-----------------------------------------------
// Change main base location if we almost lost
//-----------------------------------------------
event MoveBase(MoveBaseTr)
{
//Scan for oil derricks and make sure there are no enemy units/structures near it
//If we could find such a place, use it as a new main base location.
//Add Outpost Truck to the build group if it exists, try to save as many Trucks
//as possible.
//------------------------------------------------------------------
// Count enemy units in the base
//-------------------------------
temp = (5 * 128); //Expand search area (Base area) by 'temp'
tempX = minx - temp;
tempY = miny - temp;
buildX = maxx + temp;
buildY = maxy + temp;
if(tempX < 0){tempX = 128;} //Must be done (WZ could stop executing this event otherwise)
if(tempY < 0){tempY = 128;}
if(buildX > (128 * mapWidth)){buildX = (128 * mapWidth) - 128;}
if(buildY > (128 * mapHeight)){buildY = (128 * mapHeight) - 128;}
//Check how many enemy droids we have in the base
count = 0;
result = 0;
while(count < numEnemies)
{
result = numDroidsInArea(Enemies[count], tempX,tempY, buildX,buildY) + result;
count = count + 1;
}
// Compare
//---------
if(result > (numDroidsInArea(player, tempX,tempY, buildX,buildY) + 2) ) //We have troubles!
{
// Check all derricks and find a good spot for a new base
//--------------------------------------------------------
temp = (30 * 128); //Minimum distance from the current main base
boolResult = FALSE; //We have no good spot so far
initEnumStruct(FALSE,derrick,player,player);
structure = enumStruct();
while(structure != NULLOBJECT)
{
if(distBetweenTwoPoints(baseX, baseY, structure.x, structure.y) > temp ) //Not too close to the current base
{
boolResult = TRUE; //We fount a good spot?
tempX = structure.x; //Remember
tempY = structure.y;
// A better way to check if enemy can see this spot
//--------------------------------------------------
count = 0;
while(count < numEnemies)
{
boolResult2 = TRUE;
initEnumStruct(FALSE,derrick,Enemies[count],player); //Check if Enemies[count] can see current player's derrick
structure2 = enumStruct();
while((structure2 != NULLOBJECT) and (boolResult2))
{
if(structure2 == structure) //Duh, enemy can see it!
{
boolResult = TRUE; //Not a good spot
boolResult2 = FALSE; //Stop checking
count = numEnemies; //Stop checking
}
structure2 = enumStruct(); //Check next structure
}
count = count + 1;
}
}
structure = enumStruct();
}
//Try to find a good spot using another method if we had not luck with the derricks
//---------------------------------------------------------------------------------
if(not boolResult)
{
count = 0;
while(count < 5) //Try 5 times
{
tempX = (random(mapWidth - 6) + 3) * 128;
tempY = (random(mapHeight - 6) + 3) * 128;
if(distBetweenTwoPoints(baseX, baseY, tempX, tempY) > temp) //Not too close to the current base
{
//Check if there are any enemies near the new spot
count2 = 0;
while(count2 < numEnemies)
{
if(not objectInRange(Enemies[count2], tempX,tempY, 7 * 128 )) //No enemies here
{
boolResult = TRUE;
}
count2 = count2 + 1;
}
}
count = count +1;
}
}
//
if(not boolResult) //Still no luck, just choose random location
{
tempX = (random(mapWidth - 6) + 3) * 128;
tempY = (random(mapHeight - 6) + 3) * 128;
boolResult = TRUE;
}
if(boolResult) //If it's a save place for a new base
{
MovingBase = TRUE;
pickStructLocation(wallStruct, ref baseX, ref baseY,player); //Make WZ find berret coords
baseX = tempX;
baseY = tempY;
temp = (3 * 128);
maxy = baseY + temp; //Will be recalculated later, must have same values as in basedetails() event
maxx = baseX + temp;
miny = baseY - temp;
minx = baseX - temp;
//centreViewPos(baseX, baseY);
//Add outpostDroid to the buildGroup
if(outpostDroid != NULLOBJECT)
{
droidLeaveGroup(outpostDroid);
groupAddDroid(buildGroup,outpostDroid);
outpostDroid = NULLOBJECT;
}
//Collect all units
groupAddGroup(defendGr, oilGr);
groupAddGroup(defendGr, scoutGroup[0]);
groupAddGroup(defendGr, scoutGroup[1]);
groupAddGroup(defendGr, attackGroup);
groupAddGroup(defendGr, sendAttackGr); //From sendAttackGr to defendGr
orderGroupLoc(buildGroup, DORDER_MOVE, baseX, baseY);
orderGroupLoc(defendGr, DORDER_MOVE, baseX, baseY);
orderGroupLoc(sVtolGr, DORDER_MOVE, baseX, baseY);
orderGroupLoc(tVtolGr, DORDER_MOVE, baseX, baseY);
//Restart the script from the beginning
//-------------------------------------
setEventTrigger(deactivate,nowTr); //Deactivate all events (deactivates itself too)
setEventTrigger(activate,nowTr); //Activate necessary events to rebuild the base and all events which
//are active when the game starts
}
//
}
}
//---------------------------------
// Activate Lego Phase
//---------------------------------
event activate(inactive)
{
setEventTrigger(LegoBuild,LegoBuildTr);
setEventTrigger(LegoTrucks,LegoTrucksTr);
setEventTrigger(Rush,RushTr);
setEventTrigger(chooseEnemy,chooseEnemyTr);
setEventTrigger(BuildAttackForce,BuildAttackForceTr);
setEventTrigger(doResearch,doResearchTr);
setEventTrigger(basedetails,basedetailsTr);
setEventTrigger(keepTrack,keepTrackTr);
setEventTrigger(droidDestroyed,droidDestroyedTr);
setEventTrigger(buildPowerGenerators,buildPowerGeneratorsTr);
setEventTrigger(droidBuilt,droidBuiltTr);
setEventTrigger(difficultyMod,difficultyModTr);
setEventTrigger(upgradeStructures,upgradeStructuresTr);
setEventTrigger(moveIfAttacked,moveIfAttackedTr);
setEventTrigger(stuck,stuckTr);
setEventTrigger(buildVtols,buildVtolsTr);
setEventTrigger(vtolDefend,vtolDefendTr);
setEventTrigger(vtolAttack,vtolAttackTr);
setEventTrigger(formAllianceEvent,formAllianceEventTr);
setEventTrigger(formHumanAlliances,humanAllianceTr);
setEventTrigger(vtolDefend,vtolDefendTr);
setEventTrigger(MoveBase,MoveBaseTr);
}
event deactivate(CALL_GAMEINIT)
{
debugMode = FALSE;
if( (not debugMode) and ((player == selectedPlayer) or (not myResponsibility(player))) )
{
setEventTrigger(StartGame,inactive);
setEventTrigger(LegoBuild,inactive);
setEventTrigger(Rush,inactive);
setEventTrigger(chooseEnemy,inactive);
setEventTrigger(BuildAttackForce,inactive);
setEventTrigger(doResearch,inactive);
setEventTrigger(basedetails,inactive);
setEventTrigger(keepTrack,inactive);
setEventTrigger(droidDestroyed,inactive);
setEventTrigger(buildPowerGenerators,inactive);
setEventTrigger(LegoTrucks,inactive);
setEventTrigger(droidBuilt,inactive);
setEventTrigger(difficultyMod,inactive);
setEventTrigger(upgradeStructures,inactive);
setEventTrigger(moveIfAttacked,inactive);
setEventTrigger(stuck,inactive);
setEventTrigger(buildVtols,inactive);
setEventTrigger(vtolDefend,inactive);
setEventTrigger(vtolAttack,inactive);
setEventTrigger(formAllianceEvent,inactive);
setEventTrigger(formHumanAlliances,inactive);
setEventTrigger(vtolDefend,inactive);
setEventTrigger(MoveBase,inactive);
}
}
//Upgrade structures
powModule STRUCTURESTAT "A0PowMod1"
facModule STRUCTURESTAT "A0FacMod1"
resModule STRUCTURESTAT "A0ResearchModule1"
//Important structures
oilRes FEATURESTAT "OilResource"
derrick STRUCTURESTAT "A0ResourceExtractor"
powGen STRUCTURESTAT "A0PowerGenerator"
factory STRUCTURESTAT "A0LightFactory"
resLab STRUCTURESTAT "A0ResearchFacility"
vtolFactory STRUCTURESTAT "A0VTolFactory1"
repairFacility STRUCTURESTAT "A0RepairCentre3"
vtolPad STRUCTURESTAT "A0VtolPad"
wallStruct STRUCTURESTAT "A0HardcreteMk1Wall"
//Structures for the first phase: LEGO
numLego INT 11
legoSt[0] STRUCTURESTAT "A0ResearchFacility"
legoSt[1] STRUCTURESTAT "A0PowerGenerator"
legoSt[2] STRUCTURESTAT "A0LightFactory"
legoSt[3] STRUCTURESTAT "A0LightFactory"
legoSt[4] STRUCTURESTAT "A0LightFactory"
legoSt[5] STRUCTURESTAT "A0LightFactory"
legoSt[6] STRUCTURESTAT "A0ResearchFacility"
legoSt[7] STRUCTURESTAT "A0ResearchFacility"
legoSt[8] STRUCTURESTAT "A0ResearchFacility"
legoSt[9] STRUCTURESTAT "A0ResearchFacility"
legoSt[10] STRUCTURESTAT "A0CommandCentre"
// extra structs
numExtraStructs INT 3
extraStructs[0] STRUCTURESTAT "A0ResearchFacility"
extraStructs[1] STRUCTURESTAT "A0LightFactory"
extraStructs[2] STRUCTURESTAT "A0CommandCentre"
//Base structures
numBaseStructs INT 10
baseStructs[0] STRUCTURESTAT "A0LightFactory"
baseStructs[1] STRUCTURESTAT "A0PowerGenerator"
baseStructs[2] STRUCTURESTAT "A0CyborgFactory"
baseStructs[3] STRUCTURESTAT "A0VTolFactory1"
baseStructs[4] STRUCTURESTAT "A0ResearchFacility"
baseStructs[5] STRUCTURESTAT "A0CommandCentre"
baseStructs[6] STRUCTURESTAT "X-Super-Cannon"
baseStructs[7] STRUCTURESTAT "X-Super-MassDriver"
baseStructs[8] STRUCTURESTAT "X-Super-Rocket"
baseStructs[9] STRUCTURESTAT "X-Super-Missile"
//AA
numVtolDefStr INT 5
vtolDefStruct[0] STRUCTURESTAT "AASite-QuadMg1"
vtolDefStruct[1] STRUCTURESTAT "AASite-QuadBof"
vtolDefStruct[2] STRUCTURESTAT "AASite-QuadRotMg"
vtolDefStruct[3] STRUCTURESTAT "P0-AASite-SAM1"
vtolDefStruct[4] STRUCTURESTAT "P0-AASite-SAM2"
//Combat Templates
numTemplates INT 12
tmpl[0] TEMPLATE "A-Viper-Wheels-MG"
tmpl[1] TEMPLATE "A-Viper-Wheels-TMG"
tmpl[2] TEMPLATE "A-Viper-Wheels-HMG"
tmpl[3] TEMPLATE "A-Cobra-Wheels-HMG"
tmpl[4] TEMPLATE "A-Cobra-Hover-HMG"
tmpl[5] TEMPLATE "A-Cobra-Hover-MC"
tmpl[6] TEMPLATE "A-Scorp-Hover-MC"
tmpl[7] TEMPLATE "A-Python-Hover-MC"
tmpl[8] TEMPLATE "A-Python-Hover-HC"
tmpl[9] TEMPLATE "A-Python-Trk-HC"
tmpl[10] TEMPLATE "A-Python-Trk-Scour"
tmpl[11] TEMPLATE "A-Python-Trk-HLaser"
//Constructor
constructor TEMPLATE "ConstructorDroid"
//---------------------------
// Base defenses
//---------------------------
numDefenses INT 4
defenses[0] STRUCTURESTAT "PillBox1" //Machinegun Bunker
defenses[1] STRUCTURESTAT "Emplacement-MRL-pit" //Mini-Rocket Artillery
defenses[2] STRUCTURESTAT "PillBox6" //Lancer bunker
defenses[3] STRUCTURESTAT "Emplacement-HPVcannon" //HPV Cannon Emplacement
//Base Defenses built by other AIs
numDefStructs INT 26
defStructs[0] STRUCTURESTAT "PillBox1"
defStructs[1] STRUCTURESTAT "Pillbox-RotMG"
defStructs[2] STRUCTURESTAT "Emplacement-MortarPit01"
defStructs[3] STRUCTURESTAT "PillBox1"
defStructs[4] STRUCTURESTAT "PillBox5"
defStructs[5] STRUCTURESTAT "Sys-SensoTower02"
defStructs[6] STRUCTURESTAT "WallTower03"
defStructs[7] STRUCTURESTAT "WallTower02"
defStructs[8] STRUCTURESTAT "Emplacement-MRL-pit"
defStructs[9] STRUCTURESTAT "Wall-RotMg" // Campaign 2 Defensive Structures
defStructs[10] STRUCTURESTAT "Wall-VulcanCan"
defStructs[11] STRUCTURESTAT "WallTower-HPVcannon"
defStructs[12] STRUCTURESTAT "Emplacement-Howitzer105"
defStructs[13] STRUCTURESTAT "Emplacement-HvyATrocket"
defStructs[14] STRUCTURESTAT "Emplacement-MortarPit02"
defStructs[15] STRUCTURESTAT "WallTower06"
defStructs[16] STRUCTURESTAT "Emplacement-PulseLaser" // Campaign 3 Defensive Structures
defStructs[17] STRUCTURESTAT "Emplacement-Rail2"
defStructs[18] STRUCTURESTAT "Wall-VulcanCan"
defStructs[19] STRUCTURESTAT "Emplacement-RotMor"
defStructs[20] STRUCTURESTAT "WallTower-HvATrocket"
defStructs[21] STRUCTURESTAT "WallTower-Atmiss"
defStructs[22] STRUCTURESTAT "WallTower-PulseLas"
defStructs[23] STRUCTURESTAT "WallTower-Rail2"
defStructs[24] STRUCTURESTAT "WallTower-Rail3"
defStructs[25] STRUCTURESTAT "Pillbox-RotMG"
//---------------------------
// VTOLs
//---------------------------
//Antistructure
numSVtolTemplates INT 1
//Anti Structure
sVtols[0] TEMPLATE "V-Scor-BB"
sVtolWeapon[0] WEAPON "Rocket-VTOL-BB"
//Antitank
numTVtolTemplates INT 2
//Anti Tanks
tVtols[0] TEMPLATE "V-Scor-Lancer"
tVtols[1] TEMPLATE "V-Scor-HPV"
tVtolWeapon[0] WEAPON "Rocket-VTOL-LtA-T" //Lancer
tVtolWeapon[1] WEAPON "Cannon4AUTO-VTOL" //HPV
//------------------------------------
// Structure target preferences
//------------------------------------
sPref[0] INT 8 //Derrick
sPref[1] INT 2 //Factory
sPref[2] INT 4 //Power gen
sPref[3] INT 32 //Res fac
sPref[4] INT 512 //Vtol fac
sPref[5] INT 28672 //Any defense
//-----------------
// Arty
//-----------------
sens[0] STRUCTURESTAT "Sys-SensoTower02" //For T2
sens[1] STRUCTURESTAT "Sys-SensoTowerWS" //For T3
arty[0] STRUCTURESTAT "Emplacement-RotMor" //Pepperpot
arty[1] STRUCTURESTAT "Emplacement-RotHow" //Hellstorm Emplacement
//------------------
// Messages
//------------------
ai_ally_msg[0] TEXTSTRING "AI_ally_msg1"
ai_ally_msg[1] TEXTSTRING "AI_ally_msg2"
ai_ally_msg[2] TEXTSTRING "AI_ally_msg3"
ai_ally_msg[3] TEXTSTRING "AI_ally_msg4"
}
|
|