1
//------------------------------------------------------
3
//------------------------------------------------------
4
public STRUCTURESTAT legoSt[12],derrick,powGen,factory,resLab,powModule,facModule,resModule,vtolFactory,wall,
5
repairFacility,extraStructs[5],defenses[18],structChoice[5],baseStructs[13],vtolPad,vtolDefStruct[5],sens[3],arty[5],attackStructs[5],cybFactory;
6
public FEATURESTAT oilRes;
7
public INT numLego,player,numTemplates,numExtraStructs,numDefenses,numBaseStructs,numSVtolTemplates,numTVtolTemplates,sPref[6],numVtolDefStr,numAttackStructs;
8
public TEMPLATE tmpl[2][12],constructor,sVtols[2][1],tVtols[2][3],tmplRep[2],cybMechanic,cybTmpl[11],Transport;
9
public WEAPON sVtolWeapon[3],tVtolWeapon[3];
10
public TEXTSTRING ai_ally_msg[5],DebugMsg[15];
11
public PROPULSION cyborgProp,vtolProp;
13
//------------------------------------------------------
15
//------------------------------------------------------
16
private GROUP buildGroup,tempGroup,sendOutpostGr,sendAttackGr,collectSendGr,attackGroup,scoutGroup[3],oilGr,sVtolGr,tVtolGr,defendGr,repGr,repairedGroup,transportGr,dropGr;
17
private INT count,count2,result,result2,result3,result4,temp,buildX,buildY,baseX,baseY,tempX,tempY,maxy,maxx,miny,minx,outpostDist;
18
private INT minAttackH,maxAttackH,maxOilGr,scoutX[2],scoutY[2],stuckX,stuckY,stuckTimes,maxTVtols,maxSVtols,maxDefenders;
19
private INT oilX,oilY;
20
private DROID droid,tempDroid,outpostDroid,repDefendDroid[2],toRepDefendDroid[2],transportDroid,transportDroid2;
21
private INT numRetreats,NumOldDefenders,helpAllyPlayer,helpAllyPlayerX,helpAllyPlayerY;
22
private BOOL boolResult,boolResult2,haveOutpost,powerSaving,defendingBase;
23
private FEATURE feature,feature2;
24
private TEMPLATE tmplChoice[5];
25
private STRUCTURE structure,structure2; //attackDerrick;
27
private BOOL actPlayer[8],allyPlayer[8],debugMode,dropEnabled,alreadyAttacked,bigMap;
28
private BASEOBJ baseobj,attackObject,defendObject,tVtolObject,sVtolObject;
30
private INT numEnemies,Enemies[8],EnemyX[8],EnemyY[8],LZ_X,LZ_Y,transportZ,cybTemplate;
31
private INT allianceTime[8];
33
//------------------------------------------------------
34
// Static private variables
35
//------------------------------------------------------
36
private INT mainPhase,curLegoStr,TemplDepth,maxTrucks,curEnemy,curEnemyX,curEnemyY,dropPhase,
37
attackPhase,maxScouts,extraStruct,curEnEdgeX,curEnEdgeY,KeepDist,numRushers,maxRepairing,maxRetreats,muchoPower;
39
//===============================================================================================
43
//===============================================================================================
45
//------------------------------------------------------
47
//------------------------------------------------------
48
trigger StartGameTr (wait, 10);
49
trigger LegoBuildTr (every, 10);
51
//------------------------------------------------------
53
//------------------------------------------------------
54
trigger RushTr (every, 30);
55
trigger RushControlTr (every, 80); //Was 80
57
//------------------------------------------------------
59
//------------------------------------------------------
60
trigger BuildAttackForceTr (every, 80);
61
trigger buildCyborgsTr (every, 100);
62
trigger buildVtolsTr (every, 100);
63
trigger doResearchTr (every, 20);
64
trigger buildDerricksTr (every, 80); //was 60
65
trigger sendScoutsTr (every, 200);
66
trigger expandBaseTr (every, 150); //was 150
67
trigger buildDefensesTr (every, 80);
68
trigger buildVtolPadsTr (every, 80);
69
trigger basedetailsTr (every, 50);
70
trigger oilDefensesTr (every, 100);
72
//------------------------------------------------------
74
//------------------------------------------------------
75
trigger droidDestroyedTr (CALL_DROID_DESTROYED, player, ref droid);
76
trigger nowTr (wait, 1);
77
trigger keepTrackTr (every, 60);
78
trigger chooseEnemyTr (every, 70);
79
trigger LegoTrucksTr (every, 10);
80
trigger buildPowerGeneratorsTr (every, 60);
81
trigger droidBuiltTr (CALL_NEWDROID,player, ref droid,ref structure);
82
trigger difficultyModTr (every, 600);
83
trigger upgradeStructuresTr (every, 50);
84
trigger moveIfAttackedTr (CALL_DROID_ATTACKED, player, ref droid, ref baseobj);
85
trigger BuildOutpostTr (every, 100);
86
trigger updateDetailsTr (every, 40);
87
trigger savePowerTr (every, 20);
88
trigger destroyOilTr (every, 60);
89
trigger stuckTr (every, 80);
90
trigger vtolAttackTr (every, 50);
91
trigger vtolDefendTr (CALL_STRUCT_ATTACKED, player, ref structure, ref baseobj);
92
trigger formAllianceEventTr (every, 170);
93
trigger humanAllianceTr (CALL_ALLIANCEOFFER,ref count, ref count2);
94
trigger FinishStructuresTr (every, 120);
95
trigger repairStuffTr (every, 130);
96
trigger cyborgDropTr (every, 999);
97
trigger manageDropAttacksTr (every, 999);
98
trigger WatchDefendBaseTr (every, 160); //was 200
99
trigger WatchHelpAllyTr (every, 200);
100
trigger agressiveDefenceTr (every, 80);
101
trigger additVTOLDefensesTr (every, 180);
102
trigger PowerBoostTr (every, 50); //Same as research timer
104
//===============================================================================================
108
//===============================================================================================
110
event initializeRushPrep;
111
event BuildAttackForce;
129
event FinishStructures;
130
event WatchDefendBase;
132
event agressiveDefence;
133
event additVTOLDefenses;
137
/*%? Help1 = "This will only have an effect untill the early-mid - mid game.\n
138
After gaining the most vital technology and being low on power,
139
GK will manage research speed by itself.
140
You can only additionaly limit the speed, but you can't make GK do more research at that time." */
142
/*%? Help2 = "Hint: play as AI ..." */
145
//===============================================================================================
149
//===============================================================================================
151
//------------------------------------------------------
153
//------------------------------------------------------
154
event StartGame(StartGameTr)
157
//Initialize variables
158
//--------------------
166
numRushers = 8; //Early rush
168
else if((temp >= 5) and (temp <= 12))
170
numRushers = 17; //Mass attack
174
numRushers = 12; //Normal attack
181
TemplDepth = 1; //From how many different templates to choose a template randomly, depends on res phase
182
maxScouts = 1; //Enable atleast 1 scout at startup, otherwise might take too long (if 20 attackers)
186
//Distance to keep of the enemy base when sending attackGr for regrouping
187
KeepDist = (19 * 128); /*%! ID="OutpostDistance",
188
MainDesc="Distance from GK outpost to enemy base",
191
ArgDesc="19 Tiles (Default)",
201
ArgDesc="30 Tiles" */
205
minAttackH = 47; //Min attack health. Retreat if < minAttackH
206
maxAttackH = 90; //Attack only if health > maxAttackH, must be bigger than minAttackH
207
//numRepairing = 0; //How many attackers are repairing at the moment
208
haveOutpost = FALSE; //Outpost to retreat to and where to repair damadged units
209
powerSaving = FALSE; //If we are in power saving mode
210
defendingBase = FALSE; //Attackers are currently defending the base
211
maxOilGr = 4; //Number of droids in the oilGr
212
//attackOilX = -1; //Coordinates of enemy derrick
213
//attackOilY = -1; //Coordinates of enemy derrick
214
//attackDerrick = NULLOBJECT; //No enemy derricks to attack yet
215
maxTVtols = 8; //Max number of antitank VTOLs
216
maxSVtols = 10; //Max number of antistructure VTOLs
217
maxDefenders = 5; //Max number of defenders
218
outpostDist = 0; //Remember the distance between the enemy base and the outpost
219
maxRetreats = 6; //Max time to retreat before alloutattack
220
muchoPower = 3500; //If this amount of power is available, then start building expensive templates
221
transportDroid = NULLOBJECT; //Cyborg transport
222
dropPhase = 0; //Phase of the vurrent cyborg drop
223
transportZ = 0; //Height of the transport when landing
224
cybTemplate = 0; //Cyborg template to use for drops
225
dropEnabled = FALSE; //Wheather to drop or not to drop
226
alreadyAttacked = FALSE; //Wheather we have already attacked an enemy base atleast 1 time
227
//toRepDefendDroid = NULLOBJECT; //Defender, which is about to be repaired by the repair unit
228
NumOldDefenders = 0; //How many defenders there were, before base defence was turned on (revert to this number)
230
helpAllyPlayer = -1; //No ally in danger right now
231
helpAllyPlayerX = -1; //Coords of where to send help for the ally
232
helpAllyPlayerY = -1; //Coords of where to send help for the ally
235
if((mapHeight > 150) and (mapWidth > 150))
246
scoutX[0] = temp; //Bottom left
247
scoutY[0] = (mapHeight * 128) - temp;
248
scoutX[1] = (mapWidth * 128) - temp; //Top right
251
//Prepair features for future use
252
//-------------------------------
253
initGetFeature(oilRes,player,player);
257
baseX = (128*mapWidth)/2;
258
baseY = (128*mapHeight)/2;
260
//Add all droids to a group and sort out constructors
261
//---------------------------------------------------
262
groupAddArea(tempGroup, player, 0, 0, (mapWidth*128), (mapHeight*128));
263
initIterateGroup(tempGroup);
264
droid = iterateGroup(tempGroup);
265
while(droid != NULLOBJECT)
267
if(droid.droidType == DROID_CONSTRUCT) //If a constructor
269
//forceDamageObject(droid, 50);
271
baseX = droid.x; //Base coordinates
274
droidLeaveGroup(droid);
275
groupAddDroid(buildGroup,droid);
277
droid = iterateGroup(tempGroup);
281
//Send one truck to build factory
282
//-------------------------------
286
initIterateGroup(buildGroup);
287
droid = iterateGroup(buildGroup);
288
while((boolResult == FALSE) and (droid != NULLOBJECT))
290
if(droid.order == DORDER_NONE)
292
boolResult2 = pickStructLocation(factory, ref buildX, ref buildY,player);
293
if(boolResult2 == TRUE)
295
orderDroidStatsLoc(droid, DORDER_BUILD, factory, buildX,buildY);
299
droid = iterateGroup(buildGroup);
302
//transportDroid = addDroid(Transport, baseX, baseY, player);
306
//------------------------------------------------------
307
// Build all necessary structures
308
//------------------------------------------------------
309
event LegoBuild(LegoBuildTr)
313
initGetFeature(oilRes,player,player);
314
feature = getFeature(player);
315
if(feature != NULLOBJECT)
320
//If no no trucks already trying to build the same derrick
321
initIterateGroup(buildGroup);
322
droid = iterateGroup(buildGroup);
324
while((droid != NULLOBJECT) and (count == 0))
326
if((droid.orderx == buildX) and (droid.ordery == buildY))
328
count = count + 1; //Count trucks
330
droid = iterateGroup(buildGroup);
333
if(count == 0) //Send only 1 truck to each derrick
335
initIterateGroup(buildGroup);
336
droid = iterateGroup(buildGroup);
338
while((boolResult == FALSE) and (droid != NULLOBJECT))
340
if(droid.order == DORDER_NONE)
342
orderDroidStatsLoc(droid, DORDER_BUILD,derrick, buildX,buildY);
345
droid = iterateGroup(buildGroup);
350
//Upgrade factories if it is T3
351
//-----------------------------
352
if(isStructureAvailable(facModule,player)) //If Factory module is already available
354
initEnumStruct(FALSE,factory,player,player);
355
structure= enumStruct();
356
while(structure != NULLOBJECT)
358
//if((skGetFactoryCapacity(structure) < 2) and (skCanBuildTemplate(player,structure, tmpl[0][8]))) //No fac module and T3 (if we have Trck Python HC)
359
if(skGetFactoryCapacity(structure) < 2)
361
initIterateGroup(buildGroup);
362
droid = iterateGroup(buildGroup);
363
//boolResult = TRUE; //Send only 1 truck
364
//while((droid != NULLOBJECT) and (boolResult))
365
while(droid != NULLOBJECT)
367
if(droid.order == DORDER_NONE)
369
//boolResult = FALSE;
370
orderDroidStatsLoc(droid, DORDER_BUILD, facModule, structure.x,structure.y);
372
droid = iterateGroup(buildGroup);
375
structure = enumStruct();
381
if(curLegoStr < numLego)
388
initIterateGroup(buildGroup);
389
droid = iterateGroup(buildGroup);
390
while((droid != NULLOBJECT) and (boolResult == FALSE))
392
if(droid.order == DORDER_NONE)
394
boolResult2 = pickStructLocation(legoSt[curLegoStr], ref buildX, ref buildY,player);
395
if(boolResult2 == TRUE)
401
droid = iterateGroup(buildGroup); //Next droid
404
//Find out if a truck is already building on the spot where another truck might try to build and will fail
408
initIterateGroup(buildGroup);
409
droid = iterateGroup(buildGroup);
410
while((droid != NULLOBJECT) and (boolResult == TRUE))
412
if(droid != tempDroid)
414
if(droid.order == DORDER_BUILD)
416
if((buildX == droid.orderx) and (buildY == droid.ordery))
422
droid = iterateGroup(buildGroup);
429
orderDroidStatsLoc(tempDroid, DORDER_BUILD,legoSt[curLegoStr], buildX,buildY);
430
curLegoStr = curLegoStr + 1;
434
//End Lego phase, start rush preparations
435
//---------------------------------------
436
if(mainPhase == 0) //If not already activated
438
if(curLegoStr == (numLego - 1)) // (numLego - HQ)
440
setEventTrigger(endPhaseOne,nowTr);
444
//Now that HQ is built we can deactivate it
445
//-----------------------------------------
446
if(curLegoStr == numLego)
448
setEventTrigger(LegoBuild, inactive);
453
//------------------------------------------------------
454
// End Lego phase, start rush preparations
455
//------------------------------------------------------
456
event endPhaseOne(inactive)
458
//Start rush preparation phase
459
//----------------------------
460
setEventTrigger(doResearch,doResearchTr);
461
setEventTrigger(buildDerricks,buildDerricksTr);
462
setEventTrigger(initializeRushPrep,nowTr);
463
setEventTrigger(RushControl,RushControlTr);
464
//setEventTrigger(sendScouts,sendScoutsTr);
465
setEventTrigger(expandBase,expandBaseTr);
466
setEventTrigger(buildDefenses,buildDefensesTr);
467
setEventTrigger(oilDefenses,oilDefensesTr);
468
//setEventTrigger(updateDetails,updateDetailsTr);
469
setEventTrigger(savePower,savePowerTr);
470
setEventTrigger(destroyOil,destroyOilTr);
471
setEventTrigger(buildVtolPads,buildVtolPadsTr);
472
setEventTrigger(FinishStructures,FinishStructuresTr);
474
setEventTrigger(LegoTrucks,inactive);
475
setEventTrigger(endPhaseOne, inactive);
479
//=============================================================================================
481
//=============================================================================================
483
//------------------------------------------------------
484
// Send units to the outpost, near the enemy base
485
//------------------------------------------------------
488
if((sendOutpostGr.members + attackGroup.members + collectSendGr.members) > numRushers)
490
//setFogColour(random(200) + 50, 1, 1);
491
if(curEnemy != -1) //We have an enemy and not already on our way
493
//setFogColour(1, random(200) + 50, 1);
494
if((curEnEdgeX > 0) and (attackPhase == 0))
496
maxTrucks = 12; //Maximum number of the trucks to be built in this phase
506
groupAddGroup(sendOutpostGr, collectSendGr); //From collectSendGr to sendOutpostGr
507
groupAddGroup(sendOutpostGr, attackGroup); //From attackGroup to sendOutpostGr
508
setGroupSecondary(sendOutpostGr, DSO_HALTTYPE, DSS_HALT_GUARD); //Don't start attacking the base
509
orderGroupLoc(sendOutpostGr, DORDER_MOVE, curEnEdgeX, curEnEdgeY);
510
attackPhase = 1; //On our way
512
alreadyAttacked = TRUE;
514
//If we were making an early rush then make sure we build more units before we attack again (otherwise will be slowly increased by 1)
515
//if(numRushers < 10)
520
setEventTrigger(BuildOutpost,BuildOutpostTr); //Start building outpost
521
setEventTrigger(Rush,inactive);
527
//------------------------------------------------------
528
// Cancel current attack
529
//------------------------------------------------------
530
event stopAttack(inactive)
532
showConsoleText(DebugMsg[4], player); //Attack stopped
542
groupAddGroup(sendOutpostGr, attackGroup); //Add attackGroup to sendOutpostGr
543
groupAddGroup(sendOutpostGr, collectSendGr); //Add collectSendGr to sendOutpostGr
544
groupAddGroup(sendOutpostGr, repairedGroup); //Add repairedGroup to sendOutpostGr
545
groupAddGroup(repGr, repairedGroup); //Add repGr to sendOutpostGr
547
//setGroupSecondary(attackGroup, DSO_HALTTYPE, DSS_HALT_GUARD);
548
//orderGroupLoc(attackGroup, DORDER_MOVE,attackGroup.x,attackGroup.y); //Collect them a bit
549
setGroupSecondary(sendOutpostGr, DSO_HALTTYPE, DSS_HALT_GUARD);
550
orderGroupLoc(sendOutpostGr, DORDER_MOVE,attackGroup.x,attackGroup.y); //Collect them a bit
551
setEventTrigger(Rush,RushTr);
553
setEventTrigger(stopAttack,inactive);
556
//------------------------------------------------------
557
// Control the attack
558
//------------------------------------------------------
559
event RushControl(inactive)
561
//=====================================================================
562
// attackPhase explaination:
564
// 1: on our way to the enemy 'edge' (waiting for regrouping)
565
// 2: on our way to the base
567
//=====================================================================
569
if((not defendingBase) and (helpAllyPlayer < 0)) //Attackers not busy
572
temp = (KeepDist / 2); //Enemy base range
574
//maxRepairing = numRushers * 3 / 7 + 1; //Max number of units allowed to be repairing before retreating
576
//Max number of units that may be going to repair at the same time before retreat
577
//-------------------------------------------------------------------------------
578
result = attackGroup.members + repGr.members; //Total available units (+repGr units to make it more precise)
580
//if(numRushers > attackGroup.members)
582
// result = numRushers; //Use numRushers or number of attackers to calculate how many units may repair at a time (whatever number is bigger)
585
maxRepairing = attackGroup.members * 3 / 7 + 2; //Max number of units allowed to be repairing before retreating
589
//------------------------
590
//Stop attack if necessary
591
//------------------------
592
if((attackPhase > 0) and (curEnemy != -1)) //If dead
594
if(not actPlayer[curEnemy])
596
//Retreat if enemy is dead
597
//------------------------
598
setEventTrigger(stopAttack,nowTr); //Cancel attack, clear variables
603
//Add units from collectSendGr to sendOutpostGr if we have a small group which can protect itself (prevent ant-tail)
604
if(collectSendGr.members > 6)
606
groupAddGroup(sendOutpostGr, collectSendGr); //Add collectSendGr to sendOutpostGr
609
//-------------------------------------------------------------
610
//Add units to attack group after they have reached the outpost
611
//-------------------------------------------------------------
612
if(attackPhase > 0) //If on our way to the outpost
614
//If all attack units were killed or alloutattack, then make defend units attackers
615
//---------------------------------------------------------------------------------
616
if(((attackGroup.members + sendOutpostGr.members + repGr.members) < (numRushers / 2)) or (numRetreats > maxRetreats))
618
if(defendGr.members > (maxDefenders / 2)) //Enough defenders
620
showConsoleText(DebugMsg[5], player); //Adding some defenders to attackers
622
initIterateGroup(defendGr);
623
droid = iterateGroup(defendGr);
624
count = defendGr.members;
625
count2 = defendGr.members;
626
while((count > (count2 / 2)) and (droid != NULLOBJECT)) //Leave atleast 50% of available number of defenders
628
if(droid.droidType != DROID_REPAIR) //Leave them the repair unit, so this will not screw up everything
630
groupAddDroid(sendOutpostGr, droid); //Add to attackers
633
droid = iterateGroup(defendGr); //Next droid
636
toRepDefendDroid[0] = NULLOBJECT; //Make repairer stop following this unit if it became an attacker
637
toRepDefendDroid[1] = NULLOBJECT;
641
//Do alloutattack if failed too many times already
642
//------------------------------------------------
643
if(numRetreats > maxRetreats)
645
//if(not defendingBase) //(Done earlier now)
647
showConsoleText(DebugMsg[3], player); //Alloutattack
648
groupAddGroup(sendOutpostGr, collectSendGr); //Add collectSendGr to sendOutpostGr
649
groupAddGroup(sendOutpostGr, attackGroup); //Add attackGroup to sendOutpostGr
650
groupAddGroup(sendOutpostGr, scoutGroup[0]); //Add scout group1 to sendOutpostGr
651
groupAddGroup(sendOutpostGr, scoutGroup[1]); //Add scout group2 to sendOutpostGr
652
groupAddGroup(sendOutpostGr, oilGr); //Add oil attacking group to sendOutpostGr
654
numRetreats = 0; //Reset (necessary?)
658
//Send newly-built units to the edge
659
//----------------------------------
661
if(((attackGroup.members + sendOutpostGr.members) > (numRushers / 2)) and (sendOutpostGr.members > 3)) //Check this condition only one time
663
//showConsoleText(DebugMsg[2], player); //reinforcements on the way
667
//tempX = sendOutpostGr.x; //Find center of the group
668
//tempY = sendOutpostGr.y;
669
//result = tempGroup.members; //By accessing another group we make WZ clear the cached sendOutpostGr member variables, to reinitialize them next time we run this event (otherwise values won't change)
671
initIterateGroup(sendOutpostGr);
672
droid = iterateGroup(sendOutpostGr);
673
while(droid != NULLOBJECT)
675
if(distBetweenTwoPoints(droid.x, droid.y, curEnEdgeX, curEnEdgeY) > temp) //If not in the outpost
677
//Prevent the ant-tail, send units to the center of the group if too far away ahead
678
//if(distBetweenTwoPoints(droid.orderx, droid.ordery, curEnEdgeX, curEnEdgeY) < temp) //If was already sent to the outpost
680
// if(distBetweenTwoPoints(droid.x, droid.y, tempX, tempY) > (9 * 128)) //If too far away from its buddies
682
// orderDroidLoc(droid, DORDER_MOVE, tempX, tempY); //Prevent ant-tail, send unit back to the group center
687
if(distBetweenTwoPoints(droid.orderx, droid.ordery, curEnEdgeX, curEnEdgeY) >= temp) //If not going to the outpost
689
if(boolResult == TRUE) //Condition checked before
691
setDroidSecondary(droid, DSO_HALTTYPE, DSS_HALT_GUARD);
693
//orderDroidLoc(droid, DORDER_MOVE, curEnEdgeX + random(result) - (result/2), curEnEdgeY + random(result) - (result/2)); //Send to the outpost
694
orderDroidLoc(droid, DORDER_SCOUT, curEnEdgeX + random(result) - (result/2), curEnEdgeY + random(result) - (result/2)); //Send to the outpost
698
else //Add to attackers if reached outpost
700
//droidLeaveGroup(droid);
701
groupAddDroid(attackGroup,droid);
703
droid = iterateGroup(sendOutpostGr); //Next droid
706
//-------------------------------------------
707
//Add repaired units back to the attack group
708
//-------------------------------------------
709
initIterateGroup(repGr);
710
droid = iterateGroup(repGr);
711
while(droid != NULLOBJECT)
714
if((droid.health > 85) or (not haveOutpost)) //Don't have to or can't repair
716
groupAddDroid(repairedGroup, droid); //Collect them, add to a temporary group to prevent ant-tail
718
else //Re-send to repair
720
if((droid.health < 85) and (haveOutpost) and (droid.order != DORDER_RTR)) //Has to and can repair and not going to repair
722
orderDroid(droid, DORDER_RTR); //Re-order to repair
727
if((droid.health < 85) and (haveOutpost) and (droid.order != DORDER_RTR))
729
//if(droid.order != DORDER_RTR) //If not going to repair
731
orderDroid(droid, DORDER_RTR); //Order to repair
734
else //If already repaired or can't repair
736
if(((droid.health > 85) or (not haveOutpost)) and (droid.order != DORDER_RTR)) //If not going to repair
738
//droidLeaveGroup(droid);
739
//groupAddDroid(attackGroup, droid); //Add to attackers
740
groupAddDroid(repairedGroup, droid); //Collect them, add to a temporary group to prevent ant-tail
745
droid = iterateGroup(repGr); //Next droid
748
//If units are far (already attacking enemy base) then wait for more peraired units
752
if(repGr.members > 7)
754
result = 6; //Wait for more repaired units, if many of them are going to repair, before sending back to enemy
757
if(repairedGroup.members > result) //Prevent ant-tail while attacking
759
groupAddGroup(sendOutpostGr, repairedGroup); //Add back to action
764
groupAddGroup(attackGroup, repairedGroup); //Add back to attackers directly
767
//Remove unit from the attack group if it is goint to repair
768
//----------------------------------------------------------
769
initIterateGroup(attackGroup);
770
droid = iterateGroup(attackGroup);
771
while(droid != NULLOBJECT)
773
if(droid.order == DORDER_RTR) //If going to repair
775
//droidLeaveGroup(droid);
776
setDroidSecondary(droid, DSO_HALTTYPE, DSS_HALT_GUARD); //Don't pursue, guard position
777
groupAddDroid(repGr, droid); //Add to repair group
780
droid = iterateGroup(attackGroup); //Next droid
785
//------------------------------------------------------------------
786
//Start attacking enemy base if most of the units are in the outpost
787
//------------------------------------------------------------------
788
if(attackPhase == 1) //If on our way to the outpost
790
//Check if we can start our invasion
791
//----------------------------------
792
//if(attackGroup.members > numRushers) //If we have enough units
795
//if(numRepairing == 0)
797
if(haveOutpost == TRUE)
799
boolResult = TRUE; //Repair units with light damage
803
//Find idle repair facility
804
//-------------------------
805
//structure2 = NULLOBJECT;
806
//initEnumStruct(FALSE,factory,player,player);
807
//structure = enumStruct();
808
//while(structure != NULLOBJECT)
810
// if(structureIdle(structure) == TRUE)
812
// structure2 = structure;
814
// structure = enumStruct();
819
result2 = repGr.members;
821
initIterateGroup(attackGroup);
822
droid = iterateGroup(attackGroup);
823
while(droid != NULLOBJECT)
825
if((droid.order == DORDER_NONE) or ((droid.orderx == curEnEdgeX) and (droid.ordery == curEnEdgeY))) //Not moving or retreating //Was != DORDER_MOVE
827
result = result + 1; //Num of idle units
829
//Repair units with light damage
830
//------------------------------
831
//if((droid.health < 60) and (boolResult) and ((result2 + 2) < maxRepairing)) //If it's damaged a bit and can repair, don't sent to rpare too many units, keep number under maxRepairing
832
if((droid.health < 70) and (boolResult)) //If it's damaged a bit and can repair
834
orderDroid(droid, DORDER_RTR); //Repair unit
835
result2 = result2 + 1;
838
droid = iterateGroup(attackGroup);
841
//Send to the enemy base if everything's ok
842
//-----------------------------------------
843
if((attackGroup.members) > numRushers) //If have enough units ready to attack
846
if(isHumanPlayer(curEnemy)) //Move instead of scout if attacking human
851
//result2 = (result * 100 / attackGroup.members);
853
//if((result2 > 60) or (result >= numRushers)) // > 60% of the entire group is ready for attack, or have enough, even if many repairing
855
if(((haveOutpost) and (attackGroup.health >= maxAttackH)) or (haveOutpost == FALSE))
857
//if((numRepairing < (attackGroup.members / 2)) and (repGr.members < (numRushers / 4))) //If not too many attackers repairing
858
if(repGr.members < (maxRepairing / 2)) //Not too many repairing otherwise wait until repaired
860
//Send to the enemy base
861
//----------------------
863
showConsoleText(DebugMsg[2], player); //Starting attack
864
setGroupSecondary(attackGroup, DSO_HALTTYPE, DSS_HALT_GUARD);
866
//if(boolResult == TRUE) //If human
868
// orderGroupLoc(attackGroup, DORDER_MOVE, curEnemyX, curEnemyY);
872
orderGroupLoc(attackGroup, DORDER_SCOUT, curEnemyX, curEnemyY);
882
//-------------------------------
883
//Sending to the enemy base rules
884
//-------------------------------
885
if(attackPhase > 1) //If goint to the enemy base or already reached it
889
//if((attackGroup.members < (numRushers * 2 / 3)) or ((haveOutpost) and (attackGroup.health < minAttackH)) or (numRepairing >= (attackGroup.members / 2)) or (repGr.members > maxRepairing)) //If not enough units available
893
if(attackGroup.members < 6) //Not enough units left
895
showConsoleText(DebugMsg[6], player); //Not enough units left
899
//else if((haveOutpost) and (attackGroup.health < minAttackH)) //Too many damaged units
901
// showConsoleText(DebugMsg[5], player); //Too many damaged units
902
// boolResult = TRUE;
904
//if(repGr.members >= maxRepairing) //Too many repairing
906
// showConsoleText(DebugMsg[4], player); //Too many repairing
907
// boolResult = TRUE;
909
//else if(attackGroup.members < (numRushers * 2 / 5)) //If not enough units available
911
// showConsoleText(DebugMsg[6], player); //Not enough units left
912
// boolResult = TRUE;
915
if(boolResult) //Cancel attack, retreat
918
setGroupSecondary(attackGroup, DSO_HALTTYPE, DSS_HALT_GUARD);
919
orderGroupLoc(attackGroup, DORDER_MOVE, curEnEdgeX, curEnEdgeY); //Retreat
920
numRushers = numRushers + 2; //Increase number of attackers
926
numRetreats = numRetreats + 1; //Remember how many times our attacks failed
928
else //If enough units available
931
if(isHumanPlayer(curEnemy)) //Move instead of scout if attacking human
936
//--------------------------------------------------
937
//Send newly-arrived units (outpost units) to attack
938
//--------------------------------------------------
939
//tempX = attackGroup.x; //Find center of the group
940
//tempY = attackGroup.y;
941
//result = tempGroup.members; //By accessing another group we make WZ clear the cached sendOutpostGr member variables, to reinitialize them next time we run this event (otherwise values won't change)
942
initIterateGroup(attackGroup);
943
droid = iterateGroup(attackGroup);
945
while(droid != NULLOBJECT)
947
if(distBetweenTwoPoints(droid.x, droid.y, curEnemyX, curEnemyY) > temp) //If not in the enemy base
949
if((droid.order == DORDER_NONE) or ((droid.orderx != curEnemyX) and (droid.ordery != curEnemyY))) //Idle, or going somewhere else, but not to the enemy base
951
setDroidSecondary(droid, DSO_HALTTYPE, DSS_HALT_GUARD);
952
//if(boolResult == TRUE) //Human
954
// orderDroidLoc(droid, DORDER_MOVE, curEnemyX, curEnemyY);
958
orderDroidLoc(droid, DORDER_SCOUT, curEnemyX, curEnemyY);
961
//else //If already on the way to the enemy base
963
// //Prevent the ant-tail, send units to the center of the group if too far away ahead
964
// if(distBetweenTwoPoints(droid.x, droid.y, tempX, tempY) > (9 * 128)) //If too far away from its buddies
966
// orderDroidLoc(droid, DORDER_MOVE, tempX, tempY); //Prevent ant-tail, send unit back to the group center
970
else //Already in the enemy base
974
showConsoleText(DebugMsg[7], player); //Reached enemy base
978
setDroidSecondary(droid,DSO_HALTTYPE, DSS_HALT_PERSUE); //Persue. For more efficient structure targeting.
980
droid = iterateGroup(attackGroup); //Next droid
989
if(attackPhase == 3) //If attacking
991
//If we were making an early rush then make sure we build more units before we attack again (otherwise will be slowly increased by 1)
997
//They are repairing bunker we attack! Eliminate the truck
998
//--------------------------------------------------------
1000
resetDroidTargets();
1001
setDroidTarPref(DT_CONSTRUCT);
1002
tempDroid = droidTargetInArea(curEnemy, player, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
1003
if(tempDroid != NULLOBJECT)
1005
if(tempDroid.droidType == DROID_CONSTRUCT)
1007
//Order droid close to the truck to attack it
1008
//-------------------------------------------
1010
initIterateGroup(attackGroup);
1011
droid = iterateGroup(attackGroup);
1012
while(droid != NULLOBJECT)
1014
if(distBetweenTwoPoints(droid.x, droid.y, tempDroid.x, tempDroid.y) < (10 * 128))
1015
//if(losTwoObjects(droid, tempDroid, TRUE)) //If can see truck
1017
orderDroidObj(droid, DORDER_ATTACK,tempDroid);
1018
attackObject = tempDroid;
1020
droid = iterateGroup(attackGroup);
1025
//Hi-priority structures
1026
//----------------------
1027
count = numAttackStructs - 1;
1030
result = (15 * 128);
1031
initEnumStruct(FALSE,attackStructs[count],curEnemy,player);
1032
structure = enumStruct();
1033
while(structure != NULLOBJECT)
1035
if(distBetweenTwoPoints(curEnemyX, curEnemyY, structure.x, structure.y) < result) //If in the enemy base
1038
initIterateGroup(attackGroup);
1039
droid = iterateGroup(attackGroup);
1040
while(droid != NULLOBJECT)
1042
if(droid.order != DORDER_ATTACK) //Not already attacking
1044
//if(distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < (12 * 128))
1045
if(losTwoObjects(droid, structure, FALSE)) //If can see this structure
1047
orderDroidObj(droid, DORDER_ATTACK, structure);
1048
sVtolObject = structure;
1051
droid = iterateGroup(attackGroup);
1054
structure = enumStruct();
1059
if(boolResult == FALSE) //Factories
1061
resetStructTargets();
1062
setStructTarPref(ST_FACTORY);
1063
structure = structTargetInArea(curEnemy, player, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
1064
if(structure != NULLOBJECT)
1066
//Order droid close to the factory to attack it
1067
initIterateGroup(attackGroup);
1068
droid = iterateGroup(attackGroup);
1069
while(droid != NULLOBJECT)
1071
if(distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < (10 * 128))
1073
orderDroidObj(droid, DORDER_ATTACK,structure);
1074
attackObject = structure;
1076
droid = iterateGroup(attackGroup);
1082
//--------------------------------------------------------
1083
//Allow repairing if we have repair facilities in outposts
1084
//--------------------------------------------------------
1087
setGroupSecondary(attackGroup, DSO_REPAIR_LEVEL, DSS_REPLEV_HIGH);
1091
setGroupSecondary(attackGroup, DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER);
1096
//------------------------------------------------------
1097
//Finish part-built structures
1098
//------------------------------------------------------
1099
event FinishStructures(inactive)
1101
//Find structure closest to the base
1102
//----------------------------------
1103
temp = tempGroup.members; //Reset cached buildGroup values
1105
structure2 = NULLOBJECT;
1106
initEnumStruct(TRUE,derrick,player,player); //TRUE: iterate through all structures
1107
structure= enumStruct();
1108
while(structure != NULLOBJECT)
1110
if(not structureComplete(structure)) //If structure not finished
1112
//Check if anybody is building it already
1113
//---------------------------------------
1115
initIterateGroup(buildGroup); // find idle droids in build group.
1116
droid = iterateGroup(buildGroup);
1117
while((droid != NULLOBJECT) and (boolResult))
1119
if((droid.orderx == structure.x) and (droid.ordery == structure.y))
1121
boolResult = FALSE; //Somebody is building it, try next structure
1123
droid = iterateGroup(buildGroup);
1126
//Make sure it is not an Outpost defense (since outpost builder is not in the buildGroup)
1127
//--------------------------------------
1130
if(outpostDroid != NULLOBJECT)
1132
if((outpostDroid.orderx == structure.x) and (outpostDroid.ordery == structure.y))
1134
boolResult = FALSE; //Don't finish building this structure
1139
//Remember this structure if it is the closest one so far
1140
//-------------------------------------------------------
1141
if(boolResult) //If nobody is building it already
1143
result2 = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y); //How far away from the base
1144
if(result2 < result) //If this structure is closer than the last one, then store it instead of the last one
1147
structure2 = structure; //Remember this structure
1151
structure = enumStruct();
1154
//Finish building structure, if there are any
1155
//-------------------------------------------
1156
if((structure2 != NULLOBJECT) and (boolResult)) //If found an unbuilt structure and nobody is building it already
1158
//Find closest truck
1159
//------------------
1161
tempDroid = NULLOBJECT;
1162
initIterateGroup(buildGroup); // find idle droids in build group.
1163
droid = iterateGroup(buildGroup);
1164
while(droid != NULLOBJECT)
1166
if(droid.order == DORDER_NONE) //If idle
1168
result2 = distBetweenTwoPoints(droid.x, droid.y, structure2.x, structure2.y); //How far away this truck is from the unfinished structure
1169
if(result2 < result)
1172
tempDroid = droid; //Remember this truck, it is the closest so far
1175
droid = iterateGroup(buildGroup);
1178
//Send to build if found a truck
1179
//------------------------------
1180
if(tempDroid != NULLOBJECT)
1182
orderDroidObj(tempDroid,DORDER_HELPBUILD,structure2);
1187
//------------------------------------------------------
1188
//Destroy enemy derricks
1189
//------------------------------------------------------
1190
event destroyOil(inactive)
1192
if(idleGroup(oilGr) > (oilGr.members / 2))
1194
if(oilGr.members >= maxOilGr)
1197
//if(attackDerrick != NULLOBJECT) //If we have derrick to attack
1202
while((count < numEnemies) and (boolResult == FALSE))
1204
boolResult = structInArea(Enemies[count], oilX - temp, oilY - temp, oilX + temp, oilY + temp);
1210
if(boolResult == FALSE) //No structures found in the area or first search
1212
//Find closest enemy derrick
1213
//--------------------------
1216
structure2 = NULLOBJECT;
1218
while(count < numEnemies)
1220
temp = 2432; //19 * 128
1221
initEnumStruct(FALSE,derrick,Enemies[count],Enemies[count]);
1222
structure = enumStruct();
1223
while(structure != NULLOBJECT)
1225
if(EnemyX[count] > 0)
1227
if(distBetweenTwoPoints(structure.x, structure.y, EnemyX[count], EnemyY[count]) > temp) //Not in the enemy base
1229
result2 = distBetweenTwoPoints(baseX, baseY, structure.x,structure.y);
1230
if(result2 < result)
1233
structure2 = structure;
1237
structure = enumStruct();
1242
//Assign to the found object
1243
//--------------------------
1244
if(structure2 != NULLOBJECT)
1246
//attackDerrick = structure2;
1247
oilX = structure2.x;
1248
oilY = structure2.y;
1253
if(boolResult == TRUE)
1255
orderGroupLoc(oilGr, DORDER_MOVE, oilX, oilY);
1260
//Manage oil attack when arrived, destroy derrick if we can get it
1261
//----------------------------------------------------------------
1262
//if(oilX > 0) //If we have an enemy derrick to attack
1264
// initIterateGroup(oilGr);
1265
// droid = iterateGroup(oilGr);
1266
// while(droid != NULLOBJECT)
1268
// //if(distBetweenTwoPoints(attackDerrick.x, attackDerrick.y, droid.x, droid.y) < (7 128)) //If close
1269
// if(losTwoObjects(droid, attackDerrick, TRUE)) //If we can shoot at the derrick
1271
// orderDroidObj(droid, DORDER_ATTACK, attackDerrick);
1273
// droid = iterateGroup(oilGr);
1278
//------------------------------------------------------
1279
// Find most suitabe enemy
1280
//------------------------------------------------------
1281
event chooseEnemy(chooseEnemyTr)
1284
//if((curEnemy == -1) and (numEnemies > 0))
1287
if((sendOutpostGr.members + attackGroup.members + collectSendGr.members) > numRushers)
1289
temp = -1; //Temp enemy
1292
while(count < numEnemies)
1294
if((isHumanPlayer(Enemies[count])) and (EnemyX[count] > 0))
1296
result2 = distBetweenTwoPoints(baseX, baseY, EnemyX[count], EnemyY[count]);
1297
if(result2 < result)
1299
result = result2; //Remember closest distance so far
1300
result3 = result2; //Remember for later use
1301
temp = Enemies[count];
1307
//If no human players, find the closest AI
1312
while(count < numEnemies)
1314
if(EnemyX[count] > 0)
1316
result2 = distBetweenTwoPoints(baseX, baseY, EnemyX[count], EnemyY[count]);
1317
if(result2 < result)
1319
result = result2; //Remember closest distance so far
1320
result3 = result2; //For later use
1321
temp = Enemies[count];
1329
//Change enemy only if new enemy is *much* closer (20 tiles)
1330
//----------------------------------------------------------
1333
result = distBetweenTwoPoints(baseX, baseY, curEnemyX, curEnemyY) + (20 * 128);
1336
if(((curEnemyX > 0) and (result3 > result)) or (curEnemyX < 1)) //If already have enemy and new enemy is much closer or no enemy set yet
1338
curEnemy = temp; //Remember 'best' enemy
1339
numRetreats = 0; //Reset, need to do it in a better place to make generic
1345
//Find bases again even if (curEnemy != -1) so that attackers could find next factory if its far away
1346
//---------------------------------------------------------------------------------------------------
1348
while(count < numEnemies)
1351
//-----------------------
1352
// Find enemy's base
1353
//-----------------------
1357
//Store enemy base coords, find closest structure
1358
//-----------------------------------------------
1363
while(count2 < numBaseStructs) //For all base structures
1365
initEnumStruct(FALSE,baseStructs[count2],Enemies[count],Enemies[count]);
1366
structure = enumStruct();
1367
while(structure != NULLOBJECT)
1369
//if(structureComplete(structure))
1371
result2 = distBetweenTwoPoints(tempX, tempY, structure.x, structure.y);
1372
if(result2 < result)
1375
EnemyX[count] = structure.x;
1376
EnemyY[count] = structure.y;
1379
structure = enumStruct();
1381
count2 = count2 + 1;
1384
//Remember coordinates of the enemy
1385
//---------------------------------
1386
if(Enemies[count] == curEnemy)
1389
if((EnemyX[count] != -1) and (EnemyY[count] != -1))
1391
curEnemyX = EnemyX[count];
1392
curEnemyY = EnemyY[count];
1395
result = distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, curEnemyX, curEnemyY); //If base moved too much
1396
if((curEnEdgeX == -1) or ((result + (6 * 128)) < outpostDist) or ((result - (6 * 128)) > outpostDist) ) //If no outpost coord yet or enemy base moved too much
1398
//Find 'edge' of the base
1399
//-----------------------
1408
curEnEdgeX = curEnemyX;
1409
curEnEdgeY = curEnemyY;
1411
//Calculate destination point of the attack group for regrouping
1412
//--------------------------------------------------------------
1413
if(curEnEdgeX != -1)
1415
result = 1; //KeepDist; //Assume enemy base to the left
1416
result2 = 1; //KeepDist; //Assume enemy base above the base
1418
if(curEnEdgeX > maxx) //Enemy base to the right
1420
result = result * (-1); //Go to the left from the enemy base for oupost
1422
else if(curEnEdgeX > minx) //Almost on the same X level
1427
if(curEnEdgeY > maxy) //Enemy base lower to the base
1429
result2 = result2 * (-1); //Go up for the outpot y coord
1431
else if(curEnEdgeY > miny) //Almost on the same Y level
1436
curEnEdgeX = curEnEdgeX + (result * KeepDist);
1437
curEnEdgeY = curEnEdgeY + (result2 * KeepDist);
1442
curEnEdgeX = (4 * 128);
1446
curEnEdgeY = (4 * 128);
1448
if(curEnEdgeX > (128 * mapWidth))
1450
curEnEdgeX = ((128 * mapWidth) - (4 * 128));
1452
if(curEnEdgeY > (128 * mapHeight))
1454
curEnEdgeY = ((128*mapHeight) - (4 * 128));
1457
outpostDist = distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, curEnemyX, curEnemyY);
1458
boolResult = pickStructLocation(factory, ref curEnEdgeX, ref curEnEdgeY,player);
1459
if(boolResult == FALSE)
1466
//--------------------------
1468
//--------------------------
1469
//result and result2 are directions
1471
result3 = 0; //Final lenght between enemy base and outpost in tiles
1472
result4 = 150; //Max number of iterations (in tiles)
1474
tempX = curEnemyX + (result * 512); //Skip 4 tiles in outpost's direction
1475
tempY = curEnemyY + (result2 * 512); //Skip 4 tiles in outpost's direction
1477
//Round to 128 (+ 64)
1478
tempX = tempX / 128;
1479
tempX = tempX * 128 + 64;
1481
tempY = tempY / 128;
1482
tempY = tempY * 128 + 64;
1484
boolResult = TRUE; //Horizontal direction not blocked
1485
boolResult2 = TRUE; //Vertical direction not blocked
1486
while((result4 > 0) and (result3 < 85)) //while still tries left and dist less than 50 tiles
1488
//---------------------------------------------
1489
//Choose new coordinates
1490
//---------------------------------------------
1491
if(temp == 0) //Move Horizontally
1493
buildX = tempX + (result * 128); //Move 1 tile in outpost's direction horizontaly (x)
1496
else //Move vertically
1499
buildY = tempY + (result2 * 128); //Move 1 tile in outpost's direction vertically (y)
1502
//---------------------------------------------
1503
//Check new location with a wall
1504
//---------------------------------------------
1505
count = buildX; //Remember to compare later
1508
if(pickStructLocation(wall, ref buildX, ref buildY, player)) //Try this location
1511
if((count != (buildX + 128)) or (count2 != (buildY + 128))) //If this location is not accessible (building coords were modified)
1514
//setPowerLevel(buildX, player);
1515
//addStructure( vtolPad, player, tempX - (3 * 128) , tempY ); //DEBUG
1516
showConsoleText(DebugMsg[2], player);
1518
if(temp == 0) //Moving horizontally
1520
boolResult = FALSE; //Can't move horizontally
1522
else //Moving vertically
1524
boolResult2 = FALSE; //Can't move vertically
1527
else //This tile is ok
1529
showConsoleText(DebugMsg[3], player);
1530
addStructure( wall, player, count , count2 ); //DEBUG
1532
tempX = count; //Remember new coords permanently
1533
tempY = count2; //Remember new coords permanently
1535
if(temp == 0) //Moving horizontally
1537
boolResult = TRUE; //Cancel direction blockage flag, if was blocked
1539
else //Moving vertically
1541
boolResult2 = TRUE; //Cancel direction blockage flag, if was blocked
1544
result3 = result3 + 1; //Moved 1 tile
1548
//------------------------------------------------
1549
//If can't move further in the outpost's direction
1550
//------------------------------------------------
1551
if((not boolResult) and (not boolResult2)) //If both directions blocked (hor and vert)
1553
showConsoleText(DebugMsg[1], player);
1554
if(temp==0) //Was moving horizontally this time (X)
1556
buildY = tempY - (result2 * 128);
1558
count = buildX; //Remember to compare later
1560
pickStructLocation(wall, ref buildX, ref buildY,player); //Try this location
1561
if((count == (buildX + 128)) and (count2 == (buildY + 128))) //If this location is accessible (building coords were same)
1566
boolResult2 = TRUE; //Reset Vertical blockage
1569
else //Was moving vertically this time (Y)
1571
buildX = tempX - (result * 128); //Move 1 tile back (reversed) into a horizontal direction
1573
count = buildX; //Remember to compare later
1575
pickStructLocation(wall, ref buildX, ref buildY,player); //Try this location
1576
if((count == (buildX + 128)) and (count2 == (buildY + 128))) //If this location is accessible (building coords were same)
1578
temp = 0; //Move vertically again next time (temp will be set to 1 later)
1579
tempX = count; //Remember new X position
1581
boolResult = TRUE; //Reset Horizontal blockage
1585
//boolResult = TRUE; //Reset Horizontal blockage
1586
//boolResult2 = TRUE; //Reset Vertical blockage
1589
//--------------------------------
1590
//Cycle moving direction
1591
//--------------------------------
1594
temp = 1; //Vertically next time
1598
temp = 0; //Horizontally next time
1602
result4 = result4 - 1;
1613
if(tempX > (128 * mapWidth))
1615
tempX = ((128 * mapWidth) - (4 * 128));
1617
if(tempY > (128 * mapHeight))
1619
tempY = ((128*mapHeight) - (4 * 128));
1622
centreViewPos(tempX, tempY);
1634
//==============================================================================================
1636
// [RUSH PREPARATION]
1638
//==============================================================================================
1641
//------------------------------------------------------
1642
// Initialize rush preparation phase.
1643
//------------------------------------------------------
1644
event initializeRushPrep(inactive)
1646
mainPhase = 1; //Next phase became active
1649
//------------------------------------------------------
1650
// Build attack units
1651
//------------------------------------------------------
1652
event BuildAttackForce(BuildAttackForceTr)
1654
//Enable more trucks after 15 mins, if got stuck in Lego phase somehow
1660
//Manage truck production
1661
//-----------------------
1662
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)
1663
temp = 2; //How many trucks to build at a time
1665
//if(buildGroup.members == 0)
1667
// temp = 5; //Build more trucks at a time
1670
temp = maxTrucks - buildGroup.members;
1673
temp = 5; //How many trucks to build at a time
1678
result = 0; //Index of the current factory (count factories)
1679
initEnumStruct(FALSE,factory,player,player);
1680
structure = enumStruct();
1681
while(structure != NULLOBJECT)
1683
if((structureIdle(structure) == TRUE) and (structureComplete(structure)))
1685
boolResult = TRUE; //Didn't start building anything yet
1687
//We have not enough trucks
1688
//-------------------------
1691
if((buildGroup.members < maxTrucks) and (result2 < temp)) //Only <temp> trucks at a time
1693
buildDroid(constructor, structure, player, 1); //Normal one
1694
result2 = result2 + 1; //Count trucks
1699
if(boolResult) //Didn't start build anything yet
1701
if((attackPhase > 0) and (result == 0) and (not defendingBase)) //If no repair unit and we already have enough attackers, use only 1 factory (result == 0)
1703
if(repDefendDroid[0] == NULLOBJECT)
1707
else if(repDefendDroid[1] == NULLOBJECT)
1713
if(not boolResult) //If decided to build a repair unit
1715
if(skCanBuildTemplate(player,structure, tmplRep[1]))
1717
buildDroid(tmplRep[1], structure, player, 1); //Heavy repair unit
1721
buildDroid(tmplRep[0], structure, player, 1); //Light repair unit
1728
//----------------------
1729
if(boolResult) //Didn't start build anything yet
1731
//Decide weather to use cheap or expensive templates
1732
//--------------------------------------------------
1733
result3 = 0; //Cheap templates
1734
if(playerPower(player) > muchoPower)
1736
result3 = 1; //Use expensive templates if we have plenty of power
1739
//Fill array with best templates
1740
//------------------------------
1742
count = numTemplates - 1;
1743
while((count2 < TemplDepth) and (count >= 0))
1745
if(skCanBuildTemplate(player,structure, tmpl[result3][count]))
1747
//setFogColour(random(200) + 50, 1, 1);
1749
tmplChoice[count2] = tmpl[result3][count];
1750
count2 = count2 + 1; //We have chosen one more template
1752
count = count - 1; //Check next template
1755
if(count2 > 0) //Any templates found
1758
if(getDroidCount(player) < 85) //Let it build VTOLs and trucks
1761
buildDroid(tmplChoice[random(count2)],structure,player,1);
1766
result = result + 1; //Remember factory index
1767
structure = enumStruct();
1771
//--------------------------------------------------------
1773
//--------------------------------------------------------
1774
event buildCyborgs(buildCyborgsTr)
1776
if((transportGr.members < 10) and (dropGr.members < 6) and (dropPhase == 0))
1778
if(getStructure(vtolFactory,player) != NULLOBJECT) //Already have VTOL tech to build transporter soon?
1780
if(dropEnabled and (not powerSaving))
1782
initEnumStruct(FALSE,cybFactory,player,player);
1783
structure= enumStruct(); //Find factory
1784
while(structure != NULLOBJECT)
1786
if(structureIdle(structure))
1789
//count = 1; //numTemplates - 1
1793
// if(skCanBuildTemplate(player,structure, cybTmpl[count]) )
1795
// tmplChoice[count2] = cybTmpl[count];
1796
// count2 = count2 + 1;
1798
// count = count - 1;
1801
if(cybTemplate > -1)
1803
buildDroid(cybTmpl[cybTemplate],structure,player,1);
1806
structure= enumStruct();
1815
//------------------------------------------------------
1817
//------------------------------------------------------
1818
event doResearch(doResearchTr)
1820
//Count how many are already researching
1821
//--------------------------------------
1822
initEnumStruct(FALSE,resLab,player,player);
1823
structure = enumStruct();
1825
while(structure != NULLOBJECT)
1827
if(not structureIdle(structure)) //Max 2 res fac if low on power
1829
result = result + 1;
1831
structure = enumStruct();
1834
temp = 2; /*%! ID="MaxResFacLowPower",
1835
MainDesc="When low on power limit research to x facilities",
1837
type="asn", //Assign
1839
ArgDesc="2 (Default)",
1841
ArgDesc="Pause researching",
1855
ArgDesc="Don't limit" */
1860
initEnumStruct(FALSE,resLab,player,player);
1861
structure = enumStruct();
1862
while(structure != NULLOBJECT)
1864
if(structureIdle(structure)) //Not researching already
1866
if((not powerSaving) or (powerSaving and (result < temp)) or (temp == -1)) //Max 2 res fac if low on power (if enough power or low power, but still not enough res labs working)
1869
if(not ((mainPhase >= 2) and (result >= 3) and (playerPower(player) < 600))) //If we already have Trck Python HC template (and low on power) then don't use more then 3 res fac, since no new usefull tech
1871
skDoResearch(structure,player,0);
1872
result = result + 1;
1876
structure = enumStruct();
1881
//------------------------------------------------------
1882
// Build derricks with nearest truck
1883
//------------------------------------------------------
1884
event buildDerricks(inactive)
1886
//Find closest oil resource
1887
//-------------------------
1889
feature2 = NULLOBJECT;
1890
initGetFeature(oilRes,player,player);
1891
feature = getFeature(player);
1892
while(feature != NULLOBJECT)
1894
//Make sure no other truck is trying to build it
1895
//-----------------------------------------------
1897
initIterateGroup(buildGroup);
1898
droid = iterateGroup(buildGroup);
1899
while((droid != NULLOBJECT) and (boolResult))
1901
if(droid.order == DORDER_BUILD)
1903
if((droid.orderx == feature.x) and (droid.ordery == feature.y))
1908
droid = iterateGroup(buildGroup);
1911
//Make sure there are no enemy units and defenses nearby
1916
while((count < numEnemies) and (boolResult))
1918
resetStructTargets();
1919
setStructTarPref(ST_DEF_GROUND);
1921
//if(numStructsByTypeInArea(Enemies[count], REF_DEFENSE, feature.x - temp, feature.y - temp, feature.x + temp, feature.y + temp) > 0)
1923
structure = structTargetInArea(Enemies[count], Enemies[count], feature.x - temp, feature.y - temp, feature.x + temp, feature.y + temp);
1924
if(structure != NULLOBJECT)
1926
boolResult = FALSE; //Too dangerous
1930
resetDroidTargets();
1931
setDroidTarPref(DT_WEAP_GROUND);
1932
droid = droidTargetInArea(Enemies[count], Enemies[count], feature.x - temp, feature.y - temp, feature.x + temp, feature.y + temp);
1933
if(droid != NULLOBJECT)
1935
boolResult = FALSE; //Too dangerous
1943
//Remember closest structure
1944
//--------------------------
1945
if(boolResult) //If not trying to build already and no enemy defenses
1947
result2 = distBetweenTwoPoints(baseX, baseY, feature.x, feature.y); //How close to the base
1948
if(result2 < result) //If closer
1951
feature2 = feature; //Remember this oil resource
1955
feature = getFeature(player);
1960
if(feature2 != NULLOBJECT)
1962
//Find closest truck
1963
//------------------
1964
tempDroid = NULLOBJECT;
1966
initIterateGroup(buildGroup);
1967
droid = iterateGroup(buildGroup);
1968
while(droid != NULLOBJECT)
1970
if(droid.order == DORDER_NONE)
1972
result2 = distBetweenTwoPoints(droid.x, droid.y, feature2.x, feature2.y);
1973
if(result2 < result)
1979
droid = iterateGroup(buildGroup);
1984
if(tempDroid != NULLOBJECT)
1986
orderDroidStatsLoc(tempDroid, DORDER_BUILD,derrick, feature2.x, feature2.y);
1992
//------------------------------------------------------
1993
// Send scouts to look for oil resources
1994
//------------------------------------------------------
1995
event sendScouts(sendScoutsTr)
1998
temp = (43 * 128); //Step
2000
while(count < maxScouts)
2002
if(scoutGroup[count].members > 0)
2004
if(idleGroup(scoutGroup[count]) > (scoutGroup[count].members /2))
2006
if(count > 1) //3rd scout vitits random places (only on big maps)
2008
tempX = random(mapWidth) * 128;
2009
tempY = random(mapHeight) * 128;
2010
boolResult = pickStructLocation(vtolPad, ref tempX, ref tempY,player);
2011
if(boolResult == TRUE)
2013
orderGroupLoc(scoutGroup[count], DORDER_MOVE, tempX, tempY);
2016
else //Using a scouting algorithm for the first 2 scouts
2018
//Send to scout before choosing new coords, so that
2019
//they would visit the initial (first) location
2020
//-------------------------------------------------
2021
tempX = scoutX[count];
2022
tempY = scoutY[count];
2023
boolResult = pickStructLocation(vtolPad, ref tempX, ref tempY,player);
2024
if(boolResult == TRUE)
2026
orderGroupLoc(scoutGroup[count], DORDER_MOVE, tempX, tempY);
2030
//Try 3 times to find a safe scouting location
2031
//--------------------------------------------
2033
result = 0; //Number of times failed to find safe location
2034
while((result < 3) and (not boolResult)) //May fail max 3 times
2036
if(count == 0) //SCOUT1: From bottom left to the top
2038
scoutY[count] = scoutY[count] - temp; //Move up 1 step
2039
if(scoutY[count] < 512) //If reached top
2041
scoutY[count] = (128 * mapHeight) - (9 * 128); //Back to bottom
2042
scoutX[count] = scoutX[count] + temp; //Move right 1 step
2045
if(scoutX[count] > (mapWidth * 128)) //If reached right border
2047
scoutX[count] = (9 * 128); //Start from the left
2051
else //SCOUT2: From top right to the left
2053
scoutX[count] = scoutX[count] - temp; //Move left 1 step
2054
if(scoutX[count] < 512) //If reached left border
2056
scoutX[count] = (mapWidth * 128) - (9 * 128); //Start from right
2057
scoutY[count] = scoutY[count] + temp; //Move line down
2060
if(scoutY[count] > (128 * mapHeight)) //If reached bottom
2062
scoutY[count] = (9 * 128); //Start from top
2067
//Check if new scouting location is safe
2068
//--------------------------------------
2070
boolResult = TRUE; //All ok right now (for max tries)
2071
while((count2 < numEnemies) and (boolResult))
2073
if(objectInRange(Enemies[count2], scoutX[count],scoutY[count], 1280)) //10*128
2075
boolResult = FALSE; //This location failed this time
2076
result = result + 1; //# of times safety check failed
2078
count2 = count2 + 1; //Next enemy
2089
//------------------------------------------------------
2091
//------------------------------------------------------
2092
event expandBase(inactive)
2094
//if(not powerSaving)
2096
if(extraStruct == numExtraStructs) // loop round
2101
//We have all vital structures, expand the base
2102
//---------------------------------------------
2104
if(isStructureAvailable(extraStructs[extraStruct],player))
2109
//Don't try to build a second HQ
2110
//------------------------------
2112
if(extraStruct == 2) //HQ
2114
if(getStructure(extraStructs[2],player) != NULLOBJECT)
2116
boolResult2 = FALSE;
2121
if(boolResult2) //If not a second HQ
2123
boolResult2 = pickStructLocation(extraStructs[extraStruct], ref buildX, ref buildY,player);
2124
if(boolResult2 == TRUE)
2134
tempDroid = NULLOBJECT;
2136
initIterateGroup(buildGroup);
2137
droid = iterateGroup(buildGroup);
2138
while(droid != NULLOBJECT)
2140
if(droid.order == DORDER_NONE)
2142
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
2143
if(result2 < result)
2149
droid = iterateGroup(buildGroup);
2152
if(tempDroid != NULLOBJECT)
2154
orderDroidStatsLoc(tempDroid, DORDER_BUILD,extraStructs[extraStruct], buildX,buildY);
2157
extraStruct = extraStruct + 1; //Next structure
2162
//------------------------------------------------------
2163
// Build base defenses
2164
//------------------------------------------------------
2165
event buildDefenses(inactive)
2169
count = numDefenses - 1;
2172
while((boolResult == TRUE) and (count >= 0))
2174
if(isStructureAvailable(defenses[count],player))
2176
structChoice[0] = defenses[count];
2182
if(boolResult == FALSE)
2186
boolResult2 = pickStructLocation(powGen, ref buildX, ref buildY,player);
2187
if(boolResult2 == TRUE)
2190
tempDroid = NULLOBJECT;
2192
initIterateGroup(buildGroup);
2193
droid = iterateGroup(buildGroup);
2194
while(droid != NULLOBJECT) //Find truck who is near the oil resource
2196
if(droid.order == DORDER_NONE)
2198
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
2199
if(result2 < result)
2205
droid = iterateGroup(buildGroup);
2208
if(tempDroid != NULLOBJECT)
2210
orderDroidStatsLoc(tempDroid, DORDER_BUILD,structChoice[0], buildX,buildY);
2218
//------------------------------------------------------
2219
// Build oil defenses
2220
//------------------------------------------------------
2221
event oilDefenses(inactive)
2225
temp = (4 * 128); //Defenses range
2228
structure2 = NULLOBJECT;
2230
initEnumStruct(FALSE,derrick,player,player);
2231
structure = enumStruct();
2232
while(structure != NULLOBJECT)
2234
result2 = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y);
2235
if(result2 < result)
2239
//If not within a base
2240
//--------------------
2241
if((structure.x > minx) and (structure.y > miny) and (structure.x < maxx) and (structure.y <maxy))
2246
//If not to many defenses already
2247
//-------------------------------
2248
if(boolResult == TRUE)
2250
if(numStructsInArea(player, structure.x - temp, structure.y - temp, structure.x + temp, structure.y + temp) > 3)
2256
//Choose best defense
2257
//-------------------
2258
if(boolResult == TRUE)
2260
count = numDefenses - 1;
2262
while((count >= 0) and (boolResult == FALSE))
2264
if(isStructureAvailable(defenses[count], player))
2266
structChoice[0] = defenses[count];
2267
boolResult = TRUE; //Stop
2273
if(boolResult == TRUE)
2275
//If we have a derrick to defend
2276
//------------------------------
2279
tempDroid = NULLOBJECT;
2281
initIterateGroup(buildGroup);
2282
droid = iterateGroup(buildGroup);
2283
while(droid != NULLOBJECT)
2285
if(droid.order == DORDER_NONE)
2287
result4 = distBetweenTwoPoints(structure.x, structure.y, droid.x, droid.y);
2288
if(result4 < result3)
2295
droid = iterateGroup(buildGroup);
2299
//If we have a droid
2300
//------------------
2301
if(boolResult == TRUE)
2303
buildX = structure.x;
2304
buildY = structure.y;
2305
boolResult = pickStructLocation(structChoice[0], ref buildX, ref buildY,player);
2306
if(boolResult == TRUE)
2309
if((buildX > structure.x - temp) and (buildY > structure.y - temp) and (buildX < structure.x + temp) and (buildY < structure.y + temp)) //If in the range
2316
if(boolResult == TRUE)
2319
structure2 = structure;
2322
structure = enumStruct();
2325
//If we can build it now
2326
//----------------------
2327
if((structure2 != NULLOBJECT) and (tempDroid != NULLOBJECT))
2329
orderDroidStatsLoc(tempDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
2334
//------------------------------------------------------
2335
// Keep details about the size and postion of the
2337
//------------------------------------------------------
2338
event basedetails(basedetailsTr)
2340
// clear old extremities
2341
//----------------------
2344
miny = (mapHeight*128);
2345
minx = (mapWidth*128);
2347
//Now find the extremities of our vital structures
2348
//------------------------------------------------
2350
while(count < numBaseStructs)
2352
initEnumStruct(FALSE,baseStructs[count],player,player);
2353
structure = enumStruct();
2354
while(structure != NULLOBJECT)
2356
if(structure.x < minx)
2358
minx = structure.x; // - 896;
2360
if(structure.x > maxx)
2362
maxx = structure.x; // + 896;
2364
if(structure.y < miny)
2366
miny = structure.y; // - 896;
2368
if(structure.y > maxy)
2370
maxy = structure.y; // + 896;
2372
structure = enumStruct();
2377
//Must be done here, after all structures are checked, otherwise
2378
//even if structure2.x < structure.x, (structure.x - minx) might be less and minx won't be set to
2379
//structure2.x, even if (structure2.x < structure.x), base won't expand enough
2380
//--------------------------------
2393
//minx = minx - 896;
2394
//maxx = maxx + 896;
2395
//miny = miny - 896;
2396
//maxy = maxy + 896;
2398
//Check everything's within limits
2399
//--------------------------------
2408
if(maxx > (mapWidth * 128))
2410
maxx = (mapWidth * 128) - 128;
2412
if(maxy > (mapHeight * 128))
2414
maxy = (mapHeight * 128) - 128;
2419
//==============================================================================================
2421
// [Other stuff important for all phases]
2423
//==============================================================================================
2425
//------------------------------------------------------
2426
// Keep track on the other players
2427
//------------------------------------------------------
2428
event keepTrack(keepTrackTr)
2434
allyPlayer[count] = FALSE;
2435
actPlayer[count] = FALSE;
2437
if(count != player) //Not me
2440
//Check if player has any structures (still alive)
2441
//------------------------------------------------
2444
while((count2 < numBaseStructs) and (not boolResult)) //For all base structures
2446
if(getStructure(baseStructs[count2],count) != NULLOBJECT)
2450
count2 = count2 + 1;
2453
if(boolResult) //If alive
2455
actPlayer[count] = TRUE;
2458
if(allianceExistsBetween(player,count))
2460
allyPlayer[count] = TRUE;
2464
//Find enemy's base by finding its base structures
2465
Enemies[numEnemies] = count; //Remember all enemies
2466
numEnemies = numEnemies + 1;
2475
//------------------------------------------------------
2476
// Deal with a droid being destroyed
2477
//------------------------------------------------------
2478
event droidDestroyed(droidDestroyedTr)
2480
count = 0; //Do nothing
2482
//if(droid.droidType == DROID_CONSTRUCT)
2484
// if(droid != outpostDroid) //If wasn't outpost builder (will outpostDroid be NULLOBJECT already?)
2486
// numTrucks = numTrucks - 1;
2492
//------------------------------------------------------
2493
// Build a power gen for every 4 derricks
2494
//------------------------------------------------------
2495
event buildPowerGenerators(buildPowerGeneratorsTr)
2498
initEnumStruct(FALSE,derrick,player,player); // count = numderricks
2499
structure = enumStruct();
2500
while(structure != NULLOBJECT)
2503
structure = enumStruct();
2507
initEnumStruct(FALSE,powGen,player,player); // count2 = numpowgens
2508
structure= enumStruct();
2509
while(structure != NULLOBJECT)
2511
count2 = count2 + 1;
2512
structure= enumStruct();
2515
if((count2 * 4) < count) // if we need powergen
2517
buildX = baseX; // try build powergen
2519
boolResult = pickStructLocation(powGen, ref buildX, ref buildY,player);
2520
if(boolResult == TRUE)
2523
tempDroid = NULLOBJECT;
2525
initIterateGroup(buildGroup);
2526
droid = iterateGroup(buildGroup);
2527
while(droid != NULLOBJECT) //Find truck who is near the oil resource
2529
if(droid.order == DORDER_NONE)
2531
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
2532
if(result2 < result)
2538
droid = iterateGroup(buildGroup);
2541
if(tempDroid != NULLOBJECT)
2543
orderDroidStatsLoc(tempDroid, DORDER_BUILD,powGen, buildX,buildY);
2550
//------------------------------------------------------
2551
// Build trucks if necessary
2552
//------------------------------------------------------
2553
event LegoTrucks(LegoTrucksTr)
2555
initEnumStruct(FALSE,factory,player,player);
2556
structure = enumStruct();
2557
if((structure != NULLOBJECT) and (buildGroup.members < maxTrucks))
2559
if(structureIdle(structure))
2561
buildDroid(constructor, structure, player, 1);
2567
//------------------------------------------------------
2568
// Deal with a droid being built
2569
//------------------------------------------------------
2570
event droidBuilt(droidBuiltTr)
2573
if(droid.droidType == DROID_CONSTRUCT) // if constructor droid
2575
groupAddDroid(buildGroup, droid);
2577
else if((droid.droidType == DROID_CYBORG) or (droid.propulsion == cyborgProp)) //Cyborg or heavy cyborg
2579
groupAddDroid(transportGr, droid);
2581
else if(droid.droidType == DROID_TRANSPORTER)
2583
//if(transportDroid == NULLOBJECT)
2585
transportDroid = droid;
2586
orderDroidLoc(transportDroid, DORDER_MOVE, baseX, baseY);
2587
//setDroidSecondary(transportDroid, DSO_ATTACK_LEVEL, DSS_ALEV_NEVER);
2593
setDroidSecondary(droid, DSO_ATTACK_RANGE, DSS_ARANGE_LONG);
2597
orderDroid(droid, DORDER_RTB); //Move away
2602
while((count < numSVtolTemplates) and (not boolResult))
2604
if(droid.weapon == sVtolWeapon[count])
2606
//setFogColour(1, 1, random(200) + 50);
2608
groupAddDroid(sVtolGr, droid); //Antistructure
2609
//setFogColour(random(200) + 50, 1, 1);
2617
groupAddDroid(tVtolGr, droid);
2623
setDroidSecondary(droid, DSO_ATTACK_RANGE, DSS_ARANGE_LONG); //Was short
2626
//---------------------------
2627
if(droid.droidType == DROID_REPAIR)
2629
setDroidSecondary(droid, DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER); //Perair units never repair
2631
if(repDefendDroid[0] == NULLOBJECT)
2633
repDefendDroid[0] = droid;
2636
else if(repDefendDroid[1] == NULLOBJECT)
2638
repDefendDroid[1] = droid;
2644
//---------------------------
2646
while((count < maxScouts) and (boolResult))
2648
if(scoutGroup[count].members == 0)
2650
groupAddDroid(scoutGroup[count], droid);
2659
if(scoutGroup[2].members == 0)
2661
if(((attackGroup.members + sendOutpostGr.members) > numRushers) and (defendGr.members >= maxDefenders))
2663
groupAddDroid(scoutGroup[2], droid);
2671
//---------------------------
2674
//if((attackPhase > 0) or (alreadyAttacked)) //Send to attack for the first time or not attacking right now, but attacked before (attackState=0, but alreadyAttacked)
2675
if(alreadyAttacked) //Already sent units to the outpost
2677
if(((attackGroup.members > numRushers) and (defendGr.members < maxDefenders)) or (defendGr.members < 7) or (defendingBase))
2679
if(defendGr.members < maxDefenders)
2681
groupAddDroid(defendGr, droid);
2690
//---------------------------
2691
//if(boolResult and ((attackGroup.members >= numRushers) or ((attackPhase > 0) and (defendGr.members < 5)))) //If already many rushers or (have already rushed and not enough defenders)
2693
// if(defendGr.members < maxDefenders)
2695
// if(mainPhase > 0)
2697
// groupAddDroid(defendGr, droid);
2698
// boolResult = FALSE;
2705
//---------------------------
2706
if(boolResult and (attackGroup.members > numRushers))
2708
if(oilGr.members < maxOilGr)
2710
groupAddDroid(oilGr, droid);
2716
//---------------------------
2719
groupAddDroid(collectSendGr, droid);
2721
//groupAddDroid(sendOutpostGr, droid);
2724
//Increase number of defenders
2725
//----------------------------
2726
if(attackGroup.members > numRushers)
2728
if((defendGr.members >= maxDefenders) and (maxDefenders < 14) and (alreadyAttacked)) //(attackPhase > 0): if we have already enough attackers and started attacking
2730
maxDefenders = maxDefenders + 1;
2738
//------------------------------------------------------
2739
// Cheat a bit, like Pumpkin AI, not more
2740
//------------------------------------------------------
2741
event difficultyMod(difficultyModTr)
2743
skDifficultyModifier(player);
2744
randomiseSeed(); //Will not hurt if done once in a while
2748
//------------------------------------------------------
2749
// Upgrade structures
2750
//------------------------------------------------------
2751
event upgradeStructures(upgradeStructuresTr)
2754
//Find closest truck
2755
//-------------------
2759
tempDroid = NULLOBJECT;
2762
initIterateGroup(buildGroup);
2763
droid = iterateGroup(buildGroup);
2764
while(droid != NULLOBJECT)
2766
if(droid.order == DORDER_NONE)
2768
result2 = distBetweenTwoPoints(tempX, tempY, droid.x, droid.y);
2769
if(result2 < result)
2775
droid = iterateGroup(buildGroup);
2778
//------------------
2781
initEnumStruct(FALSE,factory,player,player);
2782
structure= enumStruct();
2783
while(structure != NULLOBJECT)
2785
if(structureComplete(structure))
2787
if(isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 2 ))
2789
if((attackPhase > 0) or (skCanBuildTemplate(player,structure, tmpl[0][8]))) //Don't upgrade while preparing the first rush or upgrade if it's necessary to be able to build units in T3
2791
if(tempDroid != NULLOBJECT)
2794
orderDroidStatsLoc(tempDroid, DORDER_BUILD,facModule, structure.x,structure.y);
2799
structure= enumStruct();
2802
//------------------
2804
//------------------
2805
initEnumStruct(FALSE,powGen,player,player);
2806
structure= enumStruct();
2807
while(structure != NULLOBJECT)
2809
if(structureComplete(structure))
2811
if(isStructureAvailable(powModule,player) and (not testStructureModule(player, structure, 0)))
2813
if((tempDroid != NULLOBJECT) and (boolResult == TRUE))
2816
orderDroidStatsLoc(tempDroid,DORDER_BUILD,powModule, structure.x,structure.y); //Upgrade it.
2820
structure= enumStruct();
2828
initEnumStruct(FALSE,resLab,player,player);
2829
structure= enumStruct();
2830
while(structure != NULLOBJECT)
2832
if(structureComplete(structure))
2834
if( isStructureAvailable(resModule,player) and (not testStructureModule(player, structure, 0)))
2836
if((tempDroid != NULLOBJECT) and (boolResult == TRUE))
2839
orderDroidStatsLoc(tempDroid, DORDER_BUILD,resModule, structure.x,structure.y);
2843
structure= enumStruct();
2846
//-------------------
2848
//-------------------
2851
initEnumStruct(FALSE,vtolFactory,player,player);
2852
structure= enumStruct();
2853
while(structure != NULLOBJECT)
2855
if(structureComplete(structure))
2857
if(isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 2 ))
2859
if((tempDroid != NULLOBJECT) and (boolResult == TRUE))
2862
orderDroidStatsLoc(tempDroid, DORDER_BUILD,facModule, structure.x,structure.y);
2866
structure = enumStruct();
2873
//------------------------------------------------------
2874
// Run for a bit when attacked
2875
//------------------------------------------------------
2876
event moveIfAttacked(moveIfAttackedTr)
2878
//If unit is still alive and is still under attack
2879
if((droid != NULLOBJECT) and (baseobj != NULLOBJECT))
2881
//If during the attack
2882
//if(attackPhase >= 2)
2884
// if(groupMember(attackGroup, droid))
2886
// if(distBetweenTwoPoints(curEnemyX, curEnemyY, baseobj.x, baseobj.y) < (KeepDist / 2))
2888
// if(losTwoObjects(droid, baseobj, TRUE)) //Only if we can see the enemy (get out of his range)
2890
// orderDroidLoc(droid, DORDER_MOVE, curEnEdgeX, curEnEdgeY); //Retreat
2896
if(baseobj.player != player) //Not attacking itself by an accident or with a mass-weapon
2900
if(baseobj.type == OBJ_DROID)
2902
if(isVtol(objToDroid(baseobj)))
2904
boolResult = FALSE; //Attacked by a VTOL
2908
if(droid.type == OBJ_DROID)
2910
if(isVtol(objToDroid(droid)))
2912
boolResult = FALSE; //VTOL was attacked
2916
//If we have a weapon, then answer
2917
//--------------------------------
2918
if(boolResult) //If a land unit or a defense
2920
if(droid.droidType == DROID_WEAPON) //Has a weapon
2922
if(droid.order == DORDER_NONE) //Not already attacking
2924
if(losTwoObjects(droid, baseobj, TRUE)) //If we can see attacker
2926
//orderDroidObj(droid, DORDER_ATTACK, baseobj);
2927
orderDroidLoc(droid, DORDER_SCOUT, baseobj.x, baseobj.y);
2932
//Help a friend if we are near
2933
//----------------------------
2934
if(groupMember(attackGroup, droid))
2937
initIterateGroup(attackGroup);
2938
tempDroid = iterateGroup(attackGroup);
2939
while(tempDroid != NULLOBJECT)
2941
if(tempDroid.order == DORDER_NONE)
2943
if(distBetweenTwoPoints(tempDroid.x, tempDroid.y, droid.x, droid.y) < temp)
2945
//if(losTwoObjects(tempDroid, baseobj, TRUE)) //If we can see attacker
2947
//orderDroidObj(tempDroid, DORDER_ATTACK, baseobj);
2948
orderDroidLoc(tempDroid, DORDER_SCOUT, baseobj.x, baseobj.y);
2952
tempDroid = iterateGroup(attackGroup);
2957
//Vtols and trucks run away
2958
//-------------------------
2959
if((droid.droidType == DROID_CONSTRUCT) or (isVtol(droid))) //If a constructor or a VTOL
2961
if(droid.order == DORDER_NONE)
2964
temp = random(temp * 2) - temp;
2965
orderDroidLoc(droid, DORDER_MOVE, droid.x + temp, droid.y + temp);
2972
//---------------------------------------------------------------
2973
// Build an outpost to retreat to and to repair damaged units
2974
//---------------------------------------------------------------
2975
event BuildOutpost(inactive)
2977
//Find trucks to build the outpost
2978
//--------------------------------
2979
count2 = (KeepDist / 2);
2981
//Reduce number of defenses temporary if low on power
2982
temp = 6; /*%! ID="NumOutpostDef",
2983
MainDesc="Num outpost defences",
2984
type="asn", //Assign
2986
ArgDesc="6 (Default)",
3000
temp = 2; /*%! ID="NumOutpostDefLowPow",
3001
MainDesc="Num outpost defences on low power",
3002
type="asn", //Assign
3004
ArgDesc="2 (Default)",
3016
ArgDesc="Same value as above" */
3019
if(outpostDroid == NULLOBJECT)
3021
if(not defendingBase) //Need trucks for base rebuilding now
3023
initIterateGroup(buildGroup);
3024
droid = iterateGroup(buildGroup);
3025
while((droid != NULLOBJECT) and (outpostDroid == NULLOBJECT))
3027
if(droid.order == DORDER_NONE)
3029
droidLeaveGroup(droid);
3030
outpostDroid = droid;
3031
orderDroidLoc(outpostDroid, DORDER_MOVE, curEnEdgeX, curEnEdgeY);
3033
droid = iterateGroup(buildGroup);
3038
//--------------------------------------------------------
3039
//Check if we have all necessary structures in the outpost
3040
//--------------------------------------------------------
3041
if((outpostDroid != NULLOBJECT) and (curEnEdgeX > 0) and (not defendingBase)) //If we have trucks, have outpost coords and don't need money for the base
3045
//-------------------------
3046
//Remove old rep facilities
3047
//-------------------------
3048
initEnumStruct(FALSE,repairFacility,player,player);
3049
structure = enumStruct();
3050
while(structure != NULLOBJECT)
3052
//Demolish if outside of the new edge
3053
if(distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, structure.x, structure.y) > count2)
3055
if((outpostDroid.order == DORDER_NONE) or (outpostDroid.order == DORDER_MOVE)) //Not busy
3057
orderDroidObj(outpostDroid, DORDER_DEMOLISH, structure);
3060
structure = enumStruct();
3063
//-----------------------
3064
//Check repair facilities
3065
//-----------------------
3066
result = numStructsByTypeInArea(player, REF_REPAIR_FACILITY, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2);
3067
if(result < 1) //We need repair facilities
3069
boolResult = FALSE; //Not done building outpost yet
3071
buildX = curEnEdgeX; //Outpost coords = build coords
3072
buildY = curEnEdgeY;
3073
boolResult2 = pickStructLocation(repairFacility, ref buildX, ref buildY, player);
3074
if(boolResult2 == TRUE) //If we can build
3076
//Not outside of the outpost
3077
//--------------------------
3078
if(distBetweenTwoPoints(curEnEdgeX, curEnEdgeY, buildX, buildY) < count2)
3080
if((outpostDroid.order == DORDER_NONE) or (outpostDroid.order == DORDER_MOVE)) //Not busy
3082
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, repairFacility, buildX,buildY);
3088
//---------------------------------------------------
3089
//Build some defenses in the outpost if we are idling
3090
//---------------------------------------------------
3091
if(outpostDroid.order == DORDER_NONE) //Not busy
3097
while(count < numDefenses)
3099
initEnumStruct(FALSE,defenses[count],player,player);
3100
structure = enumStruct();
3101
while(structure != NULLOBJECT)
3103
if(distBetweenTwoPoints(structure.x, structure.y, curEnEdgeX, curEnEdgeY) < count2) //In the outpost
3105
result = result + 1;
3107
structure = enumStruct();
3112
//if(numStructsInArea(player, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2) < count)
3115
//Choose best defense
3116
//-------------------
3117
count = numDefenses - 1;
3119
while((count >= 0) and (boolResult == FALSE))
3121
if(isStructureAvailable(defenses[count], player))
3123
structChoice[0] = defenses[count];
3124
boolResult = TRUE; //Stop
3129
if(boolResult == TRUE) //If we have a defense we can build
3131
buildX = curEnEdgeX;
3132
buildY = curEnEdgeY;
3133
boolResult = pickStructLocation(powGen, ref buildX, ref buildY, player);
3134
if(boolResult == TRUE)
3136
if(distBetweenTwoPoints(buildX, buildY, curEnEdgeX, curEnEdgeY) < count2)
3138
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
3148
result4 = 6; /*%! ID="NumOutpostArtyDef",
3149
MainDesc="Num outpost arty defences",
3150
type="asn", //Assign
3152
ArgDesc="6 (Default)",
3164
if(outpostDroid.order == DORDER_NONE)
3167
if(numStructsByTypeInArea(player, REF_DEFENSE, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2) < (temp + result4)) //Max 6 arty def
3169
//Check if we have arty tech available
3172
while((count >= 0) and (boolResult == FALSE))
3174
if(isStructureAvailable(arty[count], player))
3176
structChoice[0] = arty[count];
3177
boolResult = TRUE; //Stop
3182
if(boolResult == TRUE) //If we have arty tech
3184
buildX = curEnEdgeX;
3185
buildY = curEnEdgeY;
3186
boolResult = pickStructLocation(powGen, ref buildX, ref buildY, player);
3187
if(boolResult == TRUE)
3189
if(distBetweenTwoPoints(buildX, buildY, curEnEdgeX, curEnEdgeY) < count2)
3191
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
3207
initEnumStruct(FALSE,sens[count],player,player);
3208
structure = enumStruct();
3209
while(structure != NULLOBJECT)
3211
if(distBetweenTwoPoints(structure.x, structure.y, curEnEdgeX, curEnEdgeY) < count2) //In the outpost
3213
result = result + 1;
3215
structure = enumStruct();
3222
//Check if we have sensor tech available
3225
while((count >= 0) and (boolResult == FALSE))
3227
if(isStructureAvailable(sens[count], player))
3229
structChoice[0] = sens[count];
3230
boolResult = TRUE; //Stop
3235
if(boolResult == TRUE) //If we have sensor tech available
3237
buildX = curEnEdgeX;
3238
buildY = curEnEdgeY;
3239
boolResult = pickStructLocation(powGen, ref buildX, ref buildY, player);
3240
if(boolResult == TRUE)
3242
if(distBetweenTwoPoints(buildX, buildY, curEnEdgeX, curEnEdgeY) < count2)
3244
orderDroidStatsLoc(outpostDroid, DORDER_BUILD, structChoice[0], buildX, buildY);
3253
//-------------------------------------------------------------
3254
// Check for some important details we need for the script
3255
//-------------------------------------------------------------
3256
event updateDetails(updateDetailsTr)
3258
//Decide wheather to drop or not
3259
//----------------------------------------------------
3262
if((alreadyAttacked and (playerPower(player) > 500)) or (playerPower(player) > muchoPower)) //Started attacking and enough power
3268
//----------------------------------------------------
3269
//Count how many attackers are repairing at the moment
3270
//----------------------------------------------------
3272
//initIterateGroup(attackGroup);
3273
//droid = iterateGroup(attackGroup);
3274
//while(droid != NULLOBJECT)
3276
// if(droid.order == DORDER_RTR)
3278
// numRepairing = numRepairing + 1;
3280
// droid = iterateGroup(attackGroup);
3283
//------------------------------------------
3284
//Check if we have an outpost and can repair
3285
//------------------------------------------
3286
haveOutpost = FALSE;
3289
//Find rep facilities
3290
//-------------------
3291
count2 = (KeepDist / 2);
3292
if(numStructsByTypeInArea(player, REF_REPAIR_FACILITY, curEnEdgeX - count2, curEnEdgeY - count2, curEnEdgeX + count2, curEnEdgeY + count2) > 0)
3298
//Decide how many templates tochoose from
3299
//---------------------------------------
3300
structure = getStructure(factory,player);
3301
if(structure != NULLOBJECT)
3305
if(playerPower(player) > muchoPower)
3310
if(skCanBuildTemplate(player,structure, tmpl[0][8])) //If we have Trck Python HC
3312
if(mainPhase == 1) //If set to 2 too early, then some stuff will not be activated at startup
3318
if(skCanBuildTemplate(player,structure, tmpl[temp][10])) //If we have A-Mantis-Trk-Lancer then start using 3 templates
3322
else if(skCanBuildTemplate(player,structure, tmpl[temp][9])) //If we have A-Python-Trk-Lancer then use A-Python-Trk-Lancer and A-Python-Trk-HC
3329
//Remember the best cyborg template available
3330
//-------------------------------------------
3331
structure = getStructure(cybFactory, player);
3332
if(structure != NULLOBJECT)
3334
count = 1; //numTemplates - 1
3336
while((count >= 0) and (boolResult))
3338
if(skCanBuildTemplate(player,structure, cybTmpl[count]) )
3340
cybTemplate = count;
3348
//----------------------------------------
3350
//----------------------------------------
3351
event savePower(inactive)
3356
powerSaving = FALSE;
3357
if((playerPower(player) < 100) or (defendingBase)) //Low on power or need power for fast unit production
3363
//----------------------------------------
3364
//Repair damaged droids using repair units
3365
//----------------------------------------
3366
event repairStuff(repairStuffTr)
3368
//------------------------
3370
//------------------------
3371
result = 2; //Total number of (repDefendDroid - 1)
3372
count = 0; //Current repair unit index
3373
while(count < result)
3375
if(repDefendDroid[count] != NULLOBJECT) //If this repairer exists
3377
boolResult = FALSE; //Assume it's still busy right now
3378
if(toRepDefendDroid[count] == NULLOBJECT) //Nothing to repair
3380
boolResult = TRUE; //Not busy, find a unit to repair
3382
else //Damaged unit still exists
3384
if(toRepDefendDroid[count].health > 95) //Already repaired
3386
boolResult = TRUE; //Find another unit
3387
toRepDefendDroid[count] = NULLOBJECT; //'Forget' this unit
3391
//-------------------
3392
//Find a damaged unit
3393
//-------------------
3394
if(boolResult) //Have nothing to repair
3396
initIterateGroup(defendGr);
3397
droid = iterateGroup(defendGr);
3399
while((droid != NULLOBJECT) and (boolResult))
3401
if(droid.health < 90) //Needs repair
3403
boolResult = FALSE; //Busy now, found a unit to repair
3405
//Make sure this unit is not already get repaired by the second repairer
3406
//----------------------------------------------------------------------
3407
if(count == 0) //For the first repairer
3409
if(droid == toRepDefendDroid[1]) //If already get repaired
3411
boolResult = TRUE; //Don't take this unit
3416
if(droid == toRepDefendDroid[0]) //If already get repaired
3418
boolResult = TRUE; //Don't take this unit
3422
if(not boolResult) //If we did decide to choose this unit for repairing
3424
toRepDefendDroid[count] = droid; //Choose it
3427
droid = iterateGroup(defendGr);
3430
//---------------------------------------------------------
3431
//If nothing to repair so far, repair the other repair unit
3432
//---------------------------------------------------------
3433
if(boolResult) //Nothing to repair
3435
if(count == 0) //For the first rep unit
3437
if(repDefendDroid[1] != NULLOBJECT) //2nd repair unit exists
3439
if(repDefendDroid[1].health < 90) //Needs repair
3441
boolResult = FALSE; //Busy now
3442
toRepDefendDroid[count] = repDefendDroid[1]; //Repair it
3448
if(repDefendDroid[0] != NULLOBJECT) //1st repair unit exists
3450
if(repDefendDroid[0].health < 90) //Needs repair
3452
boolResult = FALSE; //Busy now
3453
toRepDefendDroid[count] = repDefendDroid[0]; //Repair it
3460
//---------------------------------------------------------
3461
//If found something to repair, then get closer to the unit
3462
//---------------------------------------------------------
3463
if(not boolResult) //Busy
3465
if(distBetweenTwoPoints(toRepDefendDroid[count].x, toRepDefendDroid[count].y, repDefendDroid[count].x, repDefendDroid[count].y) > 256) //If too far away from the damaged unit
3469
if(repDefendDroid[count].x < toRepDefendDroid[count].x) //Don't make the unit get out of the way, stop near it
3474
if(repDefendDroid[count].y < toRepDefendDroid[count].y)
3479
orderDroidLoc(repDefendDroid[count], DORDER_MOVE, toRepDefendDroid[count].x + tempX, toRepDefendDroid[count].y + tempY);
3482
else //If still idle, then move closer to the defend group
3487
if(distBetweenTwoPoints(tempX, tempY, repDefendDroid[count].x, repDefendDroid[count].y) > 1024) //Too far away from defenders
3489
orderDroidLoc(repDefendDroid[count], DORDER_MOVE, tempX, tempY); //Move closer to the group
3494
else if(toRepDefendDroid[count] != NULLOBJECT) //Has something to repair and not going to repair it
3496
if(repDefendDroid[count].order == DORDER_NONE) //Idle
3498
if(distBetweenTwoPoints(repDefendDroid[count].x, repDefendDroid[count].y, toRepDefendDroid[count].x, toRepDefendDroid[count].y) > (3 * 128))
3500
orderDroidLoc(repDefendDroid[count], DORDER_MOVE, toRepDefendDroid[count].x, toRepDefendDroid[count].y);
3510
//------------------------
3512
//------------------------
3513
if(repAttackDroid != NULLOBJECT)
3515
if(repAttackDroid.order == DORDER_NONE) //Not busy
3517
initIterateGroup(attackGroup);
3518
droid = iterateGroup(attackGroup);
3519
boolResult = TRUE; //Send only 1 truck
3520
while((droid != NULLOBJECT) and (boolResult))
3522
if(droid.health < 90) //Needs repair
3524
if(distBetweenTwoPoints(droid.x, droid.y, repAttackDroid.x, repAttackDroid.y) > 256)
3529
if(repAttackDroid.x < droid.x) //Don't make the unit get out of the way, stop near it
3534
if(repAttackDroid.y < droid.y)
3539
orderDroidLoc(repAttackDroid, DORDER_MOVE, droid.x + tempX, droid.y + tempY);
3542
droid = iterateGroup(attackGroup);
3545
tempX = attackGroup.x;
3546
tempY = attackGroup.y;
3549
if(distBetweenTwoPoints(tempX, tempY, repAttackDroid.x, repAttackDroid.y) > 512) //(6 * 128)
3551
orderDroidLoc(repDefendDroid, DORDER_MOVE, tempX, tempY); //Move closer to the group
3558
//-----------------------
3560
//-----------------------
3561
structure2 = NULLOBJECT;
3562
initEnumStruct(TRUE,derrick,player,player); //TRUE: iterate through all structures
3563
structure = enumStruct();
3564
while((structure != NULLOBJECT) and (structure2 == NULLOBJECT))
3566
//if(not structureComplete(structure)) //If structure not finished
3568
if(structure.health < 90)
3570
if((structure.x < maxx) and (structure.x > minx)) //Only base structures
3572
if((structure.y < maxy) and (structure.y > miny))
3574
structure2 = structure;
3579
structure = enumStruct();
3582
if(structure2 != NULLOBJECT)
3586
tempDroid = NULLOBJECT;
3589
initIterateGroup(buildGroup);
3590
droid = iterateGroup(buildGroup);
3591
while((droid != NULLOBJECT) and (boolResult))
3593
if(droid.order == DORDER_NONE) //Make sure there's only one droid repairing at a time
3595
if(distBetweenTwoPoints(droid.x, droid.y, structure2.x, structure2.y) < temp) //Not too far away
3598
boolResult = FALSE; //We found our droid, make iteration stop here
3601
else //Max 2 trucks repairing the same structure
3603
if(droid.order == DORDER_REPAIR) //If somebody is already repairing something
3605
if((droid.orderx == structure2.x) and (droid.ordery == structure2.y))
3607
tempDroid = NULLOBJECT;
3608
boolResult = FALSE; //Stop iteration
3612
droid = iterateGroup(buildGroup);
3615
if(tempDroid != NULLOBJECT) //Droid found and nobody already repairing
3617
orderDroidObj(tempDroid, DORDER_REPAIR, structure2); //Repair
3623
//------------------------------------
3624
// Units stuck, do something!
3625
//------------------------------------
3626
event stuck(stuckTr)
3628
//Most of them have an order
3629
if((attackGroup.members > 0) and (idleGroup(attackGroup) < (attackGroup.members / 2)))
3634
if(repGr.members > 0) //Have repGr
3636
tempX = (attackGroup.x + repGr.x) / 2; //Attack and rep group stuck often,
3637
tempY = (attackGroup.y + repGr.y) / 2; //so use the middle value of the 2 groups
3641
tempX = attackGroup.x;
3642
tempY = attackGroup.y;
3646
if(distBetweenTwoPoints(tempX, tempY, stuckX, stuckY) > temp) //Moved
3649
stuckX = tempX; //Store new coordinates
3654
stuckTimes = stuckTimes + 1;
3658
result2 = result + 15;
3660
//If they are really stuck
3661
if((stuckTimes > result) and (stuckTimes < result2))
3663
showConsoleText(DebugMsg[9], player); //STUCK: Running a bit
3669
initIterateGroup(attackGroup);
3670
droid = iterateGroup(attackGroup);
3671
while(droid != NULLOBJECT)
3673
orderDroid(droid, DORDER_RUN);
3674
droid = iterateGroup(attackGroup);
3678
initIterateGroup(sendOutpostGr);
3679
droid = iterateGroup(sendOutpostGr);
3680
while(droid != NULLOBJECT)
3682
orderDroid(droid, DORDER_RUN);
3683
droid = iterateGroup(sendOutpostGr);
3687
initIterateGroup(repGr);
3688
droid = iterateGroup(repGr);
3689
while(droid != NULLOBJECT)
3691
orderDroid(droid, DORDER_RUN);
3692
droid = iterateGroup(repGr);
3694
// count = count + 1;
3697
else if(stuckTimes >= result2)
3699
showConsoleText(DebugMsg[10], player); //STUCK: Removing obstacles
3701
//Wipe out any structure near the group or some units if there are no structures
3702
resetStructTargets();
3704
structure = structTargetInArea(player, player, tempX - result, tempY - result, tempX + result, tempY + result);
3705
if(structure == NULLOBJECT)
3707
setStructTarPref(ST_WALL);
3708
structure = structTargetInArea(player, player, tempX - result, tempY - result, tempX + result, tempY + result);
3711
if(structure != NULLOBJECT)
3713
orderGroupObj(attackGroup, DORDER_ATTACK, structure);
3717
resetDroidTargets();
3718
tempDroid = droidTargetInArea(player, player, tempX - result, tempY - result, tempX + result, tempY + result);
3719
if(tempDroid != NULLOBJECT)
3721
orderGroupObj(attackGroup, DORDER_ATTACK, tempDroid);
3725
else if(stuckTimes > (result2 + 20)) //Destroy 20 objects, then reset
3727
stuckTimes = 0; //Try to get out now
3732
//=============================================================================================
3734
//=============================================================================================
3735
//---------------------
3737
//---------------------
3738
event buildVtolPads(inactive)
3740
if(getStructure(vtolFactory,player) != NULLOBJECT) //If we have VTOL factory
3742
if(alreadyAttacked and (not powerSaving)) //If we already have built an attack force
3746
initEnumStruct(FALSE,vtolPad,player,player);
3747
structure= enumStruct();
3749
while(structure != NULLOBJECT)
3752
structure= enumStruct();
3755
//Do we have enough rearm pads?
3756
//-----------------------------
3757
if(count < ((maxTVtols + maxSVtols) / 2))
3759
//Find nearest truck
3760
//------------------
3764
tempDroid = NULLOBJECT;
3765
initIterateGroup(buildGroup);
3766
droid = iterateGroup(buildGroup);
3767
while(droid != NULLOBJECT)
3769
if(droid.order == DORDER_NONE)
3771
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
3772
if(result2 < result)
3778
droid = iterateGroup(buildGroup);
3781
//Build vtol rearm pads
3782
//---------------------
3783
boolResult = pickStructLocation(vtolPad, ref buildX, ref buildY,player);
3784
if((boolResult == TRUE) and (tempDroid != NULLOBJECT))
3786
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolPad, buildX, buildY);
3791
else if((not powerSaving) and (alreadyAttacked)) //Build VTOL Factory
3793
if(isStructureAvailable(vtolFactory,player))
3795
//Find nearest truck
3796
//------------------
3800
tempDroid = NULLOBJECT;
3801
initIterateGroup(buildGroup);
3802
droid = iterateGroup(buildGroup);
3803
while(droid != NULLOBJECT)
3805
if(droid.order == DORDER_NONE)
3807
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
3808
if(result2 < result)
3814
droid = iterateGroup(buildGroup);
3817
//Build VTOL Facrory
3818
//------------------
3819
boolResult = pickStructLocation(vtolFactory, ref buildX, ref buildY,player);
3820
if((boolResult == TRUE) and (tempDroid != NULLOBJECT))
3822
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolFactory, buildX, buildY);
3828
//----------------------
3830
//----------------------
3831
event buildVtols(buildVtolsTr)
3833
structure = getStructure(vtolPad,player); //Got vtol pads?
3834
if((structure != NULLOBJECT) and (alreadyAttacked) and (not powerSaving)) //Got pads and already have an attack force
3836
structure = getStructure(vtolFactory,player);
3837
if(structure != NULLOBJECT)
3839
//Check if we can afford heavy templates
3840
//--------------------------------------
3841
temp = 0; //Light templates
3842
if(playerPower(player) > muchoPower)
3844
temp = 1; //Use heavy, expensive templates, if can afford it
3847
//Check if we have any antitank template
3848
//--------------------------------------
3850
count = numTVtolTemplates - 1;
3852
while((count >= 0) and (boolResult == FALSE))
3854
if(skCanBuildTemplate(player,structure, tVtols[temp][count]))
3861
//Check if we have any antistructure template
3862
//-------------------------------------------
3863
boolResult2 = FALSE;
3864
count = numSVtolTemplates - 1;
3866
while((count >= 0) and (not boolResult2))
3868
if(skCanBuildTemplate(player,structure, sVtols[temp][count]) )
3875
//Build Cyborg Transport
3876
//-------------------------------------
3878
if((transportDroid == NULLOBJECT) and (dropEnabled) and (transportGr.members > 7))
3884
//Decide for which group to build VTOLs
3885
//-------------------------------------
3886
if((tVtolGr.members < maxTVtols) and ((tVtolGr.members <= sVtolGr.members) or (not boolResult2)))
3888
result = 1; //tVtolGr
3890
//else if((sVtolGr.members < maxSVtols) and ((sVtolGr.members < tVtolGr.members) or (not boolResult)))
3891
else if(sVtolGr.members < maxSVtols)
3893
result = 2; //sVtolGr
3898
//-------------------------------------
3901
if(structureIdle(structure)) // if factory idle
3904
if(result == 2) //sVtolGr
3906
count = numSVtolTemplates - 1;
3907
while((count2 < numSVtolTemplates) and (count >= 0))
3909
if(skCanBuildTemplate(player,structure, sVtols[temp][count]) )
3911
tmplChoice[count2] = sVtols[temp][count];
3912
count2 = count2 + 1;
3917
else if(result == 1) //tVtolGr
3919
count = numTVtolTemplates - 1;
3920
while((count2 < numTVtolTemplates) and (count >= 0))
3922
if(skCanBuildTemplate(player,structure, tVtols[temp][count]) )
3924
tmplChoice[count2] = tVtols[temp][count];
3925
count2 = count2 + 1;
3933
tmplChoice[0] = Transport;
3937
//--------------------
3940
buildDroid(tmplChoice[random(count2)],structure,player,1);
3943
structure = enumStruct();
3949
//----------------------------
3950
// Build VTOL defenses
3951
//----------------------------
3952
event vtolDefend(vtolDefendTr)
3954
if(baseobj != NULLOBJECT)
3956
if(baseobj.player != player) //Wasn't our own tank
3958
//Break alliance if our ally has attacked us
3959
//------------------------------------------
3960
if(allianceExistsBetween(player, baseobj.player)) //If we allied
3962
breakAlliance(player, baseobj.player); //No backstabbing
3965
if(baseobj.type == OBJ_DROID)
3967
if(isVtol(objToDroid(baseobj)))
3969
if(structure != NULLOBJECT) //Attacked structure still exists
3971
buildX = structure.x;
3972
buildY = structure.y;
3975
tempDroid = NULLOBJECT;
3977
initIterateGroup(buildGroup);
3978
droid = iterateGroup(buildGroup);
3979
while(droid != NULLOBJECT)
3981
if(droid.order == DORDER_NONE)
3983
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
3984
if(result2 < result)
3990
droid = iterateGroup(buildGroup);
3993
if(tempDroid != NULLOBJECT) //If we have a truck
3995
//Find best defense we can build
3996
//------------------------------
3999
while(count < numVtolDefStr)
4001
if(isStructureAvailable(vtolDefStruct[count],player))
4008
if(count2 != (-1) ) //If we have a structure to build
4010
boolResult = pickStructLocation(vtolDefStruct[count2], ref buildX, ref buildY,player);
4011
if(boolResult == TRUE)
4013
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolDefStruct[count2],buildX,buildY);
4019
else //Attacked by a tank
4021
tVtolObject = baseobj;
4024
else //Attacked by a structure
4026
sVtolObject = baseobj;
4029
//Remember this attacker
4030
//if(defendObject == NULLOBJECT) //Killed last attacker already, remember new one
4033
if(structure != NULLOBJECT) //Attacked structure still exists
4035
//If structure is in the base
4036
if((structure.x > minx) and (structure.x < maxx) and (structure.y > miny) and (structure.y < maxy))
4038
if(baseobj.type == OBJ_STRUCTURE)
4040
defendObject = baseobj;
4042
else if(baseobj.type == OBJ_DROID)
4044
tempDroid = objToDroid(baseobj);
4045
//if(not isVtol(tempDroid))
4046
if(tempDroid.propulsion != vtolProp)
4048
defendObject = baseobj;
4056
if(defendObject != NULLOBJECT)
4058
if(defendGr.members > 0)
4060
if(idleGroup(defendGr) >= (defendGr.members / 2))
4062
showConsoleText(DebugMsg[13], player); //Base attacked. Defending.
4064
orderGroupLoc(defendGr, DORDER_SCOUT, defendObject.x, defendObject.y);
4068
//Use collectSendGr group too, since they are just idling anyway
4069
if(collectSendGr.members > 0)
4071
if(idleGroup(collectSendGr) >= (collectSendGr.members / 2))
4073
orderGroupLoc(collectSendGr, DORDER_SCOUT, defendObject.x, defendObject.y);
4076
defendObject = NULLOBJECT; //Reset
4084
//----------------------------------
4085
//Build min number of VTOL defenses
4086
//----------------------------------
4087
event additVTOLDefenses(additVTOLDefensesTr)
4089
if((not defendingBase) and (alreadyAttacked))
4091
//Count VTOL defenses
4092
//-------------------
4095
while(count < numVtolDefStr)
4097
initEnumStruct(FALSE,vtolDefStruct[count],player,player);
4098
structure = enumStruct();
4099
while(structure != NULLOBJECT)
4101
if((structure.x > minx) and (structure.y > miny) and (structure.x < maxx) and (structure.y < maxy)) //If in the base
4103
result = result + 1;
4105
structure = enumStruct();
4110
//Min number of VTOL defenses
4111
temp = 16; /*%! ID="MinVTOL_AdditDefences",
4112
MainDesc="Min number of VTOL defences",
4113
type="asn", //Assign
4115
ArgDesc="16 (Default)",
4117
ArgDesc="No additional defences",
4130
//Don't buld too many if not enough power
4131
temp = 7; /*%! ID="MinVTOL_AdditDefencesLowPow",
4132
MainDesc="Low power VTOL defences",
4133
type="asn", //Assign
4135
ArgDesc="7 (Default)",
4137
ArgDesc="No additional defences",
4147
ArgDesc="Same value as above" */
4152
//Find the best VTOL defense available
4153
//------------------------------------
4156
while(count < numVtolDefStr)
4158
if(isStructureAvailable(vtolDefStruct[count],player))
4165
if(temp != (-1) ) //If we have a structure to build
4170
boolResult = pickStructLocation(vtolDefStruct[temp], ref buildX, ref buildY,player);
4171
if(boolResult == TRUE)
4173
//Find closest droid
4174
//------------------------------------
4176
tempDroid = NULLOBJECT;
4178
initIterateGroup(buildGroup);
4179
droid = iterateGroup(buildGroup);
4180
while(droid != NULLOBJECT)
4182
if(droid.order == DORDER_NONE)
4184
result2 = distBetweenTwoPoints(buildX, buildY, droid.x, droid.y);
4185
if(result2 < result)
4191
droid = iterateGroup(buildGroup);
4194
if(tempDroid != NULLOBJECT) //If we have a truck
4196
orderDroidStatsLoc(tempDroid, DORDER_BUILD, vtolDefStruct[temp],buildX,buildY);
4205
//------------------------------------------
4206
//Attack enemy objects in the base
4207
//------------------------------------------
4208
event agressiveDefence(agressiveDefenceTr)
4210
//If defenders got carried away from the base, make them return
4211
if((defendGr.x < minx) or (defendGr.y < miny) or (defendGr.x > maxx) or (defendGr.y > maxy))
4215
if(pickStructLocation(factory, ref buildX, ref buildY, player)) //Find an open spot
4217
orderGroupLoc(defendGr, DORDER_SCOUT, buildX, buildY); //Send back
4218
orderGroupLoc(collectSendGr, DORDER_SCOUT, buildX, buildY); //Send back
4222
result = defendGr.members + collectSendGr.members;
4223
if(result > 3) //Have defenders
4225
if((idleGroup(defendGr) + idleGroup(collectSendGr)) > (result / 2)) //Not busy
4227
//Find enemy droids in the base
4228
//-----------------------------
4229
resetDroidTargets();
4230
setDroidTarPref(DT_WEAP_GROUND); //Ignore VTOLs, tanks only
4231
setDroidTarIgnore(DT_VTOL);
4233
tempDroid = NULLOBJECT;
4235
while((count < numEnemies) and (tempDroid == NULLOBJECT))
4237
tempDroid = droidTargetInArea(Enemies[count], player, minx, miny, maxx, maxy); //Droid
4241
if(tempDroid != NULLOBJECT)
4243
//Check if we are following our own tank
4244
//--------------------------------------
4245
if((tempDroid.player == player) or (isVtol(tempDroid)))
4247
tempDroid = NULLOBJECT;
4252
//Still have an attacker
4253
if(tempDroid != NULLOBJECT)
4255
showConsoleText(DebugMsg[14], player); //Agressive defence
4256
orderGroupLoc(defendGr, DORDER_SCOUT, tempDroid.x, tempDroid.y);
4257
orderGroupLoc(collectSendGr, DORDER_SCOUT, tempDroid.x, tempDroid.y);
4259
if(idleGroup(sVtolGr) == sVtolGr.members)
4261
orderGroupObj(sVtolGr, DORDER_ATTACK, tempDroid);
4264
if(idleGroup(tVtolGr) == tVtolGr.members)
4266
orderGroupObj(tVtolGr, DORDER_ATTACK, tempDroid);
4275
//-------------------------
4276
// Attack with VTOLs
4277
//-------------------------
4278
event vtolAttack(vtolAttackTr)
4280
temp = (KeepDist / 2); //Enemy base range
4281
//if(attackPhase > 1)
4284
//-------------------------
4285
//Attack with anitank VTOLs
4286
//-------------------------
4288
if(tVtolObject == NULLOBJECT) //No target
4292
//else if(tVtolObject.player != curEnemy) //Attacking another player
4294
// boolResult = TRUE;
4300
resetDroidTargets();
4301
setDroidTarPref(DT_CONSTRUCT); //Find truck to attack
4302
//tempDroid = droidTargetInArea(curEnemy, -1, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
4304
//if(tempDroid == NULLOBJECT)
4306
tempDroid = droidTargetOnMap(curEnemy, -1);
4309
if(tempDroid == NULLOBJECT) //No truck, find another unit
4311
resetDroidTargets();
4312
setDroidTarPref(DT_WEAP_GROUND); //Ground,air,idf units
4313
setDroidTarIgnore(DT_LEGS); //Ignore cyborgs
4314
setDroidTarIgnore(DT_LIGHT); //Ignore light units
4315
tempDroid = droidTargetOnMap(curEnemy, curEnemy);
4316
//tempDroid = droidTargetInArea(curEnemy, curEnemy, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
4320
if(tempDroid != NULLOBJECT) //Attack
4322
tVtolObject = tempDroid; //Remember
4326
//-------------------------------
4327
//Attack with antistructure VTOLs
4328
//-------------------------------
4330
if(sVtolObject == NULLOBJECT) //No target
4334
//else if(sVtolObject.player != curEnemy) //Attacking another player
4336
// boolResult = TRUE;
4343
structure = NULLOBJECT;
4344
while((count < 6) and (structure == NULLOBJECT))
4346
resetStructTargets();
4347
setStructTarPref(sPref[count]); //Find structure to attack
4348
structure = structTargetInArea(curEnemy, -1, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
4352
if(structure == NULLOBJECT) //No structure, find another structure
4354
resetStructTargets();
4355
setStructTarPref(ST_DEF_ALL); //Ground,air,idf
4356
structure = structTargetOnMap(curEnemy, -1);
4359
if(structure != NULLOBJECT) //Attack
4361
sVtolObject = structure; //Remember
4367
//-------------------------
4368
//Attack with anitank VTOLs
4369
//-------------------------
4370
if(tVtolObject == NULLOBJECT)
4373
resetDroidTargets();
4374
setDroidTarPref(DT_CONSTRUCT);
4378
while((count < numEnemies) and (droid == NULLOBJECT))
4380
droid = droidTargetOnMap(Enemies[count], Enemies[count]);
4384
//No truck, find another unit
4385
if(droid == NULLOBJECT)
4387
resetDroidTargets();
4388
setDroidTarPref(DT_WEAP_ALL); //Any weapon unit
4392
while((count < numEnemies) and (droid == NULLOBJECT))
4394
droid = droidTargetOnMap(Enemies[count], Enemies[count]);
4399
if(droid != NULLOBJECT)
4401
tVtolObject = droid;
4405
//-------------------------------
4406
//Attack with antistructure VTOLs
4407
//-------------------------------
4408
if(sVtolObject == NULLOBJECT)
4412
structure = NULLOBJECT;
4413
while((count < numEnemies) and (structure == NULLOBJECT))
4416
while((count2 < 6) and (structure == NULLOBJECT))
4418
resetStructTargets();
4419
setStructTarPref(sPref[count2]); //Find structure to attack
4420
structure = structTargetOnMap(Enemies[count], Enemies[count]);
4421
count2 = count2 + 1;
4426
if(structure != NULLOBJECT)
4428
sVtolObject = structure;
4439
if(tVtolObject != NULLOBJECT)
4441
if((idleGroup(tVtolGr) >= (tVtolGr.members - 1)) and (tVtolGr.members >= maxTVtols)) //Enough VTOLs?
4443
orderGroupObj(tVtolGr, DORDER_ATTACK, tVtolObject); //Attack
4445
else if((idleGroup(tVtolGr) <= (tVtolGr.members / 2)) and (tVtolGr.members <= (maxTVtols / 2)))
4447
orderGroup(tVtolGr, DORDER_RTB);
4452
if(sVtolObject != NULLOBJECT)
4454
if((idleGroup(sVtolGr) >= (sVtolGr.members - 1)) and (sVtolGr.members >= maxSVtols)) //Enough VTOLs?
4456
orderGroupObj(sVtolGr, DORDER_ATTACK, sVtolObject); //Attack
4458
else if((idleGroup(sVtolGr) <= (sVtolGr.members / 2)) and (sVtolGr.members <= (maxSVtols / 2))) //Return home
4460
orderGroup(sVtolGr, DORDER_RTB);
4465
/////////////////////////////////////////////////////////////////////
4466
/////////////////////////////////////////////////////////////////////
4470
event formAllianceEvent(every, 170)
4472
if( (player == selectedPlayer) or (not myResponsibility(player)) )
4474
setEventTrigger(formAllianceEvent, inactive);
4481
if( count != player ) // if not the only other player and rand2
4483
if((getDroidCount(player) > 1) and (getDroidCount(count) > 1) ) // not dead
4485
if(not isHumanPlayer(count)) // not human
4487
createAlliance(player,count);
4488
allianceTime[count] = gameTime;
4494
setEventTrigger(formAllianceEvent, inactive);
4498
//--------------------
4500
//--------------------
4501
event formHumanAlliances(humanAllianceTr)
4503
if(count2 == player) //If offered to me
4508
showConsoleText(ai_ally_msg[random(4)],count);
4513
//=====================================================================================================
4515
//=====================================================================================================
4516
event cyborgDrop(cyborgDropTr)
4518
/********************************
4522
2 - on the way to lz
4524
4 - landed and released cyborgs, transport returning home
4525
********************************/
4527
//Wait until all droids are loaded
4528
//--------------------------------
4529
if(dropPhase == 1) //Loading
4532
if(transportDroid == NULLOBJECT) //Was destroyed
4535
dropPhase = 0; //Stop
4538
if(boolResult) //If transport is still there
4542
//Check if all droids are idle (loaded into transport)
4543
//----------------------------------------------------
4545
initIterateGroup(transportGr);
4546
droid = iterateGroup(transportGr);
4547
while(droid != NULLOBJECT)
4549
if(distBetweenTwoPoints(droid.x, droid.y, transportDroid.x, transportDroid.y) > 256)
4552
if((droid.orderx != transportDroid.x) or (droid.ordery != transportDroid.y)) //Not going to the transport
4554
orderDroidLoc(droid, DORDER_MOVE, transportDroid.x, transportDroid.y); //Go to the transport
4562
droid = iterateGroup(transportGr);
4565
//Order transport to fly to the enemy to unload the units
4566
//-------------------------------------------------------
4567
if((boolResult) and (curEnemy >= 0) and (curEnemyX > 0)) //If all loaded
4569
//Find an enemy base structure that is far away from the tank attack point
4570
//------------------------------------------------------------------------
4573
temp = (30 * 128); //Enemy base radius
4575
while(count < numBaseStructs)
4577
initEnumStruct(FALSE,baseStructs[count],curEnemy,player); //Find visible in-base structure that is far away from the attack point (more efficient)
4578
structure = enumStruct();
4579
while(structure != NULLOBJECT)
4581
//if(losTwoObjects(transportDroid, structure, FALSE)) //If can see enemy base structure
4584
result2 = distBetweenTwoPoints(curEnemyX,curEnemyY, structure.x, structure.y);
4585
if(result2 < temp) //In the enemy base
4587
//setFogColour(1, random(200) + 50, 1);
4588
if(result2 > result) //Further away
4590
//setFogColour(1, 1, random(200) + 50);
4597
structure = enumStruct();
4602
//setFogColour(random(200) + 50, 1, 1);
4606
temp = (7 * 128); //temp / 2;
4607
resetStructTargets();
4608
structure = structTargetInArea(curEnemy, player, curEnemyX - temp, curEnemyY - temp, curEnemyX + temp, curEnemyY + temp);
4609
if(structure != NULLOBJECT)
4611
//setFogColour(1, random(200) + 50, random(200) + 50);
4618
if(result > 0) //Found a structure
4621
//resetStructTargets();
4622
//setStructTarPref(ST_DEF_AIR); //Make sure no AA
4623
//structure = structTargetInArea(curEnemy, curEnemy, LZ_X - temp, LZ_Y - temp, LZ_X + temp, LZ_Y + temp);
4624
//if(structure == NULLOBJECT) //No AA
4626
boolResult = pickStructLocation(wall, ref LZ_X, ref LZ_Y,player);
4629
//centreViewPos(LZ_X, LZ_Y);
4630
//setFogColour(random(200) + 50, 1, random(200) + 50);
4631
orderDroidLoc(transportDroid, DORDER_MOVE, LZ_X, LZ_Y);
4633
if(transportDroid.order != DORDER_NONE)
4639
resetPlayerVisibility(player); //Reset structures which were discovered and *are not visible anymore*
4645
//orderDroidLoc(transportDroid, DORDER_SCOUT, LZ_X, LZ_Y); //Take off
4649
else if(dropPhase == 2) //On the way to LZ
4653
if(transportDroid != NULLOBJECT)
4655
if(transportDroid.order == DORDER_NONE) //If reached LZ and is landing
4658
transportZ = -1; //Remember current height of the transport
4661
else //Transport destroyed
4666
else if(dropPhase == 3) //Landing on LZ
4670
//Release cyborgs if stopped landiong
4671
//-----------------------------------
4672
if(transportDroid != NULLOBJECT)
4674
if(transportZ == transportDroid.z) //If stopped landing
4676
//setFogColour(random(200) + 50, 1, 1);
4678
//'Unload' best cyborgs with best templates available
4679
//---------------------------------------------------
4680
structure = getStructure(cybFactory,player);
4681
if(structure != NULLOBJECT)
4683
if(cybTemplate > -1)
4685
//setFogColour(random(200) + 50, random(200) + 50, 1);
4687
//Cyborgs with weapons
4688
//--------------------
4690
while(result < 8) //Unload 8 weapon cyborgs
4693
droid = addDroid(cybTmpl[cybTemplate], transportDroid.x, transportDroid.y, player);
4694
if(droid != NULLOBJECT)
4696
//orderDroid(droid, DORDER_RUN); //Don't stay too compact
4697
//groupAddDroid(attackGroup, droid);
4698
groupAddDroid(dropGr, droid);
4700
result = result + 1;
4704
//--------------------
4706
while(result < 2) //Unload 2 mechanics
4708
droid = addDroid(cybMechanic, transportDroid.x, transportDroid.y, player); //Add mechanic
4709
//groupAddDroid(attackGroup,droid);
4710
groupAddDroid(dropGr, droid);
4711
result = result + 1;
4718
orderDroid(transportDroid, DORDER_RTB);
4719
//orderDroidLoc(transportDroid, DORDER_MOVE, baseX, baseY); //Send transport back to the base
4723
else //Transport destroyed
4728
transportZ = transportDroid.z;
4730
else if(dropPhase == 4) //Transport returning to the base
4733
if(transportDroid != NULLOBJECT)
4735
if(transportDroid.order == DORDER_NONE) //If reached LZ and is landing
4746
if((attackPhase > 2) and (dropPhase == 0)) //Attacking enemy base and not already transporting
4747
//if(dropPhase == 0) //Attacking enemy base and not already transporting
4749
if((transportDroid != NULLOBJECT) and (curEnemyX > 0))
4751
if((transportGr.members >= 10) and (transportDroid.order == DORDER_NONE))
4753
showConsoleText(DebugMsg[8], player); //Initializing drop
4756
//----------------------------
4757
initIterateGroup(transportGr);
4758
droid = iterateGroup(transportGr);
4759
while(droid != NULLOBJECT)
4761
orderDroidLoc(droid, DORDER_MOVE, transportDroid.x, transportDroid.y);
4762
//setDroidSecondary(droid, DSO_RETURN_TO_LOC, DSS_RTL_TRANSPORT);
4763
//orderDroidObj(droid, DORDER_EMBARK, transportDroid);
4764
droid = iterateGroup(transportGr);
4770
dropPhase = 1; //Loading Transport
4776
//---------------------------------------------
4777
//Attack with cyborgs
4778
//---------------------------------------------
4779
event manageDropAttacks(manageDropAttacksTr)
4781
if(dropGr.members > 0)
4783
if(idleGroup(dropGr) >= (dropGr.members / 2))
4785
if((curEnemyX > 0) and (curEnemy > -1))
4792
count = 0; //Attack base structures
4793
while(count < numBaseStructs)
4795
initEnumStruct(FALSE,baseStructs[count],curEnemy,player);
4796
structure = enumStruct();
4797
while(structure != NULLOBJECT)
4799
if(distBetweenTwoPoints(tempX, tempY, structure.x, structure.y) < temp) //If in the enemy base
4802
initIterateGroup(dropGr);
4803
droid = iterateGroup(dropGr);
4804
while(droid != NULLOBJECT)
4806
//if(droid.droidType != DROID_REPAIR) //Mechanics stay near the group
4808
if(droid.order != DORDER_ATTACK) //Not already attacking
4810
if(losTwoObjects(droid, structure, FALSE)) //If can see this structure
4812
orderDroidObj(droid, DORDER_ATTACK, structure);
4813
//sVtolObject = structure;
4817
droid = iterateGroup(dropGr);
4820
structure = enumStruct();
4825
//Still no target, attack the base
4826
//--------------------------------
4827
if(idleGroup(dropGr) >= (dropGr.members / 2))
4829
orderGroupLoc(dropGr, DORDER_SCOUT, curEnemyX, curEnemyY);
4836
//------------------------------------------------------
4837
//Make attackers return to the base if base is in danger
4838
//------------------------------------------------------
4839
event WatchDefendBase(WatchDefendBaseTr)
4841
//temp = 20 * 128; //Search radius
4852
//tempX = minx - temp;
4853
//tempY = miny - temp;
4854
//buildX = maxx + temp;
4855
//buildY = maxy + temp;
4862
//Check everything's within limits
4863
//--------------------------------
4864
if(tempX < 0) { tempX = 128; }
4865
if(tempY < 0) { tempY = 128; }
4866
if(buildX > (mapWidth * 128)) { buildX = (mapWidth * 128) - 128; }
4867
if(buildY > (mapHeight * 128)) { buildY = (mapHeight * 128) - 128; }
4870
//--------------------------
4871
resetDroidTargets();
4872
setDroidTarPref(DT_WEAP_GROUND); //Tanks only, ignore VTOLs
4875
while(count < numEnemies)
4877
result = numDroidsInArea(Enemies[count], tempX, tempY, buildX, buildY) + result; //Count enemy units
4882
//---------------------------
4883
//If not defending right now
4884
//---------------------------
4885
if(not defendingBase)
4887
//If too many enemies
4888
//---------------------------------
4889
if(result > (defendGr.members + collectSendGr.members + 5)) //collectSendGr is also in the base
4891
defendingBase = TRUE;
4892
powerSaving = TRUE; //Save some power
4893
attackPhase = 1; //Re-initialize attack later
4895
showConsoleText(DebugMsg[0], player); //Base defence active
4897
NumOldDefenders = defendGr.members; //Revert to this number after threat is gone
4899
//Order back to the base (before addign to defeners, so that defenders wouldn't cancel defending, if they already are)
4900
orderGroupLoc(sendOutpostGr, DORDER_MOVE, baseX, baseY);
4901
orderGroupLoc(collectSendGr, DORDER_MOVE, baseX, baseY);
4902
orderGroupLoc(attackGroup, DORDER_MOVE, baseX, baseY);
4903
orderGroupLoc(oilGr, DORDER_MOVE, baseX, baseY);
4904
orderGroupLoc(repairedGroup, DORDER_MOVE, baseX, baseY);
4906
//Add to defenders now
4907
groupAddGroup(defendGr, sendOutpostGr);
4908
groupAddGroup(defendGr, repairedGroup);
4909
groupAddGroup(defendGr, collectSendGr);
4910
groupAddGroup(defendGr, attackGroup);
4911
groupAddGroup(defendGr, oilGr);
4913
setGroupSecondary(defendGr, DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER); //Don't return to the outpost for repair
4916
else //If defending and no threat, then cancel defend state
4919
if(result < 2) //Almost all kiled
4923
//else //Compare number of enemy and friendly units in the base
4925
// result2 = numDroidsInArea(player, tempX, tempY, buildX, buildY);
4926
// if(result2 > (result + 8))
4928
// boolResult = TRUE;
4932
if(boolResult) //Can stop defending
4934
showConsoleText(DebugMsg[1], player); //Base defence off
4935
defendingBase = FALSE;
4937
if(NumOldDefenders < 8) //Leave enough defenders
4939
NumOldDefenders = 8;
4942
//Add defenders back to attackers
4943
//-------------------------------
4944
count = defendGr.members;
4945
initIterateGroup(defendGr);
4946
droid = iterateGroup(defendGr);
4947
while((droid != NULLOBJECT) and (count > NumOldDefenders)) //While there are now more defenders that there were
4949
if(droid.droidType != DROID_REPAIR) //Leave repair unit for the defenders
4951
orderDroid(droid, DORDER_STOP); //Make idle
4952
groupAddDroid(sendOutpostGr, droid); //Add back to attackers
4955
droid = iterateGroup(defendGr);
4958
toRepDefendDroid[0] = NULLOBJECT; //Make repairer stop following this unit if it became an attacker
4959
toRepDefendDroid[1] = NULLOBJECT;
4961
NumOldDefenders = 0;
4967
//-------------------------------------
4968
//Help an ally if he's in trouble
4969
//-------------------------------------
4970
event WatchHelpAlly(WatchHelpAllyTr)
4972
temp = (12 * 128); //Base radius around the found structure
4974
if((not defendingBase) and (helpAllyPlayer < 0)) //Not busy
4976
if(attackGroup.members > 5)
4979
while((count < 8) and (helpAllyPlayer < 0)) //For all 8 players and while haven't started helping to defend yet
4981
if(allyPlayer[count])
4984
//--------------------------------------
4985
boolResult2 = FALSE;
4987
while((count2 < numBaseStructs) and (not boolResult2)) //For all base structures
4989
structure = getStructure(baseStructs[count2], count); //Find Ally's base structure
4990
if(structure != NULLOBJECT)
4992
tempX = structure.x;
4993
tempY = structure.y;
4994
boolResult2 = TRUE; //Found base
4996
count2 = count2 + 1;
4999
if(boolResult2) //If base found
5001
temp = 12 * 128; //Search radius
5003
result = numDroidsInArea(count, tempX - temp, tempY - temp, tempX + temp, tempY + temp); //Count Ally's units
5005
//Count number of enemies in ally's base
5006
//--------------------------------------
5009
while(count2 < numEnemies)
5011
result2 = numDroidsInArea(Enemies[count2], tempX - temp, tempY - temp, tempX + temp, tempY + temp) + result2; //Count enemy units
5012
count2 = count2 + 1;
5015
if(result2 > (result + 7)) //If many more enemy than ally units in ally's base
5017
showConsoleText(DebugMsg[12], player); //Helping ally's base
5020
groupAddGroup(attackGroup, sendOutpostGr);
5021
groupAddGroup(attackGroup, repairedGroup);
5022
groupAddGroup(attackGroup, oilGr);
5023
//groupAddGroup(attackGroup, collectSendGr);
5025
setGroupSecondary(attackGroup, DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER); //Don't return to the outpost for repair
5026
attackPhase = 1; //Re-initialize attack later
5027
helpAllyPlayer = count;
5035
else if(helpAllyPlayer > (-1)) //Helping an ally already
5037
if((helpAllyPlayerX > (-1)) and (helpAllyPlayerY > (-1))) //Help coords exist
5039
//Check if threat is gone now
5040
//---------------------------
5041
result = numDroidsInArea(helpAllyPlayer, helpAllyPlayerX - temp, helpAllyPlayerY - temp, helpAllyPlayerX + temp, helpAllyPlayerY + temp); //Count Ally's units
5043
//Count number of enemies in ally's base
5044
//--------------------------------------
5047
while(count2 < numEnemies)
5049
result2 = numDroidsInArea(Enemies[count2], helpAllyPlayerX - temp, helpAllyPlayerY - temp, helpAllyPlayerX + temp, helpAllyPlayerY + temp) + result2; //Count enemy units
5050
count2 = count2 + 1;
5053
if((result > (result2 + 6)) or (result2 == 0)) //If ally has more units than enemy or no enemy units at all
5055
showConsoleText(DebugMsg[13], player); //Ally's base is safe. Returning.
5057
helpAllyPlayer = -1; //Cancel 'help AI base' state
5058
helpAllyPlayerX = -1;
5059
helpAllyPlayerY = -1;
5066
event PowerBoost(PowerBoostTr)
5068
//Customizable power cheat
5070
addPower(temp, player); /*%! ID="GKPowerBoost",
5071
MainDesc="Power boost amount",
5072
type="asn", //Assign
5074
ArgDesc="No power boost (Default)",
5076
ArgDesc="Small power boost",
5078
ArgDesc="Medium power boost",
5080
ArgDesc="Big power boost",
5082
ArgDesc="Huge power boost" */
5085
event deactivate(CALL_GAMEINIT)
5087
debugMode = FALSE; /*%! ID="GK_Debug",
5088
MainDesc="Enable GK debug (observe) mode",
5090
type="asn", //Assign
5093
if( (not debugMode) and ((player == selectedPlayer) or (not myResponsibility(player))) )
5095
setEventTrigger(StartGame,inactive);
5096
setEventTrigger(LegoBuild,inactive);
5097
setEventTrigger(Rush,inactive);
5098
setEventTrigger(chooseEnemy,inactive);
5099
setEventTrigger(BuildAttackForce,inactive);
5100
setEventTrigger(doResearch,inactive);
5101
setEventTrigger(basedetails,inactive);
5102
setEventTrigger(keepTrack,inactive);
5103
setEventTrigger(droidDestroyed,inactive);
5104
setEventTrigger(buildPowerGenerators,inactive);
5105
setEventTrigger(LegoTrucks,inactive);
5106
setEventTrigger(droidBuilt,inactive);
5107
setEventTrigger(difficultyMod,inactive);
5108
setEventTrigger(upgradeStructures,inactive);
5109
setEventTrigger(moveIfAttacked,inactive);
5110
setEventTrigger(stuck,inactive);
5111
setEventTrigger(buildVtols,inactive);
5112
setEventTrigger(vtolDefend,inactive);
5113
setEventTrigger(vtolAttack,inactive);
5114
setEventTrigger(formAllianceEvent,inactive);
5115
setEventTrigger(formHumanAlliances,inactive);
5116
setEventTrigger(updateDetails,inactive);
5117
setEventTrigger(repairStuff,inactive);
5118
setEventTrigger(FinishStructures,inactive);
5119
setEventTrigger(buildCyborgs,inactive);
5120
setEventTrigger(cyborgDrop,inactive);
5121
setEventTrigger(manageDropAttacks,inactive);
5122
setEventTrigger(WatchDefendBase,inactive);
5123
setEventTrigger(WatchHelpAlly,inactive);
5124
setEventTrigger(sendScouts,inactive);
5125
setEventTrigger(agressiveDefence,inactive);
5126
setEventTrigger(additVTOLDefenses,inactive);
5127
setEventTrigger(PowerBoost,inactive);