location_t CTC_TAR_LOC[]; int_t CTC_TAR_LOC_INDEX; army_t CTC_FIELD_ARMY[]; int_t CTC_FIELD_ARMY_INDEX; army_t CTC_TO_TRANSPORT[]; int_t CTC_TO_TRANSPORT_INDEX; army_t CTC_FRO_TRANSPORT[]; int_t CTC_FRO_TRANSPORT_INDEX; int_t CTC_THE_ENEMY; int_t CTC_LAND_TACTICS_ON_FLG; int_t TMP_DIR; int_t CTC_AT_VAL; int_t CTC_DEF_VAL; int_t CTC_RAN_VAL; int_t CTC_HP_VAL; // for test message: int_t CTC_AT_VAL0; int_t CTC_DEF_VAL0; int_t CTC_RAN_VAL0; int_t CTC_HP_VAL0; int_t CTC_AT_VALD; int_t CTC_DEF_VALD; int_t CTC_RAN_VALD; int_t CTC_HP_VALD; void_f MoveShipsToTarget(army_t theArmy, location_t theLoc){ army_t tmpArmy; unit_t tmpUnit; location_t tmpLoc; location_t newLoc; int_t i; int_t direction; int_t tmpDist; int_t newDist; tmpArmy=theArmy; tmpLoc=theLoc; tmpDist=Distance(tmpArmy.location,tmpLoc); direction=-1; for (i=0;i<8;i=i+1){ GetNeighbor(tmpArmy.location,i,newLoc); if (CTC_IsSeaTerrain(newLoc)){ newDist=Distance(tmpLoc,newLoc); if (newDist-1){ tmpDist=99999; for (i=0;i (300*enemyAtVal)/1000 && ourDefVal> (300*enemyDefVal)/1000 && ourRanVal>= (100*enemyRanVal)/1000 // '=' in case there's no ranged units in either army && ourHPVal> (700*enemyHPVal)/1000 ){ return 1; } else{ return 2; } } elseif (theFlag==0){//attacking an army if (ourAtVal > (250*enemyAtVal)/1000 && ourDefVal> (250*enemyDefVal)/1000 && ourRanVal>= (100*enemyRanVal)/1000 // '=' in case there's no ranged units in either army && ourHPVal> (650*enemyHPVal)/1000 ){ return 1; } else{ return 3; } } } } return 0; } int_f CTC_FindNearestTarget(army_t theArmy){ int_t i; int_t tmpDist; int_t smlDist; int_t target; army_t tmpArmy; tmpArmy=theArmy; smlDist=9999;//max squared dist to look for target, could be variable for (i=0;i3){ CTC_TAR_LOC[CTC_TAR_LOC_INDEX]=tmpLoc; CTC_TAR_LOC_INDEX=CTC_TAR_LOC_INDEX+1; value[0]=CTC_GetArmyType(hisArmy); message(1,'TestGetArmyType'); } } } } } } } GetNeighbor(ourArmy.location, 4, tmpLoc); GetNeighbor(tmploc, 4, centerLoc); for (i=0;i<8;i=i+1){ GetNeighbor(centerloc, i, tmpLoc); if (!CTC_IsSeaTerrain(tmpLoc)){ if (GetUnitsAtLocation(tmpLoc)) { if (!GetCityByLocation(tmpLoc,tmpCity)){ knownArmy=0; for (j=0;j3){ CTC_TAR_LOC[CTC_TAR_LOC_INDEX]=tmpLoc; CTC_TAR_LOC_INDEX=CTC_TAR_LOC_INDEX+1; value[0]=CTC_GetArmyType(hisArmy); message(1,'TestGetArmyType'); } } } } } } } GetNeighbor(ourArmy.location, 0, tmpLoc); GetNeighbor(tmploc, 1, centerLoc); for (i=0;i<8;i=i+1){ GetNeighbor(centerloc, i, tmpLoc); if (!CTC_IsSeaTerrain(tmpLoc)){ if (GetUnitsAtLocation(tmpLoc)) { if (!GetCityByLocation(tmpLoc,tmpCity)){ knownArmy=0; for (j=0;j3){ CTC_TAR_LOC[CTC_TAR_LOC_INDEX]=tmpLoc; CTC_TAR_LOC_INDEX=CTC_TAR_LOC_INDEX+1; value[0]=CTC_GetArmyType(hisArmy); message(1,'TestGetArmyType'); } } } } } } } GetNeighbor(ourArmy.location, 7, tmpLoc); GetNeighbor(tmploc, 6, centerLoc); for (i=0;i<8;i=i+1){ GetNeighbor(centerloc, i, tmpLoc); if (!CTC_IsSeaTerrain(tmpLoc)){ if (GetUnitsAtLocation(tmpLoc)) { if (!GetCityByLocation(tmpLoc,tmpCity)){ knownArmy=0; for (j=0;j3){ CTC_TAR_LOC[CTC_TAR_LOC_INDEX]=tmpLoc; CTC_TAR_LOC_INDEX=CTC_TAR_LOC_INDEX+1; value[0]=CTC_GetArmyType(hisArmy); message(1,'TestGetArmyType'); } } } } } } } } messagebox 'TestGetArmyType' { Text (ID_TestGetArmyTypeTxt ); eyepoint(CTC_TAR_LOC[CTC_TAR_LOC_INDEX-1].location); } army_t TMP_ARMY[]; location_t TMP_LOC[]; int_t TMP_FIELD_INDEX[]; int_t TMP_INDEX; void_f CTC_DoTacticalMoves(army_t theArmy, int_t availableArmy){ int_t i; int_t nearestTarget; int_t armyType; int_t targetType; int_t FMresult; int_t usedIndex; army_t tmpArmy; army_t copyArmy[]; city_t tmpCity; location_t tarLoc; location_t attLoc; tmpArmy=theArmy; nearestTarget=CTC_FindNearestTarget(tmpArmy); if (nearestTarget > -1){ tarLoc=CTC_TAR_LOC[nearestTarget]; armyType=CTC_GetArmyType(tmpArmy); if (armyType==1){//pure air squad // => check range first: event:BombardOrder(tmpArmy,tarLoc.location); } elseif (armyType==5){//pure land squad targetType=0; if (GetCityByLocation(tarLoc.location,tmpCity)){ targetType=1; } FMresult=CTC_CheckForceMatching(tmpArmy,tarLoc.location,targetType); if (FMresult){ if (FMresult==1 || tmpArmy.size>10){ player[0]=army[0].owner; //message(1,'Test_FM_VALUES'); if (SquaredDistance(tmpArmy.location,tarLoc.location)>2){ event:MovePathOrder(tmpArmy,tarLoc.location); } else{ for (i=0;i<8;i=i+1){ GetNeighbor(tmpArmy.location,i,attLoc); if (attLoc==tarLoc){ event:MoveToOrder(tmpArmy,i); i=8; } } } } else{ if (SquaredDistance(tmpArmy.location,CTC_THE_TARGET_CITY.location)>9){ event:MovePathOrder(tmpArmy,CTC_THE_TARGET_CITY.location); TMP_LOC[TMP_INDEX]=CTC_THE_TARGET_CITY.location; TMP_ARMY[TMP_INDEX]=tmpArmy; TMP_FIELD_INDEX[TMP_INDEX]=availableArmy; TMP_INDEX=TMP_INDEX+1; } } usedIndex=availableArmy; for (i=0;i= usedIndex) { CTC_FIELD_ARMY[i]=copyArmy[i+1]; } } CTC_FIELD_ARMY_INDEX=CTC_FIELD_ARMY_INDEX-1; } } } } HandleEvent(EndTurn) 'AdjustSeaTactics' post {//every turn :( int_t i; int_t j; int_t SeaTacticsChk; if (!IsHumanPlayer(player[0].owner) && player[0].owner>0){ for (i=1;i0 && CTC_SEA_TACTICS[player[0].owner]==0){ SeaTacticsChk=1; for (j=1;j0){ //someone else is using the sea tactics handlers, so SeaTacticsChk=0; j=CTC_PLAYER_COUNT; } } } if (SeaTacticsChk && CTC_THE_SEA_TARGET==0){//the sea tactics handlers are free CTC_THE_SEA_TARGET=i; CTC_THE_SEA_INVADER=player[0].owner; value[0]=CTC_THE_SEA_TARGET; value[1]=CTC_SEA_TACTICS[CTC_THE_SEA_INVADER]; value[2]=CTC_THE_SEA_INVADER; message(1,'testAdjustSeaTactics'); EnableTrigger('CTC_StartSeaTactics'); } } elseif (TurnsSinceLastWar(player[0],i)==1 && CTC_THE_SEA_TARGET==i){//peace has broken out if (CTC_SEA_TACTICS[player[0].owner]==i){ CTC_SEA_TACTICS[player[0].owner]=0; CTC_THE_SEA_INVADER=0; CTC_THE_SEA_TARGET=0; } } } } } } } messagebox 'testAdjustSeaTactics' { show(); Text (ID_testAdjustSeaTacticsTxt ); } HandleEvent(ResetAllMovement) 'CTC_StartSeaTactics' post { int_t i; int_t j; int_t locChk; location_t tmpLoc; if (player[0].owner==CTC_THE_SEA_INVADER){ CTC_SEA_TACTICS[player[0].owner]=CTC_THE_SEA_TARGET; CTC_GetLaunchCity(player[0].owner,CTC_THE_SEA_TARGET); CTC_GetTargetCity(player[0].owner,CTC_THE_SEA_TARGET); for (i=0;i<8;i=i+1){ GetNeighbor(CTC_THE_LAUNCH_CITY.location,i,tmpLoc); if (TerrainType(tmpLoc) ==13){ SEA_LAUNCH_LOC=tmpLoc; i=8; } } // preferably, find a land launchLoc adjacent to CTC_THE_LAUNCH_CITY.location locChk=0; for (i=0;i<8;i=i+1){ GetNeighbor(SEA_LAUNCH_LOC.location,i,tmpLoc); if (tmpLoc.location != CTC_THE_LAUNCH_CITY.location){ if (!CTC_IsSeaTerrain(tmpLoc)){ locChk=1; i=8; } } } if (locChk){ LAND_LAUNCH_LOC=tmpLoc; } else{// it might be on a one tile island LAND_LAUNCH_LOC=CTC_THE_LAUNCH_CITY.location; } CTC_FRO_TRANSPORT_INDEX=0; CTC_TO_TRANSPORT_INDEX=0; army_t ourArmy; city_t tmpCity; unit_t tmpUnit; for (i=0;i0){ if (AtWarCount(player[0].owner) == 1){ For (i=1; i< CTC_PLAYER_COUNT; i=i+1){ if (IsPlayerAlive(i) ){ if (AtWarWith(player[0].owner,i) ) {// && IsHumanPlayer(i) CTC_THE_ENEMY=i; i=CTC_PLAYER_COUNT; } } } } if (CTC_THE_ENEMY){ if (CTC_SEA_TACTICS[player[0].owner]>0){ value[0]=CTC_SEA_TACTICS[player[0].owner]; message(1,'SeaTacticsEnabled'); EnableTrigger('CTC_TacticsPrep');//make field army arrays EnableTrigger('CTC_AI_Sea_Tactics'); EnableTrigger('CTC_BackToLaunch'); godmode(1); } elseif (CTC_SEA_TACTICS[player[0].owner]==0) { SetString(0,ID_PREPARING); message(1,'AI_Tactics'); EnableTrigger('CTC_PrepareForCrossWaterInvasion'); EnableTrigger('CTC_PreCrossWaterInvasion'); godmode(0); } else{ SetString(0,ID_LAND); message(1,'AI_Tactics'); godmode(0); } EnableTrigger('CTC_Trigger_AI_Land_Tactics'); } elseif(AtWarCount(player[0].owner)==0 && CTC_SEA_TACTICS[player[0].owner]==0){ //send transports to launch in preparation EnableTrigger('CTC_PrepareForCrossWaterInvasion'); EnableTrigger('CTC_PreCrossWaterInvasion'); godmode(0); } else{ SetString(0,ID_DEFAULT); message(1,'AI_Tactics'); godmode(0); } } } messagebox 'AI_Tactics' { //show(); Text (ID_AI_TacticsTxt ); } HandleEvent(BeginTurn) 'CTC_Trigger_AI_Land_Tactics' post { int_t lastAttack; int_t numAI; int_t TacticsOnFlg; int_t i; int_t diffLev; location_t tmpLoc; diffLev=preference("Difficulty"); TacticsOnFlg=0; CTC_LAND_TACTICS_ON_FLG=0; if (GetLastHotWarAttack(CTC_THE_ENEMY,player[0]) < GetLastHotWarAttack(player[0],CTC_THE_ENEMY)){ lastAttack=GetLastHotWarAttack(player[0],CTC_THE_ENEMY); } else{ lastAttack=GetLastHotWarAttack(CTC_THE_ENEMY,player[0]); } if (HasAdvance(player[0].owner,ID_ADVANCE_TANK_WARFARE)){ if (lastAttack > 7-diffLev){ TacticsOnFlg=1; } } elseif (HasAdvance(player[0].owner,ID_ADVANCE_GUNPOWDER) ){ if (lastAttack > 8-diffLev){ TacticsOnFlg=1; } } else{ if (lastAttack > 9-diffLev){ TacticsOnFlg=1; } } numAI=0; for (i=0;i 10){ event:ActivateAllUnits(ourArmy.location); } } } } } for (i=0;i -1){// it's on land and not in a city CTC_DoTacticalMoves(army[0],availableArmy); } } } void_f CTC_DoFieldArmyMoves(army_t theArmy, int_t theFieldArmyIndex){ int_t i; int_t usedIndex; army_t tmpArmy; army_t copyTransport[]; tmpArmy=theArmy; if (SquaredDistance(tmpArmy.location,CTC_THE_LAUNCH_CITY.location)< SquaredDistance(tmpArmy.location,CTC_THE_TARGET_CITY.location)){ usedIndex=-1; for (i=0;i -1){ CTC_TO_TRANSPORT[CTC_TO_TRANSPORT_INDEX]=CTC_FRO_TRANSPORT[usedIndex]; CTC_TO_TRANSPORT_INDEX=CTC_TO_TRANSPORT_INDEX+1; for (i=0;i= usedIndex) { CTC_FRO_TRANSPORT[i]=copyTransport[i+1]; } } CTC_FRO_TRANSPORT_INDEX=CTC_FRO_TRANSPORT_INDEX-1; } if (usedIndex == -1){//didn't board transport event:MovePathOrder(tmpArmy,LAND_LAUNCH_LOC.location); //TMP_LOC[0]=tmpArmy.location; //message(1,'SeaTacticsLandArmy'); } } elseif (CTC_LAND_TACTICS_ON_FLG){ // remark: very rare occasion where the function bug // applys to int function parameters? Or it may be something different. int_t newIndex; newIndex=theFieldArmyIndex; CTC_DoTacticalMoves(tmpArmy,newIndex); } } void_f CTC_DoToTransportMoves(army_t theArmy){ int_t i; army_t tmpArmy; location_t tmpLoc; city_t tmpCity; tmpArmy=theArmy; if (SquaredDistance(tmpArmy.location,CTC_SEA_TAR_LOC[tmpArmy.owner]) < 5){ for (i=0;i<8;i=i+1){ GetNeighbor(tmpArmy.location,i,tmpLoc); if (!CTC_IsSeaTerrain(tmpLoc)){ if (!GetCityByLocation(tmpLoc,tmpCity)){ if (GetUnitsAtLocation(tmpLoc) == 0){ event:UnloadOrder(tmpArmy,tmpLoc); i=8; } } } } // it's now a FRO_TRANSPORT // when unloaded, send it back } else{ int_t tmpDist; int_t newDist; int_t dir; int_t j; location_t moveLoc; location_t nextLoc; moveLoc=tmpArmy.location; for (j=1;j<10;j=j+1){ tmpDist=Distance(moveLoc.location,CTC_SEA_TAR_LOC[tmpArmy.owner].location); //get the approx direction for (i=0;i<8;i=i+1){ GetNeighbor(moveLoc.location,i,tmpLoc); newDist=Distance(tmpLoc,CTC_SEA_TAR_LOC[tmpArmy.owner].location); if (newDist2){ event:MovePathOrder(tmpArmy,SEA_LAUNCH_LOC.location); location[0]=SEA_LAUNCH_LOC.location; message(1,'SeaTacticsTransport'); } else{ for (i=0;i<8;i=i+1){ GetNeighbor(tmpArmy.location,i,tmpLoc); if (tmpLoc.location == SEA_LAUNCH_LOC.location){ event:MoveToOrder(tmpArmy,i); i=8; } } } } HandleEvent(BeginTurnArmy) 'CTC_AI_Sea_Tactics' pre { int_t i; int_t availableArmy; location_t tmpLoc; city_t tmpCity; unit_t tmpUnit; if (ArmyIsValid(army[0])){ availableArmy=-1; for (i=0;i -1){// it's a field army CTC_DoFieldArmyMoves(army[0],availableArmy); } elseif (CTC_GetArmyType(army[0])==2){//pure sea squad availableArmy=-1; for (i=0;i -1){// it's a TO_TRANSPORT CTC_DoToTransportMoves(army[0]); } else{ for (i=0;i -1){// it's a FRO_TRANSPORT value[0]=availableArmy; message(1,'FroTransportIndex'); CTC_DoFroTransportMoves(army[0]); } else{//if it's a new transport put it in the fro array for (i=0;i-1){ for (i=0;i= killedIndex) { CTC_FRO_TRANSPORT[i]=copyTransport[i+1]; } } CTC_FRO_TRANSPORT_INDEX=CTC_FRO_TRANSPORT_INDEX-1; } else{ for (i=0;i-1){ for (i=0;i= killedIndex) { CTC_TO_TRANSPORT[i]=copyTransport[i+1]; } } CTC_TO_TRANSPORT_INDEX=CTC_TO_TRANSPORT_INDEX-1; } } message(1,'TestKill'); } } messagebox 'TestKill' { Text (ID_TestKillTxt ); } messagebox 'SeaTacticsTransport' { Text (ID_SeaTacticsTransportTxt ); eyepoint(location[0].location); } messagebox 'SeaTacticsLandArmy' { //show(); eyepoint(TMP_LOC[0].location); } messagebox 'FoundTo_Transport' { Text (ID_To_TransportTxt ); eyepoint(location[0].location); } HandleEvent(UnloadOrder) 'CTC_BackToLaunch' post { int_t i; int_t j; int_t dir; int_t usedIndex; location_t tmpLoc; usedIndex=-1; for (i=0;i-1){ event:MoveToOrder(army[0],dir); } } for (i=0;i=usedIndex ) { CTC_TO_TRANSPORT[i]=copyArmy[i+1]; } } CTC_TO_TRANSPORT_INDEX=CTC_TO_TRANSPORT_INDEX-1; } } messagebox 'FoundFro_Transport' { Text (ID_Fro_TransportTxt ); eyepoint(location[0].location); } HandleEvent(ResetAllMovement) 'CTC_PrepareForCrossWaterInvasion' post { int_t i; int_t theEnemy; location_t tmpLoc; theEnemy=CellOwner(CTC_SEA_TAR_LOC[player[0].owner]);//valid loc? CTC_GetLaunchCity(player[0].owner,theEnemy); for (i=0;i<8;i=i+1){ GetNeighbor(CTC_THE_LAUNCH_CITY.location,i,tmpLoc); if (TerrainType(tmpLoc) ==13){ SEA_PREP_LAUNCH_LOC=tmpLoc; i=8; } } DisableTrigger('CTC_PrepareForCrossWaterInvasion'); } HandleEvent(BeginTurnArmy) 'CTC_PreCrossWaterInvasion' pre { int_t i; unit_t tmpUnit; for (i=0;i