-299 Removals
+1279 Additions
1/////////////////////////////////////////////////////////////////////1/////////////////////////////////////////////////////////////////////
2// general ai for skirmish game2// general ai for skirmish game
3/////////////////////////////////////////////////////////////////////3/////////////////////////////////////////////////////////////////////
4// Warzone2100, Pumpkin Studios,4// Warzone2100, Pumpkin Studios,
5// alex lee.98/99.5// alex lee.98/99.
6//6//
7/////////////////////////////////////////////////////////////////////7/////////////////////////////////////////////////////////////////////
88
9//Tile in world units9//Tile in world units
10#define TILE 12810#define TILE 128
11#define NONE (-1)11#define NONE (-1)
1212
13// These are final rules of the lexical parser13// These are final rules of the lexical parser
14#define R_REQUEST_HELP "help me"14#define R_REQUEST_HELP "help me"
15#define R_REQUEST_BEACON "drop a beacon"15#define R_REQUEST_BEACON "drop a beacon"
16#define R_REPORT_SAFETY "i'm ok"16#define R_REPORT_SAFETY "i'm ok"
17#define R_REQUEST_ALLY "ally me"17#define R_REQUEST_ALLY "ally me"
1818
19// These are our own messages - lexical parser should be able to handle them19// These are our own messages - lexical parser should be able to handle them
20#define M_REQUEST_HELP "help me!!"20#define M_REQUEST_HELP "help me!!"
21#define M_REQUEST_BEACON "drop a beacon"21#define M_REQUEST_BEACON "drop a beacon"
22#define M_AFFIRMATIVE_OK "ok"22#define M_AFFIRMATIVE_OK "ok"
23#define M_AFFIRMATIVE_ROGER "roger"23#define M_AFFIRMATIVE_ROGER "roger"
24#define M_ANNOYED "bug off"24#define M_ANNOYED "bug off"
25#define M_HELPERS_KILLED "that was all I had.."25#define M_HELPERS_KILLED "that was all I had.."
26#define M_HELP_NO_UNITS "I don't have anything"26#define M_HELP_NO_UNITS "I don't have anything"
2727
28#define MAX_PROBABILITY 10028#define MAX_PROBABILITY 100
2929
30// Base threat range in world units30// Base threat range in world units
31#define W_BASE_THREAT_RANGE ((17 + (mapWidth + mapHeight) / 2 / 35) * TILE)31#define W_BASE_THREAT_RANGE ((17 + (mapWidth + mapHeight) / 2 / 35) * TILE)
32#define ALL_ALLIES -132#define ALL_ALLIES -1
3333
34#define BASE_DEFEND_DURATION (3 * 60)34#define BASE_DEFEND_DURATION 1
3535
36// Delay before we repeat our request, in seconds36// Delay before we repeat our request, in seconds
37#define HELP_REQUEST_INTERVAL (3 * 60)37#define HELP_REQUEST_INTERVAL 20
3838
39//in secs39//in secs
40#define BEACON_TIMEOUT 3040#define BEACON_TIMEOUT 25
4141
42#define MAX_DROIDS 15042#define MAX_DROIDS 150
4343
44//range for trucks to look for more oil44//range for trucks to look for more oil
45#define MORE_OIL_RANGE (10 * TILE)45#define MORE_OIL_RANGE (10 * TILE)
46//don't try to build on oil if there's threat within this range46//don't try to build on oil if there's threat within this range
47#define OIL_THREAT_RANGE (9 * TILE)47#define OIL_THREAT_RANGE (9 * TILE)
4848
49#define MAX_TRUCKS 1249#define MAX_TRUCKS 14
50#define MIN_TRUCKS 550#define MIN_TRUCKS 2
5151
52//Enter power saving mode when lower than this52//Enter power saving mode when lower than this
53#define LOW_POWER 25053#define LOW_POWER 250
5454
55//Target type values55//Target type values
56#define NO_TARGET_VALUE 056#define NO_TARGET_VALUE 0
57#define DROID_TARGET_VALUE 157#define DROID_TARGET_VALUE 1
58#define OTHER_TARGET_VALUE 258#define OTHER_TARGET_VALUE 2
59#define DEFENSE_TARGET_VALUE 359#define DEFENSE_TARGET_VALUE 3
60#define RESEARCH_TARGET_VALUE 460#define RESEARCH_TARGET_VALUE 4
61#define HQ_TARGET_VALUE 561#define HQ_TARGET_VALUE 5
62#define OIL_TARGET_VALUE 662#define OIL_TARGET_VALUE 6
63#define FACTORY_TARGET_VALUE 763#define FACTORY_TARGET_VALUE 7
6464
65#define UNLIMITED (-1)65#define UNLIMITED (-1)
6666
67#define AA_THREAT_RANGE (TILE * 12)67#define AA_THREAT_RANGE 1
6868
69#define MAX_DEFENDERS_RADIUS (TILE * 40)69#define MAX_DEFENDERS_RADIUS (TILE * 50)
70
71#define MAX_VTOL_DEFEND_RADIUS (TILE * 50)
7072
71#define MAX_VTOL_DEFEND_RADIUS (TILE * 25)
7273
73// AI will remember max this number of structures74// AI will remember max this number of structures
74#define MAX_REBUILD_STRUCT 10075#define MAX_REBUILD_STRUCT 100
7576
76//Total number of technology branches77//Total number of technology branches
77#define TECHS 278#define TECHS 6
7879
79//How many best templates to choose from when deciding what template to build80//How many best templates to choose from when deciding what template to build
80#define MAX_RANDOM_TEMPLATES 481#define MAX_RANDOM_TEMPLATES 4
8182
8283
8384
84private int me; // player for this instance.85private int me; // player for this instance.
85public int tileExpand; // rate of exploration86public int tileExpand; // rate of exploration
8687
87public int numScouts[TECHS],maxScouts[TECHS]; // aim for...88public int numScouts[TECHS],maxScouts[TECHS]; // aim for...
88public int numDefenders[TECHS],maxDefenders[TECHS];89public int numDefenders[TECHS],maxDefenders[TECHS];
89public int numAttackers[TECHS],maxAttackers[TECHS];90public int numAttackers[TECHS],maxAttackers[TECHS];
90public int numCyborgs[TECHS],maxCyborgs[TECHS];91public int numCyborgs[TECHS],maxCyborgs[TECHS];
9192
92public int branchDefault,branchVTOL,techCount[TECHS],maxVtolFacs[TECHS],maxIdleRes[TECHS],93public int branchRocket,branchVTOL,branchCannon,branchArtillery,branchOneAlly,branchTwoAlly,techCount[TECHS],maxVtolFacs[TECHS],maxIdleRes[TECHS],
93 maxVTOLs[TECHS],numVtolTargets,vtolTargetWeight[10],numRebuildStat[TECHS];94 maxVTOLs[TECHS],numVtolTargets,vtolTargetWeight[10],numRebuildStat[TECHS];
94public RESEARCHSTAT tech[TECHS][30]; //technology for different research branches95public RESEARCHSTAT tech[TECHS][47]; //technology for different research branches
95public STRUCTURESTAT vtolTarget[10],rebuildStat[TECHS][2];96public STRUCTURESTAT vtolTarget[10],rebuildStat[TECHS][2];
9697
97// structures98// structures
98private int baseX,baseY,minx,miny,maxx,maxy;99private int baseX,baseY,minx,miny,maxx,maxy;
99public int numStructs,numIncendrys,numDefStructs,numExtraStructs[TECHS],numWallWeaps,numBaseStruct,numLightCyborgs,numFundamental;100public int numStructs,numIncendrys,numDefStructs,numExtraStructs[TECHS],numWallWeaps,numBaseStruct,numLightCyborgs,numFundamental;
100private STRUCTURESTAT structChoice[5];101private STRUCTURESTAT structChoice[5];
101public STRUCTURESTAT incendrys[8],structs[13],defStructs[26],extraStructs[TECHS][6],wallWeaps[11];102public STRUCTURESTAT incendrys[11],structs[16],defStructs[37],extraStructs[TECHS][6],wallWeaps[11];
102public STRUCTURESTAT sensorTower,wall,cornerWall,resLab,powGen,playerHQ,lassat,factory,derrick,cybFactory,103public STRUCTURESTAT sensorTower,wall,cornerWall,resLab,powGen,playerHQ,lassat,factory,derrick,gderrick,cybFactory,
103 vtolDefStruct[5],vtolPad,vtolFactory,uplink,baseStruct[8];104 vtolDefStruct[9],vtolPad,vtolFactory,uplink,baseStruct[8];
104public STRUCTURESTAT powModule,facModule,resModule,vtolModule;105public STRUCTURESTAT powModule,facModule,resModule,vtolModule;
105public int extraStruct;106public int extraStruct;
106107
107// unit templates108// unit templates
108public int numTemplates[TECHS];109public int numTemplates[TECHS];
109public TEMPLATE tmpl[TECHS][70];110public TEMPLATE tmpl[TECHS][100];
110private TEMPLATE tmplChoice[5];111private TEMPLATE tmplChoice[100];
111112
112public TEMPLATE cybTempl[10],superCyb[4],cybMechanic,cybEngineer,hovertruck;113public TEMPLATE cybTempl[9],superCyb[15],cybMechanic,cybEngineer,hovertruck;
113114
114public TEMPLATE vtols[18];115public TEMPLATE vtols[27],vtolAAdroid;
115public int numVtolTemplates;116public int numVtolTemplates;
116117
117public TEMPLATE sense[11];118public TEMPLATE sense[8];
118public int numSenseTemplates;119public int numSenseTemplates;
119120
120public TEMPLATE constructor,repairUnit;121public TEMPLATE constructor,repair[6];
121public int numRepairUnits;122public int numRepairUnits;
123public int numSensorUnits;
124public int numRepairTemplates;
122125
123//defend126//defend
124private GROUP defendGroup;127private GROUP defendGroup;
125private bool defendbusy;128private bool defendbusy;
126private BASEOBJ defendObj;129private BASEOBJ defendObj;
127130
128public RESEARCHSTAT nexusDefence;131public RESEARCHSTAT nexusDefence;
129private RESEARCHSTAT research;132private RESEARCHSTAT research;
130133
131//build134//build
132private GROUP buildGroup;135private GROUP buildGroup;
133private int buildX,buildY,buildX2,buildY2;136private int buildX,buildY,buildX2,buildY2;
134public FEATURESTAT oilRes;137public FEATURESTAT oilRes;
135138
136// scout139// scout
137private GROUP scoutGroup;140private GROUP scoutGroup;
138private int scoutX,scoutY;141private int scoutX,scoutY;
139private int scoutTLX,scoutTLY,scoutW,scoutH;142private int scoutTLX,scoutTLY,scoutW,scoutH;
140143
141// attack144// attack
142private GROUP attackGroup;145private GROUP attackGroup;
143private BASEOBJ attackObj,allOutAttack,vtolGrAttackObj[10];146private BASEOBJ attackObj,allOutAttack,vtolGrAttackObj[10];
144147
145// vtols148// vtols
146private GROUP vtolDefendGr,vtolAttackGr[10];149private GROUP vtolDefendGr,vtolAttackGr[10];
147150
148// generic151// generic
149private STRUCTURE structure,structure2,rebuildObj[100];152private STRUCTURE structure,structure2,rebuildObj[100];
150private DROID droid;153private DROID droid;
151private FEATURE feature;154private FEATURE feature;
152private BASEOBJ baseobj,baseobj2;155private BASEOBJ baseobj,baseobj2;
153private int count,count2,result,result2,tempx,tempy;156private int count,count2,result,result2,tempx,tempy;
154private bool boolResult,boolResult2;157private bool boolResult,boolResult2;
155158
156private bool powerSave,_DEBUG,bRunning;159private bool powerSave,_DEBUG,bRunning;
157// Hopefully this will be at least as large as MAX_PLAYERS... Why can't I just use MAX_PLAYERS as the array size?!160// Hopefully this will be at least as large as MAX_PLAYERS... Why can't I just use MAX_PLAYERS as the array size?!
158// P.S. And why can't I put a comment on the same line as a #define??!! Gah, who cares if the lua2 branch works, lets switch to it, anyway.161// P.S. And why can't I put a comment on the same line as a #define??!! Gah, who cares if the lua2 branch works, lets switch to it, anyway.
159#define MAX_PLAYERS_HACK 17162#define MAX_PLAYERS_HACK 17
160private int allianceTime[MAX_PLAYERS_HACK];163private int allianceTime[MAX_PLAYERS_HACK];
161private int sender,x,y,beaconX[8],beaconY[8],tBeacon[8],164private int sender,x,y,beaconX[8],beaconY[8],tBeacon[8],
162 tLastHelpRequest,lastHelpPlayer,tHelp,tHelpTimeout,helpX,helpY;165 tLastHelpRequest,lastHelpPlayer,tHelp,tHelpTimeout,helpX,helpY;
163private string message;166private string message;
164167
165private int defendX,defendY,__defendRadiusUnused,tDefendStart,tDefendTimeout,168private int defendX,defendY,__defendRadiusUnused,tDefendStart,tDefendTimeout,
166 defendMoveType,baseRange,curTech,numVtolAttackGroups,numAttackVtols,169 defendMoveType,baseRange,curTech,numVtolAttackGroups,numAttackVtols,
167 numDefendVtols,rebuildStructX[MAX_REBUILD_STRUCT],rebuildStructY[MAX_REBUILD_STRUCT],countRebuildStruct;170 numDefendVtols,rebuildStructX[MAX_REBUILD_STRUCT],rebuildStructY[MAX_REBUILD_STRUCT],countRebuildStruct;
168private STRUCTURESTAT rebuildStructStat[MAX_REBUILD_STRUCT];171private STRUCTURESTAT rebuildStructStat[MAX_REBUILD_STRUCT];
169172
170private STRUCTURESTAT fundamentalBeingBuilt;173private STRUCTURESTAT fundamentalBeingBuilt;
171private int order; // callback global174private int order; // callback global
172175
173/////////////////////////////////////////////////////////////////////176/////////////////////////////////////////////////////////////////////
174// triggers.177// triggers.
175178
176#region triggers179#region triggers
177trigger reachedTr (CALL_DROID_REACH_LOCATION, me, ref droid, ref order);180trigger reachedTr (CALL_DROID_REACH_LOCATION, me, ref droid, ref order);
178trigger buildExpandTr (every, 600);181trigger buildExpandTr (every, 999999999);
179trigger fortifyTr (every, 1000);182trigger fortifyTr (every, 1200);
180trigger upgradeStructuresTr (every, 360);183trigger upgradeStructuresTr (every, 40);
181trigger conDroidsTr (every, 900); // was 1400184trigger conDroidsTr (every, 400); // was 1400
182trigger repairDroidsTr (every, 2600);185trigger repairDroidsTr (every, 500);
186trigger sensorDroidsTr (every, 800);
183trigger basedetailsTr (every, 600 );187trigger basedetailsTr (every, 600 );
184trigger buildDerrickTr (every, 80 );188trigger buildDerrickTr (every, 140 );
185trigger buildOilDefenseOrRetreatTr (every, 120 );189trigger buildOilDefenseOrRetreatTr (every, 400 );
186trigger incendryTr (every, 250 );190trigger incendryTr (every, 60 );
187trigger buildPowerGeneratorsTr (every, 80 );191trigger buildPowerGeneratorsTr (every, 50 );
188trigger buildBaseTr (every, 150 );192trigger buildResearchCentersTr (every, 70 );
189trigger finishStructsTr (every, 210);193trigger buildFactoryTr (every, 120 );
194trigger buildCyborgFactoryTr (every, 150 );
195trigger buildVTOLFactoryTr (every, 350 );
196trigger buildBaseTr (every, 1800);
197trigger finishStructsTr (every, 30);
190trigger droidBuiltTr (CALL_NEWDROID,me, ref droid,ref structure);198trigger droidBuiltTr (CALL_NEWDROID,me, ref droid,ref structure);
191trigger structBuiltTr (CALL_STRUCTBUILT, me, ref droid, ref structure);199trigger structBuiltTr (CALL_STRUCTBUILT, me, ref droid, ref structure);
192trigger droidDestroyedTr (CALL_DROID_DESTROYED, me, ref droid);200trigger droidDestroyedTr (CALL_DROID_DESTROYED, me, ref droid);
201trigger enemyInBaseTr (every, 120);
193trigger structureDestroyedTr (CALL_STRUCT_DESTROYED, me, ref structure);202trigger structureDestroyedTr (CALL_STRUCT_DESTROYED, me, ref structure);
194trigger rebuildStructureTr (every, 50);203trigger rebuildStructureTr (every, 50);
195trigger consolidateEventTr (every, 3100);204trigger consolidateEventTr (every, 999999);
196trigger factoryEventTr (every, 170 );205trigger factoryEventTr (every, 180 );
197trigger cyborgFactoryEventTr (every, 170 );206trigger cyborgFactoryEventTr (every, 120 );
198trigger chooseScoutAreaTr (every, 200 );207trigger chooseScoutAreaTr (every, 80 );
199trigger expandScoutAreaTr (every, 600 );208trigger expandScoutAreaTr (every, 240 );
200trigger scoutMainTr (every, 150 );209trigger scoutMainTr (every, 150 );
201trigger newObjectReportTr (CALL_OBJ_SEEN, me, ref baseobj, ref baseobj2);210trigger newObjectReportTr (CALL_OBJ_SEEN, me, ref baseobj, ref baseobj2);
202trigger attackStuffTr (every, 300 );211trigger attackStuffTr (every, 100 );
203trigger allOutAttackTr (every, 4000);212trigger allOutAttackTr (every, 6000);
204trigger defendWatchTr (CALL_STRUCT_ATTACKED, me, ref structure, ref baseobj);213trigger defendWatchTr (CALL_STRUCT_ATTACKED, me, ref structure, ref baseobj);
205trigger defendReturnTr (every, 500 );214trigger defendReturnTr (every, 100000 );
206trigger doResearchTr (CALL_RESEARCHCOMPLETED, ref research, ref structure, me);215trigger doResearchTr (CALL_RESEARCHCOMPLETED, ref research, ref structure, me);
207trigger vtolDefendTr (CALL_STRUCT_ATTACKED, me, ref structure, ref baseobj);216trigger vtolDefendTr (CALL_STRUCT_ATTACKED, me, ref structure, ref baseobj);
208trigger vtolStructsTr (every, 290);217trigger vtolStructsTr (every, 185);
209trigger buildVtolsTr (every, 360);218trigger buildVtolsTr (every, 360);
210trigger vtolAttackTr (every, 150);219trigger vtolAttackTr (every, 75);
211trigger vtolEnablerTr (every, 700);220trigger vtolEnablerTr (every, 80);
212trigger takeoverTr (CALL_UNITTAKEOVER, ref droid);221trigger takeoverTr (CALL_UNITTAKEOVER, ref droid);
213trigger useLassatTr (every, 3000);222trigger useLassatTr (every, 1000);
214trigger reassignTr (CALL_PLAYERLEFT,ref count);223trigger reassignTr (CALL_PLAYERLEFT,ref count);
215trigger formAllianceEventTr (every,170);224trigger formAllianceEventTr (every,170);
216trigger breakAllianceEventTr (every,3000);225trigger breakAllianceEventTr (every,3000);
217trigger difficultyModifierTr (every,600);226//trigger difficultyModifierTr (every,600);
218trigger humanAllianceTr (CALL_ALLIANCEOFFER,ref count, ref count2);227trigger humanAllianceTr (CALL_ALLIANCEOFFER,ref count, ref count2);
219trigger multiMsgTr (CALL_AI_MSG, me, ref sender, ref message);228trigger multiMsgTr (CALL_AI_MSG, me, ref sender, ref message);
220trigger beaconTr (CALL_BEACON, me, ref sender, ref x, ref y, ref message);229trigger beaconTr (CALL_BEACON, me, ref sender, ref x, ref y, ref message);
221trigger consoleTr (CALL_CONSOLE, ref sender, ref message);230trigger consoleTr (CALL_CONSOLE, ref sender, ref message);
222trigger watchBaseThreatTr (every, 120);231trigger watchBaseThreatTr (every, 120);
223trigger manageAllyHelpTr (every, 80);232trigger manageAllyHelpTr (every, 80);
224trigger everySec (every, 10);233trigger everySec (every, 10);
225trigger manageDefendLocationTr (every, 70);234trigger manageDefendLocationTr (every, 70);
226trigger startLevelTr (CALL_START_NEXT_LEVEL);235trigger startLevelTr (CALL_START_NEXT_LEVEL);
227trigger chainloadTr (wait, 1);236trigger chainloadTr (wait, 1);
228trigger slowloadTr (wait, 13);237trigger slowloadTr (wait, 13);
229trigger checkResearchTr (every, 400);238trigger delayedloadTr (wait, 50);
239trigger checkResearchTr (every, 100);
230240
231/* Events */241/* Events */
232event conDroids;242event conDroids;
233event multiMsgEv;243event multiMsgEv;
234event beaconEv;244event beaconEv;
235event watchBaseThreat;245event watchBaseThreat;
236event manageAllyHelp;246event manageAllyHelp;
237event everySecEv;247event everySecEv;
238event manageDefendLocationEv;248event manageDefendLocationEv;
239event structureDestroyed;249event structureDestroyed;
240event rebuildStructureEv;250event rebuildStructureEv;
241event doResearch;251event doResearch;
242event buildDerrick;252event buildDerrick;
253event findEnemy;
254//event newfortify;
255//event incendry;
243256
244/* Function prototypes */257/* Function prototypes */
245function bool haveBeacon(int _player);258function bool haveBeacon(int _player);
246function bool beaconTimeout(int _player);259function bool beaconTimeout(int _player);
247function void processCommand(string _message, int _sender, bool _bBlipMessage);260function void processCommand(string _message, int _sender, bool _bBlipMessage);
248function bool haveHelpers();261function bool haveHelpers();
249function bool attemptToHelp(int _playerToHelp, int _x, int _y);262function bool attemptToHelp(int _playerToHelp, int _x, int _y);
250function void helpPlayer(int _playerToHelp, int _helpX, int _helpY);263function void helpPlayer(int _playerToHelp, int _helpX, int _helpY);
251function bool canStopHelpingAlly();264function bool canStopHelpingAlly();
252function void stopHelpingAlly();265function void stopHelpingAlly();
253function bool helpingAlly();266function bool helpingAlly();
254function bool helpAllyTimeout();267function bool helpAllyTimeout();
255function void requestHelp(int _helpX, int _helpY);268function void requestHelp(int _helpX, int _helpY);
256function void doRequestHelp(int _helpX, int _helpY);269function void doRequestHelp(int _helpX, int _helpY);
257function bool allyBaseAtLoc(int _ally, int _x, int _y);270function bool allyBaseAtLoc(int _ally, int _x, int _y);
258function void messagePlayer(int _playerToMessage, string _message, int _probability);271function void messagePlayer(int _playerToMessage, string _message, int _probability);
259function void messagePlayerAddressed(int _playerToMessage, int _playersToAddress, string _message);272function void messagePlayerAddressed(int _playerToMessage, int _playersToAddress, string _message);
260function bool canSeeAllies();273function bool canSeeAllies();
261function bool baseInTrouble();274function bool baseInTrouble();
262function string m_affirmative();275function string m_affirmative();
263function void defendLocation(int _defendX, int _defendY, int _tDefendTimeout, bool _bMove);276function void defendLocation(int _defendX, int _defendY, int _tDefendTimeout, bool _bMove);
264function void stopDefendingLocation();277function void stopDefendingLocation();
265function bool defendingLocation();278function bool defendingLocation();
266function bool defendLocationTimeout();279function bool defendLocationTimeout();
267function bool friendlyPlayer(int _playerToCheck);280function bool friendlyPlayer(int _playerToCheck);
268function void factoryBuildDroid(STRUCTURE _factory);281function void factoryBuildDroid(STRUCTURE _factory);
269function void cybFactorBuildCyborg(STRUCTURE _factory);282function void cybFactorBuildCyborg(STRUCTURE _factory);
270function void vtolFactoryBuildVtol(STRUCTURE _factory);283function void vtolFactoryBuildVtol(STRUCTURE _factory);
271function bool insideBase(int _x, int _y);284function bool insideBase(int _x, int _y);
272function int numAlliesInBase(bool _bVtols);285function int numAlliesInBase(bool _bVtols);
273function int numEnemiesInBase(bool _bVtols);286function int numEnemiesInBase(bool _bVtols);
274function bool defendingOwnBase();287function bool defendingOwnBase();
275function int targetTypeValue(BASEOBJ _target);288function int targetTypeValue(BASEOBJ _target);
276function int numBitsSet(int _integer);289function int numBitsSet(int _integer);
277function int findResearch(int _searchStart, int _techTree);290function int findResearch(int _searchStart, int _techTree);
278function bool upgradeFactory(DROID _truck, int _maxBuilders);291function bool upgradeFactory(DROID _truck, int _maxBuilders);
279function bool upgradeVtolFactory(DROID _truck, int _maxBuilders);292function bool upgradeVtolFactory(DROID _truck, int _maxBuilders);
280function bool upgradeResearch(DROID _truck, int _maxBuilders);293function bool upgradeResearch(DROID _truck, int _maxBuilders);
281function bool upgradePowGen(DROID _truck, int _maxBuilders);294function bool upgradePowGen(DROID _truck, int _maxBuilders);
282function void buildRearmPads();295function void buildRearmPads();
283function int numEnemyAAInRange(int _x, int _y, int _range);296function int numEnemyAAInRange(int _x, int _y, int _range);
284function BASEOBJ chooseVtolTarget(bool bExclusiveTarget);297function BASEOBJ chooseVtolTarget(bool bExclusiveTarget);
285function int getVtolTargetWeight(BASEOBJ _target);298function int getVtolTargetWeight(BASEOBJ _target);
286function bool vtolTargetAssigned(BASEOBJ _target);299function bool vtolTargetAssigned(BASEOBJ _target);
287function int numBuildSameBuilding(STRUCTURESTAT _checkStat, int _x, int _y);300function int numBuildSameBuilding(STRUCTURESTAT _checkStat, int _x, int _y);
288function int totalVtols();301function int totalVtols();
289function bool needTank();302function bool needTank();
290function void setTechBranch(int _tech);303function void setTechBranch(int _tech);
291function DROID closestIdleTruck(int _x, int _y);304function DROID closestIdleTruck(int _x, int _y);
292function void buildOnExactLocation(DROID _truck, int _x, int _y, STRUCTURESTAT _stat);305function void buildOnExactLocation(DROID _truck, int _x, int _y, STRUCTURESTAT _stat);
293function void rebuildStructures();306function void rebuildStructures();
294function BASEOBJ chooseVtolDefenceTarget(int _x, int _y, int _range, bool bExclusiveTarget);307function BASEOBJ chooseVtolDefenceTarget(int _x, int _y, int _range, bool bExclusiveTarget);
295function int numGroupSameOrder(GROUP _group, int _orderIndex);308function int numGroupSameOrder(GROUP _group, int _orderIndex);
296function void rearrangeAttackVtols();309function void rearrangeAttackVtols();
297function int numStructBusyByType(STRUCTURESTAT _busyStructType);310function int numStructBusyByType(STRUCTURESTAT _busyStructType);
298function bool aiResponsibleForPlayer(int _player);311function bool aiResponsibleForPlayer(int _player);
299function void reassignAI();312function void reassignAI();
300function void shutDownAI();313function void shutDownAI();
301function bool buildUnit(TEMPLATE _tankTemplate, STRUCTURE _factory, STRUCTURESTAT _factoryType, bool _bIdleOnly);314function bool buildUnit(TEMPLATE _tankTemplate, STRUCTURE _factory, STRUCTURESTAT _factoryType, bool _bIdleOnly);
302function STRUCTURE findIdleStructure(STRUCTURESTAT _structType, bool _bIdleOnly);315function STRUCTURE findIdleStructure(STRUCTURESTAT _structType, bool _bIdleOnly);
303#endregion triggers316#endregion triggers
304317
305/////////////////////////////////////////////////////////////////////318/////////////////////////////////////////////////////////////////////
306// HouseKeeping319// HouseKeeping
307event initialisedEvent(CALL_GAMEINIT)320event initialisedEvent(CALL_GAMEINIT)
308{321{
309 local int player;322 local int player;
310 // initialise323 // initialise
311 me = getPlayer("Nexus");324 me = getPlayer("Nexus");
312 _DEBUG = FALSE;325 _DEBUG = FALSE;
313 dbgMsgOn(me, _DEBUG);326 dbgMsgOn(me, _DEBUG);
314327
315 extraStruct = 0;328 extraStruct = 0;
316 numRepairUnits = 0;329 numRepairUnits = 0;
330 numSensorUnits = 0;
317 allOutAttack = NULLOBJECT;331 allOutAttack = NULLOBJECT;
318332
319 tLastHelpRequest = -1; //when we requested help for the last time333 tLastHelpRequest = -1; //when we requested help for the last time
320 lastHelpPlayer = -1; //we are not currently helping anyone334 lastHelpPlayer = -1; //we are not currently helping anyone
321 tHelp = -1; //when we started helping last time335 tHelp = -1; //when we started helping last time
322 tHelpTimeout = -1; //time when help times out336 tHelpTimeout = -1; //time when help times out
323 helpX = -1;337 helpX = -1;
324 helpY = -1;338 helpY = -1;
325 defendX = -1;339 defendX = -1;
326 defendY = -1;340 defendY = -1;
327 tDefendStart = -1;341 tDefendStart = -1;
328 tDefendTimeout = -1;342 tDefendTimeout = -1;
329 defendMoveType = -1; //move or scout343 defendMoveType = -1; //move or scout
330344
331 baseRange = 4 * TILE;345 baseRange = 4 * TILE;
332346
333 // set current research branch347 // set current research branch
334 setTechBranch(-1);348 setTechBranch(-1);
335349
336 numVtolAttackGroups = 10;350 numVtolAttackGroups = 10;
337 numAttackVtols = 10; //num vtols in an attack group351 numAttackVtols = 10; //num vtols in an attack group
338 numDefendVtols = 5; //num vtols in an attack group352 numDefendVtols = 1; //num vtols in an attack group
339353
340 // setup build group - all initial droids are in buildgroup!354 // setup build group - all initial droids are in buildgroup!
341 groupAddArea(buildGroup, me, 0, 0, (mapWidth*128), (mapHeight*128));355 groupAddArea(buildGroup, me, 0, 0, (mapWidth*128), (mapHeight*128));
342356
343 // note where our base is.357 // note where our base is.
344 getPlayerStartPosition(me, ref baseX, ref baseY);358 getPlayerStartPosition(me, ref baseX, ref baseY);
345359
346 // defence.360 // defence.
347 defendbusy = FALSE;361 defendbusy = FALSE;
348362
349 // setup scouts363 // setup scouts
350 structure = getStructure(factory, me);364 structure = getStructure(factory, me);
351 if(structure != NULLOBJECT)365 if(structure != NULLOBJECT)
352 {366 {
353 scoutTLX = structure.x;367 scoutTLX = structure.x;
354 scoutTLY = structure.y;368 scoutTLY = structure.y;
355 }369 }
356 else370 else
357 {371 {
358 scoutTLX = baseX;372 scoutTLX = baseX;
359 scoutTLY = baseY;373 scoutTLY = baseY;
360 }374 }
361 scoutW = 256;375 scoutW = 256;
362 scoutH = 256;376 scoutH = 256;
363 scoutX = scoutTLX;377 scoutX = scoutTLX;
364 scoutY = scoutTLY;378 scoutY = scoutTLY;
365379
366 // clear the alliance array...380 // clear the alliance array...
367 player = 0;381 player = 0;
368 while (player != MAX_PLAYERS)382 while (player != MAX_PLAYERS)
369 {383 {
370 allianceTime[player] = 0;384 allianceTime[player] = 0;
371 player = player + 1;385 player = player + 1;
372 }386 }
373387
374 fundamentalBeingBuilt = derrick; // to avoid ever being null388 fundamentalBeingBuilt = derrick; // to avoid ever being null
375 389
376 if(aiResponsibleForPlayer(me))390 if(aiResponsibleForPlayer(me))
377 {391 {
378 bRunning = true;392 bRunning = true;
379 }393 }
380 else394 else
381 {395 {
382 bRunning = false;396 bRunning = false;
383 shutDownAI();397 shutDownAI();
384 }398 }
399
385}400}
386401
387// check whether we have at least one structure of that type402// check whether we have at least one structure of that type
388function bool haveStructure(STRUCTURESTAT type) 403function bool haveStructure(STRUCTURESTAT type)
389{404{
390 return getStructure(type, me) != NULLOBJECT;405 return getStructure(type, me) != NULLOBJECT;
391}406}
392407
393// check if we are getting any income408// check if we are getting any income
394function bool havePowerSource()409function bool havePowerSource()
395{410{
396 // we don't check buildings being finished here411 // we don't check buildings being finished here
397 return haveStructure(powGen) and haveStructure(derrick);412 return haveStructure(powGen) and (haveStructure(derrick) or haveStructure(gderrick));
398}413}
399414
400// I am not sure why we need this hack, but the AI can still end up not researching anything at times415// I am not sure why we need this hack, but the AI can still end up not researching anything at times
401event checkResearch(checkResearchTr)416event checkResearch(checkResearchTr)
402{417{
403 setEventTrigger(doResearch, chainloadTr);418 setEventTrigger(doResearch, chainloadTr);
404}419}
405420
406function void dbgPlr(string message)421function void dbgPlr(string message)
407{422{
408 setEventTrigger(doResearch, chainloadTr);423 setEventTrigger(doResearch, chainloadTr);
409 if (me == selectedPlayer)424 if (me == selectedPlayer)
410 {425 {
411 console(message);426 console(message);
412 }427 }
413}428}
414429
415function void dbgObj(DROID obj, string message)430function void dbgObj(DROID obj, string message)
416{431{
417 if (obj.selected)432 if (obj.selected)
418 {433 {
419 console(message);434 console(message);
420 }435 }
421}436}
422437
423function bool conCanHelp(DROID mydroid, int bx, int by)438function bool conCanHelp(DROID mydroid, int bx, int by)
424{439{
425 return (mydroid.order != DORDER_HELPBUILD and mydroid.order != DORDER_BUILD and mydroid.order != DORDER_LINEBUILD and droidCanReach(mydroid, bx, by));440 return (mydroid.order != DORDER_HELPBUILD and mydroid.order != DORDER_BUILD and mydroid.order != DORDER_LINEBUILD and droidCanReach(mydroid, bx, by));
426}441}
427442
428// Build something in main base, grab trucks to do it within tiles range443// Build something in main base, grab trucks to do it within tiles range
429function bool grabTrucksAndBuild(int range, STRUCTURESTAT bstats, int maxBlockingTiles)444function bool grabTrucksAndBuild(int range, STRUCTURESTAT bstats, int maxBlockingTiles)
430{445{
431 local DROID mydroid, closestDroid;446 local DROID mydroid, closestDroid;
432 local int closestDist, currDist, numHelpDroids, tilerange, bx, by;447 local int closestDist, currDist, numHelpDroids, tilerange, bx, by;
433448
434 initIterateGroup(buildGroup); // find idle droids in build group.449 initIterateGroup(buildGroup); // find idle droids in build group.
435 mydroid = iterateGroup(buildGroup);450 mydroid = iterateGroup(buildGroup);
436 closestDist = 99999;451 closestDist = 99999;
437 closestDroid = NULLOBJECT;452 closestDroid = NULLOBJECT;
438 numHelpDroids = 0;453 numHelpDroids = 0;
439 tilerange = range * TILE;454 tilerange = range * TILE;
440 while (mydroid != NULLOBJECT)455 while (mydroid != NULLOBJECT)
441 {456 {
442 if (conCanHelp(mydroid, baseX, baseY))457 if (conCanHelp(mydroid, baseX, baseY))
443 {458 {
444 bx = baseX;459 bx = baseX;
445 by = baseY;460 by = baseY;
446 if (pickDroidStructLocation(mydroid, bstats, ref bx, ref by, me, maxBlockingTiles))461 if (pickDroidStructLocation(mydroid, bstats, ref bx, ref by, me, maxBlockingTiles))
447 {462 {
448 currDist = distBetweenTwoPoints(bx, by, mydroid.x, mydroid.y);463 currDist = distBetweenTwoPoints(bx, by, mydroid.x, mydroid.y);
449 if (currDist < tilerange)464 if (currDist < tilerange)
450 {465 {
451 orderDroidStatsLoc(mydroid, DORDER_BUILD, bstats, bx, by); // close, so help build it466 orderDroidStatsLoc(mydroid, DORDER_BUILD, bstats, bx, by); // close, so help build it
452 numHelpDroids = numHelpDroids + 1;467 numHelpDroids = numHelpDroids + 1;
453 }468 }
454 else if (currDist < closestDist)469 else if (currDist < closestDist)
455 {470 {
456 closestDroid = mydroid; // record this droid as being closest so far471 closestDroid = mydroid; // record this droid as being closest so far
457 closestDist = currDist;472 closestDist = currDist;
458 }473 }
459 }474 }
460 }475 }
461 mydroid = iterateGroup(buildGroup);476 mydroid = iterateGroup(buildGroup);
462 }477 }
463 if (numHelpDroids == 0 and closestDroid != NULLOBJECT) // found none within help radius, so force someone to go long distance traveling478 if (numHelpDroids == 0 and closestDroid != NULLOBJECT) // found none within help radius, so force someone to go long distance traveling
464 {479 {
465 orderDroidStatsLoc(closestDroid, DORDER_BUILD, bstats, bx, by); // you, book a plane ticket and go!480 orderDroidStatsLoc(closestDroid, DORDER_BUILD, bstats, bx, by); // you, book a plane ticket and go!
466 return true;481 return true;
467 }482 }
468 return (numHelpDroids > 0);483 return (numHelpDroids > 0);
469}484}
470485
471event arrived(reachedTr)486event arrived(reachedTr)
472{487{
473 local bool found;488 local bool found;
474 local STRUCTURESTAT myChoice;489 local STRUCTURESTAT myChoice;
490 local STRUCTURE _structure,_target;
491 local int _groupIndex,_newTargetWeight,_oldTargetWeight;
492 local DROID _droid;
493 local BASEOBJ _newTarget;
494
475 if (droid.droidType == DROID_CONSTRUCT or droid.droidType == DROID_CYBORG_CONSTRUCT)495 if (droid.droidType == DROID_CONSTRUCT or droid.droidType == DROID_CYBORG_CONSTRUCT)
476 {496 {
477 dbgObj(droid, "Failed to build where we should - attempt to screw up enemy oil derrick");497 dbgObj(droid, "Failed to build where we should - attempt to screw up enemy oil derrick");
478498
479 // Check if at oil well, and it was taken by enemy499 // Check if at oil well, and it was taken by enemy
480 structure = structureBuiltInRange(derrick, droid.x, droid.y, (5 * 128), -1);500 structure = structureBuiltInRange(derrick, droid.x, droid.y, (5 * 128), -1);
501 _structure = structureBuiltInRange(gderrick, droid.x, droid.y, (5 * 128), -1);
481 if (structure != NULLOBJECT)502 if (structure != NULLOBJECT)
482 {503 {
483 if (not friendlyPlayer(structure.player) and droid.health == 100)504 if (not friendlyPlayer(structure.player) and droid.health == 100)
484 {505 {
485 // Ok, at enemy derrick, and nobody has hurt us yet. Start being nasty.506 // Ok, at enemy derrick, and nobody has hurt us yet. Start being nasty.
486 count = 0;507 count = 0;
487 found = false;508 found = false;
488 // find simplest/cheapest one available to build509 // find simplest/cheapest one available to build
489 while (count < numDefStructs and not found)510 while (count < numDefStructs and not found)
490 {511 {
491 if (isStructureAvailable(defStructs[count], me))512 if (isStructureAvailable(defStructs[count], me))
492 {513 {
493 found = true;514 found = true;
494 }515 }
495 else516 else
496 {517 {
497 count++;518 count++;
498 }519 }
499 }520 }
500 if (found)521 if (found)
501 {522 {
502 buildX = droid.x;523 buildX = droid.x;
503 buildY = droid.y;524 buildY = droid.y;
504 if (pickDroidStructLocation(droid, defStructs[count], ref buildX, ref buildY, me, -1))525 if (pickDroidStructLocation(droid, defStructs[count], ref buildX, ref buildY, me, -1))
505 {526 {
506 orderDroidStatsLoc(droid, DORDER_BUILD, defStructs[count], buildX, buildY);527 orderDroidStatsLoc(droid, DORDER_BUILD, defStructs[count], buildX, buildY);
507 }528 }
508 else529 else
509 {530 {
510 dbgObj(droid, "Wanted to be nasty, but found nowhere to build defense");531 dbgObj(droid, "Wanted to be nasty, but found nowhere to build defense");
511 orderDroid(droid, DORDER_RTB); // nothing more to do here.532 orderDroid(droid, DORDER_RTB); // nothing more to do here.
512 }533 }
513 }534 }
514 else535 else
515 {536 {
516 dbgObj(droid, "Wanted to be nasty, but had nothing nasty to build - returning to base");537 dbgObj(droid, "Wanted to be nasty, but had nothing nasty to build - returning to base");
517 orderDroid(droid, DORDER_RTB); // oh, well. nothing more to do here.538 orderDroid(droid, DORDER_RTB); // oh, well. nothing more to do here.
518 }539 }
519 exit;540 exit;
520 }541 }
521 else if (droid.health < 100 and !insideBase(droid.x, droid.y))542 else if (droid.health < 100 and !insideBase(droid.x, droid.y))
522 {543 {
523 orderDroid(droid, DORDER_RTR); // bolt back to base now!544 orderDroid(droid, DORDER_RTR); // bolt back to base now!
524 exit;545 exit;
525 }546 }
526 }547 }
527 }548 }
549
550 if (isVtol(droid))
551 {
552
553
554 //if(droid.order == DORDER_SCOUT and )
555 //{
556 // orderDroid(droid, DORDER_RTR);
557 //}
558// if(numEnemyObjInRange(me,droid.x,droid.y,1024,FALSE,TRUE) > 1)
559// {
560// orderDroid(droid, DORDER_RTR);
561// _groupIndex = 0;
562// while(_groupIndex < numVtolAttackGroups)
563// {
564// if(attackObj != NULLOBJECT)
565// {
566// initIterateGroup(vtolAttackGr[_groupIndex]);
567// _droid = iterateGroup(vtolAttackGr[_groupIndex]);
568// while(_droid != NULLOBJECT)
569// {
570// if(!friendlyPlayer(attackObj.player))
571// {
572// //_target = objToStructure(attackObj);
573//
574// orderDroidObj(droid, DORDER_ATTACK, attackObj);
575//
576// }
577// _droid = iterateGroup(vtolAttackGr[_groupIndex]);
578// }
579//
580// }
581// _groupIndex++;
582// }
583// }
584// else
585// {
586 setDroidSecondary(droid, DSO_PATROL, DSS_PATROL_SET);
587// }
588
589// _groupIndex = 0;
590// while(_groupIndex < numVtolAttackGroups)
591// {
592// if(vtolAttackGr[_groupIndex].members > 0)
593// {
594// _newTarget = NULLOBJECT;
595//
596// //reset attack targets once in a while
597// if(vtolGrAttackObj[_groupIndex] != NULLOBJECT)
598// {
599// if(random(10) > 8)
600// {
601// vtolGrAttackObj[_groupIndex] = NULLOBJECT;
602// }
603// }
604//
605// //now try to find an attack target if we have no defence target
606// //find best attack target
607// _newTarget = chooseVtolTarget(TRUE); //search for an exclusive target
608// if(_newTarget == NULLOBJECT)
609// {
610// _newTarget = chooseVtolTarget(FALSE); //search for any target
611// }
612//
613// _newTargetWeight = getVtolTargetWeight(_newTarget);
614// _oldTargetWeight = getVtolTargetWeight(vtolGrAttackObj[_groupIndex]);
615//
616// // new one or a much better one
617// if((_newTargetWeight >= (_oldTargetWeight + 10)) or
618// (vtolGrAttackObj[_groupIndex] == NULLOBJECT ))
619// {
620// dbg("choosing new attack object for " & _groupIndex, me);
621// vtolGrAttackObj[_groupIndex] = _newTarget;
622// }
623//
624//
625// if(vtolGrAttackObj[_groupIndex] != NULLOBJECT)
626// {
627// if(!friendlyPlayer(vtolGrAttackObj[_groupIndex].player))
628// {
629// if(vtolAttackGr[_groupIndex].members > 0)
630// {
631// initIterateGroup(vtolAttackGr[_groupIndex]);
632// _droid = iterateGroup(vtolAttackGr[_groupIndex]);
633// while(_droid != NULLOBJECT)
634// {
635// if(attackObj != NULLOBJECT) // consolidate any ongoing attack.
636// {
637// if(!friendlyPlayer(attackObj.player))
638// {
639// setDroidSecondary(droid, DSO_PATROL, DSS_PATROL_SET);
640// orderDroidObj(droid, DORDER_ATTACK,attackObj);
641// }
642// }
643// else
644// {
645// orderDroid(droid, DORDER_RTB);
646// }
647//
648// _droid = iterateGroup(vtolAttackGr[_groupIndex]);
649// }
650// }
651// }
652// }
653// }
654// _groupIndex++;
655// }
656 }
528}657}
529658
530event buildFundamentals(inactive)659event buildFundamentals(inactive)
531{660{
532 count = 0;661 count = 0;
533 while (count < numFundamental)662 while (count < numFundamental)
534 {663 {
535 // check that struct.664 // check that struct.
536 structure = getStructure(structs[count], me);665 structure = getStructure(structs[count], me);
537 if (structure == NULLOBJECT) // if missing build it.666 if (structure == NULLOBJECT) // if missing build it.
538 {667 {
539 if (isStructureAvailable(structs[count], me))668 if (isStructureAvailable(structs[count], me))
540 {669 {
541 if (grabTrucksAndBuild(12, structs[count], 0))670 if (grabTrucksAndBuild(12, structs[count], 0))
542 {671 {
543 exit; // no need to check more672 exit; // no need to check more
544 }673 }
545 }674 }
546 }675 }
547 count = count + 1;676 count = count + 1;
548 }677 }
549 fundamentalBeingBuilt = derrick;678 fundamentalBeingBuilt = derrick;
550 setEventTrigger(buildFundamentals, inactive);679 setEventTrigger(buildFundamentals, inactive);
551}680}
552681
553event startLevel(startLevelTr)682event startLevel(startLevelTr)
554{683{
555 setEventTrigger(buildFundamentals, slowloadTr);684 setEventTrigger(buildFundamentals, slowloadTr);
556 setEventTrigger(conDroids, chainloadTr);685 setEventTrigger(conDroids, chainloadTr);
557 setEventTrigger(doResearch, chainloadTr);686 setEventTrigger(doResearch, chainloadTr);
558 setEventTrigger(buildDerrick, slowloadTr);687 setEventTrigger(buildDerrick, delayedloadTr);
559 setEventTrigger(startLevel, inactive);688 setEventTrigger(startLevel, inactive);
560}689}
561690
562// decide what technology branch we will use691// decide what technology branch we will use
563function void setTechBranch(int _tech)692function void setTechBranch(int _tech)
564{693{
565 local float _y2,_y1,_x2,_x1,_a,_y,_m,_rnd,_mapSize;694 local float _y2,_y1,_x2,_x1,_a,_y,_m,_rnd,_mapSize;
695 local int __rnd,_ally,_count;
566 _mapSize = (float)((mapWidth + mapHeight) / 2);696 _mapSize = (float)((mapWidth + mapHeight) / 2);
567697
568 if(_tech != -1)698 if(_tech != -1)
569 {699 {
570 curTech = _tech;700 curTech = _tech;
701 }
702 //messagePlayer(ALL_ALLIES, M_REQUEST_HELP, MAX_PROBABILITY);
703 //messagePlayerAddressed(int _playerToMessage, int _playersToAddress, string _message);
704
705 _ally = 0;
706 _count = 0;
707 while(_ally < MAX_PLAYERS)
708 {
709 if(allianceExistsBetween(me, _ally)){
710 _count++;
711 }
712 _ally++;
713 }
714
715 if(_count > 0 and multiPlayerAlliancesType == ALLIANCES_TEAMS)
716 {
717 if(_mapSize < 150.0)
718 {
719 curTech = branchOneAlly;
720 messagePlayerAddressed(0, 1, "Branch One Reporting");
721 }
722 else
723 {
724 curTech = branchTwoAlly;
725 messagePlayerAddressed(1, 0, "Branch Two Reporting");
726 }
727 if(_count > 4)
728 {
729 maxIdleRes[curTech] = -1;
730 }
571 }731 }
572 else732 else
573 {733 {
574 //probability to choose vtol branch for map size 90 = 0; probability for map size 200 = 45734 //probability to choose vtol branch for map size 90 = 0; probability for map size 200 = 55
575 //build a linear function: y = ((y2 - y1) / (x2 - x1)) * x + a depending on two values given (short: y = mx+a)735 //build a linear function: y = ((y2 - y1) / (x2 - x1)) * x + a depending on two values given (short: y = mx+a)
576 _x1 = 90.0; _y1 = 0.0;736 _x1 = 90.0; _y1 = 0.0;
577 _x2 = 200.0; _y2 = 45.0;737 _x2 = 200.0; _y2 = 55.0;
578 _m = ((_y2 - _y1) / (_x2 - _x1));738 _m = ((_y2 - _y1) / (_x2 - _x1));
579 _a = -(_m * _x1);739 _a = -(_m * _x1);
580740
581 //calculate probability for the current map741 //calculate probability for the current map
582 _y = _m * _mapSize + _a;742 _y = _m * _mapSize + _a;
583743
584 dbg("_m = " & _m & ", a = " & _a, me);744 dbg("_m = " & _m & ", a = " & _a, me);
585745
586 _rnd = (float)random(100);746 _rnd = (float)random(100);
587 if(_rnd < _y)747 if(_rnd < _y)
588 {748 {
589 curTech = branchVTOL;749 __rnd = random(10);
590 dbg("going air (" & _y & "/" & _rnd & ")", me);750 if(__rnd < 5)
751 {
752 curTech = branchVTOL;
753 dbg("going air (" & _y & "/" & _rnd & ")", me);
754 }
755 else
756 {
757 curTech = branchArtillery;
758 dbg("going air (" & _y & "/" & _rnd & ")", me);
759 }
760
591 }761 }
592 else762 else
593 {763 {
594 curTech = branchDefault;764 __rnd = random(10);
595 dbg("going land (" & _y & "/" & _rnd & ")", me);765 if(__rnd < 5)
766 {
767 curTech = branchRocket;
768 dbg("going rockets (" & _y & "/" & _rnd & ")", me);
769 }
770 else
771 {
772 curTech = branchCannon;
773 dbg("going cannons (" & _y & "/" & _rnd & ")", me);
774 }
596 }775 }
597 }776 }
598}777}
599778
600/* returns TRUE if AI is responsible for the _player */779/* returns TRUE if AI is responsible for the _player */
601function bool aiResponsibleForPlayer(int _player)780function bool aiResponsibleForPlayer(int _player)
602{781{
603 if(not _DEBUG and ((_player == selectedPlayer) or not myResponsibility(_player)))782 if(not _DEBUG and ((_player == selectedPlayer) or not myResponsibility(_player)))
604 {783 {
605 return FALSE;784 return FALSE;
606 }785 }
607786
608 return TRUE;787 return TRUE;
609}788}
610789
611/////////////////////////////////////////////////////////////////////790/////////////////////////////////////////////////////////////////////
612// keep details about the size and postion of the ai players base791// keep details about the size and postion of the ai players base
613event basedetails(basedetailsTr)792event basedetails(basedetailsTr)
614{793{
615 // clear old extremities.794 // clear old extremities.
616 maxy = 0;795 maxy = 0;
617 maxx = 0;796 maxx = 0;
618 miny = (mapHeight*128);797 miny = (mapHeight*128);
619 minx = (mapWidth*128);798 minx = (mapWidth*128);
620799
621 baseRange = 4 * TILE;800 baseRange = 4 * TILE;
622801
623 // now find the extremities of our vital structures.802 // now find the extremities of our vital structures.
624 count = 0;803 count = 0;
625 while(count < numBaseStruct)804 while(count < numBaseStruct)
626 {805 {
627 initEnumStruct(FALSE,baseStruct[count],me,me);806 initEnumStruct(FALSE,baseStruct[count],me,me);
628 structure= enumStruct();807 structure= enumStruct();
629 while(structure != NULLOBJECT)808 while(structure != NULLOBJECT)
630 {809 {
631 if(structure.x < minx)810 if(structure.x < minx)
632 {811 {
633 minx = structure.x;812 minx = structure.x;
634 }813 }
635 if(structure.x > maxx)814 if(structure.x > maxx)
636 {815 {
637 maxx = structure.x;816 maxx = structure.x;
638 }817 }
639 if(structure.y < miny)818 if(structure.y < miny)
640 {819 {
641 miny = structure.y;820 miny = structure.y;
642 }821 }
643 if(structure.y > maxy)822 if(structure.y > maxy)
644 {823 {
645 maxy = structure.y;824 maxy = structure.y;
646 }825 }
647826
648 result = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y);827 result = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y);
649828
650 if(result > baseRange){829 if(result > baseRange){
651 baseRange = result;830 baseRange = result;
652 }831 }
653832
654 structure= enumStruct();833 structure= enumStruct();
655 }834 }
656835
657 count = count + 1;836 count = count + 1;
658 }837 }
659838
660 result = 3 * 128;839 result = 3 * 128;
661 minx = minx - result;840 minx = minx - result;
662 maxx = maxx + result;841 maxx = maxx + result;
663 miny = miny - result;842 miny = miny - result;
664 maxy = maxy + result;843 maxy = maxy + result;
665844
666 baseRange = baseRange + (4 * 128);845 baseRange = baseRange + (4 * 128);
667}846}
668847
669/////////////////////////////////////////////////////////////////////848/////////////////////////////////////////////////////////////////////
670// structure building rules849// structure building rules
671850
672// build derricks on oil.851// build derricks on oil.
673event buildDerrick(buildDerrickTr)852event buildDerrick(buildDerrickTr)
674{853{
675 local bool foundOne, _same;854 local bool foundOne, _same;
676 local FEATURE _oil, _closestOil;855 local FEATURE _oil, _closestOil;
677 local int _bestDist, _newDist;856 local int _bestDist, _newDist, _count;
678 local DROID _search;857 local DROID _search;
858 local STRUCTURE _structure;
679859
680 // what if we can't waste power on building derricks because we don't have a gen yet?860 // what if we can't waste power on building derricks because we don't have a gen yet?
681 if (playerPower(me) < 300 and haveStructure(derrick) and not haveStructure(powGen))861 if (playerPower(me) < 500 and haveStructure(derrick) and not haveStructure(powGen))
682 {862 {
683 setEventTrigger(buildDerrick, slowloadTr);863 setEventTrigger(buildDerrick, slowloadTr);
684 exit;864 exit;
685 }865 }
686866
687 _bestDist = 99999;867 _bestDist = 99999;
688 _closestOil = NULLOBJECT;868 _closestOil = NULLOBJECT;
689 foundOne = false;869 foundOne = false;
690 initIterateGroup(buildGroup); // find all units in build group870 initIterateGroup(buildGroup); // find all units in build group
691 droid = iterateGroup(buildGroup);871 droid = iterateGroup(buildGroup);
692 while (droid != NULLOBJECT && !foundOne)872 while (droid != NULLOBJECT && !foundOne)
693 {873 {
694 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD and droid.order != DORDER_HELPBUILD)874 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD and droid.order != DORDER_HELPBUILD)
695 {875 {
696 foundOne = true;876 foundOne = true;
697 }877 }
698 else878 else
699 {879 {
700 droid = iterateGroup(buildGroup);880 droid = iterateGroup(buildGroup);
701 }881 }
702 }882 }
703 if (droid != NULLOBJECT)883 if (droid != NULLOBJECT)
704 {884 {
705 initGetFeature(oilRes, -1, me);885 initGetFeature(oilRes, -1, me);
706 _oil = getFeatureB(me);886 _oil = getFeatureB(me);
707 while (_oil != NULLOBJECT)887 while (_oil != NULLOBJECT)
708 {888 {
709 _newDist = distBetweenTwoPoints(droid.x, droid.y, _oil.x, _oil.y);889 _newDist = distBetweenTwoPoints(droid.x, droid.y, _oil.x, _oil.y);
710 _same = false;890 _same = false;
711891
712 if (_newDist < _bestDist and droidCanReach(droid, _oil.x, _oil.y)) // this one is closer892 if (_newDist < _bestDist and droidCanReach(droid, _oil.x, _oil.y)) // this one is closer
713 {893 {
714 if (!threatInRange(me, _oil.x, _oil.y, OIL_THREAT_RANGE, FALSE))894 if (!threatInRange(me, _oil.x, _oil.y, OIL_THREAT_RANGE, FALSE))
715 {895 {
716 initIterateGroup(buildGroup); // find all units in build group.896 initIterateGroup(buildGroup); // find all units in build group.
717 _search = iterateGroup(buildGroup);897 _search = iterateGroup(buildGroup);
718 foundOne = false;898 foundOne = false;
719 while (_search != NULLOBJECT && !foundOne)899 while (_search != NULLOBJECT && !foundOne)
720 {900 {
721 if (_search.orderx == _oil.x and _search.ordery == _oil.y and _search != droid)901 if (_search.orderx == _oil.x and _search.ordery == _oil.y and _search != droid)
722 {902 {
723 _same = true;903 _same = true;
724 foundOne = true;904 foundOne = true;
725 }905 }
726 _search = iterateGroup(buildGroup);906 _search = iterateGroup(buildGroup);
727 }907 }
728 if (!_same) // do not go to same spot as another droid908 if (!_same) // do not go to same spot as another droid
729 {909 {
730 _bestDist = _newDist;910 _bestDist = _newDist;
731 _closestOil = _oil;911 _closestOil = _oil;
732 }912 }
733 }913 }
734 }914 }
735 _oil = getFeatureB(me);915 _oil = getFeatureB(me);
736 }916 }
737 if (_closestOil != NULLOBJECT)917
918 initEnumStruct(FALSE,derrick,me,me);
919 structure= enumStruct();
920 count = 0;
921 while(structure != NULLOBJECT)
738 {922 {
739 orderDroidStatsLoc(droid, DORDER_BUILD, derrick, _closestOil.x, _closestOil.y); // build a derick923 count = count + 1; // count = numderricks
924 structure= enumStruct();
925 }
926
927 initEnumStruct(FALSE,gderrick,me,me);
928 structure= enumStruct();
929 _count = 0;
930 while(_structure != NULLOBJECT)
931 {
932 _count = _count + 1; // _count = numGuardedDerricks
933 structure= enumStruct();
934 }
935
936 count = _count + count; // total derricks
937 // prevent trucks from wandering off far distances in early phase of base build. Usually not desirable but sometimes is. experimental
938 if (((gameTime < 3000) and _bestDist > (10 * TILE)) and count > 14)
939 {
940 setEventTrigger(buildDerrick, buildDerrickTr);
941 exit;
942 }
943
944 if (((gameTime < 6000) and _bestDist > (15 * TILE)) and count > 18)
945 {
946 setEventTrigger(buildDerrick, buildDerrickTr);
947 exit;
948 }
949
950 if (_closestOil != NULLOBJECT and count < 40)
951 {
952 if( isStructureAvailable(gderrick,me))
953 {
954 orderDroidStatsLoc(droid, DORDER_BUILD, gderrick, _closestOil.x, _closestOil.y); // build a derick
955 }
956 else
957 {
958 orderDroidStatsLoc(droid, DORDER_BUILD, derrick, _closestOil.x, _closestOil.y); // build a derick
959 }
960
740 if (idleGroup(buildGroup) > 0)961 if (idleGroup(buildGroup) > 0)
741 {962 {
742 setEventTrigger(buildDerrick, slowloadTr); // do it again for next droid963 setEventTrigger(buildDerrick, slowloadTr); // do it again for next droid
743 exit;964 exit;
744 }965 }
745 }966 }
746 }967 }
747 setEventTrigger(buildDerrick, buildDerrickTr);968 setEventTrigger(buildDerrick, buildDerrickTr);
748}969}
749970
750/////////////////////////////////////////////////////////////////////971/////////////////////////////////////////////////////////////////////
751// if idle and derrick in range and no defense then build defense, else ret to base .972// if idle and derrick in range and no defense then build defense, else ret to base .
752event buildOilDefenseOrRetreat(buildOilDefenseOrRetreatTr)973event buildOilDefenseOrRetreat(buildOilDefenseOrRetreatTr)
753{974{
754 local int _numBuilders,_maxBuilders;975 local int _numBuilders,_maxBuilders;
976 local STRUCTURE _structure;
755977
756 _maxBuilders = 1;978 _maxBuilders = 1;
757979
758 // check idle.980 // check idle.
759 initIterateGroup(buildGroup); // find idle droids in build group.981 initIterateGroup(buildGroup); // find idle droids in build group.
760 droid = iterateGroup(buildGroup);982 droid = iterateGroup(buildGroup);
761 while(droid != NULLOBJECT)983 while(droid != NULLOBJECT)
762 {984 {
763 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD and droid.order != DORDER_HELPBUILD)985 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD and droid.order != DORDER_HELPBUILD)
764 {986 {
765 // if in range of a derrick987 // if in range of a derrick
766 structure = structureBuiltInRange(derrick, droid.x, droid.y, (5*128), me);988 structure = structureBuiltInRange(derrick, droid.x, droid.y, (5*128), me);
989 _structure = structureBuiltInRange(gderrick, droid.x, droid.y, (5*128), me);
990
767 // if inside base limits then presume ok..991 // if inside base limits then presume ok..
768 if( structure != NULLOBJECT)992 if( structure != NULLOBJECT)
769 {993 {
770 if((structure.x > minx) and (structure.y > miny) and (structure.x < maxx) and (structure.y <maxy))994 if((structure.x > minx) and (structure.y > miny) and (structure.x < maxx) and (structure.y <maxy))
771 {995 {
772 structure = NULLOBJECT;996 structure = NULLOBJECT;
773 }997 }
774 }998 }
999
1000 // if inside base limits then presume ok..
1001 if( _structure != NULLOBJECT)
1002 {
1003 if((_structure.x > minx) and (_structure.y > miny) and (_structure.x < maxx) and (_structure.y <maxy))
1004 {
1005 _structure = NULLOBJECT;
1006 }
1007 }
7751008
1009 if(_structure != NULLOBJECT)
1010 {
1011 buildX = _structure.x;
1012 buildY = _structure.y;
1013
1014 // not many defenses nearby
1015 if(numFriendlyWeapStructsInRange(me, buildX, buildY, (3*128), FALSE) < 2)
1016 {
1017 count = numDefStructs - 1; //pick a struct to build..
1018 count2 = 0;
1019 while( (count2 < 5) and (count >= 0) )
1020 {
1021 if( isStructureAvailable(defStructs[count],me))
1022 {
1023 structChoice[count2] = defStructs[count];
1024 count2 = count2 + 1;
1025 }
1026 count = count - 1;
1027 }
1028 count =0;
1029 if(count2 > 0)
1030 {
1031 count = random(count2); //count = choice!
1032
1033 // pick a location
1034 boolResult = pickDroidStructLocation(droid, structChoice[count], ref buildX, ref buildY, me, -1);
1035
1036 _numBuilders = numBuildSameBuilding(NULLSTRUCTURESTAT, buildX, buildY);
1037
1038 if((boolResult == TRUE) and (_numBuilders < _maxBuilders) and droidCanReach(droid, buildX, buildY))
1039 {
1040 // build it.
1041 orderDroidStatsLoc(droid, DORDER_BUILD,structChoice[count], buildX,buildY);
1042 _numBuilders++;
1043 }
1044 }
1045 }
1046 else
1047 {
1048 _structure = structureBuiltInRange(playerHQ, droid.x, droid.y, (5*128), me);
1049 if(_structure == NULLOBJECT)
1050 {
1051 if(!insideBase(droid.x, droid.y))
1052 {
1053 orderDroid(droid,DORDER_RTB); // return to base;
1054 }
1055 }
1056 }
1057 }
1058 else
1059 {
1060 _structure = structureBuiltInRange(playerHQ, droid.x, droid.y, (5*128), me);
1061 if(_structure == NULLOBJECT)
1062 {
1063 if(!insideBase(droid.x, droid.y))
1064 {
1065 orderDroid(droid,DORDER_RTB); // return to base;
1066 }
1067 }
1068 }
1069
776 if(structure != NULLOBJECT)1070 if(structure != NULLOBJECT)
777 {1071 {
778 buildX = structure.x;1072 buildX = structure.x;
779 buildY = structure.y;1073 buildY = structure.y;
7801074
781 // not many defenses nearby1075 // not many defenses nearby
782 if(numFriendlyWeapStructsInRange(me, buildX, buildY, (3*128), FALSE) < 2)1076 if(numFriendlyWeapStructsInRange(me, buildX, buildY, (3*128), FALSE) < 2)
783 {1077 {
784 count = numDefStructs - 1; //pick a struct to build..1078 count = numDefStructs - 1; //pick a struct to build..
785 count2 = 0;1079 count2 = 0;
786 while( (count2 < 5) and (count >= 0) )1080 while( (count2 < 5) and (count >= 0) )
787 {1081 {
788 if( isStructureAvailable(defStructs[count],me))1082 if( isStructureAvailable(defStructs[count],me))
789 {1083 {
790 structChoice[count2] = defStructs[count];1084 structChoice[count2] = defStructs[count];
791 count2 = count2 + 1;1085 count2 = count2 + 1;
792 }1086 }
793 count = count - 1;1087 count = count - 1;
794 }1088 }
795 count =0;1089 count =0;
796 if(count2 > 0)1090 if(count2 > 0)
797 {1091 {
798 count = random(count2); //count = choice!1092 count = random(count2); //count = choice!
7991093
800 // pick a location1094 // pick a location
801 boolResult = pickDroidStructLocation(droid, structChoice[count], ref buildX, ref buildY, me, -1);1095 boolResult = pickDroidStructLocation(droid, structChoice[count], ref buildX, ref buildY, me, -1);
8021096
803 _numBuilders = numBuildSameBuilding(NULLSTRUCTURESTAT, buildX, buildY);1097 _numBuilders = numBuildSameBuilding(NULLSTRUCTURESTAT, buildX, buildY);
8041098
805 if((boolResult == TRUE) and (_numBuilders < _maxBuilders) and droidCanReach(droid, buildX, buildY))1099 if((boolResult == TRUE) and (_numBuilders < _maxBuilders) and droidCanReach(droid, buildX, buildY))
806 {1100 {
807 // build it.1101 // build it.
808 orderDroidStatsLoc(droid, DORDER_BUILD,structChoice[count], buildX,buildY);1102 orderDroidStatsLoc(droid, DORDER_BUILD,structChoice[count], buildX,buildY);
809 _numBuilders++;1103 _numBuilders++;
810 }1104 }
811 }1105 }
812 }1106 }
813 else1107 else
814 {1108 {
815 structure = structureBuiltInRange(playerHQ, droid.x, droid.y, (5*128), me);1109 structure = structureBuiltInRange(playerHQ, droid.x, droid.y, (5*128), me);
816 if(structure == NULLOBJECT)1110 if(structure == NULLOBJECT)
817 {1111 {
818 if(!insideBase(droid.x, droid.y))1112 if(!insideBase(droid.x, droid.y))
819 {1113 {
820 orderDroid(droid,DORDER_RTB); // return to base;1114 orderDroid(droid,DORDER_RTB); // return to base;
821 }1115 }
822 }1116 }
823 }1117 }
824 }1118 }
825 else1119 else
826 {1120 {
827 structure = structureBuiltInRange(playerHQ, droid.x, droid.y, (5*128), me);1121 structure = structureBuiltInRange(playerHQ, droid.x, droid.y, (5*128), me);
828 if(structure == NULLOBJECT)1122 if(structure == NULLOBJECT)
829 {1123 {
830 if(!insideBase(droid.x, droid.y))1124 if(!insideBase(droid.x, droid.y))
831 {1125 {
832 orderDroid(droid,DORDER_RTB); // return to base;1126 orderDroid(droid,DORDER_RTB); // return to base;
833 }1127 }
834 }1128 }
835 }1129 }
836 }1130 }
837 droid = iterateGroup(buildGroup);1131 droid = iterateGroup(buildGroup);
838 }1132 }
839}1133}
8401134
841/////////////////////////////////////////////////////////////////////1135/////////////////////////////////////////////////////////////////////
842//mortar etc.. rules. build sensor towers and emplacements.1136//mortar etc.. rules. build sensor towers and emplacements.
843event incendry(incendryTr)1137event incendry(incendryTr)
844{1138{
1139
845 if (not isStructureAvailable(sensorTower, me))1140 if (not isStructureAvailable(sensorTower, me))
846 {1141 {
847 exit;1142 exit;
848 }1143 }
1144
1145 if(curTech != branchArtillery and curTech != branchOneAlly and curTech != branchTwoAlly)
1146 {
1147 exit;
1148 }
8491149
850 initEnumStruct(FALSE,sensorTower,me,me);1150 initEnumStruct(FALSE,sensorTower,me,me);
8511151
852 count = 0;1152 count = 0;
853 structure = enumStruct();1153 structure = enumStruct();
854 while(structure != NULLOBJECT)1154 while(structure != NULLOBJECT)
855 {1155 {
856 count = count + 1;1156 count = count + 1;
857 structure = enumStruct();1157 structure = enumStruct();
858 }1158 }
8591159
860 if (count < (gameTime/4200)) // every 7 mins1160 if (count < (gameTime/1800)) // every 5 mins
861 {1161 {
862 // if not found build a sensor tower.1162 // if not found build a sensor tower.
863 // find a place to build.1163 // find a place to build.
864 buildX = 0;1164 buildX = 0;
865 buildY = 0;1165 buildY = 0;
866 initEnumStruct(FALSE,derrick,me,me);1166 initEnumStruct(FALSE,derrick,me,me);
867 structure= enumStruct();1167 structure= enumStruct();
868 while(structure != NULLOBJECT)1168 while(structure != NULLOBJECT)
869 {1169 {
870 count = 0;1170 count = 0;
871 result = 0;1171 result = 0;
872 while(count < numDefStructs)1172 while(count < numDefStructs)
873 {1173 {
874 structure2 = structureBuiltInRange(defStructs[count], structure.x, structure.y,(4*128), me);1174 structure2 = structureBuiltInRange(defStructs[count], structure.x, structure.y,(4*128), me);
875 if(structure2 != NULLOBJECT)1175 if(structure2 != NULLOBJECT)
876 {1176 {
877 result = result + 1;1177 result = result + 1;
878 }1178 }
879 count = count + 1;1179 count = count + 1;
880 }1180 }
8811181
882 // check for sensor nearby,1182 // check for sensor nearby,
883 structure2 = structureBuiltInRange(sensorTower, structure.x, structure.y,(5*128), me);1183 structure2 = structureBuiltInRange(sensorTower, structure.x, structure.y,(5*128), me);
884 if(structure2 != NULLOBJECT)1184 if(structure2 != NULLOBJECT)
885 {1185 {
886 result = 4;1186 result = 4;
887 }1187 }
8881188
889 if(result < 3)1189 if(result < 3)
890 {1190 {
891 buildX = structure.x;1191 buildX = structure.x;
892 buildY = structure.y;1192 buildY = structure.y;
893 structure = NULLOBJECT;1193 structure = NULLOBJECT;
894 }1194 }
895 else1195 else
896 {1196 {
897 structure = enumStruct();1197 structure = enumStruct();
898 }1198 }
899 }1199 }
9001200
901 if(buildX != 0)1201 if(buildX != 0)
902 {1202 {
903 boolResult = pickStructLocation(sensorTower, ref buildX, ref buildY,me); // pick spot.1203 boolResult = pickStructLocation(sensorTower, ref buildX, ref buildY,me); // pick spot.
904 if(boolResult == TRUE)1204 if(boolResult == TRUE)
905 {1205 {
906 // find unit1206 // find unit
907 initIterateGroup(buildGroup);1207 initIterateGroup(buildGroup);
908 droid = iterateGroup(buildGroup);1208 droid = iterateGroup(buildGroup);
909 while(droid != NULLOBJECT)1209 while(droid != NULLOBJECT)
910 {1210 {
911 if ((droid.order == DORDER_NONE or droid.order == DORDER_RTB) and droidCanReach(droid, buildX, buildY))1211 if ((droid.order == DORDER_NONE or droid.order == DORDER_RTB) and droidCanReach(droid, buildX, buildY))
912 {1212 {
913 orderDroidStatsLoc(droid, DORDER_BUILD, sensorTower, buildX, buildY);1213 orderDroidStatsLoc(droid, DORDER_BUILD, sensorTower, buildX, buildY);
914 droid = NULLOBJECT;1214 droid = NULLOBJECT;
915 }1215 }
916 else1216 else
917 {1217 {
918 droid = iterateGroup(buildGroup);1218 droid = iterateGroup(buildGroup);
919 }1219 }
920 }1220 }
921 }1221 }
922 }1222 }
923 }1223 }
924 else1224 else
925 {1225 {
926 // find a sensor tower with least incencdry structs around it..1226 // find a sensor tower with least incendry structs around it..
927 buildX = 0;1227 buildX = 0;
928 buildY = 0;1228 buildY = 0;
9291229
930 initEnumStruct(FALSE,sensorTower,me,me);1230 initEnumStruct(FALSE,sensorTower,me,me);
931 structure= enumStruct();1231 structure= enumStruct();
932 count = 999;1232 count = 999;
933 while(structure != NULLOBJECT)1233 while(structure != NULLOBJECT)
934 {1234 {
935 // count incendrys near this tower.1235 // count incendrys near this tower.
936 result = 0;1236 result = 0;
937 count2 = 0;1237 count2 = 0;
938 while(count2 < numIncendrys)1238 while(count2 < numIncendrys)
939 {1239 {
940 structure2 = structureBuiltInRange(incendrys[count2], structure.x, structure.y,(4*128), me);1240 structure2 = structureBuiltInRange(incendrys[count2], structure.x, structure.y,(4*128), me);
941 if(structure2 != NULLOBJECT)1241 if(structure2 != NULLOBJECT)
942 {1242 {
943 result = result + 1;1243 result = result + 1;
944 }1244 }
945 count2 = count2 + 1;1245 count2 = count2 + 1;
946 }1246 }
9471247
948 if((result < 6) and (result < count)) // lowest found yet. only sites with <6 too.1248 if((result < 12) and (result < count)) // lowest found yet. only sites with <6 too.
949 {1249 {
950 buildX = structure.x;1250 buildX = structure.x;
951 buildY = structure.y;1251 buildY = structure.y;
952 count = result;1252 count = result;
953 }1253 }
954 structure = enumStruct();1254 structure = enumStruct();
955 }1255 }
9561256
957 if(buildX != 0)1257 if(buildX != 0)
958 {1258 {
9591259
960 // choose a device1260 // choose a device
961 count = numIncendrys - 1;1261 count = numIncendrys - 1;
962 result = 99;1262 result = 99;
963 while(count >= 0 )1263 while(count >= 0 )
964 {1264 {
965 if(isStructureAvailable(incendrys[count],me))1265 if(isStructureAvailable(incendrys[count],me))
966 {1266 {
967 result = count;1267 result = count;
968 count = -1;1268 count = -1;
969 }1269 }
970 else1270 else
971 {1271 {
972 count = count - 1;1272 count = count - 1;
973 }1273 }
974 }1274 }
9751275
9761276
977 // find a unit and build an incendry device.1277 // find a unit and build an incendry device.
978 if(result != 99)1278 if(result != 99)
979 {1279 {
980 boolResult = pickStructLocation(incendrys[result], ref buildX, ref buildY,me); // pick spot.1280 boolResult = pickStructLocation(incendrys[result], ref buildX, ref buildY,me); // pick spot.
981 if(boolResult == TRUE)1281 if(boolResult == TRUE)
982 {1282 {
983 initIterateGroup(buildGroup);1283 initIterateGroup(buildGroup);
984 droid = iterateGroup(buildGroup);1284 droid = iterateGroup(buildGroup);
9851285
986 boolResult = (numBuildSameBuilding(incendrys[result], buildX, buildY) > 0); //anyone building there already?1286 boolResult = (numBuildSameBuilding(incendrys[result], buildX, buildY) > 0); //anyone building there already?
9871287
988 while(droid != NULLOBJECT and (not boolResult))1288 while(droid != NULLOBJECT and (not boolResult))
989 {1289 {
990 if ((droid.order == DORDER_NONE or droid.order == DORDER_RTB) and droidCanReach(droid, buildX, buildY))1290 if ((droid.order == DORDER_NONE or droid.order == DORDER_RTB) and droidCanReach(droid, buildX, buildY))
991 {1291 {
992 orderDroidStatsLoc(droid, DORDER_BUILD,incendrys[result], buildX,buildY);1292 orderDroidStatsLoc(droid, DORDER_BUILD,incendrys[result], buildX,buildY);
993 boolResult = TRUE; //only 1 truck1293 boolResult = TRUE; //only 1 truck
994 }1294 }
995 droid = iterateGroup(buildGroup);1295 droid = iterateGroup(buildGroup);
996 }1296 }
997 }1297 }
998 }1298 }
999 }1299 }
1000 }1300 }
1001}1301}
10021302
1003/////////////////////////////////////////////////////////////////////1303/////////////////////////////////////////////////////////////////////
1004// build a power gen for every 4 derricks. VITAL!1304// build a power gen for every 4 derricks. VITAL!
1005event buildPowerGenerators(buildPowerGeneratorsTr)1305event buildPowerGenerators(buildPowerGeneratorsTr)
1006{1306{
1307 local INT _count;
1007 if (!isStructureAvailable(powGen, me))1308 if (!isStructureAvailable(powGen, me))
1008 {1309 {
1009 exit;1310 exit;
1010 }1311 }
1011 initEnumStruct(FALSE,derrick,me,me); // count = numderricks1312 initEnumStruct(FALSE,derrick,me,me); // count = numderricks
1012 structure= enumStruct();1313 structure= enumStruct();
1013 count = 0;1314 count = 0;
1014 while(structure != NULLOBJECT)1315 while(structure != NULLOBJECT)
1015 {1316 {
1016 count = count + 1;1317 count = count + 1;
1017 structure= enumStruct();1318 structure= enumStruct();
1018 }1319 }
1320
1321 initEnumStruct(FALSE,gderrick,me,me); // count = numderricks
1322 structure= enumStruct();
1323 _count = 0;
1324 while(structure != NULLOBJECT)
1325 {
1326 _count = _count + 1;
1327 structure= enumStruct();
1328 }
1329
1330 count = _count + count;
10191331
1020 initEnumStruct(FALSE,powGen,me,me); // count2 = numpowgens1332 initEnumStruct(FALSE,powGen,me,me); // count2 = numpowgens
1021 structure= enumStruct();1333 structure= enumStruct();
1022 count2 = 0;1334 count2 = 0;
1023 while(structure != NULLOBJECT)1335 while(structure != NULLOBJECT)
1024 {1336 {
1025 count2 = count2 + 1;1337 count2 = count2 + 1;
1026 structure= enumStruct();1338 structure= enumStruct();
1027 }1339 }
10281340
1029 if( (count2 * 4) < count ) // if we need powergen1341 if( (count2 * 4) < count ) // if we need powergen
1030 {1342 {
1031 initIterateGroup(buildGroup);1343 initIterateGroup(buildGroup);
1032 droid = iterateGroup(buildGroup);1344 droid = iterateGroup(buildGroup);
1033 while(droid != NULLOBJECT)1345 while(droid != NULLOBJECT)
1034 {1346 {
1035 if (droid.order != DORDER_HELPBUILD and droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD)1347 if (droid.order != DORDER_HELPBUILD and droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD)
1036 {1348 {
1037 buildX = baseX; // try build powergen.1349 buildX = baseX; // try build powergen.
1038 buildY = baseY;1350 buildY = baseY;
1039 if (pickDroidStructLocation(droid, powGen, ref buildX, ref buildY, me, 1))1351 if (pickDroidStructLocation(droid, powGen, ref buildX, ref buildY, me, 1))
1040 {1352 {
1041 orderDroidStatsLoc(droid, DORDER_BUILD, powGen, buildX,buildY);1353 orderDroidStatsLoc(droid, DORDER_BUILD, powGen, buildX,buildY);
1042 }1354 }
1043 }1355 }
1044 droid = iterateGroup(buildGroup);1356 droid = iterateGroup(buildGroup);
1045 }1357 }
1046 }1358 }
1047}1359}
10481360
1361/////////////////////////////////////////////////////////////////////
1362// build a research center for every 4 derricks if we have at least 100 power
1363event buildResearchCenters(buildResearchCentersTr)
1364{
1365 local INT _count;
1366 if (!isStructureAvailable(resLab, me) or (playerPower(me) < 100))
1367 {
1368 exit;
1369 }
1370 initEnumStruct(FALSE,derrick,me,me); // count = numderricks
1371 structure= enumStruct();
1372 count = 0;
1373 while(structure != NULLOBJECT)
1374 {
1375 count = count + 1;
1376 structure= enumStruct();
1377 }
1378
1379 initEnumStruct(FALSE,gderrick,me,me); // count = numderricks
1380 structure= enumStruct();
1381 _count = 0;
1382 while(structure != NULLOBJECT)
1383 {
1384 _count = _count + 1;
1385 structure= enumStruct();
1386 }
1387
1388 count = _count + count;
1389
1390 initEnumStruct(FALSE,resLab,me,me);
1391 structure= enumStruct();
1392 count2 = 0;
1393 while(structure != NULLOBJECT)
1394 {
1395 count2 = count2 + 1;
1396 structure= enumStruct();
1397 }
1398
1399 if( (count2 * 4) < count )
1400 {
1401 initIterateGroup(buildGroup);
1402 droid = iterateGroup(buildGroup);
1403 while(droid != NULLOBJECT)
1404 {
1405 if (droid.order != DORDER_HELPBUILD and droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD)
1406 {
1407 buildX = baseX; // try build powergen.
1408 buildY = baseY;
1409 if (pickDroidStructLocation(droid, resLab, ref buildX, ref buildY, me, 1))
1410 {
1411 orderDroidStatsLoc(droid, DORDER_BUILD, resLab, buildX,buildY);
1412 }
1413 }
1414 droid = iterateGroup(buildGroup);
1415 }
1416 }
1417}
1418
1419
1420/////////////////////////////////////////////////////////////////////
1421// build a factory for every 5 derricks if we at least 500 power
1422event buildFactory(buildFactoryTr)
1423{
1424 local INT _count;
1425 if (!isStructureAvailable(factory, me) or (playerPower(me) < 300))
1426 {
1427 exit;
1428 }
1429 initEnumStruct(FALSE,derrick,me,me); // count = numderricks
1430 structure= enumStruct();
1431 count = 0;
1432 while(structure != NULLOBJECT)
1433 {
1434 count = count + 1;
1435 structure= enumStruct();
1436 }
1437
1438 initEnumStruct(FALSE,gderrick,me,me); // count = numderricks
1439 structure= enumStruct();
1440 _count = 0;
1441 while(structure != NULLOBJECT)
1442 {
1443 _count = _count + 1;
1444 structure= enumStruct();
1445 }
1446
1447 count = _count + count;
1448
1449 initEnumStruct(FALSE,factory,me,me); // count2 = numpowgens
1450 structure= enumStruct();
1451 count2 = 0;
1452 while(structure != NULLOBJECT)
1453 {
1454 count2 = count2 + 1;
1455 structure= enumStruct();
1456 }
1457
1458 if( (count2 * 5) < count ) // if we need powergen
1459 {
1460 initIterateGroup(buildGroup);
1461 droid = iterateGroup(buildGroup);
1462 while(droid != NULLOBJECT)
1463 {
1464 if (droid.order != DORDER_HELPBUILD and droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD)
1465 {
1466 buildX = baseX; // try build powergen.
1467 buildY = baseY;
1468 if (pickDroidStructLocation(droid, factory, ref buildX, ref buildY, me, 1))
1469 {
1470 orderDroidStatsLoc(droid, DORDER_BUILD, factory, buildX,buildY);
1471 }
1472 }
1473 droid = iterateGroup(buildGroup);
1474 }
1475 }
1476}
1477
1478/////////////////////////////////////////////////////////////////////
1479// build a cyborg factory for every 4 derricks
1480event buildCyborgFactory(buildCyborgFactoryTr)
1481{
1482 local INT _count;
1483 if (!isStructureAvailable(cybFactory, me))
1484 {
1485 exit;
1486 }
1487 initEnumStruct(FALSE,derrick,me,me); // count = numderricks
1488 structure= enumStruct();
1489 count = 0;
1490 while(structure != NULLOBJECT)
1491 {
1492 count = count + 1;
1493 structure= enumStruct();
1494 }
1495
1496 initEnumStruct(FALSE,gderrick,me,me); // count = numderricks
1497 structure= enumStruct();
1498 _count = 0;
1499 while(structure != NULLOBJECT)
1500 {
1501 _count = _count + 1;
1502 structure= enumStruct();
1503 }
1504
1505 count = _count + count;
1506
1507 initEnumStruct(FALSE,cybFactory,me,me); // count2 = numpowgens
1508 structure= enumStruct();
1509 count2 = 0;
1510 while(structure != NULLOBJECT)
1511 {
1512 count2 = count2 + 1;
1513 structure= enumStruct();
1514 }
1515
1516 if( (count2 * 5) < count ) // if we need powergen
1517 {
1518 initIterateGroup(buildGroup);
1519 droid = iterateGroup(buildGroup);
1520 while(droid != NULLOBJECT)
1521 {
1522 if (droid.order != DORDER_HELPBUILD and droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD)
1523 {
1524 buildX = baseX; // try build powergen.
1525 buildY = baseY;
1526 if (pickDroidStructLocation(droid, cybFactory, ref buildX, ref buildY, me, 1))
1527 {
1528 orderDroidStatsLoc(droid, DORDER_BUILD, cybFactory, buildX,buildY);
1529 }
1530 }
1531 droid = iterateGroup(buildGroup);
1532 }
1533 }
1534}
1535
1536/////////////////////////////////////////////////////////////////////
1537// build a VTOL factory for every 5 derricks if we have at least 1500 power
1538event buildVTOLFactory(buildVTOLFactoryTr)
1539{
1540 local INT _count;
1541 if (!isStructureAvailable(vtolFactory, me) or (playerPower(me) < 1200))
1542 {
1543 exit;
1544 }
1545 initEnumStruct(FALSE,derrick,me,me); // count = numderricks
1546 structure= enumStruct();
1547 count = 0;
1548 while(structure != NULLOBJECT)
1549 {
1550 count = count + 1;
1551 structure= enumStruct();
1552 }
1553
1554 initEnumStruct(FALSE,gderrick,me,me); // count = numderricks
1555 structure= enumStruct();
1556 _count = 0;
1557 while(structure != NULLOBJECT)
1558 {
1559 _count = _count + 1;
1560 structure= enumStruct();
1561 }
1562
1563 count = _count + count;
1564
1565 initEnumStruct(FALSE,vtolFactory,me,me); // count2 = numpowgens
1566 structure= enumStruct();
1567 count2 = 0;
1568 while(structure != NULLOBJECT)
1569 {
1570 count2 = count2 + 1;
1571 structure= enumStruct();
1572 }
1573
1574 if( (count2 * 5) < count ) // if we need powergen
1575 {
1576 initIterateGroup(buildGroup);
1577 droid = iterateGroup(buildGroup);
1578 while(droid != NULLOBJECT)
1579 {
1580 if (droid.order != DORDER_HELPBUILD and droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD)
1581 {
1582 buildX = baseX; // try build powergen.
1583 buildY = baseY;
1584 if (pickDroidStructLocation(droid, vtolFactory, ref buildX, ref buildY, me, 1))
1585 {
1586 orderDroidStatsLoc(droid, DORDER_BUILD, vtolFactory, buildX,buildY);
1587 }
1588 }
1589 droid = iterateGroup(buildGroup);
1590 }
1591 }
1592}
10491593
1050/////////////////////////////////////////////////////////////////////1594/////////////////////////////////////////////////////////////////////
1051// ensure we have everything in the vital structs list.1595// ensure we have everything in the vital structs list.
1052event buildBase(buildBaseTr)1596event buildBase(buildBaseTr)
1053{1597{
1054 if (idleGroup(buildGroup) >= (buildGroup.members / 2))1598 if (idleGroup(buildGroup) >= (buildGroup.members / 2))
1055 {1599 {
1056 count = 0;1600 count = 0;
1057 while(count < numStructs)1601 while(count < numStructs)
1058 {1602 {
1059 // check that struct.1603 // check that struct.
1060 structure = getStructure(structs[count],me);1604 structure = getStructure(structs[count],me);
1061 if(structure == NULLOBJECT) // if missing build it.1605 if(structure == NULLOBJECT) // if missing build it.
1062 {1606 {
1063 if(isStructureAvailable(structs[count],me))1607 if(isStructureAvailable(structs[count],me))
1064 {1608 {
1065 if (grabTrucksAndBuild(10, structs[count], 0))1609 if (grabTrucksAndBuild(12, structs[count], 0))
1066 {1610 {
1067 exit; // done here1611 exit; // done here
1068 }1612 }
1069 }1613 }
1070 }1614 }
1071 count = count + 1;1615 count = count + 1;
1072 }1616 }
1073 }1617 }
1074}1618}
10751619
1076/////////////////////////////////////////////////////////////////////1620/////////////////////////////////////////////////////////////////////
1077// build other stuff, grow the base slowly...1621// build other stuff, grow the base slowly...
1078event buildExpand( buildExpandTr )1622event buildExpand( buildExpandTr )
1079{1623{
1080 if (playerPower(me) < LOW_POWER)1624 if (playerPower(me) < LOW_POWER)
1081 {1625 {
1082 exit; // do not expand base with low power1626 exit; // do not expand base with low power
1083 }1627 }
10841628
1085 if(extraStruct == numExtraStructs[curTech]) // loop round1629 if(extraStruct == numExtraStructs[curTech]) // loop round
1086 {1630 {
1087 extraStruct = 0;1631 extraStruct = 0;
1088 }1632 }
10891633
1090 if(isStructureAvailable(extraStructs[curTech][extraStruct],me))1634 if(isStructureAvailable(extraStructs[curTech][extraStruct],me))
1091 {1635 {
1092 if (not grabTrucksAndBuild(10, extraStructs[curTech][extraStruct], 0))1636 if (not grabTrucksAndBuild(10, extraStructs[curTech][extraStruct], 0))
1093 {1637 {
1094 dbg("Failed to build expand", me);1638 dbg("Failed to build expand", me);
1095 }1639 }
1096 }1640 }
10971641
1098 extraStruct = extraStruct + 1;1642 extraStruct = extraStruct + 1;
1099}1643}
11001644
11011645
1102/////////////////////////////////////////////////////////////////////1646/////////////////////////////////////////////////////////////////////
1103// Structure (fac/res/pow) upgrades1647// Structure (fac/res/pow) upgrades
1104event upgradeStructures(upgradeStructuresTr )1648event upgradeStructures(upgradeStructuresTr )
1105{1649{
1106 if (not havePowerSource()) 1650 if (not havePowerSource())
1107 {1651 {
1652 setEventTrigger(upgradeStructures, upgradeStructuresTr);
1108 exit;1653 exit;
1109 }1654 }
1110 initIterateGroup(buildGroup); // find idle droids in build group.1655 initIterateGroup(buildGroup); // find idle droids in build group.
1111 droid = iterateGroup(buildGroup);1656 droid = iterateGroup(buildGroup);
1112 while(droid != NULLOBJECT)1657 while(droid != NULLOBJECT)
1113 {1658 {
1114 if ((droid.order != DORDER_BUILD) and (droid.order != DORDER_LINEBUILD))1659 if ((droid.order != DORDER_BUILD) and (droid.order != DORDER_LINEBUILD) and (droid.order != DORDER_HELPBUILD))
1115 {1660 {
1116 boolResult = FALSE;1661 boolResult = FALSE;
11171662
1118 if(curTech == branchDefault)1663 //powergen
1119 {1664 if(droid.order != DORDER_BUILD){
1120 //powergen1665 boolResult = upgradePowGen(droid, 4);
1121 boolResult = upgradePowGen(droid, 2);1666 }
11221667
1123 //factory1668 //research
1124 if(droid.order != DORDER_BUILD){1669 if(droid.order != DORDER_BUILD){
1125 boolResult = upgradeFactory(droid, 3);1670 boolResult = upgradeResearch(droid, 4);
1126 }1671 }
11271672
1128 //research1673 if(droid.order != DORDER_BUILD){
1129 if(droid.order != DORDER_BUILD){1674 boolResult = upgradeFactory(droid, 4);
1130 boolResult = upgradeResearch(droid, 1);1675 }
1131 }
11321676
1133 //vtol Factory1677 if(curTech != branchVTOL)
1678 {
1134 if(droid.order != DORDER_BUILD){1679 if(droid.order != DORDER_BUILD){
1135 boolResult = upgradeVtolFactory(droid, 1);1680 boolResult = upgradeVtolFactory(droid, 4);
1136 }1681 }
1137 }1682 }
1138 else if(curTech == branchVTOL)1683 else
1139 {1684 {
1140 //powergen
1141 boolResult = upgradePowGen(droid, 2);
1142
1143 //vtol Factory
1144 if(droid.order != DORDER_BUILD){1685 if(droid.order != DORDER_BUILD){
1145 boolResult = upgradeVtolFactory(droid, 3);1686 boolResult = upgradeVtolFactory(droid, 4);
1146 }
1147
1148 //factory
1149 if(droid.order != DORDER_BUILD){
1150 boolResult = upgradeFactory(droid, 2);
1151 }
1152
1153 //research
1154 if(droid.order != DORDER_BUILD){
1155 boolResult = upgradeResearch(droid, 1);
1156 }1687 }
1157 }1688 }
1158 }1689 }
1159 droid = iterateGroup(buildGroup);1690 droid = iterateGroup(buildGroup);
1160 }1691 }
1161}1692}
11621693
1163function bool upgradeFactory(DROID _truck, int _maxBuilders)1694function bool upgradeFactory(DROID _truck, int _maxBuilders)
1164{1695{
1165 local STRUCTURE _factory;1696 local STRUCTURE _factory, _closestFac;
11661697 local bool foundOne;
1698 local int _bestDist, _newDist;
1699 local DROID _search;
1700
1701 if(!isStructureAvailable(facModule,me))
1702 {
1703 return FALSE;
1704 }
1705
1706 _bestDist = 99999;
1167 initEnumStruct(FALSE,factory,me,me);1707 initEnumStruct(FALSE,factory,me,me);
1168 _factory = enumStruct();1708 _factory= enumStruct();
1169 while(_factory != NULLOBJECT)1709 while(_factory != NULLOBJECT)
1170 {1710 {
1171 // if upgrade is available && struct is not upgraded1711 if(not testStructureModule(me, _factory, 0) and droidCanReach(_truck, _factory.x, _factory.y))
1172 if( isStructureAvailable(facModule,me) and (skGetFactoryCapacity(_factory) < 2 ) and droidCanReach(_truck, _factory.x, _factory.y))
1173 {1712 {
1174 if((numBuildSameBuilding(facModule, _factory.x, _factory.y) +1713 _newDist = distBetweenTwoPoints(_truck.x, _truck.y, _factory.x, _factory.y);
1175 numBuildSameBuilding(vtolFactory, _factory.x, _factory.y)) < _maxBuilders)1714
1715 if (_newDist < _bestDist and droidCanReach(_truck, _factory.x, _factory.y)) // this one is closer
1176 {1716 {
1177 orderDroidStatsLoc(_truck, DORDER_BUILD,facModule, _factory.x,_factory.y); // upgrade it.1717 _bestDist = _newDist;
1178 return TRUE;1718 _closestFac = _factory;
1179 }1719 }
1180 }1720 }
1181 _factory = enumStruct();1721 _factory = enumStruct();
1182 }1722 }
1723
1724 if(_closestFac != NULLOBJECT)
1725 {
1726 if((numBuildSameBuilding(facModule, _closestFac.x,_closestFac.y) +
1727 numBuildSameBuilding(factory, _closestFac.x,_closestFac.y)) < _maxBuilders)
1728 {
1729 orderDroidStatsLoc(_truck, DORDER_BUILD, facModule, _closestFac.x,_closestFac.y); // upgrade it.
1730 return TRUE;
1731 }
1732 }
1183 return FALSE;1733 return FALSE;
1184}1734}
11851735
1186function bool upgradeVtolFactory(DROID _truck, int _maxBuilders)1736function bool upgradeVtolFactory(DROID _truck, int _maxBuilders)
1187{1737{
1188 local STRUCTURE _factory;1738 local STRUCTURE _factory, _closestVfac;
11891739 local bool foundOne;
1740 local int _bestDist, _newDist;
1741 local DROID _search;
1742
1743 if(!isStructureAvailable(facModule,me))
1744 {
1745 return FALSE;
1746 }
1747
1748 _bestDist = 99999;
1190 initEnumStruct(FALSE,vtolFactory,me,me);1749 initEnumStruct(FALSE,vtolFactory,me,me);
1191 _factory = enumStruct();1750 _factory= enumStruct();
1192 while(_factory != NULLOBJECT)1751 while(_factory != NULLOBJECT)
1193 {1752 {
1194 // if upgrade is available && struct is not upgraded1753 if(not testStructureModule(me, _factory, 0) and droidCanReach(_truck, _factory.x, _factory.y))
1195 if( isStructureAvailable(facModule,me) and (skGetFactoryCapacity(_factory) < 2 ) and droidCanReach(_truck, _factory.x, _factory.y))
1196 {1754 {
1197 if((numBuildSameBuilding(facModule, _factory.x, _factory.y) +1755 _newDist = distBetweenTwoPoints(_truck.x, _truck.y, _factory.x, _factory.y);
1198 numBuildSameBuilding(factory, _factory.x, _factory.y)) < _maxBuilders)1756
1757 if (_newDist < _bestDist and droidCanReach(_truck, _factory.x, _factory.y)) // this one is closer
1199 {1758 {
1200 orderDroidStatsLoc(_truck, DORDER_BUILD,facModule, _factory.x,_factory.y); // upgrade it.1759 _bestDist = _newDist;
1201 return TRUE;1760 _closestVfac = _factory;
1202 }1761 }
1203 }1762 }
1204 _factory = enumStruct();1763 _factory = enumStruct();
1205 }1764 }
1765
1766 if(_closestVfac != NULLOBJECT)
1767 {
1768 if((numBuildSameBuilding(facModule, _closestVfac.x,_closestVfac.y) +
1769 numBuildSameBuilding(factory, _closestVfac.x,_closestVfac.y)) < _maxBuilders)
1770 {
1771 orderDroidStatsLoc(_truck, DORDER_BUILD, facModule, _closestVfac.x,_closestVfac.y); // upgrade it.
1772 return TRUE;
1773 }
1774 }
1206 return FALSE;1775 return FALSE;
1207}1776}
12081777
1209function bool upgradeResearch(DROID _truck, int _maxBuilders)1778function bool upgradeResearch(DROID _truck, int _maxBuilders)
1210{1779{
1211 local STRUCTURE _resFac;1780 local STRUCTURE _resFac, _closestRes;
12121781 local bool foundOne;
1782 local int _bestDist, _newDist;
1783 local DROID _search;
1784
1785 if(!isStructureAvailable(resModule,me))
1786 {
1787 return FALSE;
1788 }
1789
1790 _bestDist = 99999;
1213 initEnumStruct(FALSE,resLab,me,me);1791 initEnumStruct(FALSE,resLab,me,me);
1214 _resFac = enumStruct();1792 _resFac= enumStruct();
1215 while(_resFac != NULLOBJECT)1793 while(_resFac != NULLOBJECT)
1216 {1794 {
1217 // if upgrade is available && struct is not upgraded1795 if(not testStructureModule(me, _resFac, 0) and droidCanReach(_truck, _resFac.x, _resFac.y))
1218 if( isStructureAvailable(resModule,me) and (not testStructureModule(me, _resFac, 0)) and droidCanReach(_truck, _resFac.x, _resFac.y))
1219 {1796 {
1220 if((numBuildSameBuilding(resModule, _resFac.x, _resFac.y) +1797 _newDist = distBetweenTwoPoints(_truck.x, _truck.y, _resFac.x, _resFac.y);
1221 numBuildSameBuilding(resLab, _resFac.x, _resFac.y)) < _maxBuilders)1798
1799 if (_newDist < _bestDist and droidCanReach(_truck, _resFac.x, _resFac.y)) // this one is closer
1222 {1800 {
1223 orderDroidStatsLoc(_truck, DORDER_BUILD,resModule, _resFac.x,_resFac.y); // upgrade it.1801 _bestDist = _newDist;
1224 return TRUE;1802 _closestRes = _resFac;
1225 }1803 }
1226 }1804 }
1227 _resFac = enumStruct();1805 _resFac = enumStruct();
1228 }1806 }
1807
1808 if(_closestRes != NULLOBJECT)
1809 {
1810 if((numBuildSameBuilding(resModule, _closestRes.x,_closestRes.y) +
1811 numBuildSameBuilding(resLab, _closestRes.x,_closestRes.y)) < _maxBuilders)
1812 {
1813 orderDroidStatsLoc(_truck, DORDER_BUILD, resModule, _closestRes.x,_closestRes.y); // upgrade it.
1814 return TRUE;
1815 }
1816 }
1229 return FALSE;1817 return FALSE;
1230}1818}
12311819
1232function bool upgradePowGen(DROID _truck, int _maxBuilders)1820function bool upgradePowGen(DROID _truck, int _maxBuilders)
1233{1821{
1234 local STRUCTURE _powGen;1822 local STRUCTURE _powGen, _closestGen;
12351823 local bool foundOne;
1824 local int _bestDist, _newDist;
1825 local DROID _search;
1826
1827 if(!isStructureAvailable(powModule,me))
1828 {
1829 return FALSE;
1830 }
1831
1832 _bestDist = 99999;
1236 initEnumStruct(FALSE,powGen,me,me);1833 initEnumStruct(FALSE,powGen,me,me);
1237 _powGen = enumStruct();1834 _powGen= enumStruct();
1238 while(_powGen != NULLOBJECT)1835 while(_powGen != NULLOBJECT)
1239 {1836 {
1240 // if upgrade is available && struct is not upgraded1837 if(not testStructureModule(me, _powGen, 0) and droidCanReach(_truck, _powGen.x, _powGen.y))
1241 if( isStructureAvailable(powModule,me) and (not testStructureModule(me, _powGen, 0)) and droidCanReach(_truck, _powGen.x, _powGen.y))
1242 {1838 {
1243 if((numBuildSameBuilding(powModule, _powGen.x,_powGen.y) +1839 _newDist = distBetweenTwoPoints(_truck.x, _truck.y, _powGen.x, _powGen.y);
1244 numBuildSameBuilding(powGen, _powGen.x,_powGen.y)) < _maxBuilders)1840
1841 if (_newDist < _bestDist and droidCanReach(_truck, _powGen.x, _powGen.y)) // this one is closer
1245 {1842 {
1246 orderDroidStatsLoc(_truck, DORDER_BUILD, powModule, _powGen.x,_powGen.y); // upgrade it.1843 _bestDist = _newDist;
1247 return TRUE;1844 _closestGen = _powGen;
1248 }1845 }
1249 }1846 }
1250 _powGen = enumStruct();1847 _powGen = enumStruct();
1251 }1848 }
1849
1850 if(_closestGen != NULLOBJECT)
1851 {
1852 if((numBuildSameBuilding(powModule, _closestGen.x,_closestGen.y) +
1853 numBuildSameBuilding(powGen, _closestGen.x,_closestGen.y)) < _maxBuilders)
1854 {
1855 orderDroidStatsLoc(_truck, DORDER_BUILD, powModule, _closestGen.x,_closestGen.y); // upgrade it.
1856 return TRUE;
1857 }
1858 }
1252 return FALSE;1859 return FALSE;
1253}1860}
12541861
12551862
1256/////////////////////////////////////////////////////////////////////1863/////////////////////////////////////////////////////////////////////
1257// Finish Building Part Built Structures1864// Finish Building Part Built Structures
1258event finishStructs(finishStructsTr)1865event finishStructs(finishStructsTr)
1259{1866{
1867 initEnumStruct(TRUE,resLab,me,me);
1868 structure= enumStruct();
1869 while(structure != NULLOBJECT)
1870 {
1871 if(not structureComplete(structure))
1872 {
1873 initIterateGroup(buildGroup); // find idle droids in build group.
1874 droid = iterateGroup(buildGroup);
1875 while(droid != NULLOBJECT)
1876 {
1877 if (droid.order != DORDER_BUILD and droid.order != DORDER_HELPBUILD
1878 and droidCanReach(droid, structure.x, structure.y )
1879 and distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < 12 * TILE)
1880 {
1881 orderDroidObj(droid,DORDER_HELPBUILD,structure);
1882 }
1883 droid = iterateGroup(buildGroup);
1884 }
1885 }
1886 structure= enumStruct();
1887 }
1888
1889 initEnumStruct(TRUE,powGen,me,me);
1890 structure= enumStruct();
1891 while(structure != NULLOBJECT)
1892 {
1893 if(not structureComplete(structure))
1894 {
1895 initIterateGroup(buildGroup); // find idle droids in build group.
1896 droid = iterateGroup(buildGroup);
1897 while(droid != NULLOBJECT)
1898 {
1899 if (droid.order != DORDER_BUILD and droid.order != DORDER_HELPBUILD
1900 and droidCanReach(droid, structure.x, structure.y)
1901 and distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < 10 * TILE)
1902 {
1903 orderDroidObj(droid,DORDER_HELPBUILD,structure);
1904 }
1905 droid = iterateGroup(buildGroup);
1906 }
1907 }
1908 structure= enumStruct();
1909 }
1910
1260 initEnumStruct(TRUE,factory,me,me);1911 initEnumStruct(TRUE,factory,me,me);
1261 structure= enumStruct();1912 structure= enumStruct();
1262 while(structure != NULLOBJECT)1913 while(structure != NULLOBJECT)
1263 {1914 {
1264 if(not structureComplete(structure))1915 if(not structureComplete(structure))
1265 {1916 {
1266 initIterateGroup(buildGroup); // find idle droids in build group.1917 initIterateGroup(buildGroup); // find idle droids in build group.
1267 droid = iterateGroup(buildGroup);1918 droid = iterateGroup(buildGroup);
1268 while(droid != NULLOBJECT)1919 while(droid != NULLOBJECT)
1269 {1920 {
1270 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD1921 if (droid.order != DORDER_BUILD and droid.order != DORDER_HELPBUILD
1271 and droidCanReach(droid, structure.x, structure.y)1922 and droidCanReach(droid, structure.x, structure.y)
1272 and distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < 20 * TILE)1923 and distBetweenTwoPoints(droid.x, droid.y, structure.x, structure.y) < 8 * TILE)
1273 {1924 {
1274 orderDroidObj(droid,DORDER_HELPBUILD,structure);1925 orderDroidObj(droid,DORDER_HELPBUILD,structure);
1275 }1926 }
1276 droid = iterateGroup(buildGroup);1927 droid = iterateGroup(buildGroup);
1277 }1928 }
1278 }1929 }
1279 structure= enumStruct();1930 structure= enumStruct();
1280 }1931 }
1281}1932}
12821933
12831934
1284/////////////////////////////////////////////////////////////////////1935/////////////////////////////////////////////////////////////////////
1285// fortify base by builiding defensive structs on the edge of the base.1936// fortify base by builiding defensive structs on the edge of the base.
1286// rewrote fortify to use scrSkDefenseLocation(baseX,baseY,me);1937// rewrote fortify to use scrSkDefenseLocation(baseX,baseY,me);
12871938
1288event newfortify(fortifyTr)1939event newfortify(fortifyTr)
1289{1940{
1290 local int _numBuilders,_maxBuilders;1941 local int _numBuilders,_maxBuilders;
12911942
1292 _maxBuilders = 1;1943 _maxBuilders = 1;
12931944
1294 if(numGroupSameOrder(buildGroup, DORDER_LINEBUILD) >= _maxBuilders)1945 if(numGroupSameOrder(buildGroup, DORDER_LINEBUILD) >= _maxBuilders or (playerPower(me) < 25))
1295 {1946 {
1296 exit;1947 exit;
1297 }1948 }
12981949
1299 boolResult = FALSE;1950 boolResult = FALSE;
1300 initIterateGroup(buildGroup); // find idle an idle veh.in build group.1951 initIterateGroup(buildGroup); // find idle an idle veh.in build group.
1301 droid = iterateGroup(buildGroup);1952 droid = iterateGroup(buildGroup);
1302 while((boolResult == FALSE) and (droid != NULLOBJECT))1953 while((boolResult == FALSE) and (droid != NULLOBJECT))
1303 {1954 {
1304 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD and droid.order != DORDER_HELPBUILD)1955 if (droid.order != DORDER_BUILD and droid.order != DORDER_LINEBUILD and droid.order != DORDER_HELPBUILD)
1305 {1956 {
1306 boolResult = TRUE; // dont do this again!1957 boolResult = TRUE; // dont do this again!
13071958
1308 tempx = baseX;1959 tempx = baseX;
1309 tempy = baseY;1960 tempy = baseY;
13101961
1311 // choose a suitable turret.1962 // choose a suitable turret.
1312 count = numWallWeaps - 1;1963 count = numWallWeaps - 1;
1313 count2 = 0;1964 count2 = 0;
1314 while( (count2 < 3) and (count >= 0) )1965 while( (count2 < 3) and (count >= 0) )
1315 {1966 {
1316 if( isStructureAvailable(wallWeaps[count],me))1967 if( isStructureAvailable(wallWeaps[count],me))
1317 {1968 {
1318 structChoice[count2] = wallWeaps[count];1969 structChoice[count2] = wallWeaps[count];
1319 count2 = count2 + 1;1970 count2 = count2 + 1;
1320 }1971 }
1321 count = count - 1;1972 count = count - 1;
1322 }1973 }
1323 count =0;1974 count =0;
1324 if((count2 > 0) and (_numBuilders < _maxBuilders))1975 if((count2 > 0) and (_numBuilders < _maxBuilders))
1325 {1976 {
1326 count = random(count2);1977 count = random(count2);
1327 skDefenseLocationB(ref tempx,ref tempy,wall,structChoice[count],droid,me);1978 skDefenseLocationB(ref tempx,ref tempy,wall,structChoice[count],droid,me);
1328 _numBuilders++;1979 _numBuilders++;
1329 }1980 }
13301981
1331 }1982