From 0007d8a57fe084c0acc0e786ae947dd0ded329e3 Mon Sep 17 00:00:00 2001 From: Dydo Date: Mon, 22 Mar 2010 20:06:26 +0000 Subject: [PATCH] DyDo-AI 2.0.8 first trunk version git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@10402 4a71c877-e1ca-e34f-864e-861f7616d084 --- .../dydo-ai/multiplay/skirmish/ai.slo | 11656 ++++++++++++++++ .../dydo-ai/multiplay/skirmish/ai.vlo | 1632 +++ 2 files changed, 13288 insertions(+) create mode 100644 data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.slo create mode 100644 data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.vlo diff --git a/data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.slo b/data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.slo new file mode 100644 index 000000000..ed9ef35f7 --- /dev/null +++ b/data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.slo @@ -0,0 +1,11656 @@ +/* +DyDo-AI Rel 2.0.8 +Mod Developer: "DylanDog" on http://forums.wz2100.net/ +AI webpage: http://www.obooma.net/dydo/ + +DyDo-AI is for skirmish & multiplayer games only. +DyDo-AI 2.x can be played on WZ 2.3.x only + +################################################################# +For changelog, bug reporting and downloads see DyDoAI homepage: +http://www.obooma.net/dydo/ +################################################################# + + +________________ CHANGELOG ___________________________________ + +See Dydo website + +{fix} In map with scavengers an error was generated as AI is not able to identify scavenger base +{fix} Fixed a bug which reduced the tanks production +{fix} Fixed a bug which could cause AI to attak with few units +{fix} Mobile repair turret was researched too late +{change} Improved the truck selection for building tasks +{change} Changed the number of building to be built, now DyDo decreses them by one too if the map has very low power. +{change} Reduced the number of Repair Facilities to be built +{change} Changed a bit the rules concerning the building of tanks +{change} Light bodies are not build anymore if heavy bodies are vailable +{change} Minor changes on attack activation events +{change} DyDo now builds artillery to defend the base + + +ToDo: +Improve lassat targets, intoduce droid targets! +Improve the way the units are gathered. dyDo should be abale to attack from various sides. + +*/ +#define DYDOBP_RELEASE "DyDo-AI ver 2.0.8" + +#define GAME_TIME_IN_SECS (gameTime / 10) +#define GAME_TIME_IN_MIN (gameTime / 10 / 60) +#define TIME_MINUTE 600 +#define MAX_WHILE_LOOPS 99 +#define BIG_MAP 120 +#define PLAYER_NUMBER 0 +#define TEAM_NUMBER 1 + +//gametype +#define GT_2PLAYERS_1HP 0 +#define GT_4PLAYERS_1HP_2T 1 +#define GT_4PLAYERS_1HP_34T 2 +#define GT_8PLAYERS_1HP_23T 3 +#define GT_8PLAYERS_1HP_4567T 4 +#define GT_4PLAYERS_2HP_2T 5 +#define GT_4PLAYERS_2HP_34T 6 +#define GT_8PLAYERS_2HP_23T 7 +#define GT_8PLAYERS_2HP_4567T 8 +#define GT_8PLAYERS_3HP_23T 9 +#define GT_STANDARD 10 + +//stats +#define OC_WEAPON_COST 0 +#define OC_RESLABS 1 +#define OC_PHYTON 2 +#define OC_MANTIS 3 +#define OC_TIGER 4 +#define OC_CYBORGS 5 +#define OC_TANKS 6 +#define OC_VTOLS 7 +#define OC_DERRICKS 8 +#define OC_DEF_STRUCT 9 +#define OC_CYB_POWER 10 +#define OC_TK_POWER 11 +#define OC_VTOL_POWER 12 +#define OC_CYB_HP 13 +#define OC_TK_HP 14 +#define OC_VTOL_HP 15 + +#define WUI_TOTUNITS 0 +#define WUI_POWER 1 +#define WUI_HP 2 + +//used with AIPersonality +#define AI_STANDARD 1 +#define AI_VTOL 2 +#define AI_TURTLE 3 +#define AI_CYBORG 4 + +//select tank template +#define BODY_HEAVY 0 +#define BODY_MEDIUM 1 +#define BODY_LIGHT 2 +#define WEAPON_AR 0 +#define WEAPON_AT 1 +#define WEAPON_AP 2 + +//used with minDefDroids[][x] +#define MINDEF_TANKS 0 +#define MINDEF_CYBORGS 1 +#define MINDEF_VTOLS 2 + +#define EVENT_CHECK_NUMBER 23 + +#define NUM_AI_PERSONALITIES 4 +#define MAX_PLAYERS 8 +#define TILE 128 +#define MAX_DROIDS 150 + +#define STR_TANK_FACTORY 0 +#define STR_RESLAB 1 +#define STR_CYB_FACTORY 2 +#define STR_VTOL_FACTORY 3 + +#define MAX_DEFSTR_DERRICKS 3 +#define MAX_DEFSTR_SPOT 3 +#define MAX_REPAIRFAC 5 + +#define VERY_LOW_POWER_MAP 0 +#define LOW_POWER_MAP 1 +#define NORMAL_POWER_MAP 2 +#define HIGH_POWER_MAP 3 + +//harvTrucks+buildTrucks+defTrucks +#define MIN_BUILDING_TANKS 6 +#define MIN_CYB_CONSTENG 4 + +#define TIME_MOVE_TOGATEWAYS 70 +#define THREAT_RANGE_TILES 8 +//used for repairing and building derricks +#define THREAT_RANGE_TILES_SHORT 7 +#define THREAT_RANGE_TILES_LONG 10 + +#define BUILDDEF_GRP 0 +#define CYBENG_GRP 1 +#define BUILD_GRP 2 +#define HARVEST_GRP 3 + +#define STRUCT_REPAIR_DAMAGE 25 + +#define RED_ALERT 3 +#define YELLOW_ALERT 2 +#define GREEN_ALERT 1 +#define ALERT_INACTIVE 0 + +//used to compare combat strenghts +#define COMBAT_RANGE (TILE * 12) + +//repairing untis +#define MAX_REPAIR_UNITS 2 +#define MIN_HEALT_REPAIR_BASE 80 +#define MIN_HEALT_SWITCH_TO_TANK 95 +#define MIN_HEALT_SWITCH_TO_CYBORG 95 +#define DAMAGE_REPAIR_LEVEL 50 +#define DAMAGE_REPAIR_LEVEL_LOW 20 +#define VTOL_DAMAGE_REPAIR_LEVEL 75 +#define STRUCT_REPAIR_DAMAGE 25 + +//tanks +#define MIN_ATTACKING_TANKS 10 +#define MAX_ATTACK_TANKS_ADD 12 +#define MIN_DEFUNIT_DEFEND 2 +#define MIN_SURVIVOR_TANKS 3 + +#define MIN_HELPING_UNITS 5 +//this is for both cybDefGRP and tkDefGRP, therefore the max helping is 10! +#define MAX_HELPING_UNITS 5 +//attack enemy and defend with defGrp only if we have at least these number of units +#define MIN_DEFUNIT_ATTACK 5 + +//cyborgs +#define MIN_DEFCYB_DEFEND 2 +#define MIN_ATT_CYBORGS 10 +#define MAX_ATTACK_CYBORG_ADD 12 +#define MIN_SURVIVOR_CYBORGS 3 + +//VTOLs - code cleaning stopped here +#define MAX_VTOLS 15 +#define MAX_VTOLS_PERS2 25 +//attack only if this number of VTOLs has been reached +#define MIN_VTOLS_ATTACK_DERRICK 2 +#define MIN_VTOLS_ATTACK_BASE 7 +#define MIN_VTOLS_DEFEND_BASE 1 +//Personality 2 aims for a quick buoild of these VTOLs +#define MIN_VTOLS 3 +#define MIN_VTOLS_PERS2 5 +#define AA_THREAT_RANGE (TILE * 18) + +//defend +#define MAX_DEFEND_RANGETILES 45 +#define MIN_BASE_DEF_STRUCTS 12 +#define MAX_BASE_DEF_STRUCTS 20 + +//AA +#define RANGE_BUILD_AADEF 7*TILE +#define MAX_AADEF_INRANGE 3 +#define MIN_AA_INBASERANGE 7 +//add to nRangeBase +#define RANGETILES_DEFSTR_AROUNDBASE 10 + +//if after TIME_HARVESTING_PHASE units are lower then this we cannot perfom building new structs, researches, upgrades +#define MIN_TOT_UNITS 8 +//build derrick defences only after this time +#define VALID_TIME_DERRICK_DEF 3600 +//change the units to add to build up the attacking group every this interval time +#define TIME_CHANGE_TANKSTOADD 3000 + +//build more then 2 repair centres aonly after this time +#define VALID_TIME_REPAIRFAC 4200 +//build 4-5 Research and Cyborg Factory after this time +#define VALID_TIME_EXTRABUILD 4800 +//build oilDef only after this time +#define VALID_TIME_CYBATTACK 6000 +//after 4 min all oil should be got +#define TIME_HARVESTING_PHASE 3000 +//after this time alert is set to DEACTIVATED anyway +#define TIME_TO_RESET_ALERT 100 +//build gateway def only after this time +#define VALID_TIME_GATEWAYDEF 3600 +//start researching VTOL stuff only after this time +#define TIME_START_VTOLRESEARCH 3000 +//force the building of a defence every x min +#define TIME_TOFORCE_BUILDDEF 1200 +//turtle AI +#define TIME_TOFORCE_BUILDDEF_2 900 + +//power +#define VERY_LOW_POWER 0 +#define LOW_POWER 1 +#define HIGH_POWER 2 +#define TIME_SWITCH_WORKSTRUCT 600 + +#define BEST_VTOL_TEMPLATES 3 + +public INT player; // player for this instance. +//public BOOL LIFE; // feature switch +public INT numMaxDerricks; // rate of exploration + +// structures +public INT baseX,baseY,minx,miny,maxx,maxy,defSpotX,defSpotY; +public INT numStructs,numAA,numIncendrys, numFortressDef,numWallWeaps,numTmpls, numSuperCyb, numSense, numGenAA; +public STRUCTURESTAT wall,incendrys[8],structs[51],defStructs[20],structChoice[30],fortressDef[4],wallWeaps[20],vtolDefStruct[10],sense[3],vtolGenStruct[10]; +public STRUCTURESTAT sensorTower,resLab,powGen,playerHQ,demAnomallyFix,lassat,factory,derrick,cybFactory,vtolPad,vtolFactory,repairFacility, uplinkCenter,CBSense; +public STRUCTURESTAT HMGhardPoint,MGbunker,miniRocketTower,LancerTower, powModule,facModule,resModule; +public STRUCTURESTAT defMortar,defBombard, defPepperpot,defRippleRockets; +public RESEARCHSTAT WhirlwindAASite,CycloneAASite,HurricaneAASite; +public RESEARCHSTAT AASite,VTOLPadRes,lancerATweap; +public int nStat,aStat[20][8],structsLimits[4][4],structsBuildLimits[4][4],numDefStructs,minDefDroids[4][3]; + +//keep even if not used +public RESEARCHSTAT nexusDefence, powerAddOn; + +public STRUCTURESTAT pickStrQueue[15]; +public INT pickStrQueueDepth; +public STRUCTURESTAT pickDefQueue[50]; +public INT pickDefQueueDepth; +public STRUCTURESTAT pickWallDefQueue[60]; +public INT pickWallDefQueueDepth; +public STRUCTURESTAT pickFortQueue[4]; +public INT pickFortQueueDepth; + +private STRUCTURESTAT pickStructureQueue[80]; +private INT pickStructureQueueDepth; + +public BOOL showAIPersonality; +public int AIPersonality,AIstrength; +private int nAI_Pers; + +// unit templates +public TEMPLATE tmpl0[63]; +public TEMPLATE tmpl1[5]; +public TEMPLATE superCyb[20]; +public TEMPLATE constructor,constructor2,VTOLconstr,cybMech,cybcondroid,repairTank; + +// special - template recognizer +public PROPULSION cyborgPropulsion; + +//build +private INT buildX,buildY; +public FEATURESTAT oilRes; + + +// GROUPS +public GROUP vtolHunterGr, vtolDefendGr ,vtolAttGr, tankGroup, buildGroup, harvesterGroup, toBeRepairedTankGroup, repairGroup, toBeRepairedCyborgGroup, cyborgDefGroup, cyborgAttGroup; +private GROUP xGroup; + +// generic +private STRUCTURE structure,structure2,structure3; +private DROID droid,droid2; +private FEATURE feature,feature2; +private BASEOBJ baseobj; +private INT count,count1,count2,count3,count4; +private BOOL boolResult,boolResult2,boolResult3; + +private INT aPlayers[8][8]; + +public BASEOBJ lassatTarget,myBaseObject,enemyBaseObject; + +//Shielding systems (2:45 hours after game begins) (KICK) +public RESEARCHSTAT SHIELDS; + +// +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +///////////////////////////////////////////// + +//// DEBUG-MODE +public BOOL EnableSliders;// DylanDog + +//// T1 cyborgs problem +public RESEARCHSTAT CyborgLegs; + +private INT oilX,oilY; + +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+ DylanDog - VARIABLES DECLARATION *+*+*+*+*+*+*++*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +public WEAPON MGun, TwinMGun , HMGun, TwinAGun, AGun, Flamer ,PlasmFlamer ,Inferno; +public WEAPON FlashLight,PulseLaser,HeavyLaser; +public WEAPON NeedleGun , RailGun, GaussCannon ,PlasmaCannon ,EMPCannon ,LCannon; +public WEAPON MCannon ,ACannon ,HCannon ,TACannon ,HVCannon ,RocketBB, RocketPod; +public WEAPON RocketMRL , Lancer, RcketBB ,TankKiller ,RippleRockets ,ScourgeMissle; +public WEAPON SeraphMissile ,ArchangelMissile; +public WEAPON cybGren, cybLancer, cybScourge, cybSuperHPV, cybSuperScourge, cybTankKiller; +public WEAPON NEXUS_WEAPON1,NEXUS_WEAPON2; +public RESEARCHSTAT research[10][62],general2[10][62],general3[10][62],general4[10][62],researchCheap[1][21],general2Cheap[1][21],general3Cheap[1][21],general4Cheap[1][21]; +public RESEARCHSTAT mediumCannon,heavyCannon,trackPropulsion,hoverPropulsion; +public RESEARCHSTAT powUpgrades0,powUpgrades1,powUpgrades2,powUpgrades3,powUpgrades4,powUpgrades5,powUpgrades6; +public RESEARCHSTAT cobraBody, phytonBody, scorpionBody, mantisBody, leopardBody, pantherBody, tigerBody, retaliationBody, retributionBody, vengeanceBody, wyvernBody, dragonBody; +public RESEARCHSTAT resCBSense,mortarPit, bombardPit, pepperpotPit, rippleRockets; + +public STRUCTURESTAT baseStructs[10]; + +public int numRes[10],numResGen2[10],numResGen3[10],numResGen4[10],numCheapRes[1],numCheapResGen2[1],numCheapResGen3[1],numCheapResGen4[1]; + +// ========================= PRIVATE ===================================== +private GROUP buildDefGroup,cyborgConstructGroup,tankDefGroup,helpGroup; +private BASEOBJ attackCybObj,attackTankObj; +private BASEOBJ objTargetHelpTeam,objTargetCybDefGRP,objTargetTankDefGRP; +private FEATURE _oilRes; +private DROID _droid, _droid1, _droid2,_idleTruck,_notIdleTruck,mydroid; +private STRUCTURE _derrick,_struct; + +private bool bPowerNormalized,bAttackedHumanDerrick,debugCenterView, bAttackedByMortars; +private bool bAttackedByLongRangeWeap,sentToGateway,isBackinBase; +private bool alertIsOn; +private bool bCybAttIsOn,lCybSentToGatheringPoint,bCybAlreadyGathered; +private bool bOilResLeft,lStopVTOLProduction,lStopVTOLFactBuilding,lStopResLabUpgrade; +private bool lMinBaseStructBuilt,lStopBuildingStructures,lStopBuildRepFacility,lStopCybEngProd; +private bool lStopBuildTankProd,lStopTankProduction, lStopCybProduction, lStopResearch; +private bool lStopCheapResearch, lStopFactUpgrade, lStopBuildDefDerricks,lStopBuildDefGateway; +private bool lStopBuildDef,lStopFactUpgrade2,bVTOLTargetIsDerrick,_bVTOLTarget; +private bool _mustBeHuman,lTankSentToGatheringPoint, bTankAttIsOn, bTankAlreadyGathered; +private bool bForceResPowUp,bFinalAttack_1vs1,bAttackTeamAttacked; +private bool _bNoTrucks,bNeedDerrick,bDroidSelected,bAttackedByVTOL; + + +private int oilResTargetId[11], oilResTargetX[11], oilResTargetY[11]; +private int aGatewayPosX[4],aGatewayPosY[4],nTotGateways,lastTimeRepairBuilt; +private int numDefStrAtGateway,numGatewaysFound,defTruckSentTime,lastBuildDefX; +private int lastBuildDefY,nRealGatewaysFound,nMidX,nMidY,nTotOilInAtStart; +private int nLastTimeBuiltRepFac,lastTruckBuilt,lastCybEngBuilt,lastDisplayAI; +private int lastDisplayAIcheck,nDefendRange,gatewaysRangeTiles,numBaseStructs; +private int nBaseRange,aaRange,gatherDefCybX,gatherDefCybY,gatherDefTankX,gatherDefTankY; +private int lastResIndex, nAttackingUnitsToAdd, nCybAttUnitsToAdd; +private int nArtilleryPos,nTime,nAttackTime,nFrWeapStructs,nFrWeapDroids,nFrWeapDrStr; +private int nTanksDefGrp,nMapPower,nEnWeapStructs,nEnWeapDroids,nEnWeapDrStr; +private int tTargetTime,tFinishOilHack,alertX,alertY,alertTime,alertLevel,nX,nY; +private int tLastRRBuilt,tLastArtilleryBuilt,tLastPowerGen,tChangeTimeTankToAdd,nHelpX,nHelpY,tLastHelp,tTotalAttack,tLastTankAttack,tLastCyborgAttack; +private int tTanksReSentToGathering,tTanksSentToGathering,nTankGatheringX,nTankGatheringY,tankAttackX,tankAttackY,targetPlayerTank,targetPlayerVTOL; +private int tCybReSentToGathering,tCybSentToGathering,tCybAttackAction,tHelpAction,tTankAttackAction,nCybGatheringX,nCybGatheringY,cybAlertX,cybAlertY,cybAttackX,cybAttackY,targetPlayerCyb; +private int tEveryMin, tEvery3Min; +private int playerLeft,nVTOLFactories,nWorkingVTOLFac,nTotTanks,nTotCyborgs,nMyDerricks,nPower,nFactories,nResLabs,nCybFact,nWorkingFact,nWorkingCybFac; +private int nKineticX,nKineticY,nWorkingLab,nTotDefences,nFreeOilRes,nTotBaseDefences; +private int _targetPlayer,nLastDefSpotUpdate,_nOilRes, _t, _pos; +private int nTotCybAR, nTotCybAP, nTotCybAT, nTotCybKK, nTotCybErr; + +private int nTotEnemyDroids,nCybMechanic,nStructToBeBuilt,nAllyBeingHelped,nPODMRLTank, nWeakTank,nTotCyborgBuilt,nTotTankBuilt; +private int tLastCybMech,tLastFinalAttack,nFinalAttacks,nDamageLevelRepair, nProdSelect, tLastPowerSwitch,tLastbuildBaseDef,nEnemyPlayers,nLastEnemyPlayer,nTeam,nHumanPlayers,nPlayersInGame,nDerricksAtStart; +private int tDefVtolAction,tDefTankAction,tDefCybAction,tLastResearch; + +private int num_aDroid,aDroid_Id[50],aDroid_X[50],aDroid_Y[50],aDroid_counter[50]; +private int nAttHumanPlayer,nAttAIPlayer; + +private int _nWeapon, _nBody; + +public TEMPLATE vtols[18]; +public int numAAinBase,tLastAAbuilt,tLastVTOLFactBuild,numVtolTemplates; +private BASEOBJ defTargetVTOL,attTargetVTOL; + +private int aPower[3],nAAPos,nAIcheck,tAIbrain,eventCheckReport[EVENT_CHECK_NUMBER],eventCheckTime[EVENT_CHECK_NUMBER],eventCheckTrigger[EVENT_CHECK_NUMBER],eventCheckCounter[EVENT_CHECK_NUMBER]; + +public PROPULSION Half_Track,TrackedProp,HoverProp; +public BODY Viper; + +//communication +private int _sender,sender, x, y, tBeaconTimeout, beaconX[8], beaconY[8], tBeacon[8]; +private int lastHelpPlayer, _fromPlayer, _choice; +private string message,_message,_cstr; +private bool _bBlipMessage,_bToHuman; + +private int tBeaconSent; + +private bool _DEBUG,_DEBUG1,_dbg, bRunning; + +//=================================================================== +// USED FOR PRODUCTION ONLY + +private int nProd1, nProd2, nProd3, nProd4, nProd5; +private float fProd1, fProd2, fProd3, fProd4, fProd5; +private int tProd1, tProd2, tProd3, tProd4, tProd5; +private bool bProd1, bProd2, bProd3, bProd4, bProd5; +private string sProd1, sProd2, sProd3, sProd4, sProd5; + + +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+ TRIGGERS *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//trigger finishStructsTr (every,300); +#region triggers + +trigger droidBuiltTr (CALL_NEWDROID,player, ref droid,ref structure); +trigger AIattackedTr (CALL_ATTACKED, player, ref myBaseObject, ref enemyBaseObject); +trigger vtolDefendTr (CALL_STRUCT_ATTACKED, player, ref structure, ref enemyBaseObject); +trigger multiMsgTr (CALL_AI_MSG, player, ref sender, ref message); +trigger beaconTr (CALL_BEACON, player, ref sender, ref x, ref y, ref message); +trigger consoleTr (CALL_CONSOLE, ref sender, ref message); +trigger reassignPlayersTr (CALL_PLAYERLEFT,ref playerLeft); + +trigger defFromLongRangeWeapTr(wait,1); +trigger difficultyModifierTr (wait,3); +trigger shutDownAITr (every,4); + +trigger AIcheckTr (every,10); +trigger buildPowerGeneratorsTr(every,10); +trigger buildRepFirstTr (every,10); +trigger harvesterOperateTr (every,10); +trigger AIbrainTr (every,10); + +trigger manageDefCyborgsTr (every,20); +trigger manageDefTankTr (every,20); +trigger unitRepairSwitchTr (every,20); +trigger upgradeStructuresTr (every,20); +trigger defendGatewaysPointTr (every,20); +trigger buildRippleRocketsTr (every,20); +trigger buildAAdefTr (every,25); +trigger defendBaseTr (every,30); +trigger defendDerrickTr (every,30); +trigger buildArtilleryTr (every,30); +trigger reSortUnitsTr (every,30); +trigger TankAttackTr (every,30); +trigger CyborgAttackTr (every,30); +trigger SelectCyborgTemplateTr(every,30); +trigger SelectTankTemplateTr (every,30); +trigger manageHelpTeamTr (every,30); +trigger sendBackDamagedUnitsTr(every,30); +trigger manageRepairTeamTr (every,30); +trigger doResearchTr (every,30); +trigger buildBaseTr (every,30); +trigger buildRepFacSuppAttackTr (every,30); +trigger vtolStructsTr (every,30); +trigger buildVtolsTr (every,30); +trigger VTOLmicroManagerTr (every,30); +trigger threatCheckTr (every,30); + +trigger manageIdleTrucksTr (every,35); + +trigger manageDefVTOLTr (every,40); + +trigger unitAssignationCheckTr(every,50); +trigger truckGroupSliderTr (every,50); +trigger evDebugTr (every,100); +trigger activateAttackTr (every,100); +trigger evPrintDebugTr (every,100); +trigger vtolEnablerTr (every,200); +trigger updateBaseDetailsTr (every,200); +trigger showPlayerInfoTr (every,200); +trigger useLassatTr (every,3000); +trigger showAImessageTr (every,6000); + +trigger VTOLhunterTr (every,15); + +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+ DylanDog - EVENTS DECLARATION *+*+*+*+*+*+*++*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* + +//event 0 +event evDebug; + +//main event 1-2 +event AIbrain; +event AIcheck; + +//harvesting - events 3-4 +event truckGroupSlider; +event harvesterOperate; + + +//building ebvents 5-9 +event upgradeStructures; +event buildBase; +event buildPowerGenerators; +event buildRepFirst; +event buildRepFacSuppAttack; + + +//Research event 10 +event doResearch; + +//defense events 11-13 +event defendBase; +event defendDerrick; +event defendGatewaysPoint; + +//event 14-16 +event manageDefTank; +event manageDefCyborgs; +event manageDefVTOL; + +//ebent 17 +event AIattacked; + +//attack event 18-20 +event activateAttack; +event CyborgAttack; +event TankAttack; + +//VTOL event 21-23-24 +event vtolEnabler; +event vtolStructs; +event vtolDefend; +event buildAAdef; + +//repair event 25-27 +event manageRepairTeam; +event unitRepairSwitch; +event sendBackDamagedUnits; + +//idleTrucks event 28 +event manageIdleTrucks; + +//Units production 29-31 +event SelectCyborgTemplate; +event SelectTankTemplate; +event buildVtols; + + +//Group Management 32-34 +event droidBuilt; +event unitAssignationCheck; +event reSortUnits; + +//uncategorized 35-40 +event initialisedEvent; +event useLassat; +event difficultyModifier; +event updateBaseDetails; +event showPlayerInfo; +event showAImessage; + +//chat 41-45 +event multiMsgEv; +event beaconEv; +event manageHelpTeam; +event shutDownAI; +event defFromLongRangeWeap; + +//debug 46-48 +event evPrintDebug; +event VTOLmicroManager; +event reassignPlayers; + +//event 49 +event threatCheck; +event VTOLhunter; + +event buildArtillery; +event buildRippleRockets; + + +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+ DylanDog - FUNCTION DECLARATION *+*+*+*+*+*+*++*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* + +function DROID getADroid(GROUP _theGRP); +function bool droidOrderIdle(DROID _droid); +function DROID pickDefTruck(bool _idleOne);//true=idle truck false=any truck +function void displayMsg(STRING _message); +function FEATURE closestOilRes(DROID _droid, int _x, int _y); +function STRUCTURE closestDerrickToDefend(); +function int getNumDerricks(int _player); +//reset oilResTargetId, oilResTargetX, oilResTargetY +function void checkDerrickIsBuilt(int _player); +//return a free position on the array of oilResTargetId & Co. +function int getOilResTargetFree(); +function void debugCentreView(DROID _droid); +//gateways and defences +function void buildGatewayDef(DROID _defTruck,int _pos); +function bool isDefStrComplete(); +function bool helpBuild(int _group); +function bool repairDefStructs(int _group); +function bool repairStructs(int _group); +function DROID pickCybEng(bool _idleOne);//true=idle truck false=any truck +function int updateGateways(); +function void initAssignUnitToGrp(); + +//base stats +function void updateBaseRange(); +function void updateBaseCoord(); + +//structure +function int numStructsByType(STRUCTURESTAT _structure, int _player); + +//research +function int do_Research(STRUCTURE _resFac, int _lastResIndex); +function int do_CheapResearch(STRUCTURE _resFac, int _lastResIndex); +function int find_Research(int _searchStart, int _techTree, int whichArray); + +//repair +function DROID unitToBeRepaired(GROUP _group); +function DROID nearestDroidToBeRepaired(GROUP _group, int _x, int _y); +function DROID idleRepairDroid(int _x, int _y); +function void moveUnitsBetweenGRPs(GROUP _toGRP, GROUP _fromGRP, int _unitsToMove, bool _bNoTrucks); +function void attackedByDroid(DROID _droid); +//used when struct attacks my base +function void attackedByStruct(STRUCTURE _struct); +function void sendIdleBackToTheBase(int _group); + +//brain +function int getNumStructNotIdle(STRUCTURESTAT _structToCheck); +function int getTotDerricksMap(); +function bool bAnyOilResLeft(); +function int numRemainingOilRes(); + +function STRUCTURE closestEnemyDerrick(bool _mustBeHuman,int _targetPlayer); +function int getCoordRelated(int _x1, int _y1, int _x2, int _y2,int _nWhichCooord, int _nDist); +function BASEOBJ findEnemyOBJ(bool _mustBeHuman,int _targetPlayer); +function int getRandomEnemyPlayer(bool _mustBeHuman); +function int getNearestEnemyPlayer(bool _humanPlayer); +function int getEnemy_baseCoord( int _player, STRING sCoord ); +function bool friendlyPlayer(int _playerToCheck); + +//VTOLS +function void buildRearmPads(); +function void vtolFactoryBuildVtol(STRUCTURE _factory); + +//others +function void deactivateTankAttack(); +function void deactivateCybAttack(); +function BASEOBJ objStrTargetInRange(int _xCoord,int _yCoord, int _Range); +function BASEOBJ objDroidTargetInRange(int _xCoord,int _yCoord,int _Range, bool bIsVTOL); +function void orderGroupMoveCMD(GROUP _grp, int _x, int _y); +function void orderGroupScoutCMD(GROUP _grp, int _x, int _y); +function void harvestNearOilRes(); +function void displayErrMsg(STRING _message); + +//AI personality +function void SetDyDoPersonality(int nPersonality, int _player); + +function bool aiResponsibleForPlayer(int _player); +function int _random(int x); +function void assignDroidToGrp(DROID droid); +function void manageVeryLowPower(); +function void manageVeryLowPower2(); +function void manageVeryLowPower3(); +function void manageVeryLowPower4(); +function STRUCTURE getVTOLstructTarget(); +function int numEnemyAAInRange(int _x, int _y, int _range); +function bool canHelpAlly(int _sender); +function bool bHelpingAnyAlly(); +function void helpAlly(int _ally); +function void deactivateHelp(); +//Communication +function void processCommand(STRING _message, int _sender, bool _bBlipMessage); +function void notifyAll(STRING _cstr); +function void sendMsgToAllAllies(STRING _message); +function void dropBeaconToAllies(STRING _message, int _x, int _y, int _z, bool _bToHuman); +function void notifyStatus(int _choice, int _player); +function bool haveBeacon(int _player); +function bool haveAnyBeacon(); +function bool beaconTimeout(int _player); +function void updateBeacons(); +function void updatePlayersStats(); +function int getDroidsInfo(int _player, int _choice); +function int getTeamNumber(int _player); +function BASEOBJ getTargetObj(); +function float getPowerIndex(int _player); +function int gameType(); +function int getWeaponUnitsInfo( int _player, int _choice); +function int getTargetEnemy(bool _dbg); +function bool bHasHumanEnemies(int _player); +function void displayStats(int _choice); + +function bool coordChanged(DROID _droid); +function bool hasCoordStored(DROID _droid); +function int getFreePosDroid(); +function void updateDroidCoord(DROID _droid); +function void storeDroidCoord(DROID _droid); +function void checkIfDroidIsStuck(GROUP _group); +function void cleanDroidPos(int _droidId); +function void cleanDroidCoordArray(); +function void stopDroidHarvesting(); +function bool incrementDroidCounter(int droid_id); +function bool isPlayerStillLive(int _player); +function bool buildDefStruct(DROID _droid, int _x, int _y ); +function int getSafeBuildCoord( DROID _droid, STRUCTURESTAT _struct, int _x, int _y, int _choice); +function BASEOBJ objHumanDerrick(bool bVTOLTarget, int _numDef, int _distInTiles); +function int numStructinRange(STRUCTURESTAT _struct, int _player, int _xCoord, int _yCoord, int _Range); +function void printDebug(STRING _message); +function void printDebug1( STRING _message); +function bool createAIalliance(int _player1, int _player2); +function STRUCTURESTAT getDefStruct(); +function DROID closestIdleDroid(GROUP _group, int _x, int _y); +function DROID closestDroidCanBuild(GROUP _group, int _x, int _y); +function STRUCTURE undefendedEnemyDerrick(bool _bVTOLTarget); +function STRUCTURE getAAStruct(bool _bVTOLTarget); +function void updateDefendRange(); +function void shutDownThisAI(); +function void activateAI(); +function bool buildHeavyTank( int _nWeapon, STRUCTURE _struct ); +function bool buildMediumTank( int _nWeapon, STRUCTURE _struct ); +function bool buildLightTank( int _nWeapon, STRUCTURE _struct ); +function int checkBestBody(int _nBody, int _nWeapon, STRUCTURE _struct ); + + + +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+ MAIN SCRIPT *+*+*+*+*+*+*++*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* + + +// HouseKeeping + +event initialisedEvent(CALL_GAMEINIT) +{ + + + player = getPlayer();//trunk + + lassatTarget = NULLOBJECT; defSpotY = 0 ; defSpotX = 0 ; maxy = 0 ; maxx = 0; + miny = 0 ; minx = 0 ; baseY = 0 ; baseX = 0 ; + + //DEBUGMESSAGE + dbgMsgOn(player, false); + debugCenterView = false; + _DEBUG = true;//print off debug messages every 5 min + _DEBUG1 = true;//print off debug messages + bRunning = false; //true if AI controls this player + + count =0; + while (count < 4){ + aGatewayPosX[count] = -1; + aGatewayPosY[count] = -1; + count++; + } + nAI_Pers = 0; + nTotCyborgBuilt = 0; + nTotTankBuilt = 0; + tFinishOilHack = gameTime; + nAIcheck = 0; + tAIbrain = 0; + defTruckSentTime= -1; + sentToGateway = false; + isBackinBase = false; + bNeedDerrick = false; + bAttackTeamAttacked = false; + bFinalAttack_1vs1 = false; + nAllyBeingHelped = -1; + nStructToBeBuilt = 0; + tDefVtolAction = 0; + tDefTankAction = 0; + tDefCybAction = 0; + tLastResearch = 0; + tLastHelp = 0; + tLastArtilleryBuilt = 0; + tLastRRBuilt = 0; + nHelpX = -1; + nHelpY = -1; + tLastbuildBaseDef = 0; + nRealGatewaysFound = 0; + lastBuildDefX = -1; + lastBuildDefY = -1; + lastResIndex = -1; + nMidX = -1; + nMidY = -1; + gatherDefTankX = -1; + gatherDefTankY = -1; + gatherDefCybX = -1; + gatherDefCybY = -1; + nTotGateways = 3; + nTotOilInAtStart = 0; + lastDisplayAI = 0; + lastDisplayAIcheck = 0; + lastTruckBuilt = 0; + lastCybEngBuilt = 0; + nPlayersInGame = -1; + nAAPos = 0; + nHumanPlayers = 0; + nTeam = -1; + nEnemyPlayers = -1; + nLastEnemyPlayer = -1; + nLastTimeBuiltRepFac = 0; + numDefStrAtGateway = -1; + lastTimeRepairBuilt = 0; + nLastDefSpotUpdate = -1; + tLastPowerSwitch = 0; + nProdSelect = 0; + nDamageLevelRepair = 0; + nFinalAttacks = 0; + tLastFinalAttack = 0; + alertIsOn = false; + alertX = baseX; + alertY = baseY; + alertTime = gameTime; + bCybAttIsOn = false; + lCybSentToGatheringPoint = false; + bCybAlreadyGathered = false; + bAttackedByVTOL = false; + cybAlertX = -1; + cybAlertY = -1; + cybAttackX = 0; + cybAttackY = 0; + nCybGatheringX = -1; + nCybGatheringY = -1; + targetPlayerCyb = -1; + tCybSentToGathering = 0; + tCybReSentToGathering = 0; + tCybAttackAction = 0; + tTankAttackAction = 0; + tHelpAction = 0; + tChangeTimeTankToAdd = 0; + tLastPowerGen = 0; + tLastTankAttack = 0; + tTotalAttack = random(3000); + tLastCyborgAttack = 0; + tLastVTOLFactBuild = 0; + tLastAAbuilt = 0; + //tank attack + bTankAttIsOn = false; + lTankSentToGatheringPoint = false; + bTankAlreadyGathered = false; + nTankGatheringX = -1; + nTankGatheringY = -1; + tankAttackX = -1; + tankAttackY = -1; + targetPlayerTank = -1; + targetPlayerVTOL = -1; + tTanksSentToGathering = 0; + tTanksReSentToGathering = 0; + pickWallDefQueueDepth = 0; + lastHelpPlayer = -1; + nKineticX = -1; + nKineticY = -1; + nAttHumanPlayer = 0; + nAttAIPlayer = 0; + tEveryMin = gameTime; + tEvery3Min = gameTime; + tBeaconSent = 0; + nTanksDefGrp=0; + nAttackingUnitsToAdd = random(MAX_ATTACK_TANKS_ADD); + nCybAttUnitsToAdd = random(MAX_ATTACK_CYBORG_ADD); + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildDefGateway = false; + lStopTankProduction = false; + lStopBuildTankProd = false; + lStopCybEngProd = false; + lStopCybProduction = false; + lStopResearch = false; + lStopCheapResearch = false; + lStopBuildRepFacility = false; + lStopBuildingStructures = false; + lMinBaseStructBuilt = false; + lStopResLabUpgrade = false; + lStopVTOLFactBuilding = false; + lStopVTOLProduction = false; + attackCybObj = NULLOBJECT; + bDroidSelected = false; + tBeaconTimeout = 45; //in secs + bAttackedHumanDerrick = false;//alternate attacks + bAttackedByMortars = false; + bAttackedByLongRangeWeap = false; + bPowerNormalized = false; + nProd1 = 1; + tLastCybMech = gameTime; + nCybMechanic = 0; + tTargetTime = gameTime; + nArtilleryPos = 0; + + num_aDroid = 50; + count = 0; + while ( count < num_aDroid ){ + aDroid_Id[count] = -1; + aDroid_X[count] = -1; + aDroid_Y[count] = -1; + aDroid_counter[count] = 0; + count++; + } + + count=0; + while ( count < MAX_PLAYERS){ + beaconX[count] = -1; + beaconY[count] = -1; + tBeacon[count] = -1; + count++; + } + + aPower[VERY_LOW_POWER] = 300; + aPower[LOW_POWER] = 600; + aPower[HIGH_POWER] = 1000; + + count = 0; + while ( count < 11 ) + { + oilResTargetId[count] = -1; oilResTargetX[count] = -1; oilResTargetY[count] = -1; + count++; + } + + count = 0; + nStat = 20; + while ( count < nStat ) + { + //reset array players stats + count2 = 0; + while ( count2 < MAX_PLAYERS ) + { + aStat[count][count2] = -1; + count2++; + } + count++; + } + + numMaxDerricks = 40; //max number of derricks per player + + structure = getStructure(playerHQ, player); + if(structure != NULLOBJECT) + { + baseX = structure.x; + baseY = structure.y; + } + else + { + groupAddArea(buildGroup, player, 0, 0, (mapWidth*128), (mapHeight*128)); + if(buildGroup.members > 0) + { + baseX = buildGroup.x; + baseY = buildGroup.y; + } + else + { + baseX = (128*mapWidth)/2; + baseY = (128*mapHeight)/2; + } + } + + initAssignUnitToGrp(); + //initialises all the no go areas to 0. + //Should be called when a new map is loaded + initAllNoGoAreas(); + + //for all players, avoid attacking themselves + createAlliance(player,player); + + //makes a research available to a player regardless of its pre-requisites + enableResearch(CyborgLegs, player); + completeResearch(CyborgLegs, player); + + //LIFE = true; + nBaseRange=TILE*5; + + //nDefend range + updateDefendRange(); + + //estimate the range for the gateways and the defend range + if ( nDefendRange > 0 ){ + gatewaysRangeTiles = nDefendRange; + } else { + if ( max(mapWidth,mapHeight) <= 92 ){ + gatewaysRangeTiles = 22; + } else if ( max(mapWidth,mapHeight) > 92 and max(mapWidth,mapHeight) <= 105 ){ + gatewaysRangeTiles = 28; + } else if ( max(mapWidth,mapHeight) > 105 and max(mapWidth,mapHeight) <= 128 ){ + gatewaysRangeTiles = 36; + } else { + gatewaysRangeTiles = 40; + } + } + + //time to force droids production. This is the time gone from last attack, if reached + //droids production is forced + nAttackTime = 7000 + random(4000); + + //store the numb of derricks at the beginning + nDerricksAtStart = getNumDerricks(player); + + //oilRes available in the map + nFreeOilRes = numRemainingOilRes(); + + //player stats, updates nPlayersInGame + updatePlayersStats(); + + //_______ AI PERSONALITY SETTINGS ________________ + SetDyDoPersonality(AIPersonality, player); + + //search if gateways have been added in the map + nRealGatewaysFound = updateGateways(); + + //AIstrength + if ( AIstrength <= 0 or AIstrength > 5){ + AIstrength = 1+random(5); + } + + //initialize eventCheckTime[] + count=0; + while (count < EVENT_CHECK_NUMBER){ + eventCheckTime[count] = gameTime; + eventCheckCounter[count] = 0; + count++; + } + + //set trigger time + count=0; + while (count < EVENT_CHECK_NUMBER){ + eventCheckTrigger[count] = 250; + eventCheckReport[count] = 0; + count++; + } + eventCheckTrigger[0] = 3050;//lassat + + if( aiResponsibleForPlayer(player) ) + { + bRunning = true; + activateAI(); + } else { + shutDownThisAI(); + } + + printDebug( DYDOBP_RELEASE & ", starting power: (" & playerPower(player) & ") "); + displayMsg( DYDOBP_RELEASE & ", www.obooma.net/dydo/"); + +} +//============================================= +event VTOLhunter (inactive){ + + //dbg("dbg->VTOLhunter: start ("& vtolHunterGr.members &")",player); + + if ( vtolHunterGr.members < 0 ){ + setEventTrigger(VTOLhunter, inactive); + exit; + } + + /* + if ( oVTOLhunterTarget == NULLOBJECT ){ + //oilRes + if (bOilResLeft){ + droid = getADroid(VTOLhunter); + _oilRes = closestOilRes(droid, droid.x, droid.y);//uses droidCanReach + if ( _oilRes == NULLOBJECT ){ + } + + } + //move + } else { + } + */ + +} +//==============================print stats and debug messages =============== +event evPrintDebug (inactive) +{ + + local string _sPlPow, _sPlInf1,_sPlInf2,_sPlInf3, _sPlInf4,_strTeams, _sWallDef, _sDef; + local string _sRes, _sRes2, _str0, _str1, _str2, _str3, _str4, _str5, _sFort; + local int _HQx,_HQy,_count; + + if ( gameTime - tEveryMin >= 600 ) { + printDebug1("Structs not idle: nProdSelect("& nProdSelect &") (Fac-Cyb-Res-VTOLfac) ("& nWorkingFact &"-"& nWorkingCybFac &"-"& nWorkingLab &"-"& nWorkingVTOLFac &") power["& playerPower(player) &"] Low Power("& aPower[VERY_LOW_POWER] &") tot Tank+Cyb("& nTotTanks+nTotCyborgs &") nAttackTime("& gameTime-nTime &"/"& nAttackTime &")"); + tEveryMin = gameTime; + } + + if ( gameTime - tEvery3Min >= 1800 ) { + structure = getStructure(playerHQ, player); + if(structure != NULLOBJECT) + { + _HQx = structure.x; + _HQy = structure.y; + } else { + _HQx = 0; + _HQy = 0; + } + + _count = 0; + while ( _count < numWallWeaps ){ + _sWallDef = _sWallDef & " ["& _count &"]("& isStructureAvailable(wallWeaps[_count],player) &") "; + _count++; + } + _count = 0; + while ( _count < numDefStructs ){ + _sDef = _sDef & " ["& _count &"]("& isStructureAvailable(defStructs[_count],player) &") "; + _count++; + } + _count = 0; + while ( _count < numFortressDef ){ + _sFort = _sFort & " ["& _count &"]("& isStructureAvailable(fortressDef[_count],player) &") "; + _count++; + } + + + _count = 0; + while ( _count < 20){ + _str0 = _str0 & " ["& _count &"]"& numResearchLeft(player,research[0][_count]) &" "; + _count++; + } + while ( _count < 40){ + _str1 = _str1 & " ["& _count &"]"& numResearchLeft(player,research[0][_count]) &" "; + _count++; + } + while ( _count < numRes[0]){ + _str2 = _str2 & " ["& _count &"]"& numResearchLeft(player,research[0][_count]) &" "; + _count++; + } + + _count = 0; + while ( _count < 23){ + _str3 = _str3 & " ["& _count &"]"& numResearchLeft(player,research[1][_count]) &" "; + _count++; + } + while ( _count < numRes[1]){ + _str4 = _str4 & " ["& _count &"]"& numResearchLeft(player,research[1][_count]) &" "; + _count++; + } + + + _count = 0; + while ( _count < numCheapRes[0] ){ + _sRes2 = _sRes2 & " ["& _count &"]"& numResearchLeft(player,researchCheap[0][_count]) &" "; + _count++; + } + + _count = 0; + while ( _count < numRes[9] ){ + _str5 = _str5 & " ["& _count &"]"& numResearchLeft(player,research[9][_count]) &" "; + _count++; + } + + _count = 0; + while (_count < MAX_PLAYERS){ + if (isPlayerStillLive(_count)){ + _strTeams = _strTeams & " '"& getPlayerName(_count) &"' #"& _count &" ["& aPlayers[TEAM_NUMBER][_count] &"] "; + } + _count++; + } + + _count=0; + while( _count < 2){ + if (isPlayerStillLive(_count)){ + _sPlInf1 = _sPlInf1 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + while( _count < 4 ){ + if (isPlayerStillLive(_count)){ + _sPlInf2 = _sPlInf2 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + while( _count < 6 ){ + if (isPlayerStillLive(_count)){ + _sPlInf3 = _sPlInf3 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + while( _count < MAX_PLAYERS ){ + if (isPlayerStillLive(_count)){ + _sPlInf4 = _sPlInf4 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + + printDebug("nAIcheck("& nAIcheck &") gameType("& gameType() &") map("& mapWidth &"-"& mapHeight &") BaseRange("& nBaseRange/TILE &") gtwRange("& gatewaysRangeTiles &") DefRange("& nDefendRange/TILE &") HQ("& _HQx/TILE &"-"& _HQy/TILE &") Base("& baseX/TILE &"-"& baseY/TILE &") lMinBaseStructBuilt("& lMinBaseStructBuilt &") "); + printDebug("Cyborgs Built: (AR-AT-AP-KK)(Error) ("& nTotCybAR &" - "& nTotCybAT &" - "& nTotCybAP &" - "& nTotCybKK &")("& nTotCybErr &") nTotCyborgBuilt("& nTotCyborgBuilt &") nTotTankBuilt("& nTotTankBuilt &")"); + printDebug("Stats1:" & _strTeams &" Teams("& nTeam &" )"); + printDebug("Stats2: nEnemyPlayers ("& nEnemyPlayers &") nHumanPlayers("& nHumanPlayers &") nPlayersInGame("& nPlayersInGame &") Att Human Player("& nAttHumanPlayer &") Att AI("& nAttAIPlayer &") anyOilResLeft("& bOilResLeft &") nTotEnemyDroids("& nTotEnemyDroids &")"); + printDebug("Stats3:" & _sPlInf1 ); + printDebug("Stats4:" & _sPlInf2 ); + printDebug("Stats5:" & _sPlInf3 ); + printDebug("Stats1:" & _sPlInf4 ); + printDebug("Std Def: Depth("& pickDefQueueDepth &") - " & _sDef ); + printDebug("Wall Def: Depth("& pickWallDefQueueDepth &") - "& _sWallDef); + printDebug("Fortresses: Depth("& pickFortQueueDepth &") - "& _sFort); + printDebug("Res 1: " & _str0 ); + printDebug("Res 2: " & _str1 ); + printDebug("Res 3: " & _str2 ); + printDebug("Res 4: " & _str3 ); + printDebug("Res 5: " & _str4 ); + printDebug("Cheap Res: "& numCheapRes[0] & " " & _sRes2); + printDebug("VTOL Res: "& _str5); + count = getTargetEnemy(true); + printDebug("------------------------------------------------------------------"); + tEvery3Min = gameTime; + } +} +//==============================event used to fix errors=============== +event evDebug (inactive) +{ + + //displayMsg("evDebug: time("& gameTime &")"); + if ( nAllyBeingHelped < 0 and helpGroup.members > 0 and gameTime - tLastHelp > 30){ + //dbg("dbg->evDebug: ("& getPlayerName(player) &") has ("& helpGroup.members &") helping units and attack is deactivated, gameTime("& gameTime &") tLastHelp ("& tLastHelp &")",player); + groupAddGroup(tankDefGroup, helpGroup); + orderGroup(tankDefGroup, DORDER_RTB); + + //if ( nAllyBeingHelped < 0 and helpGroup.members == 0){ + //dbg("dbg->evDebug: ("& getPlayerName(player) &") has now no more helping units, FIXED!",player); + //} else { dbg("dbg->evDebug: ("& getPlayerName(player) &"): is not able to switch helping units back to tankGroup!",player); } + } + + //Search for stucked droids + + cleanDroidCoordArray(); + checkIfDroidIsStuck(buildGroup); + checkIfDroidIsStuck(buildDefGroup); + checkIfDroidIsStuck(harvesterGroup); + +} +//----------------------------------------------------------------- +event shutDownAI(inactive) +{ + + //check if all enemies are dead + count = 0; + boolResult = true; + boolResult2 = false; + + while ( count < MAX_PLAYERS and boolResult ){ + if ( !friendlyPlayer(count) ){ + if ( isPlayerStillLive(count) ){ + boolResult = false; + } + } + count++; + } + //then check if this AI is dead + if ( !isPlayerStillLive(player) ){ + boolResult2 = true; + printDebug(" ________shutting down this AI: game lost______"); + } + if ( boolResult ){ + printDebug(" _________shutting down this AI: game won_______"); + } + + //check if this player is dead... + if ( boolResult or boolResult2 ){ + + //dbg("__________SHUT DOWN AI #("& player &") '"& getPlayerName(player) &")' ("& boolResult &")("& boolResult2 &")_________",player); + + shutDownThisAI(); + + } //else { displayMsg("__________("& anyDroidsLeft(player) &")("& _nFact &")("& _nCybFact &")_________"); } + + +} + +//---------------------------------------------------- +function void activateAI() +{ + local string strMessage; + //activate all events!! + setEventTrigger(droidBuilt, droidBuiltTr); + setEventTrigger(AIattacked, AIattackedTr); + setEventTrigger(vtolDefend, vtolDefendTr); + //setEventTrigger(consoleEv, inactive); + setEventTrigger(multiMsgEv, multiMsgTr); + setEventTrigger(beaconEv, beaconTr); + setEventTrigger(reassignPlayers, reassignPlayersTr); + + + setEventTrigger(evDebug, evDebugTr); + setEventTrigger(AIbrain, AIbrainTr); + setEventTrigger(buildBase, buildBaseTr); + setEventTrigger(buildPowerGenerators, buildPowerGeneratorsTr); + setEventTrigger(buildRepFacSuppAttack, buildRepFacSuppAttackTr); + setEventTrigger(buildRepFirst, buildRepFirstTr); + setEventTrigger(defendBase, defendBaseTr); + setEventTrigger(defendDerrick, defendDerrickTr); + setEventTrigger(defendGatewaysPoint, defendGatewaysPointTr); + setEventTrigger(difficultyModifier, difficultyModifierTr); + setEventTrigger(buildAAdef, buildAAdefTr); + setEventTrigger(doResearch, doResearchTr); + setEventTrigger(manageDefCyborgs, manageDefCyborgsTr); + setEventTrigger(manageDefTank, manageDefTankTr); + setEventTrigger(activateAttack, activateAttackTr); + setEventTrigger(manageIdleTrucks, manageIdleTrucksTr); + setEventTrigger(manageRepairTeam, manageRepairTeamTr); + setEventTrigger(SelectCyborgTemplate, SelectCyborgTemplateTr); + setEventTrigger(SelectTankTemplate, SelectTankTemplateTr); + setEventTrigger(sendBackDamagedUnits, sendBackDamagedUnitsTr); + setEventTrigger(showPlayerInfo, showPlayerInfoTr); + setEventTrigger(truckGroupSlider, truckGroupSliderTr); + setEventTrigger(unitAssignationCheck, unitAssignationCheckTr); + setEventTrigger(unitRepairSwitch, unitRepairSwitchTr); + setEventTrigger(updateBaseDetails, updateBaseDetailsTr); + setEventTrigger(upgradeStructures, upgradeStructuresTr); + setEventTrigger(useLassat, useLassatTr); + setEventTrigger(vtolEnabler, vtolEnablerTr); + setEventTrigger(multiMsgEv, multiMsgTr); + setEventTrigger(beaconEv, beaconTr); + setEventTrigger(shutDownAI, shutDownAITr); + setEventTrigger(evPrintDebug, evPrintDebugTr); + setEventTrigger(harvesterOperate,harvesterOperateTr); + setEventTrigger(AIcheck,AIcheckTr); + setEventTrigger(threatCheck,threatCheckTr); + setEventTrigger(VTOLhunter,VTOLhunterTr); + setEventTrigger(buildArtillery,buildArtilleryTr); + setEventTrigger(buildRippleRockets,buildRippleRocketsTr); + tFinishOilHack = gameTime; + + + +} +//================================================================ +//this event checks that most important events are not stucked +event AIcheck (inactive) //event 3 +{ + local string errorMSG, errorMSG2, errorMSG3, errorMSG4; + local int tTimeGone; + + if ( gameTime-tFinishOilHack < 100 ) {exit;}//harvestoperate would generate an error + + + errorMSG = "An error occurred on the Dydo-AI script player ("& player &"), this error message will appear only 4 times"; + errorMSG2 = "Please report the below DEBUG REPORT to http://forums.wz2100.net/ or on the AI webpage http://www.obooma.net/dydo/"; + errorMSG3 = "DEBUG REPORT: "; + + //TEST + + count=0; + while (count < EVENT_CHECK_NUMBER){ + tTimeGone = (gameTime - eventCheckTime[count]); + if ( tTimeGone > eventCheckTrigger[count] ){ + if (eventCheckCounter[count] < 4){ + nAIcheck++; + eventCheckCounter[count] = eventCheckCounter[count] + 1; + eventCheckReport[count] = eventCheckReport[count] + 1; + errorMSG3 = errorMSG3 & " event:"& count &"["& eventCheckTime[count] &"] time gone:("& tTimeGone &") should be("& eventCheckTrigger[count] &") "; + } + } else { + if (eventCheckReport[count] > 0){ + eventCheckReport[count] = 0; + eventCheckCounter[count] = 0; + } + } + count++; + } + + + count=0; + while (count < EVENT_CHECK_NUMBER){ + if ( eventCheckReport[count] > 0 and eventCheckCounter[count] < 4 and (gameTime - lastDisplayAIcheck) > 50 ){ + //dbg(errorMSG,player); + //dbg(errorMSG2,player); + //dbg(errorMSG3,player); + printDebug1( "######## AIcheck: " & errorMSG3 ); + lastDisplayAIcheck = gameTime; + //reactivateEvent + //if( count == 7 ){ + //setEventTrigger(manageIdleTrucks, manageIdleTrucksTr); + //displayErrMsg("DyDo will try try to reactivate event # 7 ---- DEBUG: (" & count & ")["& eventCheckReport[count] &"] " ); + //} + } + count++; + } + + //DEBUG MESSAGE + if ( gameTime - lastDisplayAIcheck >= 600 ){ + //dbg("dbg->AIcheck: player ("& getPlayerName(player) &") gameTime ("& gameTime &") nAIcheck ("& nAIcheck &") ",player); + lastDisplayAIcheck = gameTime; + } + +} +//----------------------------------------------------------------- +event showAImessage(wait,60) { + //let human player know he is playing with DyDo-AI mod + local string strMessage; + local bool bWebSite; + + count = 0; + while(count < MAX_PLAYERS) + { + + if ( isHumanPlayer(count) and count != player ){ + if (showAIPersonality){ + if(allianceExistsBetween(count,player)){ + strMessage = "player " & player & " " & DYDOBP_RELEASE & " General " & AIPersonality &" Level ["& AIstrength &"] (Ally)"; + } else { + strMessage = "player " & player & " " & DYDOBP_RELEASE & " General " & AIPersonality &" Level ["& AIstrength &"] (Enemy)" ; + } + } else { + strMessage = DYDOBP_RELEASE & " is active"; + } + msg( strMessage, player, count ); + } + count++; + } + setEventTrigger(showAImessage, showAImessageTr); +} +//----------------------------------------------------------------- + // find my lassat + // fire it at my attack objective. +event useLassat(inactive) +{ + + local BASEOBJ _targetStruct; + local int _loop,_pos,_xCoord,_yCoord,_targetPl,_rnd,_nTargets; + local bool _mustBeHuman; + local STRUCTURESTAT _aTargets[7]; + + eventCheckTime[0] = gameTime; + + _nTargets = 7; + _aTargets[0] = powGen; + _aTargets[1] = factory; + _aTargets[2] = cybFactory; + _aTargets[3] = vtolFactory; + _aTargets[4] = lassat; + _aTargets[5] = playerHQ; + _aTargets[6] = uplinkCenter; + + _targetPl = -1; + _targetStruct = NULLOBJECT; + + if ( !isStructureAvailable(lassat,player) ){ + exit; + } + + if ( AIstrength > 3 and bHasHumanEnemies(player) ){ + _mustBeHuman = true; + } else { + _mustBeHuman = false; + } + + + //find the nearest enemy player + _targetPl = getNearestEnemyPlayer(_mustBeHuman); + if (_targetPl < 0 ){ + _targetPl = getRandomEnemyPlayer(_mustBeHuman);//be sure we have a target player + } + + if ( _targetPl < 0 ){ + //dbg("dbg->useLassat: _targetPl < 0 ("& _mustBeHuman &")",player); + printDebug1("#### useLassat: _targetPl < 0 ("& _mustBeHuman &")"); + exit; + } + //get a target struct + _pos = random(_nTargets); + _loop = 0; + while( _loop < _nTargets and _targetStruct == NULLOBJECT) + { + if ( AIstrength < 4 ){ + initEnumStruct(false, _aTargets[_pos], _targetPl, player);//get only visible enemy structs + } else { + initEnumStruct(false, _aTargets[_pos], _targetPl, _targetPl);//get also enemy structs not visible to player + } + _targetStruct = enumStruct(); + _loop++; + _pos++; + if ( _pos == _nTargets ){ _pos = 0; } + } + + //target found!! + boolResult=false; + if(_targetStruct != NULLOBJECT) + { + printDebug1("useLassat: target found !! _targetPl("& getPlayerName(_targetPl) &") _pos("& _pos &")"); + initEnumStruct(FALSE,lassat,player,player); + structure = enumStruct(); + while(structure != NULLOBJECT) + { + if( structureComplete(structure) ) + { + //dbg("dbg->useLassat: Lassat ("& structure.id &") fires to ("& _targetStruct.id &") player ("& getPlayerName(_targetStruct.player) &") ",player); + printDebug1("Lassat ("& structure.id &") fires to struct.id ("& _targetStruct.id &") player ("& getPlayerName(_targetStruct.player) &") "); + skFireLassat(player,_targetStruct); + boolResult = true; + } + structure= enumStruct(); + } + } else { + //dbg("dbg->useLassat: No target found, _targetPl("& getPlayerName(_targetPl) &")",player); + printDebug1("useLassat: No target found, _targetPl("& getPlayerName(_targetPl) &") _loop("& _loop &")"); + } + + if ( !boolResult ){ + //dbg("dbg->useLassat: Lassat hasn`t fire",player); + printDebug1("useLassat: Lassat hasn`t fired "); + } + +} +//================================================================ +/* +add lStopBuildOilDef and check whenoilRes == 0 -> lStopBuildOilDef = false +defendGatewaysPoint: buildDefGroup - defend gateways +defendBase: buildGroup/harvestGrpoup - defend base +defendDerrick buildGroup/dbuildDefGroup/harvestGrpoup def derrick +*/ +event AIbrain (inactive) +{ + + local string _sWallDef, _sDef; + local BASEOBJ _attackObj; + local int _nMaxCybEngineers, _nMaxTrucks, enemy, nMyUnits ,nEnemyUnits, _player; + + //if ( gameTime - tProd1 > 600 ){ + //addPower(500, player); + //tProd1 = gameTime; + //} + + eventCheckTime[1] = gameTime; + + //hack to put all at same power when debugging + if ( isHumanPlayer(player) and !bPowerNormalized ){ + bPowerNormalized = true; + count = playerPower(player); + if ( player == 0 ){ count1 = playerPower(1); } else { count1 = playerPower(0); } + count2 = count1 - count; + if ( count2 > 300 ){ + addPower(500,player); + printDebug1(" added 500 power to player #"& player &"-"& getPlayerName(player) &", starting was power("& count &") instead of power("& count1 &")"); + //displayMsg(" added 500 power to player #"& player &"-"& getPlayerName(player) &", starting was power("& count &") instead of power("& count1 &")"); + } else { + printDebug1(" No need to add 500 power to player #"& player &"-"& getPlayerName(player) &", starting was power("& count &") instead of power("& count1 &")"); + } + } + + ASSERT(player >= 0 and player < 8, "player out of bounds: AIbrain " & player, player); + + //reset alert + if (gameTime - alertTime > TIME_TO_RESET_ALERT){ + alertIsOn = false; + alertX = -1; + alertY = -1; + alertTime = -1; + alertLevel= ALERT_INACTIVE; + } + + + nTotTanks = tankGroup.members+tankDefGroup.members+toBeRepairedTankGroup.members+helpGroup.members; + nTotCyborgs = cyborgDefGroup.members + cyborgAttGroup.members + toBeRepairedCyborgGroup.members; + nMyDerricks = getNumDerricks(player); + nPower = playerPower(player); + nFactories = numStructsByType(factory, player); + nVTOLFactories = numStructsByType(vtolFactory, player); + nResLabs = numStructsByType(resLab, player); + nCybFact = numStructsByType(cybFactory, player); + nWorkingVTOLFac = getNumStructNotIdle(vtolFactory); + nWorkingFact = getNumStructNotIdle(factory); + nWorkingLab = getNumStructNotIdle(resLab); + nWorkingCybFac = getNumStructNotIdle(cybFactory); + //nTotBaseDefences = numFriendlyWeapStructsInRange(player, baseX, baseY, nBaseRange+RANGETILES_DEFSTR_AROUNDBASE*TILE , false); + nFreeOilRes = numRemainingOilRes(); + bOilResLeft = bAnyOilResLeft(); + //nTotDerricks = getTotDerricksMap();//nTotOilInAtStart + //update power levels + + //check how many tanks are in tankDefGroup + nTanksDefGrp=0; + if( gameTime - lastDisplayAI >= 90 and tankDefGroup.members > 0 ){ + initIterateGroup(tankDefGroup); + droid = iterateGroup(tankDefGroup); + while(droid != NULLOBJECT) + { + //dbg("dbg->assignDroidToGrp: droid ("& droid.id &") ("& droid.y/TILE &")("& droid.y/TILE &") found a droid with no group ("& droid.id &"), force assign to tankdefGroup",player); + if(droid.droidType == DROID_WEAPON and droid.propulsion != cyborgPropulsion) + { + nTanksDefGrp++; + } + droid = iterateGroup(tankDefGroup); + } + } + + if ( aPower[VERY_LOW_POWER] < 400 and researchFinished(cobraBody, player) and researchFinished(mediumCannon,player) ){ + //displayMsg("AIbrain: ______________ SWITCH POWER to level 2 ___________"); + aPower[VERY_LOW_POWER] = 400; + aPower[LOW_POWER] = 700; + aPower[HIGH_POWER] = 1100; + } + if ( aPower[VERY_LOW_POWER] < 500 and researchFinished(trackPropulsion, player) ){ + //displayMsg("AIbrain: ______________ SWITCH POWER to level 3 ___________"); + aPower[VERY_LOW_POWER] = 500; + aPower[LOW_POWER] = 800; + aPower[HIGH_POWER] = 1200; + } + + //reactivate all (but the fact upgrades!!!) + lStopTankProduction = false; + lStopBuildTankProd = false; + lStopCybEngProd = false; + lStopCybProduction = false; + lStopFactUpgrade = true; + lStopFactUpgrade2 = true; + lStopResearch = false; + lStopCheapResearch = false; + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildDefGateway = false; + lStopBuildRepFacility = false; + lStopBuildingStructures = false; + lStopResLabUpgrade = false; + lStopVTOLProduction = false; + lStopVTOLFactBuilding = false; + + + if (nFactories >= structsBuildLimits[nAI_Pers][STR_TANK_FACTORY] and nResLabs >= structsBuildLimits[nAI_Pers][STR_RESLAB] and nCybFact >= structsBuildLimits[nAI_Pers][STR_CYB_FACTORY] ){ + lMinBaseStructBuilt = true; + } else { + lMinBaseStructBuilt = false; + } + + + + if ( gameTime - tLastPowerSwitch > TIME_SWITCH_WORKSTRUCT ){ + tLastPowerSwitch = gameTime; + nProdSelect++; + if (nProdSelect == 8){ nProdSelect = 0; } + } + + if ( nPower < 100 )//=========== VERY LOW POWER ============================= + { + lStopTankProduction = true; + lStopCybProduction = true; + lStopResearch = true; + lStopCheapResearch = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildDefGateway = true; + //lStopBuildRepFacility = true; + lStopBuildingStructures = true; + lStopVTOLProduction = true; + lStopVTOLFactBuilding = true; + + } + else if ( nPower >= 100 and nPower < aPower[VERY_LOW_POWER] ) + { + + if ( AIPersonality == AI_STANDARD ){ + manageVeryLowPower(); + } + if ( AIPersonality == AI_VTOL ){ + manageVeryLowPower2(); + } + if ( AIPersonality == AI_TURTLE ){ + manageVeryLowPower3(); + } + if ( AIPersonality == AI_CYBORG ){ + manageVeryLowPower4(); + } + + //always block with this power level + //lStopBuildDefGateway = true; + //lStopVTOLFactBuilding = true; + //lStopBuildingStructures = true;//activated if not min struct reached + + } //================== POWER END ============================== + + //do not build too many VTOLs + if ( vtolDefendGr.members > 6 ){ + if ( (float)(vtolDefendGr.members) > (float)(nTotTanks + nTotCyborgs) * 0.33 ){ + lStopVTOLProduction = true; + } + } + + count = 0; + count2 = 0; + while ( count < numCheapRes[0] ){ + if ( researchFinished(researchCheap[0][count], player) ){ + count2++; + } + count++; + } + if ( count2 == numCheapRes[0] ){ lStopCheapResearch = true; } + //try to minimize the spending of money for researches + //if ( nWorkingLab >= 2 ){ lStopCheapResearch = true; } + + //resLab upgrade + if (!lMinBaseStructBuilt and gameTime < 8*TIME_MINUTE){ + lStopResLabUpgrade = true; + } + + //repair Facility + if( gameTime < VALID_TIME_REPAIRFAC or numStructsByType(repairFacility, player) >= MAX_REPAIRFAC) + { lStopBuildRepFacility = true; } + + if( gameTime < 20*TIME_MINUTE and numStructsByType(repairFacility, player) > 2 ) + { lStopBuildRepFacility = true; } + + if( gameTime < 30*TIME_MINUTE and numStructsByType(repairFacility, player) > 3 ) + { lStopBuildRepFacility = true; } + + if ( gameTime - nLastTimeBuiltRepFac < 2*TIME_MINUTE ) + { lStopBuildRepFacility = true; } + + //build def only when enough structs have been built!! + if ( !lMinBaseStructBuilt and gameTime < TIME_HARVESTING_PHASE){ + lStopBuildDef = true; + lStopBuildDefGateway = true; + lStopBuildRepFacility = true; + lStopVTOLFactBuilding = true; + lStopVTOLProduction = true; + } + + + //start building gateway def a bit later + if ( gameTime < VALID_TIME_GATEWAYDEF) + {lStopBuildDefGateway = true;} + + //defend only on alert points!! + if ( defSpotX <= 0 ) + {lStopBuildDef = true;} + + //have been attacked and have no troups remaining + if ( gameTime > 12*TIME_MINUTE and (nTotCyborgs+nTotTanks) < MIN_TOT_UNITS )//============================== + { + + if ( nPower > 100 ){ + if (AIPersonality == AI_CYBORG ){ + lStopCybProduction = false; + if ( nWorkingFact >= 1){lStopTankProduction = true; } + } else { + lStopTankProduction = false; + lStopCybProduction = false; + } + } + + count = numTemplatesInProduction(cybcondroid, player); + count = count + numTemplatesInProduction(constructor, player); + count = count + numTemplatesInProduction(constructor2, player); + if ( count + cyborgConstructGroup.members + buildGroup.members + harvesterGroup.members + buildDefGroup.members >= 2 ) { + //I am in trouble need tanks not trucks!!! + lStopBuildTankProd = true; + lStopCybEngProd = true; + } + + if ( nPower < aPower[LOW_POWER] ){ + lStopResearch = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildDefGateway = true; + lStopBuildRepFacility = true; + lStopBuildingStructures = true; + lStopCheapResearch = true; + lStopResLabUpgrade = true; + lStopVTOLProduction = true; + lStopVTOLFactBuilding = true; + } + + } else { // ======================= ACTIVATE EVENTS ========================= + + //activate more tanks and cyb engineers if AA def are required + if ( !lMinBaseStructBuilt ){ + _nMaxTrucks = MIN_BUILDING_TANKS+1; + _nMaxCybEngineers = MIN_CYB_CONSTENG+1; + } else { + _nMaxTrucks = MIN_BUILDING_TANKS; + _nMaxCybEngineers = MIN_CYB_CONSTENG; + } + + + //Trucks & cybEng + if ( buildGroup.members + harvesterGroup.members + buildDefGroup.members < _nMaxTrucks){ + if ( nPower > 100 ){ lStopBuildTankProd = false;} + } else { + lStopBuildTankProd = true; + } + if ( cyborgConstructGroup.members + numTemplatesInProduction(cybcondroid, player) < _nMaxCybEngineers){ + if ( nPower > 100 and gameTime > TIME_HARVESTING_PHASE ){ lStopCybEngProd = false; } + } else { + lStopCybEngProd = true; + } + + //At least one research every 4 min + if( gameTime - tLastResearch > 4*TIME_MINUTE ) + { lStopResearch = false; } + + //upgrades + if ( lMinBaseStructBuilt ) { + if ( researchFinished(cobraBody, player) or researchFinished(hoverPropulsion, player) ) + { lStopFactUpgrade = false; } + if ( researchFinished(trackPropulsion, player) or researchFinished(phytonBody, player) ) + { lStopFactUpgrade2 = false; } + } + + //activate building of structs + if ( !lMinBaseStructBuilt ) + { lStopBuildingStructures = false; } + + } + + if ( AIPersonality == AI_TURTLE ){ + if ( gameTime - tLastbuildBaseDef > (TIME_TOFORCE_BUILDDEF_2) ) + { + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildDefGateway = false; + } + } else { + if ( gameTime - tLastbuildBaseDef > TIME_TOFORCE_BUILDDEF ) + { + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildDefGateway = false; + } + } + + //stop all for 2 minutes long but droids production + if ( bFinalAttack_1vs1 and gameTime-tLastFinalAttack < 2*TIME_MINUTE ){ + lStopTankProduction = false; + lStopCybProduction = false; + if (nPower < aPower[VERY_LOW_POWER]){ + lStopBuildTankProd = true; + lStopResearch = true; + lStopCheapResearch = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildDefGateway = true; + lStopBuildRepFacility = true; + lStopBuildingStructures = true; + lStopResLabUpgrade = true; + lStopVTOLProduction = true; + lStopVTOLFactBuilding = true; + } + nDamageLevelRepair = DAMAGE_REPAIR_LEVEL_LOW; + } else { + nDamageLevelRepair = DAMAGE_REPAIR_LEVEL; + } + + + //power superiority check in 1vs1 games + bForceResPowUp = false; + if ( nEnemyPlayers == 1 and gameTime > 15*TIME_MINUTE ){ + if ( getPowerIndex( nLastEnemyPlayer ) >= getPowerIndex( player ) ){ //human player has more or higher power index + if ( nMyDerricks >= getNumDerricks(nLastEnemyPlayer) ){ //derricks are fine + bForceResPowUp = true;//force research of power + lStopResearch = false; + } + } + } + + //checking power in all type of games + _player=0; + while( _player < MAX_PLAYERS and gameTime > 15*TIME_MINUTE ){ + if (isPlayerStillLive(_player)){ + if ( getPowerIndex( _player ) > getPowerIndex( player ) ){ //human player has higher power index + if ( nMyDerricks >= getNumDerricks(_player) ){ //derricks are fine + bForceResPowUp = true;//force research of power + lStopResearch = false; + } + } + } + _player++; + } + + //droid production guarantee + if (!bTankAttIsOn and AIPersonality == AI_STANDARD or AIPersonality == AI_TURTLE ){ + if ( nTanksDefGrp < 12 ){ + if ( nTanksDefGrp < 8 ){ + if ( nWorkingFact < 2 ){lStopTankProduction = false; } + } else { + if ( nWorkingFact < 1 ){lStopTankProduction = false; } + } + } + } + + if (!bCybAttIsOn and AIPersonality == AI_CYBORG ){ + if ( nTotCyborgs < 20 ){ + if ( nTotCyborgs < 12 ){ + if ( nWorkingCybFac < 2 ){lStopCybProduction = false; } + } else { + if ( nWorkingCybFac < 1 ){lStopCybProduction = false; } + } + } + } + + if (AIPersonality == AI_VTOL){ + if ( vtolDefendGr.members + vtolAttGr.members < 10 ){ + if ( vtolDefendGr.members + vtolAttGr.members < 5 ){ + if ( nWorkingVTOLFac < 2 ){lStopVTOLProduction = false; } + } else { + if ( nWorkingVTOLFac < 1 ){lStopVTOLProduction = false; } + } + } + } else { + if ( vtolDefendGr.members + vtolAttGr.members < 3 ){ + if ( nWorkingVTOLFac == 0 ){lStopVTOLProduction = false; } + if ( nWorkingVTOLFac > 1 ){lStopVTOLProduction = true; } + } + } + if (!bCybAttIsOn and AIPersonality == AI_STANDARD or AIPersonality == AI_TURTLE ){ + if ( nTotCyborgs < 12 ){ + if ( nTotCyborgs < 8 ){ + if ( nWorkingCybFac < 2 ){lStopCybProduction = false; } + } else { + if ( nWorkingCybFac < 1 ){lStopCybProduction = false; } + } + } + } + + //Research guarantee + if ( nTotTanks+nTotCyborgs > 16 ){ + if ( nWorkingLab < 2 ){lStopResearch = false; } + } + + numAAinBase = numAAinRange(player, player, baseX, baseY, nBaseRange ); + if ( numAAinBase < 5 and bAttackedByVTOL ) { + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildDefGateway = true; + } + + //attack guarantee + /* + if ( tLastCyborgAttack > tLastTankAttack ){ + nTime = tLastCyborgAttack; + } else { + nTime = tLastTankAttack; + } + if ( gameTime - nTime > nAttackTime and nTotTanks+nTotCyborgs < 25 ){ + lStopCybProduction = false; + lStopTankProduction = false; + lStopBuildTankProd = false; + if (nPower < aPower[VERY_LOW_POWER]){ + if (AIPersonality != AI_CYBORG ){ + lStopResearch = true; + } + lStopCheapResearch = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildDefGateway = true; + lStopBuildRepFacility = true; + lStopBuildingStructures = true; + lStopResLabUpgrade = true; + lStopVTOLProduction = true; + lStopVTOLFactBuilding = true; + } + } + */ + + if ( gameTime - lastDisplayAI >= 110 ){ + //displayMsg("Structs not idle: nProdSelect("& nProdSelect &") (Fac-Cyb-Res-VTOLfac) ("& nWorkingFact &"-"& nWorkingCybFac &"-"& nWorkingLab &"-"& nWorkingVTOLFac &") power["& playerPower(player) &"] Low Power("& aPower[VERY_LOW_POWER] &") tot Tank+Cyb("& nTotTanks+nTotCyborgs &") nTanksDefGrp("& nTanksDefGrp &") "); + //displayMsg("Stops: (Fac-Cyb-VTOLfac-Res-CheapRes__DefBase-DefDerr-Gateways) ("& lStopTankProduction &"-"& lStopCybProduction &"-"& lStopVTOLProduction &"-"& lStopResearch &"-"& lStopCheapResearch &"__"& lStopBuildDef &"-"& lStopBuildDefDerricks &"-"& lStopBuildDefGateway &") nAttackTime("& gameTime-nTime &"/"& nAttackTime &")" ); + lastDisplayAI = gameTime; + } + + tAIbrain = gameTime; +} +/*====================================================================== + VTOL STUFF +========================================================================*/ +event vtolEnabler(inactive) +{ + ASSERT(player >= 0 and player < 8, "player out of bounds: vtolEnabler " & player, player); + dbg("vtolEnabler: __________ ("& skVtolEnableCheck(0) &") 1("& skVtolEnableCheck(1) &") 7("& skVtolEnableCheck(7) &")__________",player); + + if( skVtolEnableCheck(player) ) // check to see if we have vtol technologies. + { + //displayMsg("vtolEnabler 1: enabling all VTOL EVENTS "); + setEventTrigger(vtolStructs,vtolStructsTr); // activate other vtol functions.. + setEventTrigger(buildVtols, buildVtolsTr); + setEventTrigger(manageDefVTOL, manageDefVTOLTr); + //setEventTrigger(buildAAdef, buildAAdefTr); + //setEventTrigger(vtolAttack, vtolAttackTr); + setEventTrigger(vtolEnabler,inactive); // turn off this event. + //dbg("----I CAN USE VTOLS----", me); + } + +} +//-------------------------------------------------------------------- +event defFromLongRangeWeap(inactive) +{ + local int _nCBSense,_nMortar,_nBombard,_nPepperpot,_nRippleRocket; + + /* + if( !aiResponsibleForPlayer(player) ) + { + setEventTrigger(defFromLongRangeWeap, inactive); + } + else + { + */ + if ( nKineticX < 0 or nKineticY < 0 ) { + setEventTrigger(defFromLongRangeWeap, inactive); + exit; + } + + //dbg("dbg->defFromLongRangeWeap: Activated attacked in coord ("& nKineticX/TILE &"-"& nKineticY/TILE &")",player); + //check if CB tower has been build in range of myattacked object + //alertX&Y are based on enemyBaseObj + _nCBSense = numStructinRange(CBSense, player, nKineticX, nKineticY, 6*TILE); + _nMortar = numStructinRange(defMortar, player, nKineticX, nKineticY, 6*TILE); + _nBombard = numStructinRange(defBombard, player, nKineticX, nKineticY, 6*TILE); + _nPepperpot = numStructinRange(defPepperpot, player, nKineticX, nKineticY, 6*TILE); + _nRippleRocket = numStructinRange(defRippleRockets, player, nKineticX, nKineticY, 6*TILE); + + droid = closestDroidCanBuild(buildDefGroup,nKineticX,nKineticY); + if ( droid == NULLOBJECT ){ + droid = closestIdleDroid(buildGroup,buildX,buildY); + } + if( droid == NULLOBJECT ){ exit; } + + //dbg("dbg->defFromLongRangeWeap, build("& buildX/TILE &"-"& buildY/TILE &") alert("& alertX/TILE &"-"& alertY/TILE &") attacked in ("& nKineticX/TILE &"-"& nKineticY/TILE &")",player); + buildX = nKineticX; + buildY = nKineticY; + + if (bAttackedByMortars){ + //CB Sense + if ( isStructureAvailable(CBSense,player) ){ + if ( _nCBSense == 0 ){ + if( pickStructLocation(CBSense, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building CB Sense in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,CBSense,buildX,buildY); + } + } + } + } + + //Defences + if ( isStructureAvailable(defRippleRockets,player) ){ + if( _nRippleRocket < 1 ){ + if( pickStructLocation(defRippleRockets, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building CB Sense in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,defRippleRockets,buildX,buildY); + } + } + } + } else if ( isStructureAvailable(defPepperpot,player) ) { + if( _nPepperpot < 2 ){ + if( pickStructLocation(defPepperpot, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building Pepperpot Pit in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,defPepperpot,buildX,buildY); + } + } + } + } else if ( isStructureAvailable(defBombard,player) ) { + if( _nBombard < 3 ){ + if( pickStructLocation(defBombard, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building Bombard Pit in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,defBombard,buildX,buildY); + } + } + } + } else if ( isStructureAvailable(defMortar,player) ) { + if( _nMortar < 3 ){ + if( pickStructLocation(defMortar, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building Mortar Pit in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,defMortar,buildX,buildY); + } + } + } + } + + //dbg("dbg->defFromLongRangeWeap, attacked by mortars CBSense("& _nCBSense &") mortar("& _nMortar &") Bombard("& _nBombard &") Pepp("& _nPepperpot &")",player); + } + if (bAttackedByLongRangeWeap){ + + //CB sense + if ( isStructureAvailable(CBSense,player) ){ + if ( _nCBSense == 0 ){ + if( pickStructLocation(CBSense, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building CB Sense in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,CBSense,buildX,buildY); + } + } + } + } + //defense + if ( isStructureAvailable(defRippleRockets,player) ){ + if( _nRippleRocket < 1 ){ + if( pickStructLocation(defRippleRockets, ref buildX, ref buildY, player ) ){ + if ( droidCanReach(droid, buildX, buildY) ){ + //dbg("dbg->defFromLongRangeWeap, building Ripple Rockets in ("& buildX/TILE &"-"& buildY/TILE &") ",player); + orderDroidStatsLoc(droid, DORDER_BUILD,defRippleRockets,buildX,buildY); + } + } + } + } + + //dbg("dbg->defFromLongRangeWeap, attacked by mortars CBSense("& _nCBSense &") mortar("& _nMortar &") Bombard("& _nBombard &") Pepp("& _nPepperpot &")",player); + } + + setEventTrigger(defFromLongRangeWeap, inactive); + //} +} + +//-------------------------------------------------------------------- +event buildAAdef(inactive) +{ + local int _numAAdefInRange, _rnd; + + if (!researchFinished(HurricaneAASite,player)){ exit; } + + dbg("buildAAdef: __________ ("& lMinBaseStructBuilt &")("& numAAinBase &") attbyVTOL("& bAttackedByVTOL &") time ("& gameTime - tLastAAbuilt&") < 300",player); + + if ( numAAinBase >= MIN_AA_INBASERANGE or (!lMinBaseStructBuilt and gameTime < 8*TIME_MINUTE) ) { exit; }//do not set to inactive because AA def can be destroyed!! + if ( numAAinBase >= 2 and !bAttackedByVTOL ) { exit; }//do not set to inactive because AA def can be destroyed!! + if ( gameTime - tLastAAbuilt < 300 ){ exit; } + + //pick up the position + nAAPos++; + if ( nAAPos > 3 ){ nAAPos = 0; } + if ( nAAPos == 0 ){ buildX = baseX+(5*TILE); buildY = baseY+(5*TILE); } + if ( nAAPos == 1 ){ buildX = baseX+(5*TILE); buildY = baseY-(5*TILE); } + if ( nAAPos == 2 ){ buildX = baseX-(5*TILE); buildY = baseY+(5*TILE); } + if ( nAAPos == 3 ){ buildX = baseX-(5*TILE); buildY = baseY-(5*TILE); } + + if ( numAAinBase < 2 ){ + buildX = baseX; + buildX = baseY; + } + if ( numAAinBase == 6 ){ + buildX = baseX; + buildX = baseY; + } + + droid = closestDroidCanBuild(buildDefGroup,buildX,buildY); + if (droid == NULLOBJECT){ + droid = closestIdleDroid(buildGroup,buildX, buildY); + } + + + // build AA defenses. + if ( droid == NULLOBJECT ){ + displayMsg("buildAAdef: No idle truck found"); + exit; + } + displayMsg("buildAAdef: truck found"); + + + //find best defense we can build. + count = 0; + count2 = -1; + while( count < numGenAA) + { + if(isStructureAvailable(vtolGenStruct[count],player)) + { count2 = count; } + count = count + 1; + } + if(count2 >= 0 ){ + boolResult = pickStructLocation(vtolGenStruct[count2], ref buildX, ref buildY,player); + if(boolResult and droidCanReach(droid, buildX ,buildY) ) // build a vtol defense near the attacked struct... + { + displayMsg("buildAAdef: droid ("& droid.id &")build AA def ["& count2 &"] at ("& buildX/TILE &"-"& buildY/TILE &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,vtolGenStruct[count2],buildX,buildY); + tLastAAbuilt = gameTime; + } + } else { displayMsg("buildAAdef: No AA def struc found"); } + +} + +//---------------------------------------------- +event vtolDefend(vtolDefendTr)//(CALL_STRUCT_ATTACKED, player, ref structure, ref enemyBaseObject) +{ + local int _numAAdefInRange,_dist; + + if(enemyBaseObject != NULLOBJECT) + { + if(enemyBaseObject.type == OBJ_DROID) + { + if( isVtol( objToDroid(enemyBaseObject) ) ) + { + + bAttackedByVTOL = true;//force research of AA defences + if ( structure != NULLOBJECT ){ + _dist = distBetweenTwoPoints( structure.x, structure.y, baseX, baseY); + } else { + _dist = distBetweenTwoPoints( enemyBaseObject.x, enemyBaseObject.y, baseX, baseY); + } + + if ( _dist/TILE > (nDefendRange/TILE) * 3 and _dist > nBaseRange){ + //dbg("dbg->vtolDefend: cannot build AA def as the palce is too far away _dist > 3*nDefendRange ("& _dist/TILE &" > "& (nDefendRange/TILE)*3 &") ",player); + exit; + } + + droid = closestDroidCanBuild(buildDefGroup,baseX,baseY); + if (droid == NULLOBJECT){ + droid = closestIdleDroid(buildGroup, baseX, baseY); + } + + // build AA defenses. + if ( droid != NULLOBJECT ){ + if( structure != NULLOBJECT ) { + //if no AA at all in AAdefRange or enough power + _numAAdefInRange = numAAinRange(player, player, structure.x, structure.y, RANGE_BUILD_AADEF ); + if ( playerPower(player) > 100 or random(10) > 4 ){ + if ( _numAAdefInRange < MAX_AADEF_INRANGE ){ + buildX = structure.x; + buildY = structure.y; + + //find best defense we can build. + count = 0; + count2 = -1; + while( count < numGenAA) + { + if(isStructureAvailable(vtolGenStruct[count],player)){ + count2 = count; + } + count = count + 1; + } + if( count2 >= 0 ){ + boolResult = pickStructLocation(vtolGenStruct[count2], ref buildX, ref buildY, player); + if( boolResult and droidCanReach(droid, buildX ,buildY) ) // build a vtol defense near the attacked struct... + { + dbg("dbg->vtolDefend: build AA def ["& count2 &"] at ("& buildX/TILE &"-"& buildY/TILE &"), tot AA in struct range ("& _numAAdefInRange &") _dist("& _dist/TILE &")",player); + printDebug1("vtolDefend: build AA def ["& count2 &"] at ("& buildX/TILE &"-"& buildY/TILE &"), tot AA in struct range ("& _numAAdefInRange &") _dist("& _dist/TILE &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,vtolGenStruct[count2],buildX,buildY); + tLastAAbuilt = gameTime; + } + } //else { dbg("dbg->vtolDefend: no AA defense found",player); } + } //else { dbg("dbg->vtolDefend: cannt build AA def _numAAdefInRange/max("& _numAAdefInRange &"/"& MAX_AADEF_INRANGE &") power("& playerPower(player) &")",player); } + } //else { dbg("dbg->vtolDefend: not enough power ("& playerPower(player) &") to build AA def _dist ("& _dist/TILE &")",player); } + } //else { dbg("dbg->vtolDefend: structure attacked is NULLOBJECT",player); } + } //else { dbg("dbg->vtolDefend: idle droid not found",player); } + } + } + } +} + +// ------------------ build VTOL structs ----------------------- +event vtolStructs(inactive) +{ + local int _totalVTOLS; + local int _numVtolFacs,_numRearmPads; + + ASSERT(player >= 0 and player < 8, "player out of bounds: vtolStructs " & player, player); + //displayMsg("vtolStructs: vtolStructs event called"); + + if( !isStructureAvailable(vtolFactory,player) ){ + exit; + } + + // see how many vtol factories we already have + _numVtolFacs = nVTOLFactories; + _numRearmPads = numStructsByType(vtolPad, player); + _totalVTOLS = vtolDefendGr.members + vtolAttGr.members; + + //see if we have enough rearm pads + if( (float)(_numRearmPads * (4 / 3)) <= (float)(_totalVTOLS) and _totalVTOLS > 0) + { + //displayMsg("vtolStructs: need rearming Pads"); + buildRearmPads(); + } + + if( lStopVTOLFactBuilding ){ + exit; + } + + //if ( gameTime - lastDisplayAI >= 90 ){ + //displayMsg("vtolStructs: vtolStructs ("& _numVtolFacs &"/"& structsBuildLimits[STR_VTOL_FACTORY] &")"); + //} + if( _numVtolFacs < structsBuildLimits[nAI_Pers][STR_VTOL_FACTORY] and gameTime - tLastVTOLFactBuild > 900 ) + { + // build factory + buildX = baseX; // pick a location + buildY = baseY; + boolResult = pickStructLocation(vtolFactory, ref buildX, ref buildY, player); + if(boolResult == TRUE) + { + droid = closestDroidCanBuild(buildGroup,buildX,buildY); + if( droid != NULLOBJECT) + { + if ( droidCanReach(droid, buildX ,buildY) ){ + //displayMsg("*** vtolStructs: droid to build vtolFactory"); + orderDroidStatsLoc(droid, DORDER_BUILD,vtolFactory, buildX,buildY); + tLastVTOLFactBuild = gameTime; + } + } //else { displayMsg("vtolStructs: cannot find an idle buildTruck"); } + } //else { displayMsg("#### vtolStructs: CANNOT PICK UP VTOL FACTORY LOCATION "); } + } //else { displayMsg("vtolStructs: MAX VTOL FACT REACHED "); } +} + +// ------------- build VTOL droids -------------------- +event buildVtols(inactive) +{ + + local int _totalVTOLS; + + ASSERT(player >= 0 and player < 8, "player out of bounds: buildVtols " & player, player); + + //displayMsg("buildVtols: buildVtols event called - 1 nProdSelect("& nProdSelect &") lStopVTOLProduction("& lStopVTOLProduction &") lMinBaseStructBuilt("& lMinBaseStructBuilt &")"); + + if( lStopVTOLProduction ){ + exit; + } + + _totalVTOLS = vtolDefendGr.members + vtolAttGr.members; + // got enough vtols? + if( getDroidCount(player) >= MAX_DROIDS ){ + //displayMsg("buildVtols: CAN'T BUILD VTOLS - TOO MANY DROIDS UNITS"); + exit; + } + if( (_totalVTOLS >= MAX_VTOLS and AIPersonality != AI_VTOL) or (_totalVTOLS >= MAX_VTOLS_PERS2 and AIPersonality == AI_VTOL) ){ + //displayMsg("buildVtols: CAN'T BUILD VTOLS - TOO MANY VTOLS tot:("& _totalVTOLS &") max VTOLs Gen1-3-4("& MAX_VTOLS &") Gen2("& MAX_VTOLS_PERS2 &")"); + exit; + } + + + // build vtols + boolResult = true; + initEnumStruct(FALSE,vtolFactory,player,player); + structure = enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if(structureIdle(structure)) // if factory idle + { + vtolFactoryBuildVtol(structure); + boolResult = false; + } + structure = enumStruct(); + } +} + +//====================================================== +event manageDefVTOL(inactive) +{ + local int _dist,_nVTOLSRequired; + local string _dbgString; + + ASSERT(player >= 0 and player < 8, "player out of bounds: manageDefVTOL " & player, player); + + if ( attTargetVTOL != NULLOBJECT ){ + _dist = distBetweenTwoPoints( attTargetVTOL.x, attTargetVTOL.y, baseX, baseY); + //dbg("attTarget != NULLOBJECT; VTOLs ("& vtolDefendGr.members &") idle("& idleGroup(vtolDefendGr) &") alertIsOn("& alertIsOn &") alertTime("& alertTime &") tDefVtolAction("& tDefVtolAction &") isDerr("& bVTOLTargetIsDerrick &") dist("& _dist/TILE &"/"& nDefendRange/TILE &") AA("& numEnemyAAInRange(attTargetVTOL.x, attTargetVTOL.y, AA_THREAT_RANGE) &")",player); + } + if ( defTargetVTOL != NULLOBJECT ){ + _dist = distBetweenTwoPoints( defTargetVTOL.x, defTargetVTOL.y, baseX, baseY); + //dbg("defTarget != NULLOBJECT; VTOLs ("& vtolDefendGr.members &") idle("& idleGroup(vtolDefendGr) &") alertIsOn("& alertIsOn &") alertTime("& alertTime &") tDefVtolAction("& tDefVtolAction &") isDerr("& bVTOLTargetIsDerrick &") dist("& _dist/TILE &"/"& nDefendRange/TILE &") AA("& numEnemyAAInRange(defTargetVTOL.x, defTargetVTOL.y, AA_THREAT_RANGE) &")",player); + } + //if ( defTargetVTOL == NULLOBJECT and attTargetVTOL == NULLOBJECT){ + //dbg("Targets == NULLOBJECTS; VTOLs ("& vtolDefendGr.members &") idle("& idleGroup(vtolDefendGr) &") alertIsOn("& alertIsOn &") alertTime("& alertTime &") tDefVtolAction("& tDefVtolAction &") isDerr("& bVTOLTargetIsDerrick &") ",player); + //} + + if (vtolDefendGr.members == 0){ + targetPlayerVTOL = -1; + attTargetVTOL = NULLOBJECT; + defTargetVTOL = NULLOBJECT; + exit; + } + + if ( targetPlayerVTOL >= 0 and targetPlayerVTOL < 8 ){ + if ( friendlyPlayer(targetPlayerVTOL) ){ + targetPlayerVTOL = -1; + attTargetVTOL = NULLOBJECT; + defTargetVTOL = NULLOBJECT; + } + } + + if (alertIsOn){ + attTargetVTOL = NULLOBJECT; + if ( idleGroup(vtolDefendGr) == 0 ){ + exit;//allow VTOLS to stay on rearming pads + } + } else { + if ( (float)idleGroup(vtolDefendGr) < (float)(vtolDefendGr.members)*0.8 ){ + exit;//allow VTOLS to stay on rearming pads + } + } + + //VTOL are attacking something, check target is still valid and have enough VTOLs + if (bVTOLTargetIsDerrick){ + _nVTOLSRequired = MIN_VTOLS_ATTACK_DERRICK; + } else { + _nVTOLSRequired = MIN_VTOLS_ATTACK_BASE; + } + + if ( attTargetVTOL != NULLOBJECT ){ + _dist = distBetweenTwoPoints( attTargetVTOL.x, attTargetVTOL.y, baseX, baseY); + if (_dist > nDefendRange and ( vtolDefendGr.members < _nVTOLSRequired or attTargetVTOL.type == OBJ_DROID) ) + { + attTargetVTOL = NULLOBJECT; + //orderGroup( vtolDefendGr, DORDER_RTR ); + } + } + + //reset defTarget is neat to many AA defences + if ( defTargetVTOL != NULLOBJECT ){ + if ( vtolDefendGr.members <= numEnemyAAInRange(defTargetVTOL.x, defTargetVTOL.y, AA_THREAT_RANGE)*3 ){ + defTargetVTOL = NULLOBJECT; + //orderGroup( vtolDefendGr, DORDER_RTR ); + } + } + + if (alertIsOn){ //------------------------------------ + + //reset attack target + attTargetVTOL = NULLOBJECT; + + //set defTarget, this is required in case a long range was set as Target + // and in the meanwhile it happen to got attacked by groud troops. In this + // case DyDo has to reset the target. + if ( gameTime - tTargetTime > 1*TIME_MINUTE ){ + defTargetVTOL = NULLOBJECT; + } + + if (defTargetVTOL != NULLOBJECT ){ + if ( !friendlyPlayer(defTargetVTOL.player) ){//due to NEXUS +//dbg("manageDefVTOL: attack defTargetVTOL",player); + orderGroupObj( vtolDefendGr, DORDER_ATTACK, defTargetVTOL ); + tDefVtolAction = gameTime; + } + } else { + + //alertX/Y can also be the coord of enemy indirect weapons which attacked in nDefendRange + if ( alertX > 0 and alertY > 0){ + defTargetVTOL = objDroidTargetInRange(alertX,alertY,TILE*12,true); + if ( defTargetVTOL == NULLOBJECT ){ + defTargetVTOL = objStrTargetInRange(alertX,alertY,TILE*12); + } + } + if ( defTargetVTOL != NULLOBJECT ){ +//dbg("manageDefVTOL: defTargetVTOL found and attacked ",player); + orderGroupObj( vtolDefendGr, DORDER_ATTACK, defTargetVTOL ); + tDefVtolAction = gameTime; + bVTOLTargetIsDerrick = false; + } //else { dbg("manageDefVTOL: target not found ",player); } + } + + } else {// ============ alert not on ================== + + + //=========== Search a target in DefendRange ================= + if ( vtolDefendGr.members >= MIN_VTOLS_DEFEND_BASE ){ + if ( attTargetVTOL == NULLOBJECT ){ + attTargetVTOL = objStrTargetInRange(baseX,baseY,nDefendRange); + if ( attTargetVTOL != NULLOBJECT ){ + targetPlayerVTOL = attTargetVTOL.player; + bVTOLTargetIsDerrick = false; +//displayMsg("manageDefVTOL: found TGT STR def range"); + } + } + if ( attTargetVTOL == NULLOBJECT ){ + attTargetVTOL = objDroidTargetInRange(baseX,baseY,nDefendRange,true); + if ( attTargetVTOL != NULLOBJECT ){ + targetPlayerVTOL = attTargetVTOL.player; + bVTOLTargetIsDerrick = false; +//displayMsg("manageDefVTOL: found TGT DROID def range"); + } + } + } + + //getAAStruct + //================== Search target = AA structs ========================= + if ( vtolDefendGr.members >= MIN_VTOLS_ATTACK_DERRICK ){ + if ( attTargetVTOL == NULLOBJECT ){ + attTargetVTOL = getAAStruct(true); +//displayMsg("manageDefVTOL: search TGT undefended AA def"); + if ( attTargetVTOL != NULLOBJECT ){ + targetPlayerVTOL = attTargetVTOL.player; + bVTOLTargetIsDerrick = true; +//displayMsg("manageDefVTOL: found TGT undefended AA def"); + } + } + } + + //================== Search target = Enemy Derricks ========================= + if ( vtolDefendGr.members >= MIN_VTOLS_ATTACK_DERRICK ){ + if ( attTargetVTOL == NULLOBJECT ){ +//displayMsg("manageDefVTOL: search TGT Human Derrick "); + attTargetVTOL = objHumanDerrick(true, 1, 0); + if ( attTargetVTOL != NULLOBJECT ){ + targetPlayerVTOL = attTargetVTOL.player; + bVTOLTargetIsDerrick = true; +//displayMsg("manageDefVTOL: found TGT Human Derrick "); + } + } + if ( attTargetVTOL == NULLOBJECT ){ + attTargetVTOL = undefendedEnemyDerrick(true); +//displayMsg("manageDefVTOL: search TGT undefended Derrick "); + if ( attTargetVTOL != NULLOBJECT ){ + targetPlayerVTOL = attTargetVTOL.player; + bVTOLTargetIsDerrick = true; +//displayMsg("manageDefVTOL: found TGT undefended Derrick "); + } + } + } + + //================== Search target = Enemy Bases ========================= + if ( vtolDefendGr.members >= MIN_VTOLS_ATTACK_BASE ){ + + if ( attTargetVTOL == NULLOBJECT ){ + + count = 0; + while ( attTargetVTOL == NULLOBJECT and count < 5) + { + //get a target Enemy first + if ( targetPlayerVTOL < 0){ + targetPlayerVTOL = getTargetEnemy(false); + if ( targetPlayerVTOL < 0){ + targetPlayerVTOL = getRandomEnemyPlayer(false); + } + } + if ( targetPlayerVTOL > 0){ + attTargetVTOL = getVTOLstructTarget();//uses targetPlayerVTOL + } + if ( attTargetVTOL == NULLOBJECT ){ + targetPlayerVTOL = -1; + } else { + bVTOLTargetIsDerrick = false; + } + count++; + } + + } +// if ( attTargetVTOL != NULLOBJECT ){ +//displayMsg("manageDefVTOL: found TGT enemy base targetPlayerVTOL("& targetPlayerVTOL &")"); +// } else { +//displayMsg("manageDefVTOL: NO TARGETS FOUND !!!"); +// } + + } + + if (bVTOLTargetIsDerrick){ + _nVTOLSRequired = MIN_VTOLS_ATTACK_DERRICK; + } else { + _nVTOLSRequired = MIN_VTOLS_ATTACK_BASE; + } + + + //================== Target is not NULLOBJECT ===================== + if ( attTargetVTOL != NULLOBJECT ) + { + + _dist = distBetweenTwoPoints( attTargetVTOL.x, attTargetVTOL.y, baseX, baseY); + if (_dist > nDefendRange){ + + //if a droid, reset target + //if ( attTargetVTOL.type == OBJ_DROID ){ + //attTargetVTOL = NULLOBJECT; + //targetPlayerVTOL = -1; + //exit; + //} + + //check if enemy has build AA def around this object and if have enough VTOLS + count2 = numEnemyAAInRange(attTargetVTOL.x, attTargetVTOL.y, AA_THREAT_RANGE ); + if ( vtolDefendGr.members < count2*3 or vtolDefendGr.members < _nVTOLSRequired ){ +//displayMsg("manageDefVTOL: reset TARGET too many defences around it ("& vtolDefendGr.members &")<("& count2*3 &") or not enough VTOLS _nVTOLSRequired("& _nVTOLSRequired &" < "& vtolDefendGr.members &")!!!"); + attTargetVTOL = NULLOBJECT; + targetPlayerVTOL = -1; + exit; + } + + //re-attacking the enemy base + if ( (float)idleGroup(vtolDefendGr) >= (float)(vtolDefendGr.members)*0.8 ){ +//displayMsg("manageDefVTOL: attack TARGET "); + orderGroupObj( vtolDefendGr, DORDER_ATTACK, attTargetVTOL ); + tDefVtolAction = gameTime; + }// else { +//displayMsg("manageDefVTOL: cannot attack TARGET, not enough idle VTOLS ("& idleGroup(vtolDefendGr) &"/"& vtolDefendGr.members &")"); + //} + + } else { //if (_dist > nDefendRange){ + + //defending the base in defend range, do not check the numbers of VTOLs + if (!friendlyPlayer(attTargetVTOL.player)){//due to NEXUS!!! + if ( (float)idleGroup(vtolDefendGr) >= (float)(vtolDefendGr.members)*0.8 ){ +//displayMsg("manageDefVTOL: VTOLs attacking enemy to defend base"); + orderGroupObj( vtolDefendGr, DORDER_ATTACK, attTargetVTOL ); + tDefVtolAction = gameTime; + } + } + + } //if (_dist > nDefendRange){ + } //if ( attTargetVTOL != NULLOBJECT ) + }//enderlse alertIsOn +} + +//=========================== END VTOL STUFF ======================================== +event buildBase(inactive) //event 8 +{ + local int _f,_r,_c,_v,_h,_l; + + ASSERT(player >= 0 and player < 8, "player out of bounds: buildBase " & player, player); + eventCheckTime[2] = gameTime; + + if ( lStopBuildingStructures ){ + //displayMsg("buildBase: stopped lMinBaseStructBuilt("& lMinBaseStructBuilt &")"); + exit; + } + + _f = nFactories; + _r = nResLabs; + _c = nCybFact; + _v = nVTOLFactories; + _h = numStructsByType(playerHQ, player); + _l = numStructsByType(lassat, player); + + + boolResult = true; + droid = closestDroidCanBuild(buildGroup,baseX,baseY); + + if(droid == NULLOBJECT){ + exit; + } + + + + //check PlayerHQ first + if(_h == 0 and isStructureAvailable(playerHQ , player) ) + { + buildX = baseX; + buildY = baseY; + boolResult = pickStructLocation(playerHQ, ref buildX, ref buildY, player); + if(boolResult){ + if (droidCanReach(droid, buildX ,buildY)){ + //displayMsg("buildBase: BUILD FIRST HQ _f("& _f &") _r("& _r &") _c("& _c &") "); + orderDroidStatsLoc(droid, DORDER_BUILD, playerHQ, buildX, buildY ); + boolResult = false; + } + } + } + + //check factory as second + if(_f == 0 and isStructureAvailable(factory , player) and boolResult) + { + buildX = baseX; + buildY = baseY; + boolResult = pickStructLocation(factory, ref buildX, ref buildY, player); + if(boolResult) + { + if (droidCanReach(droid, buildX ,buildY)){ + //displayMsg("buildBase: BUILD FIRST FACTORY _f("& _f &") _r("& _r &") _c("& _c &") "); + orderDroidStatsLoc(droid, DORDER_BUILD, factory, buildX, buildY ); + boolResult = false; + } + } + } + + //check resLab + if(_r == 0 and isStructureAvailable(resLab , player) and boolResult) + { + buildX = baseX; + buildY = baseY; + boolResult = pickStructLocation(resLab, ref buildX, ref buildY, player); + if(boolResult) + { + if (droidCanReach(droid, buildX ,buildY)){ + //displayMsg("buildBase: BUILD FIRST RESEARCH LAB _f("& _f &") _r("& _r &") _c("& _c &") "); + orderDroidStatsLoc(droid, DORDER_BUILD, resLab, buildX, buildY ); + boolResult = false; + } + } + } + + //check cybfactory + if(_c == 0 and isStructureAvailable(cybFactory , player) and boolResult) + { + buildX = baseX; + buildY = baseY; + boolResult = pickStructLocation(cybFactory, ref buildX, ref buildY, player); + if(boolResult) + { + if (droidCanReach(droid, buildX ,buildY)){ + //displayMsg("buildBase: BUILD FIRST CYBORG FACTORY _f("& _f &") _r("& _r &") _c("& _c &") "); + orderDroidStatsLoc(droid, DORDER_BUILD, cybFactory, buildX, buildY ); + boolResult = false; + } + } + } + + //check lassat + if(_l == 0 and isStructureAvailable(lassat , player) and boolResult) + { + buildX = baseX; + buildY = baseY; + boolResult = pickStructLocation(lassat, ref buildX, ref buildY, player); + if(boolResult) + { + if (droidCanReach(droid, buildX ,buildY)){ + //displayMsg("buildBase: BUILD FIRST LASSAT _f("& _f &") _r("& _r &") _c("& _c &") "); + //displayMsg("buildBase: nAI_Pers("& nAI_Pers &") ("& structsBuildLimits[nAI_Pers][STR_TANK_FACTORY] &")("& structsBuildLimits[nAI_Pers][STR_RESLAB] &")("& structsBuildLimits[nAI_Pers][STR_CYB_FACTORY] &")("& structsBuildLimits[nAI_Pers][STR_VTOL_FACTORY] &") "); + orderDroidStatsLoc(droid, DORDER_BUILD, lassat, buildX, buildY ); + boolResult = false; + } + } + } + + //displayMsg("buildBase: _f("& _f &") _r("& _r &") _c("& _c &") _v("& _v &") "); + //displayMsg("buildBase: lMinBaseStructBuilt("& lMinBaseStructBuilt &") nStructToBeBuilt("& nStructToBeBuilt &") nAI_Pers("& nAI_Pers &") ("& structsBuildLimits[nAI_Pers][STR_TANK_FACTORY] &")("& structsBuildLimits[nAI_Pers][STR_RESLAB] &")("& structsBuildLimits[nAI_Pers][STR_CYB_FACTORY] &")("& structsBuildLimits[nAI_Pers][STR_VTOL_FACTORY] &") "); + + //just validate the below rows + //droid = getADroid(buildGroup); + + + if( boolResult ) + { + + if ( nStructToBeBuilt >= 4){ nStructToBeBuilt = 0; } + + if ( nStructToBeBuilt == STR_TANK_FACTORY and _f >= structsBuildLimits[nAI_Pers][STR_TANK_FACTORY] ){ + nStructToBeBuilt++; + } + + if ( nStructToBeBuilt == STR_RESLAB and _r >= structsBuildLimits[nAI_Pers][STR_RESLAB] ){ + nStructToBeBuilt++; + } + + if ( nStructToBeBuilt == STR_CYB_FACTORY and _c >= structsBuildLimits[nAI_Pers][STR_CYB_FACTORY] ){ + nStructToBeBuilt++; + } + + if ( nStructToBeBuilt == STR_VTOL_FACTORY and _v >= structsBuildLimits[nAI_Pers][STR_VTOL_FACTORY] and isStructureAvailable(vtolFactory,player) ){ + nStructToBeBuilt++; + } + + //all base structs have been built! + if ( nStructToBeBuilt == 4 or (nStructToBeBuilt == 3 and !isStructureAvailable(vtolFactory,player)) ){ + nStructToBeBuilt = 0; + exit; + } + + //displayMsg("buildBase: nStructToBeBuilt("& nStructToBeBuilt &") "); + if( isStructureAvailable(structs[nStructToBeBuilt],player) ) + { + buildX = baseX; // pick a location + buildY = baseY; + if( pickStructLocation(structs[nStructToBeBuilt], ref buildX, ref buildY,player) ) + { + droid = closestDroidCanBuild(buildGroup,buildX,buildY); + if( droid == NULLOBJECT and buildGroup.members < 2 ){ + droid = pickCybEng(true); + } + if( droid != NULLOBJECT) + { + if (droidCanReach(droid, buildX ,buildY)){ + //displayMsg("buildBase: nStructToBeBuilt["& nStructToBeBuilt &"] _fact("& _f &") _resLab("& _r &") _cyb("& _c &") "); + //displayMsg("buildBase: buildGroup("& buildGroup.members &") harvester("& harvesterGroup.members &") "); + orderDroidStatsLoc(droid, DORDER_BUILD,structs[nStructToBeBuilt],buildX,buildY); + nStructToBeBuilt++; + } + } + } + } + }// if( droid != NULLOBJECT and boolResult) +} +//----------------------------------------- +event sendBackDamagedUnits(inactive) +{ + + //Check for untis to be repaired + eventCheckTime[3] = gameTime; + if(getStructure(repairFacility, player) != NULLOBJECT and toBeRepairedTankGroup.members>0) + { + + initIterateGroup(toBeRepairedTankGroup); + droid = iterateGroup(toBeRepairedTankGroup); + while(droid != NULLOBJECT) + { + if ( droid.order != DORDER_RTR ){ + orderDroid(droid,DORDER_RTR); + //displayMsg("*** sendBackDamagedUnits: Order droid ("& droid.id &") RTR with health ("& droid.health &") in group toBeRepairedTankGroup ("& toBeRepairedTankGroup.members &")"); + } + droid = iterateGroup(toBeRepairedTankGroup); + } + + initIterateGroup(toBeRepairedCyborgGroup); + droid = iterateGroup(toBeRepairedCyborgGroup); + while(droid != NULLOBJECT) + { + if ( droid.order != DORDER_RTR ){ + orderDroid(droid,DORDER_RTR); + //displayMsg("*** sendBackDamagedUnits: Order droid ("& droid.id &") RTR with health ("& droid.health &") in group toBeRepairedTankGroup ("& toBeRepairedCyborgGroup.members &")"); + } + droid = iterateGroup(toBeRepairedCyborgGroup); + } + + } else { + + //send in the base to be repaired by repair tank!! + initIterateGroup(toBeRepairedTankGroup); + droid = iterateGroup(toBeRepairedTankGroup); + while(droid != NULLOBJECT) + { + + if ( droid.order != DORDER_RTB and droid.order != DORDER_RTR ) + { + if( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) > nBaseRange ) + { + //displayMsg("*** sendBackDamagedUnits: Order droid ("& droid.id &") MOVE to baseX and baseY with health ("& droid.health &") in group toBeRepairedTankGroup ("& toBeRepairedTankGroup.members &")"); + orderDroid(droid, DORDER_RTB); + } + } //else{ displayMsg("*** sendBackDamagedUnits: damaged droid ("& droid.id &") already sent back to repair "); } + + droid = iterateGroup(toBeRepairedTankGroup); + } + + initIterateGroup(toBeRepairedCyborgGroup); + droid = iterateGroup(toBeRepairedCyborgGroup); + while(droid != NULLOBJECT) + { + + if ( droid.order != DORDER_RTB and droid.order != DORDER_RTR ) + { + if( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) > nBaseRange ) + { + //displayMsg("*** sendBackDamagedUnits: Order droid ("& droid.id &") MOVE to baseX and baseY with health ("& droid.health &") in group toBeRepairedCyborgGroup ("& toBeRepairedCyborgGroup.members &")"); + orderDroid(droid, DORDER_RTB); + } + } //else{ displayMsg("*** sendBackDamagedUnits: damaged droid ("& droid.id &") already sent back to repair "); } + + droid = iterateGroup(toBeRepairedCyborgGroup); + } + + } +} +//=============================================0 +event unitRepairSwitch(inactive) +{ + + eventCheckTime[4] = gameTime; + //displayMsg("unitRepairSwitch: unitRepairSwitch START "); + + //Check for untis to be repaired + if(getStructure(repairFacility, player) != NULLOBJECT or repairGroup.members > 0) + { + //defense tanks + initIterateGroup(tankDefGroup); + droid = iterateGroup(tankDefGroup); + while(droid != NULLOBJECT) + { + if( droid.health < nDamageLevelRepair ) + { + groupAddDroid(toBeRepairedTankGroup, droid); + orderDroid(droid,DORDER_RTR); + //displayMsg("*** unitRepairSwitch1: move damaged tankDefGroup to toBeRepairedTankGroup ("& droid.id &") with health ("& droid.health &") added in group toBeRepairedTankGroup ("& toBeRepairedTankGroup.members &")"); + } + droid = iterateGroup(tankDefGroup); + } + + //attack tanks + initIterateGroup(tankGroup); + droid = iterateGroup(tankGroup); + while(droid != NULLOBJECT) + { + if( droid.health < nDamageLevelRepair and droid.propulsion != TrackedProp ) + { + groupAddDroid(toBeRepairedTankGroup, droid); + orderDroid(droid,DORDER_RTR); + //displayMsg("*** unitRepairSwitch1: move damaged tankGroup to toBeRepairedTankGroup ("& droid.id &") with health ("& droid.health &") added in group toBeRepairedTankGroup ("& toBeRepairedTankGroup.members &")"); + } + droid = iterateGroup(tankGroup); + } + + //help group + initIterateGroup(helpGroup); + droid = iterateGroup(helpGroup); + while(droid != NULLOBJECT) + { + if( droid.health < nDamageLevelRepair and droid.propulsion != TrackedProp ) + { + groupAddDroid(toBeRepairedTankGroup, droid); + orderDroid(droid,DORDER_RTR); + //displayMsg("*** unitRepairSwitch1: move damaged units to toBeRepairedTankGroup ("& droid.id &") with health ("& droid.health &") added in group toBeRepairedTankGroup ("& toBeRepairedTankGroup.members &")"); + } + droid = iterateGroup(helpGroup); + } + + //cyborgs - defend + initIterateGroup(cyborgDefGroup); + droid = iterateGroup(cyborgDefGroup); + while(droid != NULLOBJECT) + { + if( droid.health < nDamageLevelRepair ) + { + groupAddDroid(toBeRepairedCyborgGroup, droid); + //displayMsg("*** unitRepairSwitch1: Send back to repair cyborgDefGroup ("& droid.id &") with health ("& droid.health &")"); + orderDroid(droid,DORDER_RTR); + } + droid = iterateGroup(cyborgDefGroup); + } + + //cyborgs - attack + initIterateGroup(cyborgAttGroup); + droid = iterateGroup(cyborgAttGroup); + while(droid != NULLOBJECT) + { + if( droid.health < nDamageLevelRepair) + { + groupAddDroid(toBeRepairedCyborgGroup, droid); + //displayMsg("*** unitRepairSwitch1: Send back to repair cyborgDefGroup ("& droid.id &") with health ("& droid.health &")"); + orderDroid(droid,DORDER_RTR); + } + droid = iterateGroup(cyborgAttGroup); + } + + //NO REPAIR FAC, NO REPAIR TRUCK switch back to tankDefGroup + } else { + if ( toBeRepairedTankGroup.members > 0 ){ + groupAddGroup(tankDefGroup,toBeRepairedTankGroup); + } + if ( toBeRepairedCyborgGroup.members > 0 ){ + groupAddGroup(cyborgDefGroup,toBeRepairedCyborgGroup); + } + } + + + //check if units have been repaired and assign back to tank group + initIterateGroup(toBeRepairedTankGroup); + droid = iterateGroup(toBeRepairedTankGroup); + while(droid != NULLOBJECT) + { + if( droid.health > MIN_HEALT_SWITCH_TO_TANK ) + { + //displayMsg("*** unitRepairSwitch: found healty tank ("& droid.id &")("& droid.health &")"); + if (droid.droidType == DROID_REPAIR) + { + //displayMsg("*** unitRepairSwitch: repairUnit ("& droid.id &") repaired and back to repairGroup -> health ("& droid.health &")"); + groupAddDroid(repairGroup,droid); + } + if (droid.droidType == DROID_WEAPON) + { + //displayMsg("*** unitRepairSwitch: tank ("& droid.id &") repaired and back to tankDefGroup -> health ("& droid.health &")"); + groupAddDroid(tankDefGroup,droid); + } + //mixed group checks!!! + if (droid.droidType == DROID_CYBORG and droid.droidType != DROID_CYBORG_CONSTRUCT) + { + nTotCyborgBuilt++; + if ( AIPersonality == AI_CYBORG){ + //displayMsg("*** unitRepairSwitch: cyborg ("& droid.id &") repaired and back to cyborgDefGroup -> health ("& droid.health &")"); + groupAddDroid(cyborgDefGroup, droid); + } else { + if (nTotCyborgBuilt > 2){ + //displayMsg("*** unitRepairSwitch: cyborg ("& droid.id &") repaired and back to tankDefGroup -> health ("& droid.health &")"); + groupAddDroid(tankDefGroup, droid); + nTotCyborgBuilt = 0; + } else { + //displayMsg("*** unitRepairSwitch: cyborg ("& droid.id &") repaired and back to cyborgDefGroup -> health ("& droid.health &")"); + groupAddDroid(cyborgDefGroup, droid); + } + } + } + + } else { + orderDroid(droid,DORDER_RTR); + } + droid = iterateGroup(toBeRepairedTankGroup); + } + + //check if units have been repaired and assign back to tank group + initIterateGroup(toBeRepairedCyborgGroup); + droid = iterateGroup(toBeRepairedCyborgGroup); + while(droid != NULLOBJECT) + { + if( droid.health > MIN_HEALT_SWITCH_TO_CYBORG ) + { + //displayMsg("*** unitRepairSwitch: tank ("& droid.id &") repaired and back to tankDefGroup -> health ("& droid.health &")"); + groupAddDroid(cyborgDefGroup,droid); + } else { + orderDroid(droid,DORDER_RTR); + } + droid = iterateGroup(toBeRepairedCyborgGroup); + } + + //if ( gameTime - lastDisplayAI >= 80 ){ + //displayMsg("unitRepairSwitch: unitRepairSwitch END ("& toBeRepairedCyborgGroup.members &")("& count &")"); + //} +} +//-------------------------------------------------------------- +event activateAttack( inactive ) +{ + local int _nTankUnitsToBeMoved,_nTotUnits,_nUnitsRequiredToAttack,_rndTime; + local int _nCybUnitsToBeMoved,_nTotCybUnits,_nCybUnitsRequiredToAttack; + local bool _bUseCybUnitsToo; + + local int _nMyUnitsTot, _nMyUnitsPower, _nMyUnitsHP; + local int _nEnUnitsTot, _nEnUnitsPower, _nEnUnitsHP; + local int _cybRequired,_tankRequired,_player; + local float _nMyPowerIndex,_nEnPowerIndex; + + eventCheckTime[22] = gameTime; + + + if ( tankDefGroup.members < minDefDroids[nAI_Pers][MINDEF_TANKS] and cyborgDefGroup.members < minDefDroids[nAI_Pers][MINDEF_CYBORGS]){ + exit; + } + if ( alertLevel == RED_ALERT ){ exit; } + + // ---------------------------------------------------------------------- + //Check for Final Attack in 1vs1 game or if just one enemy player exists + _nMyUnitsTot = tankDefGroup.members + cyborgDefGroup.members + cyborgAttGroup.members; + if ( !bTankAttIsOn and nEnemyPlayers == 1 and (gameTime - tLastFinalAttack) > 6*TIME_MINUTE and gameTime > 20*TIME_MINUTE) + { + _nMyUnitsPower = getWeaponUnitsInfo( player, WUI_POWER); + _nMyUnitsHP = getWeaponUnitsInfo( player, WUI_HP); + _nMyPowerIndex = getPowerIndex( player ); + + _nEnUnitsTot = getWeaponUnitsInfo( nLastEnemyPlayer, WUI_TOTUNITS); + _nEnUnitsPower = getWeaponUnitsInfo( nLastEnemyPlayer, WUI_POWER); + _nEnUnitsHP = getWeaponUnitsInfo( nLastEnemyPlayer, WUI_HP); + _nEnPowerIndex = getPowerIndex( nLastEnemyPlayer ); + + bFinalAttack_1vs1 = false; + //droid superiority + if ( _nMyUnitsTot > 15 and _nMyUnitsTot > _nEnUnitsTot*2 ){ + if ( _nMyUnitsTot > _nEnUnitsTot*3 ){ bFinalAttack_1vs1 = true; } + if ( _nMyUnitsPower > _nEnUnitsPower*2 ){ bFinalAttack_1vs1 = true; } + if ( _nMyUnitsHP > _nEnUnitsHP*2 ){ bFinalAttack_1vs1 = true; } + } + //enemy with lower power + if ( _nMyPowerIndex > _nEnPowerIndex*2.0 ){ + if ( _nMyUnitsTot > 15 ){ + if ( _nMyUnitsTot > _nEnUnitsTot*2 ){ bFinalAttack_1vs1 = true; } + if ( (float)_nMyUnitsPower > (float)_nEnUnitsPower*1.5 ){ bFinalAttack_1vs1 = true; } + if ( (float)_nMyUnitsHP > (float)_nEnUnitsHP*1.5 ){ bFinalAttack_1vs1 = true; } + } + } + //dbg("dbg->activateAttack: Final Attack - tkdef("& tankDefGroup.members &") cybdef("& cyborgDefGroup.members &") tkatt("& tankGroup.members &") cybatt("& cyborgAttGroup.members &") pow("& _nMyPowerIndex &")("& _nEnPowerIndex &") my("& _nMyUnitsTot &"-"& _nMyUnitsPower &"-"& _nMyUnitsHP &") en("& _nEnUnitsTot &"-"& _nEnUnitsPower &"-"& _nEnUnitsHP &") ("& tLastFinalAttack &")("& nEnemyPlayers &") ["& bFinalAttack_1vs1 &"] bForceResPowUp("& bForceResPowUp &")",player); + } //else { dbg("dbg->activateAttack: gameTime("& gameTime &") ",player); } + + if (bFinalAttack_1vs1){ + if ( gameTime - tLastFinalAttack > 5*TIME_MINUTE ){ + if (helpGroup.members>0) {groupAddGroup(tankGroup, helpGroup);} + if (tankDefGroup.members>0) {groupAddGroup(tankGroup, tankDefGroup);} + if (cyborgDefGroup.members>0) {groupAddGroup(tankGroup, cyborgDefGroup);} + if (cyborgAttGroup.members>0) {groupAddGroup(tankGroup, cyborgAttGroup);} + printDebug1("activateAttack: Final Attack Activated, attacking with droids("& tankGroup.members &") tLastFinalAttack("& tLastFinalAttack &") "); + tLastFinalAttack = gameTime; + tLastTankAttack = gameTime; + bTankAttIsOn = true; + nFinalAttacks++; + //dbg("dbg->activateAttack: ____________________ FINAL ATTACK ___________________" , player); + //dbg("dbg->activateAttack: FINAL ATTACK, ("& getPlayerName(player) &") attacks with ("& tankGroup.members &") units against ("& getPlayerName(nLastEnemyPlayer) &")" , player); + if ( !bTankAttIsOn ){ + setEventTrigger(TankAttack,TankAttackTr); + } + exit; + } + } + + if ( !bFinalAttack_1vs1 ){ + + if (!bTankAttIsOn){ + // ---------------------- virtual victory check + _player=0; + nTotEnemyDroids = 0; + while( _player < MAX_PLAYERS ){ + if ( isPlayerStillLive(_player) and !friendlyPlayer(_player) ){ + nTotEnemyDroids = nTotEnemyDroids + (aStat[OC_CYBORGS][_player] + aStat[OC_TANKS][_player]); + } + _player++; + } + //send reinforcements by grouping them (min 8 droids) + if ( nTotEnemyDroids*4 < _nMyUnitsTot and _nMyUnitsTot > 8 ){ + if (helpGroup.members>0) { groupAddGroup(tankGroup, helpGroup);} + if (tankDefGroup.members>0) { groupAddGroup(tankGroup, tankDefGroup);} + if (cyborgDefGroup.members>0){ groupAddGroup(tankGroup, cyborgDefGroup);} + if (cyborgAttGroup.members>0){ groupAddGroup(tankGroup, cyborgAttGroup);} + tLastTankAttack = gameTime; + bTankAttIsOn = true; + setEventTrigger(TankAttack,TankAttackTr); + printDebug1("activateAttack: Virtual Victory check is positive: attacking with droids ("& tankGroup.members &") TotEnemyDroids*4("& nTotEnemyDroids*4 &") < MyTotUnits("& _nMyUnitsTot &") and available droids > 8 "); + exit; + } + } + + // ================== TANK ATTACK ============================= + if ( AIPersonality != AI_CYBORG and tankDefGroup.members > minDefDroids[nAI_Pers][MINDEF_TANKS]){ + _nTotUnits = tankDefGroup.members; + _nTankUnitsToBeMoved = _nTotUnits - minDefDroids[nAI_Pers][MINDEF_TANKS];//MIN_DEFENDING_TANKS; + _nUnitsRequiredToAttack = minDefDroids[nAI_Pers][MINDEF_TANKS]+MIN_ATTACKING_TANKS+nAttackingUnitsToAdd; + if ( cyborgDefGroup.members > minDefDroids[nAI_Pers][MINDEF_CYBORGS] ){ + _nCybUnitsToBeMoved = cyborgDefGroup.members - minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + } else { + _nCybUnitsToBeMoved = 0; + } + _bUseCybUnitsToo = false; + + //force attack after some time by using both cyborgs and tanks droids. + if ( AIPersonality == AI_TURTLE ){ + _rndTime = (10*TIME_MINUTE + _random(900)); + } else { + _rndTime = (6*TIME_MINUTE + _random(900)); + } + if ( nMapPower <= LOW_POWER_MAP ){ + _bUseCybUnitsToo = true; + } + if ( gameTime > (15*TIME_MINUTE + tTotalAttack) and ( (gameTime - tLastTankAttack > _rndTime) or (gameTime - tLastCyborgAttack > _rndTime) ) ){ + _bUseCybUnitsToo = true; + _nUnitsRequiredToAttack = _nUnitsRequiredToAttack + 5;//otherwise will always attack with 7!! + } + if ( _bUseCybUnitsToo ){ + _nTotUnits = _nTotUnits + _nCybUnitsToBeMoved; + } + + if ( _nTotUnits >= _nUnitsRequiredToAttack ) + { + //check time to avoid all tanks are re-assigned back to tankgroup after a withdraw + //do not attack if we have not enough units + if ( _bUseCybUnitsToo and (cyborgDefGroup.members > minDefDroids[nAI_Pers][MINDEF_CYBORGS]) ){ + _nCybUnitsToBeMoved = cyborgDefGroup.members - minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + moveUnitsBetweenGRPs(tankGroup, cyborgDefGroup, _nCybUnitsToBeMoved, false); + } + moveUnitsBetweenGRPs(tankGroup, tankDefGroup, _nTankUnitsToBeMoved, true); + tLastTankAttack = gameTime; + bTankAttIsOn = true; + bAttackedHumanDerrick = false;//alternate attacks + //dbg("dbg->activateAttack: ("& getPlayerName(player) &") attacks with tanks ("& tankGroup.members &") _bUseCybUnitsToo ("& _bUseCybUnitsToo &")",player); + printDebug1("ActivateAttack: Tank Attack Activated, att droids("& tankGroup.members &") _nTotUnits("& _nTotUnits &") _nUnitsRequired("& _nUnitsRequiredToAttack &") _bUseCybUn("& _bUseCybUnitsToo &") ToBeMoved Tk-Cy-toAdd("& _nTankUnitsToBeMoved &")("& _nCybUnitsToBeMoved &")("& nAttackingUnitsToAdd &")"); + setEventTrigger(TankAttack,TankAttackTr); + exit; + } + } + + //==================== CYBORG ATTACK ===================================== + //cyborgs + if (!bCybAttIsOn and cyborgDefGroup.members > minDefDroids[nAI_Pers][MINDEF_CYBORGS] and gameTime > VALID_TIME_CYBATTACK){ + _nTotCybUnits = cyborgDefGroup.members; + _nCybUnitsRequiredToAttack = minDefDroids[nAI_Pers][MINDEF_CYBORGS]+MIN_ATT_CYBORGS+nCybAttUnitsToAdd; + _nCybUnitsToBeMoved = _nTotCybUnits - minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + if ( _nTotCybUnits >= _nCybUnitsRequiredToAttack ){ + moveUnitsBetweenGRPs( cyborgAttGroup, cyborgDefGroup, _nCybUnitsToBeMoved, false ); + bCybAttIsOn = true; + tLastCyborgAttack = gameTime; + bAttackedHumanDerrick = false;//alternate attacks + //dbg("dbg->activateAttack: ("& getPlayerName(player) &") attacks with cyborg team units: ("& cyborgAttGroup.members &") ",player); + printDebug1("ActivateAttack: Cyborg Attack Activated, attacking with Cyborgs ("& cyborgAttGroup.members &") "); + setEventTrigger(CyborgAttack,CyborgAttackTr); + exit; + } + } + + //==================== HUMAN DERRICKS ===================================== + //attack human derrick with few defences if no targets in defend range + if ( AIPersonality == AI_CYBORG ){ + + if ( !bCybAttIsOn ){ + _cybRequired = 5 + minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + if ( attackCybObj == NULLOBJECT and !bAttackedHumanDerrick){ + //dbg("dbg->activateAttack: '"& getPlayerName(player) &"' attacks human derrick STEP 1 ("& _cybRequired &") - ("& cyborgDefGroup.members &")",player); + if (cyborgDefGroup.members >= _cybRequired){ + //dbg("dbg->activateAttack: '"& getPlayerName(player) &"' attacks human derrick STEP 2",player); + attackCybObj = objHumanDerrick(false, 1, 8);//(bool bVTOLTarget, int _numDef, int _distInTiles + if ( attackCybObj != NULLOBJECT ){ + moveUnitsBetweenGRPs(cyborgAttGroup, cyborgDefGroup, 5, false); + bCybAttIsOn = true; + tLastCyborgAttack = gameTime; + bAttackedHumanDerrick = true;//alternate attacks + nAttHumanPlayer++; + //dbg("dbg->activateAttack: '"& getPlayerName(player) &"' attacks human derrick with cyborgs ("& cyborgAttGroup.members &")",player); + printDebug1("ActivateAttack: Attacking human derricks with Tk+Cy droids("& cyborgAttGroup.members &") "); + setEventTrigger(CyborgAttack,CyborgAttackTr); + exit; + } //else { dbg("dbg->activateAttack: '"& getPlayerName(player) &"' no undefended human derricks to attack found",player); } + } + } + } + + } else { //Other personalities + + if ( !bTankAttIsOn ){ + _cybRequired = 3 + minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + _tankRequired = 2 + minDefDroids[nAI_Pers][MINDEF_TANKS]; + if ( !alertIsOn and !bAttackedHumanDerrick){ + //dbg("dbg->activateAttack: '"& getPlayerName(player) &"' attacks human derrick STEP 1 ("& _cybRequired &")("& _tankRequired &") - ("& cyborgDefGroup.members &")("& tankDefGroup.members &")",player); + if ( tankDefGroup.members >= _tankRequired and cyborgDefGroup.members >= _cybRequired){ + //dbg("dbg->activateAttack: '"& getPlayerName(player) &"' attacks human derrick STEP 2",player); + attackTankObj = objHumanDerrick(false, 1, 8); + if ( attackTankObj != NULLOBJECT ){ + moveUnitsBetweenGRPs(tankGroup, cyborgDefGroup, 3, false); + moveUnitsBetweenGRPs(tankGroup, tankDefGroup, 2, true); + bTankAttIsOn = true; + tLastTankAttack = gameTime; + bAttackedHumanDerrick = true;//alternate attacks + nAttHumanPlayer++; + //dbg("dbg->activateAttack: '"& getPlayerName(player) &"' attacks human derrick with tanks ("& tankGroup.members &")",player); + printDebug1("ActivateAttack: Attacking human derricks with droids("& tankGroup.members &") "); + setEventTrigger(TankAttack,TankAttackTr); + exit; + } //else { dbg("dbg->activateAttack: '"& getPlayerName(player) &"' no undefended human derricks to attack found",player); } + } + } + } + } + + } // if ( !bFinalAttack_1vs1 ){ + +} +//=========================================================================== +event TankAttack(inactive) +{ + + local int _distFromObj; + + ASSERT(player >= 0 and player < 8, "player out of bounds: TankAttack " & player, player); + //if ( gameTime - lastDisplayAI >= 10 ){ + //dbg("dbg->TankAttack : tank ("& tankGroup.members &") bTankAlreadyGathered("& bTankAlreadyGathered &") targ("& targetPlayerTank &") x-Y("& tankAttackX &")("& tankAttackY &") ",player); + //} + + //do a preliminary check + if ( tankGroup.members < MIN_SURVIVOR_TANKS and !bAttackedHumanDerrick){ + if (tankGroup.members>0){ + groupAddGroup(tankDefGroup , tankGroup); + } + deactivateTankAttack(); + exit;//this is necessary otherwise the event proceeeds! + } + + //get target for the first attack, further targets are chosen below + if ( attackTankObj == NULLOBJECT and !bTankAlreadyGathered ){ + attackTankObj = getTargetObj(); + if ( attackTankObj != NULLOBJECT ){ + //dbg("dbg->TankAttack: Player '"& getPlayerName(player) & "' attacking with "& tankGroup.members &" units enemy player '"& getPlayerName(attackTankObj.player) &"'' at coord "& attackTankObj.x/TILE &"-"& attackTankObj.y/TILE , player); + if ( isHumanPlayer(attackTankObj.player) ){ + nAttHumanPlayer++; + dropBeaconToAllies("Player "& getPlayerName(player) & " attacking "& getPlayerName(attackTankObj.player) &" with "& tankGroup.members &" droids" ,attackTankObj.x, attackTankObj.y, 0, true); + printDebug1("TankAttack: attacking human player '"& getPlayerName(attackTankObj.player) &"' with ("& tankGroup.members &")"); + } else { + nAttAIPlayer++; + dropBeaconToAllies("go!" ,attackTankObj.x, attackTankObj.y, 0, false); + printDebug1("TankAttack: attacking AI player '"& getPlayerName(attackTankObj.player) &"' with ("& tankGroup.members &")"); + } + } + } + + if ( attackTankObj == NULLOBJECT ){ + if ( bTankAlreadyGathered ){ + //get a new target in area + attackTankObj = objDroidTargetInRange(tankAttackX,tankAttackY,TILE*25,false); + if (attackTankObj == NULLOBJECT){ + attackTankObj = objStrTargetInRange(tankAttackX,tankAttackY,TILE*25); + } + + if (attackTankObj != NULLOBJECT){ + //collect info + targetPlayerTank = attackTankObj.player; + targetPlayerVTOL = targetPlayerTank; + tankAttackX = attackTankObj.x; + tankAttackY = attackTankObj.y; + orderGroupScoutCMD(tankGroup, tankAttackX, tankAttackY); + //orderGroupObj( tankGroup, DORDER_ATTACK, attackTankObj ); + //dbg("dbg->TankAttack: attacking tankAttackX("& tankAttackX/TILE &")-("& tankAttackY/TILE &")",player); + //orderGroupObj( tankGroup, DORDER_ATTACK, attackTankObj ); + } else { + //dbg("dbg->TankAttack: deactivate attack",player); + groupAddGroup(tankDefGroup , tankGroup); + deactivateTankAttack(); + } + } //else { displayMsg("TankAttack: ________________ FIRST TARGET NOT FOUND ___________________"); } + exit; + + } else { // ____ attackTankObj != NULLOBJECT ______ + + //collect all obj info, later on this object could be dead... + _distFromObj = 13*TILE + (((mapWidth*TILE+mapHeight*TILE)/2) / 40 ); + targetPlayerTank = attackTankObj.player; + targetPlayerVTOL = targetPlayerTank; + tankAttackX = attackTankObj.x; + tankAttackY = attackTankObj.y; + + //determine gathering positions, 12 tiles away from it + //send tanks to gathering positions + if ( !lTankSentToGatheringPoint ){ + if (nTankGatheringX <= 0 and nTankGatheringY <= 0){ + + count = random(3); + if ( count == 0 ){ //between bases + if ( attackTankObj.x > baseX ){ + count2 = baseX + (attackTankObj.x-baseX)/2; + } else { + count2 = baseX - (baseX-attackTankObj.x)/2; + } + if ( attackTankObj.y > baseY ){ + count3 = baseY + (attackTankObj.y-baseY)/2; + } else { + count3 = baseY - (baseY-attackTankObj.y)/2; + } + nTankGatheringX = getCoordRelated(count2, count3, baseX, baseY, 1, 1*TILE); + nTankGatheringY = getCoordRelated(count2, count3, baseX, baseY, 2, 1*TILE); + } + if ( count == 1 ){ //centre of the map + count2 = (mapWidth*TILE)/2; + count3 = (mapHeight*TILE)/2; + nTankGatheringX = getCoordRelated(count2, count3, baseX, baseY, 1, 1*TILE); + nTankGatheringY = getCoordRelated(count2, count3, baseX, baseY, 2, 1*TILE); + } + if ( count == 2 ){ //standard + nTankGatheringX = getCoordRelated(attackTankObj.x, attackTankObj.y, baseX, baseY, 1, _distFromObj); + nTankGatheringY = getCoordRelated(attackTankObj.x, attackTankObj.y, baseX, baseY, 2, _distFromObj); + } + + } + //centre of the map. + if (nTankGatheringX <= 0 or nTankGatheringY <= 0) { + nTankGatheringX = (mapWidth*TILE)/2; + nTankGatheringY = (mapHeight*TILE)/2; + } + + orderGroupLoc(tankGroup,DORDER_MOVE,nTankGatheringX,nTankGatheringY); + lTankSentToGatheringPoint = true; + tTanksSentToGathering = gameTime; + } + + //check if tank group has arrived at gathring point, need to check the distance too!!! + if ( !bTankAlreadyGathered ){ + //displayMsg(" tanks ("& idleGroup(tankGroup) &"/"& tankGroup.members &") dist("& distBetweenTwoPoints(tankGroup.x, tankGroup.y, nTankGatheringX, nTankGatheringY)/TILE &") ("& gameTime - tTanksSentToGathering &"/2400 "); + if ( (float)idleGroup(tankGroup) > (float)tankGroup.members*0.8 or distBetweenTwoPoints(tankGroup.x, tankGroup.y, nTankGatheringX, nTankGatheringY) < 4 * TILE or gameTime - tTanksSentToGathering > 2400 ) + { + bTankAlreadyGathered = true; + nTankGatheringX = -1; + nTankGatheringY = -1; + tTanksSentToGathering = 0; + orderGroupScoutCMD(tankGroup,tankAttackX,tankAttackY); + + } else { + + //just "rememeber" tanks where to go... + if ( gameTime - tTanksReSentToGathering > 70 ){ + if (bAttackTeamAttacked){ + orderGroupScoutCMD(tankGroup,nTankGatheringX,nTankGatheringY); + }else{ + orderGroupLoc(tankGroup,DORDER_MOVE,nTankGatheringX,nTankGatheringY); + } + tTanksReSentToGathering = gameTime; + if ( tTanksSentToGathering < 0){tTanksSentToGathering = gameTime;} + } + } + + } else {//bTankAlreadyGathered == TRUE + + //check if target has been destroyed + if ( structInRange(targetPlayerTank, tankAttackX, tankAttackY, 2*TILE ) or droidInRange(targetPlayerTank, tankAttackX, tankAttackY, 2*TILE ) ){ + if ( gameTime - tTankAttackAction > 100 ){ + //dbg("dbg->TankAttack: attacking again tankAttackX("& tankAttackX/TILE &")-("& tankAttackY/TILE &")",player); + orderGroupScoutCMD(tankGroup,tankAttackX, tankAttackY);//DORDER_SCOUT + tTankAttackAction = gameTime; + } + } + + } + } +} +//=========================================================================== +event CyborgAttack(inactive)//Original event ID: xx (of 106) +{ + local int _distFromObj; + + ASSERT(player >= 0 and player < 8, "player out of bounds: CyborgAttack " & player, player); + //dbg("dbg->CyborgAttack: '"& getPlayerName(player) &"' cyborgs ("& cyborgAttGroup.members &") CALLED bCybAlreadyGathered("& bCybAlreadyGathered &") targ("& targetPlayerCyb &") x-Y("& cybAttackX &")("& cybAttackY &")",player); + + //do a preliminary check + if ( cyborgAttGroup.members < MIN_SURVIVOR_CYBORGS and !bAttackedHumanDerrick){ + //displayMsg("CyborgAttack: ________________ STOP CYBORG ATTACK - cyborgAttGroup.members < MIN_SURVIVOR_CYBORGS___________________"); + //displayMsg("CyborgAttack: cyborgAttGroup.members ("& cyborgAttGroup.members &") < MIN_SURVIVOR_CYBORGS ("& MIN_SURVIVOR_CYBORGS &") alertLevel ("& alertLevel &") "); + if (cyborgAttGroup.members > 0){ + groupAddGroup(cyborgDefGroup , cyborgAttGroup); + } + deactivateCybAttack(); + exit; + } + + //get target + //displayMsg("CyborgAttack: ________________ START CYBORG ATTACK ___________________"); + + if ( attackCybObj == NULLOBJECT ){ + + if ( bCybAlreadyGathered ){ + //get a new target in area + attackCybObj = objDroidTargetInRange(cybAttackX,cybAttackY,TILE*25,false); + if (attackCybObj == NULLOBJECT){ + attackCybObj = objStrTargetInRange(cybAttackX,cybAttackY,TILE*25); + } + if (attackCybObj != NULLOBJECT){ + //collect info + targetPlayerCyb = attackCybObj.player; + targetPlayerVTOL = targetPlayerCyb; + cybAttackX = attackCybObj.x; + cybAttackY = attackCybObj.y; + + //dbg("CyborgAttack: ________________ CYBORG ATTACK NEW TARGET IN AREA ___________________",player); + //dbg("CyborgAttack: move all ("& cyborgAttGroup.members &") attacking struct/droid ("& cybAttackX/128 &"-"& cybAttackY/128 &") ",player); + tCybAttackAction = gameTime; + orderGroupScoutCMD(cyborgAttGroup, cybAttackX, cybAttackX); + } else { + //displayMsg("CyborgAttack: ________________ CYBORG ATTACK DEACTIVATED - ALL TARGETS IN RANGE HAVE BEEN DESTROYED___________________"); + if (cyborgAttGroup.members>0){ + groupAddGroup(cyborgDefGroup , cyborgAttGroup); + } + deactivateCybAttack(); + } + + } else { // NOT bCybAlreadyGathered + + //displayMsg("#### CyborgAttack: First target not found"); + attackCybObj = getTargetObj(); + if ( attackCybObj != NULLOBJECT ){ + if ( isHumanPlayer(attackCybObj.player) ){ + nAttHumanPlayer++; + dropBeaconToAllies("Player "& getPlayerName(player) & " attacking "& getPlayerName(attackCybObj.player) &" with "& cyborgAttGroup.members &" droids" ,attackCybObj.x, attackCybObj.y, 0, true); + printDebug1("CyborgAttack: attacking Human player '"& getPlayerName(attackCybObj.player) &"' with "& cyborgAttGroup.members &" droids "); + } else { + nAttAIPlayer++; + dropBeaconToAllies("go!" ,attackCybObj.x, attackCybObj.y, 0, false); + printDebug1("CyborgAttack: attacking AI player '"& getPlayerName(attackCybObj.player) &"' with "& cyborgAttGroup.members &" droids"); + } + } + exit; + } + + } else { //attackCybObj != NULLOBJECT + + //collect all obj info, later on this object could be dead... + _distFromObj = 13*TILE + (((mapWidth*TILE+mapHeight*TILE)/2) / 40 ); + targetPlayerCyb = attackCybObj.player; + targetPlayerVTOL = targetPlayerCyb; + cybAttackX = attackCybObj.x ; + cybAttackY = attackCybObj.y ; + + //determine gathering positions, 12 tiles away from it + //send cyborgs to gathering positions + if ( !lCybSentToGatheringPoint ){ + + if (nCybGatheringX <= 0 and nCybGatheringX <= 0){ + + count = random(3); + count2 = (mapWidth*TILE+mapHeight*TILE)/2; + + if ( count == 0 ){ + if ( attackCybObj.x > baseX ){ + count2 = baseX + (attackCybObj.x-baseX)/2; + } else { + count2 = baseX - (baseX-attackCybObj.x)/2; + } + if ( attackCybObj.y > baseY ){ + count3 = baseY + (attackCybObj.y-baseY)/2; + } else { + count3 = baseY - (baseY-attackCybObj.y)/2; + } + nCybGatheringX = getCoordRelated(count2, count3, baseX, baseY, 1, 1*TILE); + nCybGatheringY = getCoordRelated(count2, count3, baseX, baseY, 2, 1*TILE); + //displayMsg("### CyborgAttack: gathering point 1 selected (between bases)"); + } + if ( count == 1 ){ //centre of the map + count2 = (mapWidth*TILE)/2; + count3 = (mapHeight*TILE)/2; + nCybGatheringX = getCoordRelated(count2, count3, baseX, baseY, 1, 1*TILE); + nCybGatheringY = getCoordRelated(count2, count3, baseX, baseY, 2, 1*TILE); + //displayMsg("### CyborgAttack: gathering point 2 selected (centre of Map)"); + } + if ( count == 2 ){ //standard + nCybGatheringX = getCoordRelated(attackCybObj.x, attackCybObj.y, baseX, baseY, 1, _distFromObj); + nCybGatheringY = getCoordRelated(attackCybObj.x, attackCybObj.y, baseX, baseY, 2, _distFromObj); + //displayMsg("### CyborgAttack: gathering point 3 selected (standard)"); + } + + } + //centre of the map. + if (nCybGatheringX <= 0 or nCybGatheringY <= 0) { + //displayMsg("### CyborgAttack: had to force the gathering point in the centre of the map"); + nCybGatheringX = (mapWidth*TILE)/2; + nCybGatheringY = (mapHeight*TILE)/2; + } + + //displayMsg("CyborgAttack: ________________ SEND CYBORG TO GATHERING POINT ___________________"); + //displayMsg("CyborgAttack: cSend ("& cyborgAttGroup.members &") Cyborgs to coord ("& nCybGatheringX/TILE &"-"& nCybGatheringY/TILE &") enemy ("& targetPlayerCyb &") obj coord ("& cybAttackX/TILE &"-"& cybAttackY/TILE &")"); + orderGroupLoc(cyborgAttGroup,DORDER_MOVE,nCybGatheringX,nCybGatheringY); + lCybSentToGatheringPoint = true; + tCybSentToGathering = gameTime; + } + + //check if Cyborgs group has arrived at gathring point, need to check the distance too!!! + if ( !bCybAlreadyGathered ) { + + if ( (float)idleGroup(cyborgAttGroup) > (float)cyborgAttGroup.members*0.8 or distBetweenTwoPoints(cyborgAttGroup.x, cyborgAttGroup.y, nCybGatheringX, nCybGatheringY) < 4 * TILE or gameTime - tCybSentToGathering > 2400) { + //displayMsg("CyborgAttack: ________________ CYBORGS ARRIVED AT GATHERING POINT ___________________"); + //displayMsg("CyborgAttack: ("& cyborgAttGroup.members &") Cyborgs arrrived at coord ("& nCybGatheringX/TILE &"-"& nCybGatheringY/TILE &") enemy ("& targetPlayerCyb &")"); + bCybAlreadyGathered = true; + nCybGatheringX = -1; + nCybGatheringY = -1; + tCybSentToGathering = 0; + orderGroupScoutCMD(cyborgAttGroup,cybAttackX,cybAttackY); + //displayMsg("CyborgAttack: cyborgs Attack player ("& targetPlayerCyb &") with ("& cyborgAttGroup.members &") at coord ("& cybAttackX/TILE &"-"& cybAttackY/TILE &")"); + } else { + + //just "rememeber" cyborgs where to go... + if ( gameTime - tCybReSentToGathering > 100 ){ + if (bAttackTeamAttacked){ + orderGroupScoutCMD(cyborgAttGroup,nCybGatheringX,nCybGatheringY); + }else{ + orderGroupLoc(cyborgAttGroup,DORDER_MOVE,nCybGatheringX,nCybGatheringY); + } + //displayMsg("CyborgAttack: remember ("& cyborgAttGroup.members &") cyborgs to gather at coord ("& nCybGatheringX/128 &"-"& nCybGatheringY/128 &") enemy ("& targetPlayerCyb &")"); + tCybReSentToGathering = gameTime; + if ( tCybSentToGathering < 0 ){ tCybSentToGathering = gameTime; } + } + } + + } else {//if ( bCybAlreadyGathered ) + + //check if target has been destroyed + if ( structInRange(targetPlayerCyb, cybAttackX, cybAttackY, 2*TILE ) or droidInRange(targetPlayerCyb, cybAttackX, cybAttackY, 2*TILE ) ){ + if ( gameTime - tCybAttackAction > 100 ){ + tCybAttackAction = gameTime; + //orderGroupLoc(cyborgAttGroup,DORDER_SCOUT,cybAttackX,cybAttackY); + orderGroupScoutCMD(cyborgAttGroup,cybAttackX, cybAttackY); + //dbg("CyborgAttack: cyborgs re-attack with ("& cyborgAttGroup.members &") cyborgs at coord ("& cybAttackX/128 &"-"& cybAttackY/128 &")",player); + } + } + + } + } ////attackCybObj != NULLOBJECT +} + + + +//================================================================ +// CALL_ATTACKED, player, ref myBaseObject, ref enemyBaseObject +event AIattacked(AIattackedTr) //event 20 +{ + local DROID _droid,_droid2; + local STRUCTURE _structure,_structure2; + local bool bProceed,_bAttackedByVTOL; + local int _nDistFromBase, _nDistFromEnemy, _nAA; + + /* + if( !aiResponsibleForPlayer(player) ) + { + setEventTrigger(AIattacked,inactive); + } + else + { + */ + ASSERT(player >= 0 and player < 8, "player out of bounds: myDroidAttacked " & player, player); + + bProceed = true; + + if ( gameTime - alertTime < 80 ){ exit; } + + if(enemyBaseObject != NULLOBJECT and myBaseObject != NULLOBJECT){ + _nDistFromEnemy = distBetweenTwoPoints(myBaseObject.x, myBaseObject.y, enemyBaseObject.x, enemyBaseObject.y); + _nDistFromBase = distBetweenTwoPoints(baseX, baseY, myBaseObject.x, myBaseObject.y); + } else { + exit; + } + + if (enemyBaseObject.type == OBJ_DROID){ + _droid2 = objToDroid(enemyBaseObject); + if ( isVtol(_droid2) ) { + _bAttackedByVTOL = true; + bAttackedByVTOL = true; + } else { + _bAttackedByVTOL = false; + } + } + + //recall to base if buildGroup, buildDefGroup or cyborgConstructGroup + if( myBaseObject.type == OBJ_DROID ){ + _droid = objToDroid(myBaseObject); + if(_droid.group == buildGroup or _droid.group == buildDefGroup or _droid.group == cyborgConstructGroup){ + if ( _nDistFromBase > nBaseRange ){ + //dbg("dbg->AIattacked: send RTB attacked truck ("& _droid.id &")",player); + orderDroid( _droid, DORDER_RTB); + } + } + } + + + //displayMsg("AIattacked: dist myOBJ from base/def Range ("& _nDistFromBase/TILE &"/"& nDefendRange/TILE &") dist my obj/en obj ("& _nDistFromEnemy/TILE &")"); + if (_nDistFromBase > nDefendRange){ + //dbg("attacked outside defend range: ("& _nDistFromBase/TILE &"/"& nDefendRange/TILE &") dist my obj en obj ("& _nDistFromEnemy/TILE &")",player); + if( myBaseObject.type == OBJ_DROID ){ + _droid = objToDroid(myBaseObject); + if(_droid.group == tankGroup or _droid.group == cyborgAttGroup or _droid.group == helpGroup){ + if (enemyBaseObject.type == OBJ_DROID){ + if ( !_bAttackedByVTOL ) { + bAttackTeamAttacked = true;//activates single unit order instead of group order + } + } + } + } else {//myBaseObject.type == OBJ_STRUCTURE + //order VTOLs to defend this structure + if( !_bAttackedByVTOL ){ + if ( vtolDefendGr.members > 0 and defTargetVTOL == NULLOBJECT ){ + _nAA = numEnemyAAInRange(enemyBaseObject.x, enemyBaseObject.y, AA_THREAT_RANGE); + if ( _nAA*3 < vtolDefendGr.members ){ + defTargetVTOL = enemyBaseObject; + targetPlayerVTOL = enemyBaseObject.player; + tTargetTime = gameTime; + //bVTOLTargetIsDerrick = false; + //dbg("dbg->AIattacked: order VTOL to defend structure and attack at ("& enemyBaseObject.x/TILE &"-"& enemyBaseObject.y/TILE &"), dist from base("& _nDistFromBase/TILE &")",player); + } + } + } + } + exit; + } + + //check if attacked by mortars!!! + if ( !_bAttackedByVTOL ){ + if ( _nDistFromEnemy > 16*TILE and _nDistFromEnemy < 19*TILE ){ + bAttackedByMortars = true;//activate research + nKineticX = myBaseObject.x; + nKineticY = myBaseObject.y; + //dbg("dbg->AIattacked: '"& getPlayerName(player) &"' attacked by long range weapons ("& _nDistFromBase/TILE &"/"& nDefendRange/TILE &") dist my obj en obj ("& _nDistFromEnemy/TILE &")",player); + if ( numEnemyAAInRange(enemyBaseObject.x, enemyBaseObject.y, AA_THREAT_RANGE) < 2 ){ + defTargetVTOL = enemyBaseObject; + targetPlayerVTOL = enemyBaseObject.player; + bVTOLTargetIsDerrick = false; + tTargetTime = gameTime; + } + bProceed = true; //send also def troops to attack + setEventTrigger(defFromLongRangeWeap,defFromLongRangeWeapTr); //build + //attacked by ripple rockets or other very long range kinetic turrets + } else if ( _nDistFromEnemy >= 19*TILE ){ + bAttackedByLongRangeWeap = true; + nKineticX = myBaseObject.x; + nKineticY = myBaseObject.y; + //dbg("dbg->AIattacked: '"& getPlayerName(player) &"' attacked by very long range weapon ("& _nDistFromBase/TILE &"/"& nDefendRange/TILE &") dist my obj en obj ("& _nDistFromEnemy/TILE &")",player); + if ( numEnemyAAInRange(enemyBaseObject.x, enemyBaseObject.y, AA_THREAT_RANGE) < 2 ){ + defTargetVTOL = enemyBaseObject; + targetPlayerVTOL = enemyBaseObject.player; + bVTOLTargetIsDerrick = false; + tTargetTime = gameTime; + } + if ( _nDistFromEnemy >=19 and _nDistFromEnemy <= 22 ){ + bProceed = true; + } else { + bProceed = false; //too far away + } + setEventTrigger(defFromLongRangeWeap,defFromLongRangeWeapTr); + } else { + //dbg("dbg->AIattacked: Not Attacked by long range weapons",player); + bProceed = true; + } + } + + if(bProceed and gameTime - alertTime > 50){ + if(enemyBaseObject != NULLOBJECT and myBaseObject != NULLOBJECT){ + + if (enemyBaseObject.type == OBJ_DROID){ + _droid2 = objToDroid(enemyBaseObject); + attackedByDroid(_droid2); + } + if (enemyBaseObject.type == OBJ_STRUCTURE){ + _structure2 = objToStructure(enemyBaseObject); + attackedByStruct(_structure2); + } + + //displayMsg("AIattacked: ACTIVATED alertTime=("& gameTime &")"); + if ( !_bAttackedByVTOL ){ + + + if (gameTime - alertTime > 10){ + gatherDefTankX = getCoordRelated(myBaseObject.x, myBaseObject.y, baseX, baseY, 1, 8*TILE); + gatherDefTankY = getCoordRelated(myBaseObject.x, myBaseObject.y, baseX, baseY, 2, 8*TILE); + gatherDefCybX = getCoordRelated(myBaseObject.x, myBaseObject.y, baseX, baseY, 1, 12*TILE); + gatherDefCybY = getCoordRelated(myBaseObject.x, myBaseObject.y, baseX, baseY, 2, 12*TILE); + //dbg("dbg->AIattacked: Attack data stored: base("& baseX/TILE &"-"& baseY/TILE &") myOBJ("& myBaseObject.x/TILE &"-"& myBaseObject.x/TILE &") gath("& gatherDefTankX/TILE &"-"& gatherDefTankY/TILE &") dist myOBJ from base("& _nDistFromBase/TILE &"/"& nDefendRange/TILE &") dist myOBJ from EnOBJ("& _nDistFromEnemy/TILE &")",player); + //printDebug1("AIattacked: Attack data stored, base("& baseX/TILE &"-"& baseY/TILE &") myOBJ("& myBaseObject.x/TILE &"-"& myBaseObject.x/TILE &") gath("& gatherDefTankX/TILE &"-"& gatherDefTankY/TILE &") dist myOBJ from base("& _nDistFromBase/TILE &"/"& nDefendRange/TILE &") dist myOBJ from EnOBJ("& _nDistFromEnemy/TILE &")"); + } + + alertTime = gameTime; + alertIsOn = true; + alertX = enemyBaseObject.x; + alertY = enemyBaseObject.y; + + //remember coord of attacked obj: build defences + if ( gameTime - nLastDefSpotUpdate > 5*TIME_MINUTE ) { + defSpotX = myBaseObject.x; + defSpotY = myBaseObject.y; + nLastDefSpotUpdate = gameTime; + } + } + + } // if(enemyBaseObject != NULLOBJECT and myBaseObject != NULLOBJECT){ + } //if(bProceed and gameTime - alertTime > 50){ + //} +} +//-------------------------------------------------------------- +event manageDefTank( inactive ) +{ + + local int _x,_y,_x1,_y1, _nDist; + + ASSERT(player >= 0 and player < 8, "player out of bounds: manageDefTank " & player, player); + eventCheckTime[6] = gameTime; + + //if ( gameTime - lastDisplayAI >= 80 ){ + //displayMsg("manageDefTank: defTK ("& tankDefGroup.members &") at("& tankDefGroup.x/TILE &"-"& tankDefGroup.y/TILE &") alertIsOn ("& alertIsOn &") alertX ("& alertX/TILE &")("& alertY/TILE &") alertTime ("& alertTime &") alert level ("& alertLevel &")______"); + //} + + if( alertLevel == RED_ALERT and gameTime > 10*TIME_MINUTE ){ + if ( alertX >= 0 and alertY >= 0 ){ + dropBeaconToAllies("help" , alertX, alertY, 0, true); + dropBeaconToAllies("help" , alertX, alertY, 0, false); + } + } + + + if( tankDefGroup.members == 0 ){ exit; } + + if ( gatherDefTankX >= 0 and gatherDefTankY >= 0 ){ + count2 = distBetweenTwoPoints(gatherDefTankX,gatherDefTankY,baseX,baseY); + //bring def units back at home + if ( count2 > nDefendRange ){ + gatherDefTankX = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 1, 8*TILE); + gatherDefTankY = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 2, 8*TILE); + } + } else { + gatherDefTankX = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 1, 8*TILE); + gatherDefTankY = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 2, 8*TILE); + } + //check is not -1; + if ( gatherDefTankX == -1 ){ gatherDefTankX = baseX; gatherDefTankY = baseY; } + if ( gatherDefTankY == -1 ){ gatherDefTankX = baseX; gatherDefTankY = baseY; } + + //if an ALERT is on send to ALERT coord + if ( alertIsOn ){ + + //displayMsg("manageDefTank: ______ ("& distBetweenTwoPoints(baseX,baseY,alertX,alertY)/TILE &")/("& nDefendRange/TILE &")________________"); + //if in baseRange attack with all Deftanks otherwise wait until enough forces are collected + _nDist = distBetweenTwoPoints(tankDefGroup.x,tankDefGroup.y,alertX,alertY); + if ( _nDist > 1*TILE and gameTime - tDefTankAction > 50 and (tankDefGroup.members >= MIN_DEFUNIT_DEFEND) ){ + orderGroupScoutCMD(tankDefGroup,alertX,alertY); + tDefTankAction = gameTime; + } + + } else { //alert is not ON + + //reset alert coord + if (cybAlertX > 0){cybAlertX = -1;cybAlertY = -1;} + + //get a target or gather coord + if ( distBetweenTwoPoints(tankDefGroup.x, tankDefGroup.y,baseX,baseY) < nDefendRange) + { + + if ( objTargetTankDefGRP == NULLOBJECT ){ + objTargetTankDefGRP = objDroidTargetInRange(baseX,baseY,nDefendRange,false); + } + if ( objTargetTankDefGRP == NULLOBJECT ){ + objTargetTankDefGRP = objStrTargetInRange(baseX,baseY,nDefendRange); + } + + //target found! + if ( objTargetTankDefGRP != NULLOBJECT and tankDefGroup.members >= MIN_DEFUNIT_ATTACK ){ + if ( gameTime - tDefTankAction > 60 ){ + if ( distBetweenTwoPoints(tankDefGroup.x, tankDefGroup.y, objTargetTankDefGRP.x, objTargetTankDefGRP.y) > 2*TILE ){ + //displayMsg("manageDefTank: _____________attacking enemy in def range__________"); + orderGroupScoutCMD(tankDefGroup,objTargetTankDefGRP.x,objTargetTankDefGRP.y); + tDefTankAction = gameTime; + } + } + + } else {//no enemy in range, return to gathering point + + if ( distBetweenTwoPoints(tankDefGroup.x,tankDefGroup.y,gatherDefTankX,gatherDefTankY) > 3*TILE and gameTime - tDefTankAction > 60){ + //displayMsg("manageDefTank: _____________back to gathering point __________"); + orderGroupScoutCMD(tankDefGroup,gatherDefTankX,gatherDefTankY); + tDefTankAction = gameTime; + } + + } + + } else {//return togathering point + + objTargetTankDefGRP = NULLOBJECT; + if ( distBetweenTwoPoints(tankDefGroup.x,tankDefGroup.y,gatherDefTankX,gatherDefTankY) > 3*TILE and gameTime - tDefTankAction > 60) + { + //displayMsg("manageDefTank: _____________back to gathering point (1)__________"); + orderGroupScoutCMD(tankDefGroup,gatherDefTankX,gatherDefTankY); + tDefTankAction = gameTime; + } + + } + + + }//alertIsOn +} + +//====================================================== +event manageDefCyborgs (inactive)//event 18!!!! +{ + + local int _nUnitsToBeMoved,_nTotUnits,_nUnitsRequiredToAttack; + local int _x,_y,_x1,_y1,_nDist; + + + ASSERT(player >= 0 and player < 8, "player out of bounds: manageDefCyborgs " & player, player); + eventCheckTime[5] = gameTime; + //if ( gameTime - lastDisplayAI >= 90 ){ + //displayMsg("manageDefCyborgs: cyborgs ("& cyborgDefGroup.members &") CALLED ("& alertIsOn &") ("& alertX &"-"& alertY &") "); + //} + + if( cyborgDefGroup.members == 0 ){ exit; } + + if ( gatherDefCybX >= 0 and gatherDefCybY >= 0 ){ + count2 = distBetweenTwoPoints(gatherDefCybX,gatherDefCybY,baseX,baseY); + if ( count2 > nDefendRange ){ + gatherDefCybX = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 1, 8*TILE); + gatherDefCybY = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 2, 8*TILE); + } + } else { + gatherDefCybX = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 1, 8*TILE); + gatherDefCybY = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 2, 8*TILE); + } + if ( gatherDefCybX == -1 ){ gatherDefCybX = baseX; gatherDefCybY = baseY; } + if ( gatherDefCybY == -1 ){ gatherDefCybX = baseX; gatherDefCybY = baseY; } + + if ( alertIsOn ) + { + + //set alert coord if not done already + if (cybAlertX < 0 or (cybAlertX != alertX) ){ + if(alertX > 0){ + cybAlertX = alertX; + cybAlertY = alertY; + } + } + + //go to alert coord + _nDist = distBetweenTwoPoints(cyborgDefGroup.x,cyborgDefGroup.y,alertX,alertY); + //displayMsg("manageDefCyborgs: cyborgs ("& cyborgDefGroup.members &") CALLED ("& alertIsOn &") _nDist("& _nDist/TILE &")"); + if ( _nDist > 1*TILE and gameTime - tDefCybAction > 50 and (cyborgDefGroup.members >= MIN_DEFCYB_DEFEND)){ + orderGroupScoutCMD(cyborgDefGroup,cybAlertX,cybAlertY); + tDefCybAction = gameTime; + } //else{ displayMsg("####### manageDefCyborgs: cybAlertX < 0??? "); } + + } else {//def alert not active + + if (cyborgDefGroup.members >= MIN_DEFUNIT_ATTACK ){ + + //reset alert coord + if (cybAlertX > 0){cybAlertX = -1;cybAlertY = -1;} + + //enemy droid or struct in Cyborg Range? + count = distBetweenTwoPoints(cyborgDefGroup.x, cyborgDefGroup.y, baseX, baseY); + if ( count < nDefendRange ){ + + //enemies in nDefendRange? + if ( objTargetCybDefGRP == NULLOBJECT ){ + objTargetCybDefGRP = objStrTargetInRange(baseX,baseY,nDefendRange); + } + if ( objTargetCybDefGRP == NULLOBJECT ){ + objTargetCybDefGRP = objDroidTargetInRange(baseX,baseY,nDefendRange,false); + } + //if no targets go back to gathering points + if ( objTargetCybDefGRP == NULLOBJECT ){ + if ( distBetweenTwoPoints(cyborgDefGroup.x,cyborgDefGroup.y,gatherDefCybX,gatherDefCybY) > 3*TILE and gameTime - tDefCybAction > 60){ + orderGroupScoutCMD(cyborgDefGroup,gatherDefCybX,gatherDefCybY); + tDefCybAction = gameTime; + } + } else { + //Attack enemy in defend range!!! + if ( gameTime - tDefCybAction > 60 ){ + count = distBetweenTwoPoints(cyborgDefGroup.x, cyborgDefGroup.y, objTargetCybDefGRP.x, objTargetCybDefGRP.y); + if ( count > 2*TILE ){ + orderGroupScoutCMD(cyborgDefGroup, objTargetCybDefGRP.x, objTargetCybDefGRP.y); + tDefCybAction = gameTime; + } + } + + } + + } else { //count > nDefendRange, send units back!! + + if ( distBetweenTwoPoints(cyborgDefGroup.x,cyborgDefGroup.y,gatherDefCybX,gatherDefCybY) > 3*TILE and gameTime - tDefCybAction > 60){ + orderGroupScoutCMD(cyborgDefGroup,gatherDefCybX,gatherDefCybY); + tDefCybAction = gameTime; + } + + } + + } else {//cyborgDefGroup.members < MIN_DEFUNIT_ATTACK + + if ( gameTime - tDefCybAction > 60){ + if ( distBetweenTwoPoints(cyborgDefGroup.x,cyborgDefGroup.y,gatherDefCybX,gatherDefCybY) > 3*TILE and gameTime - tDefCybAction > 60){ + orderGroupScoutCMD(cyborgDefGroup,gatherDefCybX,gatherDefCybY); + tDefCybAction = gameTime; + } + } + } + } //alertIsOn +} +//=================================================================== +//manages idle buildGrp,harvGrp,buildDefGrp and CybEng Grp +//does not use any money, only help and repairTaks +event manageIdleTrucks(inactive) +{ + + ASSERT(player >= 0 and player < 8, "player out of bounds: manageIdleTrucks " & player, player); + eventCheckTime[7] = gameTime; + //dbg("manageIdleTrucks: ________________ START 1__________________",player); + if ( gameTime < 300 ) { exit; } + + boolResult = true; + boolResult2 = true; + boolResult3 = true; + + //force helpbuild of derricks + initEnumStruct(FALSE,derrick,player,player); + structure = enumStruct(); + while (structure != NULLOBJECT){ + if(!structureComplete(structure)){ + if ( !threatInRange(player,structure.x, structure.y, THREAT_RANGE_TILES_SHORT*128, false) ) + { + + _idleTruck = pickCybEng(true); + if (_idleTruck == NULLOBJECT){ + _idleTruck = closestIdleDroid(buildGroup,baseX, baseY); + } + if (_idleTruck != NULLOBJECT){ + if (droidCanReach(_idleTruck, structure.x, structure.y) ){ + //displayMsg("**** manageIdleTrucks: found a derrick not complete for droid ("& _idleTruck.id &") "); + orderDroidObj(_idleTruck,DORDER_HELPBUILD,structure); + } + } + + } //else {displayMsg("manageIdleTrucks: there is some threat in range of derrick");} + } + structure = enumStruct(); + } + + //force helpbuild of repair Facility first + initEnumStruct(FALSE,repairFacility,player,player); + structure = enumStruct(); + while (structure != NULLOBJECT){ + if(!structureComplete(structure)){ + if ( !threatInRange(player,structure.x, structure.y, THREAT_RANGE_TILES_SHORT*128, false) ) + { + _idleTruck = pickCybEng(true); + if (_idleTruck == NULLOBJECT){ + _idleTruck = closestIdleDroid(buildGroup,baseX, baseY); + } + if (_idleTruck != NULLOBJECT){ + if (droidCanReach(_idleTruck, structure.x, structure.y) ){ + //displayMsg("**** manageIdleTrucks: found a repairFacility not complete for droid ("& _idleTruck.id &") "); + orderDroidObj(_idleTruck,DORDER_HELPBUILD,structure); + } + } + } //else {displayMsg("manageIdleTrucks: there is some threat in range of repairFacility");} + } + structure = enumStruct(); + } + + + if ( (numAAinBase > 4 and bAttackedByVTOL) or !bAttackedByVTOL ) { + if( buildDefGroup.members>0 ){ + if (!repairDefStructs(BUILDDEF_GRP)){ + if ( !repairStructs(BUILDDEF_GRP) ){ + if ( !helpBuild(BUILDDEF_GRP) ){ + boolResult = helpBuild(BUILDDEF_GRP); + } + } //else {displayMsg("manageIdleTrucks: - nothing to do for BUILDDEF_GRP");} + } + } + } + + //if ( gameTime - lastDisplayAI >= 20 ){ displayMsg("manageIdleTrucks: ________________ START 2__________________"); } + if( cyborgConstructGroup.members>0 ){ + harvestNearOilRes(); + if ( !repairStructs(CYBENG_GRP) ){ + if (!repairDefStructs(BUILDDEF_GRP)){ + if ( !helpBuild(CYBENG_GRP) ){ + boolResult3 = repairDefStructs(CYBENG_GRP); + //if( !boolResult3 and gameTime > TIME_HARVESTING_PHASE ){ + //harvestNearOilRes(); + //} + } + } + } + } + //if ( gameTime - lastDisplayAI >= 20 ){ displayMsg("manageIdleTrucks: ________________ START 4__________________"); } + if( buildGroup.members>0 and lMinBaseStructBuilt ){ + if (!helpBuild(BUILD_GRP)){ + if ( !repairStructs(BUILD_GRP) ){ + boolResult2 = repairDefStructs(BUILD_GRP); + } //else {displayMsg("manageIdleTrucks: - nothing to do for BUILD_GRP");} + } + } + + //exit;// problems before + //if ( gameTime - lastDisplayAI >= 20 ){ displayMsg("manageIdleTrucks: ________________ START 5__________________"); } + //send all idle back to the base!!! + sendIdleBackToTheBase(BUILD_GRP); + sendIdleBackToTheBase(CYBENG_GRP); + sendIdleBackToTheBase(BUILDDEF_GRP); + + //if ( gameTime - lastDisplayAI >= 80 ){ displayMsg("manageIdleTrucks: ________________ STOP 6__________________");} + + +} +//================================================ +event manageRepairTeam(inactive) +{ + + ASSERT(player >= 0 and player < 8, "player out of bounds: manageRepairTeam " & player, player); + + //if ( gameTime - lastDisplayAI >= 80 ){ + //displayMsg("manageRepairTeam: _____________ START 1("& toBeRepairedCyborgGroup.members &")("& toBeRepairedTankGroup.members &")("& repairGroup.members &") _______________"); + //} + if (repairGroup.members < 0){exit;} + + //displayMsg("manageRepairTeam: _____________ START 2("& tankGroup.members &")("& toBeRepairedTankGroup.members &")("& repairGroup.members &") _______________"); + boolResult = true; + + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + //displayMsg("manageRepairTeam: _____________ START 3 ("& droid2.id &")_______________"); + droid = nearestDroidToBeRepaired(toBeRepairedTankGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in TankRepGroup ("& droid.id &"), health ("& droid.health &")"); + boolResult = false; + } //else { displayMsg("manageRepairTeam: toBeRepairedTankGroup ("& droid.id &") too far away from base"); } + } //else { displayMsg("manageRepairTeam: toBeRepairedTankGroup droid not found"); } + } //else { displayMsg("manageRepairTeam: idle repair droid not found"); } + + + if (boolResult){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(toBeRepairedCyborgGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in repairGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + + if (boolResult){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(buildGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in repairGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + + if (boolResult){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(harvesterGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in repairGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + + if (boolResult){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(buildDefGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in repairGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + + if (boolResult){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(cyborgConstructGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in repairGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + + if (boolResult){ + droid2 = idleRepairDroid(baseX,baseY);//this picks up + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(repairGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if( droid.id != droid2.id ){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nBaseRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in repairGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + } + + //modify -> force return to base even if not idle + initIterateGroup(repairGroup); + droid = iterateGroup(repairGroup); + while(droid != NULLOBJECT) + { + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) > nBaseRange+5*TILE ) { + //displayMsg("*** manageRepairTeam: send repair tank to RTB"); + orderDroid(droid, DORDER_RTB); + } + droid = iterateGroup(repairGroup); + } + + //As last chance let`s try to completely repair defend idle droids + if (boolResult and !alertIsOn){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(tankDefGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nDefendRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in tankDefGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + if (boolResult and !alertIsOn){ + droid2 = idleRepairDroid(baseX,baseY); + if ( droid2 != NULLOBJECT ) + { + droid = nearestDroidToBeRepaired(cyborgDefGroup, droid2.x, droid2.y); + if ( droid != NULLOBJECT){ + if ( distBetweenTwoPoints( droid.x, droid.y, baseX, baseY) < nDefendRange ) { + orderDroidObj(droid2, DORDER_DROIDREPAIR, droid); + //displayMsg("*** manageRepairTeam: found unit in cyborgDefGroup ("& droid.id &") to be repaired, health ("& droid.health &")"); + boolResult = false; + } + } + } + } + +} + +// ===================================================================== +event updateBaseDetails(inactive) +{ + ASSERT(player >= 0 and player < 8, "player out of bounds: updateBaseDetails " & player, player); + eventCheckTime[8] = gameTime; + + updateBaseRange(); + updateBaseCoord(); + updateBeacons(); + + //get all players stats + updatePlayersStats(); + + //units to attack with tanks + if ( tChangeTimeTankToAdd == 0 ){ tChangeTimeTankToAdd = tLastTankAttack; } + if ( gameTime - tChangeTimeTankToAdd > TIME_CHANGE_TANKSTOADD ){ + nAttackingUnitsToAdd = random(MAX_ATTACK_TANKS_ADD); + nCybAttUnitsToAdd = random(MAX_ATTACK_CYBORG_ADD); + tChangeTimeTankToAdd = gameTime; + } + + + //store the oliRes to get at the beginning + if( nTotOilInAtStart < nFreeOilRes ){ + nTotOilInAtStart = nFreeOilRes; + } + + updateDefendRange(); + + //checking if I have min numb of derricks; + if ( nPlayersInGame > 1 and nTotOilInAtStart > 0 ){ + if ( nMyDerricks-nDerricksAtStart < nTotOilInAtStart/nPlayersInGame ){ + bNeedDerrick = true; + } else { + bNeedDerrick = false; + } + } + + //build defense queue + count = 0; + pickDefQueueDepth = 0; + while(count < numDefStructs ) + { + if(isStructureAvailable(defStructs[count],player)){ + pickDefQueue[pickDefQueueDepth] = defStructs[count]; + pickDefQueueDepth = pickDefQueueDepth + 1; + } + count = count + 1; + } + + //build wall defense queue + count = 0; + pickWallDefQueueDepth = 0; + while( count < numWallWeaps ) + { + if( isStructureAvailable(wallWeaps[count],player) ){ + pickWallDefQueue[pickWallDefQueueDepth] = wallWeaps[count]; + pickWallDefQueueDepth = pickWallDefQueueDepth + 1; + } + count = count + 1; + } + + //Fortresses queue + count = 0; + pickFortQueueDepth = 0; + while(count < numFortressDef) + { + if(isStructureAvailable(fortressDef[count],player) ){ + pickFortQueue[pickFortQueueDepth] = fortressDef[count]; + pickFortQueueDepth = pickFortQueueDepth + 1; + } + count = count + 1; + } + + //update structs queue + count = 0; + pickStrQueueDepth = 0; + while(count < numStructs) + { + if(isStructureAvailable(structs[count],player) ) + { + pickStrQueue[pickStrQueueDepth] = structs[count]; + pickStrQueueDepth = pickStrQueueDepth + 1; + } + count = count + 1; + } + + +} + +// ============================ Debug messages==================== +event showPlayerInfo (inactive) +{ + ASSERT(player >= 0 and player < 8, "player out of bounds: showPlayerInfo " & player, player); + boolResult = true; +} + +//----------------------------------------------------------------- +event buildRepFirst(inactive) +{ + + local int _nMaxRepFac; + ASSERT(player >= 0 and player < 8, "player out of bounds:.5 " & player, player); + eventCheckTime[9] = gameTime; + + //displayMsg("lStopBuildRepFacility ("& lStopBuildRepFacility &") nPower("& nPower &")"); + if( !lStopBuildRepFacility ) + { + if (nMapPower <= LOW_POWER_MAP){ + _nMaxRepFac = 2; + } + if (nMapPower == NORMAL_POWER_MAP){ + _nMaxRepFac = 3; + } + if (nMapPower == HIGH_POWER_MAP){ + _nMaxRepFac = 5; + } + //check on quantity and avoid multiple contruction at time, build max repFac - 1 to keep one + // repFac to support attack team + if( numStructsByType(repairFacility, player) < _nMaxRepFac and (gameTime - nLastTimeBuiltRepFac) > 600 ) + { + boolResult = false; + if ( isStructureAvailable(repairFacility, player) ) + { + //returns _nWhichCooord(x or y) such that they are _nDist distance away from _x1/_y1 direction _x2,_y2 + buildX = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 1, nBaseRange/4); + buildY = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 2, nBaseRange/4); + + boolResult = pickStructLocation(repairFacility, ref buildX, ref buildY,player); + //DylanDog - BUG on BP2.92, the check on struct availability was not made + if(boolResult) + { + droid = closestDroidCanBuild(buildGroup,buildX,buildY); + if(droid != NULLOBJECT) + { + if (droidCanReach(droid, buildX, buildY) ){ + orderDroidStatsLoc(droid, DORDER_BUILD,repairFacility, buildX,buildY); + nLastTimeBuiltRepFac = gameTime; + } + } + } + } + } + } + +} + + +//====================================ADVANCED HARVESTER SCRIPT========================== +event harvesterOperate(inactive) +{ + ASSERT(player >= 0 and player < 8, "player out of bounds: harvesterOperate " & player, player); + eventCheckTime[10] = gameTime; + + //displayMsg("harvestOperate: called ("& bOilResLeft &") ("& harvesterGroup.members &")"); + + if ( !bOilResLeft ){ exit; } + + //stop moving to oilRes if a derrick is already built in that position or if a threat is present + stopDroidHarvesting(); + + _oilRes = NULLOBJECT; + + //reset if necessary oilResTargetId, oilResTargetX, oilResTargetY + checkDerrickIsBuilt(player); + + //nearest oilRes to base, try to pick up the nearest to the base as it is + //the easier to defend. + droid = closestIdleDroid(harvesterGroup,baseX, baseY); + if( droid != NULLOBJECT ) + { + _oilRes = closestOilRes(droid, droid.x, droid.y);//uses droidCanReach + } //else { displayMsg("harvesterOperate: no idle harvester trucks found"); } + //get the number of Derricks built + if ( _oilRes != NULLOBJECT ) + { + //displayMsg("harvesterOperate: oilRes found"); + if ( nMyDerricks < numMaxDerricks ) + { + //to avoid another droid target this oliRes + if( gameTime < TIME_HARVESTING_PHASE ){ + + _nOilRes = getOilResTargetFree(); + if ( _nOilRes > -1 and droidCanReach(droid, _oilRes.x, _oilRes.y) ){ + oilResTargetId[_nOilRes] = _oilRes.id; + oilResTargetX[_nOilRes] = _oilRes.x; + oilResTargetY[_nOilRes] = _oilRes.y; + orderDroidStatsLoc( droid, DORDER_BUILD, derrick, _oilRes.x, _oilRes.y); + //dbg("*** harvestOperate: droid ("& droid.id &") TARGET OilRes (" & _oilRes.id & ") oilResTargetId[" & _nOilRes & "] coord (" & _oilRes.x/TILE & "-" & _oilRes.y/TILE & ")",player ); + } + //else { + //dbg("*** harvestOperate: droid ("& droid.id &") ALREADY TARGETED OilRes (" & _oilRes.id & ") oilResTargetId[" & _nOilRes & "] coord (" & _oilRes.x/TILE & "-" & _oilRes.y/TILE & ")",player ); + //} + + } else {//============= HARVEST WITHOUT CHECKING oliRes TARGET + + //Check this oilRes is not too far away + //count = ((mapWidth+mapHeight)/2)*TILE; + //count = (count/3*2);//2/3 of the map + //count2 = distBetweenTwoPoints(_oilRes.x ,_oilRes.y , baseX , baseY); + if ( count2 < count and droidCanReach(droid, _oilRes.x, _oilRes.y) ) + { + + orderDroidStatsLoc( droid, DORDER_BUILD, derrick, _oilRes.x, _oilRes.y); + //displayMsg("*** harvestOperate: droid (" & droid.id & ") build DERRICK (" & _oilRes.id & ") oilResTargetId[" & _nOilRes & "] coord (" & _oilRes.x/TILE & "-" & _oilRes.y/TILE & ")" ); + } //else { displayMsg("harvesterOperate: oilRes is too far away ("& count2/TILE &" / "& count/TILE &") "); } + } + } + } //else { displayMsg("harvesterOperate: oilRes not found");} +} + + +//====================================================================== +event truckGroupSlider(inactive) +{ + + ASSERT(player >= 0 and player < 8, "player out of bounds: truckGroupSlider " & player, player); + eventCheckTime[11] = gameTime; + //displayMsg("truckGroupSlider 1: b("& buildGroup.members &") d("& buildDefGroup.members &") h("& harvesterGroup.members &") "); + //at this time the harvesting phase should be finished + if ( gameTime > TIME_HARVESTING_PHASE ){ + + //harvester are not required, move them to buildGRP and buildDefGRP + if ( !bOilResLeft ){ + + initIterateGroup(harvesterGroup); + droid = iterateGroup(harvesterGroup); + while(droid != NULLOBJECT) + { + if ( buildGroup.members > buildDefGroup.members ){ + //displayMsg("truckGroupSlider: Opt 1a - added a droid in buildDefGroup ("& buildDefGroup.members &") from harvesterGroup ("& harvesterGroup.members &")"); + groupAddDroid(buildDefGroup, droid ); + } else { + //displayMsg("truckGroupSlider: Opt 1b - added a droid in buildGroup ("& buildGroup.members &") from harvesterGroup ("& harvesterGroup.members &")"); + groupAddDroid(buildGroup, droid ); + } + droid = iterateGroup(harvesterGroup); + } + + } else { + + if ( harvesterGroup.members == 0 ){ + if ( buildGroup.members > buildDefGroup.members ){ + + droid = closestIdleDroid(buildGroup,baseX,baseY); + if (droid == NULLOBJECT){ droid = getADroid(buildGroup); } + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 2a - added a droid in harvesterGroup ("& harvesterGroup.members &") from buildGroup ("& buildGroup.members &")"); + groupAddDroid(harvesterGroup, droid ); + } + + } else { + + if (droid == NULLOBJECT){ droid = pickDefTruck(true); } + if (droid == NULLOBJECT){ droid = getADroid(buildDefGroup); } + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 2b - added a droid in harvesterGroup ("& harvesterGroup.members &") from buildDefGroup ("& buildDefGroup.members &")"); + groupAddDroid(harvesterGroup, droid ); + } + } + } + } + + } else {//initial phase, keep at least 2 harvester trucks, 1 buildGrp and 1 defGrp + + if ( bOilResLeft ){ + if ( harvesterGroup.members < 2 ){ + if ( buildDefGroup.members >= 1 ){ + droid = getADroid(buildDefGroup); + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 4a - added a droid in harvesterGroup ("& harvesterGroup.members &") from buildDefGroup ("& buildDefGroup.members &")"); + groupAddDroid(harvesterGroup, droid ); + } + } + } + if ( harvesterGroup.members < 2 ){ + if ( buildGroup.members > 1 ){ + droid = getADroid(buildGroup); + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 4b - added a droid in harvesterGroup ("& buildGroup.members &") from buildGroup ("& buildGroup.members &")"); + groupAddDroid(harvesterGroup, droid ); + } + } + } + } else { + if ( harvesterGroup.members > 0 ){ + initIterateGroup(harvesterGroup); + droid = iterateGroup(harvesterGroup); + while(droid != NULLOBJECT) + { + if ( buildGroup.members > buildDefGroup.members ){ + //displayMsg("truckGroupSlider: Opt 1a - added a droid in buildDefGroup ("& buildDefGroup.members &") from harvesterGroup ("& harvesterGroup.members &")"); + groupAddDroid(buildDefGroup, droid ); + } else { + //displayMsg("truckGroupSlider: Opt 1b - added a droid in buildGroup ("& buildGroup.members &") from harvesterGroup ("& harvesterGroup.members &")"); + groupAddDroid(buildGroup, droid ); + } + droid = iterateGroup(harvesterGroup); + } + } + } + + }//gametime > TIME_HARVESTING_PHASE + + //ensure a bit of balance between buildGrp and buildDef GRP + if ( !lMinBaseStructBuilt ){ + if ( buildDefGroup.members > buildGroup.members ){ + droid = getADroid(buildDefGroup); + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 1c - added a droid in buildGroup ("& buildGroup.members &") from buildDefGroup ("& buildDefGroup.members &")"); + groupAddDroid(buildGroup, droid ); + } + } + + if ( buildGroup.members > buildDefGroup.members+1 ){ + droid = getADroid(buildGroup); + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 1d - added a droid in buildDefGroup ("& buildDefGroup.members &") from buildGroup ("& buildGroup.members &")"); + groupAddDroid(buildDefGroup, droid ); + } + } + } else {//need more def trucks + if ( buildGroup.members > buildDefGroup.members ){ + droid = getADroid(buildGroup); + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 1c - added a droid in buildGroup ("& buildGroup.members &") from buildDefGroup ("& buildDefGroup.members &")"); + groupAddDroid(buildDefGroup, droid ); + } + } + + if ( buildDefGroup.members > buildGroup.members+1 ){ + droid = getADroid(buildDefGroup); + if (droid != NULLOBJECT){ + //displayMsg("truckGroupSlider: Opt 1d - added a droid in buildDefGroup ("& buildDefGroup.members &") from buildGroup ("& buildGroup.members &")"); + groupAddDroid(buildGroup, droid ); + } + } + } + + //displayMsg("truckGroupSlider 2: b("& buildGroup.members &") d("& buildDefGroup.members &") h("& harvesterGroup.members &") "); + +} + +//============================================================================ +event defendDerrick(inactive) +{ + local STRUCTURESTAT _defStruct; + + ASSERT(player >= 0 and player < 8, "player out of bounds: defendDerrick " & player, player); + eventCheckTime[12] = gameTime; + + if (lStopBuildDefDerricks){exit;} + //displayMsg("_______________ defendDerrick called 1______________"); + + //also checks there are already enough def around the derrick + _derrick = closestDerrickToDefend(); + if(gameTime>300 and _derrick != NULLOBJECT){//check on time is to avoid this event starts before AIbrain + //this is the difference against event harvestOperate + //displayMsg("_______________ defendDerrick called 2______________"); + + droid = pickDefTruck(false); + + if(droid != NULLOBJECT) + { + + _defStruct = getDefStruct(); + + if( isStructureAvailable(_defStruct,player) ) + { + buildX = _derrick.x ; + buildY = _derrick.y ; + if(!threatInRange(player,buildX, buildY, THREAT_RANGE_TILES*128, false)){ + if(pickStructLocation(_defStruct, ref buildX, ref buildY,player)) { + if (droidCanReach(droid, buildX, buildY) ){ + orderDroidStatsLoc(droid, DORDER_BUILD, _defStruct, buildX, buildY); + //displayMsg("**** defendDerrick droid ("& droid.id &") build def ["& _t &"] best is ["& pickDefQueueDepth &"] - derrick ("& _derrick.id &")" ); + } + } + } //else { displayMsg("defendDerrick : some threat in range") ;} + } //else { displayMsg("defendDerrick : structure no available") ;} + } //else { displayMsg("defendDerrick : NO idle trucks found") ; } + } //else { displayMsg("defendDerrick : NO DERRICKS FOUND???"); } +} + +//============================================================================ +// build a power gen for every 4 derricks. VITAL! +event buildPowerGenerators(inactive) +{ + + ASSERT(player >= 0 and player < 8, "player out of bounds:.13 " & player, player); + eventCheckTime[13] = gameTime; + + //search for incompleted structure fist + boolResult = true; + initEnumStruct(false,powGen,player,player); + structure = enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if ( !structureComplete(structure) ){ + droid = closestDroidCanBuild(buildGroup,structure.x,structure.y); + if( droid != NULLOBJECT ) + { + if (droidCanReach(droid, structure.x, structure.y) ){ + //displayMsg("*** buildPowerGenerators: completing Power Generator ("& structure.id &")"); + orderDroidObj(droid,DORDER_HELPBUILD,structure); + boolResult = false; + } + } //else { displayMsg("*** buildPowerGenerators: completing powGen - DROID NOT FOUND"); } + } //else { displayMsg("*** buildPowerGenerators: struct is complete"); } + structure = enumStruct(); + } + + if( boolResult and (numStructsByType(powGen, player) * 4) < numStructsByType(derrick, player) and (gameTime - tLastPowerGen) > 300 ) + { + buildX = baseX; + buildY = baseY; + boolResult = pickStructLocation(powGen, ref buildX, ref buildY,player); + if(boolResult) + { + droid = closestDroidCanBuild(buildGroup,baseX,baseY); + if( droid != NULLOBJECT ){ + if ( droidCanReach(droid, buildX, buildY) ) + //displayMsg("*** buildPowerGenerators: building Power Generator - Derricks ("& count &") powGen ("& count2 &") last build ("& tLastPowerGen &"), ("& (gameTime - tLastPowerGen)/10 &") secs ago"); + orderDroidStatsLoc(droid, DORDER_BUILD,powGen, buildX,buildY); + tLastPowerGen = gameTime; + } + } + } + +} +//------------------------------------- +event defendGatewaysPoint(inactive) +{ + ASSERT(player >= 0 and player < 8, "player out of bounds: defendGatewaysPoint " & player, player); + eventCheckTime[14] = gameTime; + _idleTruck = NULLOBJECT; + _notIdleTruck = NULLOBJECT; + //-------------------------------- + //displayMsg("defendGatewaysPoint: lStopBuildDefGateway("& lStopBuildDefGateway &") defTanks("& buildDefGroup.members &") pickWallDefQueueDepth("& pickWallDefQueueDepth &")nRealGatewaysFound("& nRealGatewaysFound &") numGTW("& nRealGatewaysFound &") defStrAtGTW("& numDefStrAtGateway &")"); + + if( buildDefGroup.members < 0 or lStopBuildDefGateway ) + { exit; } + + //defend real gateways if they exists + if ( nRealGatewaysFound == 0){ + setEventTrigger(defendGatewaysPoint,inactive); + exit; + } + + _idleTruck = pickDefTruck(false); + if ( _idleTruck == NULLOBJECT ){ + //displayMsg("defendGatewaysPoint: _____________EXIT no idle trucks ("& buildDefGroup.members &")_____________"); + exit; + } + + count = 0; + boolResult = true; + while ( count < nRealGatewaysFound and boolResult) + { + count2 = numFriendlyWeapStructsInRange(player, aGatewayPosX[count], aGatewayPosY[count], 2*TILE, false); + //displayMsg("defendGatewaysPoint: _____________ GTW("& count &"/"& nRealGatewaysFound &") numDefStrAtGateway("& count2 &"/"& numDefStrAtGateway &")_____________"); + if ( count2 < numDefStrAtGateway and !threatInRange(player, aGatewayPosX[count], aGatewayPosY[count], THREAT_RANGE_TILES*128, false)){ + buildGatewayDef(_idleTruck, count); + boolResult = false;//exit the loop + } else { + displayMsg("defendGatewaysPoint: cannot build def as GTW("& count &" >= "& nRealGatewaysFound &") or threat in range"); + } + count++; + } + +} + +//======================================================================= +event defendBase(inactive) +{ + local STRUCTURESTAT _defStruct; + + ASSERT(player >= 0 and player < 8, "player out of bounds: defendBase " & player, player); + eventCheckTime[15] = gameTime; + + //dbg("dbg->defendBase: lStopBuildDef ("& lStopBuildDef &") time("& gameTime - tLastbuildBaseDef &") > ("& TIME_TOFORCE_BUILDDEF &")",player); + if(pickDefQueueDepth <= 0 and pickWallDefQueueDepth <= 0 ) { + //dbg("dbg->defendBase: DEFENSE ARRAYS ARE EMPTY !!!!!",player); + exit; + } + + if (lStopBuildDef or gameTime < 2*TIME_MINUTE ){//hack, check time to avoid building at very beginning + exit; + } + + droid = pickDefTruck(false); + if( droid == NULLOBJECT ) { exit; } + + count = random(100); + if ( AIPersonality == AI_TURTLE ) { count = count+25; } + if ( pickFortQueueDepth > 0 and count > 75 and lMinBaseStructBuilt){ + count = random(pickFortQueueDepth); + _defStruct = pickFortQueue[count]; + } else { + _defStruct = getDefStruct(); + } + + // ----------- build! ---------------- + if(isStructureAvailable(_defStruct,player)) + { + + if( defSpotX > 0 and defSpotY > 0 ){ + //best option + buildX = defSpotX; + buildY = defSpotY; + } else { + buildX = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 1, count*TILE); + buildY = getCoordRelated(baseX, baseY, mapWidth*TILE/2, mapHeight*TILE/2, 2, count*TILE); + } + + //check number of def already built in area + if( numFriendlyWeapStructsInRange(player, buildX, buildY, TILE*6, false) < MAX_DEFSTR_SPOT){ + boolResult = pickStructLocation(_defStruct, ref buildX, ref buildY,player); + if(boolResult == TRUE) + { + if ( droidCanReach(droid, buildX, buildY) ){ + printDebug1("defendBase: building base defence on coord ("& buildX/TILE &"-"& buildY/TILE &") defSpotX-Y("& defSpotX/TILE &")("& defSpotY/TILE &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,_defStruct,buildX,buildY); + tLastbuildBaseDef = gameTime; + } + } + } else { + //force the building every tot min regardless of the def already built... + if ( gameTime - tLastbuildBaseDef > TIME_TOFORCE_BUILDDEF){ + if( pickStructLocation(_defStruct, ref buildX, ref buildY, player) ) + { + if ( droidCanReach(droid, buildX, buildY) ){ + printDebug1("defendBase: force building base defence on coord ("& buildX/TILE &"-"& buildY/TILE &") defSpotX-Y("& defSpotX/TILE &")("& defSpotY/TILE &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,_defStruct,buildX,buildY); + tLastbuildBaseDef = gameTime; + } + } + } //else {displayMsg("defendBase: time gone ("& gameTime - tLastbuildBaseDef &" / "& TIME_TOFORCE_BUILDDEF &") to force build of def is not enough"); } + } + } else { printDebug1("#### Trying to build a def struct which is not available"); } + + +} + +// ========================================================================== +event upgradeStructures(inactive) +{ + ASSERT(player >= 0 and player < 8, "player out of bounds:.17 " & player, player); + eventCheckTime[16] = gameTime; + + + droid = closestIdleDroid(buildGroup,baseX,baseY); + if(droid == NULLOBJECT){ + droid = pickDefTruck(true); + } + if(droid != NULLOBJECT) + { + + boolResult = true; + + if ( lMinBaseStructBuilt ){ + initEnumStruct(false,powGen,player,player); + structure= enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if( structureComplete(structure) and isStructureAvailable(powModule,player) and (not testStructureModule(player, structure, 0)) ) + { + //displayMsg("*** UpgradeStructures: upgrading Power Structure ("& structure.id &") "); + orderDroidStatsLoc(droid,DORDER_BUILD,powModule, structure.x,structure.y); + boolResult = false; + } + structure= enumStruct(); + } + } + + + //if "R-Vehicle-Body05" is not completed we do not perform the upgrade + if ( !lStopFactUpgrade and boolResult ) + { + initEnumStruct(false,factory,player,player); + structure= enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if( structureComplete(structure) and isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 1 ) ) + { + //displayMsg("*** UpgradeStructures: upgrading factory ("& structure.id &") capacity to 2 ("& skGetFactoryCapacity(structure) &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,facModule, structure.x,structure.y); + boolResult = false; + } + structure= enumStruct(); + } + + if ( !lStopFactUpgrade2 and boolResult ) + { + initEnumStruct(false,factory,player,player); + structure= enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if( structureComplete(structure) and isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 2 ) ) + { + orderDroidStatsLoc(droid, DORDER_BUILD,facModule, structure.x,structure.y); + boolResult = false; + } + structure= enumStruct(); + } + } + + initEnumStruct(false,vtolFactory,player,player); + structure= enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if( structureComplete(structure) and isStructureAvailable(facModule,player) and (skGetFactoryCapacity(structure) < 2 ) ) + { + orderDroidStatsLoc(droid, DORDER_BUILD,facModule, structure.x,structure.y); + boolResult = false; + } + structure= enumStruct(); + } + + }//if ( !lStopFactUpgrade and boolResult ) + + //researches + if(!lStopResLabUpgrade and boolResult) + { + initEnumStruct(false,resLab,player,player); + structure= enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if( structureComplete(structure) and isStructureAvailable(resModule,player) and (not testStructureModule(player, structure, 0)) ) + { + //displayMsg("*** UpgradeStructures: upgrading ResLab ("& structure.id &") "); + orderDroidStatsLoc(droid, DORDER_BUILD,resModule, structure.x,structure.y); + boolResult = false; + } + structure= enumStruct(); + } + }//power check + + } //else { displayMsg("UpgradeStructures: no idle buildDroid found!! "); } +} + +//=========================================================================== +event droidBuilt(droidBuiltTr) // (CALL_NEWDROID,player, ref droid,ref structure); +{ + + /* + if( !aiResponsibleForPlayer(player) ) + { + dbg("dbg->droidBuilt : ai not responsible for player ("& player &") ",player); + setEventTrigger(droidBuilt,inactive); + } + else + { + */ + + ASSERT(player >= 0 and player < 8, "player out of bounds: droidBuilt " & player, player); + + boolResult = true; + //dbg("dbg->droidBuilt : droid ("& droid.id &") hitPoints ("& droid.hitPoints &") ",player); + if(droid != NULLOBJECT) + { + if ( droid.player != player ){ exit; } + // TANK + if(droid.droidType == DROID_WEAPON and droid.propulsion != cyborgPropulsion) + { + nTotTankBuilt++; + //displayMsg("droidBuilt: tank ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") "); + groupAddDroid(tankDefGroup, droid); + } + + // TANK REPAIR + if(droid.droidType == DROID_REPAIR ) + { + //displayMsg("droidBuilt: tank ("& droid.id &") hitPoints ("& droid.hitPoints &") assigned to repairGroup "); + groupAddDroid(repairGroup, droid); + } + + //TANK CONTRUCTOR + if( droid.droidType == DROID_CONSTRUCT ) + { + //store coord for stuck check + //storeDroidCoord(droid); + //displayMsg("droidBuilt: tank ("& droid.id &") hitPoints ("& droid.hitPoints &") assigned to buildGroup "); + groupAddDroid(buildGroup, droid); + } + + + // CYBORG + if(droid.propulsion == cyborgPropulsion) + { + if(droid.droidType == DROID_CYBORG_CONSTRUCT) + { + //displayMsg("droidBuilt: cyborg ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to cyborgConstructGroup"); + groupAddDroid(cyborgConstructGroup, droid); + } else { + nTotCyborgBuilt++; + if ( AIPersonality == AI_CYBORG ){ + //displayMsg("droidBuilt: cyborg ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to cyborgDefGroup"); + groupAddDroid(cyborgDefGroup, droid); + } else { + if (nTotCyborgBuilt > 2){ + //displayMsg("droidBuilt: ["& nTotCyborgBuilt &"] CYBORG ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to tankDefGroup "); + groupAddDroid(tankDefGroup, droid); + nTotCyborgBuilt = 0; + } else { + //displayMsg("droidBuilt: ["& nTotCyborgBuilt &"] cyborg ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to cyborgDefGroup "); + groupAddDroid(cyborgDefGroup, droid); + } + } + } + } + + + // VTOL + if( isVtol(droid) ) + { + //displayMsg("droidBuilt: VTOL ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to vtolDefendGr "); + groupAddDroid(vtolDefendGr, droid); + //need to check if I have to give new droid an order to attack + if (attTargetVTOL != NULLOBJECT){ + if ( !friendlyPlayer(attTargetVTOL.player) ){ + //displayMsg("droidbuilt: ordered VTOL to attack attTargetVTOL("& attTargetVTOL.id &") "); + orderDroidObj(droid,DORDER_ATTACK,attTargetVTOL); + } + } //else { displayMsg("droidbuilt: attTargetVTOL is NULL "); } + if ( defTargetVTOL != NULLOBJECT ){ + if ( !friendlyPlayer(defTargetVTOL.player) ){ + //displayMsg("droidbuilt: ordered VTOL to attack defTargetVTOL("& defTargetVTOL.id &") "); + orderDroidObj(droid,DORDER_ATTACK,defTargetVTOL); //bug fixed in DyDo 1.2.3a, the target object was attTargetVTOL and not defTargetVTOL + } + } //else { displayMsg("droidbuilt: defTargetVTOL is NULL "); } + //setDroidSecondary(droid, DSO_PATROL, DSS_PATROL_SET); + exit; + } + + //to be improved: add secondary for weapons cyborgs + setDroidSecondary(droid,DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER); + setDroidSecondary(droid, DSO_HALTTYPE, DSS_HALT_PERSUE); + setDroidSecondary(droid, DSO_ATTACK_LEVEL, DSS_ALEV_ALWAYS); + + boolResult = false; + if( droid.droidType == DROID_WEAPON){ + boolResult = true; + //short range tanks + if ( droid.weapon == Flamer or droid.weapon == PlasmFlamer or droid.weapon == Inferno or droid.weapon == PlasmaCannon or droid.weapon == EMPCannon or droid.weapon == AGun or droid.weapon == MGun or droid.weapon == TwinMGun or droid.weapon == HMGun or droid.weapon == TwinAGun){ + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_SHORT); + //displayMsg("droidbuilt: short attack range assigned to tank "); + //long range tanks-1 + } else if ( droid.weapon == LCannon or droid.weapon == MCannon or droid.weapon == ACannon or droid.weapon == HCannon or droid.weapon == TACannon or droid.weapon == NeedleGun or droid.weapon == RailGun or droid.weapon == GaussCannon ){ + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_SHORT); + //displayMsg("droidbuilt: short attack range assigned to tank "); + } else if ( droid.weapon == FlashLight or droid.weapon == PulseLaser or droid.weapon == HeavyLaser ){ + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_LONG); + //displayMsg("droidbuilt: long attack range assigned to Laser-tank "); + //long range tanks-2 + } else if ( droid.weapon == RocketBB or droid.weapon == RocketPod or droid.weapon == HVCannon or droid.weapon == RocketMRL or droid.weapon == Lancer or droid.weapon == TankKiller or droid.weapon == RippleRockets or droid.weapon == ScourgeMissle or droid.weapon == ArchangelMissile){ + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_LONG); + //displayMsg("droidbuilt: long attack range assigned to tank "); + } else { + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_DEFAULT); + //displayMsg("droidbuilt: default attack range assigned to droid "); + } + } + + + if( droid.propulsion == cyborgPropulsion and droid.droidType != DROID_CYBORG_CONSTRUCT ){ + boolResult = true; + //short range cyborgs + if ( droid.weapon == cybGren or droid.weapon == cybLancer or droid.weapon == cybScourge or droid.weapon == cybSuperHPV or droid.weapon == cybSuperScourge or droid.weapon == cybTankKiller){ + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_LONG); + //displayMsg("droidbuilt: long attack range assigned to cyborg"); + } else { + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_SHORT); + //displayMsg("droidbuilt: short attack range assigned to cyborg"); + } + } + + //for debug purposes only + //if( !boolResult ){ + //dbg("dbg->droidbuilt: no attack range assigned to droid",player); + //} + + }//droid != NULLOBJECT + //} +} + +// ================== UNITS RESORTING SCRIPT ========================== +event reSortUnits(inactive) +{ + + /* + if( !aiResponsibleForPlayer(player) ) + { + setEventTrigger(reSortUnits, inactive); + } + else + { + */ + + + ASSERT(player >= 0 and player < 8, "player out of bounds: reSortUnits " & player, player); + + groupAddAreaNoGroup(xGroup, player, 0, 0, (mapWidth*128), (mapHeight*128)); + //dbg("reSortUnits: xGroup.members bofore re-sort ("& xGroup.members &") _________________",player); + initIterateGroup(xGroup); + droid = iterateGroup(xGroup); + while(droid != NULLOBJECT) + { + //dbg("dbg->assignDroidToGrp: droid ("& droid.id &") ("& droid.y/TILE &")("& droid.y/TILE &") found a droid with no group ("& droid.id &"), force assign to tankdefGroup",player); + assignDroidToGrp(droid); + droid = iterateGroup(xGroup); + } + + groupAddAreaNoGroup(xGroup, player, 0, 0, (mapWidth*128), (mapHeight*128)); + //dbg("reSortUnits: xGroup.members after re-sort ("& xGroup.members &") _______________",player); + + //deactivate itself + setEventTrigger(reSortUnits,inactive); + + //} +} + +// ============================================================================= +event SelectTankTemplate(inactive) +{ + + local int _nRnd, _nRnd2,_nBestHvyBody,_nBestMedBody,_nBestLghBody; + + eventCheckTime[17] = gameTime; + ASSERT(player >= 0 and player < 8, "player out of bounds:.27 " & player, player); + + //displayMsg("SelectTankTemplate 1: nWorkingFact("& nWorkingFact &") nFactories("& nFactories &") boolResult ("& boolResult &") nProdSelect("& nProdSelect &") stopProdTank("& lStopTankProduction &")_______________"); + + if ( getDroidCount(player) >= MAX_DROIDS ){ exit; } + if ( nWorkingFact == nFactories ){ exit; } + + boolResult = true; + + //build trucks + if ( gameTime > TIME_HARVESTING_PHASE and (numTemplatesInProduction(constructor2,player) > 0 or numTemplatesInProduction(constructor,player) > 0) ){ + lStopBuildTankProd = true; + } + if (!lStopBuildTankProd ){ + initEnumStruct(false,factory,player,player); + structure = enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if(structureComplete(structure) and structureIdle(structure)){ + if ( skCanBuildTemplate(player,structure, constructor2) ){ + buildDroid(constructor2, structure, player, 1); // can harvest on islands! + } else { + buildDroid(constructor, structure, player, 1); // build tank wheeled constructor + } + lastTruckBuilt = gameTime; + boolResult = false; + } + structure = enumStruct(); + } + } + + //repair Truck + if ( boolResult and repairGroup.members+numTemplatesInProduction(repairTank,player) < MAX_REPAIR_UNITS ){ + if ( getStructure(repairFacility,player) == NULLOBJECT ){ + if ( gameTime > TIME_HARVESTING_PHASE ){ + initEnumStruct(false,factory,player,player); + structure = enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + if(structureComplete(structure) and structureIdle(structure)){ + if( skCanBuildTemplate(player,structure, repairTank) ){ + boolResult = false; + buildDroid(repairTank, structure, player, 1); // build tank repair + lastTimeRepairBuilt = gameTime;//avoid multipe builds in high power + } //else { displayMsg("SelectTankTemplate: 1-cannot build template for repair tank");} + } + structure = enumStruct(); + } + } + } + } + + //do not build any other type of tanks for cyborgAI + if ( AIPersonality == AI_CYBORG ){ exit; } + + //displayMsg("SelectTankTemplate 2: nWorkingFact("& nWorkingFact &") nFactories("& nFactories &") boolResult ("& boolResult &") nProdSelect("& nProdSelect &") stopProdTank("& lStopTankProduction &")_______________"); + + //build tanks + if (boolResult and !lStopTankProduction) + { + boolResult = true; + _pos = -1;//tmpl to be built + + initEnumStruct(false,factory,player,player); + structure = enumStruct(); + while(structure != NULLOBJECT and boolResult) + { + //displayMsg("SelectTankTemplate: structure.id("& structure.id &") boolResult("& boolResult &")________"); + if(structureComplete(structure) and structureIdle(structure)) + { + + _nRnd = random(100);//weapon type (WEAPON_AR/AT/AP) + if ( _nRnd < 40 ){ + _nRnd = 0;//AllRounder + } + if ( _nRnd >= 40 and _nRnd < 70 ){ + _nRnd = 1;//AntiTank + } + if ( _nRnd >= 70 and _nRnd < 100 ){ + _nRnd = 2;//AntiPersonnel + } + _nRnd2 = random(100);//body type + + _nBestHvyBody = checkBestBody(BODY_HEAVY,_nRnd,structure);//heavy + _nBestMedBody = checkBestBody(BODY_MEDIUM,_nRnd,structure);//medium + _nBestLghBody = checkBestBody(BODY_LIGHT,_nRnd,structure);//light + + //dbg("SelectTankTemplate: _nRnd("& _nRnd &") bodies hv-md-lg("& _nBestHvyBody &")("& _nBestMedBody &")("& _nBestLghBody &")",player); + printDebug1("SelectTankTemplate: _nRnd2("& _nRnd2 &") _nRnd("& _nRnd &") bodies hv-md-lg("& _nBestHvyBody &")("& _nBestMedBody &")("& _nBestLghBody &")"); + + if ( _nBestHvyBody == 0 and _nBestMedBody == 0 and _nBestLghBody == 0){ + printDebug1("####SelectTankTemplate: Not able to build any template with _nRnd("& _nRnd &"); bodies hv-md-lg("& _nBestHvyBody &")("& _nBestMedBody &")("& _nBestLghBody &")"); + // + if( skCanBuildTemplate(player,structure, tmpl0[61]) ){//Viper Flamer + buildDroid( tmpl0[61] , structure, player, 1); + } else { + if( skCanBuildTemplate(player,structure, tmpl0[60]) ){//Viper HMG + buildDroid( tmpl0[60] , structure, player, 1); + } else { + if( skCanBuildTemplate(player,structure, tmpl0[62]) ){//Viper MG + buildDroid( tmpl0[62] , structure, player, 1); + } else { + printDebug1("####SelectTankTemplate: REALLY not able to build any tank template !!"); + } + } + } + exit; + } + + //Heavy and Medium are availabe + if ( _nBestHvyBody > 0 ){ + if (_nBestMedBody > 0 ){ + if ( _nRnd2 < 65 ){ + boolResult = buildHeavyTank(_nRnd,structure); + } else { + boolResult = buildMediumTank(_nRnd,structure); + } + } else { + boolResult = buildHeavyTank(_nRnd,structure); + } + } + + //Medium and Light are availabe + if ( _nBestHvyBody == 0 ){ + if (_nBestMedBody > 0 ){ + if (_nBestLghBody > 0 ){ + if ( _nRnd2 < 65 ){ + boolResult = buildMediumTank(_nRnd,structure); + } else { + boolResult = buildLightTank(_nRnd,structure); + } + } else { + boolResult = buildMediumTank(_nRnd,structure); + } + } + } + + //Only Light is availabe + if ( _nBestHvyBody == 0 and _nBestMedBody == 0 and _nBestLghBody > 0){ + boolResult = buildLightTank(_nRnd,structure); + } + + //if ( boolResult ){ + //dbg("Building Tank: _nRnd("& _nRnd &") _nRnd2("& _nRnd2 &") bodies hv-md-lg("& _nBestHvyBody &")("& _nBestMedBody &")("& _nBestLghBody &")",player); + //printDebug1(" Building Tank: _nRnd("& _nRnd &") _nRnd2("& _nRnd2 &") bodies hv-md-lg("& _nBestHvyBody &")("& _nBestMedBody &")("& _nBestLghBody &")"); + //} else { + //printDebug1("#### Not able to build _nRnd("& _nRnd &") _nRnd2("& _nRnd2 &") bodies hv-md-lg("& _nBestHvyBody &")("& _nBestMedBody &")("& _nBestLghBody &")"); + //} + + }//endif(structureComplete(structure) and structureIdle(structure)) + + structure = enumStruct(); + }//end while + + + }//endif (boolResult and !lStopTankProduction) +} + + +//========================================================================= +event SelectCyborgTemplate(inactive) +{ + + local TEMPLATE cybTmpl[17]; + local int _nRnd, _pos; + local bool _bBuildAR_cyborg, _bBuildAT_cyborg, _bBuildAP_cyborg, _bBuildKK_cyborg; + + ASSERT(player >= 0 and player < 8, "player out of bounds:.29 " & player, player); + eventCheckTime[18] = gameTime; + //displayMsg("*** SelectCyborgTemplate: ___________ CALLED lStopCybProduction("& lStopCybProduction &") droids tot("& getDroidCount(player) &"/"& MAX_DROIDS &")___________"); + + _pos = -1; + _bBuildAR_cyborg = false;//AllRounder + _bBuildAT_cyborg = false; //AntiTank + _bBuildAP_cyborg = false; //AntiPersonnel + _bBuildKK_cyborg = false; //Kinetic (Grenadier-NeedleGunner) + + if( getDroidCount(player) >= MAX_DROIDS){ exit; } + + if(!lStopCybProduction) + { + initEnumStruct(false,cybFactory,player,player); + structure = enumStruct(); + boolResult = true; + while(structure != NULLOBJECT and boolResult) + { + if( structureComplete(structure) and structureIdle(structure) ) + { + + boolResult = true; + + // build cyborg constructor + if( !lStopCybEngProd ){ + boolResult = false; + lastCybEngBuilt = gameTime; + buildDroid(cybcondroid, structure, player, 1); + //displayMsg("*** SelectCyborgTemplate: Building Constructor Droid power("& playerPower(player) &")"); + } + + //build cyborg Mechanic + /* + if ( nCybMechanic < 3 and (gameTime - tLastCybMech > 2*TIME_MINUTE) ){ + tLastCybMech = gameTime; + nCybMechanic++; + buildDroid(cybMech, structure, player, 1); + } + */ + + if( boolResult ) + { + + count = 0; + while ( _pos == -1 and count < 20 ) + { + _nRnd = random(100); + if ( _nRnd < 30 ){ + _bBuildAR_cyborg = true;//Allrounder + nTotCybAR++; + } else if ( _nRnd >= 30 and _nRnd < 55 ){ + _bBuildAT_cyborg = true; //AntiTank + nTotCybAT++; + } else if ( _nRnd >= 55 and _nRnd < 80 ){ + _bBuildAP_cyborg = true; //AntiPersonnel + nTotCybAP++; + } else { + _bBuildKK_cyborg = true; //Kinetic + nTotCybKK++; + } + + //Build best Anti-Tank Template + if ( _bBuildAT_cyborg ){ + if( skCanBuildTemplate(player,structure, superCyb[9]) ){ _pos = 9; }//Lancer + if( skCanBuildTemplate(player,structure, superCyb[7]) ){ _pos = 7; }//Scourge + if ( random(10) < 5 ){ + if( skCanBuildTemplate(player,structure, superCyb[3]) ){ _pos = 3; }//Super Tank-Killer Cyborg + } else { + if( skCanBuildTemplate(player,structure, superCyb[0]) ){ + _pos = 0;//Super Scourge Cyborg + } else { + //backup + if( skCanBuildTemplate(player,structure, superCyb[3]) ){ _pos = 3; }//Super Tank-Killer Cyborg + } + } + } + + //Build best All-Rounder Template + if ( _bBuildAR_cyborg ){ + if( skCanBuildTemplate(player,structure, superCyb[6]) ){ _pos = 6; } + if( skCanBuildTemplate(player,structure, superCyb[5]) ){ _pos = 5; } + if( skCanBuildTemplate(player,structure, superCyb[4]) ){ _pos = 4; } + if( skCanBuildTemplate(player,structure, superCyb[1]) ){ _pos = 1; } + } + + //Build best Anti-Personnel Template + if ( _bBuildAP_cyborg ){ + if ( random(100) < 65 ){//65% Flamers-Lasers + if( skCanBuildTemplate(player,structure, superCyb[15]) ){ _pos = 15; } + if( skCanBuildTemplate(player,structure, superCyb[12]) ){ _pos = 12; } + if( skCanBuildTemplate(player,structure, superCyb[10]) ){ _pos = 10; } + if( skCanBuildTemplate(player,structure, superCyb[2] ) ){ _pos = 2; } + } else { //35% Gunners + if( skCanBuildTemplate(player,structure, superCyb[16]) ){ _pos = 16; } + if( skCanBuildTemplate(player,structure, superCyb[14]) ){ _pos = 14; } + if( skCanBuildTemplate(player,structure, superCyb[11]) ){ _pos = 11; } + } + } + + //Build best Kinetic Template + if ( _bBuildKK_cyborg ){ + if( skCanBuildTemplate(player,structure, superCyb[13]) ){ _pos = 13; } + if( skCanBuildTemplate(player,structure, superCyb[8] ) ){ _pos = 8; } + } + count++; + } //endwhile + + if ( _pos == -1 ){ + printDebug1("#### SelectCyborgTemplate: (A) cannot build template ["& _pos &"] "); + nTotCybErr++; + exit; + } + if( skCanBuildTemplate(player,structure, superCyb[_pos]) ) + { + //displayMsg("*** SelectCyborgTemplate: Building cyborg template ["& count &"]["& _pos &"] - best tmpl is ["& _nBestTmpl &"] - tot templates found ("& nCybTemplates &") "); + buildDroid(superCyb[_pos],structure,player,1); //build droid + boolResult = false; + } else { + printDebug1("#### SelectCyborgTemplate: (B) cannot build template ["& _pos &"] "); + } + + } //end check on tankGroupMembers + + } + structure = enumStruct(); + } + } + +} + +// ---------------------- DylanDog ---------------------------------- +event buildRepFacSuppAttack(inactive) +{ + local int _totFacilities; + eventCheckTime[19] = gameTime; + + exit; //need to think if this is ok + +} +//======================================================================= +// do research +event doResearch(inactive)//doResearchTr +{ + ASSERT(player >= 0 and player < 8, "player out of bounds:.44 " & player, player); + eventCheckTime[20] = gameTime; + //displayMsg("doResearch:___________("& lStopResearch &")prod["& nProdSelect &"]work("& getNumStructNotIdle(resLab) &")______________"); + + + initEnumStruct(false,resLab,player,player); + structure= enumStruct(); + count = 0; + boolResult2 = true; + while(structure != NULLOBJECT and boolResult2) + { + if( structureIdle(structure) and structureComplete(structure) ){ + //displayMsg("doResearch: resLab ("& structure.id &")"); + //check for AA first!! + if ( bAttackedByVTOL ){ + if ( !researchFinished(CycloneAASite,player) ){ + //displayMsg("doResearch: forcing research of Cyclone AA Site"); + boolResult = pursueResearch(structure,player,CycloneAASite); + if (boolResult) { + printDebug1("doResearch: forcing research of Cyclone AA Site"); + boolResult2 = false; tLastResearch = gameTime; + }//execute only once + } + } + //need rearmin pad for VTOL troops? + if ( nVTOLFactories > 0 ){ + if ( !isStructureAvailable(vtolPad,player) ){ + //displayMsg("doResearch: forcing research OF VTOLPad"); + + boolResult = pursueResearch(structure,player,VTOLPadRes); + if (boolResult) { + printDebug1("doResearch: forced research OF VTOLPad"); + boolResult2 = false; tLastResearch = gameTime; + }//execute only once + } + } + + if ( !lStopResearch and boolResult2 ){ + + //1v1 game, human player has more power and derricks are ok + if (bForceResPowUp){ + if (!researchFinished(powUpgrades3,player)){ + boolResult = pursueResearch(structure,player,powUpgrades3); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") OK forcing research of POWER UPGRADES 'powUpgrades3' ",player); + printDebug1("doResearch: OK forcing research of POWER UPGRADES 'powUpgrades3' "); + } //else { dbg("dbg->doResearch: ("& getPlayerName(player) &") failed forcing research of POWER UPGRADES 'powUpgrades3' ",player); } + } else { + if (!researchFinished(powUpgrades6,player)){ + boolResult = pursueResearch(structure,player,powUpgrades6); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") forcing research of POWER UPGRADES 'powUpgrades6' ",player); + printDebug1("doResearch: OK forcing research of POWER UPGRADES 'powUpgrades6' "); + } //else { dbg("dbg->doResearch: ("& getPlayerName(player) &") failed forcing research of POWER UPGRADES 'powUpgrades6' ",player); } + } + } + } + + //Need a CB tower and bombard ? + if (boolResult2 and bAttackedByMortars){ + if (!researchFinished(resCBSense,player)){ + boolResult = pursueResearch(structure,player,resCBSense); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by long range weapon weap OK FORCING RESEARCH OF CB TOWER ",player); + printDebug1("doResearch: attacked by long range weapon weap forcing research of CB TOWER"); + } //else {dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by long range weapon weap FAILED FORCING RESEARCH OF CB TOWER ",player); } + } else { + if (!researchFinished(bombardPit,player)){ + boolResult = pursueResearch(structure,player,bombardPit); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by long range weapon weap OK FORCING RESEARCH OF BOMBARD ",player); + printDebug1("doResearch: attacked by long range weapon weap forcing research of BOMBARD"); + } //else { dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by long range weapon weap FAILED FORCING RESEARCH OF BOMBARD ",player); } + } + } + } + + //Need a CB tower and RippleRockets ? + if (boolResult2 and bAttackedByLongRangeWeap){ + if (!researchFinished(resCBSense,player)){ + boolResult = pursueResearch(structure,player,resCBSense); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by very long range weap OK forcing research of CB TOWER",player); + printDebug1("doResearch: attacked by very long range weap forcing research of OF CB TOWER"); + } //else { dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by very long range weap FAILED forcing research of CB TOWER ",player); } + } else { + if (!researchFinished(rippleRockets,player)){ + boolResult = pursueResearch(structure,player,rippleRockets); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by very long range weap OK forcing research of RippleRockets ",player); + printDebug1("doResearch: attacked by very long range weap OK forcing research of RippleRockets"); + } //else { dbg("dbg->doResearch: ("& getPlayerName(player) &") attacked by very long range weap FAILED forcing research of RippleRockets ",player); } + } + } + } + + //Need Scorpion for VTOL templates? + if (boolResult2 and !researchFinished(scorpionBody,player) and isStructureAvailable(vtolFactory , player)){ + boolResult = pursueResearch(structure,player,scorpionBody); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") forcing research to Scorpion body",player); + printDebug1("doResearch: forcing research to Scorpion body as VTOL struct is available"); + } + } + + //Need Scorpion for VTOL templates? + if (boolResult2 and !researchFinished(lancerATweap,player) and isStructureAvailable(vtolFactory , player)){ + boolResult = pursueResearch(structure,player,lancerATweap); + if (boolResult) { + boolResult2 = false; tLastResearch = gameTime; + //dbg("dbg->doResearch: ("& getPlayerName(player) &") forcing research to Scorpion body",player); + printDebug1("doResearch: forcing research to Lancer AT weapon as VTOL struct is available"); + } + } + + //perform a standard Research + if ( boolResult2 and do_Research(structure, 0 ) < 0 ){ + //displayMsg("doResearch: no standard research to pursue found, doing a random research"); + printDebug1("doResearch: no standard research to pursue found, doing a random research"); + skDoResearch(structure,player,1); + tLastResearch = gameTime; + boolResult2 = false;//execute only once + } else { + boolResult2 = false;//execute only once + } + + }// if ( !lStopResearch ){ + + }//if( structureIdle(structure) and structureComplete(structure) ){ + structure= enumStruct(); + } //endwhile + //}//(!lStopResearch) + + + // =========== perform cheap researches ============== + boolResult = true; + if ( !lStopCheapResearch ) + { + initEnumStruct(false,resLab,player,player); + structure= enumStruct(); + count = 0; + while(structure != NULLOBJECT and boolResult) + { + if( structureIdle(structure) and structureComplete(structure) ) + { + //displayMsg("doResearch: Cheap one on resLab ("& structure.id &")"); + count = do_CheapResearch(structure, 0 ); + //if ( do_CheapResearch(structure, 0 ) < 0 ){ + //displayMsg("doResearch: no cheap research to pursue found"); + //} + boolResult = false;//execute only once + } + structure= enumStruct(); + } + }//(!lStopCheapResearch) +} + +//---------------------------------------------------------------- +event difficultyModifier(inactive) +{ + if ( EnableSliders == TRUE and !isHumanPlayer(player) )//this setting can be changed in the vlo file + { + skDifficultyModifier(player); + } + else + { + setEventTrigger(difficultyModifier, inactive); + } +} + +//----------------------------------------------------------------------------- +event manageHelpTeam(inactive) +{ + + local int _dist; + + ASSERT(player >= 0 and player < 8, "player out of bounds: manageHelpTeam " & player, player); + + + if ( gameTime - tProd4 >= 80 ){ + //dbg("dbg->manageHelpTeam: ("& getPlayerName(player) &") droids("& helpGroup.members &") helping ("& getPlayerName(nAllyBeingHelped) &") nHelpX-Y("& nHelpX &")("& nHelpY &")", player); + tProd4 = gameTime; + } + + if ( nAllyBeingHelped == -1 ){ + deactivateHelp(); + exit; + } + + if ( helpGroup.members == 0 ){ + msg("Player '"& getPlayerName(player) &"' has no helping units left, stop helping player '"& getPlayerName(nAllyBeingHelped) &"'" , player, nAllyBeingHelped); + deactivateHelp(); + } else { + //if haveBeacon + if (haveBeacon(nAllyBeingHelped) or nHelpX > -1){ + +//displayMsg("manageHelpTeam: 1"); + + //update beacon for the first time or with a new one + if ( beaconX[nAllyBeingHelped] > -1 ){ + nHelpX = beaconX[nAllyBeingHelped]; + nHelpY = beaconY[nAllyBeingHelped]; + } + _dist = distBetweenTwoPoints(helpGroup.x, helpGroup.y,nHelpX, nHelpY); + + if ( _dist > TILE*12){ //move to beacon + if ( gameTime - tHelpAction > 200){ + orderGroupMoveCMD(helpGroup, nHelpX, nHelpY); + //dbg("dbg: player # ("& player &") - moving to beacon ("& nHelpX/TILE &"-"& nHelpY/TILE &")", player); + tHelpAction = gameTime; + } + } else { //scout to beacon + if ( gameTime - tHelpAction > 50){ + orderGroupScoutCMD(helpGroup, nHelpX, nHelpY); + tHelpAction = gameTime; + } + //reset help coord, this will force searching of target next time event is called + if ( _dist < TILE*3 and numEnemyWeapObjInRange(player, nHelpX, nHelpY, TILE*5, false, false) == 0){ + nHelpX = -1; + nHelpY = -1; + } + + } + + + } else { //else -> do not have beacon and help coord + +//displayMsg("manageHelpTeam: 2"); + + //beacon expired, no enemy in short range...get a target + if ( objTargetHelpTeam == NULLOBJECT ){ +//displayMsg("manageHelpTeam: 3"); + + //msg("manageHelpTeam: player ("& player &") - No enemy on beacon point, getting a new target", player, nAllyBeingHelped); + if ( objTargetHelpTeam == NULLOBJECT ){ + objTargetHelpTeam = objDroidTargetInRange(helpGroup.x,helpGroup.y,15*TILE,false); + } + if ( objTargetHelpTeam == NULLOBJECT ){ + objTargetHelpTeam = objStrTargetInRange(helpGroup.x,helpGroup.y,25*TILE); + } + + + if ( objTargetHelpTeam != NULLOBJECT ){ +//displayMsg("manageHelpTeam: 4"); + + _dist = distBetweenTwoPoints(helpGroup.x, helpGroup.y,objTargetHelpTeam.x, objTargetHelpTeam.y); + + if ( _dist > TILE*12){ //move to target + if ( gameTime - tHelpAction > 200){ + orderGroupMoveCMD(helpGroup, objTargetHelpTeam.x, objTargetHelpTeam.y); + msg("manageHelpTeam: player ("& player &") - moving to new target", player, nAllyBeingHelped); + tHelpAction = gameTime; + } + } else { //scout to target + if ( gameTime - tHelpAction > 50){ + orderGroupScoutCMD(helpGroup, objTargetHelpTeam.x, objTargetHelpTeam.y); + //msg("manageHelpTeam: player ("& player &") - SCOUT to beacon",player, nAllyBeingHelped); + tHelpAction = gameTime; + } + } + + } else { +//displayMsg("manageHelpTeam: 5"); + //deactivate help, no more enemies in Range + msg("manageHelpTeam: No enemies in range, no beacon...let`s come back to the base", player, nAllyBeingHelped); + deactivateHelp(); + } + + } else { //have a target!!! + +//displayMsg("manageHelpTeam: 6"); + if ( gameTime - tHelpAction > 50){ + orderGroupScoutCMD(helpGroup, objTargetHelpTeam.x, objTargetHelpTeam.y); + //msg("manageHelpTeam: player ("& player &") - SCOUT to beacon",player, nAllyBeingHelped); + tHelpAction = gameTime; + } + + } + } + + } +} + +//---------------------------------------------------------------- +// check if all units are assigned to a group !!! +event unitAssignationCheck( inactive ) +{ + eventCheckTime[21] = gameTime; + count = toBeRepairedCyborgGroup.members + cyborgConstructGroup.members + cyborgAttGroup.members + cyborgDefGroup.members + toBeRepairedTankGroup.members + tankDefGroup.members + tankGroup.members + vtolDefendGr.members + vtolAttGr.members + repairGroup.members + buildDefGroup.members + buildGroup.members + harvesterGroup.members + helpGroup.members; + if( count != numDroidsInArea(player, 0, 0, (mapWidth*128), (mapHeight*128)) ) + { + dbg("dbg->unitAssignationCheck: activating reSortUnits assigned("& count &") tot("& numDroidsInArea(player, 0, 0, (mapWidth*128), (mapHeight*128)) &") ",player); + setEventTrigger(reSortUnits,reSortUnitsTr); + } +} +//---------------------------------------------------------------- +event VTOLmicroManager(inactive) +{ + local DROID _droid,_targetVTOL[3]; + local int _n,_i,_nPos,_nNumEnDroids,_nBestHit; + local DROID _aTmp[60]; + _n=0; _i=0; _nNumEnDroids=0; + + if ( !alertIsOn or alertX < 0 or alertY < 0){ exit; } + if ( vtolDefendGr.members < 1 or targetPlayerVTOL < 0 ){ exit; } + + /* + //update array enemy droids in alert area + InitEnumDroids(targetPlayerVTOL,targetPlayerVTOL); + _droid = EnumDroid(); + while(_droid != NULLOBJECT and _n < 60) + { + if (distBetweenTwoPoints(_droid.x,_droid.y,alertX,alertY) < 12*TILE){ + aTmp[_n] = _droid; + _n++; + _nNumEnDroids++; + } + _droid = EnumDroid(); + } + + //get best three targets + _i=0; + _nBestHit = 999999; + _loop = 0; + while (_loop < 3 and _loop < _nNumEnDroids){ + _i=0; + while (_i <= _n){ + _droid = aTmp[_i]; + if ( _droid.hitPoints > _nBestHit ) { + _targetVTOL[_loop] = _droid; + _nBestHit = _droid.hitPoints; + _nPos = _i; + } + _i++; + } + //clear this array pos to avoid to be chosen twice or more + aTmp[_nPos] = NULLOBJECT; + _loop++; + } + + //Attack the targets, assign at least 3 droids to each target + _i=0; + _n=0; + initIterateGroup(vtolDefendGr); + droid = iterateGroup(vtolDefendGr); + while(droid != NULLOBJECT) + { + if ( _n == 3 ){ _i++; _n=0;} + if ( _i == 3 ){ _i=0;} + orderDroidObj( droid, DORDER_ATTACK, _targetVTOL[_i] ); + _n++; + droid = iterateGroup(vtolDefendGr) + } + + + */ +} +//---------------------------------------------------------------- +event reassignPlayers(reassignPlayersTr) +{ + if( playerLeft == player ){ + console(getPlayerName(player) & " is now assigned to DyDo AI as human player has left"); + bRunning = true; + activateAI(); + } +} + + +//---------------------------------------------------------------- +//Check if any threat is in range of Trucks/cybEng order location. +//The order RTB is given only if the droid distance from order location is +// greater than 4 TILES. This because AI left the droid complete the +// building even with threat in range. The droid is called back anyway if +// it is attacked (see event AIattacked). +event threatCheck(threatCheckTr) +{ + local int _dist,_dist2; + + //buildGroup + initIterateGroup(buildGroup); + droid = iterateGroup(buildGroup); + while(droid != NULLOBJECT) + { + _dist2 = distBetweenTwoPoints(baseX,baseY,droid.x,droid.y); + _dist = distBetweenTwoPoints(droid.orderx,droid.ordery,droid.x,droid.y); + if ( _dist2 > nBaseRange and _dist > 4*TILE and threatInRange(player,droid.orderx,droid.ordery, THREAT_RANGE_TILES*128, false) ) + { + //dbg("dbg->threatCheck: THREAT found! stop building truck ("& droid.id &") order at ("& droid.orderx/TILE &"-"& droid.ordery/TILE &") distance from orderLoc ("& _dist/TILE &") dist from base/nBaseRange("& _dist2 &"/"& nBaseRange &")",player); + orderDroid( droid, DORDER_RTB ); + } + droid = iterateGroup(buildGroup); + } + + //buildDefGroup + initIterateGroup(buildDefGroup); + droid = iterateGroup(buildDefGroup); + while(droid != NULLOBJECT) + { + _dist2 = distBetweenTwoPoints(baseX,baseY,droid.x,droid.y); + _dist = distBetweenTwoPoints(droid.orderx,droid.ordery,droid.x,droid.y); + if ( _dist2 > nBaseRange and _dist > 4*TILE and threatInRange(player,droid.orderx,droid.ordery, THREAT_RANGE_TILES*128, false) ) + { + //dbg("dbg->threatCheck: THREAT found! stop buildDef truck ("& droid.id &") order at ("& droid.orderx/TILE &"-"& droid.ordery/TILE &") distance from orderLoc ("& _dist/TILE &") dist from base/nBaseRange("& _dist2 &"/"& nBaseRange &")",player); + orderDroid( droid, DORDER_RTB ); + } + droid = iterateGroup(buildDefGroup); + } + + //cyborgConstruct + initIterateGroup(cyborgConstructGroup); + droid = iterateGroup(cyborgConstructGroup); + while(droid != NULLOBJECT) + { + _dist2 = distBetweenTwoPoints(baseX,baseY,droid.x,droid.y); + _dist = distBetweenTwoPoints(droid.orderx,droid.ordery,droid.x,droid.y); + if ( _dist2 > nBaseRange and _dist > 4*TILE and threatInRange(player,droid.orderx,droid.ordery, THREAT_RANGE_TILES*128, false) ) + { + //dbg("dbg->threatCheck: THREAT found! stop truck ("& droid.id &") order at ("& droid.orderx/TILE &"-"& droid.ordery/TILE &") distance from orderLoc ("& _dist/TILE &") dist from base/nBaseRange("& _dist2 &"/"& nBaseRange &")",player); + orderDroid( droid, DORDER_RTB ); + } + droid = iterateGroup(cyborgConstructGroup); + } + +} +//---------------------------------------------------------------- +//structureBuiltInRange +event buildRippleRockets(inactive) +{ + + local int _nBestDef, _numWeapInRange, _numWeapInBase, _rnd; + + if(!isStructureAvailable(incendrys[3],player)){ exit; } + + _numWeapInBase = numStructinRange(incendrys[3],player, baseX, baseY, nDefendRange ); + + //dbg("buildRippleRockets Weap: lMinBaseStructBuilt("& lMinBaseStructBuilt &") _numWeapInBase("& _numWeapInBase &") lStopBuildDef("& lStopBuildDef &") tLastRRBuilt("& tLastRRBuilt &")",player); + + if ( _numWeapInBase >= 2 or (!lMinBaseStructBuilt and gameTime < 10*TIME_MINUTE) ) { exit; } + if ( _numWeapInBase > 1 and lStopBuildDef ) { exit; } + if ( gameTime - tLastRRBuilt < 3 * TIME_MINUTE ){ exit; } + + + droid = closestDroidCanBuild(buildDefGroup,baseX, baseY); + if (droid == NULLOBJECT){ + droid = closestIdleDroid(buildGroup,baseX, baseY); + } + if ( buildGroup.members < 2 and buildDefGroup.members < 2){ + if (droid == NULLOBJECT){ + droid = pickCybEng(true); + } + } + + + // build AA defenses. + if ( droid != NULLOBJECT ){ + + //pick up the position + buildX = baseX+(5*TILE); + buildY = baseY-(5*TILE); + + if(_nBestDef >= 0 ){ + boolResult = pickStructLocation(incendrys[3], ref buildX, ref buildY, player); + if(boolResult and droidCanReach(droid, buildX ,buildY) ) + { + printDebug1("buildRippleRockets: build Ripple Rockets _numWeapInBase("& _numWeapInBase &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,incendrys[3],buildX,buildY); + tLastRRBuilt = gameTime; + } + } //else { displayMsg("buildRippleRockets: No def struc found"); } + } //else { displayMsg("buildRippleRockets: No idle droid found"); } +} + +//---------------------------------------------------------------- +//structureBuiltInRange +event buildArtillery(inactive) +{ + local int _nBestDef, _numWeapInRange, _numWeapInBase, _rnd; + + //find best defense we can build. + count = 0; + _nBestDef = -1; + while( count < numIncendrys) + { + if(isStructureAvailable(incendrys[count],player)) + { _nBestDef = count; } + count++; + } + if ( _nBestDef < 0 ){ exit; }//no artillery + + count = 0; + while( count < numIncendrys) + { + _numWeapInBase = _numWeapInBase + numStructinRange(incendrys[count],player, baseX, baseY, nDefendRange + TILE*3); + count++; + } + + //dbg("buildArtillery Weap: lMinBaseStructBuilt("& lMinBaseStructBuilt &") num weap in base("& _numWeapInBase &") lStopBuildDef("& lStopBuildDef &") tLastArtilleryBuilt("& tLastArtilleryBuilt &")",player); + + if ( _numWeapInBase >= 5 or (!lMinBaseStructBuilt and gameTime < 10*TIME_MINUTE) ) { exit; } + if ( _numWeapInBase > 2 and lStopBuildDef ) { exit; } + //if ( gameTime - tLastIWbuilt < 1 * TIME_MINUTE ){ exit; } + + droid = closestDroidCanBuild(buildDefGroup,baseX, baseY); + if (droid == NULLOBJECT){ + droid = closestIdleDroid(buildGroup,baseX, baseY); + } + + // build AA defenses. + if ( droid != NULLOBJECT ){ + + //pick up the position + nArtilleryPos++; + if ( nArtilleryPos > 3 ){ nArtilleryPos = 0; } + if ( nArtilleryPos == 0 ){ buildX = baseX+(5*TILE); buildY = baseY+(5*TILE); } + if ( nArtilleryPos == 1 ){ buildX = baseX+(5*TILE); buildY = baseY-(5*TILE); } + if ( nArtilleryPos == 2 ){ buildX = baseX-(5*TILE); buildY = baseY+(5*TILE); } + if ( nArtilleryPos == 3 ){ buildX = baseX-(5*TILE); buildY = baseY-(5*TILE); } + + if(_nBestDef >= 0 ){ + boolResult = pickStructLocation(incendrys[_nBestDef], ref buildX, ref buildY,player); + if(boolResult and droidCanReach(droid, buildX ,buildY) ) + { + printDebug1("buildArtillery: build def ["& _nBestDef &"] _numWeapInBase("& _numWeapInBase &")"); + orderDroidStatsLoc(droid, DORDER_BUILD,incendrys[_nBestDef],buildX,buildY); + tLastArtilleryBuilt = gameTime; + } + } //else { displayMsg("buildArtillery: No def struc found"); } + } //else { displayMsg("buildArtillery: No idle droid found"); } +} + +/* +============================================================================== +Functions Section +============================================================================== +*/ +function void shutDownThisAI() +{ + bRunning = false; + setEventTrigger(activateAttack, inactive); + setEventTrigger(AIbrain, inactive); + setEventTrigger(AIcheck, inactive); + setEventTrigger(defFromLongRangeWeap, inactive); + setEventTrigger(beaconEv, inactive); + setEventTrigger(buildAAdef, inactive); + setEventTrigger(buildBase, inactive); + setEventTrigger(buildPowerGenerators, inactive); + setEventTrigger(buildRepFacSuppAttack, inactive); + setEventTrigger(buildRepFirst, inactive); + setEventTrigger(buildVtols, inactive); + setEventTrigger(CyborgAttack, inactive); + setEventTrigger(defendBase, inactive); + setEventTrigger(defendDerrick, inactive); + setEventTrigger(defendGatewaysPoint, inactive); + setEventTrigger(difficultyModifier, inactive); + setEventTrigger(doResearch, inactive); + setEventTrigger(evDebug, inactive); + setEventTrigger(evPrintDebug, inactive); + setEventTrigger(harvesterOperate, inactive); + setEventTrigger(manageDefCyborgs, inactive); + setEventTrigger(manageDefTank, inactive); + setEventTrigger(manageDefVTOL, inactive); + setEventTrigger(manageHelpTeam, inactive); + setEventTrigger(manageIdleTrucks, inactive); + setEventTrigger(manageRepairTeam, inactive); + setEventTrigger(reSortUnits, inactive); + setEventTrigger(SelectCyborgTemplate, inactive); + setEventTrigger(SelectTankTemplate, inactive); + setEventTrigger(sendBackDamagedUnits, inactive); + setEventTrigger(showAImessage, inactive); + setEventTrigger(showPlayerInfo, inactive); + setEventTrigger(shutDownAI, inactive); + setEventTrigger(TankAttack, inactive); + setEventTrigger(truckGroupSlider, inactive); + setEventTrigger(unitAssignationCheck, inactive); + setEventTrigger(unitRepairSwitch, inactive); + setEventTrigger(updateBaseDetails, inactive); + setEventTrigger(upgradeStructures, inactive); + setEventTrigger(useLassat, inactive); + setEventTrigger(vtolEnabler, inactive); + setEventTrigger(vtolStructs, inactive); + setEventTrigger(threatCheck,inactive); + //events activated via callbacks, not sure if this is required or not. + setEventTrigger(droidBuilt, inactive); + setEventTrigger(AIattacked, inactive); + setEventTrigger(vtolDefend, inactive); + //setEventTrigger(consoleEv, inactive); + setEventTrigger(multiMsgEv, inactive); + setEventTrigger(beaconEv, inactive); + setEventTrigger(reassignPlayers, inactive); + setEventTrigger(VTOLhunter,inactive); + setEventTrigger(buildArtillery,inactive); + setEventTrigger(buildRippleRockets,inactive); + + + +} +//----------------------------------------------------------------------------- +function void buildRearmPads() +{ + + if(!isStructureAvailable(vtolPad,player)){ + //displayMsg("*** buildRearmPads: vtolPad not available "); + return; + } + + buildX = baseX; + buildY = baseY; + + if(pickStructLocation(vtolPad, ref buildX, ref buildY, player)) + { + droid = closestDroidCanBuild(buildGroup, buildX , buildY ); + if ( buildGroup.members < 2 ){ + if (droid == NULLOBJECT){ + droid = pickCybEng(true); + } + } + if(droid != NULLOBJECT) + { + if ( droidCanReach(droid, buildX, buildY) ){ + //displayMsg("*** buildRearmPads: droid to build vtolPad"); + orderDroidStatsLoc(droid, DORDER_BUILD,vtolPad, buildX,buildY); + } + } //else { displayMsg("buildRearmPads: no idle buildDroid found"); } + } //else { displayMsg("#### buildRearmPads: cannot pick up a location to build vtolPad"); } +} +//----------------------------------------------------------------------------- +function void vtolFactoryBuildVtol(STRUCTURE _factory) +{ + local int _nRnd, _t,_nLoop,_nTemplAT,_nTemplBomb,_templateAT,_templateBomb; + local TEMPLATE _tmplToBuild; + local bool _bResult, _bBombVTOL; + + if( _factory == NULLOBJECT){ return; } + if( !structureIdle(_factory) ) { return; } + + _bResult = false; + _bBombVTOL = false; + + _t = -1; + _nLoop = 0; + _nTemplAT = 0; + _nTemplBomb = 0; + while( _nLoop < numVtolTemplates ) + { + if ( _nLoop < 5 ){//AT - light/medium body + if( skCanBuildTemplate(player,_factory, vtols[_nLoop]) ){ + _nTemplAT++; + _bResult = true; + //dbg("vtolFactoryBuildVtol: can build AT vtols["& _nLoop &"]",player); + } + } else { //Bomb - Heavy Body + if( skCanBuildTemplate(player,_factory, vtols[_nLoop]) ){ + //dbg("vtolFactoryBuildVtol: can build Bomb vtols["& _nLoop &"]",player); + _nTemplBomb++; + _bResult = true; + } + } + _nLoop++; + } + + if(!_bResult) { + //dbg("vtolFactoryBuildVtol: no templates lancer("& researchFinished(lancerATweap,player) &") scorpion("& skVtolEnableCheck(player) &")("& _nTemplAT &")("& _nTemplBomb &") ",player); + return; + } + + + _nRnd = random(100); + if ( _nTemplBomb == 0){ //Only AT + + if ( _nRnd < 70 ){ //Lancer - Scourge + //Lancer-Scourge + if( skCanBuildTemplate( player ,_factory, vtols[0]) ){ _t = 0; } + if( skCanBuildTemplate( player ,_factory, vtols[2]) ){ _t = 2; } + if( skCanBuildTemplate( player ,_factory, vtols[4]) ){ _t = 4; } + if ( _t == -1 ){ //backup + if( skCanBuildTemplate( player ,_factory, vtols[1]) ){ _t = 1; } + if( skCanBuildTemplate( player ,_factory, vtols[3]) ){ _t = 3; } + } + } else {//HPV + if( skCanBuildTemplate( player ,_factory, vtols[1]) ){ _t = 1; } + if( skCanBuildTemplate( player ,_factory, vtols[3]) ){ _t = 3; } + if ( _t == -1 ){ //backup + if( skCanBuildTemplate( player ,_factory, vtols[0]) ){ _t = 0; } + if( skCanBuildTemplate( player ,_factory, vtols[2]) ){ _t = 2; } + if( skCanBuildTemplate( player ,_factory, vtols[4]) ){ _t = 4; } + } + } + + + } else { + + if ( _nRnd < 50 ){ //Bomb + + if( skCanBuildTemplate( player ,_factory, vtols[5]) ){ _t = 5; } + if( skCanBuildTemplate( player ,_factory, vtols[6]) ){ _t = 6; } + if( skCanBuildTemplate( player ,_factory, vtols[7]) ){ _t = 7; } + if( skCanBuildTemplate( player ,_factory, vtols[8]) ){ _t = 8; } + + } else { //AT + + _nRnd = random(100); + if ( _nRnd < 70 ){ //Lancer - Scourge + //Lancer-Scourge + if( skCanBuildTemplate( player ,_factory, vtols[0]) ){ _t = 0; } + if( skCanBuildTemplate( player ,_factory, vtols[2]) ){ _t = 2; } + if( skCanBuildTemplate( player ,_factory, vtols[4]) ){ _t = 4; } + if ( _t == -1 ){ //backup + if( skCanBuildTemplate( player ,_factory, vtols[1]) ){ _t = 1; } + if( skCanBuildTemplate( player ,_factory, vtols[3]) ){ _t = 3; } + } + } else {//HPV + if( skCanBuildTemplate( player ,_factory, vtols[1]) ){ _t = 1; } + if( skCanBuildTemplate( player ,_factory, vtols[3]) ){ _t = 3; } + if ( _t == -1 ){ //backup + if( skCanBuildTemplate( player ,_factory, vtols[0]) ){ _t = 0; } + if( skCanBuildTemplate( player ,_factory, vtols[2]) ){ _t = 2; } + if( skCanBuildTemplate( player ,_factory, vtols[4]) ){ _t = 4; } + } + } + + } + } + + if ( _t == -1 ){ + //dbg("vtolFactoryBuildVtol: tmplate not found lancer("& researchFinished(lancerATweap,player) &") scorpion("& researchFinished(scorpionBody,player) &") _t("& _t &"), _bBombVTOL("& _bBombVTOL &") _nTemplBomb("& _nTemplBomb &") _nTemplAT("& _nTemplAT &")_nRnd("& _nRnd &") ",player); + exit; + } + + if( skCanBuildTemplate( player ,_factory, vtols[_t]) ){ + displayMsg("vtolFactoryBuildVtol: build VTOL _t("& _t &"), _bBombVTOL("& _bBombVTOL &") _nTemplBomb("& _nTemplBomb &") _nTemplAT("& _nTemplAT &")_nRnd("& _nRnd &") lancer("& researchFinished(lancerATweap,player) &") scorpion("& researchFinished(scorpionBody,player) &")"); + buildDroid(vtols[_t],_factory,player,1); + } + //else { + //dbg("vtolFactoryBuildVtol: CANNOT build VTOL; lancer("& researchFinished(lancerATweap,player) &") scorpion("& researchFinished(scorpionBody,player) &") _t("& _t &"), _bBombVTOL("& _bBombVTOL &") _nTemplBomb("& _nTemplBomb &") _nTemplAT("& _nTemplAT &")_nRnd("& _nRnd &") ",player); + //} + + +} +//----------------------------------------------------------------------------- +function void deactivateTankAttack() +{ + tTanksSentToGathering = 0; + tTankAttackAction = 0; + bTankAttIsOn = false; + lTankSentToGatheringPoint = false; + bTankAlreadyGathered = false; + nTankGatheringX = -1; + nTankGatheringY = -1; + tankAttackX = -1; + tankAttackY = -1; + targetPlayerTank = -1; + attackTankObj = NULLOBJECT; + bAttackTeamAttacked = false; + setEventTrigger(TankAttack,inactive); +} +//----------------------------------------------------------------------------- +function void deactivateCybAttack() +{ + bCybAttIsOn = false; + lCybSentToGatheringPoint = false; + bCybAlreadyGathered = false; + cybAttackX = -1; + cybAttackY = -1; + nCybGatheringX = -1; + nCybGatheringY = -1; + targetPlayerCyb = -1; + tCybSentToGathering = 0; + tCybAttackAction = 0; + bAttackTeamAttacked = false; + setEventTrigger(CyborgAttack,inactive); +} +//----------------------------------------------------------------------------- +function void harvestNearOilRes() +{ + local FEATURE _oilRes, _bestOilRes; + local int _player,_tempDist,_bestDist; + local STRUCTURE _hq; + local bool _okToProceed; + + _oilRes = NULLOBJECT; + _bestOilRes = NULLOBJECT; + _okToProceed = true; + _bestDist = 9999*TILE; + + droid = pickCybEng(true);//needed for droidCanReach + if( droid != NULLOBJECT ) { + + initGetFeature(oilRes,player,player); + _oilRes = getFeature(player); + + while(_oilRes != NULLOBJECT) + { + + if ( droidCanReach(droid, _oilRes.x ,_oilRes.y) ) { + + //check oilRes is not in Ally base range + _okToProceed = true; + _player=0; + while (_player < MAX_PLAYERS) + { + //check oilRes is not in range of an Ally base, leave this oilRes to the Ally + if ( friendlyPlayer(_player) and ( _player != player) ){//OK + _hq = getStructure( playerHQ , _player); + if ( _hq != NULLOBJECT ){ + if ( distBetweenTwoPoints(_oilRes.x ,_oilRes.y ,_hq.x ,_hq.y) < 15 * TILE ) + { _okToProceed = false; } + } + } + + _player++; + }//endwhile + + //Check this oilRes is not too far away, trucks will harvest anyway + count = ((mapWidth+mapHeight)/2)*TILE; + count = (count/2);//half map + count2 = distBetweenTwoPoints(_oilRes.x ,_oilRes.y , baseX , baseY); + if ( count2 > count ) + { + _okToProceed = false; + //displayMsg("harvestNearOilRes: oilRes is too far away ("& count2/TILE &" / "& count/TILE &") "); + } + + + //check for threats in range + if ( threatInRange(player ,_oilRes.x, _oilRes.y, THREAT_RANGE_TILES_SHORT*128, false) ) + { _okToProceed = false; } + + if ( _okToProceed ){ + _tempDist = distBetweenTwoPoints(_oilRes.x, _oilRes.y, droid.x, droid.y); + if(_tempDist < _bestDist ) + { + _bestOilRes = _oilRes; + _bestDist = _tempDist; + } + } + + }//endif droidCanReach + + _oilRes = getFeature(player); + }//while + + + } + if ( _bestOilRes != NULLOBJECT ){ + droid = closestIdleDroid(cyborgConstructGroup,_bestOilRes.x,_bestOilRes.y); + if ( nMyDerricks < numMaxDerricks ) { + orderDroidStatsLoc( droid, DORDER_BUILD, derrick, _bestOilRes.x, _bestOilRes.y); + //displayMsg("*** manageIdleTrucks: Cybdroid (" & droid.id & ") build DERRICK (" & _bestOilRes.id & ") coord (" & _bestOilRes.x/TILE & "-" & _bestOilRes.y/TILE & ")" ); + } + } + + return; +} +//----------------------------------------------------------------------------- +function DROID pickCybEng(bool _idleOne) +{ + local DROID _Truck,_tempTruck; + _Truck = NULLOBJECT; + initIterateGroup(cyborgConstructGroup); + _tempTruck = iterateGroup(cyborgConstructGroup); + while(_tempTruck != NULLOBJECT and _Truck == NULLOBJECT) + { + if(_idleOne) + { + if(droidOrderIdle(_tempTruck)) { _Truck = _tempTruck; } + } else { + _Truck = _tempTruck; + } + _tempTruck = iterateGroup(cyborgConstructGroup); + }//end while + + return _Truck; +} + +//----------------------------------------------------------------------------- +function int getOilResTargetFree() +{ + local int _i; + _i = 0; + while ( _i < 11 ) + { + //dbg("getOilResTargetFree: _i ("& _i &") id("& oilResTargetId[_i] &")",player); + if (oilResTargetId[_i] == -1) + { + return _i; + } + _i++; + } + return -1; +} + + +//----------------------------------------------------------------------------- +function void checkDerrickIsBuilt(int _player) +{ + local STRUCTURE _structure; + local FEATURE _tempOilRes; + local int _i, _cc,_el; + + //if no oliRes left then reset the array! + initGetFeature(oilRes,-1,player); + _tempOilRes = getFeature(player); + _i = 0; + while(_tempOilRes != NULLOBJECT and _i < MAX_WHILE_LOOPS) + { + _i++; + _tempOilRes = getFeature(player); + } + + if( _i == 0 ){ + //general reset of array + _cc = 0; + while ( _cc < 11 ) + { + oilResTargetId[_cc] = -1; oilResTargetX[_cc] = -1; oilResTargetY[_cc] = -1; + _cc++; + } + } + + _el = 0; + initEnumStruct(false,derrick,_player,_player); + _structure= enumStruct(); + //displayMsg("checkDerrickIsBuilt player (" & _player & ")" ); /* -------DEBUG MESSAGE -------------- */ + while ( _structure != NULLOBJECT ) + { + while ( _el < 11 ) + { + if (( _structure.x == oilResTargetX[_el] ) and ( _structure.y == oilResTargetY[_el] ) and ( structureComplete(_structure) )) + { + //dbg("*** checkDerrickIsBuilt: derrick (" & _structure.id & ") completed, array pos ("& _el &") is free",player ); /* -------DEBUG MESSAGE -------------- */ + oilResTargetId[_el] = -1; + oilResTargetX[_el] = -1; + oilResTargetY[_el] = -1; + } + //else { if ( _structure.x == oilResTargetX[_el] and _structure.y == oilResTargetY[_el] ){displayMsg("checkDerrickIsBuilt: derrick (" & _structure.id & ") being built" ); }} + _el++; + } + _el = 0; + _structure= enumStruct(); + } +} +//----------------------------------------------------------------------------- +function void stopDroidHarvesting() +{ + local int _player, _dist, _dist2, _c2; + + _player=0; + + if ( harvesterGroup.members == 0 and cyborgConstructGroup.members == 0){return;} + + while ( _player < MAX_PLAYERS ) + { + initEnumStruct(false,derrick,_player,_player); + structure= enumStruct(); + _c2=0; + while ( structure != NULLOBJECT and _c2 < MAX_WHILE_LOOPS) + { + //check harvesting team first + initIterateGroup(harvesterGroup); + droid = iterateGroup(harvesterGroup); + while(droid != NULLOBJECT) + { + if( droid.orderx == structure.x and droid.ordery == structure.y ){ + _dist = distBetweenTwoPoints(structure.x,structure.y,droid.x,droid.y); + if( _dist > 3*TILE ){ + //dbg("dbg->stopDroidHarvesting: truck ("& droid.id &") harvesting at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &")",player); + if ( bOilResLeft ){ + //dbg("dbg->stopDroidHarvesting: a) stop harvesting truck ("& droid.id &") at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &")",player); + orderDroid( droid, DORDER_STOP ); + } else { + if( _dist < 20 * TILE and !threatInRange(player,structure.x,structure.y, THREAT_RANGE_TILES*128, false)){ + //dbg("dbg->stopDroidHarvesting: stop harvesting truck ("& droid.id &") at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &"), order build def here!!!",player); + boolResult = buildDefStruct(droid,structure.x,structure.y); + if ( !boolResult ){//cannot reach location! + //dbg("dbg->stopDroidHarvesting: harvesting truck ("& droid.id &") cannot build def at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &"), order build def here!!!",player); + orderDroid( droid, DORDER_RTB ); + } + } else { + //dbg("dbg->stopDroidHarvesting: b) stop harvesting truck ("& droid.id &") at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &")",player); + orderDroid( droid, DORDER_RTB ); + } + } + } + } + droid = iterateGroup(harvesterGroup); + } + //check cyborg engineers + initIterateGroup(cyborgConstructGroup); + droid = iterateGroup(cyborgConstructGroup); + while(droid != NULLOBJECT) + { + if( droid.orderx == structure.x and droid.ordery == structure.y ){ + _dist = distBetweenTwoPoints(structure.x,structure.y,droid.x,droid.y); + if( _dist > 3*TILE ){ + //dbg("dbg->stopDroidHarvesting: cyborg ("& droid.id &") harvesting at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &")",player); + if ( bOilResLeft ){ + //dbg("dbg->stopDroidHarvesting: a) stop harvesting cyborg ("& droid.id &") at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &")",player); + orderDroid( droid, DORDER_STOP ); + } else { + if( _dist < 15* TILE and !threatInRange(player,structure.x,structure.y, THREAT_RANGE_TILES*128, false)){ + //dbg("dbg->stopDroidHarvesting: stop harvesting cyborg ("& droid.id &") at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &"), order build def here!!!",player); + boolResult = buildDefStruct(droid,structure.x,structure.y); + if ( !boolResult ){orderDroid( droid, DORDER_RTB ); } + } else { + //dbg("dbg->stopDroidHarvesting: b) stop harvesting cyborg ("& droid.id &") at ("& structure.x/TILE &"-"& structure.y/TILE &") distance ("& _dist/TILE &")",player); + orderDroid( droid, DORDER_RTB ); + } + } + } + } + droid = iterateGroup(cyborgConstructGroup); + } + + structure= enumStruct(); + _c2++; + } + _player++; + } + + //check if any threat is in range + initIterateGroup(harvesterGroup); + droid = iterateGroup(harvesterGroup); + while(droid != NULLOBJECT) + { + _dist = distBetweenTwoPoints(droid.orderx,droid.ordery,droid.x,droid.y); + if ( _dist > 4*TILE and threatInRange(player,droid.orderx,droid.ordery, THREAT_RANGE_TILES*128, false) ) + { + //dbg("dbg->stopDroidHarvesting: THREAT stop truck ("& droid.id &") harvesting at ("& droid.orderx/TILE &"-"& droid.ordery/TILE &") distance ("& _dist/TILE &")",player); + orderDroid( droid, DORDER_RTB ); + } + droid = iterateGroup(harvesterGroup); + } + + initIterateGroup(cyborgConstructGroup); + droid = iterateGroup(cyborgConstructGroup); + while(droid != NULLOBJECT) + { + _dist2 = distBetweenTwoPoints(baseX,baseY,droid.x,droid.y); + _dist = distBetweenTwoPoints(droid.orderx,droid.ordery,droid.x,droid.y); + if ( _dist2 > nBaseRange and _dist > 4*TILE and threatInRange(player,droid.orderx,droid.ordery, THREAT_RANGE_TILES*128, false) ) + { + //dbg("dbg->stopDroidHarvesting: THREAT stop cyb eng ("& droid.id &") harvesting at ("& droid.orderx/TILE &"-"& droid.ordery/TILE &") distance ("& _dist/TILE &")",player); + orderDroid( droid, DORDER_RTB ); + } + droid = iterateGroup(cyborgConstructGroup); + } + + return; +} +//----------------------------------------------------------------------------- +function bool buildDefStruct(DROID _droid, int _x, int _y ) +{ + local int _t; + _t = max(pickDefQueueDepth - 1 - _random(3),0); + if( isStructureAvailable(pickDefQueue[_t],player) ) + { + buildX = _x ; + buildY = _y ; + if(pickStructLocation(pickDefQueue[_t], ref buildX, ref buildY,player)) + { + if (droidCanReach(_droid, buildX, buildY) ){ + orderDroidStatsLoc(_droid, DORDER_BUILD, pickDefQueue[_t], buildX, buildY); + //displayMsg("buildDefStruct: droid ("& _droid.id &") build def ["& _t &"] best is ["& pickDefQueueDepth &"] " ); + return true; + } + } + } + return false; +} + +//----------------------------------------------------------------------------- +function int getWeaponUnitsInfo( int _player, int _choice) +{ + + if ( _choice == WUI_TOTUNITS){ + return aStat[OC_CYBORGS][_player] + aStat[OC_TANKS][_player]; + } + if ( _choice == WUI_POWER){ + return aStat[OC_CYB_POWER][_player] + aStat[OC_TK_POWER][_player]; + } + if ( _choice == WUI_HP){ + return aStat[OC_CYB_HP][_player] + aStat[OC_TK_HP][_player]; + } + return -1; +} +//----------------------------------------------------------------------------- +function float getPowerIndex(int _player) +{ + + + local RESEARCHSTAT _powUpgrades[7]; + local int _powUpgrPerc[7],_nArr,_index,_nLastRes, _nDerricks; + local float _powIndRet; + _nArr = 7; + + _powUpgrades[0] = powUpgrades0; + _powUpgrades[1] = powUpgrades1; + _powUpgrades[2] = powUpgrades2; + _powUpgrades[3] = powUpgrades3; + _powUpgrades[4] = powUpgrades4; + _powUpgrades[5] = powUpgrades5; + _powUpgrades[6] = powUpgrades6; + + _powUpgrPerc[0] = 125; + _powUpgrPerc[1] = 150; + _powUpgrPerc[2] = 175; + _powUpgrPerc[3] = 200; + _powUpgrPerc[4] = 230; + _powUpgrPerc[5] = 260; + _powUpgrPerc[6] = 290; + + _nLastRes = -1; + _index = 0; + while ( _index < _nArr ){ + if (researchFinished( _powUpgrades[_index],_player) ){ + //displayMsg("getPowerIndex: YES _player("& _player &") _index("& _index &") completed("& researchFinished( _powUpgrades[_index],_player) &")" ); + _nLastRes = _index; + } //else { displayMsg("getPowerIndex: NO _player("& _player &") _index("& _index &") completed("& researchFinished( _powUpgrades[_index],_player) &")" );} + _index++; + } + _nDerricks = getNumDerricks(_player); + + if ( _nLastRes != -1 ) + { + _powIndRet = (float)_nDerricks * (float)_powUpgrPerc[_nLastRes]/(float)100; + //displayMsg("dbg -> getPowerIndex: YES _player ("& _player &") derricks("& _nDerricks &") powIndex("& _powIndRet &")" ); + return _powIndRet; + } //else { displayMsg("dbg -> getPowerIndex: NO _player ("& _player &") _nLastRes("& _nLastRes &") " );} + + return (float)_nDerricks; + //researchFinished(res,pl) + +} +//----------------------------------------------------------------------------- +function int getNumDerricks(int _player) +{ + local int _count; + local STRUCTURE _structure; + _count = 0; + initEnumStruct(false,derrick,_player,_player); + _structure= enumStruct(); + while ( _structure != NULLOBJECT ) + { + _count++; + _structure= enumStruct(); + } + return _count; +} + +//----------------------------------------------------------------------------- +// show a debug message, ca be activated/deactivated +function void displayMsg(STRING _message) +{ + if( isHumanPlayer(player) ) + { + dbg(_message, player); + } +} +//----------------------------------------------------------------------------- +// show a debug message -> reports error +function void dropBeaconToAllies(STRING _message, int _x, int _y, int _z, bool _bToHuman) +{ + local int _toPlayer; + _toPlayer = 0; + + //avoid too many blips... + if ( _message != "help" ){ + if ( (gameTime - tBeaconSent) < 2*TIME_MINUTE ){ return; } + } else { + if ( (gameTime - tBeaconSent) < 1*TIME_MINUTE ){ return; } + } + + while ( _toPlayer < MAX_PLAYERS ){ + if( friendlyPlayer(_toPlayer) ){ + if ( _bToHuman ){ + if ( isHumanPlayer(_toPlayer) ){ + dropBeacon( _message, _toPlayer, player, _x, _y, _z ); + msg( _message, player, _toPlayer); + } + } else { //send msg to AI + if ( !isHumanPlayer(_toPlayer) ){ + dropBeacon( "a", _toPlayer, player, _x, _y, _z ); + msg( _message, player, _toPlayer); + } + } + } + _toPlayer++; + } + tBeaconSent = gameTime; + return; + +} + +//----------------------------------------------------------------------------- +// show a debug message -> reports error +function void sendMsgToAllAllies(STRING _message) +{ + local int _c; + _c = 0; + while ( _c < MAX_PLAYERS ){ + if( friendlyPlayer(_c) ) + { + msg(_message, player, _c ); + } + _c++; + } +} +//----------------------------------------------------------------------------- +// show a debug message -> reports error +function void displayErrMsg(STRING _message) +{ + local int _c; + _c = 0; + while ( _c < MAX_PLAYERS ){ + if( isHumanPlayer(_c) ) + { + dbg(_message, _c); + } + _c++; + } +} +//----------------------------------------------------------------------------- +// Return an AA defence as target for +// VTOL: _nDefInRange*3 < vtolDefendGr.members +// DROID: _nDefInRange < 1 +function STRUCTURE getAAStruct(bool _bVTOLTarget) +{ + local int _n, _bestDist, _tempDist, _targetPl, _dist, _numPl,_nDefInRange; + local STRUCTURE _bestAAdef, _tempAAdef, _BaseStruct,_struct; + + _bestDist = 999*TILE; + _bestAAdef = NULLOBJECT; + _numPl = 0;//avoid to start always from player 0 + _targetPl = random(MAX_PLAYERS);//avoid to start always from player 0 + + while(_numPl < MAX_PLAYERS) + { + + if ( !friendlyPlayer(_targetPl) and isPlayerStillLive(_targetPl) ){ + //displayMsg("undefendedEnemyAAdef: AAdef x-y("& _targetPl &"-"& count &")"); + //find enemy HQ and check distance to AAdef + _dist = 0; + _struct = getStructure(playerHQ,_targetPl); + if ( _struct == NULLOBJECT ){ + _struct = getStructure(factory,_targetPl); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(resLab,_targetPl); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(cybFactory,_targetPl); + } + + if ( _struct != NULLOBJECT ){ + //only AAdefs visible to player (myself) are processed + + _n=0; + while (_n < numGenAA){ + + if ( AIstrength < 4 ){ + initEnumStruct(false,vtolGenStruct[_n],_targetPl,player); //only struct visible to player + } else { + initEnumStruct(false,vtolGenStruct[_n],_targetPl,_targetPl); //all structs, also those not visible to player + } + _tempAAdef = enumStruct(); + while(_tempAAdef != NULLOBJECT and _struct != NULLOBJECT) + { + _tempDist = distBetweenTwoPoints(_tempAAdef.x, _tempAAdef.y, baseX, baseY); + _dist = distBetweenTwoPoints(_struct.x, _struct.y, _tempAAdef.x, _tempAAdef.y); + + if ( _bVTOLTarget ){ + _nDefInRange = numEnemyAAInRange(_tempAAdef.x, _tempAAdef.y, AA_THREAT_RANGE ); + if (_tempDist < _bestDist and _dist > 20*TILE and _nDefInRange*3 < vtolDefendGr.members ){ + _bestAAdef = _tempAAdef; + _bestDist = _tempDist; + } + } else { + _nDefInRange = numEnemyWeapStructsInRange(player, _tempAAdef.x, _tempAAdef.y, COMBAT_RANGE , false); + if (_tempDist < _bestDist and _dist > 20*TILE and _nDefInRange < 1 ){ + _bestAAdef = _tempAAdef; + _bestDist = _tempDist; + } + } + + _tempAAdef = enumStruct(); + }//while + + _n++; + }//while + + + + }//struct + + + } + _targetPl++; + if ( _targetPl > 7 ){ _targetPl = 0; } + _numPl++; + }//endwhile players + + return _bestAAdef; +} +//----------------------------------------------------------------------------- +// Return a derrick as target for +// VTOL: _nDefInRange*3 < vtolDefendGr.members +// DROID: _nDefInRange < 1 +function STRUCTURE undefendedEnemyDerrick(bool _bVTOLTarget) +{ + local int _bestDist, _tempDist, _targetPl, _dist, _numPl,_nDefInRange; + local STRUCTURE _derrick, _tempDerrick, _BaseStruct,_struct; + + _bestDist = 999*TILE; + _derrick = NULLOBJECT; + _numPl = 0;//avoid to start always from player 0 + _targetPl = random(MAX_PLAYERS);//avoid to start always from player 0 + + while(_numPl < MAX_PLAYERS) + { + + if ( !friendlyPlayer(_targetPl) and isPlayerStillLive(_targetPl) ){ + //displayMsg("undefendedEnemyDerrick: derrick x-y("& _targetPl &"-"& count &")"); + //find enemy HQ and check distance to derrick + _dist = 0; + _struct = getStructure(playerHQ,_targetPl); + if ( _struct == NULLOBJECT ){ + _struct = getStructure(factory,_targetPl); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(resLab,_targetPl); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(cybFactory,_targetPl); + } + + if ( _struct != NULLOBJECT ){ + //only derricks visible to player (myself) are processed + if ( AIstrength < 4 ){ + initEnumStruct(false,derrick,_targetPl,player); //only struct visible to player + } else { + initEnumStruct(false,derrick,_targetPl,_targetPl); //all structs, also those not visible to player + } + _tempDerrick = enumStruct(); + while(_tempDerrick != NULLOBJECT and _struct != NULLOBJECT) + { + _tempDist = distBetweenTwoPoints(_tempDerrick.x, _tempDerrick.y, baseX, baseY); + _dist = distBetweenTwoPoints(_struct.x, _struct.y, _tempDerrick.x, _tempDerrick.y); + + if ( _bVTOLTarget ){ + _nDefInRange = numEnemyAAInRange(_tempDerrick.x, _tempDerrick.y, AA_THREAT_RANGE ); + if (_tempDist < _bestDist and _dist > 20*TILE and _nDefInRange*3 < vtolDefendGr.members ){ + _derrick = _tempDerrick; + _bestDist = _tempDist; + } + } else { + _nDefInRange = numEnemyWeapStructsInRange(player, _tempDerrick.x, _tempDerrick.y, COMBAT_RANGE , false); + if (_tempDist < _bestDist and _dist > 20*TILE and _nDefInRange < 1 ){ + _derrick = _tempDerrick; + _bestDist = _tempDist; + } + } + + _tempDerrick = enumStruct(); + }//while + }//struct + + + } + _targetPl++; + if ( _targetPl > 7 ){ _targetPl = 0; } + _numPl++; + }//endwhile players + + return _derrick; +} +//----------------------------------------------------------------------------- +function STRUCTURE closestEnemyDerrick(bool _mustBeHuman, int _targetPlayer) +{ + + local int _bestDist, _tempDist, _targetPl, _dist,_xCoord,_yCoord ; + local STRUCTURE _derrick, _tempDerrick, _BaseStruct,_struct; + + _bestDist = 999*TILE; + _derrick = NULLOBJECT; + _targetPl = 0;//avoid to start always from player 0 + + while(_targetPl < MAX_PLAYERS) + { + + boolResult = true; + if ( _mustBeHuman and !isHumanPlayer(_targetPl) ){ + boolResult = false; + } + //a target player is required? + if ( _targetPlayer >= 0 and _targetPlayer != _targetPl ){ + boolResult = false; + } + + if ( !friendlyPlayer(_targetPl) and boolResult ){ + + //displayMsg("closestEnemyDerrick: derrick x-y("& _targetPl &"-"& count &")"); + //find enemy HQ and check distance to derrick + _dist = 0; + _xCoord = getEnemy_baseCoord( _targetPl , "X" ); + _yCoord = getEnemy_baseCoord( _targetPl , "Y" ); + + if (_xCoord>0 and _yCoord>0 ){ + //only derricks visible to player (myself) are processed + initEnumStruct(false,derrick,_targetPl,player); + _tempDerrick = enumStruct(); + while(_tempDerrick != NULLOBJECT and _struct != NULLOBJECT) + { + _tempDist = distBetweenTwoPoints(_tempDerrick.x, _tempDerrick.y, baseX, baseY); + _dist = distBetweenTwoPoints(_xCoord, _yCoord, _tempDerrick.x, _tempDerrick.y); + + //displayMsg("closestEnemyDerrick: _targetPl("& _targetPl &") _tempDist("& _tempDist/TILE &") _dist("& _dist/TILE &") _tempDerrick("& _tempDerrick.id &") derrick x-y("& _tempDerrick.x/TILE &"-"& _tempDerrick.y/TILE &")"); + if (_tempDist < _bestDist and _dist > 20*TILE ){ + _derrick = _tempDerrick; + _bestDist = _tempDist; + } + _tempDerrick = enumStruct(); + }//while + } + + + } + _targetPl++; + }//endwhile players + + return _derrick; + +} +//----------------------------------------------------------------------------- +/* + Used to pick up the most appropriate Derrick to defend. + It also check that the Derrick has already enough defences or not. +*/ +function STRUCTURE closestDerrickToDefend() +{ + local int _bestDist, _derrickDist; + local STRUCTURE _derrick, _tempDerrick; + local bool _OK1, _OK2; + + _bestDist = 999*TILE; + _derrick = NULLOBJECT; + + initEnumStruct(false,derrick,player,player); + _tempDerrick = enumStruct(); + + if( !isStructureAvailable(pickDefQueue[pickDefQueueDepth],player) ) + { + return _derrick; + } + while(_tempDerrick != NULLOBJECT) + { + _OK1 = false; + _OK2 = false; + _derrickDist = distBetweenTwoPoints(_tempDerrick.x,_tempDerrick.y, baseX, baseY); + if( _derrickDist > max(nBaseRange,15*TILE) ) + { + + //check derrick area + if( numFriendlyWeapStructsInRange(player, _tempDerrick.x, _tempDerrick.y, TILE*5, false) < MAX_DEFSTR_DERRICKS) + { + if ( _derrickDist < _bestDist ) + { + _OK1 = true; + //displayMsg("closestDerrickToDefend: ("& _tempDerrick.id &") distance ("& _OK1 &")("& _OK2 &") !!"); + } + } //else { displayMsg("closestDerrickToDefend: derrick ("& _tempDerrick.id &") already with defences in DERRICK AREA" ); } + + //now check the building area + buildX = _tempDerrick.x; + buildY = _tempDerrick.y; + boolResult = pickStructLocation(pickDefQueue[pickDefQueueDepth], ref buildX, ref buildY, player); + if(boolResult) + { + //check for defence structs in BUILDING area, this is an HACK + if( numFriendlyWeapStructsInRange(player, buildX, buildY, TILE*6, false) < MAX_DEFSTR_DERRICKS){ + _OK2 = true; + } //else { displayMsg("closestDerrickToDefend: derrick ("& _tempDerrick.id &") already with defences in BUILD AREA" ); } + } //else { displayMsg("closestDerrickToDefend: cannor build a def struct around ("& _tempDerrick.id &") " ); } + + if ( _OK1 and _OK2 ) + { + _derrick = _tempDerrick; + _bestDist = _derrickDist; + } + + } //else { //displayMsg("closestDerrickToDefend: derrick ("& _tempDerrick.id &") is in the base" ); } + _tempDerrick = enumStruct(); + }//endwhile + return _derrick; +} +//----------------------------------------------------------------------------- +//Pick up the closest oilRes at given coord and check that oliRes is not already +//a "target" of another droid +function STRUCTURE closestOilRes(DROID _droid, int _x, int _y) +{ + local int _bestDist,_tempDist, _nOilResFound, _i, _ii, _player; + local FEATURE _closestOilRes,_tempOilRes; + local bool _okToProceed; + local STRUCTURE _hq; + + _bestDist = 999*TILE; + _closestOilRes = NULLOBJECT; + _okToProceed = TRUE; + _nOilResFound = 0; + + _player=0; + while (_player < MAX_PLAYERS) + { + initGetFeature(oilRes,-1,player); + _tempOilRes = getFeature(player); + _ii = 0; + while(_tempOilRes != NULLOBJECT and _ii < MAX_WHILE_LOOPS) + { + + //check the oilRes can be reached + if ( _droid != NULLOBJECT ){//droid is set in harvestoperate and cannot be NULLOBJECT + if ( !droidCanReach(_droid, _tempOilRes.x ,_tempOilRes.y)){ + _okToProceed = false; + } + } else { + _okToProceed = false; + } + //displayMsg("OilRes ("& _tempOilRes.id &") @("& _tempOilRes.x/TILE &")("& _tempOilRes.y/TILE &") can be reached ("& _okToProceed &") by droid ("& _droid.id &")"); + + //check that this OilRes is not already a "target" of a droid + if ( gameTime < TIME_HARVESTING_PHASE ){ + _i = 0; + while (_i < 11) + { + if ( _tempOilRes.id == oilResTargetId[_i] ){ + _okToProceed = false; + } + _i++; + } + } + + //check oilRes is not in range of an Ally base, leave this oilRes to the Ally + if ( _okToProceed and (_player != player) and allianceExistsBetween(_player,player) ){//OK + _hq = getStructure(playerHQ,_player); + if ( _hq != NULLOBJECT ) { + if( distBetweenTwoPoints(_tempOilRes.x ,_tempOilRes.y ,_hq.x ,_hq.y) < 15 * TILE ) + { + _okToProceed = false; + } + } + } + + //check for threats in range + if( gameTime > TIME_HARVESTING_PHASE ){ + if( threatInRange(player ,_tempOilRes.x, _tempOilRes.y, THREAT_RANGE_TILES_LONG*128, false) ) + { + _okToProceed = false; + } + } else { + if ( threatInRange(player ,_tempOilRes.x, _tempOilRes.y, THREAT_RANGE_TILES_SHORT*128, false) ) + { + _okToProceed = false; + } + } + + + if ( _okToProceed ) { + _tempDist = distBetweenTwoPoints(_tempOilRes.x, _tempOilRes.y, _x, _y); + //displayMsg("Closest Oil Res: oilRes ("& _tempOilRes.id &") dist / best ("& _tempDist/TILE &" / "& _bestDist/TILE &") ("& _tempOilRes.x/TILE &"-"& _tempOilRes.y/TILE &")"); + if (_tempDist < _bestDist ) + { + _closestOilRes = _tempOilRes; + _bestDist = _tempDist; + } + } //else { displayMsg("Closest Oil Res: player ("& player &") cannot proceed for oilRes ("& _tempOilRes.id &") dist ("& distBetweenTwoPoints(_tempOilRes.x, _tempOilRes.y, _x, _y)/TILE &") ("& _tempOilRes.x/TILE &"-"& _tempOilRes.y/TILE &")"); } + _tempOilRes = getFeature(player); + _nOilResFound++; + _okToProceed = true; + _ii++; + } + _player++; + } + + return _closestOilRes; +} + +//----------------------------------------------------------------------------- +function DROID getADroid(GROUP _theGRP) +{ + local DROID _tempTruck,_returnTruck; + + _returnTruck = NULLOBJECT; + + initIterateGroup(_theGRP); + _tempTruck = iterateGroup(_theGRP); + while(_tempTruck != NULLOBJECT) + { + _returnTruck = _tempTruck; + _tempTruck = iterateGroup(_theGRP); + } + + return _returnTruck; +} +//----------------------------------------------------------------------------- +function bool droidOrderIdle(DROID _droid) +{ + if(_droid.order == DORDER_RTB){ + return true; + } + + if(_droid.order == DORDER_STOP){ + return true; + } + + if(_droid.order == DORDER_NONE){ + return true; + } + + if(_droid.order == DORDER_GUARD){ + return true; + } + + return false; +} +//----------------------------------------------------------------------------- +function void debugCentreView(DROID _droid) +{ + + local int _player; + _player = 0; + if( debugCenterView == true ){ + while(_player < 8) + { + if( isHumanPlayer(_player) and allianceExistsBetween(_player,player) ) { //OK + centreView(_droid); + } + _player++; + } + } +} + +//----------------------------------------------------------------------------- +function DROID pickDefTruck(bool _idleOne) +{ + local DROID _tempTruck, _Truck; + + _Truck = NULLOBJECT; + + initIterateGroup(buildDefGroup); + _tempTruck = iterateGroup(buildDefGroup); + //let`s try with really idle one + while( _tempTruck != NULLOBJECT and _Truck == NULLOBJECT ) + { + if( droidOrderIdle(_tempTruck) ) { + _Truck = _tempTruck; + } + if ( !_idleOne and _Truck == NULLOBJECT ){ + if ( _tempTruck.order == DORDER_HELPBUILD or _tempTruck.order == DORDER_REPAIR ){ + _Truck = _tempTruck; + } + } + _tempTruck = iterateGroup(buildDefGroup); + }//end while + + /* + //now try with trucks just helping or repairing + if ( _Truck == NULLOBJECT ){ + initIterateGroup(buildDefGroup); + _tempTruck = iterateGroup(buildDefGroup); + while( _tempTruck != NULLOBJECT and _Truck == NULLOBJECT ) + { + if( droidOrderIdle(_tempTruck) or _tempTruck.order == DORDER_HELPBUILD or _tempTruck.order == DORDER_REPAIR) { + _Truck = _tempTruck; + } + _tempTruck = iterateGroup(buildDefGroup); + }//end while + } + */ + + return _Truck; +} +//----------------------------------------------------------------------------- +// use numFriendlyWeapStructsInRange(player, _struct.x, _struct.y, COMBAT_RANGE, onlycompletedStruct); +function void buildGatewayDef(DROID _defTruck, int _pos) +{ + local int _x,_y,_nDefBuilt,_tmpl,_n; + + if (_defTruck == NULLOBJECT ){ return; } + + //dbg("dbg->buildGatewayDef(): START numDefStrAtGateway("& numDefStrAtGateway &") _x/_y("& _x &"-"& _y &")",player); + if(pickWallDefQueueDepth <= 0 and pickDefQueueDepth <= 0){ + //dbg("dbg->buildGatewayDef(): No wall def available",player); + return; + } + + _x = aGatewayPosX[_pos]; + _y = aGatewayPosY[_pos]; + if ( pickWallDefQueueDepth > 0 ){ + _n = min(pickWallDefQueueDepth,3); + _tmpl = pickWallDefQueueDepth - 1 - _random(_n); + if(isStructureAvailable(pickWallDefQueue[_tmpl],player)){ + skDefenseLocationB(ref _x, ref _y, wall, pickWallDefQueue[_tmpl], _defTruck, player); + //dbg("dbg->buildGatewayDef(): droid ("& _defTruck.id &") build WALL def ["& _tmpl &"], best is ["& pickWallDefQueueDepth &"] - at("& _x/TILE &"-"& _y/TILE &")",player); + printDebug1("buildGatewayDef(): build WALL def ["& _tmpl &"], best is ["& pickWallDefQueueDepth &"] - at("& _x/TILE &"-"& _y/TILE &")"); + } + + } + + /* + else { + + //standard defences + _n = min(pickDefQueueDepth,3); + _tmpl = pickDefQueueDepth - 1 - _random(_n); + boolResult = isStructureAvailable(pickDefQueue[_tmpl],player); + //dbg("dbg->buildGatewayDef(): STD _tmpl("& _tmpl &") avail("& boolResult &") numDefStrAtGateway("& numDefStrAtGateway &") _x/_y("& _x/TILE &"-"& _y/TILE &")",player); + if( isStructureAvailable(pickDefQueue[_tmpl],player) ){ + + _x = getSafeBuildCoord( _defTruck, pickDefQueue[_tmpl], _x, _y, 0);//_x + _y = getSafeBuildCoord( _defTruck, pickDefQueue[_tmpl], _x, _y, 1);//_y + boolResult = pickStructLocation(pickDefQueue[_tmpl], ref _x, ref _y, player); + boolResult2 = droidCanReach(_defTruck, _x ,_y); + //dbg("dbg->buildGatewayDef(): STD droid can reach ("& boolResult2 &") _x/_y("& _x/TILE &"-"& _y/TILE &")",player); + if(boolResult and droidCanReach(_defTruck, _x ,_y)){ + orderDroidStatsLoc(_defTruck, DORDER_BUILD,pickDefQueue[_tmpl], _x, _y); + lastBuildDefX = _x;//store coord needed to check if struct has been built + lastBuildDefY = _y; + //dbg("buildGatewayDef: build STD def ["& _tmpl &"], best is ["& pickDefQueueDepth &"] - at("& _x/TILE &"-"& _y/TILE &")",player); + printDebug1("buildGatewayDef(): droid build STD def ["& _tmpl &"], best is ["& pickDefQueueDepth &"] - at("& _x/TILE &"-"& _y/TILE &")"); + } + } + } + */ +} +//----------------------------------------------------------------------------- +// _x and _y are changed per reference +function int getSafeBuildCoord( DROID _droid, STRUCTURESTAT _struct, int _x, int _y, int _choice) +{ + local int _x1, _y1, _c1, _c2, _c3, _aX[8], _aY[8], _aD[8]; + + _c3 = 0; + while ( _c3 < 8){ + _aX[_c3] = -1; + _aY[_c3] = -1; + _aD[_c3] = -1; + _c3++; + } + + boolResult = pickStructLocation(_struct, ref _x, ref _y, player); + boolResult2 = droidCanReach(_droid, _x ,_y); + if ( boolResult and boolResult2 ){ + if ( _choice == 0 ){ return _x; } + if ( _choice == 1 ){ return _y; } + } + + _x1 = _x; _y1 = _y; + _c3 = 1; _c2 = 0; + while ( _c3 < 3){ + + _x = _x1 + _c3*TILE; + _y = _y1 + _c3*TILE; + boolResult = pickStructLocation(_struct, ref _x, ref _y, player); + boolResult2 = droidCanReach(_droid, _x ,_y); + //dbg("dbg->getSafeBuildCoord: try x-y("& _x/TILE &"-"& _y/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + if ( boolResult and boolResult2 ){ + _aX[_c2] = _x; + _aY[_c2] = _y; + _aD[_c2] = distBetweenTwoPoints(_x,_y,_x1,_y1); + //dbg("dbg->getSafeBuildCoord: added in _c2("& _c2 &") x-y("& _aX[_c2]/TILE &"-"& _aY[_c2]/TILE &") dist ("& _aD[_c2]/TILE &"/"& _c1/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + _c2++; + } + + _x = _x1 - _c3*TILE; + _y = _y1 - _c3*TILE; + boolResult = pickStructLocation(_struct, ref _x, ref _y, player); + boolResult2 = droidCanReach(_droid, _x ,_y); + if ( boolResult and boolResult2 ){ + _aX[_c2] = _x; + _aY[_c2] = _y; + _aD[_c2] = distBetweenTwoPoints(_x,_y,_x1,_y1); + //dbg("dbg->getSafeBuildCoord: added in _c2("& _c2 &") x-y("& _aX[_c2]/TILE &"-"& _aY[_c2]/TILE &") dist ("& _aD[_c2]/TILE &"/"& _c1/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + _c2++; + } + + _x = _x1 + _c3*TILE; + _y = _y1 - _c3*TILE; + boolResult = pickStructLocation(_struct, ref _x, ref _y, player); + boolResult2 = droidCanReach(_droid, _x ,_y); + if ( boolResult and boolResult2 ){ + _aX[_c2] = _x; + _aY[_c2] = _y; + _aD[_c2] = distBetweenTwoPoints(_x,_y,_x1,_y1); + //dbg("dbg->getSafeBuildCoord: added in _c2("& _c2 &") x-y("& _aX[_c2]/TILE &"-"& _aY[_c2]/TILE &") dist ("& _aD[_c2]/TILE &"/"& _c1/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + _c2++; + } + + _x = _x1 - _c3*TILE; + _y = _y1 + _c3*TILE; + boolResult = pickStructLocation(_struct, ref _x, ref _y, player); + boolResult2 = droidCanReach(_droid, _x ,_y); + if ( boolResult and boolResult2 ){ + _aX[_c2] = _x; + _aY[_c2] = _y; + _aD[_c2] = distBetweenTwoPoints(_x,_y,_x1,_y1); + //dbg("dbg->getSafeBuildCoord: added in _c2("& _c2 &") x-y("& _aX[_c2]/TILE &"-"& _aY[_c2]/TILE &") dist ("& _aD[_c2]/TILE &"/"& _c1/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + _c2++; + } + + _c3++; + } + + _c3 = 0; + _c1 = 9999*TILE; + //find the nearest place to build + while ( _c3 < _c2 ){ + //dbg("dbg->getSafeBuildCoord: ("& _aX[_c3]/TILE &"-"& _aY[_c3]/TILE &") dist ("& _aD[_c3]/TILE &"/"& _c1/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + if ( _aD[_c3] < _c1 ){ + _x = _aX[_c3]; + _y = _aY[_c3]; + _c1 = _aD[_c3]; + } + _c3++; + } + + //dbg("dbg->getSafeBuildCoord: safe build pos found in ("& _x/TILE &"-"& _y/TILE &") dist ("& _c1/TILE &") from ("& _x1/TILE &"-"& _y1/TILE &")",player); + + if ( _choice == 0 ){ return _x; } + if ( _choice == 1 ){ return _y; } + + return -1; + +} +//----------------------------------------------------------------------------- +function bool isDefStrComplete() +{ + local STRUCTURE _defense; + local int _i; + + _i=0; + _defense = NULLOBJECT; + + while(_i < pickDefQueueDepth ) + { + initEnumStruct(FALSE,pickDefQueue[_i],player,player); + _defense = enumStruct(); + while (_defense != NULLOBJECT){ + //displayMsg("isDefStrComplete: looping def struct ("& _i &") at ("& _defense.x &"-"& _defense.y &") "); + if(_defense.x==lastBuildDefX and _defense.y==lastBuildDefY){ + //displayMsg("isDefStrComplete: found def struct at ("& lastBuildDefX &"-"& lastBuildDefY &") "); + if(!structureComplete(_defense)){ + //displayMsg("isDefStrComplete: def NOT complete "); + return false; + } else { + //displayMsg("isDefStrComplete: def IS complete "); + return true; + } + } + _defense = enumStruct(); + } + _i++; + }//endwhile + + //displayMsg("isDefStrComplete: OUT OF THE LOOP "); + return false; +} +//----------------------------------------------------------------------------- +//sends the defTruck to help building structures. +//It checks there are no threat in range. +function bool helpBuild(int _group) +{ + local DROID _idleTruck; + local STRUCTURE _structurestat; + local int _i; + + _i=0; + + if (_group == BUILDDEF_GRP){ + _idleTruck = pickDefTruck(true); + } + if (_group == CYBENG_GRP){ + _idleTruck = pickCybEng(true); + } + if (_group == BUILD_GRP){ + _idleTruck = closestIdleDroid(buildGroup,baseX, baseY); + } + if (_group == HARVEST_GRP){ + _idleTruck = closestIdleDroid(harvesterGroup,baseX, baseY); + } + + if (_idleTruck == NULLOBJECT){ return false; } + + //look for def structures first + while(_i < pickWallDefQueueDepth ) + { + initEnumStruct(FALSE,pickWallDefQueue[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if ( !structureComplete(_structurestat) ){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + //look for def structures first + while(_i < pickDefQueueDepth ) + { + initEnumStruct(FALSE,pickDefQueue[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if ( !structureComplete(_structurestat) ){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + //look for for incendries + //numIncendrys INT 8 + //incendrys[7] STRUCTURESTAT "Emplacement-MortarPit01" + //look for def structures first + _i=0; + while(_i < numIncendrys ) + { + initEnumStruct(FALSE,incendrys[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if ( !structureComplete(_structurestat) ){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + if (_idleTruck == NULLOBJECT){ return false; } + //look for sensor types + //numSense INT 3 + //sense[0] STRUCTURESTAT "Sys-SensoTowerWS" + _i=0; + while(_i < numSense ) + { + initEnumStruct(FALSE,sense[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if ( !structureComplete(_structurestat) ){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + + + //look for anti a. + //numAA INT 6 + //vtolDefStruct[0] STRUCTURESTAT "AASite-QuadMg1" //hurricane + _i=0; + while(_i < numAA ) + { + initEnumStruct(FALSE,vtolDefStruct[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if ( !structureComplete(_structurestat) ){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + if (_idleTruck == NULLOBJECT){ return false; } + + //look for Fortresses structs. + //numFortressDef + //fortressDef[0] + _i=0; + while(_i < numFortressDef ) + { + initEnumStruct(FALSE,fortressDef[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if(!structureComplete(_structurestat)){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES_SHORT*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + + //look for Essential structs. + //numStructs + //structs[0] + _i=0; + while(_i < numStructs ) + { + initEnumStruct(FALSE,baseStructs[_i],player,player); + _structurestat = enumStruct(); + while (_structurestat != NULLOBJECT){ + if(!structureComplete(_structurestat)){ + if ( !threatInRange(player,_structurestat.x, _structurestat.y, THREAT_RANGE_TILES_SHORT*128, false) ) + { + if (droidCanReach(_idleTruck, _structurestat.x, _structurestat.y) ){ + orderDroidObj(_idleTruck,DORDER_HELPBUILD,_structurestat); + return true; + } + } //else {displayMsg("helpBuild: there is some threat in range");} + } + _structurestat = enumStruct(); + }//while struct + _i++; + }//While _i + + //displayMsg("helpBuild: no structs found"); + return false; +} + + +//----------------------------------------------------------------------------- +//search for the most damaged structure in the base and repair it +//if found return true, otherwise return false. Return false also +// if not idle trucks are found. it checks there are no threats in range +function bool repairStructs(int _group) +{ + local int _mostDamage,_tempDamage, _i,_numStrToCheck; + local STRUCTURE _structure, _mostDamagedStructure; + local DROID _idleTruck; + + _mostDamage = 0; + _mostDamagedStructure = NULLOBJECT; + _idleTruck = NULLOBJECT; + + if (_group == BUILDDEF_GRP){ + _idleTruck = pickDefTruck(true); + } + if (_group == CYBENG_GRP){ + _idleTruck = pickCybEng(true); + } + if (_group == BUILD_GRP){ + _idleTruck = closestIdleDroid(buildGroup,baseX, baseY); + } + if (_group == HARVEST_GRP){ + _idleTruck = closestIdleDroid(harvesterGroup,baseX, baseY); + } + + if (_idleTruck == NULLOBJECT){ return false; } + + + _i = 0; + _numStrToCheck = (numBaseStructs - 1); + while( _i < _numStrToCheck )//exclude derricks, threated below in this function + { + initEnumStruct(FALSE,baseStructs[_i],player,player); + _structure = enumStruct(); + while(_structure != NULLOBJECT) + { + _tempDamage = 100 - _structure.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + //if ( !threatInRange(player,_structure.x, _structure.y, THREAT_RANGE_TILES*128, false) ) + //{ + if(_tempDamage > _mostDamage){ + _mostDamage = _tempDamage; + _mostDamagedStructure = _structure; + } + //} + } + _structure = enumStruct(); + } + _i = _i + 1; + } + + if(_mostDamagedStructure != NULLOBJECT) { + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedStructure); + return true; + } + + initEnumStruct(false,derrick,player,player); + _structure = enumStruct(); + while(_structure != NULLOBJECT) + { + _tempDamage = 100 - _structure.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + if ( !threatInRange(player,_structure.x, _structure.y, THREAT_RANGE_TILES_SHORT*128, false) and distBetweenTwoPoints(_structure.x, _structure.y, baseX, baseY) < nDefendRange ) { + if(_tempDamage > _mostDamage){ + _mostDamage = _tempDamage; + _mostDamagedStructure = _structure; + } + } + } + _structure = enumStruct(); + } + + if(_mostDamagedStructure != NULLOBJECT) { + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedStructure); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +//search for the most damaged sefense in the base and repair it +//if found return true, otherwise return false. Return false also +// if not idle trucks are found. it checks there are no threats in range +function bool repairDefStructs(int _group) +{ + local int _mostDamage,_tempDamage, _i; + local STRUCTURE _defense, _mostDamagedDefense; + local DROID _idleTruck; + + _mostDamage = 0; + _mostDamagedDefense = NULLOBJECT; + + _idleTruck = NULLOBJECT; + + if (_group == BUILDDEF_GRP){ + _idleTruck = pickDefTruck(true); + } + if (_group == CYBENG_GRP){ + _idleTruck = pickCybEng(true); + } + if (_group == BUILD_GRP){ + _idleTruck = closestIdleDroid(buildGroup,baseX, baseY); + } + if (_group == HARVEST_GRP){ + _idleTruck = closestIdleDroid(harvesterGroup,baseX, baseY); + } + + if (_idleTruck == NULLOBJECT){ return false; } + +//look for vtol def + _i=0; + while(_i < numAA ) + { + initEnumStruct(FALSE,vtolDefStruct[_i],player,player); + _defense = enumStruct(); + while (_defense != NULLOBJECT){ + if(distBetweenTwoPoints(_defense.x, _defense.y, baseX, baseY) < nDefendRange ){ + _tempDamage = 100 - _defense.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + if ( !threatInRange(player,_defense.x, _defense.y, THREAT_RANGE_TILES*128, false) ) { + if(_tempDamage > _mostDamage) { + _mostDamage = _tempDamage; + _mostDamagedDefense = _defense; + } + } + } + } + _defense = enumStruct(); + }//while struct + _i++; + }//While _i + if(_mostDamagedDefense != NULLOBJECT) + { + //displayMsg("**** repairDefStructs: found a damaged def struct damage=("& _mostDamage &") "); + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedDefense); + return true; + } + + _i=0; + //look for def structures + while(_i < pickWallDefQueueDepth ) + { + initEnumStruct(FALSE,pickWallDefQueue[_i],player,player); + _defense = enumStruct(); + while (_defense != NULLOBJECT){ + if(distBetweenTwoPoints(_defense.x, _defense.y, baseX, baseY) < nDefendRange ){ + _tempDamage = 100 - _defense.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + if ( !threatInRange(player,_defense.x, _defense.y, THREAT_RANGE_TILES*128, false) ) { + if(_tempDamage > _mostDamage) { + _mostDamage = _tempDamage; + _mostDamagedDefense = _defense; + } + } + } + } + _defense = enumStruct(); + }//while struct + _i++; + }//While _i + if(_mostDamagedDefense != NULLOBJECT) { + //displayMsg("**** repairDefStructs: found a damaged WALL def struct damage=("& _mostDamage &") "); + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedDefense); + return true; + } + + _i=0; + //look for def structures + while(_i < pickDefQueueDepth ) + { + initEnumStruct(FALSE,pickDefQueue[_i],player,player); + _defense = enumStruct(); + while (_defense != NULLOBJECT){ + if(distBetweenTwoPoints(_defense.x, _defense.y, baseX, baseY) < nDefendRange ){ + _tempDamage = 100 - _defense.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + if ( !threatInRange(player,_defense.x, _defense.y, THREAT_RANGE_TILES*128, false) ) { + if(_tempDamage > _mostDamage) { + _mostDamage = _tempDamage; + _mostDamagedDefense = _defense; + } + } + } + } + _defense = enumStruct(); + }//while struct + _i++; + }//While _i + if(_mostDamagedDefense != NULLOBJECT) { + //displayMsg("**** repairDefStructs: found a damaged def struct damage=("& _mostDamage &") "); + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedDefense); + return true; + } + + //double check... + if (_idleTruck == NULLOBJECT){ return false; } + + //look for for incendries + _i=0; + while(_i < numIncendrys ) + { + initEnumStruct(FALSE,incendrys[_i],player,player); + _defense = enumStruct(); + while (_defense != NULLOBJECT){ + if(distBetweenTwoPoints(_defense.x, _defense.y, baseX, baseY) < nDefendRange ){ + _tempDamage = 100 - _defense.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + if ( !threatInRange(player,_defense.x, _defense.y, THREAT_RANGE_TILES*128, false) ) { + if(_tempDamage > _mostDamage) { + _mostDamage = _tempDamage; + _mostDamagedDefense = _defense; + } + } + } + } + _defense = enumStruct(); + }//while struct + _i++; + }//While _i + if(_mostDamagedDefense != NULLOBJECT) + { + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedDefense); + return true; + } + + //double check... + if (_idleTruck == NULLOBJECT){ return false; } + + //look for sensor types + //numSense INT 3 + //sense[0] STRUCTURESTAT "Sys-SensoTowerWS" + _i=0; + while(_i < numSense ) + { + initEnumStruct(FALSE,sense[_i],player,player); + _defense = enumStruct(); + while (_defense != NULLOBJECT){ + if( distBetweenTwoPoints(_defense.x, _defense.y, baseX, baseY) < nDefendRange ){ + _tempDamage = 100 - _defense.health; + if(_tempDamage >= STRUCT_REPAIR_DAMAGE){ + if ( !threatInRange(player,_defense.x, _defense.y, THREAT_RANGE_TILES*128, false) ) { + if(_tempDamage > _mostDamage) { + _mostDamage = _tempDamage; + _mostDamagedDefense = _defense; + } + } + } + } + _defense = enumStruct(); + }//while struct + _i++; + }//While _i + if(_mostDamagedDefense != NULLOBJECT){ + //displayMsg("**** repairDefStructs: found a damaged def struct damage=("& _mostDamage &") "); + orderDroidObj(_idleTruck, DORDER_REPAIR, _mostDamagedDefense); + return true; + } + return false; +} + +//----------------------------------------------------------------------------- +/* +update gateways coordinate +this works for now with maps with at least 2 gateways near the base +*/ +function int updateGateways() +{ + local int _x,_y,_tx,_ty,_i,_xx[4],_yy[4]; + local float _basecoordX,_basecoordY; + local int _dist; + + _x = 0; + _y = 0; + + _i=0; + while (_i<4){ + _xx[_i] = -1; + _yy[_i] = -1; + _i++; + } + + //displayMsg("updateGateways:MAP DIMENSIONS("& mapWidth &"-"& mapHeight &")"); + + //corner 1 + _tx = max( baseX-TILE*8 , 0 ); + _ty = max( baseY-TILE*8 , 0 ); + _basecoordX = (float)_tx/(float)TILE; + _basecoordY = (float)_ty/(float)TILE; + if ( getNearestGateway( (int)_basecoordX, (int)_basecoordY, ref _x, ref _y ) ){ + _dist = distBetweenTwoPoints(baseX, baseY, _x*TILE, _y*TILE); + //displayMsg("updateGateways:Base coord 1 dist("& _dist/TILE &") - ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + if( _dist < gatewaysRangeTiles*TILE) { + //displayMsg("updateGateways:Base coord 1a ("& baseX/TILE &"-"& baseY/TILE &") = ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + _xx[0] = _x; + _yy[0] = _y; + }//else {displayMsg("updateGateways:Base coord 1 ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways ("& _x &")-("& _y &") NOT IN RANGE ("& gatewaysRangeTiles*128 &")");} + }//else {displayMsg("Base coord ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways NOT found ");} + + //corner 2 + _x = 0; + _y = 0; + _tx = min( baseX+TILE*8 , mapWidth*TILE ); + _ty = min( baseY+TILE*8 , mapHeight*TILE ); + _basecoordX = (float)_tx/(float)TILE; + _basecoordY = (float)_ty/(float)TILE; + if ( getNearestGateway( (int)_basecoordX, (int)_basecoordY, ref _x, ref _y ) ){ + _dist = distBetweenTwoPoints(baseX, baseY, _x*TILE, _y*TILE); + //displayMsg("updateGateways:Base coord 2 dist("& _dist/TILE &") - ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + if( _dist < gatewaysRangeTiles*TILE) { + if( (_xx[0]+_yy[0] != _x+_y) ) { + //displayMsg("updateGateways:Base coord 2a ("& baseX/TILE &"-"& baseY/TILE &") = ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + _xx[1] = _x; + _yy[1] = _y; + } + }//else {displayMsg("updateGateways:Base coord 2 ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways ("& _x &")-("& _y &") NOT IN RANGE ("& gatewaysRangeTiles*128 &")");} + }//else {displayMsg("Base coord ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways NOT found ");} + + //corner 3 + _x = 0; + _y = 0; + _tx = min( baseX+TILE*8 , mapWidth*TILE ); + _ty = max( baseY-TILE*8 , 0 ); + _basecoordX = (float)_tx/(float)TILE; + _basecoordY = (float)_ty/(float)TILE; + if ( getNearestGateway( (int)_basecoordX, (int)_basecoordY, ref _x, ref _y ) ) + { + _dist = distBetweenTwoPoints(baseX, baseY, _x*TILE, _y*TILE); + //displayMsg("updateGateways:Base coord 3 dist("& _dist/TILE &") - ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + if( _dist < gatewaysRangeTiles*TILE) { + if( (_xx[0]+_yy[0] != _x+_y) and (_xx[1]+_yy[1] != _x+_y) ) { + //displayMsg("updateGateways:Base coord 3a ("& baseX/TILE &"-"& baseY/TILE &") = ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + _xx[2] = _x; + _yy[2] = _y; + } + }//else {displayMsg("updateGateways:Base coord 3 ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways ("& _x &")-("& _y &") NOT IN RANGE ("& gatewaysRangeTiles*128 &")");} + }//else {displayMsg("Base coord ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways NOT found ");} + + //corner 4 + _x = 0; + _y = 0; + _tx = max( baseX-TILE*8 , 0 ); + _ty = min( baseY+TILE*8 , mapHeight*TILE ); + _basecoordX = (float)_tx/(float)TILE; + _basecoordY = (float)_ty/(float)TILE; + if ( getNearestGateway( (int)_basecoordX, (int)_basecoordY, ref _x, ref _y ) ) + { + _dist = distBetweenTwoPoints(baseX, baseY, _x*TILE, _y*TILE); + //displayMsg("updateGateways:Base coord 4 dist("& _dist/TILE &") - ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + if( _dist < gatewaysRangeTiles*TILE) { + if( (_xx[0]+_yy[0] != _x+_y) and (_xx[1]+_yy[1] != _x+_y) and (_xx[2]+_yy[2] != _x+_y) ) { + //displayMsg("updateGateways:Base coord 4a ("& baseX/TILE &"-"& baseY/TILE &") = ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways found at ("& _x &")-("& _y &") "); + _xx[3] = _x; + _yy[3] = _y; + } + }// else {displayMsg("updateGateways:Base coord 4 ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways ("& _x &")-("& _y &") NOT IN RANGE ("& gatewaysRangeTiles*128 &")");} + }//else {displayMsg("Base coord ("& (int)_basecoordX &")-("& (int)_basecoordY &") gateways NOT found ");} + + + //find out how many gateways have been found + _i=0; + while ( _i < 4 ) { + if( _xx[_i] > 0 and _yy[_i] > 0 ) { + //displayMsg("updateGateways: gateways stored at x:("& _xx[_i] &"-"& _yy[_i] &")"); + aGatewayPosX[nRealGatewaysFound] = _xx[_i]*TILE; + aGatewayPosY[nRealGatewaysFound] = _yy[_i]*TILE; + _dist = distBetweenTwoPoints(baseX, baseY, aGatewayPosX[nRealGatewaysFound], aGatewayPosY[nRealGatewaysFound]); + nRealGatewaysFound++; + printDebug1( "gateway #"& nRealGatewaysFound &" coord x-y" & _xx[_i] & "-" & _yy[_i] &" dist from base("& _dist/TILE &") defend range("& nDefendRange/TILE &")" ); + } + _i++; + }//endwhile + + /* + if (nRealGatewaysFound == 0){ + numDefStrAtGateway = 3; + } + if (nRealGatewaysFound == 1){ + numDefStrAtGateway = 5; + } + if (nRealGatewaysFound == 2){ + numDefStrAtGateway = 4; + } + if (nRealGatewaysFound == 3){ + numDefStrAtGateway = 3; + } + if (nRealGatewaysFound == 4){ + numDefStrAtGateway = 2; + } + if (nRealGatewaysFound > 4){ + numDefStrAtGateway = 2; + } + */ + numDefStrAtGateway = 1; + //reSortGateways - put the gateways near to the enemy on the top of the array. + //reSortGateways(); + //displayMsg("*** updateGateways: tot REAL gateways found: ("& nRealGatewaysFound &")" ); + + return nRealGatewaysFound;//default is 0 +} + +//----------------------------------------------------------------------------- +function void initAssignUnitToGrp() +{ + local GROUP xGRP; + local DROID _droid; + local int cc,_tot; + + cc=0; + groupAddArea(xGRP, player, 0, 0, (mapWidth*128), (mapHeight*128)); + initIterateGroup(xGRP); + droid = iterateGroup(xGRP); + while(droid != NULLOBJECT) + { + assignDroidToGrp(droid); + droid = iterateGroup(xGRP); + } + + //in assignDroidToGrp all trcks are assigned as default to buildGroup + _tot = buildGroup.members; + if ( _tot == 2 or _tot == 3 ){ + _droid = getADroid(buildGroup); + if (_droid != NULLOBJECT){ + groupAddDroid(harvesterGroup, _droid ); + } + } + if ( _tot > 3 ){ + _droid = getADroid(buildGroup); + if (_droid != NULLOBJECT){ + groupAddDroid(harvesterGroup, _droid ); + } + _droid = getADroid(buildGroup); + if (_droid != NULLOBJECT){ + groupAddDroid(harvesterGroup, _droid ); + } + } + +} +//----------------------------------------------------------------------------- +function void updateBaseRange() +{ + + local int _baseRange,_i,_result; + + maxy = 0; maxx = 0; + miny = (mapHeight*128); minx = (mapWidth*128); + + _baseRange = 1; //avoid possible div by 0 + aaRange = 1; + + _i = 0; + while( _i+1 < numBaseStructs )//need +1 to exclude the derricks!!! + { + initEnumStruct(FALSE,baseStructs[_i],player,player); + structure = enumStruct(); + while(structure != NULLOBJECT) + { + if(structure.x < minx){minx = structure.x;} + if(structure.x > maxx){maxx = structure.x;} + if(structure.y < miny){miny = structure.y;} + if(structure.y > maxy){maxy = structure.y;} + + _result = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y); + if(_result > _baseRange){_baseRange = _result;} + + structure = enumStruct(); + } + _i = _i + 1; + } + + _result = 7 * TILE; + + minx = minx - _result; maxx = maxx + _result; + miny = miny - _result; maxy = maxy + _result; + + if(minx < 0){minx = TILE;} + if(miny < 0){miny = TILE;} + if(maxx > (mapWidth * TILE)){maxx = (mapWidth * TILE) - TILE;} + if(maxy > (mapHeight * TILE)){maxy = (mapHeight * TILE) - TILE;} + + aaRange = _baseRange + TILE; //between the base and _baseRange + + nBaseRange = _baseRange + (5 * TILE); +} + +//----------------------------------------------------------------------------- +function void updateDefendRange() +{ + + local int _n,_g; + + //Update nDefendRange + _n = 0; + _g = 999*TILE; + while ( _n < MAX_PLAYERS ) + { + if ( !friendlyPlayer(_n) ) {//replace the code below with initenumstruct() + structure = getStructure(playerHQ,_n); + if ( structure == NULLOBJECT ){ structure = getStructure(factory,_n); } + if ( structure == NULLOBJECT ){ structure = getStructure(powGen,_n); } + if ( structure == NULLOBJECT ){ structure = getStructure(vtolFactory,_n); } + if ( structure == NULLOBJECT ){ structure = getStructure(cybFactory,_n); } + if ( structure == NULLOBJECT ){ structure = getStructure(uplinkCenter,_n); } + if ( structure == NULLOBJECT ){ structure = getStructure(resLab,_n); } + if ( structure != NULLOBJECT ){ + if ( distBetweenTwoPoints(baseX ,baseY ,structure.x ,structure.y) < _g ) + { + _g = distBetweenTwoPoints(baseX ,baseY ,structure.x ,structure.y);//best dist + } + } + } + _n++; + } + if ( _g != 999*TILE ){ + nDefendRange = _g/2; + } else { + + if ( nPlayersInGame > 1 ){ + if (nPlayersInGame < 5 ){ + nDefendRange = (int)(float)( ( max(mapWidth,mapHeight)*TILE ) / 2 ); + } else if (nPlayersInGame < 8 ){ + nDefendRange = (int)(float)( ( max(mapWidth,mapHeight)*TILE ) / 4 ); + } + nDefendRange = (int)((float)(nDefendRange)*0.7); + } + + } + + if (nDefendRange < nBaseRange){ //double check... + nDefendRange = nBaseRange + 8*TILE; + } + + if (nDefendRange > MAX_DEFEND_RANGETILES*TILE){ //do not make it too big + nDefendRange = MAX_DEFEND_RANGETILES*TILE; + } +} +//----------------------------------------------------------------------------- +//update base coordinates dinamically +function void updateBaseCoord() +{ + local STRUCTURE _structure; + local DROID _truck; + local bool _bHaveBaseStructs; + local int _index,_baseX,_baseY,_numBaseStructs,_bucket; + + _bHaveBaseStructs = FALSE; + + //Go through all structures + _index = 0; + _numBaseStructs = 0; + _baseX = 0; + _baseY = 0; + while(_index+1 < numBaseStructs)//+1 to exclude derricks!! + { + initEnumStruct(FALSE,baseStructs[_index],player,player); + _structure = enumStruct(); + while(_structure != NULLOBJECT) + { + _baseX = _baseX + _structure.x / TILE; + _baseY = _baseY + _structure.y / TILE; + + _numBaseStructs++; + _structure = enumStruct(); + } + _index++; + } + + if(_numBaseStructs > 0) + { + baseX = (_baseX / _numBaseStructs) * TILE; + baseY = (_baseY / _numBaseStructs) * TILE; + } + else + { + + _truck = getADroid(buildGroup); + if(_truck == NULLOBJECT) + { + _truck = getADroid(harvesterGroup); + } + if(_truck == NULLOBJECT) + { + _truck = getADroid(buildDefGroup); + } + + + if(_truck != NULLOBJECT){ + baseX = _truck.x; + baseY = _truck.y; + }else{ + baseX = (TILE * mapWidth) / 2; + baseY = (TILE * mapHeight) / 2; + displayMsg("### Couldn't find base location for " & getPlayerName(player)); + } + + } +} +//perform a research o resLab _resFac on the _lastResIndex+1 item +//returns -1 if no researches have started +//----------------------------------------------------------------------------- +function int do_CheapResearch(STRUCTURE _resFac, int _lastResIndex) +{ + local bool _bStarted; + local int _tech, _nn, _ii; + + /* current tech tree */ + _tech = 0; //0=tank + _nn = 0; + + + _bStarted = false; //this res lab idle for now + while(not _bStarted and _nn < 100) + { + + _lastResIndex = find_Research(_lastResIndex, _tech, 2);//1=standard res, 2= cheap + if(_lastResIndex > -1) //found research + { + _bStarted = pursueResearch(_resFac,player,researchCheap[_tech][_lastResIndex]); + if ( _bStarted ){ + tLastResearch = gameTime; + //displayMsg("*** do_CheapResearch : pursue: ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,researchCheap[_tech][_lastResIndex]) &") researchFinished("& researchFinished(researchCheap[_tech][_lastResIndex],player)&") researchStarted("& researchStarted(researchCheap[_tech][_lastResIndex],player)&") lStopResearch("& lStopResearch &") nProdSelect("& nProdSelect &") lStopCheapResearch("& lStopCheapResearch &") pow("& playerPower(player) &")"); + printDebug1("do_CheapResearch : pursue ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,researchCheap[_tech][_lastResIndex]) &") nProdSelect("& nProdSelect &") power("& playerPower(player) &")"); + } //else {displayMsg("### do_CheapResearch: COULD NOT pursue: ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,researchCheap[_tech][_lastResIndex]) &") researchFinished("& researchFinished(researchCheap[_tech][_lastResIndex],player)&") researchStarted("& researchStarted(researchCheap[_tech][_lastResIndex],player)&") lStopResearch("& lStopResearch &") nProdSelect("& nProdSelect &") lStopCheapResearch("& lStopCheapResearch &") pow("& playerPower(player) &")"); } + + } + else + { + _bStarted = TRUE; //make loop end, no research found + } + + _nn++; + } + + if(!_bStarted) {return -1;} + return _lastResIndex; +} +//perform a research o resLab _resFac on the _lastResIndex+1 item +//returns -1 if no researches have started +//----------------------------------------------------------------------------- +function int do_Research(STRUCTURE _resFac, int _lastResIndex) +{ + local bool _bStarted; + local int _tech, _nn, _VTOLprob; + + /* current tech tree */ + _tech = 0; //0=tank 1=VTOL research + _nn = 0; + + //VTOL AI + if ( AIPersonality == AI_VTOL ){ + if ( gameTime > TIME_START_VTOLRESEARCH ){ + if ( !skVtolEnableCheck(player) ){ + _VTOLprob = 99; //max spped VTOL research + } else { + _VTOLprob = 40; + } + } else { + if ( !skVtolEnableCheck(player) ){ + _VTOLprob = 50; + } else { + _VTOLprob = 40; + } + } + } + + //Other AIs + if ( gameTime > TIME_START_VTOLRESEARCH ){ + if ( !skVtolEnableCheck(player) ){ + _VTOLprob = 50; + } else { + _VTOLprob = 25; + } + } else { + _VTOLprob = 20; + } + + if ( random(100) > _VTOLprob ){ + _tech = 0;//standard researches + } else { + _tech = 9;//VTOL + } + + _bStarted = false; //this res lab idle for now + while(not _bStarted and _nn < 100) + { + + _lastResIndex = find_Research(_lastResIndex, _tech, 1);//1=standard Research + if(_lastResIndex > -1){ + _bStarted = pursueResearch(_resFac,player,research[_tech][_lastResIndex]); + if ( _bStarted ){ + //displayMsg("*** do_Research : pursue: ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,research[_tech][_lastResIndex]) &") researchFinished("& researchFinished(research[_tech][_lastResIndex],player)&") researchStarted("& researchStarted(research[_tech][_lastResIndex],player)&") lStopCheapResearch("& lStopCheapResearch &") nProdSelect("& nProdSelect &") lStopCheapResearch("& lStopCheapResearch &") pow("& playerPower(player) &")"); + printDebug1("do_Research : pursue ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,research[_tech][_lastResIndex]) &") nProdSelect("& nProdSelect &") power("& playerPower(player) &") _VTOLprob("& _VTOLprob &"%)"); + tLastResearch = gameTime; + } //else { displayMsg("### do_Research : COULD NOT pursue: ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,research[_tech][_lastResIndex]) &") researchFinished("& researchFinished(research[_tech][_lastResIndex],player)&") researchStarted("& researchStarted(research[_tech][_lastResIndex],player)&") lStopCheapResearch("& lStopCheapResearch &") nProdSelect("& nProdSelect &") lStopCheapResearch("& lStopCheapResearch &") pow("& playerPower(player) &")"); } + + } + else //try with second block + { + if ( _tech == 0 ){ //was not researching VTOL stuff + //Try array research block #2 + _tech = 1; + _lastResIndex = find_Research(_lastResIndex, _tech, 1);//1=standard Research + if(_lastResIndex > -1){ + _bStarted = pursueResearch(_resFac,player,research[_tech][_lastResIndex]); + if ( _bStarted ){ + //displayMsg("do_Research : pursue: ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,research[_tech][_lastResIndex]) &") researchFinished("& researchFinished(research[_tech][_lastResIndex],player)&") researchStarted("& researchStarted(research[_tech][_lastResIndex],player)&") lStopCheapResearch("& lStopCheapResearch &") nProdSelect("& nProdSelect &") lStopCheapResearch("& lStopCheapResearch &") pow("& playerPower(player) &")"); + printDebug1("do_Research : pursue ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,research[_tech][_lastResIndex]) &") nProdSelect("& nProdSelect &") power("& playerPower(player) &") _VTOLprob("& _VTOLprob &"%)"); + tLastResearch = gameTime; + } //else { displayMsg("### do_Research : COULD NOT pursue: ["& _tech &"]["& _lastResIndex &"] steps left ("& numResearchLeft(player,research[_tech][_lastResIndex]) &") researchFinished("& researchFinished(research[_tech][_lastResIndex],player)&") researchStarted("& researchStarted(research[_tech][_lastResIndex],player)&") lStopCheapResearch("& lStopCheapResearch &") nProdSelect("& nProdSelect &") lStopCheapResearch("& lStopCheapResearch &") pow("& playerPower(player) &")"); } + } else { + _bStarted = true; //make loop end, no research found + } + } else {//was researching VTOL stuff + _bStarted = true; //make loop end, no research found + } + } + + _nn++; + } + + + if(!_bStarted) + { + return -1; + } + + return _lastResIndex; +} +//----------------------------------------------------------------------------- +// return the _resIndex to be used for pursueResearch(_resFac,me,research[_tech][_resIndex]) +// if not research is found returns -1 +function int find_Research(int _searchStart, int _techTree, int whichArray) +{ + local int _retInt; + + ASSERT(_searchStart >= 0, "findResearch: _searchStart < 0", player); + ASSERT(_techTree >= 0, "findResearch: _techTree < 0", player); + + if ( whichArray == 1 ){// =============== STANDARD RESEARCH ================== + + //find research to pursue + _retInt = _searchStart; + while(_retInt < numRes[_techTree]) + { + if((not researchFinished(research[_techTree][_retInt], player)) and (not researchStarted(research[_techTree][_retInt], player))) + { + //displayMsg("Standard Research found ("& _retInt &") "); + return _retInt; //found research + } + _retInt++; + } + + } else { // =============== CHEAP RESEARCH ================== + + while(_retInt < numCheapRes[0]) + { + if((not researchFinished(researchCheap[_techTree][_retInt], player)) and (not researchStarted(researchCheap[_techTree][_retInt], player))) + { + //displayMsg("Cheap Research found ("& _retInt &") "); + return _retInt; //found research + } //else {displayMsg("Cheap Research index ("& _retInt &") cannot be researched "); } + _retInt++; + } + + } + + _retInt = -1; //not found + return(_retInt); +} +//----------------------------------------------------------------------------- +function int numStructsByType(STRUCTURESTAT _structure, int _player) +{ + local STRUCTURE _str; + local int _count; + + _count=0; + + initEnumStruct(false,_structure,_player,_player); + _str = enumStruct(); + while(_str != NULLOBJECT) + { + _count++; + _str = enumStruct(); + } + return _count; +} +//----------------------------------------------------------------------------- +function DROID nearestDroidToBeRepaired(GROUP _group, int _x, int _y) +{ + local DROID _droid, _damagedUnit; + local int _tmpDist; + + _tmpDist = 999*TILE; + _damagedUnit = NULLOBJECT; + + initIterateGroup(_group); + _droid = iterateGroup(_group); + while(_droid != NULLOBJECT) + { + if( _droid.health < MIN_HEALT_REPAIR_BASE ) + { + if(distBetweenTwoPoints( _droid.x, _droid.y, _x, _y) < _tmpDist) + { + _tmpDist = distBetweenTwoPoints( _droid.x, _droid.y, _x, _y); + _damagedUnit = _droid; + } //else{ displayMsg("*** unitToBeRepaired: damaged unit ("& _droid.id &") with damage ("& _droid.health &") not in basereange "); } + } + _droid = iterateGroup(_group); + } + + //check for damaged units _droid.health < 95 + if ( _damagedUnit == NULLOBJECT ){ + initIterateGroup(_group); + _droid = iterateGroup(_group); + while(_droid != NULLOBJECT) + { + if( _droid.health < 95 ) + { + if(distBetweenTwoPoints( _droid.x, _droid.y, _x, _y) < _tmpDist) + { + _tmpDist = distBetweenTwoPoints( _droid.x, _droid.y, _x, _y); + _damagedUnit = _droid; + } //else{ displayMsg("*** unitToBeRepaired: damaged unit ("& _droid.id &") with damage ("& _droid.health &") not in basereange "); } + } + _droid = iterateGroup(_group); + } + } + + return _damagedUnit; +} +//----------------------------------------------------------------------------- +function DROID unitToBeRepaired(GROUP _group) +{ + local DROID _droid, _damagedUnit; + local int _tmpDamage, _damage; + + _tmpDamage = 0; + _damagedUnit = NULLOBJECT; + + initIterateGroup(_group); + _droid = iterateGroup(_group); + while(_droid != NULLOBJECT) + { + _damage = 100 - _droid.health; + if( _droid.health < MIN_HEALT_REPAIR_BASE and _damage >_tmpDamage ) + { + if(distBetweenTwoPoints( _droid.x, _droid.y, baseX, baseY) < nBaseRange) + { + _tmpDamage = _damage; + _damagedUnit = _droid; + } //else{ displayMsg("*** unitToBeRepaired: damaged unit ("& _droid.id &") with damage ("& _droid.health &") not in basereange "); } + } + _droid = iterateGroup(_group); + } + + return _damagedUnit; +} +//----------------------------------------------------------------------------- +// check if the repair droid itself has to be repaired or not. +function DROID idleRepairDroid(int _x, int _y) +{ + local DROID _closestTruck,_tempTruck; + local int _closestDist,_tempDist; + + _closestTruck = NULLOBJECT; + _closestDist = 999*TILE; + + initIterateGroup(repairGroup); + _tempTruck = iterateGroup(repairGroup); + while(_tempTruck != NULLOBJECT) + { + //if less then I cannot pick him up to avoid self repair + if( _tempTruck.health > MIN_HEALT_REPAIR_BASE ) { + if(_tempTruck.order != DORDER_DROIDREPAIR) { + _tempDist = distBetweenTwoPoints(_x, _y, _tempTruck.x, _tempTruck.y); + if(_tempDist < _closestDist) + { + _closestDist = _tempDist; + _closestTruck = _tempTruck; + } + } + } + _tempTruck = iterateGroup(repairGroup); + } + return _closestTruck; +} +//----------------------------------------------------------------------------- +function void moveUnitsBetweenGRPs(GROUP _toGRP, GROUP _fromGRP, int _unitsToMove, bool _bNoTrucks) +{ + local int _c; + local DROID _tempTruck; + + _c = 0; + + //If requested, leave trucked droids in defend group + if (_bNoTrucks ){ + initIterateGroup(_fromGRP); + _tempTruck = iterateGroup(_fromGRP); + while ( _c < _unitsToMove and _tempTruck != NULLOBJECT){ + if ( _tempTruck.propulsion != TrackedProp ){ + groupAddDroid(_toGRP, _tempTruck); + _c++; + } + _tempTruck = iterateGroup(_fromGRP); + } + } + + //move the remaining units + initIterateGroup(_fromGRP); + _tempTruck = iterateGroup(_fromGRP); + while ( _c < _unitsToMove ){ + groupAddDroid(_toGRP, _tempTruck); + _c++; + _tempTruck = iterateGroup(_fromGRP); + } + +} +//----------------------------------------------------------------------------- +function void attackedByDroid(DROID _droid) +{ + local int _nEnNewWeapDroids,_nOldEnWeapDroids,_nNewAlertDistFromBase,_nOldAlertDistFromBase; + local int _nEnWeapDroids,_nFrWeapStructs,_nFrWeapDroids,_nTotFriendlyWapons; + + if ( _droid == NULLOBJECT ){ return; } + + boolResult = true; + _nOldAlertDistFromBase = 9999*TILE; + _nOldEnWeapDroids = 0; + + if (_droid.player<0 or _droid.player>7){ + //dbg("dbg->attackedByDroid: droid.player is not in 0-7 range ("& _droid.player &") ",player); + return; + } + if( isVtol(_droid) ){ + //set target for VTOLs + if ( defTargetVTOL == NULLOBJECT ){ + defTargetVTOL = _droid; + targetPlayerVTOL = _droid.player; + bVTOLTargetIsDerrick = false; + } + return; + } + + + _nNewAlertDistFromBase = distBetweenTwoPoints(_droid.x,_droid.y,baseX,baseY); + + //get VTOL target + if ( _nNewAlertDistFromBase < nDefendRange and vtolDefendGr.members > 0 and defTargetVTOL == NULLOBJECT and attTargetVTOL == NULLOBJECT ){ + defTargetVTOL = objDroidTargetInRange(_droid.x,_droid.y,TILE*12,true); + if ( defTargetVTOL == NULLOBJECT ){ + //displayMsg("AIAttacked: FAILED to get a droid target in range for VTOLs"); + defTargetVTOL = _droid; + bVTOLTargetIsDerrick = false; + if ( targetPlayerVTOL < 0 ){ targetPlayerVTOL = _droid.player; } + } //else { displayMsg("AIAttacked: SUCCESSFUL to get a Target in defend range for VTOLs"); } + } + + _nEnWeapDroids = numEnemyWeapDroidsInRange(player, _droid.x, _droid.y, COMBAT_RANGE , false); + _nFrWeapStructs = numFriendlyWeapStructsInRange(player, _droid.x, _droid.y, COMBAT_RANGE, false); + _nFrWeapDroids = tankDefGroup.members + cyborgDefGroup.members; + _nTotFriendlyWapons = _nFrWeapStructs+_nFrWeapDroids; + + //if it is a new second alert check which one is the nearest to the base + if (alertIsOn and alertX>0 and alertY>0){ + _nOldAlertDistFromBase = distBetweenTwoPoints(alertX,alertY,baseX,baseY); + _nOldEnWeapDroids = numEnemyWeapDroidsInRange(player, alertX, alertY, COMBAT_RANGE , false); //check if new threat is bigger then the older one + if ( _nOldEnWeapDroids > _nEnNewWeapDroids ){ + boolResult = false; + } + //if new alert is within the base this has priority 1!! + if ( boolResult and _nNewAlertDistFromBase > nBaseRange and _nOldAlertDistFromBase < nBaseRange ){ + boolResult = false; + } + } + + if(boolResult) + { + + //determine the ALERT level + if ( _nEnWeapDroids >= _nTotFriendlyWapons ) { + alertLevel = RED_ALERT; + } + if ( (float)_nEnWeapDroids >= (float)_nTotFriendlyWapons*0.7 and _nEnWeapDroids < _nTotFriendlyWapons ) { + alertLevel = YELLOW_ALERT; + } + if ( (float)_nEnWeapDroids < (float)_nTotFriendlyWapons*0.7 ) { + alertLevel = GREEN_ALERT; + } + + // move all untis in tankDefGrp + if (alertLevel == RED_ALERT){ + if (tankGroup.members>0){ + //displayMsg("attackedByDroid: RED ALERT all tanks moved from tankGroup to tankDefGroup"); + groupAddGroup(tankDefGroup,tankGroup); + deactivateTankAttack(); + } + if (cyborgAttGroup.members>0){ + //displayMsg("attackedByDroid: RED ALERT all cyborgs moved from cyborgDefGroup"); + groupAddGroup(cyborgDefGroup , cyborgAttGroup); + deactivateCybAttack(); + } + if (helpGroup.members>0){ + //displayMsg("attackedByDroid: RED ALERT all helping units back!"); + msg("My base is in trouble recalling "& helpGroup.members &" helping units back", player, nAllyBeingHelped); + if ( AIPersonality == AI_CYBORG ){ + groupAddGroup(cyborgDefGroup , helpGroup); + } else { + groupAddGroup(tankDefGroup , helpGroup); + } + deactivateHelp(); + } + //ask for help, recalculate my units + _nFrWeapDroids = tankDefGroup.members + cyborgDefGroup.members; + + } + + }//endif boolResult +} +//----------------------------------------------------------------------------- +function void attackedByStruct(STRUCTURE _struct) +{ + + local int _nEnNewWeapDroids,_nOldEnWeapDroids,_nNewAlertDistFromBase,_nOldAlertDistFromBase; + local int _nEnWeapDroids,_nFrWeapStructs,_nFrWeapDroids,_nTotFriendlyWapons; + + if ( _struct == NULLOBJECT ){ return; } + + boolResult = true; + if (_struct.player<0 or _struct.player>7){ + return; + } + + //set as VTOL target + defTargetVTOL = _struct; + targetPlayerVTOL = _struct.player; + bVTOLTargetIsDerrick = false; + + //// IF targetPl NOT SET - PUNISH THE OFFENDER + _nNewAlertDistFromBase = distBetweenTwoPoints(_struct.x,_struct.y,baseX,baseY); + _nEnWeapDroids = numEnemyWeapStructsInRange(player, _struct.x, _struct.y, COMBAT_RANGE , false); + _nFrWeapStructs = numFriendlyWeapStructsInRange(player, _struct.x, _struct.y, COMBAT_RANGE, false); + _nFrWeapDroids = tankDefGroup.members + cyborgDefGroup.members; + _nTotFriendlyWapons = _nFrWeapStructs+_nFrWeapDroids; + + + //if it is a new second alert check which one is the nearest to the base + if ( alertIsOn and alertX > 0 and alertY > 0 ){ + _nOldAlertDistFromBase = distBetweenTwoPoints(alertX,alertY,baseX,baseY); + _nOldEnWeapDroids = numEnemyWeapDroidsInRange(player, alertX, alertY, COMBAT_RANGE , false); //check if new threat is bigger then the older one + if ( _nOldEnWeapDroids > _nEnWeapDroids ) + { + + boolResult = false; + } + //if new alert is uin the base this has priority 1!! + if ( (_nNewAlertDistFromBase < nBaseRange) and (_nOldAlertDistFromBase > nBaseRange) ) + { + boolResult = true; + } + } + + if(boolResult) + { + + //determine the ALERT level + if ( _nEnWeapDroids >= _nTotFriendlyWapons ) { + alertLevel = RED_ALERT; + } + if ( (float)_nEnWeapDroids >= (float)_nTotFriendlyWapons*0.7 and _nEnWeapDroids < _nTotFriendlyWapons ) { + alertLevel = YELLOW_ALERT; + } + if ( (float)_nEnWeapDroids < (float)_nTotFriendlyWapons*0.7 ) { + alertLevel = GREEN_ALERT; + } + + if (tankGroup.members>0 and alertLevel == RED_ALERT){ + //displayMsg("attackedByDroid: RED ALERT all tanks moved from tankGroup to tankDefGroup"); + groupAddGroup(tankDefGroup,tankGroup); + } + if (cyborgAttGroup.members>0 and alertLevel == RED_ALERT){ + //displayMsg("attackedByDroid: RED ALERT all cyborgs moved from cyborgDefGroup"); + groupAddGroup(cyborgDefGroup , cyborgAttGroup); + } + + + //displayMsg("______________________________________________________________________________________"); + + }//endif boolResult +} +//----------------------------------------------------------------------------- +function int getNumStructNotIdle(STRUCTURESTAT _structToCheck) +{ + local STRUCTURE _struct; + local int _tot; + + _tot=0; + + initEnumStruct(false,_structToCheck,player,player); + _struct = enumStruct(); + while(_struct != NULLOBJECT) + { + if(structureComplete(_struct)) + { + if(!structureIdle(_struct)){ _tot++; } + } + _struct = enumStruct(); + } + + return _tot; +} +//----------------------------------------------------------------------------- +function int numRemainingOilRes() +{ + local FEATURE _tempOilRes; + local int _nTot; + _nTot=0; + + initGetFeature(oilRes,-1,player); + _tempOilRes = getFeature(player); + while(_tempOilRes != NULLOBJECT and _nTot < MAX_WHILE_LOOPS) + { + _nTot++; + _tempOilRes = getFeature(player); + } + + return _nTot; +} +//----------------------------------------------------------------------------- +function bool bAnyOilResLeft() +{ + local DROID _droid; + boolResult = true; + + InitEnumDroids(player,player); + _droid = EnumDroid(); + while ( _droid != NULLOBJECT and boolResult ){ + if (_droid != NULLOBJECT){ boolResult = false;} + _droid = EnumDroid(); + } + + if ( _droid == NULLOBJECT ){ + return false; + } + + initGetFeature(oilRes,-1,player); + feature = getFeature(player); + while(feature != NULLOBJECT) + { + if ( droidCanReach(_droid, feature.x, feature.y) ){ + return true; + } + feature = getFeature(player); + } + + return false; +} +//----------------------------------------------------------------------------- +function int getTotDerricksMap() +{ + local int _player, _totDerricks; + _player = 0; + _totDerricks = 0; + + while ( _player < MAX_PLAYERS ){ + _totDerricks = _totDerricks + getNumDerricks(_player); + _player++; + } + return _totDerricks; +} + +//----------------------------------------------------------------------------- +function void sendIdleBackToTheBase(int _group) +{ + local DROID _idleTruck; + local bool _stop; + local int _c; + + //_c=0; + //_stop = false; + _idleTruck = NULLOBJECT; + + if (_group == BUILDDEF_GRP){ _idleTruck = pickDefTruck(true); } + if (_group == CYBENG_GRP){_idleTruck = pickCybEng(true); } + if (_group == BUILD_GRP){ _idleTruck = closestIdleDroid(buildGroup,baseX, baseY); } + if (_group == HARVEST_GRP){ _idleTruck = closestIdleDroid(harvesterGroup,baseX, baseY); } + + if ( _idleTruck != NULLOBJECT) { + _c = distBetweenTwoPoints( _idleTruck.x, _idleTruck.y, baseX, baseY); + if ( _c > nBaseRange and _idleTruck.order != DORDER_RTB) + { + //dbg("sendIdleBackToTheBase: ("& _group &") send droid ("& _idleTruck.id &") back to the base",player); + orderDroid(_idleTruck, DORDER_RTB); + } + //else { + //dbg("sendIdleBackToTheBase: ("& _group &") NOT send droid ("& _idleTruck.id &") back to the base _c("& _c/TILE &")("& nBaseRange/TILE &")",player); + //} + + } //end while + //_c++; + //} +} +//----------------------------------------------------------------------------- +//returns _nWhichCooord(x or y) such that they are _nDist distance away from _x1/_y1 direction _x2,_y2 +function int getCoordRelated(int _x1, int _y1, int _x2, int _y2, int _nWhichCooord, int _nDist) +{ + local int _xx,_yy,_return; + local DROID _droid; + + _droid = getADroid(harvesterGroup); + if ( _droid == NULLOBJECT ){ _droid = getADroid(buildGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(buildDefGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(tankDefGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(cyborgDefGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(cyborgConstructGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(tankGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(cyborgAttGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(toBeRepairedCyborgGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(toBeRepairedTankGroup); } + if ( _droid == NULLOBJECT ){ _droid = getADroid(helpGroup); } + if ( _droid != NULLOBJECT ){ + if (_x1 > _x2) { + _xx = _x1 - _nDist; + if ( _xx < _x2 ) { _xx = _x1 - (_x1-_x2)/2; } + } else { + _xx = _x1 + _nDist; + if ( _xx > _x2 ) { _xx = _x1 + (_x2-_x1)/2; } + } + if (_y1 > _y2) { + _yy = _y1 - _nDist; + if ( _yy < _y2 ) { _yy = _y2 - (_y1-_y2)/2; } + } else { + _yy = _y1 + _nDist; + if ( _yy > _y2 ) { _yy = _y1 + (_y2-_y1)/2; } + } + //printDebug1("getCoordRelated-1, _nDist("& _nDist/TILE &") from("& _x1/TILE &"-"& _y1/TILE &") to("& _x2/TILE &"-"& _y2/TILE &") result("& _xx/TILE &"-"& _yy/TILE &")"); + + if ( pickStructLocation(vtolPad, ref _xx, ref _yy, player) ){ + //printDebug1("getCoordRelated-2, _nDist("& _nDist/TILE &") from("& _x1/TILE &"-"& _y1/TILE &") to("& _x2/TILE &"-"& _y2/TILE &") result("& _xx/TILE &"-"& _yy/TILE &")"); + if( droidCanReach(_droid, _xx, _yy) ){ + if( _nWhichCooord == 1){ + return _xx; + } + if( _nWhichCooord == 2){ + return _yy; + } + } + } + } + return -1; +} + +//----------------------------------------------------------------------------- +// _targetPlayer == -1 as default +function BASEOBJ findEnemyOBJ(bool _mustBeHuman, int _targetPlayer) +{ + local BASEOBJ _attackObject; + local int _targetPl,_xCoord,_yCoord; + + _attackObject = NULLOBJECT; + _targetPl = -1; + + //if big maps, pick up nearest enemy + if ( (mapWidth+mapHeight)/2 > BIG_MAP ){ + if ( _targetPlayer >= 0 ){ + _targetPl = _targetPlayer; + } else { + _targetPl = getNearestEnemyPlayer(_mustBeHuman); + } + } else { + if ( _targetPlayer >= 0 ){ + _targetPl = _targetPlayer; + } + } + + //target player not found!!! + if ( _targetPl < 0 ) { + _targetPl = getRandomEnemyPlayer(_mustBeHuman); + } + if ( _targetPl == -1 ){ + //dbg("dbg -> findEnemyOBJ(): No random enemy found _mustBeHuman("& _mustBeHuman &") _targetPlayer("& _targetPlayer &")",player); + return _attackObject; //NULLOBJECT + } //else { dbg("dbg -> findEnemyOBJ(): found a target player player("& _targetPl &") _mustBeHuman("& _mustBeHuman &")",player); } + + _xCoord = getEnemy_baseCoord( _targetPl , "X" ); + _yCoord = getEnemy_baseCoord( _targetPl , "Y" ); + if (_xCoord>0 and _yCoord>0 ){ + _attackObject = objStrTargetInRange( _xCoord , _yCoord, 15 * TILE ); + } + if ( _attackObject == NULLOBJECT ){ + _attackObject = skLocateEnemy(_targetPl); + } + + return _attackObject; +} + +//----------------------------------------------------------------------------- +function int gameType() +{ + + if ( nHumanPlayers == 1 ){ + + if ( nPlayersInGame == 2 ){ + return GT_2PLAYERS_1HP; + } + if ( nPlayersInGame == 3 or nPlayersInGame == 4){ + if ( nTeam == 2 ){ + return GT_4PLAYERS_1HP_2T; + } + if ( nTeam > 2 ){ + return GT_4PLAYERS_1HP_34T; + } + } + if ( nPlayersInGame > 4 ){ + if ( nTeam < 4 ){ + return GT_8PLAYERS_1HP_23T; + } + if ( nTeam >= 4 ){ + return GT_8PLAYERS_1HP_4567T; + } + } + + } else if ( nHumanPlayers == 2 ){ + + if ( nPlayersInGame == 3 or nPlayersInGame == 4){ + if ( nTeam == 2 ){ + return GT_4PLAYERS_2HP_2T; + } + if ( nTeam > 2 ){ + return GT_4PLAYERS_2HP_34T; + } + } + if ( nPlayersInGame > 4 ){ + if ( nTeam < 4 ){ + return GT_8PLAYERS_2HP_23T; + } + if ( nTeam >= 4 ){ + return GT_8PLAYERS_2HP_4567T; + } + } + + } else if ( nHumanPlayers == 3 ){ + + return GT_8PLAYERS_3HP_23T; + + } else { + + return GT_STANDARD; + } + + return GT_STANDARD; +} +//----------------------------------------------------------------------------- +// +function int getTargetEnemy(bool _dbg) +{ + local int _nMyUnitsTot, _nMyUnitsPower, _nMyUnitsHP; + local int _nEnUnitsTot, _nEnUnitsPower, _nEnUnitsHP; + local int _nAvUnitsTot, _nAvUnitsPower, _nAvUnitsHP; + local int _nTotUnitsTot, _nTotUnitsPower, _nTotUnitsHP; + local int _player,_tempPlayer,_c2,_c3; + local float _nMyPowerIndex,_nEnPowerIndex,_nAvPowerIndex,_nTotPowerIndex; + + _tempPlayer = -1; + + _nMyUnitsTot = tankDefGroup.members + cyborgDefGroup.members + cyborgAttGroup.members; + _nMyUnitsPower = getWeaponUnitsInfo( player, WUI_POWER); + _nMyUnitsHP = getWeaponUnitsInfo( player, WUI_HP); + _nMyPowerIndex = getPowerIndex( player ); + + //find average values first + _player=0; + while( _player < MAX_PLAYERS ){ + if ( isPlayerStillLive(_player) ){ + _nEnUnitsTot = getWeaponUnitsInfo( _player, WUI_TOTUNITS); + _nEnUnitsPower = getWeaponUnitsInfo( _player, WUI_POWER); + _nEnUnitsHP = getWeaponUnitsInfo( _player, WUI_HP); + _nEnPowerIndex = getPowerIndex( _player ); + _nTotUnitsTot = _nTotUnitsTot + _nEnUnitsTot; + _nTotUnitsPower = _nTotUnitsPower + _nEnUnitsPower; + _nTotUnitsHP = _nTotUnitsHP + _nEnUnitsHP; + _nTotPowerIndex = _nTotPowerIndex + _nEnPowerIndex; + } + _player++; + } + _nAvUnitsTot = _nTotUnitsTot / nPlayersInGame; + _nAvUnitsPower = _nTotUnitsPower / nPlayersInGame; + _nAvUnitsHP = _nTotUnitsHP / nPlayersInGame; + _nAvPowerIndex = _nTotPowerIndex / (float)nPlayersInGame; + + + //dbg("dbg->getTargetEnemy: pl("& getPlayerName(player) &") avUnTot("& _nAvUnitsTot &") avCost("& _nAvUnitsPower &") avHP("& _nAvUnitsHP &") avPowInd("& _nAvPowerIndex &")",player); + //dbg("dbg->getTargetEnemy: pl("& getPlayerName(player) &") myUnTot("& _nMyUnitsTot &") myCost("& _nMyUnitsPower &") myHP("& _nMyUnitsHP &") myPowInd("& _nMyPowerIndex &")",player); + + //search for enemies which are too strong + _player=0; + while( _player < MAX_PLAYERS ){ + if ( !friendlyPlayer(_player) and isPlayerStillLive(_player) ){ + //give priority to human players ;-) + boolResult = true; + if ( _tempPlayer >= 0 and isHumanPlayer(_tempPlayer) ){ + boolResult = false; + } + if ( boolResult or _tempPlayer == -1){ + _nEnUnitsTot = getWeaponUnitsInfo( _player, WUI_TOTUNITS); + _nEnUnitsPower = getWeaponUnitsInfo( _player, WUI_POWER); + _nEnUnitsHP = getWeaponUnitsInfo( _player, WUI_HP); + _nEnPowerIndex = getPowerIndex( _player ); + if ( _nEnUnitsTot >= 2*_nAvUnitsTot ){ _tempPlayer = _player; } + if ( _nEnUnitsPower >= 2*_nAvUnitsPower ){ _tempPlayer = _player; } + if ( _nEnUnitsHP >= 2*_nAvUnitsHP ){ _tempPlayer = _player; } + if ( _nEnPowerIndex >= 1.4*_nAvPowerIndex ){ _tempPlayer = _player; } + } + }//endif !friendlyPlayer() + _player++; + } + + //search for enemies which are too weak + if ( _tempPlayer == -1){ + //dbg("dbg->getTargetEnemy: pl("& getPlayerName(player) &") too strong enemy not found",player); + if ( _dbg ) { + printDebug1("getTargetEnemy: pl("& getPlayerName(player) &") too strong enemy not found"); + } + _player=0; + while( _player < MAX_PLAYERS ){ + if ( !friendlyPlayer(_player) and isPlayerStillLive(_player) ){ + //give priority to human players ;-) + boolResult = true; + if ( _tempPlayer >= 0 and isHumanPlayer(_tempPlayer) ){ + boolResult = false; + } + if ( boolResult or _tempPlayer == -1){ + _nEnUnitsTot = getWeaponUnitsInfo( _player, WUI_TOTUNITS); + _nEnUnitsPower = getWeaponUnitsInfo( _player, WUI_POWER); + _nEnUnitsHP = getWeaponUnitsInfo( _player, WUI_HP); + _nEnPowerIndex = getPowerIndex( _player ); + if ( 2*_nEnUnitsTot < _nAvUnitsTot ){ _tempPlayer = _player; } + if ( 2*_nEnUnitsPower < _nAvUnitsPower ){ _tempPlayer = _player; } + if ( 2*_nEnUnitsHP < _nAvUnitsHP ){ _tempPlayer = _player; } + if ( 1.5*_nEnPowerIndex < _nAvPowerIndex ){ _tempPlayer = _player; } + } + }//endif !friendlyPlayer() + _player++; + } + if ( _tempPlayer == -1){ + //dbg("dbg->getTargetEnemy: pl("& getPlayerName(player) &") too weak enemy not found",player); + if ( _dbg ) { + printDebug1("getTargetEnemy: too weak enemy not found"); + } + } else { + //dbg("dbg->getTargetEnemy: pl("& getPlayerName(player) &") too weak enemy found: ("& getPlayerName(_tempPlayer) &") isHuman("& isHumanPlayer(_tempPlayer) &")",player); + if ( _dbg ) { + printDebug1("getTargetEnemy: too weak enemy found: ("& getPlayerName(_tempPlayer) &") isHuman("& isHumanPlayer(_tempPlayer) &")"); + } + + //check we do not attack weak human player too often! unless this is the strong AI + if ( isHumanPlayer(_tempPlayer) and AIstrength < 4 ) + { + if (nAttHumanPlayer > nAttAIPlayer*2) { + printDebug1("getTargetEnemy-1/2: too weak human enemy was attacked too often Hum_Pl/AI_Pl ("& nAttHumanPlayer &"/"& nAttAIPlayer &"), try to changed target to AI player"); + //get an AI enemy as target, if possible...maybe there are only enemy human players??? + _c2 = random(MAX_PLAYERS); + _c3 = 0; + boolResult = true; + while( _c3 < MAX_PLAYERS and boolResult ) + { + if ( !isHumanPlayer(_c2) and isPlayerStillLive(_c2) and !friendlyPlayer(_c2) ){ + boolResult = false; + _tempPlayer = _c2; + } + _c2++; _c3++; + if ( _c2 == 8 ){ _c2 = 0; } + } + if ( !boolResult ){ + printDebug1("getTargetEnemy-2/2: changed target to AI player: ("& getPlayerName(_tempPlayer) &") isHuman("& isHumanPlayer(_tempPlayer) &")"); + } else { + printDebug1("getTargetEnemy-2/2: not able to change target to AI player"); + } + //if the loops ends it means there are no enemy AI left!! + } else { + printDebug1("getTargetEnemy: too weak human enemy was attacked NOT too often Hum_Pl/AI_Pl ("& nAttHumanPlayer &"/"& nAttAIPlayer &"), DyDo attacks him again!!"); + } + } + + } + } else { + //dbg("dbg->getTargetEnemy: pl("& getPlayerName(player) &") too strong enemy found: ("& getPlayerName(_tempPlayer) &") isHuman("& isHumanPlayer(_tempPlayer) &")",player); + if ( _dbg ) { + printDebug("getTargetEnemy: pl("& getPlayerName(player) &") too strong enemy found: ("& getPlayerName(_tempPlayer) &") isHuman("& isHumanPlayer(_tempPlayer) &")"); + } + } + + return _tempPlayer; +} +//----------------------------------------------------------------------------- +/* +// TankAttack/CyborgAttack events +// --> getTargetObj +// --> getTargetEnemy() +// --> findEnemyOBJ() +// +*/ +function BASEOBJ getTargetObj() +{ + + + local int _nGameType,nPerc_HP_Target,_tempTargetPlayer,_rnd; + local bool _mustBeHuman; + + _mustBeHuman = false; + nPerc_HP_Target = -1; + + //search for primary enemy player target + _targetPlayer = getTargetEnemy(false);//search for too strong or too weak enemies + if (_targetPlayer >= 0){ + printDebug1("dbg->getTargetObj: Very strong or weak enemy found:'"& getPlayerName(_targetPlayer) &"'"); + } + + _nGameType = gameType(); + if ( _nGameType == GT_4PLAYERS_1HP_2T ){ + nPerc_HP_Target = 40+random(10)+AIstrength*10; + } + if ( _nGameType == GT_4PLAYERS_1HP_34T ){ + nPerc_HP_Target = 30+random(20)+AIstrength*10; + } + if ( _nGameType == GT_4PLAYERS_2HP_2T ){ + nPerc_HP_Target = 40+random(10)+AIstrength*10; + } + if ( _nGameType == GT_4PLAYERS_2HP_34T ){ + nPerc_HP_Target = 30+random(20)+AIstrength*10; + } + if ( _nGameType == GT_8PLAYERS_1HP_23T ){ + nPerc_HP_Target = 20+random(20)+AIstrength*10; + } + if ( _nGameType == GT_8PLAYERS_1HP_4567T ){ + nPerc_HP_Target = 15+random(25)+AIstrength*10; + } + if ( _nGameType == GT_8PLAYERS_2HP_23T ){ + nPerc_HP_Target = 25+random(25)+AIstrength*10; + } + if ( _nGameType == GT_8PLAYERS_2HP_4567T ){ + nPerc_HP_Target = 25+random(20)+AIstrength*10; + } + if ( _nGameType == GT_8PLAYERS_3HP_23T ){ + nPerc_HP_Target = 25+random(20)+AIstrength*10; + } + if ( nPerc_HP_Target == -1 ){ + nPerc_HP_Target = 25+random(20)+AIstrength*10; + } + + //select the type of target + _rnd = random(100); + if ( _rnd <= nPerc_HP_Target ){ + _mustBeHuman = true; + //dbg("dbg: getTargetObj-> pl("& getPlayerName(player) &") target must be human _rnd/perc("& _rnd &"/"& nPerc_HP_Target &") AIstrength("& AIstrength &")" , player); + } //else { dbg("dbg: getTargetObj-> pl("& getPlayerName(player) &") target can be human or AI _rnd/perc("& _rnd &"/"& nPerc_HP_Target &") AIstrength("& AIstrength &")" , player);} + + //test or debug game + if ( bRunning or !bHasHumanEnemies(player) ){ + //dbg("dbg: getTargetObj-> pl("& getPlayerName(player) &") target cannot be human: if (isHumanPlayer()("& isHumanPlayer(player) &") bRunning("& bRunning &")) OR !bHasHumanEnemies("& bHasHumanEnemies(player) &")" , player); + _mustBeHuman = false; + } + + //check if big map and if derricks are required + _rnd = random(10); + if ( bNeedDerrick or ( _rnd < 7 and (mapWidth+mapHeight)/2 > BIG_MAP) ){ + //dbg("dbg: getTargetObj-> pl("& getPlayerName(player) &") big map or derricks required _rnd("& _rnd &")" , player); + printDebug1("getTargetObj-> _targetPlayer forced to ("& -1 &") target is derrick, big map or derricks required _rnd("& _rnd &"/7) bNeedDerrick("& bNeedDerrick &") mapSize("& (mapWidth+mapHeight)/2 &") bigMap("& BIG_MAP &") _mustBeHuman("& _mustBeHuman &")" ); + attackTankObj = closestEnemyDerrick(_mustBeHuman , -1); + } else { + printDebug1("getTargetObj-> target will not be a derrick; _targetPlayer("& _targetPlayer &") _rnd("& _rnd &"/7) bNeedDerrick("& bNeedDerrick &") mapSize("& (mapWidth+mapHeight)/2 &") bigMap("& BIG_MAP &")"); + } + + if ( attackTankObj == NULLOBJECT ){ + printDebug1("getTargetObj-> derrick not found, try with base _targetPlayer("& _targetPlayer &") _mustBeHuman("& _mustBeHuman &")"); + attackTankObj = findEnemyOBJ(_mustBeHuman,_targetPlayer); + } + //attackTankObj = findEnemyOBJ(_mustBeHuman); + + if (attackTankObj != NULLOBJECT) { + //dbg("dbg: getTargetObj-> pl("& getPlayerName(player)&") target found: player #("& attackTankObj.player &") '"& getPlayerName(attackTankObj.player) &"' human("& isHumanPlayer(attackTankObj.player) &")" , player); + printDebug1("getTargetObj-> target found: player #("& attackTankObj.player &") '"& getPlayerName(attackTankObj.player) &"' human("& isHumanPlayer(attackTankObj.player) &") "); + } else { + //dbg("dbg: getTargetObj-> pl("& getPlayerName(player) &") NO target found ! ####" , player); + printDebug1("getTargetObj-> NO target found !"); + } + return attackTankObj; +} + +//----------------------------------------------------------------------------- +function bool bHasHumanEnemies(int _player) +{ + local int _c; + _c = 0; + while( _c < MAX_PLAYERS ) + { + if ( isHumanPlayer(_c) and !allianceExistsBetween(_player,_c) ) { + return true; + } + _c++; + } + return false; +} +//----------------------------------------------------------------------------- +function int getRandomEnemyPlayer(bool _mustBeHuman) +{ + local int _c2,_c3; + _c2 = random(MAX_PLAYERS); + _c3 = 0; + while( _c3 < MAX_PLAYERS ) + { + + boolResult = true; + if ( _mustBeHuman and !isHumanPlayer(_c2) ){ + boolResult = false; + } + if( boolResult and !friendlyPlayer(_c2) and isPlayerStillLive(_c2) ) { + return _c2; + } + _c2++; _c3++; + if ( _c2 == 8 ){ _c2 = 0; } + } + return -1; +} +//----------------------------------------------------------------------------- +function int getNearestEnemyPlayer(bool _humanPlayer) +{ + local STRUCTURE _struct; + local int _player, _targetPlayer, _bestDist, _dist, _ii; + + _struct = NULLOBJECT; + _player = 0; + _targetPlayer = -1; + _bestDist = 9999999; + + while( _player < MAX_PLAYERS ) + { + + boolResult = true; + if ( _humanPlayer and !isHumanPlayer(_player) ){ + boolResult = false; + } + if ( !isPlayerStillLive(_player) ){ + boolResult = false; + } + if (!friendlyPlayer(_player) and boolResult){//OK + + //find enemy HQ and check distance to + _struct = getStructure(playerHQ,_player); + if ( _struct == NULLOBJECT ){ + _struct = getStructure(factory,_player); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(cybFactory,_player); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(resLab,_player); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(powGen,_player); + } + if ( _struct == NULLOBJECT ){ + _struct = getStructure(vtolFactory,_player); + } + if ( _struct == NULLOBJECT ){ + _ii = 0; + while ( _ii < numStructs and _struct == NULLOBJECT){ + _struct = getStructure(structs[_ii],_player); + _ii++; + } + } + if ( _struct != NULLOBJECT ){ + _dist = distBetweenTwoPoints(_struct.x,_struct.y, baseX, baseY); + if ( _dist < _bestDist ){ + _bestDist = _dist; + _targetPlayer = _player; + } + } + + }//player check + + _player++; + }//while + return _targetPlayer; +} + +//----------------------------------------------------------------------------- +function int getEnemy_baseCoord( int _player, STRING sCoord ) +{ + local STRUCTURE _structure; + local int _index,_baseX,_baseY,_numBaseStructs; + //Go through all structures + _index = 0; + _numBaseStructs = 0; + _baseX = 0; + _baseY = 0; + while(_index+1 < numBaseStructs)//+1 to exclude derricks!! + { + initEnumStruct( false, baseStructs[_index], _player, _player); + _structure = enumStruct(); + + while(_structure != NULLOBJECT) + { + _baseX = _baseX + _structure.x / TILE; + _baseY = _baseY + _structure.y / TILE; + _numBaseStructs++; + _structure = enumStruct(); + } + _index++; + } + + if(_numBaseStructs > 0) + { + _baseX = (_baseX / _numBaseStructs) * TILE; + _baseY = (_baseY / _numBaseStructs) * TILE; + //displayMsg("getEnemy_baseCoord: Base Structs tmethod #1 ok _baseX("& _baseX/TILE &")_baseY("& _baseY/TILE &") "); + + } else { + + //method #2 + _index = 0; + _numBaseStructs = 0; + while(_index+1 < numBaseStructs)//+1 to exclude derricks!! + { + _structure = getStructure(baseStructs[_index],_player); + if ( _structure != NULLOBJECT ){ + _baseX = _baseX + _structure.x / TILE; + _baseY = _baseY + _structure.y / TILE; + _numBaseStructs++; + } + _index++; + } + if(_numBaseStructs > 0) + { + _baseX = (_baseX / _numBaseStructs) * TILE; + _baseY = (_baseY / _numBaseStructs) * TILE; + //displayMsg("getEnemy_baseCoord: Base Structs tmethod #2 ok _baseX("& _baseX/TILE &")_baseY("& _baseY/TILE &") "); + } else { + printDebug1("#### getEnemy_baseCoord: not able to find any struct for player ("& _player &") "); + return -1; + } + } + + if ( sCoord == "X" or sCoord == "x" ) { + return _baseX; + } else { + return _baseY; + } + return -1; +} + + +//----------------------------------------------------------------------------- +function bool friendlyPlayer(int _playerToCheck) +{ + if(allianceExistsBetween(_playerToCheck, player) or (_playerToCheck == player)){ + return true; + } + + return false; +} +//----------------------------------------------------------------------------- +function BASEOBJ objHumanDerrick(bool bVTOLTarget, int _numDef, int _distInTiles) +{ + local BASEOBJ _objTarget; + local int _targetPlayer,_dist,_tmpDist,_defences,_mapSize; + local STRUCTURE _tempDerrick; + + _targetPlayer = 0; + _objTarget = NULLOBJECT; + _dist = 9999*TILE; + + while ( _targetPlayer < MAX_PLAYERS and _objTarget == NULLOBJECT) + { + if ( _targetPlayer != player and !friendlyPlayer(_targetPlayer) and isHumanPlayer(_targetPlayer) ) { + + initEnumStruct(false,derrick,_targetPlayer,_targetPlayer); + _tempDerrick = enumStruct(); + while( _tempDerrick != NULLOBJECT ){ + boolResult = true; + if ( bVTOLTarget ){ + _defences = numEnemyAAInRange(_tempDerrick.x, _tempDerrick.y, AA_THREAT_RANGE ); + } else { + _defences = numEnemyWeapDroidsInRange(player, _tempDerrick.x, _tempDerrick.y, _distInTiles*TILE , false); + _defences = _defences + numEnemyWeapStructsInRange(player, _tempDerrick.x, _tempDerrick.y, _distInTiles*TILE , false); + } + _tmpDist = distBetweenTwoPoints(baseX,baseY,_tempDerrick.x, _tempDerrick.y); + if ( !bVTOLTarget and _tmpDist > ((mapWidth*TILE+mapHeight*TILE)/6*2) ) { boolResult = false; } + if ( boolResult and _tmpDist < _dist and _defences <= _numDef){ + _objTarget = _tempDerrick; + _dist = _tmpDist; + } + _tempDerrick = enumStruct(); + } + + } + _targetPlayer++; + } + return _objTarget; +} +//----------------------------------------------------------------------------- +function BASEOBJ objStrTargetInRange(int _xCoord,int _yCoord, int _Range) +{ + local BASEOBJ _objTarget; + local int _x,_y,_x1,_y1; + local int _xx, _yy, _targetPlayer; + + resetStructTargets(); + setStructTarIgnore(ST_WALL); + setStructTarPref(ST_DEF_GROUND); + setStructTarPref(ST_FACTORY); + setStructTarPref(ST_CYBORG_FACTORY); + setStructTarPref(ST_VTOL_FACTORY); + setStructTarPref(ST_POWER_GEN); + //setStructTarPref(ST_SENSOR); + setStructTarPref(ST_RESOURCE_EXTRACTOR); + setStructTarPref(ST_DEF_AIR); + setStructTarPref(ST_RESEARCH); + setStructTarPref(ST_HQ); + setStructTarPref(ST_REARM_PAD); + setStructTarPref(ST_SENSOR); + + _objTarget = NULLOBJECT; + _Range = _Range/2 ; + + _xx = (mapWidth*128)-(128*2); + _yy = (mapHeight*128)-(128*2); + + _x = min( _xCoord + _Range , _xx ); + _y = min( _yCoord + _Range , _yy ); + _x1 = max( _xCoord - _Range , 256); + _y1 = max( _yCoord - _Range , 256); + + _targetPlayer = 0; + while ( _targetPlayer < MAX_PLAYERS and _objTarget == NULLOBJECT){ + if ( _targetPlayer != player and !friendlyPlayer(_targetPlayer) ) + { + _objTarget = structTargetInArea(_targetPlayer, player, _x, _y, _x1, _y1); + if (_objTarget != NULLOBJECT) + { + //displayMsg("objStrTargetInRange: dist("& distBetweenTwoPoints(_xCoord, _yCoord, _objTarget.x, _objTarget.y)/TILE &") range ("& _Range/TILE &") - ("& _xCoord/TILE &") ("& _yCoord/TILE &") "); + if ( distBetweenTwoPoints(_xCoord, _yCoord, _objTarget.x, _objTarget.y) > _Range ) + { + _objTarget = NULLOBJECT; + } + } + } + _targetPlayer++; + } + return _objTarget; +} +//----------------------------------------------------------------------------- +function BASEOBJ objDroidTargetInRange(int _xCoord ,int _yCoord, int _Range, bool bIsVTOL) +{ + local BASEOBJ _objTarget; + local int _x,_y,_x1,_y1; + local int _xx, _yy, _n, _bestHitPoints; + + resetDroidTargets(); + setDroidTarIgnore(ST_WALL); + if ( bIsVTOL ){ + setDroidTarPref(DT_SUPER_HEAVY); + setDroidTarPref(DT_HEAVY); + setDroidTarPref(DT_MEDIUM); + setDroidTarPref(DT_LIGHT); + setDroidTarPref(DT_LEGS); + setDroidTarPref(DT_VTOL); + } + else//tank or cyborg + { + setDroidTarPref(DT_SENSOR); + setDroidTarPref(DT_CONSTRUCT); + setDroidTarPref(DT_COMMAND); + setDroidTarPref(DT_REPAIR); + setDroidTarPref(DT_WEAP_GROUND); + setDroidTarPref(DT_WEAP_AIR); + setDroidTarPref(DT_WEAP_ALL); //Ground,air,idf units + } + + + _objTarget = NULLOBJECT; + + _xx = (mapWidth*128)-(128*2); + _yy = (mapHeight*128)-(128*2); + + _Range = _Range/2; + + _x = min( _xCoord + _Range , _xx ); + _y = min( _yCoord + _Range , _yy ); + _x1 = max( _xCoord - _Range , 256); + _y1 = max( _yCoord - _Range , 256); + + if (bIsVTOL and targetPlayerVTOL > -1){ + _n=0; + _bestHitPoints=0; + InitEnumDroids(targetPlayerVTOL,player); + droid = EnumDroid(); + while(droid != NULLOBJECT) + { + if (!isVtol(droid) and distBetweenTwoPoints(droid.x,droid.y,_xCoord,_yCoord) < 15*TILE){ + if ( numEnemyAAInRange(droid.x, droid.y, AA_THREAT_RANGE) < 2 ){ + if ( droid.hitPoints > _bestHitPoints ){ + //displayMsg("objDroidTargetInRange: target for VTOL found: Id("& droid.id &") hitPoints("& droid.hitPoints &")"); + _objTarget = droid; + _bestHitPoints = droid.hitPoints; + } + } + } + _n++; + droid = EnumDroid(); + } + } + + _bestHitPoints=0; + if ( _objTarget == NULLOBJECT ){ + //displayMsg("objDroidTargetInRange: ("& _n &") best target for VTOL NOT found, targetPlayerVTOL("& targetPlayerVTOL &")"); + count = 0; + while ( count < MAX_PLAYERS and _objTarget == NULLOBJECT){ + if ( count != player and !friendlyPlayer(count) ) + { + _objTarget = droidTargetInArea(count, player, _x, _y, _x1, _y1); + if (_objTarget != NULLOBJECT) + { + if ( !isVtol(objToDroid(_objTarget)) ){ + if ( distBetweenTwoPoints(_xCoord, _yCoord, _objTarget.x, _objTarget.y) > _Range ) + { + //if ( _objTarget.hitPoints > _bestHitPoints ){ + _objTarget = NULLOBJECT; + //_bestHitPoints = _objTarget.hitPoints; + //} + } + } + } + } + count++; + } + } else { + if (bIsVTOL){displayMsg("objDroidTargetInRange: ***** best target for VTOL found: Id("& _objTarget.id &") hitPoints("& _objTarget.hitPoints &")");} + } + return _objTarget; +} +//----------------------------------------------------------------------------- +function void orderGroupMoveCMD(GROUP _grp, int _x, int _y) +{ + local int _c; + local DROID _tempTruck; + + _c = 0; + + initIterateGroup(_grp); + _tempTruck = iterateGroup(_grp); + while ( _tempTruck != NULLOBJECT ){ + if (droidCanReach(_tempTruck,_x, _y )){ + orderDroidLoc(_tempTruck, DORDER_MOVE,_x, _y ); + } + _tempTruck = iterateGroup(_grp); + _c++; + } + return; +} + +//----------------------------------------------------------------------------- +function void orderGroupScoutCMD(GROUP _grp, int _x, int _y) +{ + local int _c; + local DROID _tempTruck; + + _c = 0; + + initIterateGroup(_grp); + _tempTruck = iterateGroup(_grp); + while ( _tempTruck != NULLOBJECT ){ + if ( distBetweenTwoPoints( _tempTruck.x, _tempTruck.y, _x, _y ) > 2*TILE and droidCanReach(_tempTruck,_x, _y ) ){ + orderDroidLoc(_tempTruck, DORDER_SCOUT, _x, _y ); + } + _tempTruck = iterateGroup(_grp); + _c++; + } + return; +} +//----------------------------------------------------------------------------- +function void SetDyDoPersonality(int nPersonality, int _player) +{ + local int cc,_c,_nAdd,_nAddVTOL; + cc=0; + + if (_player != player){exit;} + + //random personality + _c = nPersonality; + if ( nPersonality == 0 or nPersonality > 4 ){ + if ( random(100) < 75 ){//75% General 1 + _c = 1; + } else {//30% for General 2-3-4 + _c = 2+random(6); + if ( _c > 4 ){ + if ( _c == 5 ) { _c = 2;} + if ( _c == 6 ) { _c = 3;} + if ( _c == 7 ) { _c = 4;} + } + } + AIPersonality = _c; + _c--; + nAI_Pers = _c; + } else { + AIPersonality = nPersonality; + nPersonality--; + nAI_Pers = nPersonality; + } + + + //____________________General 2____________________________ + if ( AIPersonality == AI_VTOL){ + //Cheap Researches + cc=0; + while ( cc < numCheapResGen2[0] ){ + researchCheap[0][cc] = general2Cheap[0][cc]; + cc++; + } + cc=0; + //Standard Researches + while ( cc < numResGen2[0] ){ + research[0][cc] = general2[0][cc]; + cc++; + } + cc=0; + //Standard Researches + while ( cc < numResGen2[1] ){ + research[0][cc] = general2[1][cc]; + cc++; + } + cc=0; + while ( cc < numResGen2[9] ){ + research[9][cc] = general2[9][cc]; + cc++; + } + numRes[0] = numResGen2[0]; + numRes[1] = numResGen2[1]; + numRes[9] = numResGen2[9]; + + } + //____________________General 3____________________________ + if ( AIPersonality == AI_TURTLE){ + //Cheap Researches + while ( cc < numCheapResGen3[0] ){ + researchCheap[0][cc] = general3Cheap[0][cc]; + cc++; + } + cc=0; + //Standard Researches + while ( cc < numResGen3[0] ){ + research[0][cc] = general3[0][cc]; + cc++; + } + cc=0; + //Standard Researches + while ( cc < numResGen3[1] ){ + research[0][cc] = general3[1][cc]; + cc++; + } + cc=0; + while ( cc < numResGen3[9] ){ + research[9][cc] = general3[9][cc]; + cc++; + } + numRes[0] = numResGen3[0]; + numRes[1] = numResGen3[1]; + numRes[9] = numResGen3[9]; + + } + //____________________General 4____________________________ + if ( AIPersonality == AI_CYBORG){ + //Cheap Researches + while ( cc < numCheapResGen4[0] ){ + researchCheap[0][cc] = general4Cheap[0][cc]; + cc++; + } + cc=0; + //Standard Researches + while ( cc < numResGen4[0] ){ + research[0][cc] = general4[0][cc]; + cc++; + } + cc=0; + //Standard Researches + while ( cc < numResGen4[1] ){ + research[0][cc] = general4[1][cc]; + cc++; + } + cc=0; + while ( cc < numResGen4[9] ){ + research[9][cc] = general4[9][cc]; + cc++; + } + numRes[0] = numResGen4[0]; + numRes[1] = numResGen4[1]; + numRes[9] = numResGen4[9]; + + } + //update struct to be built + count = nDerricksAtStart+(nFreeOilRes/nPlayersInGame); + printDebug1("derricks/player=("& count &"); initial derricks("& nDerricksAtStart &") free oilRes ("& nFreeOilRes &") players in game("& nPlayersInGame &")"); + + //determine numb if additinal structs and type of mapPower + _nAdd = 0; + if (count < 4){ + printDebug1("Build standard quantity of structures -1"); + _nAdd = -1; + _nAddVTOL = -1; + nMapPower = VERY_LOW_POWER_MAP; + } else if (count >= 4 and count < 7){ + printDebug1("Build standard quantity of structures"); + _nAdd = 0; + _nAddVTOL = 0; + nMapPower = LOW_POWER_MAP; + } else if (count >= 7 and count < 11){ + printDebug1("Build standard quantity of structures + 1"); + _nAdd = 1; + _nAddVTOL = 0; + nMapPower = NORMAL_POWER_MAP; + } else if (count >= 11){ + printDebug1("Build standard quantity of structures + 2"); + _nAdd = 2; + _nAddVTOL = 1; + nMapPower = HIGH_POWER_MAP; + } + + //print off standard stats + count2=0; + while ( count2 < 4 ){ + if ( nAI_Pers == count2 ){ + printDebug1(" Standard building: Fact-Res-Cyb-VTOL("& structsLimits[count2][STR_TANK_FACTORY] &"-"& structsLimits[count2][STR_RESLAB] &"-"& structsLimits[count2][STR_CYB_FACTORY] &"-"& structsLimits[count2][STR_VTOL_FACTORY] &") mapPowerType ("& nMapPower &") _nAdd("& _nAdd &") _nAddVTOL("& _nAddVTOL &")"); + } + count2++; + } + + //update array + count2=0; + while ( count2 < 4 ){ + structsBuildLimits[count2][STR_TANK_FACTORY] =_nAdd + structsLimits[count2][STR_TANK_FACTORY]; + structsBuildLimits[count2][STR_RESLAB] =_nAdd + structsLimits[count2][STR_RESLAB]; + structsBuildLimits[count2][STR_CYB_FACTORY] =_nAdd + structsLimits[count2][STR_CYB_FACTORY]; + structsBuildLimits[count2][STR_VTOL_FACTORY] =_nAddVTOL + structsLimits[count2][STR_VTOL_FACTORY]; + count2++; + } + //set to 5 if too high. + count2=0; + while ( count2 < 4 ){ + if (structsBuildLimits[count2][STR_TANK_FACTORY] > 5) {structsBuildLimits[count2][STR_TANK_FACTORY] = 5;} + if (structsBuildLimits[count2][STR_RESLAB] > 5) {structsBuildLimits[count2][STR_RESLAB] = 5;} + if (structsBuildLimits[count2][STR_CYB_FACTORY] > 5) {structsBuildLimits[count2][STR_CYB_FACTORY] = 5;} + if (structsBuildLimits[count2][STR_VTOL_FACTORY] > 5) {structsBuildLimits[count2][STR_VTOL_FACTORY] = 5;} + count2++; + } + //set to 1 if less then 1. + count2=0; + while ( count2 < 4 ){ + if (structsBuildLimits[count2][STR_TANK_FACTORY] < 1) {structsBuildLimits[count2][STR_TANK_FACTORY] = 1;} + if (structsBuildLimits[count2][STR_RESLAB] < 1) {structsBuildLimits[count2][STR_RESLAB] = 1;} + if (structsBuildLimits[count2][STR_CYB_FACTORY] < 1) {structsBuildLimits[count2][STR_CYB_FACTORY] = 1;} + if (structsBuildLimits[count2][STR_VTOL_FACTORY] < 1) {structsBuildLimits[count2][STR_VTOL_FACTORY] = 1;} + count2++; + } + + //print off stats + count2=0; + while ( count2 < 4 ){ + if ( nAI_Pers == count2 ){ + printDebug1(" Selected building: General "& (count2+1) &" Fact-ResLab-CybFact-VTOLFact = ("& structsBuildLimits[count2][STR_TANK_FACTORY] &"-"& structsBuildLimits[count2][STR_RESLAB] &"-"& structsBuildLimits[count2][STR_CYB_FACTORY] &"-"& structsBuildLimits[count2][STR_VTOL_FACTORY] &") mapPowerType ("& nMapPower &") _nAdd("& _nAdd &")"); + } + count2++; + } + +} +//----------------------------------------------------------------------------- +function bool aiResponsibleForPlayer(int _player) +{ + if(_player == selectedPlayer or not myResponsibility(_player)) + { + return false; + } + + return true; +} +//----------------------------------------------------------------------------- +function int _random(int x) +{ + local int _c,_d; + _c=0; + while( _c < (player+1)*2 ){ + _d = random(x); + _c++; + } + return _d; +} +//----------------------------------------------------------------------------- +function void assignDroidToGrp(DROID droid) +{ + +/* +buildDefGroup.members +buildGroup.members +cyborgConstructGroup.members +cyborgAttGroup.members +cyborgDefGroup.members +harvesterGroup.members +helpGroup.members +repairGroup.members +tankDefGroup.members +tankGroup.members +toBeRepairedCyborgGroup.members +toBeRepairedTankGroup.members +vtolDefendGr.members +vtolAttGr.members +vtolHunterGr.members +*/ + // TANK + if ( droid == NULLOBJECT ){ return; } + if ( droid.player != player ){ return; } + + + if(droid.droidType == DROID_WEAPON and droid.propulsion != cyborgPropulsion) + { + groupAddDroid(tankDefGroup, droid); + } + +// TANK REPAIR + if(droid.droidType == DROID_REPAIR and droid.propulsion != cyborgPropulsion) + { + groupAddDroid(repairGroup, droid); + } + +// VTOL/CYBORG/TANK TRUCK + if( droid.droidType == DROID_CONSTRUCT and droid.propulsion != cyborgPropulsion ) + { + groupAddDroid(buildGroup, droid); + } + +// CYBORG +if(droid.propulsion == cyborgPropulsion) +{ + if(droid.droidType == DROID_CYBORG_CONSTRUCT) + { + //displayMsg("droidBuilt: cyborg ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to cyborgConstructGroup"); + groupAddDroid(cyborgConstructGroup, droid); + } else { + nTotCyborgBuilt++; + if ( AIPersonality == AI_CYBORG ){ + //displayMsg("droidBuilt: cyborg ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to cyborgDefGroup"); + groupAddDroid(cyborgDefGroup, droid); + } else { + if (nTotCyborgBuilt > 2){ + //displayMsg("droidBuilt: ["& nTotCyborgBuilt &"] CYBORG ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to tankDefGroup "); + groupAddDroid(tankDefGroup, droid); + nTotCyborgBuilt = 0; + } else { + //displayMsg("droidBuilt: ["& nTotCyborgBuilt &"] cyborg ("& droid.id &") hitPoints ("& droid.hitPoints &") power ("& calcDroidPower(droid) &") assigned to cyborgDefGroup "); + groupAddDroid(cyborgDefGroup, droid); + } + } + } +} + +// VTOL + boolResult = false; + if((isVtol(droid)) and (droid.droidType != DROID_CONSTRUCT)) + { + groupAddDroid(vtolDefendGr, droid); + } + + //debug check + if ( !hasGroup(droid) ){ + //dbg("dbg->assignDroidToGrp: player("& getPlayerName(player) &") found a droid with no group ("& droid.id &"), force assign to tankdefGroup",player); + groupAddDroid(tankDefGroup, droid); + } + + setDroidSecondary(droid,DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER); + if( droid.droidType == DROID_WEAPON or droid.droidType == DROID_CYBORG ){ + setDroidSecondary(droid,DSO_HALTTYPE, DSS_HALT_PERSUE); + setDroidSecondary(droid,DSO_ATTACK_RANGE, DSS_ARANGE_LONG); + setDroidSecondary(droid,DSO_ATTACK_LEVEL, DSS_ALEV_ALWAYS); + } +} +//----------------------------------------------------------------------------- +/* what to stop, keep working +[ResLab - TkFact - cybFac - VTOLFact] +(Defences - Uprades - RepairFac) +tkProd stop @ 15 droids +cybProd stop @ 15 droids +VTOLProd stop @ 8 droids +0- [1-1-1-1] (1-1-1) +1- [0-2-2-1] (1-1-1) +2- [0-2-2-0] (1-1-1) +3- [3-1-1-1] (0-1-1) +4- [3-1-1-0] (0-1-1) +5- [3-1-1-1] (1-1-1) +6- [0-0-0-0] (0-0-0) +7- [0-0-0-0] (0-0-0) +*/ +function void manageVeryLowPower() +{ + if ( nProdSelect == 0 ){//standard + if ( nWorkingLab >= 2){lStopResearch = true; } + //lStopCheapResearch = true; + if ( nWorkingFact >= 2 ){lStopTankProduction = true; } + if ( nWorkingCybFac >= 2 ) {lStopCybProduction = true; } + if ( nWorkingVTOLFac >= 1){lStopVTOLProduction = true; } + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + if ( nProdSelect == 1){ //ok defences and upgrades + if ( nWorkingLab >= 1){lStopResearch = true; } + //lStopCheapResearch = true; + lStopTankProduction = true; + lStopCybProduction = true; + lStopVTOLProduction = true; + //lStopBuildDefGateway = true; + //lStopBuildDef = true; + //lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + } + if ( nProdSelect == 2){ //ok units production + lStopResearch = true; + lStopCheapResearch = true; + //lStopTankProduction = true; + //lStopCybProduction = true; + //lStopVTOLProduction = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + if ( nProdSelect == 3){ + if ( nWorkingLab >= 1){lStopResearch = true; } + lStopCheapResearch = true; + if ( nWorkingFact >= 1 or nTotTanks > 10){lStopTankProduction = true; } + if ( nWorkingCybFac >= 1 or nTotCyborgs > 10) {lStopCybProduction = true; } + lStopVTOLProduction = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + //lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + if ( nProdSelect == 4){//stop all but cheap researches!! + lStopResearch = true; + //lStopCheapResearch = true; + if ( nWorkingFact >= 1 or nTotTanks > 10){lStopTankProduction = true; } + if ( nWorkingCybFac >= 1 or nTotCyborgs > 10){lStopCybProduction = true; } + lStopVTOLProduction = true; + lStopBuildDef = true; + lStopBuildDefGateway = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + } + if ( nProdSelect == 5){//stop all but researches, def and RepFac + //lStopResearch = true; + //lStopCheapResearch = true; + lStopTankProduction = true; + lStopCybProduction = true; + lStopVTOLProduction = true; + //lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildDefGateway = true; + //lStopBuildRepFacility = true; + } + if ( nProdSelect == 6){//stop upgrades only + if ( nWorkingFact >= 1){lStopTankProduction = true; } + if ( nWorkingCybFac >= 1){lStopCybProduction = true; } + if ( nWorkingVTOLFac >= 1){lStopVTOLProduction = true; } + if ( nWorkingLab >= 1){lStopResearch = true; } + //lStopCheapResearch = true; + //lStopBuildDef = true; + //lStopBuildDefGateway = true; + //lStopBuildDefDerricks = true; + //lStopBuildRepFacility = true; + } + if ( nProdSelect == 7){ //allow upgrades and researches stop defences and units prod + lStopTankProduction = true; + lStopCybProduction = true; + lStopVTOLProduction = true; + if ( nWorkingLab >= 2){lStopResearch = true; } + lStopCheapResearch = true; + lStopBuildDef = true; + lStopBuildDefGateway = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + } + + //activate VTOL production if min droids has been reached + if ( vtolDefendGr.members < MIN_VTOLS and nVTOLFactories > 0 ){ + lStopVTOLProduction = false; + if ( (nTotCyborgs+nTotTanks) > 15 ){ + lStopTankProduction = true; + lStopCybProduction = true; + } + } + +} +//================================================== +function void manageVeryLowPower2() //Personality General 2 +{ + if ( nProdSelect < 3 ){ + if ( vtolDefendGr.members < MIN_VTOLS_PERS2 and nVTOLFactories > 0){ + lStopVTOLProduction = false; + lStopTankProduction = true; + lStopCybProduction = true; + lStopResearch = true; + lStopCheapResearch = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = false; + lStopBuildDefGateway = true; + } else { + if ( nWorkingVTOLFac >= 2){lStopVTOLProduction = true; } + if ( nWorkingFact >= 0 ) {lStopTankProduction = true; } + if ( nWorkingCybFac >= 0) {lStopCybProduction = true; } + if ( nWorkingLab >= 2 ) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + } + + if ( nProdSelect >= 3 and nProdSelect < 6){ + if ( vtolDefendGr.members < MIN_VTOLS_PERS2 and nVTOLFactories > 0 ){ + lStopVTOLProduction = false; + lStopTankProduction = true; + lStopCybProduction = true; + if ( nWorkingLab >= 1 ) {lStopResearch = true; } + lStopCheapResearch = true; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } else { + if ( nWorkingVTOLFac >= 1){lStopVTOLProduction = true; } + if ( nWorkingFact >= 2 ) {lStopTankProduction = true; } + if ( nWorkingCybFac >= 2) {lStopCybProduction = true; } + if ( nWorkingLab >= 2 ) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildRepFacility = false; + lStopBuildDefGateway = false; + } + } + + if ( nProdSelect >= 6 and nProdSelect < 8){ + if ( vtolDefendGr.members < MIN_VTOLS_PERS2 and nVTOLFactories > 0 ){ + lStopVTOLProduction = false; + lStopTankProduction = true; + lStopCybProduction = true; + lStopResearch = true; + lStopCheapResearch = true; + lStopBuildDef = false; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } else { + if ( nWorkingVTOLFac >= 2){lStopVTOLProduction = true; } + if ( nWorkingFact >= 1 ) {lStopTankProduction = true; } + if ( nWorkingCybFac >= 1) {lStopCybProduction = true; } + if ( nWorkingLab >= 0 ) {lStopResearch = true; } + lStopCheapResearch = true; + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + + } + + if ( gameTime > TIME_START_VTOLRESEARCH ){ + if ( !skVtolEnableCheck(player) ){ + if ( nWorkingLab < 2 ) {lStopResearch = false; } + else { lStopResearch = true; } + } + } + +} +//================================================== +function void manageVeryLowPower3() //Personality General 3 +{ + + if ( nProdSelect < 3 ){ + if ( nWorkingVTOLFac>= 0) {lStopVTOLProduction = true; } + if ( nWorkingFact >= 1) {lStopTankProduction = true; } + if ( nWorkingCybFac >= 1) {lStopCybProduction = true; } + if ( nWorkingLab >= 2) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = false; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = false; + } + if ( nProdSelect >= 3 and nProdSelect < 6 ){ + if ( nWorkingVTOLFac>= 0) {lStopVTOLProduction = true; } + if ( nWorkingFact >= 1) {lStopTankProduction = true; } + if ( nWorkingCybFac >= 2) {lStopCybProduction = true; } + if ( nWorkingLab >= 2) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildRepFacility = true; + lStopBuildDefGateway = false; + } + if ( nProdSelect >= 6 ){ + if ( nWorkingVTOLFac>= 1) {lStopVTOLProduction = true; } + if ( nWorkingFact >= 0) {lStopTankProduction = true; } + if ( nWorkingCybFac >= 0) {lStopCybProduction = true; } + if ( nWorkingLab >= 4) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + + //stop events + if ( nTotTanks >= 12 and gameTime > 15*TIME_MINUTE ){//20 min + lStopTankProduction = true; + } + + //activate VTOL production if min droids has been reached + if ( vtolDefendGr.members < MIN_VTOLS and nVTOLFactories > 0 and ( (nTotCyborgs+nTotTanks) > MIN_TOT_UNITS) ){ + lStopVTOLProduction = false; + lStopTankProduction = true; + lStopCybProduction = true; + } +} + +//================================================== +function void manageVeryLowPower4() //Personality General 4 +{ + if ( nProdSelect < 3 ){ + if ( nWorkingVTOLFac>= 1) {lStopVTOLProduction = true; } + lStopTankProduction = false; + if ( nWorkingCybFac >= 2) {lStopCybProduction = true; } + if ( nWorkingLab >= 3) {lStopResearch = true; } + lStopCheapResearch = true; + lStopBuildDef = false; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + if ( nProdSelect >= 3 and nProdSelect < 6 ){ + if ( nWorkingVTOLFac>= 0) {lStopVTOLProduction = true; } + lStopTankProduction = false; + if ( nWorkingCybFac >= 3) {lStopCybProduction = true; } + if ( nWorkingLab >= 2) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = false; + lStopBuildDefDerricks = false; + lStopBuildRepFacility = false; + lStopBuildDefGateway = false; + } + if ( nProdSelect >= 6 ){ + if ( nWorkingVTOLFac>= 0) {lStopVTOLProduction = true; } + lStopTankProduction = false; + lStopCybProduction = false; + if ( nWorkingLab >= 1) {lStopResearch = true; } + lStopCheapResearch = false; + lStopBuildDef = true; + lStopBuildDefDerricks = true; + lStopBuildRepFacility = true; + lStopBuildDefGateway = true; + } + + //activate VTOL production if min droids has been reached + if ( vtolDefendGr.members < MIN_VTOLS and nVTOLFactories > 0 and ( (nTotCyborgs+nTotTanks) > MIN_TOT_UNITS) ){ + lStopVTOLProduction = false; + lStopTankProduction = true; + lStopCybProduction = true; + } + +} + + +//----------------------------------------------------------------------------- +function STRUCTURE getVTOLstructTarget() +{ + local int _player, _aa, _bestAA, _ii; + local STRUCTURE _struct, _structTarget; + + _structTarget = NULLOBJECT; + + //search for enemy def structs not protected by AA + if ( _random(10) < 6 ){ // ------------ attack def structs or AA def ---------------- + + if ( _random(10) < 5 ){ // ------------ attack def structs ---------------- + + _aa=0; + _bestAA=999; + _ii = 0; + while ( _ii < numDefStructs){ + _struct = getStructure(defStructs[_ii],targetPlayerVTOL); + if ( _struct != NULLOBJECT ){ + _aa = numEnemyAAInRange(_struct.x, _struct.y, AA_THREAT_RANGE ); + if ( _aa < _bestAA ){ + //displayMsg("_________ getVTOLstructTarget DEF1 ("& _struct.id &")("& _aa &")__________"); + _bestAA = _aa; _structTarget = _struct; + } + } + _ii++; + } + _aa=0; + _bestAA=999; + _ii = 0; + while ( _ii < numWallWeaps){ + _struct = getStructure(wallWeaps[_ii],targetPlayerVTOL); + if ( _struct != NULLOBJECT ){ + _aa = numEnemyAAInRange(_struct.x, _struct.y, AA_THREAT_RANGE ); + if ( _aa < _bestAA ){ + //displayMsg("_________ getVTOLstructTarget DEF2 ("& _struct.id &")("& _aa &")__________"); + _bestAA = _aa; _structTarget = _struct; + } + } + _ii++; + } + + } else { // ------------ attack AA def structs ---------------- + + //displayMsg("_________ getVTOLstructTarget __________"); + _aa=0; + _bestAA=999; + _ii = 0; + while ( _ii < numGenAA){ + _struct = getStructure(vtolGenStruct[_ii],targetPlayerVTOL); + if ( _struct != NULLOBJECT ){ + _aa = numEnemyAAInRange(_struct.x, _struct.y, AA_THREAT_RANGE ); + if ( _aa < _bestAA ){ + _bestAA = _aa; _structTarget = _struct; + //displayMsg("_________ getVTOLstructTarget AA ("& _struct.id &")("& _aa &")__________"); + } + } + _ii++; + } + + } + + } else {// ------------- attack base ------------ + + //displayMsg("_________ getVTOLstructTarget search target in Base __________"); + _aa=0; + _bestAA=999; + _ii = 0; + while ( _ii < numStructs){ + _struct = getStructure(structs[_ii],targetPlayerVTOL); + if ( _struct != NULLOBJECT ){ + _aa = numEnemyAAInRange(_struct.x, _struct.y, AA_THREAT_RANGE ); + if ( _aa < _bestAA ){ _bestAA = _aa; _structTarget = _struct; } + } + _ii++; + } + if ( _structTarget == NULLOBJECT or _bestAA*3 > vtolDefendGr.members){ + _aa=0; + _bestAA=999; + _ii = 0; + while ( _ii < numWallWeaps){ + _struct = getStructure(wallWeaps[_ii],targetPlayerVTOL); + if ( _struct != NULLOBJECT ){ + _aa = numEnemyAAInRange(_struct.x, _struct.y, AA_THREAT_RANGE ); + if ( _aa < _bestAA ){ _bestAA = _aa; _structTarget = _struct; } + } + _ii++; + } + } + if ( _structTarget == NULLOBJECT or _bestAA*2 > vtolDefendGr.members){ + _aa=0; + _bestAA=999; + _ii = 0; + while ( _ii < numDefStructs){ + _struct = getStructure(defStructs[_ii],targetPlayerVTOL); + if ( _struct != NULLOBJECT ){ + _aa = numEnemyAAInRange(_struct.x, _struct.y, AA_THREAT_RANGE ); + if ( _aa < _bestAA ){ _bestAA = _aa; _structTarget = _struct; } + } + _ii++; + } + } + } + return _structTarget; +} + +//----------------------------------------------------------------------------- +function int numEnemyAAInRange(int _x, int _y, int _range) +{ + local int _enemy,_numAA; + + _numAA = 0; + _enemy = 0; + while(_enemy < MAX_PLAYERS) + { + if(!friendlyPlayer(_enemy)) + { + _numAA = _numAA + numAAinRange(_enemy, player, _x, _y, _range); + } + _enemy++; + } + + return _numAA; +} +//----------------------------------------------------------------------------- +function void updatePlayersStats() +{ + local int _player, _range, _temp, _nFact, _nCybFact, _nVTOLFact; + local int _c2,_c3; + + _range = max(mapWidth,mapHeight)*TILE*2; + + nPlayersInGame = 0; + nEnemyPlayers = 0; + nHumanPlayers = 0; + nLastEnemyPlayer = -1; + _c2 = 0; + _c3 = 0; + while ( _c2 < MAX_PLAYERS ){ + if ( isPlayerStillLive(_c2)){ + if ( isHumanPlayer(_c2) ){ nHumanPlayers++; } + + nPlayersInGame++; + if ( !friendlyPlayer(_c2) ){ + //printDebug1("updatePlayersStats: enemy player found _c2("& getPlayerName(_c2) &" #("& _c2 &") "); + nEnemyPlayers++; + nLastEnemyPlayer = _c2; + } + aPlayers[PLAYER_NUMBER][_c3] = _c2; + _c3++; + } + _c2++; + } + + //reset teams, just in case alliances changed. + count = 0; + while (count < MAX_PLAYERS){ + aPlayers[TEAM_NUMBER][count] = -1; + count++; + } + + count = 0; + _c2 = 0; + nTeam = 0; + while (count < MAX_PLAYERS){ + if ( aPlayers[TEAM_NUMBER][count] < 0 and isPlayerStillLive(count) ){ + + //assign a team to the player + nTeam++; + aPlayers[TEAM_NUMBER][count] = nTeam; + + //loop + _c2 = 0; + while (_c2 < MAX_PLAYERS){ + if ( allianceExistsBetween(count,_c2) and count != _c2 and isPlayerStillLive(_c2) ){ + if ( aPlayers[TEAM_NUMBER][_c2] < 0 ){ + aPlayers[TEAM_NUMBER][_c2] = aPlayers[TEAM_NUMBER][count]; + } + } + _c2++; + } + } + count++; + } + + _player=0; + while( _player < MAX_PLAYERS ){ + if ( isPlayerStillLive(_player) ){ + aStat[OC_DERRICKS][_player] = getNumDerricks(_player); + aStat[OC_RESLABS][_player] = numStructsByType( resLab, _player ); + aStat[OC_CYBORGS][_player] = getDroidsInfo(_player, 0); + aStat[OC_TANKS][_player] = getDroidsInfo(_player, 1); + aStat[OC_VTOLS][_player] = getDroidsInfo(_player, 2); + aStat[OC_CYB_POWER][_player] = getDroidsInfo(_player, 3); + aStat[OC_TK_POWER][_player] = getDroidsInfo(_player, 4); + aStat[OC_VTOL_POWER][_player] = getDroidsInfo(_player, 5); + aStat[OC_CYB_HP][_player] = getDroidsInfo(_player, 6); + aStat[OC_TK_HP][_player] = getDroidsInfo(_player, 7); + aStat[OC_VTOL_HP][_player] = getDroidsInfo(_player, 8); + } + _player++; + } + +} + +//----------------------------------------------------------------------------- +//not used +function int getTeamNumber(int _player) +{ + return aPlayers[TEAM_NUMBER][_player]; +} +//----------------------------------------------------------------------------- +function int getDroidsInfo(int _player, int _choice) +{ + local DROID _droid; + local GROUP _grp[8]; + local int _cyb, _tk, _vtol, _powCYB, _powTK, _powVTOL, _hpCYB, _hpTK, _hpVTOL; + + _tk=0; _cyb=0; _vtol=0; _powCYB=0; _powTK=0; _powVTOL=0; + _hpCYB=0; _hpTK=0; _hpVTOL=0; + + + InitEnumDroids(_player,_player); + _droid = EnumDroid(); + while(_droid != NULLOBJECT) + { + if(_droid.droidType == DROID_WEAPON and _droid.propulsion != cyborgPropulsion){ + _powTK = _powTK + calcDroidPower(_droid); + _hpTK = _hpTK + _droid.hitPoints; + _tk++; + } + if(_droid.droidType == DROID_CYBORG){ + _powCYB = _powCYB + calcDroidPower(_droid); + _hpCYB = _hpCYB + _droid.hitPoints; + _cyb++; + } + if( isVtol(_droid) ){ + _powVTOL = _powVTOL + calcDroidPower(_droid); + _hpVTOL = _hpVTOL + _droid.hitPoints; + _vtol++; + } + //power cost + _droid = EnumDroid(); + } + + if ( _choice == 0 ){ return _cyb; } + if ( _choice == 1 ){ return _tk; } + if ( _choice == 2 ){ return _vtol; } + if ( _choice == 3 ){ return _powCYB; } + if ( _choice == 4 ){ return _powTK; } + if ( _choice == 5 ){ return _powVTOL; } + if ( _choice == 6 ){ return _hpCYB; } + if ( _choice == 7 ){ return _hpTK; } + if ( _choice == 8 ){ return _hpVTOL; } + return -1; +} + +//----------------------------------------- +function void deactivateHelp() +{ + + //if (nAllyBeingHelped<0){ dbg("dbg->deactivateHelp: Unnecessary deactivate request, player ("& player &") is not helping any ally", player);} + //tBeacon[nAllyBeingHelped] = -1; + //beaconX[nAllyBeingHelped] = -1; + //beaconY[nAllyBeingHelped] = -1; + nAllyBeingHelped = -1; + tHelpAction = -1; + nHelpX = -1; + nHelpY = -1; + lastHelpPlayer = -1; + objTargetHelpTeam = NULLOBJECT; + if ( helpGroup.members > 0){ + if ( AIPersonality == AI_CYBORG ){ + groupAddGroup(cyborgDefGroup, helpGroup); + orderGroup(cyborgDefGroup, DORDER_RTB); + } else { + groupAddGroup(tankDefGroup, helpGroup); + orderGroup(tankDefGroup, DORDER_RTB); + } + } + setEventTrigger(manageHelpTeam,inactive); +} +//----------------------------------------------------------------------------- +function bool bHelpingAnyAlly() +{ + if ( nAllyBeingHelped == -1 ){ + return false; + } + return true; +} +//----------------------------------------------------------------------------- +function bool canHelpAlly(int _sender) +{ + local int _tank, _cyb; + + _tank = tankDefGroup.members - minDefDroids[nAI_Pers][MINDEF_TANKS]; + _cyb = cyborgDefGroup.members - minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + + dbg("dbg->canHelpAlly: Player ("& getPlayerName(player) &") has tk ("& _tank &") and cyb ("& _cyb &") availabe for help, alert ("& alertIsOn &") alertLevel ("& alertLevel &") _sender("& _sender &") lastHelpPlayer("& lastHelpPlayer &")", player ); + + if ( lastHelpPlayer != _sender and lastHelpPlayer != -1){ + return false; + } + if (alertLevel == RED_ALERT){ + return false; + } + if ( _tank +_cyb < MIN_HELPING_UNITS ){ + //dbg("Player ("& player &") cannot help has tk+cyb ("& _tank +_cyb &") and min should be ("& MIN_HELPING_UNITS &")", _sender ); + return false; + } + return true; +} + +//----------------------------------------------------------------------------- +function void helpAlly(int _ally){ + + local int _tank, _cyb; + + _tank = tankDefGroup.members - minDefDroids[nAI_Pers][MINDEF_TANKS]; + _cyb = cyborgDefGroup.members - minDefDroids[nAI_Pers][MINDEF_CYBORGS]; + + printDebug1("helpAlly: has tk("& tankDefGroup.members &"/"& _tank &") cyb("& cyborgDefGroup.members &"/"& _cyb &") availabe for help, alert ("& alertIsOn &") alertLevel ("& alertLevel &")" ); + if ( _tank > MAX_HELPING_UNITS ){ _tank = MAX_HELPING_UNITS; } + if ( _cyb > MAX_HELPING_UNITS ){ _cyb = MAX_HELPING_UNITS; } + + moveUnitsBetweenGRPs(helpGroup, tankDefGroup, _tank, true); + moveUnitsBetweenGRPs(helpGroup, cyborgDefGroup, _cyb, false); + + tLastHelp = gameTime; + nHelpX = beaconX[_ally]; + nHelpY = beaconY[_ally]; + nAllyBeingHelped = _ally; + + //helping droids never repair themselves + initIterateGroup(helpGroup); + droid = iterateGroup(helpGroup); + while( droid != NULLOBJECT) + { + setDroidSecondary(droid,DSO_REPAIR_LEVEL, DSS_REPLEV_NEVER); + droid = iterateGroup(helpGroup); + } + + msg("Sending "& helpGroup.members &" units to beacon point coord: "& (nHelpX/TILE) &"-"& (nHelpY/TILE), player, _ally); + printDebug1("helpAlly: Sending "& helpGroup.members &" units to beacon point coord: "& (nHelpX/TILE) &"-"& (nHelpY/TILE) &" helping ("& getPlayerName(_ally) &")" ); + + orderGroupMoveCMD(helpGroup, nHelpX, nHelpY); + setEventTrigger(manageHelpTeam,manageHelpTeamTr); + +} + +//====================================================================== +// +// DyDo Communcation Functions & Events +// +//====================================================================== +event consoleEv(consoleTr) //(CALL_CONSOLE, ref sender, ref message); +{ + //console(getPlayerName(player) & " console sender ("& sender &") message ("& message &")"); + + if( (sender!=player) and (message == "are you dydo?" or message == "are you DyDo?" or message == "who are you?")) + { + //boolResult=true; + if(allianceExistsBetween(_sender,player)){ + msg("I am ("& DYDOBP_RELEASE &"), player "& player &", General " & AIPersonality & " ["& AIstrength &"] (ally)",player, sender); + } else { + msg("I am ("& DYDOBP_RELEASE &"), player "& player &", General " & AIPersonality & " ["& AIstrength &"] (enemy)",player, sender); + } + } + + if ( message == "/debug0 on" and player == 0 ) { + msg("Debug turned on", player, sender); + dbgMsgOn(player, true); + } + + if ( message == "/debug1 on" and player == 1 ) { + msg("Debug turned on", player, sender); + dbgMsgOn(player, true); + } + + if ( message == "/debug2 on" and player == 2 ) { + msg("Debug turned on", player, sender); + dbgMsgOn(player, true); + } + + if ( message == "/debug3 on" and player == 3 ) { + msg("Debug turned on", player, sender); + dbgMsgOn(player, true); + } + + if ( message == "/debug on") { + msg("Debug turned on", player, sender); + dbgMsgOn(player, true); + } + + if (message == "/debug off" ) { + msg("Debug turned off", player, sender); + dbgMsgOn(player, false); + } + + if (message == "/stats" ) { + count = getTargetEnemy(false); + } + + if (message == "/stats1" ) { + displayStats(1); + } + + if (message == "/stats2" ) { + displayStats(2); + } + + if (message == "/stats3" ) { + displayStats(3); + } + + if ( gameTime < 2*TIME_MINUTE ){ + if(message == "/set dydo gen1" ) { + SetDyDoPersonality(AI_STANDARD,player); + console(getPlayerName(player) & " is now DyDo Standard AI"); + } + if(message == "/set dydo gen2" ) { + SetDyDoPersonality(AI_VTOL,player); + console(getPlayerName(player) & " is now DyDo VTOL AI"); + } + if(message == "/set dydo gen3" ) { + SetDyDoPersonality(AI_TURTLE,player); + console(getPlayerName(player) & " is now DyDo Turtle AI"); + } + if(message == "/set dydo gen4" ) { + SetDyDoPersonality(AI_CYBORG,player); + console(getPlayerName(player) & " is now DyDo Cyborg AI"); + } + if(message == "/set dydo random" ) { + SetDyDoPersonality(0,player); + console(getPlayerName(player) & " is now DyDo random AI"); + } + + if(message == "/set player0 gen1" ) { + SetDyDoPersonality(AI_STANDARD,0); + if ( player==3 ){console( getPlayerName(0) & " is now DyDo Standard AI"); } + } + if(message == "/set player1 gen1" ) { + SetDyDoPersonality(AI_STANDARD,1); + if ( player==3 ){console( getPlayerName(1) & " is now DyDo Standard AI"); } + } + if(message == "/set player2 gen1" ) { + SetDyDoPersonality(AI_STANDARD,2); + if ( player==3 ){console( getPlayerName(2) & " is now DyDo Standard AI"); } + } + if(message == "/set player3 gen1" ) { + SetDyDoPersonality(AI_STANDARD,3); + if ( player==3 ){console( getPlayerName(3) & " is now DyDo Standard AI"); } + } + + if(message == "/set player0 gen2" ) { + SetDyDoPersonality(AI_VTOL,0); + if ( player==0 ){console( getPlayerName(0) & " is now DyDo VTOL AI"); } + } + if(message == "/set player1 gen2" ) { + SetDyDoPersonality(AI_VTOL,1); + if ( player==1 ){console( getPlayerName(1) & " is now DyDo VTOL AI"); } + } + if(message == "/set player2 gen2" ) { + SetDyDoPersonality(AI_VTOL,2); + if ( player==2 ){console( getPlayerName(2) & " is now DyDo VTOL AI"); } + } + if(message == "/set player3 gen2" ) { + SetDyDoPersonality(AI_VTOL,3); + if ( player==3 ){console( getPlayerName(3) & " is now DyDo VTOL AI"); } + } + + if(message == "/set player0 gen3" ) { + SetDyDoPersonality(AI_TURTLE,0); + if ( player==0 ){console( getPlayerName(0) & " is now DyDo Turtle AI"); } + } + if(message == "/set player1 gen3" ) { + SetDyDoPersonality(AI_TURTLE,1); + if ( player==1 ){console( getPlayerName(1) & " is now DyDo Turtle AI"); } + } + if(message == "/set player2 gen3" ) { + SetDyDoPersonality(AI_TURTLE,2); + if ( player==2 ){console( getPlayerName(2) & " is now DyDo Turtle AI"); } + } + if(message == "/set player3 gen3" ) { + SetDyDoPersonality(AI_TURTLE,3); + if ( player==3 ){console( getPlayerName(3) & " is now DyDo Turtle AI"); } + } + + if(message == "/set player0 gen4" ) { + SetDyDoPersonality(AI_CYBORG,0); + if ( player==0 ){console( getPlayerName(0) & " is now DyDo Cyborg AI"); } + } + if(message == "/set player1 gen4" ) { + SetDyDoPersonality(AI_CYBORG,1); + if ( player==1 ){console( getPlayerName(1) & " is now DyDo Cyborg AI"); } + } + if(message == "/set player2 gen4" ) { + SetDyDoPersonality(AI_CYBORG,2); + if ( player==2 ){console( getPlayerName(2) & " is now DyDo Cyborg AI"); } + } + if(message == "/set player3 gen4" ) { + SetDyDoPersonality(AI_CYBORG,3); + if ( player==3 ){console( getPlayerName(3) & " is now DyDo Cyborg AI"); } + } + } + + if(message == "/autogame on" && (sender == player)) + { + if(myResponsibility(player)) + { + if(!bRunning) //make sure current machine is responsible for this AI and it's not already active + { + console(getPlayerName(player) & " is now active"); + bRunning = true; + activateAI(); + } + } + } + + if(message == "/autogame off" && (sender == player)) + { + if(myResponsibility(player)) + { + if(bRunning) + { + console(getPlayerName(player) & " AI has been deactivated"); + bRunning = false; + shutDownThisAI(); + } + } + } + +} +//======================================================================== +/* Deal with beacons */ +//(CALL_BEACON, player, ref sender, ref x, ref y, ref message); +event beaconEv(beaconTr) +{ + local int _players; + local string _processedString; + + /* + if( !aiResponsibleForPlayer(player) ) + { + setEventTrigger(beaconEv, inactive); + } + else + { + */ + ASSERT(sender >= 0 and sender < 8, "beaconEv: sender out of bounds: " & sender , player); + + updateBeacons(); + + beaconX[sender] = x; + beaconY[sender] = y; + tBeacon[sender] = gameTime / 10; + + processCommand(message, sender, TRUE); + //} +} + +//----------------------------------------------------------------------------- +function bool haveAnyBeacon() +{ + local int _c; + _c = 0; + while ( _c < MAX_PLAYERS ){ + if((tBeacon[_c] > 0) and (not beaconTimeout(_c))) + { + return true; //have beacon for this player + } + _c++; + } + + return false; +} +//----------------------------------------------------------------------------- +function bool haveBeacon(int _player) +{ + if((tBeacon[_player] > 0) and (not beaconTimeout(_player))) + { + return true; //have beacon for this player + } + + return false; +} +//----------------------------------------------------------------------------- +function bool beaconTimeout(int _player) +{ + if((tBeacon[_player] > 0) and (( tBeacon[_player] + tBeaconTimeout) < GAME_TIME_IN_SECS)) //not too long ago + { + return true; //this beacon is still 'fresh' + } + + return false; +} +//----------------------------------------------------------------------------- +function void updateBeacons() +{ + local int _c; + _c = 0; + while(_c < MAX_PLAYERS) + { + if(beaconTimeout(_c)) //last beacon timed out + { + tBeacon[_c] = -1; + beaconX[_c] = -1; + beaconY[_c] = -1; + } + _c = _c + 1; + } +} +//----------------------------------------------------------------------------- +/* Deal with a chat message */ +//(CALL_AI_MSG, player, ref sender, ref message); +event multiMsgEv(multiMsgTr) +{ + /* + if( !aiResponsibleForPlayer(player) ) + { + setEventTrigger(multiMsgEv, inactive); + } else { + */ + if( sender == player or !allianceExistsBetween(sender,player) ){ exit; } + processCommand(message, sender, false); + //} +} +//----------------------------------------------------------------------------- +function void processCommand(string _message, int _sender, bool _bBlipMessage) +{ + + //go,/stop,/status + local int _numMsgs, _curMsg, _addressedPlayers, _x, _y, _player; + local string _msg, _processedString; + local int _enWeap,_myWeap,_myWeapSTR,_enemyCost,_friendCost; + local int _tDG, _bg, _hg, _cAt, _tg, _bdg, _cG, _ccG, _rg, _HelpG; + local string _strTeams, _sWallDef, _sDef, _sRes, _sRes2, _str0, _str1, _str2, _str3, _str4; + + /* Extract semantic information */ + _curMsg = 0; + _numMsgs = processChatMsg(_message); + + //boolResult=false; + //dbg("processCommand A: player("& getPlayerName(player) &") num messages("& _numMsgs &") _message(" & _message & ") from " & _sender, player); + + + //if (_message == "/debug_on" or _message == "/debug_on_player0" and player == 0 or _message == "/debug_on_player1" and player == 1 or _message == "/debug_on_player2" and player == 2 or _message == "/debug_on_player3" and player == 3 or _message == "/debug_on_player4" and player == 4 or _message == "/debug_on_player5" and player == 5 or _message == "/debug_on_player6" and player == 6 or _message == "/debug_on_player7" and player == 7 ) + + if(!allianceExistsBetween(_sender,player) ){ return; } + + while(_curMsg < _numMsgs ) + { + if(chatCmdIsPlayerAddressed(_curMsg, player))//not AIV func + { + + if ( _message == "stop" or _message == "Stop" ){ + _msg = "xxx"; + } else { + _msg = getChatCmdDescription(_curMsg); + } + + //dbg("Player ("& player &") addressed with : ("& _msg &")", player); + if(_msg == "help" or _msg == "help me" or _msg == "go!" or _msg == "go") //go + { + boolResult=true; + if(not haveBeacon(_sender)) + { + msg("Drop a beacon please (Alt+H), I need to know where to send the units", player, _sender); + return; + } else { + //dbg("dbg: Got a beacon on: "& (beaconX[_sender]/TILE) &"-"& (beaconY[_sender]/TILE), player); + if ( nAllyBeingHelped == -1 ){ + if ( canHelpAlly(_sender) ){//nAllyBeingHelped + lastHelpPlayer = _sender; + //dbg("dbg: Ally can help", _sender); + helpAlly(_sender); + } else{ + msg("I am sorry. I have no enough units to send or I am in trouble", player, _sender); + } + } else{ + if ( nAllyBeingHelped == _sender ){ + msg(getPlayerName(nAllyBeingHelped) & ", I am coming!" , player, _sender); + } else { + msg("I am sorry but I am already helping player # "& nAllyBeingHelped &" ("& getPlayerName(nAllyBeingHelped) &" colour)", player, _sender); + } + } + } + + } else if (_msg == "status?" or _msg == "Status?" or _msg == "status") { + boolResult=true; + //dbg("Got a status request :" & _msg, _sender ); + notifyStatus(1, _sender); + + } else if ( _msg == "xxx" ) { + boolResult=true; + if ( !bHelpingAnyAlly() ){ + msg("There is nothing to stop!", player, _sender); + } else { + //dbg("dbg: i'm addressed with stop", player); + if ( nAllyBeingHelped == _sender ){ + deactivateHelp(); + msg("Action deactivated!", player, _sender); + } + } + + } else if (_msg == "power?" or _msg == "power") { + boolResult=true; + msg("I have ("& playerPower(player) &") power available", player, _sender); + + } else if (_msg == "/status" ) { + count = (tankDefGroup.members-minDefDroids[nAI_Pers][MINDEF_TANKS])+(cyborgDefGroup.members-minDefDroids[nAI_Pers][MINDEF_CYBORGS])-MIN_HELPING_UNITS; + msg("Have a Beacon("& haveAnyBeacon() &") Player Helped("& nAllyBeingHelped &") Helping Droids("& helpGroup.members &") Help Countdown("& count &"/"& MIN_HELPING_UNITS &")", player, _sender); + _enWeap = numEnemyWeapDroidsInRange(player,baseX, baseY, nDefendRange , false); + _myWeap = numPlayerWeapDroidsInRange(player, player, baseX, baseY, nDefendRange , true); + _myWeapSTR = numFriendlyWeapStructsInRange(player,baseX, baseY, nDefendRange, true); + _enemyCost = enemyWeapObjCostInRange(player, baseX, baseY, nDefendRange, false, true); + _friendCost = friendlyWeapObjCostInRange(player, baseX, baseY, nDefendRange,false, true); + msg("Defend Range: _enWeap ("& _enWeap&") _myWeap ("& _myWeap &") _myWeapSTR ("& _myWeapSTR &") _enemyCost("& _enemyCost &") _friendCost("& _friendCost &")", player, _sender); + _enWeap = numEnemyWeapDroidsInRange(player,baseX, baseY, nBaseRange , false); + _myWeap = numPlayerWeapDroidsInRange(player, player, baseX, baseY, nBaseRange , true); + _myWeapSTR = numFriendlyWeapStructsInRange(player,baseX, baseY, nBaseRange, true); + _enemyCost = enemyWeapObjCostInRange(player, baseX, baseY, nBaseRange, false, true); + _friendCost = friendlyWeapObjCostInRange(player, baseX, baseY, nBaseRange,false, true); + msg("Base Range: _enWeap ("& _enWeap&") _myWeap ("& _myWeap &") _myWeapSTR ("& _myWeapSTR &") _enemyCost("& _enemyCost &") _friendCost("& _friendCost &")", player, _sender); + _bg = buildGroup.members; + _hg = harvesterGroup.members; + _rg = repairGroup.members; + _tg = tankGroup.members; + _bdg = buildDefGroup.members; + _ccG = cyborgConstructGroup.members; + _cG = cyborgDefGroup.members; + _tDG = tankDefGroup.members; + _cAt = cyborgAttGroup.members; + _HelpG = helpGroup.members; + msg(" build("& _bg &"), harv("& _hg &"), buildDef("& _bdg &"), cybConst("& _ccG &"), repair("& _rg &"), tkDef("& _tDG &"), tkAttack("& _tg &"), cybDef("& _cG &"), cybAtt("& _cAt &"), help("& _HelpG &") ", player, _sender); + + count = 0; + while ( count < numWallWeaps ){ + _sWallDef = _sWallDef & " ["& count &"]("& isStructureAvailable(wallWeaps[count],player) &") "; + count++; + } + count = 0; + while ( count < numDefStructs ){ + _sDef = _sDef & " ["& count &"]("& isStructureAvailable(defStructs[count],player) &") "; + count++; + } + count = 0; + while ( count < 20){ + _str0 = _str0 & " ["& count &"]"& numResearchLeft(player,research[0][count]) &" "; + count++; + } + while ( count < 40){ + _str1 = _str1 & " ["& count &"]"& numResearchLeft(player,research[0][count]) &" "; + count++; + } + //displayMsg("________ (3) _________"); + while ( count < 60){ + _str2 = _str2 & " ["& count &"]"& numResearchLeft(player,research[0][count]) &" "; + count++; + } + + count = 0; + while ( count < numCheapRes[0] ){ + _sRes2 = _sRes2 & " ["& count &"]"& numResearchLeft(player,researchCheap[0][count]) &" "; + count++; + } + + count = 0; + while ( count < numRes[9] ){ + _str4 = _str4 & " ["& count &"]"& numResearchLeft(player,research[9][count]) &" "; + count++; + } + count = 0; + while (count < MAX_PLAYERS){ + if (isPlayerStillLive(count)){ + _strTeams = _strTeams & " "& getPlayerName(count) &" ("& count &") ["& aPlayers[TEAM_NUMBER][count] &"] "; + } + count++; + } + msg("STDdef: ("& pickDefQueueDepth &") - " & _sDef , player, _sender); + msg("WALLdef: ("& pickWallDefQueueDepth &") - "& _sWallDef , player, _sender); + msg("A: " & _str0, player, _sender); + msg("B: " & _str1, player, _sender); + msg("C: " & _str2, player, _sender); + msg("Cheap: TOT:"& numCheapRes[0] & " " & _sRes2, player, _sender); + msg("VTOL: VTOL_PAD("& numResearchLeft(player,research[9][0]) &") Hurricane("& numResearchLeft(player,HurricaneAASite) &")Cyclone("& numResearchLeft(player,CycloneAASite) &")Whirlwind("& numResearchLeft(player,WhirlwindAASite) &") " & _str4, player, _sender); + } + + } //if(chatCmdIsPlayerAddressed(_curMsg, player))/ + _curMsg++; + } + +} +//----------------------------------------------------------------------------- +function void notifyAll(STRING _cstr) +{ + local int _player; + + _player = 0; + while(_player < MAX_PLAYERS ) + { + if ( player != _player ){ + msg(_cstr, player, _player); + } + _player++; + } + +} +//----------------------------------------------------------------------------- +function void notifyStatus(int _choice, int _player) +{ + + //nTotTanks = tankGroup.members+tankDefGroup.members+toBeRepairedTankGroup.members+helpGroup.members; + //nTotCyborgs = cyborgDefGroup.members + cyborgAttGroup.members + toBeRepairedCyborgGroup.members; + local int _f,_c,_r,_v,_h,_l,_cc; + + _f = nFactories; + _r = nResLabs; + _c = nCybFact; + _v = nVTOLFactories; + _h = numStructsByType(playerHQ, player); + _l = numStructsByType(lassat, player); + _cc = numStructsByType(derrick, player); + + msg("Player #("& player &") colour("& getPlayerName(player) &") Game Time("& gameTime/10/60 &" min) Map Size("& mapWidth &"-"& mapHeight &") Defend Range("& nDefendRange/TILE &") Under attack("& alertIsOn &")", player, _player); + msg("Power:"& playerPower(player) &" Derricks:"& _cc &" Min base structures buit:"& lMinBaseStructBuilt &" alert is on("& alertIsOn &") alert level("& alertLevel &")", player, _player); + msg("Droids: Tot("& nTotTanks+nTotCyborgs &") Defending("& tankDefGroup.members+cyborgDefGroup.members &") Attacking("& tankGroup.members+cyborgAttGroup.members &") Helping("& helpGroup.members &") To be Repaired("& toBeRepairedCyborgGroup.members+toBeRepairedTankGroup.members &") ", player, _player); + msg("Structs: Factories("& _f &") ResLabs("& _r &") CybFactories("& _c &") VTOLFactories("& _v &") Lassat("& _l &") HQ("& _h &") ", player, _player); + msg("Team1 attack active("& bTankAttIsOn &") Team 1 target player ("& targetPlayerTank &") Team 2 attack active("& bCybAttIsOn &") Team 2 target player("& targetPlayerCyb &") ", player, _player); + msg("Have a beacon("& haveAnyBeacon() &") Player Helped("& nAllyBeingHelped &") Helping Droids("& helpGroup.members &")", player, _player); + +} +//----------------------------------------------------------------------------- +function void displayStats(int _choice) +{ + + local string _sPlPow, _sPlInf1,_sPlInf2,_sPlInf3, _strTeams, _sWallDef, _sDef; + local string _sRes, _sRes2, _str0, _str1, _str2, _str3, _str4, _str5, _sFort; + local int _totTanks, _HQx,_HQy,_tDG, _bg, _hg, _tg, _bdg, _ccG, _rg, _HelpG; + local int _cG, _totHarv, _enWeap, _myWeap, _myWeapSTR, _enemyCost, _friendCost; + local int _count,_count2; + + ASSERT(player >= 0 and player < 8, "player out of bounds: showPlayerInfo " & player, player); + + _count=0; + while ( _count < 11 ) + { + if ( oilResTargetId[_count] > -1 ){ + _totHarv++; + } + _count++; + } + + _bg = buildGroup.members; + _hg = harvesterGroup.members; + _rg = repairGroup.members; + _tg = tankGroup.members; + _bdg = buildDefGroup.members; + _ccG = cyborgConstructGroup.members; + _cG = cyborgDefGroup.members; + _tDG = tankDefGroup.members; + _HelpG = helpGroup.members; + _totTanks = MIN_ATTACKING_TANKS+nAttackingUnitsToAdd+minDefDroids[nAI_Pers][MINDEF_TANKS]; + + _enWeap = numEnemyWeapDroidsInRange(player,baseX, baseY, nBaseRange , false); + _myWeap = numPlayerWeapDroidsInRange(player, player, baseX, baseY, nBaseRange , true); + _myWeapSTR = numFriendlyWeapStructsInRange(player,baseX, baseY, nBaseRange, true); + + structure = getStructure(playerHQ, player); + if(structure != NULLOBJECT) + { + _HQx = structure.x; + _HQy = structure.y; + } else { + _HQx = 0; + _HQy = 0; + } + + _count = 0; + while ( _count < numWallWeaps ){ + _sWallDef = _sWallDef & " ["& _count &"]("& isStructureAvailable(wallWeaps[_count],player) &") "; + _count++; + } + _count = 0; + while ( _count < numDefStructs ){ + _sDef = _sDef & " ["& _count &"]("& isStructureAvailable(defStructs[_count],player) &") "; + _count++; + } + + _count = 0; + while ( _count < numFortressDef ){ + _sFort = _sFort & " ["& _count &"]("& isStructureAvailable(fortressDef[_count],player) &") "; + _count++; + } + + _count = 0; + while ( _count < 20){ + _str0 = _str0 & " ["& _count &"]"& numResearchLeft(player,research[0][_count]) &" "; + _count++; + } + while ( _count < 40){ + _str1 = _str1 & " ["& _count &"]"& numResearchLeft(player,research[0][_count]) &" "; + _count++; + } + while ( _count < numRes[0]){ + _str2 = _str2 & " ["& _count &"]"& numResearchLeft(player,research[0][_count]) &" "; + _count++; + } + + _count = 0; + while ( _count < 23){ + _str3 = _str3 & " ["& _count &"]"& numResearchLeft(player,research[1][_count]) &" "; + _count++; + } + while ( _count < numRes[1]){ + _str4 = _str4 & " ["& _count &"]"& numResearchLeft(player,research[1][_count]) &" "; + _count++; + } + + + _count = 0; + while ( _count < numCheapRes[0] ){ + _sRes2 = _sRes2 & " ["& _count &"]"& numResearchLeft(player,researchCheap[0][_count]) &" "; + _count++; + } + + _count = 0; + while ( _count < numRes[9] ){ + _str5 = _str5 & " ["& _count &"]"& numResearchLeft(player,research[9][_count]) &" "; + _count++; + } + + _count = 0; + while (_count < MAX_PLAYERS){ + if (isPlayerStillLive(_count)){ + _strTeams = _strTeams & " '"& getPlayerName(_count) &"'' #"& _count &" ["& aPlayers[TEAM_NUMBER][_count] &"] "; + } + _count++; + } + + _count=0; + while( _count < MAX_PLAYERS and _count < 3){ + if (isPlayerStillLive(_count)){ + _sPlInf1 = _sPlInf1 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + while( _count < MAX_PLAYERS and _count < 6 ){ + if (isPlayerStillLive(_count)){ + _sPlInf2 = _sPlInf2 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + while( _count < MAX_PLAYERS and _count < 8 ){ + if (isPlayerStillLive(_count)){ + _sPlInf3 = _sPlInf3 & " *["& getPlayerName(_count) &"] RL(" & aStat[OC_RESLABS][_count] & ") Der("& aStat[OC_DERRICKS][_count] &") Cy-Tk-VTOL("& aStat[OC_CYBORGS][_count] &"-"& aStat[OC_TANKS][_count] &"-"& aStat[OC_VTOLS][_count] &") Pow("& aStat[OC_CYB_POWER][_count] &"-"& aStat[OC_TK_POWER][_count] &"-"& aStat[OC_VTOL_POWER][_count] &") hp("& aStat[OC_CYB_HP][_count] &"-"& aStat[OC_TK_HP][_count] &"-"& aStat[OC_VTOL_HP][_count] &")"; + } + _count++; + } + + _count2=0; + while( _count2 < MAX_PLAYERS ){ + if (isPlayerStillLive(_count2)){ + _sPlPow = _sPlPow & " __"& getPlayerName(_count2) &" (" & getPowerIndex(_count2) & ")" ; + } + _count2++; + } + + _count = player; + if ( _choice == 1 ){ + dbg("dbg-> GameTime("& gameTime &") General("& AIPersonality &") AIstrength("& AIstrength &") gameType("& gameType() &") gameTime("& gameTime &") MAP("& mapWidth &"-"& mapHeight &") nBasRg("& nBaseRange/TILE &") gatRange("& gatewaysRangeTiles &") DefRange("& nDefendRange/TILE &") HQ("& _HQx/TILE &"-"& _HQy/TILE &") Base("& baseX/TILE &"-"& baseY/TILE &") arHarv("& _totHarv &") ",_count); + dbg("dbg-> Plyers: " & _strTeams & " nTeam("& nTeam &") nLastEnemyPlayer ("& nLastEnemyPlayer &") nEnemyPlayers ("& nEnemyPlayers &") nHumanPlayers("& nHumanPlayers &") nPlayersInGame("& nPlayersInGame &") nTotEnemyDroids("& nTotEnemyDroids &")", _count); + dbg("dbg-> bAnyOilResLeft("& bOilResLeft &") Harv("& _hg &") build("& _bg &") bDef"& _bdg &") cybConst("& _ccG &") _HelpG ("& _HelpG &") Tank("& _tg &") TankDef(" & _tDG & ") cybDef("& _cG &") cybAtt("& cyborgAttGroup.members &") CybRep("& toBeRepairedCyborgGroup.members &") TankRep("& toBeRepairedTankGroup.members &") VTOLdef("& vtolDefendGr.members &") VTOLatt("& vtolAttGr.members &")",_count); + dbg("dbg-> CybAttReq("& minDefDroids[nAI_Pers][MINDEF_CYBORGS]+MIN_ATT_CYBORGS+nCybAttUnitsToAdd &") TotCyb("& nTotCyborgs &") TankAttReq("& _totTanks &") TotTank("& nTotTanks &") help("& helpGroup.members &") alertIsOn ("& alertIsOn &") realGatew("& nRealGatewaysFound &") nAllyBeingHelped("& nAllyBeingHelped &") ",_count ); + dbg("dbg-> Cyborgs Built: (AR-AT-AP-KK)(Error) ("& nTotCybAR &" - "& nTotCybAT &" - "& nTotCybAP &" - "& nTotCybKK &")("& nTotCybErr &")",player); + dbg("dbg-> POWER ("& playerPower(0) &") ("& playerPower(1) &") ("& playerPower(2) &") ("& playerPower(3) &") ("& playerPower(4) &") ("& playerPower(5) &") ("& playerPower(6) &") ("& playerPower(7) &") DROID-LEFT ("& anyDroidsLeft(0) &")("& anyDroidsLeft(1) &")("& anyDroidsLeft(2) &")("& anyDroidsLeft(3) &")("& anyDroidsLeft(4) &")("& anyDroidsLeft(5) &")("& anyDroidsLeft(6) &")("& anyDroidsLeft(7) &") defSpotX/Y ("& defSpotX &"-"& defSpotY &") nTotOilInAtStart ("& nTotOilInAtStart &") ",_count); + + } + if ( _choice == 2 ){ + dbg("dbg-> Power: bNeedDerrick ("& bNeedDerrick &") bForceResPowUp("& bForceResPowUp &") numRemainingOilRes()("& nFreeOilRes &") " & _sPlPow, _count); + dbg("dbg-> Info : " & _sPlInf1,_count); + dbg("dbg-> Info : " & _sPlInf2,_count); + dbg("dbg-> Info : " & _sPlInf3,_count); + dbg("dbg-> Tank Attack: tTKSentToGath ("& tTanksSentToGathering &") bTankAttIsOn ("& bTankAttIsOn &") lTKSentToGathPt ("& lTankSentToGatheringPoint &") bTKAlreadyGathered ("& bTankAlreadyGathered &") tankAttackX-Y ("& tankAttackY/TILE &"-"& tankAttackY/TILE &") targetPlTK ("& targetPlayerTank &") targetPlCyb("& targetPlayerCyb &") AttHumanPl("& nAttHumanPlayer &") AttAI("& nAttAIPlayer &")",_count); + } + if ( _choice == 3 ){ + dbg("dbg-> Standard Defe: Depth("& pickDefQueueDepth &") - " & _sDef, _count ); + dbg("dbg-> Wall Defences: Depth("& pickWallDefQueueDepth &") - "& _sWallDef, _count ); + dbg("dbg-> Fortresses: Depth("& pickFortQueueDepth &") - "& _sFort, _count); + dbg("dbg-> Res: " & _str0, _count); + dbg("dbg-> Res: " & _str1, _count); + dbg("dbg-> Res: " & _str2, _count); + dbg("dbg-> Res: " & _str3, _count); + dbg("dbg-> Res: " & _str4, _count); + dbg("dbg-> Cheap Res: "& numCheapRes[0] & " " & _sRes2, _count); + dbg("dbg-> VTOL Res: "& _str5,_count); + dbg("dbg-> lMinBaseStructBuilt("& lMinBaseStructBuilt &") Working Lab("& nWorkingLab &") Fact("& nWorkingFact &") Cyb("& nWorkingCybFac &") ", _count); + } + +} +//----------------------------------------------------------------------------- +function bool isPlayerStillLive(int _player) +{ + if ( anyDroidsLeft(_player) or anyFactoriesLeft(_player) ){ + return true; + } + return false; +} +//----------------------------------------------------------------------------- +function void checkIfDroidIsStuck(GROUP _group) +{ + + //displayMsg("checkIfDroidIsStuck: time("& gameTime &")"); + local int _x,_y,_dist,_rnd; + //Search for stucked droids + initIterateGroup(_group); + droid = iterateGroup(_group); + while(droid != NULLOBJECT) + { + if(!droidOrderIdle(droid)){ + + if ( !hasCoordStored(droid) ){ + //displayMsg("checkIfDroidIsStuck: droid ("& droid.id &") store coord in x("& droid.x/TILE &") y("& droid.y/TILE &") buildx("& droid.orderx/TILE &") buildx("& droid.ordery/TILE &") time("& gameTime &")"); + storeDroidCoord(droid); + } else { + + if ( coordChanged(droid) ){ + _dist = distBetweenTwoPoints(droid.x,droid.y,droid.orderx,droid.ordery); + //displayMsg("checkIfDroidIsStuck: droid ("& droid.id &") MOVES dist("& _dist/TILE &") pos("& droid.x/TILE &"-"& droid.y/TILE &") build("& droid.orderx/TILE &"-"& droid.ordery/TILE &") time("& gameTime &")"); + updateDroidCoord(droid); + + } else { + _dist = distBetweenTwoPoints(droid.x,droid.y,droid.orderx,droid.ordery); + if ( _dist < 3*TILE ){ + //displayMsg("checkIfDroidIsStuck: droid ("& droid.id &") BUILDS dist("& _dist/TILE &") pos("& droid.x/TILE &"-"& droid.y/TILE &") buildx("& droid.orderx/TILE &"-"& droid.ordery/TILE &") time("& gameTime &")"); + cleanDroidPos(droid.id);//this is a necessary hack to avoid wrong stuck + } else { + if ( incrementDroidCounter(droid.id) ){ + //dbg("dbg->checkIfDroidIsStuck: droid ("& droid.id &") IS *****STUCK******* dist("& _dist/TILE &") pos("& droid.x/TILE &"-"& droid.y/TILE &") buildx("& droid.orderx/TILE &"-"& droid.ordery/TILE &") time("& gameTime &")",player); + orderDroid(droid, DORDER_RUN); + /* + _rnd = random(4); + if ( _rnd == 0 ){ _x = droid.x + 4*TILE; _y=droid.y + 4*TILE; } + if ( _rnd == 1 ){ _x = droid.x - 4*TILE; _y=droid.y + 4*TILE; } + if ( _rnd == 2 ){ _x = droid.x + 4*TILE; _y=droid.y - 4*TILE; } + if ( _rnd == 3 ){ _x = droid.x - 4*TILE; _y=droid.y - 4*TILE; } + if ( _x < 0 ) { _x = 2*TILE; } + if ( _y < 0 ) { _y = 2*TILE; } + if ( _x > mapWidth*TILE ) { _x = mapWidth*TILE-(2*TILE); } + if ( _y > mapHeight*TILE ) { _y = mapHeight*TILE-(2*TILE); } + if( !droidCanReach(droid, _x ,_y) ){ + if ( pickStructLocation(powGen, ref _x, ref _y, player) ){ + //dbg("dbg->checkIfDroidIsStuck: 1-Moving droid ("& droid.id &") to("& _x/TILE &"-"& _y/TILE &") time("& gameTime &")",player); + orderDroidLoc(droid, DORDER_MOVE, _x, _y); + } + } else { + //dbg("dbg->checkIfDroidIsStuck: 2-Moving droid ("& droid.id &") to("& _x/TILE &"-"& _y/TILE &") time("& gameTime &")",player); + orderDroidLoc(droid, DORDER_MOVE, _x, _y); + } + */ + } //else { displayMsg("checkIfDroidIsStuck: droid ("& droid.id &") is possibly **STUCK** dist("& _dist/TILE &") pos("& droid.x/TILE &"-"& droid.y/TILE &") buildx("& droid.orderx/TILE &"-"& droid.ordery/TILE &") time("& gameTime &")"); } + + } + + } + } + + } else { + //displayMsg("checkIfDroidIsStuck: droid ("& droid.id &") is idle in x("& droid.x/TILE &") y("& droid.y/TILE &") time("& gameTime &")"); + cleanDroidPos(droid.id);//put all to -1 + } + droid = iterateGroup(_group); + } + return; +} +//----------------------------------------------------------------------------- +function bool incrementDroidCounter(int droid_id) +{ + local int _c; + _c = 0; + while ( _c < num_aDroid ) + { + if (aDroid_Id[_c] == droid_id ){ + aDroid_counter[_c] = aDroid_counter[_c] + 1; + if ( aDroid_counter[_c] > 1 ){ return true; } else { return false;} + } + _c++; + } + + //dbg("dbg->incrementDroidCounter: Error! droid ("& droid_id &") not found",player); + return false; +} +//----------------------------------------------------------------------------- +function void cleanDroidCoordArray() +{ + local int _c; + _c = 0; + while ( _c < num_aDroid ) + { + + boolResult = false; + initIterateGroup(buildGroup); + droid = iterateGroup(buildGroup); + while(droid != NULLOBJECT) + { + if ( aDroid_Id[_c] == droid.id ){ + boolResult = true; + } + droid = iterateGroup(buildGroup); + } + + initIterateGroup(buildDefGroup); + droid = iterateGroup(buildDefGroup); + while(droid != NULLOBJECT) + { + if ( aDroid_Id[_c] == droid.id ){ + boolResult = true; + } + droid = iterateGroup(buildDefGroup); + } + + initIterateGroup(harvesterGroup); + droid = iterateGroup(harvesterGroup); + while(droid != NULLOBJECT) + { + if ( aDroid_Id[_c] == droid.id ){ + boolResult = true; + } + droid = iterateGroup(harvesterGroup); + } + + if ( !boolResult ){ + cleanDroidPos(aDroid_Id[_c]); + } + + _c++; + } + + + return; +} +//----------------------------------------------------------------------------- +function void cleanDroidPos(int _droidId) +{ + local int _c; + _c = 0; + while ( _c < num_aDroid ) + { + if ( aDroid_Id[_c] == _droidId ){ + aDroid_Id[_c] = -1; + aDroid_X[_c] = -1; + aDroid_Y[_c] = -1; + aDroid_counter[_c] = 0; + } + _c++; + } +} + +//----------------------------------------------------------------------------- +function void storeDroidCoord(DROID _droid) +{ + local int _c; + _c = getFreePosDroid(); + if ( _c == -1 ){ _c = 49-random(10); } //hack + aDroid_Id[_c] = droid.id; + aDroid_X[_c] = droid.x; + aDroid_Y[_c] = droid.y; +} +//----------------------------------------------------------------------------- +function void updateDroidCoord(DROID _droid) +{ + local int _c; + _c = 0; + while ( count < num_aDroid ) + { + if ( aDroid_Id[_c] == _droid.id ){ + aDroid_Id[_c] = droid.id; + aDroid_X[_c] = droid.x; + aDroid_Y[_c] = droid.y; + return; + } + _c++; + } + //it is ok if the droid has not been found because positions are resetted + //for droid not idle + storeDroidCoord(_droid); + return; +} + +//----------------------------------------------------------------------------- +function bool coordChanged(DROID _droid) +{ + local int _c,_c2; + _c = 0; + while ( _c < num_aDroid ) + { + if ( aDroid_Id[_c] == _droid.id ){ + _c2 = distBetweenTwoPoints(_droid.x,_droid.y,aDroid_X[_c],aDroid_Y[_c]); + if ( _c2 > 2*TILE ){ + //displayMsg("coordChanged: TRUE droid ("& droid.id &") _c2("& _c2 &")>("& 2*TILE &") "); + return true; + } else { + //displayMsg("coordChanged: FALSE droid ("& droid.id &") _c2("& _c2 &")>("& 2*TILE &") "); + return false; + } + } + _c++; + } + //dbg("dbg->coordChanged: Error! droid ("& _droid.id &") not found",player); + return true; +} +//----------------------------------------------------------------------------- +function bool hasCoordStored(DROID _droid) +{ + local int _c; + _c = 0; + while ( _c < num_aDroid ) + { + if ( aDroid_Id[_c] == _droid.id ){ + return true; + } + _c++; + } + return false; +} +//----------------------------------------------------------------------------- +function int getFreePosDroid() +{ + local int _c; + _c = 0; + while ( _c < num_aDroid ) + { + if ( aDroid_Id[_c] == -1 ){ return _c; } + _c++; + } + //dbg("dbg->getFreePosDroid: player("& player &") free pos not found!! ("& _c &")",player); + return -1; +} +//-------------------------------------------------------------------- +function int numStructinRange(STRUCTURESTAT _struct, int _player, int _xCoord, int _yCoord, int _Range) +{ + local int _nTot; + local STRUCTURE _structure; + + _nTot = 0; + + initEnumStruct(FALSE,_struct,_player,_player); + _structure = enumStruct(); + while(_structure != NULLOBJECT) + { + if ( distBetweenTwoPoints(_xCoord,_yCoord,_structure.x,_structure.y) <= _Range ) { _nTot++; } + _structure = enumStruct(); + } + + return _nTot; + +} +//-------------------------------------------------------------------- +function void printDebug( STRING _message ) +{ + if ( _DEBUG ){ + debug( GAME_TIME_IN_MIN &"min; "& getPlayerName(player) &" #"& player &" ["& AIPersonality &"-"& AIstrength &"] ;0 ;" & _message); + } +} +//-------------------------------------------------------------------- +function void printDebug1( STRING _message ) +{ + if ( _DEBUG1 ){ + debug( GAME_TIME_IN_MIN &"min; "& getPlayerName(player) &" #"& player &" ["& AIPersonality &"-"& AIstrength &"] ;1 ;" & _message); + } +} +//-------------------------------------------------------------------- +// form alliances between AIs +function bool createAIalliance(int _player1, int _player2) +{ + + if (!isPlayerStillLive(_player1) or !isPlayerStillLive(_player2)){ + //dbg("dbg->createAIalliance: cannot ally as one or both players are not live",player); + return false; + } + + if( isHumanPlayer(_player1) or isHumanPlayer(_player1) ) { + //dbg("dbg->createAIalliance: cannot ally as one or both players are human",player); + return false; + } + + if( allianceExistsBetween(_player1, _player2) ){ + //dbg("dbg->createAIalliance: players are already allied",player); + return false; + } + + createAlliance(_player1,_player2); + notifyAll("-----------------------------------------------"); + notifyAll("Alliance created between AIs: '"& getPlayerName(_player1) &"' '"& getPlayerName(_player2) &"'"); + notifyAll("-----------------------------------------------"); + + printDebug1("createAIalliance: Alliance created between AIs '"& getPlayerName(_player1) &"' '"& getPlayerName(_player2) &"'"); + + return true; +} +//-------------------------------------------------------------------- +function STRUCTURESTAT getDefStruct() +{ + + local STRUCTURESTAT _defstruct; + local int _nDef,_n,_rnd; + + _n = min(pickDefQueueDepth,3); + _nDef = pickDefQueueDepth - 1 - random(_n);//best 3 defences + _defstruct = pickDefQueue[_nDef]; + + //=========== STANDARD DEFENCES ================================== + if ( random(100) < 35 or pickWallDefQueueDepth < 2 ){ + + if ( pickDefQueueDepth < 7 ){ + _rnd = _random(100); + //build mainly HMGhardPoint/MGbunker, LancerTower/miniRocketTower + if ( _rnd < 40 ){ + if (isStructureAvailable(HMGhardPoint,player)){ + _defstruct = HMGhardPoint; + } else { + if (isStructureAvailable(MGbunker,player)){ + _defstruct = MGbunker; + } + } + } + if ( _rnd >= 40 and _rnd < 70 ) { + if (isStructureAvailable(LancerTower,player)){ + _defstruct = LancerTower; + } else { + if (isStructureAvailable(miniRocketTower,player)){ + _defstruct = miniRocketTower; + } else { + if (isStructureAvailable(MGbunker,player)){ + _defstruct = MGbunker; + } + } + } + } + } + + + } else { //=========== WALL DEFENCES ================================== + + if(pickWallDefQueueDepth > 0)//best 4 def + { + _n = min(pickWallDefQueueDepth,4); + _nDef = pickWallDefQueueDepth - 1 - _random(_n); + _defstruct = pickWallDefQueue[_nDef]; + } + + } + + return _defstruct; +} +//----------------------------------------------------------------------------- +//only droids with order != build are taken into account +function DROID closestDroidCanBuild(GROUP _group, int _x, int _y) +{ + local DROID _closestTruck,_tempTruck; + local int _closestDist,_tempDist; + + _closestTruck = NULLOBJECT; + _closestDist = 999*TILE; + + if (_group.members == 0){ return _closestTruck; } + + initIterateGroup(_group); + _tempTruck = iterateGroup(_group); + while(_tempTruck != NULLOBJECT) + { + if( _tempTruck.order != DORDER_BUILD ) + { + _tempDist = distBetweenTwoPoints(_x, _y, _tempTruck.x, _tempTruck.y); + if(_tempDist < _closestDist) + { + _closestDist = _tempDist; + _closestTruck = _tempTruck; + } + } + _tempTruck = iterateGroup(_group); + } + return _closestTruck; +} +//----------------------------------------------------------------------------- +function DROID closestIdleDroid(GROUP _group, int _x, int _y) +{ + local DROID _closestTruck,_tempTruck; + local int _closestDist,_tempDist; + + _closestTruck = NULLOBJECT; + _closestDist = 999*TILE; + + if (_group.members == 0){ return _closestTruck; } + + initIterateGroup(_group); + _tempTruck = iterateGroup(_group); + while(_tempTruck != NULLOBJECT) + { + if( droidOrderIdle(_tempTruck) ) + { + _tempDist = distBetweenTwoPoints(_x, _y, _tempTruck.x, _tempTruck.y); + if(_tempDist < _closestDist) + { + _closestDist = _tempDist; + _closestTruck = _tempTruck; + } + } + _tempTruck = iterateGroup(_group); + } + return _closestTruck; +} +//------------------------------------------------------------------------ +function bool buildHeavyTank( int _nWeapon, STRUCTURE _struct ) +{ + + local int _n, _pos, _nChoice; + local int _tmpl[15]; + + _n = 0; + while ( _n < 15 ){ + _tmpl[_n] = -1; + _n++ ; + } + + _n = 0; + _pos = -1; + + if ( _nWeapon == WEAPON_AP ){ + if( skCanBuildTemplate(player,_struct, tmpl0[46]) ){ _tmpl[_n] = 46; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[44]) ){ _tmpl[_n] = 44; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[21]) ){ _tmpl[_n] = 21; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[20]) ){ _tmpl[_n] = 20; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[9]) ){ _tmpl[_n] = 9; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[8]) ){ _tmpl[_n] = 8; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[3]) ){ _tmpl[_n] = 3; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[2]) ){ _tmpl[_n] = 2; _n++; } + } + if ( _nWeapon == WEAPON_AT ){ + if( skCanBuildTemplate(player,_struct, tmpl0[48]) ){ _tmpl[_n] = 48; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[47]) ){ _tmpl[_n] = 47; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[23]) ){ _tmpl[_n] = 23; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[22]) ){ _tmpl[_n] = 22; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[11]) ){ _tmpl[_n] = 11; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[10]) ){ _tmpl[_n] = 10; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[5]) ) { _tmpl[_n] = 5; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[4]) ) { _tmpl[_n] = 4; _n++; } + } + if ( _nWeapon == WEAPON_AR ){ + if( skCanBuildTemplate(player,_struct, tmpl0[43]) ){ _tmpl[_n] = 43; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[42]) ){ _tmpl[_n] = 42; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[41]) ){ _tmpl[_n] = 41; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[40]) ){ _tmpl[_n] = 40; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[36]) ){ _tmpl[_n] = 36; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[35]) ){ _tmpl[_n] = 35; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[34]) ){ _tmpl[_n] = 34; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[19]) ){ _tmpl[_n] = 19; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[18]) ){ _tmpl[_n] = 18; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[7]) ) { _tmpl[_n] = 7; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[6]) ) { _tmpl[_n] = 6; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[1]) ) { _tmpl[_n] = 1; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[0]) ) { _tmpl[_n] = 0; _n++; } + } + + //dbg("buildHeavyTank: _tmpl[0]("& _tmpl[0] &") _tmpl[1]("& _tmpl[1] &") _tmpl[2]("& _tmpl[2] &") _n("& _n &") < 0 !!! ",player); + printDebug1("buildHeavyTank: _tmpl[0]("& _tmpl[0] &") _tmpl[1]("& _tmpl[1] &") _tmpl[2]("& _tmpl[2] &") _n("& _n &") < 0 !!! "); + if ( _n == 0 ){ + printDebug1("#### buildHeavyTank: error ! _nWeapon("& _nWeapon &") _n("& _n &") < 0 !!! "); + return false; + } + + if ( _n > 2 ) { _pos = (_n - 1) - random(3); } + if ( _n == 2 ){ _pos = random(2); } + if ( _n == 1 ){ _pos = 0; } + + _nChoice = _tmpl[_pos]; + + if( skCanBuildTemplate( player , _struct , tmpl0[_nChoice]) ){ + //dbg("buildHeavyTank: build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")",player); + printDebug1("buildHeavyTank: build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")"); + buildDroid( tmpl0[_nChoice] , _struct, player, 1); + return true; + } else { + //dbg("#### buildHeavyTank: could not build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")",player); + printDebug1("#### buildHeavyTank: could not build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")"); + return false; + } + return false; +} +//------------------------------------------------------------------------ +function bool buildMediumTank( int _nWeapon, STRUCTURE _struct ) +{ + + local int _n, _pos, _nChoice; + local int _tmpl[15]; + + _n = 0; + while ( _n < 15 ){ + _tmpl[_n] = -1; + _n++; + } + + _n = 0; + _pos = -1; + + if ( _nWeapon == WEAPON_AP ){ + if( skCanBuildTemplate(player,_struct, tmpl0[53]) ){ _tmpl[_n] = 53; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[50]) ){ _tmpl[_n] = 50; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[49]) ){ _tmpl[_n] = 49; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[38]) ){ _tmpl[_n] = 38; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[27]) ){ _tmpl[_n] = 27; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[26]) ){ _tmpl[_n] = 26; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[15]) ){ _tmpl[_n] = 15; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[14]) ){ _tmpl[_n] = 14; _n++; } + } + if ( _nWeapon == WEAPON_AT ){ + if( skCanBuildTemplate(player,_struct, tmpl0[56]) ){ _tmpl[_n] = 56; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[55]) ){ _tmpl[_n] = 55; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[54]) ){ _tmpl[_n] = 54; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[39]) ){ _tmpl[_n] = 39; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[29]) ){ _tmpl[_n] = 29; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[28]) ){ _tmpl[_n] = 28; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[17]) ){ _tmpl[_n] = 17; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[16]) ){ _tmpl[_n] = 16; _n++; } + } + if ( _nWeapon == WEAPON_AR ){ + if( skCanBuildTemplate(player,_struct, tmpl0[52]) ){ _tmpl[_n] = 52; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[51]) ){ _tmpl[_n] = 51; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[37]) ){ _tmpl[_n] = 37; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[25]) ){ _tmpl[_n] = 25; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[24]) ){ _tmpl[_n] = 24; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[13]) ){ _tmpl[_n] = 13; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[12]) ){ _tmpl[_n] = 12; _n++; } + } + + //dbg("buildMediumTank: _tmpl[0]("& _tmpl[0] &") _tmpl[1]("& _tmpl[1] &") _tmpl[2]("& _tmpl[2] &") _n("& _n &") < 0 !!! ",player); + printDebug1("buildMediumTank: _tmpl[0]("& _tmpl[0] &") _tmpl[1]("& _tmpl[1] &") _tmpl[2]("& _tmpl[2] &") _n("& _n &") < 0 !!! "); + if ( _n == 0 ){ + printDebug1("#### buildMediumTank: error ! _nWeapon("& _nWeapon &") _n("& _n &") < 0 !!! "); + return false; + } + + if ( _n > 2 ) { _pos = (_n - 1) - random(3); } + if ( _n == 2 ){ _pos = random(2); } + if ( _n == 1 ){ _pos = 0; } + + _nChoice = _tmpl[_pos]; + + if( skCanBuildTemplate( player , _struct , tmpl0[_nChoice]) ){ + //dbg("buildMediumTank: build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")",player); + printDebug1("buildMediumTank: build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")"); + buildDroid( tmpl0[_nChoice] , _struct, player, 1); + return true; + } else { + printDebug1("#### buildMediumTank: could not build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")"); + return false; + } + return false; + +} +//------------------------------------------------------------------------ +function bool buildLightTank( int _nWeapon, STRUCTURE _struct ) +{ + + local int _n, _pos, _nChoice; + local int _tmpl[15]; + + _n = 0; + while ( _n < 15 ){ + _tmpl[_n] = -1; + _n++ ; + } + + _n = 0; + _pos = -1; + + if ( _nWeapon == WEAPON_AP ){ + if( skCanBuildTemplate(player,_struct, tmpl0[62]) ){ _tmpl[_n] = 62; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[61]) ){ _tmpl[_n] = 61; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[60]) ){ _tmpl[_n] = 60; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[33]) ){ _tmpl[_n] = 33; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[32]) ){ _tmpl[_n] = 32; _n++; } + } + if ( _nWeapon == WEAPON_AT ){ + if( skCanBuildTemplate(player,_struct, tmpl0[58]) ){ _tmpl[_n] = 58; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[57]) ){ _tmpl[_n] = 57; _n++; } + } + if ( _nWeapon == WEAPON_AR ){ + if( skCanBuildTemplate(player,_struct, tmpl0[59]) ){ _tmpl[_n] = 59; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[31]) ){ _tmpl[_n] = 31; _n++; } + if( skCanBuildTemplate(player,_struct, tmpl0[30]) ){ _tmpl[_n] = 30; _n++; } + } + + //dbg("buildLightTank: _tmpl[0]("& _tmpl[0] &") _tmpl[1]("& _tmpl[1] &") _tmpl[2]("& _tmpl[2] &") _n("& _n &") < 0 !!! ",player); + printDebug1("buildLightTank: _tmpl[0]("& _tmpl[0] &") _tmpl[1]("& _tmpl[1] &") _tmpl[2]("& _tmpl[2] &") _n("& _n &") !!! "); + if ( _n == 0 ){ + printDebug1("#### buildLightTank: error ! _nWeapon("& _nWeapon &") _n("& _n &") < 0 !!! "); + return false; + } + + if ( _n > 2 ) { _pos = (_n - 1) - random(3); } + if ( _n == 2 ){ _pos = random(2); } + if ( _n == 1 ){ _pos = 0; } + + _nChoice = _tmpl[_pos]; + + if( skCanBuildTemplate( player , _struct , tmpl0[_nChoice]) ){ + //dbg("buildLightTank: build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")",player); + printDebug1("buildLightTank: build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")"); + buildDroid( tmpl0[_nChoice] , _struct, player, 1); + return true; + } else { + printDebug1("#### buildLightTank: could not build template _nWeapon("& _nWeapon &") _nChoice("& _nChoice &") _pos("& _pos &") _n("& _n &")"); + return false; + } + return false; + +} +//--------------------------------------------------------------------------- +function int checkBestBody(int _nBody, int _nWeapon, STRUCTURE _struct ) +{ + local int _i; + + _i = 0; + if ( _nBody == BODY_HEAVY ){ + if ( _nWeapon == WEAPON_AP ){ + if( skCanBuildTemplate(player,_struct, tmpl0[46]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[45]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[44]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[21]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[20]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[9]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[8]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[3]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[2]) ){ _i++; } + } + if ( _nWeapon == WEAPON_AR ){ + if( skCanBuildTemplate(player,_struct, tmpl0[43]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[42]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[41]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[40]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[36]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[35]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[34]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[19]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[18]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[7]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[6]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[1]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[0]) ){ _i++; } + } + if ( _nWeapon == WEAPON_AT ){ + if( skCanBuildTemplate(player,_struct, tmpl0[48]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[47]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[23]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[22]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[11]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[10]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[5]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[4]) ){ _i++; } + } + } + if ( _nBody == BODY_MEDIUM ){ + if ( _nWeapon == WEAPON_AP ){ + if( skCanBuildTemplate(player,_struct, tmpl0[53]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[50]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[49]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[38]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[27]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[26]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[15]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[14]) ){ _i++; } + } + if ( _nWeapon == WEAPON_AR ){ + if( skCanBuildTemplate(player,_struct, tmpl0[52]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[51]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[37]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[25]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[24]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[13]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[12]) ){ _i++; } + } + if ( _nWeapon == WEAPON_AT ){ + if( skCanBuildTemplate(player,_struct, tmpl0[56]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[55]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[54]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[39]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[29]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[28]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[17]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[16]) ){ _i++; } + } + } + if ( _nBody == BODY_LIGHT ){ + if ( _nWeapon == WEAPON_AP ){ + if( skCanBuildTemplate(player,_struct, tmpl0[62]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[61]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[60]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[33]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[32]) ){ _i++; } + } + if ( _nWeapon == WEAPON_AR ){ + if( skCanBuildTemplate(player,_struct, tmpl0[59]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[31]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[30]) ){ _i++; } + } + if ( _nWeapon == WEAPON_AT ){ + if( skCanBuildTemplate(player,_struct, tmpl0[58]) ){ _i++; } + if( skCanBuildTemplate(player,_struct, tmpl0[57]) ){ _i++; } + } + } + printDebug1("checkBestBody: _i("& _i &") _nBody("& _nBody &") _nWeapon("& _nWeapon &")"); + return _i; +} + diff --git a/data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.vlo b/data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.vlo new file mode 100644 index 000000000..b1a1a8f43 --- /dev/null +++ b/data/mods/multiplay/dydo-ai/multiplay/skirmish/ai.vlo @@ -0,0 +1,1632 @@ +///////////////////////////////////////////////////////////////////// +// DyDo-AI +// Generic vlo for each computer player - skirmish games +///////////////////////////////////////////////////////////////////// + +script "ai.slo" +run +{ + player INT 0 + +// Version 2.1 +// the version of the .vlo files is not related to the one of the .slo files +// +// +// AI mod developer DylanDog +// AI webpage: http://www.obooma.net/dydo/ +/////////////////////////////////////// +// +// THIS FILE STORES DATA AND CONSTANT VARIABLES +// +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+*+*+ DyDo-AI AI SETTINGS (modify number variables and TRUE/FALSE) *+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* + + //AI too strong ?? enable this and use the slider while you create a new game + //SLIDER MODE + EnableSliders BOOL true //<-- edit this value + + //AI CONTROLS HUMAN BASE + //AIControl BOOL false //<-- edit this value + + //CHANGE AI Personality + AIPersonality int 0 //<-- edit this value + + //SHOW AI Personality + showAIPersonality bool true //<-- edit this value + + //AI strenght + AIstrength int 0 //<-- edit this value + +// -------->>> MODIFICATION MANUAL: +/*--------------------------------------------------------------- + +EnableSliders - SLIDER MODE: + TRUE enables sliders - Apply the frontend slider settings. + FALSE disables sliders - Frontend slider settings are deactivated. + + +AIControl - ALLOW AI TO CONTROL HUMAN BASE: + TRUE enables AI control over your base + FALSE disables AI control over your base + +AIPersonality - CHANGE AI Personality + 0 - Random personality {General x} + 1 - General 1 personality {Standard AI} + 2 - General 2 personality {AI prioritizes use, production and research of VTOLs stuffs} + 3 - General 3 personality {Turtle AI} + 4 - General 4 personality {Cyborg AI} + +AIstrenght - CHANGE DYDO STRENGHT, it affects game difficulty in 4 and 8 players games + 2 players gaems are not affected by this (yet!). + 0 - random + 1 - standard + 2 - a bit stronger + 3 - stronger + 4 - hard + 5 - really hard + +// + +//////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +*/ + +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* +//+*+ DO NOT EDIT BELOW THIS LINE (for AI experts and mod developers ONLY) *+*+*+*+*+*+* +//+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* + + + + //long Range Cyborgs + cybGren WEAPON "Cyb-Wpn-Grenade" + cybLancer WEAPON "CyborgRocket" + cybScourge WEAPON "Cyb-Wpn-Atmiss" + cybSuperHPV WEAPON "Cyb-Hvywpn-HPV" + cybSuperScourge WEAPON "Cyb-Hvywpn-A-T" + cybTankKiller WEAPON "Cyb-Hvywpn-TK" + + /* + xxxxx WEAPON "xxxxx" + xxxxx WEAPON "xxxxx" + xxxxx WEAPON "xxxxx" + xxxxx WEAPON "xxxxx" + */ + //Short Range Tank Weapons + MGun WEAPON "MG1Mk1" + TwinMGun WEAPON "MG2Mk1" + HMGun WEAPON "MG3Mk1" + TwinAGun WEAPON "MG5TWINROTARY" + AGun WEAPON "MG4ROTARYMk1" + Flamer WEAPON "Flame1Mk1" + PlasmFlamer WEAPON "PlasmiteFlamer" + Inferno WEAPON "Flame2" + NeedleGun WEAPON "RailGun1Mk1" + RailGun WEAPON "RailGun2Mk1" + GaussCannon WEAPON "RailGun3Mk1" + PlasmaCannon WEAPON "Laser4-PlasmaCannon" + EMPCannon WEAPON "EMP-Cannon" + LCannon WEAPON "Cannon1Mk1" + MCannon WEAPON "Cannon2A-TMk1" + ACannon WEAPON "Cannon5VulcanMk1" + HCannon WEAPON "Cannon375mmMk1" + TACannon WEAPON "Cannon6TwinAslt" + //Long Range Tank Weapons + HVCannon WEAPON "Cannon4AUTOMk1" + RocketPod WEAPON "Rocket-Pod" + RocketMRL WEAPON "Rocket-MRL" + Lancer WEAPON "Rocket-LtA-T" + RocketBB WEAPON "Rocket-BB" + TankKiller WEAPON "Rocket-HvyA-T" + RippleRockets WEAPON "Rocket-IDF" + ScourgeMissle WEAPON "Missile-A-T" + SeraphMissile WEAPON "Missile-MdArt" + ArchangelMissile WEAPON "Missile-HvyArt" + FlashLight WEAPON "Laser3BEAMMk1" + PulseLaser WEAPON "Laser2PULSEMk1" + HeavyLaser WEAPON "HeavyLaser" + + + HoverProp PROPULSION "hover01" + TrackedProp PROPULSION "tracked01" + Half_Track PROPULSION "HalfTrack" + Viper BODY "Body1REC" + + // structures + + // generic names, often used. + oilRes FEATURESTAT "OilResource" + resLab STRUCTURESTAT "A0ResearchFacility" + powGen STRUCTURESTAT "A0PowerGenerator" + factory STRUCTURESTAT "A0LightFactory" + derrick STRUCTURESTAT "A0ResourceExtractor" + cybFactory STRUCTURESTAT "A0CyborgFactory" + playerHQ STRUCTURESTAT "A0CommandCentre" + vtolPad STRUCTURESTAT "A0VtolPad" + vtolFactory STRUCTURESTAT "A0VTolFactory1" + repairFacility STRUCTURESTAT "A0RepairCentre3" + uplinkCenter STRUCTURESTAT "A0Sat-linkCentre" + lassat STRUCTURESTAT "A0LasSatCommand" + demAnomallyFix STRUCTURESTAT "A0ADemolishStructure" + + powModule STRUCTURESTAT "A0PowMod1" + facModule STRUCTURESTAT "A0FacMod1" + resModule STRUCTURESTAT "A0ResearchModule1" + miniRocketTower STRUCTURESTAT "GuardTower6" + LancerTower STRUCTURESTAT "GuardTower5" + HMGhardPoint STRUCTURESTAT "WallTower01" + MGbunker STRUCTURESTAT "PillBox1"//Machinegun Bunker $100 + + //indirect weapons + resCBSense RESEARCHSTAT "R-Sys-CBSensor-Tower01" + mortarPit RESEARCHSTAT "R-Wpn-Mortar01Lt" + bombardPit RESEARCHSTAT "R-Wpn-Mortar02Hvy" + pepperpotPit RESEARCHSTAT "R-Wpn-Mortar3" + rippleRockets RESEARCHSTAT "R-Wpn-Rocket06-IDF" + sensorTower STRUCTURESTAT "Sys-SensoTower02" + CBSense STRUCTURESTAT "Sys-CB-Tower01" + defMortar STRUCTURESTAT "Emplacement-MortarPit01" //Mortar Pit [range 9-18] + defBombard STRUCTURESTAT "Emplacement-MortarPit02" //Bombard Pit [range 9-18] + defPepperpot STRUCTURESTAT "Emplacement-RotMor" //*Pepperpot Pit [range 9-18] + defRippleRockets STRUCTURESTAT "Emplacement-Rocket06-IDF" //*Ripple Rockets Battery [range 8-86] + + NEXUS_WEAPON1 WEAPON "NEXUSlink" + NEXUS_WEAPON2 WEAPON "SpyTurret01" + + cyborgPropulsion PROPULSION "CyborgLegs" + + lancerATweap RESEARCHSTAT "R-Wpn-Rocket01-LtAT" //Lancer + + nexusDefence RESEARCHSTAT "R-Sys-Resistance-Circuits" + powerAddOn RESEARCHSTAT "R-Struc-Power-Upgrade03a" + CyborgLegs RESEARCHSTAT "R-Cyborg-Legs01" + VTOLPadRes RESEARCHSTAT "R-Struc-VTOLPad" + AASite RESEARCHSTAT "R-Defense-AASite-QuadBof"//Cyclone AA Site + HurricaneAASite RESEARCHSTAT "R-Defense-AASite-QuadMg1" //Hurricane AA Site + CycloneAASite RESEARCHSTAT "R-Defense-AASite-QuadBof" + WhirlwindAASite RESEARCHSTAT "R-Defense-AASite-QuadRotMg" + + cobraBody RESEARCHSTAT "R-Vehicle-Body05" + phytonBody RESEARCHSTAT "R-Vehicle-Body11" + scorpionBody RESEARCHSTAT "R-Vehicle-Body08" + mantisBody RESEARCHSTAT "R-Vehicle-Body12" + leopardBody RESEARCHSTAT "R-Vehicle-Body02" + pantherBody RESEARCHSTAT "R-Vehicle-Body06" + tigerBody RESEARCHSTAT "R-Vehicle-Body09" + retaliationBody RESEARCHSTAT "R-Vehicle-Body03" + retributionBody RESEARCHSTAT "R-Vehicle-Body07" + vengeanceBody RESEARCHSTAT "R-Vehicle-Body10" + wyvernBody RESEARCHSTAT "R-Vehicle-Body13" + dragonBody RESEARCHSTAT "R-Vehicle-Body14" + + mediumCannon RESEARCHSTAT "R-Wpn-Cannon2Mk1" + heavyCannon RESEARCHSTAT "R-Wpn-Cannon3Mk1" + + trackPropulsion RESEARCHSTAT "R-Vehicle-Prop-Tracks" + hoverPropulsion RESEARCHSTAT "R-Vehicle-Prop-Hover" + + powUpgrades0 RESEARCHSTAT "R-Struc-PowerModuleMk1" + powUpgrades1 RESEARCHSTAT "R-Struc-Power-Upgrade01" + powUpgrades2 RESEARCHSTAT "R-Struc-Power-Upgrade01b" + powUpgrades3 RESEARCHSTAT "R-Struc-Power-Upgrade01c" + powUpgrades4 RESEARCHSTAT "R-Struc-Power-Upgrade02" + powUpgrades5 RESEARCHSTAT "R-Struc-Power-Upgrade03" + powUpgrades6 RESEARCHSTAT "R-Struc-Power-Upgrade03a" + + wall STRUCTURESTAT "A0HardcreteMk1Wall" + + // incendry emplacements + numIncendrys INT 8 + incendrys[0] STRUCTURESTAT "Emplacement-MortarPit01" //Mortar Pit [range 9-18] + incendrys[1] STRUCTURESTAT "Emplacement-MortarPit02" //Bombard Pit [range 9-18] + incendrys[2] STRUCTURESTAT "Emplacement-RotMor" //*Pepperpot Pit [range 9-18] + + incendrys[3] STRUCTURESTAT "Emplacement-Rocket06-IDF" //*Ripple Rockets Battery [range 8-86] + + incendrys[4] STRUCTURESTAT "Emplacement-Howitzer105" //Howitzer Emplacement [range 15-39] + incendrys[5] STRUCTURESTAT "Emplacement-Howitzer150" //*Ground Shaker Emplacement [range 15-78] + + incendrys[6] STRUCTURESTAT "Emplacement-RotHow" //HellStorm Emplacement [range 15-55] + incendrys[7] STRUCTURESTAT "Emplacement-HvART-pit" //*Archangel Missile Emplacement [range 16-120] + + // sensor types + numSense INT 3 + sense[0] STRUCTURESTAT "Sys-SensoTowerWS" //Wide Spectrum Sensor Tower [17.7-26.5] + sense[1] STRUCTURESTAT "Sys-CB-Tower01" //CB Tower [range 16-24] + sense[2] STRUCTURESTAT "Sys-SensoTower01" //Sensor Tower [range 12-18] + + //anti air + numAA INT 6 + vtolDefStruct[0] STRUCTURESTAT "AASite-QuadMg1" //hurricane + vtolDefStruct[1] STRUCTURESTAT "AASite-QuadBof" //cyclone + vtolDefStruct[2] STRUCTURESTAT "AASite-QuadRotMg" //plasma site + vtolDefStruct[3] STRUCTURESTAT "P0-AASite-SAM1" //avenger + vtolDefStruct[4] STRUCTURESTAT "P0-AASite-SAM2" //vindicator + vtolDefStruct[5] STRUCTURESTAT "P0-AASite-Laser" //laser + + //min droids to keep in defend team for each AIpersonality + //[x][0] tanks + //[x][1] cyborgs + //[x][2] VTOLs + + minDefDroids[0][0] INT 5 + minDefDroids[0][1] INT 5 + minDefDroids[0][2] INT 3 + //VTOL + minDefDroids[1][0] INT 5 + minDefDroids[1][1] INT 5 + minDefDroids[1][2] INT 5 + //turtle + minDefDroids[2][0] INT 8 + minDefDroids[2][1] INT 8 + minDefDroids[2][2] INT 5 + //Cyborg + minDefDroids[3][0] INT 0 + minDefDroids[3][1] INT 10 + minDefDroids[3][2] INT 3 + + // Essential structs. + numStructs INT 4 + structs[0] STRUCTURESTAT "A0LightFactory" + structs[1] STRUCTURESTAT "A0ResearchFacility" + structs[2] STRUCTURESTAT "A0CyborgFactory" + structs[3] STRUCTURESTAT "A0VTolFactory1" + + // General 1 + structsLimits[0][0] INT 3 //FACT + structsLimits[0][1] INT 4 //RES + structsLimits[0][2] INT 3 //CYB + structsLimits[0][3] INT 2 //VTOL + + // General 2 VTOL + structsLimits[1][0] INT 3 + structsLimits[1][1] INT 2 + structsLimits[1][2] INT 3 + structsLimits[1][3] INT 4 + + // General 3 Turtle + structsLimits[2][0] INT 2 + structsLimits[2][1] INT 5 + structsLimits[2][2] INT 2 + structsLimits[2][3] INT 2 + + // General 4 Cyborg + structsLimits[3][0] INT 1 + structsLimits[3][1] INT 4 + structsLimits[3][2] INT 5 + structsLimits[3][3] INT 1 + + numDefStructs INT 11 + defStructs[0] STRUCTURESTAT "GuardTower1"//*MG3Mk1 $Machinegun Guard Tower + defStructs[1] STRUCTURESTAT "PillBox1"//Machinegun Bunker + defStructs[2] STRUCTURESTAT "PillBox5"//Flamer Bunker + defStructs[3] STRUCTURESTAT "GuardTower6"//Mini-Rocket (pod) tower + defStructs[4] STRUCTURESTAT "GuardTower5"//Lancer Tower + defStructs[5] STRUCTURESTAT "PillBox6"//Lancer Bunker + defStructs[6] STRUCTURESTAT "PillBox4"//Light Cannon Bunker + defStructs[7] STRUCTURESTAT "Emplacement-RotMor" //*Pepperpot Pit [range 9-18] + defStructs[8] STRUCTURESTAT "Emplacement-HvyATrocket" + defStructs[9] STRUCTURESTAT "Emplacement-PulseLaser" + defStructs[10] STRUCTURESTAT "Emplacement-Rail2" + + + // wall structs - NOT BUILT YET + numWallWeaps INT 16 + wallWeaps[0] STRUCTURESTAT "WallTower01"//Heavy Machinegun Hardpoint $100 + wallWeaps[1] STRUCTURESTAT "WallTower02"//Light Cannon Hardpoint $125 + wallWeaps[2] STRUCTURESTAT "WallTower03"//*Medium Cannon Hardpoint $200 + wallWeaps[3] STRUCTURESTAT "WallTower06"//Lancer Hardpoint $150 + wallWeaps[4] STRUCTURESTAT "WallTower04"//*Heavy Cannon Hardpoint $250 + wallWeaps[5] STRUCTURESTAT "Wall-RotMg"//*Assault Gun Hardpoin $150 + wallWeaps[6] STRUCTURESTAT "WallTower-EMP" + wallWeaps[7] STRUCTURESTAT "WallTower-Projector" + wallWeaps[8] STRUCTURESTAT "Wall-VulcanCan" + wallWeaps[9] STRUCTURESTAT "WallTower-HvATrocket" + wallWeaps[10] STRUCTURESTAT "WallTower-Rail2"//Rail Gun Hardpoint $350 + wallWeaps[11] STRUCTURESTAT "WallTower-Rail3"//Gauss Cannon Emplacement $450 + wallWeaps[12] STRUCTURESTAT "WallTower-PulseLas" + wallWeaps[13] STRUCTURESTAT "WallTower-HPVcannon"//??Emplacement-HPVcannon $200 + wallWeaps[14] STRUCTURESTAT "WallTower-Atmiss" + wallWeaps[15] STRUCTURESTAT "WallTower-Atmiss" + + numFortressDef INT 4 + fortressDef[0] STRUCTURESTAT "X-Super-Cannon"//"R-Defense-Super-Cannon"//Cannon Fortress + fortressDef[1] STRUCTURESTAT "X-Super-Rocket"//"R-Defense-Super-Rocket"//Heavy Rocket Bastion + fortressDef[2] STRUCTURESTAT "X-Super-Missile"//"R-Defense-Super-Missile"//Missile Fortress + fortressDef[3] STRUCTURESTAT "X-Super-MassDriver"//"R-Defense-MassDriver"// Mass Driver Fortress + + + numGenAA INT 10 + vtolGenStruct[0] STRUCTURESTAT "AASite-QuadMg1" //Hurricane Site + vtolGenStruct[1] STRUCTURESTAT "WallTower-DoubleAAGun" //Cyclone - HP + vtolGenStruct[2] STRUCTURESTAT "AASite-QuadBof" //Cyclone - Site + vtolGenStruct[3] STRUCTURESTAT "AASite-QuadRotMg" //WhirlWind - Site + vtolGenStruct[4] STRUCTURESTAT "WallTower-QuadRotAAGun" //Whirlwind - HP + vtolGenStruct[5] STRUCTURESTAT "P0-AASite-SAM1" //Avenger SAM - Site + vtolGenStruct[6] STRUCTURESTAT "WallTower-SamSite" //Avenger - HP + vtolGenStruct[7] STRUCTURESTAT "P0-AASite-SAM2" //Vindicator SAM - Site + vtolGenStruct[8] STRUCTURESTAT "WallTower-SamHvy" //Vindicator - HP + vtolGenStruct[9] STRUCTURESTAT "P0-AASite-Laser" //Laser + + + + ///////////////////////////////////////////////////////////////////// + // SENSORS / REPAIR TEMPLATES + + repairTank TEMPLATE "ViperRepairWheels" + constructor TEMPLATE "ConstructorDroid" + constructor2 TEMPLATE "ScorpHoverTruck" + cybcondroid TEMPLATE "Cyb-ComEng" + cybMech TEMPLATE "Cyb-Mechanic" + + + ///////////////////////////////////////////////////////////////////// + // cyborg templates + numSuperCyb INT 17 + + //Anti tank + superCyb[0] TEMPLATE "Cyb-Hvy-A-T" //[1][36]Super Scourge Cyborg + superCyb[3] TEMPLATE "Cyb-Hvy-TK" //[1][0]Super Tank-Killer Cyborg + superCyb[7] TEMPLATE "MP-Cyb-ATmiss-GRD"//[1][21]Scourge + superCyb[9] TEMPLATE "CyborgRkt01Ground"//[0][24]Lancer + + //All Rounder + superCyb[1] TEMPLATE "Cyb-Hvy-RailGunner" //[1][2] Super Rail-Gunner + superCyb[4] TEMPLATE "Cyb-Hvy-HPV" //[0][51] Super HPV Cyborg + superCyb[5] TEMPLATE "Cyb-Hvy-Acannon" //[0][50] Super Auto-Cannon Cyborg + superCyb[6] TEMPLATE "Cyb-Hvy-Mcannon" //[0][49] Super Heavy-Gunner + + //Anti Personnel + //Flamers-Lasers + superCyb[2] TEMPLATE "Cyb-Hvy-PulseLsr" //[1][1]Super Pulse Laser Cyborg + superCyb[10] TEMPLATE "MP-Cyb-Laser1-GRD" //[0][59] Flashlight Gunner + superCyb[12] TEMPLATE "Cyb-Thermite" //Thermite Flamer + superCyb[15] TEMPLATE "CyborgFlamer01Grd" //flamer + //Guns + superCyb[11] TEMPLATE "CyborgRotMgGround" //[0][25] Assault Gunner + superCyb[14] TEMPLATE "CyborgCannon01Grd" //heavy Gunner + superCyb[16] TEMPLATE "CyborgChain01Ground" //Machinegunner + + //Kinetic + superCyb[8] TEMPLATE "MP-Cyb-Needle-GRD" //[0][58]Needle Gunner + superCyb[13] TEMPLATE "Cyb-Gren" //Grenadier + + + ///////////////////////////////////////////////////////////////////// + // VTOL TEMPLATES + numVtolTemplates int 9 + vtols[0] TEMPLATE "V-Bug-Lancer" //Bug - Lancer + vtols[1] TEMPLATE "V-Bug-HPV" //Bug - HyperVelCann + vtols[2] TEMPLATE "H-Scorp-VTOL-Lancer" //Scorpion - Lancer + vtols[3] TEMPLATE "V-Scor-HPV" //Scorpion - HyperVelCann + vtols[4] TEMPLATE "SK-Retal-VTOL-Scourge" //Retaliation - Scourge Missle (AT) + vtols[5] TEMPLATE "SK-Mantis-VTOL-PBB" //**Mantis - Phosphor Bomb Bay + vtols[6] TEMPLATE "SK-Mantis-VTOL-HBB" //**Mantis - Heap Bomb Bay + vtols[7] TEMPLATE "SK-Retre-VTOL-HBB" //**Retribution - Heap Bomb Bay + vtols[8] TEMPLATE "SK-Retre-VTOL-Thermite" //**Retribution - Thermite Bomb Bay + +//////////////////////////////////////////////////////////////////// +// +// COMBAT TANK TEMPLATES + +/* + //Viper 65hp-600w-30$ Cobra 130hp-2000w-46$ Phyton 200hp-2700w-60$ + //Bug 55hp-450w-25$ Scorpion 125hp-1500w-39$ Mantis 180hp-2100w-52$ + //Leopard 85hp-750w-41$ Panther 145hp-2500w-57$ Tiger 225hp-3300w-71$ + //Retaliaton 100hp-450w-68$ Retribution 200hp-1500w-100$ Vengeance 300hp-2500w-130$ + // Wyvern 350hp-5000w-156$ Dragon 400hp-6000w-1820$ + + Tank bodies + numTankBodies int 9 + tankBody[0] BODY "Body1REC" // viper + tankBody[1] BODY "Body5REC" // cobra + tankBody[2] BODY "Body2SUP" // leopard + tankBody[3] BODY "Body11ABT" // python + tankBody[4] BODY "Body7ABT" // **retribution + tankBody[5] BODY "Body9REC" // tiger + tankBody[6] BODY "Body10MBT" // **vengeance + tankBody[7] BODY "Body13SUP" // wyvern + tankBody[8] BODY "Body14SUP" // dragon + tankBody[2] BODY "Body3MBT" // **Retaliation + tankBody[3] BODY "Body4ABT" // *Bug + tankBody[5] BODY "Body6SUPP" // Panther + tankBody[7] BODY "Body8MBT" // *Scorpion + tankBody[11] BODY "Body12SUP" // *Mantis + +*/ + + + numTmpls INT 63 + //================================================================= + //1-Viper + tmpl0[62] TEMPLATE "ViperMG01Wheels"// + tmpl0[61] TEMPLATE "ViperFlameHalfTracks" //Anti personnel + tmpl0[60] TEMPLATE "ViperMG02Halftrack" //Anti personnel + tmpl0[59] TEMPLATE "ViperLtCannonHTracks" //all-rounder + tmpl0[58] TEMPLATE "ViperPODHalfTracks" //anti-tank + tmpl0[57] TEMPLATE "ViperMRLHalfTracks" //anti-tank + + //1-Cobra + tmpl0[56] TEMPLATE "CobraPODHTracks" //anti-tank + tmpl0[55] TEMPLATE "CobraMRLHalftrack"//anti-tank + tmpl0[54] TEMPLATE "CobraLtA-Thalftrack"//anti-tank + tmpl0[53] TEMPLATE "CobraHMGHalfTrack" //Anti personnel + tmpl0[52] TEMPLATE "CobraMedCnHTrks" //all-rounder + tmpl0[51] TEMPLATE "A-Cobra-Hover-MC" //all-rounder + tmpl0[50] TEMPLATE "CobraInfernoHTracks"//Anti personnel + tmpl0[49] TEMPLATE "CobraInfernoHover" //Anti personnel + + + //1-Phyton + tmpl0[48] TEMPLATE "SK-Python-Hover-Lancer" //anti-tank + tmpl0[47] TEMPLATE "PythonTKTracks" //anti-tank + tmpl0[46] TEMPLATE "PythonHoverInferno" //Anti personnel + tmpl0[45] TEMPLATE "PhytonHoverAssGun" //Anti personnel + tmpl0[44] TEMPLATE "PhytonHTrackAssGun" //Anti personnel + tmpl0[43] TEMPLATE "PythonMedCanTracks" //all-rounder + tmpl0[42] TEMPLATE "SK-Python-Hover-Mcannon" //all-rounder + tmpl0[41] TEMPLATE "Sk-PythonHvCanTrack" //all-rounder + tmpl0[40] TEMPLATE "SK-Python-Hover-Hcannon" //all-rounder + + //================================================================= + //2-Bug + + //2-Scorpion {R-Vehicle-Body08} + tmpl0[39] TEMPLATE "SK-Scorp-Hover-Lancer" //anti-tank + tmpl0[38] TEMPLATE "ScorpHTrackHMG" //Anti personnel + tmpl0[37] TEMPLATE "SK-Scorp-Hover-Mcannon" //all-rounder + + //2-Mantis {R-Vehicle-Body12} + tmpl0[36] TEMPLATE "MantisHoverAC" //all-rounder + tmpl0[35] TEMPLATE "SK-Mantis-Hover-Hcannon" //all-rounder + tmpl0[34] TEMPLATE "SK-Mantis-Hover-HVC" //all-rounder + + //================================================================= + //3-Leopard {R-Vehicle-Body02} + tmpl0[33] TEMPLATE "LeopardHoverPulseLas" //Anti personnel + tmpl0[32] TEMPLATE "SK-Leopard-HTrk-ASGun" //Anti personnel + tmpl0[31] TEMPLATE "SK-Leopard-Hover-Needle" //all-rounder + tmpl0[30] TEMPLATE "SK-Leopard-Htrk-Needle" //all-rounder + + //3-Panther {R-Vehicle-Body06} + tmpl0[29] TEMPLATE "SK-Panther-Hover-TK" //anti-tank + tmpl0[28] TEMPLATE "SK-Panther-Track-TK" //anti-tank + tmpl0[27] TEMPLATE "PantherHoverPulseLas" //Anti personnel + tmpl0[26] TEMPLATE "SK-Panther-Htrk-ASGun" //Anti personnel + tmpl0[25] TEMPLATE "SK-Panther-Hover-HVC" //all-rounder + tmpl0[24] TEMPLATE "SK-Panther-Track-HVC" //all-rounder + + //3-Tiger {R-Vehicle-Body09} + tmpl0[23] TEMPLATE "SK-Tiger-Hover-TK" //anti-tank + tmpl0[22] TEMPLATE "SK-Tiger-Track-TK" //anti-tank + tmpl0[21] TEMPLATE "TigerHoverPulseLas" // Anti personnel + tmpl0[20] TEMPLATE "SK-Tiger-Track-ASCannon" // Anti personnel + tmpl0[19] TEMPLATE "TigerHoverRailGun" // all-rounder + tmpl0[18] TEMPLATE "SK-Tiger-Track-Hcannon" //all-rounder + //tmpl0[14] TEMPLATE "TigerPulseTracks" //OK + //tmpl0[13] TEMPLATE "TigerHvLaserTracks" //OK + + //================================================================= + //4-Retaliation {R-Vehicle-Body03} + + //4-Retribution {R-Vehicle-Body07} + tmpl0[17] TEMPLATE "SK-Retre-Hover-Scourge" //anti-tank + tmpl0[16] TEMPLATE "SK-Retre-Track-Scourge" //anti-tank + tmpl0[15] TEMPLATE "RetreHoverFlashLight" //Anti personnel - replace with PulseLAS?? + tmpl0[14] TEMPLATE "SK-Retre-Track-PulseLsr" //Anti personnel + tmpl0[13] TEMPLATE "SK-Retre-Hover-RailGun" //all-rounder + tmpl0[12] TEMPLATE "SK-Retre-Track-RailGun" //all-rounder + + //4-R-Wpn-Cannon-Damage07 + tmpl0[11] TEMPLATE "SK-Veng-Hover-Scourge" //anti-tank + tmpl0[10] TEMPLATE "SK-Veng-Track-Scourge" //anti-tank + tmpl0[9] TEMPLATE "SK-Veng-Hover-PulseLsr" //Anti personnel + tmpl0[8] TEMPLATE "SK-Veng-Track-HvyLaser" //Anti personnel + tmpl0[7] TEMPLATE "SK-Veng-Hover-Gauss" //all-rounder + tmpl0[6] TEMPLATE "SK-Veng-Track-Gauss" //all-rounder + + //================================================================= + //5-Wyvern {R-Vehicle-Body13} + tmpl0[5] TEMPLATE "WyvernScourgeTracks" //anti-tank + tmpl0[4] TEMPLATE "WyvernScourgeTracks" //anti-tank + tmpl0[3] TEMPLATE "WyvernPulseTracks" //Anti personnel + tmpl0[2] TEMPLATE "WyvernHvLaserTracks" //Anti personnel + tmpl0[1] TEMPLATE "WyvernGaussTracks" // all-rounder + tmpl0[0] TEMPLATE "WyvernPlasmaCTracks" //all-rounder + + //5-Dragon {R-Vehicle-Body14} + + //Base structures + numBaseStructs INT 10 + baseStructs[0] STRUCTURESTAT "A0LightFactory" + baseStructs[1] STRUCTURESTAT "A0CommandCentre" + baseStructs[2] STRUCTURESTAT "A0ResearchFacility" + baseStructs[3] STRUCTURESTAT "A0VTolFactory1" + baseStructs[4] STRUCTURESTAT "A0PowerGenerator" + baseStructs[5] STRUCTURESTAT "A0CyborgFactory" + baseStructs[6] STRUCTURESTAT "A0LasSatCommand" + baseStructs[7] STRUCTURESTAT "A0Sat-linkCentre" + baseStructs[8] STRUCTURESTAT "A0LasSatCommand" + baseStructs[9] STRUCTURESTAT "A0ResourceExtractor" + + + + //resUnitTransporter RESEARCHSTAT "R-Cyborg-TransportU" + + /***************************************************************/ + // Array used in the slo file - DEFAULT Personality - General 1 + /***************************************************************/ + + //cheap Researches + numCheapRes[0] INT 21 + researchCheap[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //$18 repair turret, pre-researched + researchCheap[0][1] RESEARCHSTAT "R-Struc-Research-Module" //$37 + researchCheap[0][2] RESEARCHSTAT "R-Struc-Research-Upgrade02" //160% + researchCheap[0][3] RESEARCHSTAT "R-Struc-RepairFacility" //repair facility {powMod - factModule-RepTurret} + researchCheap[0][4] RESEARCHSTAT "R-Defense-Tower06" //Mini-Rocket Tower + researchCheap[0][5] RESEARCHSTAT "R-Wpn-MG-Damage01" //Hardened MG Bullets + researchCheap[0][6] RESEARCHSTAT "R-Struc-Materials01" //Reinforced Base Structure Materials + researchCheap[0][7] RESEARCHSTAT "R-Cyborg-Metals01" //Cyborg Composite Alloys + researchCheap[0][8] RESEARCHSTAT "R-Struc-Factory-Upgrade01" //Automated Manufacturing {factMod-powMod} + researchCheap[0][9] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //HEAT Cannon Shells + researchCheap[0][10] RESEARCHSTAT "R-Vehicle-Engine01" //Fuel Injection Engine + researchCheap[0][11] RESEARCHSTAT "R-Defense-WallUpgrade01"//Improved Hardcrete + researchCheap[0][12] RESEARCHSTAT "R-Defense-AASite-QuadBof"//Cyclone AA site + researchCheap[0][13] RESEARCHSTAT "R-Vehicle-Body11" //$37 - Phyton , Cobra {facMod, powMod} + researchCheap[0][14] RESEARCHSTAT "R-Defense-WallTower01" //$37 - Heavy Machinegun Hardpoint + researchCheap[0][15] RESEARCHSTAT "R-Defense-WallTower02" //$46 - "Light Cannon HardPoint" {Light Cannon, HardCrete} + researchCheap[0][16] RESEARCHSTAT "R-Wpn-Rocket02-MRL" //$75 - {POD, HE Mini-Rockets Mk2} + researchCheap[0][17] RESEARCHSTAT "R-Defense-Pillbox06" //$46 - Lancer Tower {MRL, Lancer AT Rocket, Stabilized Mini-Rockets} + researchCheap[0][18] RESEARCHSTAT "R-Vehicle-Prop-Tracks" //$75 - Tracked Propulsion - {Composite Alloys Mk2, FactMod, ResearchMod} + researchCheap[0][19] RESEARCHSTAT "R-Defense-MortarPit" //$37 - Mortar Pit {hardcrete,facMod} + researchCheap[0][20] RESEARCHSTAT "R-Sys-CBSensor-Tower01" //CB Tower + + + //used for checks + + numRes[0] INT 62 + + //essentials + research[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //repair turret, pre-researched + research[0][1] RESEARCHSTAT "R-Wpn-Flamer-ROF03" + research[0][2] RESEARCHSTAT "R-Wpn-Flamer-Damage03" + research[0][3] RESEARCHSTAT "R-Struc-Research-Upgrade03"// 130/160/190/(220*)/250/280/310**/340/370 + research[0][4] RESEARCHSTAT "R-Struc-Power-Upgrade01b" // 150-01*/(175-01b)/200-01c/230-02**/260-03/290-03a + + //Cobra & Hover --------------------- + research[0][5] RESEARCHSTAT "R-Vehicle-Body05" + research[0][6] RESEARCHSTAT "R-Vehicle-Prop-Hover" //Hover + research[0][7] RESEARCHSTAT "R-Defense-WallTower01" //HMG + research[0][8] RESEARCHSTAT "R-Defense-Tower06" //POD + research[0][9] RESEARCHSTAT "R-Wpn-Flame2" //Inferno {damage04} + research[0][10] RESEARCHSTAT "R-Defense-MRL" //MRL + research[0][11] RESEARCHSTAT "R-Defense-WallTower03" //MEDCann + + //Cyborg Upgrades + research[0][12] RESEARCHSTAT "R-Cyborg-Metals04" // 135/170/205/(240*)/275/310/345**/380/415 + research[0][13] RESEARCHSTAT "R-Cyborg-Armor-Heat01" // (145)*/190/235/270**/315/360/405/450/495 + + + //Weapon Upgrades + research[0][14] RESEARCHSTAT "R-Wpn-MG-Damage02" //125/(150)/175/200/225/250/275/300/325 % + research[0][15] RESEARCHSTAT "R-Wpn-Rocket-Damage02" //150% + research[0][16] RESEARCHSTAT "R-Wpn-Rocket-ROF02" //143% + + //HardCretes & Armors + research[0][17] RESEARCHSTAT "R-Vehicle-Armor-Heat02"//140/(180)/220/260/300/340/380/420/460 + research[0][18] RESEARCHSTAT "R-Struc-Materials03" // 135/170/(205)/240/275/310/345* /370/405 + research[0][19] RESEARCHSTAT "R-Defense-WallUpgrade03" // 135/170/(205)/240/275/305/340* /375/405/440/475/510 + //* Research-Upgarde-08; + + //Research and power upgrades + research[0][20] RESEARCHSTAT "R-Struc-Research-Upgrade05"// 30/160/190/220*/(250)/280/310**/340/370 + research[0][21] RESEARCHSTAT "R-Struc-Power-Upgrade01c" // 150-01*/175-01b/(200-01c)/230-02**/260-03/290-03a + + //Phyton - Heavy Cannon, Lancer, Assault Gun, Inferno -------------------- + research[0][22] RESEARCHSTAT "R-Vehicle-Body11" + research[0][23] RESEARCHSTAT "R-Defense-WallTower04" //HeavyCann {damage04} + research[0][24] RESEARCHSTAT "R-Defense-Pillbox06" //Lancer + research[0][25] RESEARCHSTAT "R-Defense-RotMG" //AssGun + research[0][26] RESEARCHSTAT "R-Defense-HvyFlamer" //Inferno - Bunker + + //Cyborg Upgrades + research[0][27] RESEARCHSTAT "R-Cyborg-Metals05" //135/170/205/240*/(275)/310/345**/380/415 + research[0][28] RESEARCHSTAT "R-Cyborg-Armor-Heat02" //145*/(190)/235/270**/315/360/405/450/495 + + //Weapon Upgrades + research[0][29] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + research[0][30] RESEARCHSTAT "R-Wpn-Flamer-ROF02" //118/(143)/182 % + research[0][31] RESEARCHSTAT "R-Wpn-MG-ROF01" //(118)/143/182 % + research[0][32] RESEARCHSTAT "R-Wpn-Flamer-Damage04" //125/150/175/(200)/225/250/275/300/325 % + research[0][33] RESEARCHSTAT "R-Wpn-MG-Damage04" //125/150/175/(200)/225/250/275/300/325 % + + //HardCretes & Armors + research[0][34] RESEARCHSTAT "R-Vehicle-Armor-Heat03"//140/180/(220)/260/300/340/380/420/460 + research[0][35] RESEARCHSTAT "R-Struc-Materials04"//135/170/205/(240)/275/310/345*/370/405 + research[0][36] RESEARCHSTAT "R-Defense-WallUpgrade04"//135/170/205/(240)/275/305/340* /375/405/440/475/510 + + //Research and Power upgrades + research[0][37] RESEARCHSTAT "R-Struc-Research-Upgrade07"// 30/160/190/220*/250/280/(310**)/340/370 + research[0][38] RESEARCHSTAT "R-Struc-Power-Upgrade02" // 150-01*/175-01b/200-01c/(230-02**)/260-03/290-03a + + //Mantis-Scorpion - HVC, Assault Cannon------------------ + research[0][39] RESEARCHSTAT "R-Vehicle-Body12" + research[0][40] RESEARCHSTAT "R-Defense-WallTower-HPVcannon" //HVC {damage05} + research[0][41] RESEARCHSTAT "R-Defense-Wall-VulcanCan" //AssCann {damage01/ROF03} + + //Weapon Upgrades + research[0][42] RESEARCHSTAT "R-Wpn-Cannon-Accuracy01" //(110)/120 % + research[0][43] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + research[0][44] RESEARCHSTAT "R-Wpn-MG-ROF02" //118/(143)/182 % + research[0][45] RESEARCHSTAT "R-Wpn-MG-Damage06" //125/150/175/200/225/(250)/275/300/325 % + research[0][46] RESEARCHSTAT "R-Wpn-Flamer-Damage06" //125/150/175/200/225/(250)/275/300/325 % + + //Cyborg Upgrades + research[0][47] RESEARCHSTAT "R-Cyborg-Metals06" //135/170/205/240*/275/(310)/345**/380/415 + research[0][48] RESEARCHSTAT "R-Cyborg-Armor-Heat03" //145*/190/(235)/270**/315/360/405/450/495 + + //Cyborg + research[0][49] RESEARCHSTAT "R-Cyborg-Hvywpn-Mcannon" //Super Heavy Gunner + research[0][50] RESEARCHSTAT "R-Cyborg-Hvywpn-HPV" //Super Auto Cannon Cyborg + research[0][51] RESEARCHSTAT "R-Cyborg-Hvywpn-Acannon" //Super HPV Cyborg + + //HardCretes & Armors + research[0][52] RESEARCHSTAT "R-Vehicle-Armor-Heat05"//140/180/220/260/(300)/340/380/420/460 + research[0][53] RESEARCHSTAT "R-Struc-Materials05"//135/170/205/240/(275)/310/345*/370/405 + research[0][54] RESEARCHSTAT "R-Defense-Super-Cannon"//R-Defense-WallUpgrade05"//135/170/205/240/(275)/305/340* /375/405/440/475/510 + + //Research and Power upgrades + research[0][55] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220*/250/280/310**/(340)/370 + research[0][56] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01*/175-01b/200-01c/230-02**/(260-03)/290-03a + + //Leopard - Panther - Needle, Pulse Laser, Tank Killer------------------------------------------- + research[0][57] RESEARCHSTAT "R-Vehicle-Body06" //Panther + research[0][58] RESEARCHSTAT "R-Defense-GuardTower-Rail1" //Neelde + research[0][59] RESEARCHSTAT "R-Defense-WallTower-PulseLas" //Pulse Laser + research[0][60] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + research[0][61] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + + numRes[1] INT 47 + + //Cyborg + research[1][0] RESEARCHSTAT "R-Cyborg-Hvywpn-TK" // Super Tank-Killer Cyborg + research[1][1] RESEARCHSTAT "R-Cyborg-Hvywpn-PulseLsr" //Super Pulse Laser Cyborg + research[1][2] RESEARCHSTAT "R-Cyborg-Hvywpn-RailGunner" // Super Rail Gunner + + //Weapon Upgrades + research[1][3] RESEARCHSTAT "R-Wpn-RocketSlow-Damage02" // 125/(150)/175/200/225/250 % + research[1][4] RESEARCHSTAT "R-Wpn-RocketSlow-ROF01" // (118)/143/182 % + research[1][5] RESEARCHSTAT "R-Wpn-RocketSlow-Accuracy01" // (110)/120/130 % + research[1][6] RESEARCHSTAT "R-Wpn-Rail-ROF01" // (118)/143/182 % + research[1][7] RESEARCHSTAT "R-Wpn-MG-Damage07" // 125/150/175/200/225/250/(275)/300/325 % + + //Tiger - Rail Gun---------------------------------------------------- + research[1][8] RESEARCHSTAT "R-Vehicle-Body09" //Tiger + research[1][9] RESEARCHSTAT "R-Defense-WallTower-Rail2" //Rail Gun + + //Research and Power upgrades + research[1][10] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220* /250/280/310** /340/(370) + research[1][11] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01* /175-01b/200-01c/230-02** /260-03/(290-03a) + + //HardCretes & Armors + research[1][12] RESEARCHSTAT "R-Vehicle-Armor-Heat06"//140/180/220/260/300/(340)/380/420/460 + research[1][13] RESEARCHSTAT "R-Struc-Materials06" // 135/170/205/240/275/(310)/345* /370/405 + research[1][14] RESEARCHSTAT "R-Defense-WallUpgrade06" // 135/170/205/240/275/(305)/340* /375/405/440/475/510 + + //Weapon Upgrades + research[1][15] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //(125)/150/175 % + research[1][16] RESEARCHSTAT "R-Wpn-Energy-Damage01" //(125)/150/175 % + research[1][17] RESEARCHSTAT "R-Wpn-Energy-ROF01" //(118)/143/182 % + + + //Cyborg Upgrades + research[1][18] RESEARCHSTAT "R-Cyborg-Metals07" //135/170/205/240* /275/310/(345**)/380/415 + research[1][19] RESEARCHSTAT "R-Cyborg-Armor-Heat04" //145* /190/235/(270**)/315/360/405/450/495 + + //Retribution - Scourge ---------------------------------------------- + research[1][20] RESEARCHSTAT "R-Vehicle-Body07" //Retribution + research[1][21] RESEARCHSTAT "R-Defense-WallTower-A-Tmiss" //Scourge + + //Weapon Upgrades + research[1][22] RESEARCHSTAT "R-Wpn-Missile-Damage01" //(125)/150/175 % + research[1][23] RESEARCHSTAT "R-Wpn-Missile-ROF01" //(118)/143/182 % + research[1][24] RESEARCHSTAT "R-Wpn-Missile-Accuracy01" //(110)/120/182 % + + //Vengeance - Heavy Laser, Gauss Cannon ---------------------------------------------- + research[1][25] RESEARCHSTAT "R-Vehicle-Body10" //Vengeance + research[1][26] RESEARCHSTAT "R-Defense-HeavyLas" //Heavy Laser + research[1][27] RESEARCHSTAT "R-Defense-WallTower-Rail3" //Gauss Cannon + + //HardCretes & Armors + research[1][28] RESEARCHSTAT "R-Vehicle-Armor-Heat07"//140/180/220/260/300/340/(380)/420/460 + research[1][29] RESEARCHSTAT "R-Struc-Materials07"//135/170/205/240/275/310/(345*)/370/405 + research[1][30] RESEARCHSTAT "R-Defense-WallUpgrade07"//135/170/205/240/275/305/(340*)/375/405/440/475/510 + + //Weapon Upgrades + research[1][31] RESEARCHSTAT "R-Wpn-Energy-Damage03" //125/150/(175) % + research[1][32] RESEARCHSTAT "R-Wpn-Energy-ROF03" //118/143/(182) % + research[1][33] RESEARCHSTAT "R-Wpn-Energy-Accuracy01" //110/110 % + research[1][34] RESEARCHSTAT "R-Wpn-Rail-ROF03" // 118/143/(182) % + research[1][35] RESEARCHSTAT "R-Wpn-Rail-Accuracy01" // 110/110 % + + //Cyborg + research[1][36] RESEARCHSTAT "R-Cyborg-Hvywpn-A-T" //Super Scourge Cyborg + + //Cyborg Upgrades + research[1][37] RESEARCHSTAT "R-Cyborg-Metals08" //135/170/205/240* /275/310/345** /(380)/415 + research[1][38] RESEARCHSTAT "R-Cyborg-Armor-Heat06" //145* /190/235/270** /315/(360)/405/450/495 + + //Wyvern - Plasma Cannon ------------------------------------------------- + research[1][39] RESEARCHSTAT "R-Vehicle-Body13" //Wyvern + research[1][40] RESEARCHSTAT "R-Defense-PlasmaCannon" //Plasma Caanon + + //Laser Satellite + research[1][41] RESEARCHSTAT "R-Wpn-LasSat" //LaserSat + + //Fortresses + research[1][42] RESEARCHSTAT "R-Defense-Super-Missile" //Missile Fortress + research[1][43] RESEARCHSTAT "R-Defense-MassDriver" //Mass Driver Fortress + + + //HardCretes & Armors + research[1][44] RESEARCHSTAT "R-Vehicle-Armor-Heat09"//140/180/220/260/300/340/380/420/(460) + research[1][45] RESEARCHSTAT "R-Struc-Materials09"//135/170/205/240/275/310/345* /370/405 + research[1][46] RESEARCHSTAT "R-Defense-WallUpgrade12"//135/170/205/240/275/305/340* /375/405/440/475/510 + + /****************************/ + /* VTOL Stuff */ + /****************************/ + + numRes[9] INT 26 + + //VTOL fact & Propulsion, Rearming PAD, Anti AA def + research[9][0] RESEARCHSTAT "R-Vehicle-Prop-Hover" + research[9][1] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade01" + research[9][2] RESEARCHSTAT "R-Defense-AASite-QuadBof" //Cyclone AA Site + research[9][3] RESEARCHSTAT "R-Wpn-AAGun-ROF03" //AA ROF + research[9][4] RESEARCHSTAT "R-Wpn-AAGun-Accuracy01" //AA Accuracy + + //Scorpion - Bug + research[9][5] RESEARCHSTAT "R-Vehicle-Body08" //Scorpion Body + Bug + + //Lancer - HPV + research[9][6] RESEARCHSTAT "R-Wpn-Rocket01-LtAT" //Lamcer + research[9][7] RESEARCHSTAT "R-Wpn-Cannon4AMk1" //HPV + + //Rearming upgrade - VTOL Strike Turret + research[9][8] RESEARCHSTAT "R-Sys-VTOLStrike-Turret01" //VTOL Strike Turret,VTOL Strike Tower detects approaching enemies + research[9][9] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade03" + + //Mantis - Phosphor Bomb Bay - Heap Bomb Bay + research[9][10] RESEARCHSTAT "R-Vehicle-Body12" + research[9][11] RESEARCHSTAT "R-Wpn-Bomb03" //Phosphor BB + research[9][12] RESEARCHSTAT "R-Wpn-Bomb02" //Heap BB + + //Rearming upgrade - AA def + research[9][13] RESEARCHSTAT "R-Defense-AASite-QuadRotMg" //Whirlwind AA Site + research[9][14] RESEARCHSTAT "R-Wpn-AAGun-ROF04" //AA ROF + research[9][15] RESEARCHSTAT "R-Wpn-AAGun-Accuracy02" //AA Accuracy + research[9][16] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade04" + + //Retaliation - Scourge Missle + research[9][17] RESEARCHSTAT "R-Vehicle-Body03" // + research[9][18] RESEARCHSTAT "R-Wpn-Missile2A-T" //AT + + //Retribution - Thermite BB + research[9][19] RESEARCHSTAT "R-Vehicle-Body07" // + research[9][20] RESEARCHSTAT "R-Wpn-Bomb04" // + + //Rearming upgrade - AA def + research[9][21] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade06" + research[9][22] RESEARCHSTAT "R-Defense-SamSite1" //Avenger SAM Site + research[9][23] RESEARCHSTAT "R-Wpn-Missile-Damage03" //Avenger Damage + research[9][24] RESEARCHSTAT "R-Wpn-Missile-ROF03" //Avenger ROF + research[9][25] RESEARCHSTAT "R-Wpn-Missile-Accuracy02" //Avenger ROF + + + + // ================================================================================ + // personality GENERAL 2 (VTOL) + // ================================================================================ + + //cheap Researches + numCheapResGen2[0] INT 21 + general2Cheap[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //$18 repair turret, pre-researched + general2Cheap[0][1] RESEARCHSTAT "R-Struc-Research-Module" //$37 + general2Cheap[0][2] RESEARCHSTAT "R-Struc-Research-Upgrade02" //160% + general2Cheap[0][3] RESEARCHSTAT "R-Struc-RepairFacility" //$75 - repair facility {powMod - factModule-RepTurret} + general2Cheap[0][4] RESEARCHSTAT "R-Wpn-MG-Damage01" //$18 - 125% - Hardened MG Bullets + general2Cheap[0][5] RESEARCHSTAT "R-Struc-Materials01" //$37 - 135% - Reinforced Base Structure Materials + general2Cheap[0][6] RESEARCHSTAT "R-Cyborg-Metals01" //$37 - 135% - Cyborg Composite Alloys + general2Cheap[0][7] RESEARCHSTAT "R-Struc-Factory-Upgrade01" //$75 - 160% - Automated Manufacturing {factMod-powMod} + general2Cheap[0][8] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //$37 - 125% - HEAT Cannon Shells + general2Cheap[0][9] RESEARCHSTAT "R-Vehicle-Engine01" //$37 - 105% - Fuel Injection Engine + general2Cheap[0][10] RESEARCHSTAT "R-Defense-WallUpgrade01"//$37 - 135% - Improved Hardcrete + general2Cheap[0][11] RESEARCHSTAT "R-Vehicle-Body11" //$37 - Phyton , Cobra {facMod, powMod} + general2Cheap[0][12] RESEARCHSTAT "R-Defense-WallTower01" //$37 - Heavy Machinegun Hardpoint + general2Cheap[0][13] RESEARCHSTAT "R-Defense-WallTower02" //$46 - "Light Cannon HardPoint" {Light Cannon, HardCrete} + general2Cheap[0][14] RESEARCHSTAT "R-Defense-Tower06" //$75 - Mini-Rocket Tower + general2Cheap[0][15] RESEARCHSTAT "R-Wpn-Rocket02-MRL" //$75 - {POD, HE Mini-Rockets Mk2} + general2Cheap[0][16] RESEARCHSTAT "R-Defense-Pillbox06" //$46 - Lancer Tower {MRL, Lancer AT Rocket, Stabilized Mini-Rockets} + general2Cheap[0][17] RESEARCHSTAT "R-Vehicle-Prop-Tracks" //$75 - Tracked Propulsion - {Composite Alloys Mk2, FactMod, ResearchMod} + general2Cheap[0][18] RESEARCHSTAT "R-Defense-AASite-QuadMg1"//Hurricane AA site + general2Cheap[0][19] RESEARCHSTAT "R-Defense-MortarPit" //$37 - Mortar Pit {hardcrete,facMod} + general2Cheap[0][20] RESEARCHSTAT "R-Sys-CBSensor-Tower01" //CB Tower + + + //used for checks + + numResGen2[0] INT 62 + //essentials + general2[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //repair turret, pre-researched + general2[0][1] RESEARCHSTAT "R-Wpn-Flamer-ROF03" + general2[0][2] RESEARCHSTAT "R-Wpn-Flamer-Damage03" + general2[0][3] RESEARCHSTAT "R-Struc-Research-Upgrade03"// 130/160/190/(220*)/250/280/310**/340/370 + general2[0][4] RESEARCHSTAT "R-Struc-Power-Upgrade01b" // 150-01*/(175-01b)/200-01c/230-02**/260-03/290-03a + + //Cobra & Hover --------------------- + general2[0][5] RESEARCHSTAT "R-Vehicle-Body05" + general2[0][6] RESEARCHSTAT "R-Vehicle-Prop-Hover" //Hover + general2[0][7] RESEARCHSTAT "R-Defense-WallTower01" //HMG + general2[0][8] RESEARCHSTAT "R-Defense-Tower06" //POD + general2[0][9] RESEARCHSTAT "R-Wpn-Flame2" //Inferno {damage04} + general2[0][10] RESEARCHSTAT "R-Defense-MRL" //MRL + general2[0][11] RESEARCHSTAT "R-Defense-WallTower03" //MEDCann + + //Cyborg Upgrades + general2[0][12] RESEARCHSTAT "R-Cyborg-Metals04" // 135/170/205/(240*)/275/310/345**/380/415 + general2[0][13] RESEARCHSTAT "R-Cyborg-Armor-Heat01" // (145)*/190/235/270**/315/360/405/450/495 + + + //Weapon Upgrades + general2[0][14] RESEARCHSTAT "R-Wpn-MG-Damage02" //125/(150)/175/200/225/250/275/300/325 % + general2[0][15] RESEARCHSTAT "R-Wpn-Rocket-Damage02" //150% + general2[0][16] RESEARCHSTAT "R-Wpn-Rocket-ROF02" //143% + + //HardCretes & Armors + general2[0][17] RESEARCHSTAT "R-Vehicle-Armor-Heat02"//140/(180)/220/260/300/340/380/420/460 + general2[0][18] RESEARCHSTAT "R-Struc-Materials03" // 135/170/(205)/240/275/310/345* /370/405 + general2[0][19] RESEARCHSTAT "R-Defense-WallUpgrade03" // 135/170/(205)/240/275/305/340* /375/405/440/475/510 + //* Research-Upgarde-08; + + //Research and power upgrades + general2[0][20] RESEARCHSTAT "R-Struc-Research-Upgrade05"// 30/160/190/220*/(250)/280/310**/340/370 + general2[0][21] RESEARCHSTAT "R-Struc-Power-Upgrade01c" // 150-01*/175-01b/(200-01c)/230-02**/260-03/290-03a + + //Phyton - Heavy Cannon, Lancer, Assault Gun, Inferno -------------------- + general2[0][22] RESEARCHSTAT "R-Vehicle-Body11" + general2[0][23] RESEARCHSTAT "R-Defense-WallTower04" //HeavyCann {damage04} + general2[0][24] RESEARCHSTAT "R-Defense-Pillbox06" //Lancer + general2[0][25] RESEARCHSTAT "R-Defense-RotMG" //AssGun + general2[0][26] RESEARCHSTAT "R-Defense-HvyFlamer" //Inferno - Bunker + + //Cyborg Upgrades + general2[0][27] RESEARCHSTAT "R-Cyborg-Metals05" //135/170/205/240*/(275)/310/345**/380/415 + general2[0][28] RESEARCHSTAT "R-Cyborg-Armor-Heat02" //145*/(190)/235/270**/315/360/405/450/495 + + //Weapon Upgrades + general2[0][29] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + general2[0][30] RESEARCHSTAT "R-Wpn-Flamer-ROF02" //118/(143)/182 % + general2[0][31] RESEARCHSTAT "R-Wpn-MG-ROF01" //(118)/143/182 % + general2[0][32] RESEARCHSTAT "R-Wpn-Flamer-Damage04" //125/150/175/(200)/225/250/275/300/325 % + general2[0][33] RESEARCHSTAT "R-Wpn-MG-Damage04" //125/150/175/(200)/225/250/275/300/325 % + + //HardCretes & Armors + general2[0][34] RESEARCHSTAT "R-Vehicle-Armor-Heat03"//140/180/(220)/260/300/340/380/420/460 + general2[0][35] RESEARCHSTAT "R-Struc-Materials04"//135/170/205/(240)/275/310/345*/370/405 + general2[0][36] RESEARCHSTAT "R-Defense-WallUpgrade04"//135/170/205/(240)/275/305/340* /375/405/440/475/510 + + //Research and Power upgrades + general2[0][37] RESEARCHSTAT "R-Struc-Research-Upgrade07"// 30/160/190/220*/250/280/(310**)/340/370 + general2[0][38] RESEARCHSTAT "R-Struc-Power-Upgrade02" // 150-01*/175-01b/200-01c/(230-02**)/260-03/290-03a + + //Mantis-Scorpion - HVC, Assault Cannon------------------ + general2[0][39] RESEARCHSTAT "R-Vehicle-Body12" + general2[0][40] RESEARCHSTAT "R-Defense-WallTower-HPVcannon" //HVC {damage05} + general2[0][41] RESEARCHSTAT "R-Defense-Wall-VulcanCan" //AssCann {damage01/ROF03} + + //Weapon Upgrades + general2[0][42] RESEARCHSTAT "R-Wpn-Cannon-Accuracy01" //(110)/120 % + general2[0][43] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + general2[0][44] RESEARCHSTAT "R-Wpn-MG-ROF02" //118/(143)/182 % + general2[0][45] RESEARCHSTAT "R-Wpn-MG-Damage06" //125/150/175/200/225/(250)/275/300/325 % + general2[0][46] RESEARCHSTAT "R-Wpn-Flamer-Damage06" //125/150/175/200/225/(250)/275/300/325 % + + //Cyborg Upgrades + general2[0][47] RESEARCHSTAT "R-Cyborg-Metals06" //135/170/205/240*/275/(310)/345**/380/415 + general2[0][48] RESEARCHSTAT "R-Cyborg-Armor-Heat03" //145*/190/(235)/270**/315/360/405/450/495 + + //Cyborg + general2[0][49] RESEARCHSTAT "R-Cyborg-Hvywpn-Mcannon" //Super Heavy Gunner + general2[0][50] RESEARCHSTAT "R-Cyborg-Hvywpn-HPV" //Super Auto Cannon Cyborg + general2[0][51] RESEARCHSTAT "R-Cyborg-Hvywpn-Acannon" //Super HPV Cyborg + + //HardCretes & Armors + general2[0][52] RESEARCHSTAT "R-Vehicle-Armor-Heat05"//140/180/220/260/(300)/340/380/420/460 + general2[0][53] RESEARCHSTAT "R-Struc-Materials05"//135/170/205/240/(275)/310/345*/370/405 + general2[0][54] RESEARCHSTAT "R-Defense-Super-Cannon"//"R-Defense-WallUpgrade05"//135/170/205/240/(275)/305/340* /375/405/440/475/510 + + //Research and Power upgrades + general2[0][55] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220*/250/280/310**/(340)/370 + general2[0][56] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01*/175-01b/200-01c/230-02**/(260-03)/290-03a + + //Leopard - Panther - Needle, Pulse Laser, Tank Killer------------------------------------------- + general2[0][57] RESEARCHSTAT "R-Vehicle-Body06" //Panther + general2[0][58] RESEARCHSTAT "R-Defense-GuardTower-Rail1" //Neelde + general2[0][59] RESEARCHSTAT "R-Defense-WallTower-PulseLas" //Pulse Laser + general2[0][60] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + general2[0][61] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + + numResGen2[1] INT 47 + + //Cyborg + general2[1][0] RESEARCHSTAT "R-Cyborg-Hvywpn-TK" // Super Tank-Killer Cyborg + general2[1][1] RESEARCHSTAT "R-Cyborg-Hvywpn-PulseLsr" //Super Pulse Laser Cyborg + general2[1][2] RESEARCHSTAT "R-Cyborg-Hvywpn-RailGunner" // Super Rail Gunner + + //Weapon Upgrades + general2[1][3] RESEARCHSTAT "R-Wpn-RocketSlow-Damage02" // 125/(150)/175/200/225/250 % + general2[1][4] RESEARCHSTAT "R-Wpn-RocketSlow-ROF01" // (118)/143/182 % + general2[1][5] RESEARCHSTAT "R-Wpn-RocketSlow-Accuracy01" // (110)/120/130 % + general2[1][6] RESEARCHSTAT "R-Wpn-Rail-ROF01" // (118)/143/182 % + general2[1][7] RESEARCHSTAT "R-Wpn-MG-Damage07" // 125/150/175/200/225/250/(275)/300/325 % + + //Tiger - Rail Gun---------------------------------------------------- + general2[1][8] RESEARCHSTAT "R-Vehicle-Body09" //Tiger + general2[1][9] RESEARCHSTAT "R-Defense-WallTower-Rail2" //Rail Gun + + //Research and Power upgrades + general2[1][10] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220* /250/280/310** /340/(370) + general2[1][11] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01* /175-01b/200-01c/230-02** /260-03/(290-03a) + + //HardCretes & Armors + general2[1][12] RESEARCHSTAT "R-Vehicle-Armor-Heat06"//140/180/220/260/300/(340)/380/420/460 + general2[1][13] RESEARCHSTAT "R-Struc-Materials06" // 135/170/205/240/275/(310)/345* /370/405 + general2[1][14] RESEARCHSTAT "R-Defense-WallUpgrade06" // 135/170/205/240/275/(305)/340* /375/405/440/475/510 + + //Weapon Upgrades + general2[1][15] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //(125)/150/175 % + general2[1][16] RESEARCHSTAT "R-Wpn-Energy-Damage01" //(125)/150/175 % + general2[1][17] RESEARCHSTAT "R-Wpn-Energy-ROF01" //(118)/143/182 % + + + //Cyborg Upgrades + general2[1][18] RESEARCHSTAT "R-Cyborg-Metals07" //135/170/205/240* /275/310/(345**)/380/415 + general2[1][19] RESEARCHSTAT "R-Cyborg-Armor-Heat04" //145* /190/235/(270**)/315/360/405/450/495 + + //Retribution - Scourge ---------------------------------------------- + general2[1][20] RESEARCHSTAT "R-Vehicle-Body07" //Retribution + general2[1][21] RESEARCHSTAT "R-Defense-WallTower-A-Tmiss" //Scourge + + //Weapon Upgrades + general2[1][22] RESEARCHSTAT "R-Wpn-Missile-Damage01" //(125)/150/175 % + general2[1][23] RESEARCHSTAT "R-Wpn-Missile-ROF01" //(118)/143/182 % + general2[1][24] RESEARCHSTAT "R-Wpn-Missile-Accuracy01" //(110)/120/182 % + + //Vengeance - Heavy Laser, Gauss Cannon ---------------------------------------------- + general2[1][25] RESEARCHSTAT "R-Vehicle-Body10" //Vengeance + general2[1][26] RESEARCHSTAT "R-Defense-HeavyLas" //Heavy Laser + general2[1][27] RESEARCHSTAT "R-Defense-WallTower-Rail3" //Gauss Cannon + + //HardCretes & Armors + general2[1][28] RESEARCHSTAT "R-Vehicle-Armor-Heat07"//140/180/220/260/300/340/(380)/420/460 + general2[1][29] RESEARCHSTAT "R-Struc-Materials07"//135/170/205/240/275/310/(345*)/370/405 + general2[1][30] RESEARCHSTAT "R-Defense-WallUpgrade07"//135/170/205/240/275/305/(340*)/375/405/440/475/510 + + //Weapon Upgrades + general2[1][31] RESEARCHSTAT "R-Wpn-Energy-Damage03" //125/150/(175) % + general2[1][32] RESEARCHSTAT "R-Wpn-Energy-ROF03" //118/143/(182) % + general2[1][33] RESEARCHSTAT "R-Wpn-Energy-Accuracy01" //110/110 % + general2[1][34] RESEARCHSTAT "R-Wpn-Rail-ROF03" // 118/143/(182) % + general2[1][35] RESEARCHSTAT "R-Wpn-Rail-Accuracy01" // 110/110 % + + //Cyborg + general2[1][36] RESEARCHSTAT "R-Cyborg-Hvywpn-A-T" //Super Scourge Cyborg + + //Cyborg Upgrades + general2[1][37] RESEARCHSTAT "R-Cyborg-Metals08" //135/170/205/240* /275/310/345** /(380)/415 + general2[1][38] RESEARCHSTAT "R-Cyborg-Armor-Heat06" //145* /190/235/270** /315/(360)/405/450/495 + + //Wyvern - Plasma Cannon ------------------------------------------------- + general2[1][39] RESEARCHSTAT "R-Vehicle-Body13" //Wyvern + general2[1][40] RESEARCHSTAT "R-Defense-PlasmaCannon" //Plasma Caanon + + //Laser Satellite + general2[1][41] RESEARCHSTAT "R-Wpn-LasSat" //LaserSat + + //Fortresses + general2[1][42] RESEARCHSTAT "R-Defense-Super-Missile" //Missile Fortress + general2[1][43] RESEARCHSTAT "R-Defense-MassDriver" //Mass Driver Fortress + + + //HardCretes & Armors + general2[1][44] RESEARCHSTAT "R-Vehicle-Armor-Heat09"//140/180/220/260/300/340/380/420/(460) + general2[1][45] RESEARCHSTAT "R-Struc-Materials09"//135/170/205/240/275/310/345* /370/405 + general2[1][46] RESEARCHSTAT "R-Defense-WallUpgrade12"//135/170/205/240/275/305/340* /375/405/440/475/510 + + /****************************/ + /* VTOL Stuff */ + /****************************/ + + numResGen2[9] INT 26 + general2[9][0] RESEARCHSTAT "R-Vehicle-Prop-Hover" + general2[9][1] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade01" + general2[9][2] RESEARCHSTAT "R-Defense-AASite-QuadBof" //Cyclone AA Site + general2[9][3] RESEARCHSTAT "R-Wpn-AAGun-ROF03" //AA ROF + general2[9][4] RESEARCHSTAT "R-Wpn-AAGun-Accuracy01" //AA Accuracy + + //Scorpion - Bug + general2[9][5] RESEARCHSTAT "R-Vehicle-Body08" //Scorpion Body + Bug + + //Lancer - HPV + general2[9][6] RESEARCHSTAT "R-Wpn-Rocket01-LtAT" //Lamcer + general2[9][7] RESEARCHSTAT "R-Wpn-Cannon4AMk1" //HPV + + //Rearming upgrade - VTOL Strike Turret + general2[9][8] RESEARCHSTAT "R-Sys-VTOLStrike-Turret01" //VTOL Strike Turret,VTOL Strike Tower detects approaching enemies + general2[9][9] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade03" + + //Mantis - Phosphor Bomb Bay - Heap Bomb Bay + general2[9][10] RESEARCHSTAT "R-Vehicle-Body12" + general2[9][11] RESEARCHSTAT "R-Wpn-Bomb03" //Phosphor BB + general2[9][12] RESEARCHSTAT "R-Wpn-Bomb02" //Heap BB + + //Rearming upgrade - AA def + general2[9][13] RESEARCHSTAT "R-Defense-AASite-QuadRotMg" //Whirlwind AA Site + general2[9][14] RESEARCHSTAT "R-Wpn-AAGun-ROF04" //AA ROF + general2[9][15] RESEARCHSTAT "R-Wpn-AAGun-Accuracy02" //AA Accuracy + general2[9][16] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade04" + + //Retaliation - Scourge Missle + general2[9][17] RESEARCHSTAT "R-Vehicle-Body03" // + general2[9][18] RESEARCHSTAT "R-Wpn-Missile2A-T" //AT + + //Retribution - Thermite BB + general2[9][19] RESEARCHSTAT "R-Vehicle-Body07" // + general2[9][20] RESEARCHSTAT "R-Wpn-Bomb04" // + + //Rearming upgrade - AA def + general2[9][21] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade06" + general2[9][22] RESEARCHSTAT "R-Defense-SamSite1" //Avenger SAM Site + general2[9][23] RESEARCHSTAT "R-Wpn-Missile-Damage03" //Avenger Damage + general2[9][24] RESEARCHSTAT "R-Wpn-Missile-ROF03" //Avenger ROF + general2[9][25] RESEARCHSTAT "R-Wpn-Missile-Accuracy02" //Avenger ROF + + // ================================================================================ + // personality GENERAL 3 (turtle) + // ================================================================================ + + + //cheap Researches + numCheapResGen3[0] INT 21 + general3Cheap[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //repair turret, pre-researched + general3Cheap[0][1] RESEARCHSTAT "R-Struc-Research-Module" + general3Cheap[0][2] RESEARCHSTAT "R-Wpn-MG-Damage01" //125% - Hardened MG Bullets + general3Cheap[0][3] RESEARCHSTAT "R-Wpn-Flamer-ROF01" //118% - Flamer Autoloader + general3Cheap[0][4] RESEARCHSTAT "R-Vehicle-Body05" //Cobra {facMod, powMod} + general3Cheap[0][5] RESEARCHSTAT "R-Vehicle-Engine01" //105% - Fuel Injection Engine + general3Cheap[0][6] RESEARCHSTAT "R-Vehicle-Metals01" //135% - Composite Alloys + general3Cheap[0][7] RESEARCHSTAT "R-Struc-RepairFacility" //repair facility {powMod - factModule-RepTurret} + + general3Cheap[0][8] RESEARCHSTAT "R-Defense-WallTower02" //Light Cannon HardPoint + general3Cheap[0][9] RESEARCHSTAT "R-Defense-WallTower01" //Heavy Machinegun Hardpoint + general3Cheap[0][10] RESEARCHSTAT "R-Defense-Tower06" //Mini-Rocket Tower {HardCrete,POD} + general3Cheap[0][11] RESEARCHSTAT "R-Wpn-Rocket02-MRL" //{POD, HE Mini-Rockets Mk2} + general3Cheap[0][12] RESEARCHSTAT "R-Defense-Pillbox06" //Lancer Tower + general3Cheap[0][13] RESEARCHSTAT "R-Sys-CBSensor-Tower01" //CB Tower + general3Cheap[0][14] RESEARCHSTAT "R-Defense-WallTower03" //Medium cannon hardpoint + general3Cheap[0][15] RESEARCHSTAT "R-Defense-HvyFlamer" //Inferno Bunker + general3Cheap[0][16] RESEARCHSTAT "R-Defense-Wall-RotMg" //Assault Gun Hardpoint + + general3Cheap[0][17] RESEARCHSTAT "R-Struc-Materials03" //*** $112 - 205% Reinforced Base Structure Materials Mk3 + general3Cheap[0][18] RESEARCHSTAT "R-Struc-RprFac-Upgrade01" //$75 Automated Repair Facility + general3Cheap[0][19] RESEARCHSTAT "R-Vehicle-Body11" //$75 Phyton + general3Cheap[0][20] RESEARCHSTAT "R-Vehicle-Prop-Tracks" // + + + numResGen3[0] INT 62 + general3[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //repair turret, pre-researched + general3[0][1] RESEARCHSTAT "R-Wpn-Flamer-ROF03" + general3[0][2] RESEARCHSTAT "R-Wpn-Flamer-Damage03" + general3[0][3] RESEARCHSTAT "R-Struc-Research-Upgrade03"// 130/160/190/(220*)/250/280/310**/340/370 + general3[0][4] RESEARCHSTAT "R-Struc-Power-Upgrade01b" // 150-01*/(175-01b)/200-01c/230-02**/260-03/290-03a + + //Cobra & Hover --------------------- + general3[0][5] RESEARCHSTAT "R-Vehicle-Body05" + general3[0][6] RESEARCHSTAT "R-Vehicle-Prop-Hover" //Hover + general3[0][7] RESEARCHSTAT "R-Defense-WallTower01" //HMG + general3[0][8] RESEARCHSTAT "R-Defense-Tower06" //POD + general3[0][9] RESEARCHSTAT "R-Wpn-Flame2" //Inferno {damage04} + general3[0][10] RESEARCHSTAT "R-Defense-MRL" //MRL + general3[0][11] RESEARCHSTAT "R-Defense-WallTower03" //MEDCann + + //Cyborg Upgrades + general3[0][12] RESEARCHSTAT "R-Cyborg-Metals04" // 135/170/205/(240*)/275/310/345**/380/415 + general3[0][13] RESEARCHSTAT "R-Cyborg-Armor-Heat01" // (145)*/190/235/270**/315/360/405/450/495 + + + //Weapon Upgrades + general3[0][14] RESEARCHSTAT "R-Wpn-MG-Damage02" //125/(150)/175/200/225/250/275/300/325 % + general3[0][15] RESEARCHSTAT "R-Wpn-Rocket-Damage02" //150% + general3[0][16] RESEARCHSTAT "R-Wpn-Rocket-ROF02" //143% + + //HardCretes & Armors + general3[0][17] RESEARCHSTAT "R-Vehicle-Armor-Heat02"//140/(180)/220/260/300/340/380/420/460 + general3[0][18] RESEARCHSTAT "R-Struc-Materials03" // 135/170/(205)/240/275/310/345* /370/405 + general3[0][19] RESEARCHSTAT "R-Defense-WallUpgrade03" // 135/170/(205)/240/275/305/340* /375/405/440/475/510 + //* Research-Upgarde-08; + + //Research and power upgrades + general3[0][20] RESEARCHSTAT "R-Struc-Research-Upgrade05"// 30/160/190/220*/(250)/280/310**/340/370 + general3[0][21] RESEARCHSTAT "R-Struc-Power-Upgrade01c" // 150-01*/175-01b/(200-01c)/230-02**/260-03/290-03a + + //Phyton - Heavy Cannon, Lancer, Assault Gun, Inferno -------------------- + general3[0][22] RESEARCHSTAT "R-Vehicle-Body11" + general3[0][23] RESEARCHSTAT "R-Defense-WallTower04" //HeavyCann {damage04} + general3[0][24] RESEARCHSTAT "R-Defense-Pillbox06" //Lancer + general3[0][25] RESEARCHSTAT "R-Defense-RotMG" //AssGun + general3[0][26] RESEARCHSTAT "R-Defense-HvyFlamer" //Inferno - Bunker + + //Cyborg Upgrades + general3[0][27] RESEARCHSTAT "R-Cyborg-Metals05" //135/170/205/240*/(275)/310/345**/380/415 + general3[0][28] RESEARCHSTAT "R-Cyborg-Armor-Heat02" //145*/(190)/235/270**/315/360/405/450/495 + + //Weapon Upgrades + general3[0][29] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + general3[0][30] RESEARCHSTAT "R-Wpn-Flamer-ROF02" //118/(143)/182 % + general3[0][31] RESEARCHSTAT "R-Wpn-MG-ROF01" //(118)/143/182 % + general3[0][32] RESEARCHSTAT "R-Wpn-Flamer-Damage04" //125/150/175/(200)/225/250/275/300/325 % + general3[0][33] RESEARCHSTAT "R-Wpn-MG-Damage04" //125/150/175/(200)/225/250/275/300/325 % + + //HardCretes & Armors + general3[0][34] RESEARCHSTAT "R-Vehicle-Armor-Heat03"//140/180/(220)/260/300/340/380/420/460 + general3[0][35] RESEARCHSTAT "R-Struc-Materials04"//135/170/205/(240)/275/310/345*/370/405 + general3[0][36] RESEARCHSTAT "R-Defense-WallUpgrade04"//135/170/205/(240)/275/305/340* /375/405/440/475/510 + + //Research and Power upgrades + general3[0][37] RESEARCHSTAT "R-Struc-Research-Upgrade07"// 30/160/190/220*/250/280/(310**)/340/370 + general3[0][38] RESEARCHSTAT "R-Struc-Power-Upgrade02" // 150-01*/175-01b/200-01c/(230-02**)/260-03/290-03a + + //Mantis-Scorpion - HVC, Assault Cannon------------------ + general3[0][39] RESEARCHSTAT "R-Vehicle-Body12" + general3[0][40] RESEARCHSTAT "R-Defense-WallTower-HPVcannon" //HVC {damage05} + general3[0][41] RESEARCHSTAT "R-Defense-Wall-VulcanCan" //AssCann {damage01/ROF03} + + //Weapon Upgrades + general3[0][42] RESEARCHSTAT "R-Wpn-Cannon-Accuracy01" //(110)/120 % + general3[0][43] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + general3[0][44] RESEARCHSTAT "R-Wpn-MG-ROF02" //118/(143)/182 % + general3[0][45] RESEARCHSTAT "R-Wpn-MG-Damage06" //125/150/175/200/225/(250)/275/300/325 % + general3[0][46] RESEARCHSTAT "R-Wpn-Flamer-Damage06" //125/150/175/200/225/(250)/275/300/325 % + + //Cyborg Upgrades + general3[0][47] RESEARCHSTAT "R-Cyborg-Metals06" //135/170/205/240*/275/(310)/345**/380/415 + general3[0][48] RESEARCHSTAT "R-Cyborg-Armor-Heat03" //145*/190/(235)/270**/315/360/405/450/495 + + //Cyborg + general3[0][49] RESEARCHSTAT "R-Cyborg-Hvywpn-Mcannon" //Super Heavy Gunner + general3[0][50] RESEARCHSTAT "R-Cyborg-Hvywpn-HPV" //Super Auto Cannon Cyborg + general3[0][51] RESEARCHSTAT "R-Cyborg-Hvywpn-Acannon" //Super HPV Cyborg + + //HardCretes & Armors + general3[0][52] RESEARCHSTAT "R-Vehicle-Armor-Heat05"//140/180/220/260/(300)/340/380/420/460 + general3[0][53] RESEARCHSTAT "R-Struc-Materials05"//135/170/205/240/(275)/310/345*/370/405 + general3[0][54] RESEARCHSTAT "R-Defense-Super-Cannon"//R-Defense-WallUpgrade05"//135/170/205/240/(275)/305/340* /375/405/440/475/510 + + //Research and Power upgrades + general3[0][55] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220*/250/280/310**/(340)/370 + general3[0][56] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01*/175-01b/200-01c/230-02**/(260-03)/290-03a + + //Leopard - Panther - Needle, Pulse Laser, Tank Killer------------------------------------------- + general3[0][57] RESEARCHSTAT "R-Vehicle-Body06" //Panther + general3[0][58] RESEARCHSTAT "R-Defense-GuardTower-Rail1" //Neelde + general3[0][59] RESEARCHSTAT "R-Defense-WallTower-PulseLas" //Pulse Laser + general3[0][60] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + general3[0][61] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + + numResGen3[1] INT 47 + + //Cyborg + general3[1][0] RESEARCHSTAT "R-Cyborg-Hvywpn-TK" // Super Tank-Killer Cyborg + general3[1][1] RESEARCHSTAT "R-Cyborg-Hvywpn-PulseLsr" //Super Pulse Laser Cyborg + general3[1][2] RESEARCHSTAT "R-Cyborg-Hvywpn-RailGunner" // Super Rail Gunner + + //Weapon Upgrades + general3[1][3] RESEARCHSTAT "R-Wpn-RocketSlow-Damage02" // 125/(150)/175/200/225/250 % + general3[1][4] RESEARCHSTAT "R-Wpn-RocketSlow-ROF01" // (118)/143/182 % + general3[1][5] RESEARCHSTAT "R-Defense-Super-Rocket"//"R-Wpn-RocketSlow-Accuracy03" // 110/120/(130) % + general3[1][6] RESEARCHSTAT "R-Wpn-Rail-ROF01" // (118)/143/182 % + general3[1][7] RESEARCHSTAT "R-Wpn-MG-Damage07" // 125/150/175/200/225/250/(275)/300/325 % + + //Tiger - Rail Gun---------------------------------------------------- + general3[1][8] RESEARCHSTAT "R-Vehicle-Body09" //Tiger + general3[1][9] RESEARCHSTAT "R-Defense-WallTower-Rail2" //Rail Gun + + //Research and Power upgrades + general3[1][10] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220* /250/280/310** /340/(370) + general3[1][11] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01* /175-01b/200-01c/230-02** /260-03/(290-03a) + + //HardCretes & Armors + general3[1][12] RESEARCHSTAT "R-Vehicle-Armor-Heat06"//140/180/220/260/300/(340)/380/420/460 + general3[1][13] RESEARCHSTAT "R-Struc-Materials06" // 135/170/205/240/275/(310)/345* /370/405 + general3[1][14] RESEARCHSTAT "R-Defense-WallUpgrade06" // 135/170/205/240/275/(305)/340* /375/405/440/475/510 + + //Weapon Upgrades + general3[1][15] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //(125)/150/175 % + general3[1][16] RESEARCHSTAT "R-Wpn-Energy-Damage01" //(125)/150/175 % + general3[1][17] RESEARCHSTAT "R-Wpn-Energy-ROF01" //(118)/143/182 % + + + //Cyborg Upgrades + general3[1][18] RESEARCHSTAT "R-Cyborg-Metals07" //135/170/205/240* /275/310/(345**)/380/415 + general3[1][19] RESEARCHSTAT "R-Cyborg-Armor-Heat04" //145* /190/235/(270**)/315/360/405/450/495 + + //Retribution - Scourge ---------------------------------------------- + general3[1][20] RESEARCHSTAT "R-Vehicle-Body07" //Retribution + general3[1][21] RESEARCHSTAT "R-Defense-WallTower-A-Tmiss" //Scourge + + //Weapon Upgrades + general3[1][22] RESEARCHSTAT "R-Wpn-Missile-Damage01" //(125)/150/175 % + general3[1][23] RESEARCHSTAT "R-Wpn-Missile-ROF01" //(118)/143/182 % + general3[1][24] RESEARCHSTAT "R-Wpn-Missile-Accuracy01" //(110)/120/182 % + + //Vengeance - Heavy Laser, Gauss Cannon ---------------------------------------------- + general3[1][25] RESEARCHSTAT "R-Vehicle-Body10" //Vengeance + general3[1][26] RESEARCHSTAT "R-Defense-HeavyLas" //Heavy Laser + general3[1][27] RESEARCHSTAT "R-Defense-WallTower-Rail3" //Gauss Cannon + + //HardCretes & Armors + general3[1][28] RESEARCHSTAT "R-Vehicle-Armor-Heat07"//140/180/220/260/300/340/(380)/420/460 + general3[1][29] RESEARCHSTAT "R-Struc-Materials07"//135/170/205/240/275/310/(345*)/370/405 + general3[1][30] RESEARCHSTAT "R-Defense-WallUpgrade07"//135/170/205/240/275/305/(340*)/375/405/440/475/510 + + //Weapon Upgrades + general3[1][31] RESEARCHSTAT "R-Wpn-Energy-Damage03" //125/150/(175) % + general3[1][32] RESEARCHSTAT "R-Wpn-Energy-ROF03" //118/143/(182) % + general3[1][33] RESEARCHSTAT "R-Wpn-Energy-Accuracy01" //110/110 % + general3[1][34] RESEARCHSTAT "R-Wpn-Rail-ROF03" // 118/143/(182) % + general3[1][35] RESEARCHSTAT "R-Wpn-Rail-Accuracy01" // 110/110 % + + //Cyborg + general3[1][36] RESEARCHSTAT "R-Cyborg-Hvywpn-A-T" //Super Scourge Cyborg + + //Cyborg Upgrades + general3[1][37] RESEARCHSTAT "R-Cyborg-Metals08" //135/170/205/240* /275/310/345** /(380)/415 + general3[1][38] RESEARCHSTAT "R-Cyborg-Armor-Heat06" //145* /190/235/270** /315/(360)/405/450/495 + + //Wyvern - Plasma Cannon ------------------------------------------------- + general3[1][39] RESEARCHSTAT "R-Vehicle-Body13" //Wyvern + general3[1][40] RESEARCHSTAT "R-Defense-PlasmaCannon" //Plasma Caanon + + //Laser Satellite + general3[1][41] RESEARCHSTAT "R-Wpn-LasSat" //LaserSat + + //Fortresses + general3[1][42] RESEARCHSTAT "R-Defense-Super-Missile" //Missile Fortress + general3[1][43] RESEARCHSTAT "R-Defense-MassDriver" //Mass Driver Fortress + + + //HardCretes & Armors + general3[1][44] RESEARCHSTAT "R-Vehicle-Armor-Heat09"//140/180/220/260/300/340/380/420/(460) + general3[1][45] RESEARCHSTAT "R-Struc-Materials09"//135/170/205/240/275/310/345* /370/405 + general3[1][46] RESEARCHSTAT "R-Defense-WallUpgrade12"//135/170/205/240/275/305/340* /375/405/440/475/510 + + /****************************/ + /* VTOL Stuff */ + /****************************/ + + numResGen3[9] INT 26 + general3[9][0] RESEARCHSTAT "R-Vehicle-Prop-Hover" + general3[9][1] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade01" + general3[9][2] RESEARCHSTAT "R-Defense-AASite-QuadBof" //Cyclone AA Site + general3[9][3] RESEARCHSTAT "R-Wpn-AAGun-ROF03" //AA ROF + general3[9][4] RESEARCHSTAT "R-Wpn-AAGun-Accuracy01" //AA Accuracy + + //Scorpion - Bug + general3[9][5] RESEARCHSTAT "R-Vehicle-Body08" //Scorpion Body + Bug + + //Lancer - HPV + general3[9][6] RESEARCHSTAT "R-Wpn-Rocket01-LtAT" //Lamcer + general3[9][7] RESEARCHSTAT "R-Wpn-Cannon4AMk1" //HPV + + //Rearming upgrade - VTOL Strike Turret + general3[9][8] RESEARCHSTAT "R-Sys-VTOLStrike-Turret01" //VTOL Strike Turret,VTOL Strike Tower detects approaching enemies + general3[9][9] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade03" + + //Mantis - Phosphor Bomb Bay - Heap Bomb Bay + general3[9][10] RESEARCHSTAT "R-Vehicle-Body12" + general3[9][11] RESEARCHSTAT "R-Wpn-Bomb03" //Phosphor BB + general3[9][12] RESEARCHSTAT "R-Wpn-Bomb02" //Heap BB + + //Rearming upgrade - AA def + general3[9][13] RESEARCHSTAT "R-Defense-AASite-QuadRotMg" //Whirlwind AA Site + general3[9][14] RESEARCHSTAT "R-Wpn-AAGun-ROF04" //AA ROF + general3[9][15] RESEARCHSTAT "R-Wpn-AAGun-Accuracy02" //AA Accuracy + general3[9][16] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade04" + + //Retaliation - Scourge Missle + general3[9][17] RESEARCHSTAT "R-Vehicle-Body03" // + general3[9][18] RESEARCHSTAT "R-Wpn-Missile2A-T" //AT + + //Retribution - Thermite BB + general3[9][19] RESEARCHSTAT "R-Vehicle-Body07" // + general3[9][20] RESEARCHSTAT "R-Wpn-Bomb04" // + + //Rearming upgrade - AA def + general3[9][21] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade06" + general3[9][22] RESEARCHSTAT "R-Defense-SamSite1" //Avenger SAM Site + general3[9][23] RESEARCHSTAT "R-Wpn-Missile-Damage03" //Avenger Damage + general3[9][24] RESEARCHSTAT "R-Wpn-Missile-ROF03" //Avenger ROF + general3[9][25] RESEARCHSTAT "R-Wpn-Missile-Accuracy02" //Avenger ROF + + + // ================================================================================ + // personality GENERAL 4 (cyborg) + // ================================================================================ + + + //cheap Researches + numCheapResGen4[0] INT 16 + + general4Cheap[0][0] RESEARCHSTAT "R-Wpn-MG-Damage01" //$18 - 125% - Hardened MG Bullets + general4Cheap[0][1] RESEARCHSTAT "R-Wpn-Flamer-ROF01" //$18 - 118% - Flamer Autoloader + general4Cheap[0][2] RESEARCHSTAT "R-Vehicle-Body05" //$37 - Cobra {facMod, powMod} + general4Cheap[0][3] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //$37 - 125% - HEAT Cannon Shells + general4Cheap[0][4] RESEARCHSTAT "R-Vehicle-Engine01" //$37 - 105% - Fuel Injection Engine + general4Cheap[0][5] RESEARCHSTAT "R-Vehicle-Metals01" //$56 - 135% - Composite Alloys + general4Cheap[0][6] RESEARCHSTAT "R-Struc-RepairFacility" //$75 - repair facility {powMod - factModule-RepTurret} + + general4Cheap[0][7] RESEARCHSTAT "R-Defense-WallTower02" //$46 - Light Cannon HardPoint + general4Cheap[0][8] RESEARCHSTAT "R-Defense-WallUpgrade01" //$37 - 135% - Improved Hardcrete + //general4Cheap[0][9] RESEARCHSTAT "R-Defense-Tower06" //$75 - Mini-Rocket Tower {HardCrete,POD} + //general4Cheap[0][10] RESEARCHSTAT "R-Wpn-Rocket02-MRL" //$75 - {POD, HE Mini-Rockets Mk2} + general4Cheap[0][9] RESEARCHSTAT "R-Defense-Pillbox06" //$46 Lancer Tower + //general4Cheap[0][12] RESEARCHSTAT "R-Defense-MRL" //$46 Mini Rocket Battery + general4Cheap[0][10] RESEARCHSTAT "R-Defense-WallTower03" //$ medium cannon hardpoint + general4Cheap[0][11] RESEARCHSTAT "R-Defense-WallTower01" //$37 - Heavy Machinegun Hardpoint + + general4Cheap[0][12] RESEARCHSTAT "R-Struc-Materials03" //*** $112 - 205% Reinforced Base Structure Materials Mk3 + general4Cheap[0][13] RESEARCHSTAT "R-Struc-RprFac-Upgrade01" //$75 Automated Repair Facility + //general4Cheap[0][17] RESEARCHSTAT "R-Vehicle-Body11" //$75 Phyton + //general4Cheap[0][18] RESEARCHSTAT "R-Vehicle-Prop-Tracks" // + general4Cheap[0][14] RESEARCHSTAT "R-Vehicle-Body08" //Scorpion + general4Cheap[0][15] RESEARCHSTAT "R-Sys-CBSensor-Tower01" //CB Tower + + + numResGen4[0] INT 53 + //standard + general4[0][0] RESEARCHSTAT "R-Sys-MobileRepairTurret01" //repair turret, pre-researched + general4[0][1] RESEARCHSTAT "R-Wpn-Flamer-ROF03" + general4[0][2] RESEARCHSTAT "R-Wpn-Flamer-Damage03" + general4[0][3] RESEARCHSTAT "R-Struc-Research-Upgrade03"// 130/160/190/(220*)/250/280/310**/340/370 + general4[0][4] RESEARCHSTAT "R-Struc-Power-Upgrade01b" // 150-01*/(175-01b)/200-01c/230-02**/260-03/290-03a + + //Cobra & Hover --------------------- + general4[0][5] RESEARCHSTAT "R-Vehicle-Body05" + general4[0][6] RESEARCHSTAT "R-Vehicle-Prop-Hover" //Hover + general4[0][7] RESEARCHSTAT "R-Defense-WallTower01" //HMG + //general4[0][8] RESEARCHSTAT "R-Defense-Tower06" //POD ** + general4[0][8] RESEARCHSTAT "R-Wpn-Flame2" //Inferno {damage04} + //general4[0][10] RESEARCHSTAT "R-Defense-MRL" //MRL ** + general4[0][9] RESEARCHSTAT "R-Defense-WallTower03" //MEDCann + + //Cyborg Upgrades + general4[0][10] RESEARCHSTAT "R-Cyborg-Metals04" // 135/170/205/(240*)/275/310/345**/380/415 + general4[0][11] RESEARCHSTAT "R-Cyborg-Armor-Heat03" // 145*/190/(235)/270**/315/360/405/450/495 + + + //Weapon Upgrades + general4[0][12] RESEARCHSTAT "R-Wpn-MG-Damage02" //125/(150)/175/200/225/250/275/300/325 % + //general4[0][15] RESEARCHSTAT "R-Wpn-Rocket-Damage02" //150% ** + //general4[0][16] RESEARCHSTAT "R-Wpn-Rocket-ROF02" //143% ** + + //HardCretes & Armors + //general4[0][17] RESEARCHSTAT "R-Vehicle-Armor-Heat02"//** 140/(180)/220/260/300/340/380/420/460 + general4[0][13] RESEARCHSTAT "R-Struc-Materials03" // 135/170/(205)/240/275/310/345* /370/405 + general4[0][14] RESEARCHSTAT "R-Defense-WallUpgrade03" // 135/170/(205)/240/275/305/340* /375/405/440/475/510 + //* Research-Upgarde-08; + + //Research and power upgrades + general4[0][15] RESEARCHSTAT "R-Struc-Research-Upgrade05"// 30/160/190/220*/(250)/280/310**/340/370 + general4[0][16] RESEARCHSTAT "R-Struc-Power-Upgrade01c" // 150-01*/175-01b/(200-01c)/230-02**/260-03/290-03a + + //Phyton - Heavy Cannon, Lancer, Assault Gun, Inferno -------------------- + //general4[0][22] RESEARCHSTAT "R-Vehicle-Body11" //** + general4[0][17] RESEARCHSTAT "R-Defense-WallTower04" //HeavyCann {damage04} + general4[0][18] RESEARCHSTAT "R-Defense-Pillbox06" //Lancer + general4[0][19] RESEARCHSTAT "R-Defense-RotMG" //AssGun + general4[0][20] RESEARCHSTAT "R-Defense-HvyFlamer" //Inferno - Bunker + + //Cyborg Upgrades + general4[0][21] RESEARCHSTAT "R-Cyborg-Metals06" //135/170/205/240*/275/(310)/345**/380/415 + //general4[0][28] RESEARCHSTAT "R-Cyborg-Armor-Heat02" //145*/(190)/235/270**/315/360/405/450/495 + + //Weapon Upgrades + general4[0][22] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + general4[0][23] RESEARCHSTAT "R-Wpn-Flamer-ROF02" //118/(143)/182 % + general4[0][24] RESEARCHSTAT "R-Wpn-MG-ROF01" //(118)/143/182 % + general4[0][25] RESEARCHSTAT "R-Wpn-Flamer-Damage04" //125/150/175/(200)/225/250/275/300/325 % + general4[0][26] RESEARCHSTAT "R-Wpn-MG-Damage04" //125/150/175/(200)/225/250/275/300/325 % + + //HardCretes & Armors + //general4[0][34] RESEARCHSTAT "R-Vehicle-Armor-Heat03"//**140/180/(220)/260/300/340/380/420/460 + general4[0][27] RESEARCHSTAT "R-Struc-Materials04"//135/170/205/(240)/275/310/345*/370/405 + general4[0][28] RESEARCHSTAT "R-Defense-WallUpgrade04"//135/170/205/(240)/275/305/340* /375/405/440/475/510 + + //Research and Power upgrades + general4[0][29] RESEARCHSTAT "R-Struc-Research-Upgrade07"// 30/160/190/220*/250/280/(310**)/340/370 + general4[0][30] RESEARCHSTAT "R-Struc-Power-Upgrade02" // 150-01*/175-01b/200-01c/(230-02**)/260-03/290-03a + + //Mantis-Scorpion - HVC, Assault Cannon------------------ + general4[0][31] RESEARCHSTAT "R-Vehicle-Body12" + general4[0][32] RESEARCHSTAT "R-Defense-WallTower-HPVcannon" //HVC {damage05} + general4[0][33] RESEARCHSTAT "R-Defense-Wall-VulcanCan" //AssCann {damage01/ROF03} + + //Weapon Upgrades + general4[0][34] RESEARCHSTAT "R-Wpn-Cannon-Accuracy01" //(110)/120 % + general4[0][35] RESEARCHSTAT "R-Wpn-Cannon-ROF04" //111/125/143/(167)/200/250 % + general4[0][36] RESEARCHSTAT "R-Wpn-MG-ROF02" //118/(143)/182 % + general4[0][37] RESEARCHSTAT "R-Wpn-MG-Damage06" //125/150/175/200/225/(250)/275/300/325 % + general4[0][38] RESEARCHSTAT "R-Wpn-Flamer-Damage06" //125/150/175/200/225/(250)/275/300/325 % + + //Cyborg Upgrades + general4[0][39] RESEARCHSTAT "R-Cyborg-Metals07" //135/170/205/240*/275/310/(345**)/380/415 + general4[0][40] RESEARCHSTAT "R-Cyborg-Armor-Heat06" //145*/190/235/270**/315/(360)/405/450/495 + + //Cyborg + general4[0][41] RESEARCHSTAT "R-Cyborg-Hvywpn-Mcannon" //Super Heavy Gunner + general4[0][42] RESEARCHSTAT "R-Cyborg-Hvywpn-HPV" //Super Auto Cannon Cyborg + general4[0][43] RESEARCHSTAT "R-Cyborg-Hvywpn-Acannon" //Super HPV Cyborg + + //HardCretes & Armors + //general4[0][52] RESEARCHSTAT "R-Vehicle-Armor-Heat05"//140/180/220/260/(300)/340/380/420/460 + general4[0][44] RESEARCHSTAT "R-Struc-Materials05"//135/170/205/240/(275)/310/345*/370/405 + general4[0][45] RESEARCHSTAT "R-Defense-Super-Cannon"//"R-Defense-WallUpgrade05"//135/170/205/240/(275)/305/340* /375/405/440/475/510 + + //Research and Power upgrades + general4[0][46] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220*/250/280/310**/(340)/370 + general4[0][47] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01*/175-01b/200-01c/230-02**/(260-03)/290-03a + + //Leopard - Panther - Needle, Pulse Laser, Tank Killer------------------------------------------- + general4[0][48] RESEARCHSTAT "R-Vehicle-Body06" //Panther + general4[0][49] RESEARCHSTAT "R-Defense-GuardTower-Rail1" //Neelde + general4[0][50] RESEARCHSTAT "R-Defense-WallTower-PulseLas" //Pulse Laser + general4[0][51] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + general4[0][52] RESEARCHSTAT "R-Defense-WallTower-HvyA-Trocket" //Tank Killer + + numResGen4[1] INT 41 + + //Cyborg + general4[1][0] RESEARCHSTAT "R-Cyborg-Hvywpn-TK" // Super Tank-Killer Cyborg + general4[1][1] RESEARCHSTAT "R-Cyborg-Hvywpn-PulseLsr" //Super Pulse Laser Cyborg + general4[1][2] RESEARCHSTAT "R-Cyborg-Hvywpn-RailGunner" // Super Rail Gunner + + //Weapon Upgrades + general4[1][3] RESEARCHSTAT "R-Wpn-RocketSlow-Damage02" // 125/(150)/175/200/225/250 % + general4[1][4] RESEARCHSTAT "R-Wpn-RocketSlow-ROF01" // (118)/143/182 % + general4[1][5] RESEARCHSTAT "R-Wpn-RocketSlow-Accuracy01" // (110)/120/130 % + general4[1][6] RESEARCHSTAT "R-Wpn-Rail-ROF01" // (118)/143/182 % + general4[1][7] RESEARCHSTAT "R-Wpn-MG-Damage07" // 125/150/175/200/225/250/(275)/300/325 % + + //Tiger - Rail Gun---------------------------------------------------- + //general4[1][8] RESEARCHSTAT "R-Vehicle-Body09" //Tiger + general4[1][8] RESEARCHSTAT "R-Defense-WallTower-Rail2" //Rail Gun + + //Research and Power upgrades + general4[1][9] RESEARCHSTAT "R-Struc-Research-Upgrade08"// 30/160/190/220* /250/280/310** /340/(370) + general4[1][10] RESEARCHSTAT "R-Struc-Power-Upgrade03" // 150-01* /175-01b/200-01c/230-02** /260-03/(290-03a) + + //HardCretes & Armors + //general4[1][12] RESEARCHSTAT "R-Vehicle-Armor-Heat06"//140/180/220/260/300/(340)/380/420/460 + general4[1][11] RESEARCHSTAT "R-Struc-Materials06" // 135/170/205/240/275/(310)/345* /370/405 + general4[1][12] RESEARCHSTAT "R-Defense-WallUpgrade06" // 135/170/205/240/275/(305)/340* /375/405/440/475/510 + + //Weapon Upgrades + general4[1][13] RESEARCHSTAT "R-Wpn-Cannon-Damage01" //(125)/150/175 % + general4[1][14] RESEARCHSTAT "R-Wpn-Energy-Damage01" //(125)/150/175 % + general4[1][15] RESEARCHSTAT "R-Wpn-Energy-ROF01" //(118)/143/182 % + + + //Cyborg Upgrades + general4[1][16] RESEARCHSTAT "R-Cyborg-Metals09" //135/170/205/240* /275/310/345**/380/(415) + general4[1][17] RESEARCHSTAT "R-Cyborg-Armor-Heat07" //145* /190/235/270**/315/360/(405)/450/495 + + //Retribution - Scourge ---------------------------------------------- + general4[1][18] RESEARCHSTAT "R-Vehicle-Body07" //Retribution + general4[1][19] RESEARCHSTAT "R-Defense-WallTower-A-Tmiss" //Scourge + + //Weapon Upgrades + general4[1][20] RESEARCHSTAT "R-Wpn-Missile-Damage01" //(125)/150/175 % + general4[1][21] RESEARCHSTAT "R-Wpn-Missile-ROF01" //(118)/143/182 % + general4[1][22] RESEARCHSTAT "R-Wpn-Missile-Accuracy01" //(110)/120/182 % + + //Vengeance - Heavy Laser, Gauss Cannon ---------------------------------------------- + //general4[1][25] RESEARCHSTAT "R-Vehicle-Body10" //Vengeance + general4[1][23] RESEARCHSTAT "R-Defense-HeavyLas" //Heavy Laser + general4[1][24] RESEARCHSTAT "R-Defense-WallTower-Rail3" //Gauss Cannon + + //HardCretes & Armors + //general4[1][28] RESEARCHSTAT "R-Vehicle-Armor-Heat07"//140/180/220/260/300/340/(380)/420/460 + general4[1][25] RESEARCHSTAT "R-Struc-Materials07"//135/170/205/240/275/310/(345*)/370/405 + general4[1][26] RESEARCHSTAT "R-Defense-WallUpgrade07"//135/170/205/240/275/305/(340*)/375/405/440/475/510 + + //Weapon Upgrades + general4[1][27] RESEARCHSTAT "R-Wpn-Energy-Damage03" //125/150/(175) % + general4[1][28] RESEARCHSTAT "R-Wpn-Energy-ROF03" //118/143/(182) % + general4[1][29] RESEARCHSTAT "R-Wpn-Energy-Accuracy01" //110/110 % + general4[1][30] RESEARCHSTAT "R-Wpn-Rail-ROF03" // 118/143/(182) % + general4[1][31] RESEARCHSTAT "R-Wpn-Rail-Accuracy01" // 110/110 % + + //Cyborg + general4[1][32] RESEARCHSTAT "R-Cyborg-Hvywpn-A-T" //Super Scourge Cyborg + + //Cyborg Upgrades + general4[1][33] RESEARCHSTAT "R-Cyborg-Metals09" //135/170/205/240* /275/310/345** /380/415 + general4[1][34] RESEARCHSTAT "R-Cyborg-Armor-Heat09" //145* /190/235/270** /315/360/405/450/495 + + //Wyvern - Plasma Cannon ------------------------------------------------- + //general4[1][39] RESEARCHSTAT "R-Vehicle-Body13" //Wyvern + general4[1][35] RESEARCHSTAT "R-Defense-PlasmaCannon" //Plasma Caanon + + //Laser Satellite + general4[1][36] RESEARCHSTAT "R-Wpn-LasSat" //LaserSat + + //Fortresses + general4[1][37] RESEARCHSTAT "R-Defense-Super-Missile" //Missile Fortress + general4[1][38] RESEARCHSTAT "R-Defense-MassDriver" //Mass Driver Fortress + + + //HardCretes & Armors + //general4[1][44] RESEARCHSTAT "R-Vehicle-Armor-Heat09"//140/180/220/260/300/340/380/420/(460) + general4[1][39] RESEARCHSTAT "R-Struc-Materials09"//135/170/205/240/275/310/345* /370/405 + general4[1][40] RESEARCHSTAT "R-Defense-WallUpgrade12"//135/170/205/240/275/305/340* /375/405/440/475/510 + + /****************************/ + /* VTOL Stuff */ + /****************************/ + + numResGen4[9] INT 26 + general4[9][0] RESEARCHSTAT "R-Vehicle-Prop-Hover" + general4[9][1] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade01" + general4[9][2] RESEARCHSTAT "R-Defense-AASite-QuadBof" //Cyclone AA Site + general4[9][3] RESEARCHSTAT "R-Wpn-AAGun-ROF03" //AA ROF + general4[9][4] RESEARCHSTAT "R-Wpn-AAGun-Accuracy01" //AA Accuracy + + //Scorpion - Bug + general4[9][5] RESEARCHSTAT "R-Vehicle-Body08" //Scorpion Body + Bug + + //Lancer - HPV + general4[9][6] RESEARCHSTAT "R-Wpn-Rocket01-LtAT" //Lamcer + general4[9][7] RESEARCHSTAT "R-Wpn-Cannon4AMk1" //HPV + + //Rearming upgrade - VTOL Strike Turret + general4[9][8] RESEARCHSTAT "R-Sys-VTOLStrike-Turret01" //VTOL Strike Turret,VTOL Strike Tower detects approaching enemies + general4[9][9] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade03" + + //Mantis - Phosphor Bomb Bay - Heap Bomb Bay + general4[9][10] RESEARCHSTAT "R-Vehicle-Body12" + general4[9][11] RESEARCHSTAT "R-Wpn-Bomb03" //Phosphor BB + general4[9][12] RESEARCHSTAT "R-Wpn-Bomb02" //Heap BB + + //Rearming upgrade - AA def + general4[9][13] RESEARCHSTAT "R-Defense-AASite-QuadRotMg" //Whirlwind AA Site + general4[9][14] RESEARCHSTAT "R-Wpn-AAGun-ROF04" //AA ROF + general4[9][15] RESEARCHSTAT "R-Wpn-AAGun-Accuracy02" //AA Accuracy + general4[9][16] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade04" + + //Retaliation - Scourge Missle + general4[9][17] RESEARCHSTAT "R-Vehicle-Body03" // + general4[9][18] RESEARCHSTAT "R-Wpn-Missile2A-T" //AT + + //Retribution - Thermite BB + general4[9][19] RESEARCHSTAT "R-Vehicle-Body07" // + general4[9][20] RESEARCHSTAT "R-Wpn-Bomb04" // + + //Rearming upgrade - AA def + general4[9][21] RESEARCHSTAT "R-Struc-VTOLPad-Upgrade06" + general4[9][22] RESEARCHSTAT "R-Defense-SamSite1" //Avenger SAM Site + general4[9][23] RESEARCHSTAT "R-Wpn-Missile-Damage03" //Avenger Damage + general4[9][24] RESEARCHSTAT "R-Wpn-Missile-ROF03" //Avenger ROF + general4[9][25] RESEARCHSTAT "R-Wpn-Missile-Accuracy02" //Avenger ROF + +}