Missile Silos

The concept of missile silos is similar to pillboxes: If you build the tile improvement "missile silo" the script creates a "missile silo"-unit that is able to carry up to 12 missiles (nukes or cruise missiles). As in Activision’s "Nuclear Detente"-scenario the nukes stored in the silos may be targeted for an automated nuclear counter-strike.

The script is also intended to make the AI move their nukes into those silos.

The advantage of storing missiles in silos instead of cities consists in not weakening the garrisons of your cities.

The Script

//--------------------------------------------------------------------------
// MoT Mod for CTP2 (Apolyton Edition) by BureauBert
// v1.1
// http://motmod.ctp2.info
//--------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// Nuclear Warfare features
// by BureauBert
// Makes missile silos functional, and makes the AI store their nukes there
////////////////////////////////////////////////////////////////////////////


/////////////////////////////////
// MISSILE SILOS
/////////////////////////////////

// Creates/removes silo unit

HandleEvent(ImprovementComplete) 'ActivateSilo' post {		
	location_t silTmpLoc;
	int_t silSiloOwner;

	silTmpLoc = location[0];
	silSiloOwner = CellOwner(location[0]);

	// If the tile has a silo ti, create silo unit

	if(TileHasImprovement(silTmpLoc, TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {	
		CreateUnit(silSiloOwner, UnitDB(MISSILE_SILO), silTmpLoc, 0);
	}
}

HandleEvent(CutImprovements) 'DeActivateSilo1' post {		
	location_t silTmpLoc;
	unit_t silTmpUnit;
	int_t silNumUnits;
	int_t silCount;
	int_t silSiloOwner;

	silTmpLoc = location[0];

	// If the tile has a Pillbox, kill the silo unit

	if(!TileHasImprovement(silTmpLoc, TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
		silSiloOwner = CellOwner(silTmpLoc);
		silNumUnits = GetUnitsAtLocation(silTmpLoc);
		for(silCount = 0; silCount < silNumUnits; silCount = silCount + 1) {
			GetUnitFromCell(silTmpLoc, silCount, silTmpUnit);
			if(silTmpUnit.valid && IsSiloUnit(silTmpUnit)) {
				KillUnit(silTmpUnit);
			}
		}
	}	
}

HandleEvent(ImprovementComplete) 'DeActivateSilo2' post {
	location_t silTmpLoc;
	unit_t silTmpUnit;
	int_t silNumUnits;
	int_t silCount;
	int_t silSiloOwner;

	silTmpLoc = location[0];	// start location

	// If the tile has no Pillbox, kill the pillbox unit

	if(!TileHasImprovement(silTmpLoc, TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
		silSiloOwner = CellOwner(silTmpLoc);
		silNumUnits = GetUnitsAtLocation(silTmpLoc);
		for(silCount = 0; silCount < silNumUnits; silCount = silCount + 1) {
			GetUnitFromCell(silTmpLoc, silCount, silTmpUnit);
			if(silTmpUnit.valid && IsSiloUnit(silTmpUnit)) {
				KillUnit(silTmpUnit);
			}
		}
	}	
}

HandleEvent(KillUnit) 'DeActivateSiloTileimp' pre {
	location_t silTmpLoc;
	unit_t silTmpUnit;

	silTmpUnit = unit[1];
	silTmpLoc = silTmpUnit.location;

	if(silTmpUnit.valid && IsSiloUnit(silTmpUnit)) {
		Event:CutImprovements(silTmpLoc);
	}
}

HandleEvent(BeginTurnUnit) 'SiloChangeOwner' pre {
	location_t silTmpLoc;
	unit_t silTmpUnit;
	int_t silUnitOwner;
	int_t silTileOwner;

	silTmpUnit = unit[0];
	silTmpLoc = silTmpUnit.location;
	silUnitOwner = silTmpUnit.owner;
	silTileOwner = CellOwner(silTmpLoc);

	if(silTmpUnit.valid && IsSiloUnit(silTmpUnit)) {
		if(silUnitOwner != silTileOwner) {
			if(TileHasImprovement(silTmpLoc, TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
				KillUnit(silTmpUnit);
				CreateUnit(silTileOwner, UnitDB(PILLBOX), silTmpLoc, 0);
			}
		}
	}
}

// Move our boom-booms to the store

HandleEvent(AddUnitToArmy) 'MoveBoomBoomToStore' post {
	unit_t		nucUnit;
	int_t		nucCountA;
	int_t		nucCountB;
	int_t		nucPlayer;
	location_t	nucLoc;
	location_t	nucLocations[];
	location_t	nucSiloLoc;
	int_t		nucDist;
	int_t		nucCheckDist;
	army_t		nucArmy;

	nucUnit = unit[0];
	nucPlayer = unit[0].owner;
	nucLoc = unit[0].location;
	nucArmy = army[0];
	nucCountB = 0;
	nucDist = 999999;

	if(!IsHumanPlayer(nucPlayer)) {
		if(nucUnit.type == UnitDB(UNIT_NUKE)) {
			for(nucCountA = 0; nucCountA < MOD_MAPLOCATIONS.#; nucCountA = nucCountA + 1) {
				if(CellOwner(MOD_MAPLOCATIONS[nucCountA]) == nucPlayer
				&& TileHasImprovement(MOD_MAPLOCATIONS[nucCountA], TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
					nucLocations[nucCountB] = MOD_MAPLOCATIONS[nucCountA];
					nucCountB = nucCountB + 1;
				}
			}
			for(nucCountA = 0; nucCountA < nucLocations.#; nucCountA = nucCountA + 1) {
				nucCheckDist = Distance(nucLoc, nucLocations[nucCountA]);
				if(nucCheckDist < nucDist
				&& UnitsInCell(nucLocations[nucCountA]) < 13) {
					nucDist = nucCheckDist;
					nucSiloLoc = nucLocations[nucCountA];
				}
			}
			if(nucDist < 999999) {
				MoveArmyToTarget(nucArmy, nucSiloLoc);
			}
		}
	}
}