//================================================================================= // // City Expansion Code v2.0 // Tile Improvements not goods // // mod by the Immortal Wombat, aka Ben Weaver, and Pedrunn //======================================================================================= // // Translated directly from BlueO's Original City Expansion mod. Many many thanks to him // for all his amazing work towards CtP2 //==================================================================================== //======================================== // GLOBAL VARIABLES //========================================== int_t IWX_MAXPLAYERS; int_t IWX_HUMAN; int_t IWX_PlayerAge[]; int_t REPLACEOLD; int_t DONTREDUCE1; //======================================== // Initiation and Assorted Functions //========================================== HandleEvent(BeginTurn) 'IWX_Initialization' pre { int_t i; army_t tmpArmy; if(preference("NumPlayers") > preference("MaxPlayers")){ IWX_MAXPLAYERS = preference("NumPlayers"); } else { IWX_MAXPLAYERS = preference("MaxPlayers"); } for (i = 0; i <= IWX_MAXPLAYERS; i = i + 1) { // initialize all players, so new players from revolts will be 'supported' as well // much simpler & faster like this IWX_PlayerAge[i] = 1; if(IsHumanPlayer(i)){ IWX_HUMAN = i; } } DisableTrigger('IWX_Initialization'); } int_f GetCityAge(int_t tmpExpander) { int_T tmpPlayer; int_T age; tmpPlayer = tmpExpander; if(HasAdvance(tmpPlayer, ID_ADVANCE_ARCOLOGIES)){ age = 5; } elseif(HasAdvance(tmpPlayer, ID_ADVANCE_EUGENICS)){ age = 4; } elseif (HasAdvance(tmpPlayer, ID_ADVANCE_GLOBAL_ECONOMICS)){ age = 3; } elseif (HasAdvance(tmpPlayer, ID_ADVANCE_CONCRETE)){ age = 2; } elseif (HasAdvance(tmpPlayer, ID_ADVANCE_TOOLMAKING)){ age = 1; } else { age = 0; } return age; } int_f HasAnyImps(location_t theLoc) { int_t i; int_t yes; yes=0; for(i=0; i < 68; i = i + 1){ if(TileHasImprovement(theLoc, i)){ yes = yes + 1; } } if(yes == 0){ return 0; } else { return 1; } } // ReplaceTile Fuction: // Will search through the tiles with certain 'range' and 'direction' starting from 'checkLoc' for player 'owner'. // If applicable terrain type is found for 'checkType', that terrain will be replaced accordingly. // The 'newType' parameter determines what to replace. // ('addDelete' == 1) adds the tile // ('addDelete' == 2) deletes the tile // // Only grasslands, plains, tundras, deserts, and abandoned lands can be used to expand the city. // Function returns 1 if any tile replacement took place. Returns 0 if it doesn't. int_f ReplacePCTile(int_t owner, location_t checkLoc, int_t range, int_t direction, int_t newType, int_t addDelete) { location_t tmpLoc; location_t tmp2Loc; int_t searchDirection; int_t TType; int_t count; int_t sucess; tmpLoc = checkLoc; count = range; // Searching through the tiles, clockwise. if (direction == 0) { // searchDirection = 4; } // NORTH if (direction == 1) { // 0 searchDirection = 4; } // 7 1 if (direction == 2) { // WEST 6 + 2 EAST searchDirection = 6; } // 5 3 if (direction == 3) { // 4 searchDirection = 1; } // SOUTH if (direction == 4) { // searchDirection = 6; } if (direction == 5) { searchDirection = 1; } if (direction == 6) { searchDirection = 3; } if (direction == 7) { searchDirection = 3; } while (count > 0) { TType = TerrainType(tmpLoc); if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 2){ if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_P1))) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_AR),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST)) { if(!IsHumanPlayer(owner)) { Terraform(tmpLoc, 1); } } elseif (TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA)){ FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_P1),0 ); FinishImprovements(tmpLoc); return 1; } } GetNeighbor(tmpLoc, searchDirection, tmp2Loc); tmpLoc = tmp2Loc; count = count - 1; } return 0; } int_f ReplaceACTile(int_t owner, location_t checkLoc, int_t range, int_t direction, int_t newType, int_t addDelete) { location_t tmpLoc; location_t tmp2Loc; int_t searchDirection; int_t TType; int_t count; int_t sucess; int_t replaceOld; tmpLoc = checkLoc; count = range; replaceOld = 0; // Searching through the tiles, clockwise. if (direction == 0) { // searchDirection = 4; } // NORTH if (direction == 1) { // 0 searchDirection = 4; } // 3 1 if (direction == 2) { // WEST 5 + 2 EAST searchDirection = 6; } // 6 4 if (direction == 3) { // 7 searchDirection = 1; } // SOUTH if (direction == 4) { // searchDirection = 6; } if (direction == 5) { searchDirection = 1; } if (direction == 6) { searchDirection = 3; } if (direction == 7) { searchDirection = 3; } while (count > 0) { TType = TerrainType(tmpLoc); if (replaceOld < 2) { if (cellOwner(tmpLoc) == owner && TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_P1))) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_A1),0 ); FinishImprovements(tmpLoc); replaceOld = replaceOld + 1; } } if (newType >= 1 && cellOwner(tmpLoc) == owner && addDelete == 2) { if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A2))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_AR),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { Terraform(tmpLoc, 1); } } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_TUNDRA) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT)) { if(!TilehasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A1)) && !TilehasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A2))){ FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_A1),0 ); FinishImprovements(tmpLoc); return 1; } } } if (newType >= 2 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { Terraform(tmpLoc, 1); } } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_TUNDRA) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT)) { if(!TilehasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A1)) && !TilehasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A2))){ FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_A2),0 ); FinishImprovements(tmpLoc); return 1; } } } GetNeighbor(tmpLoc, searchDirection, tmp2Loc); tmpLoc = tmp2Loc; count = count - 1; } return 0; } int_f ReplaceMCTile(int_t owner, location_t checkLoc, int_t range, int_t direction, int_t newType, int_t addDelete) { location_t tmpLoc; location_t tmp2Loc; int_t searchDirection; int_t TType; int_t count; int_t sucess; int_t replaceOld; tmpLoc = checkLoc; count = range; replaceOld = 0; // Searching through the tiles, clockwise. if (direction == 0) { // searchDirection = 4; } // NORTH if (direction == 1) { // 0 searchDirection = 4; } // 3 1 if (direction == 2) { // WEST 5 + 2 EAST searchDirection = 6; } // 6 4 if (direction == 3) { // 7 searchDirection = 1; } // SOUTH if (direction == 4) { // searchDirection = 6; } if (direction == 5) { searchDirection = 1; } if (direction == 6) { searchDirection = 3; } if (direction == 7) { searchDirection = 3; } while (count > 0) { TType = TerrainType(tmpLoc); if (replaceOld < 2) { if (cellOwner(tmpLoc) == owner && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_AR)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A2)))) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M1),0 ); FinishImprovements(tmpLoc); replaceOld = replaceOld + 1; } } if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 2 && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M2))) ) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_MR1),0 ); FinishImprovements(tmpLoc); return 1; } elseif (newType >= 2 && cellOwner(tmpLoc) == owner && addDelete == 2 && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M3)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M4)) )) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_MR2),0 ); FinishImprovements(tmpLoc); return 1; } if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { Terraform(tmpLoc, 1); } } elseif (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A1))) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M1),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA)) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M1),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType == 2 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { Terraform(tmpLoc, 1); } } elseif (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR2)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_A2))) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M2),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA)) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M2),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType == 3 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { Terraform(tmpLoc, 1); } } elseif (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR2)) ) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M3),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND)) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M4),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA)) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_M3),0 ); FinishImprovements(tmpLoc); return 1; } } GetNeighbor(tmpLoc, searchDirection, tmp2Loc); tmpLoc = tmp2Loc; count = count - 1; } return 0; } int_f ReplaceGCTile(int_t owner, location_t checkLoc, int_t range, int_t direction, int_t newType, int_t addDelete) { location_t tmpLoc; location_t tmp2Loc; int_t searchDirection; int_t TType; int_t count; int_t sucess; int_t replaceOld; tmpLoc = checkLoc; count = range; replaceOld = 0; // Searching through the tiles, clockwise. if (direction == 0) { // searchDirection = 4; } // NORTH if (direction == 1) { // 0 searchDirection = 4; } // 3 1 if (direction == 2) { // WEST 5 + 2 EAST searchDirection = 6; } // 6 4 if (direction == 3) { // 7 searchDirection = 1; } // SOUTH if (direction == 4) { // searchDirection = 6; } if (direction == 5) { searchDirection = 1; } if (direction == 6) { searchDirection = 3; } if (direction == 7) { searchDirection = 3; } while (count > 0) { TType = TerrainType(tmpLoc); if (replaceOld < 3) { if (cellOwner(tmpLoc) == owner && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M2)) )) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G1),0 ); FinishImprovements(tmpLoc); replaceOld = replaceOld + 1; } elseif (cellOwner(tmpLoc) == owner && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M3)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M4)) )) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G2),0 ); FinishImprovements(tmpLoc); replaceOld = replaceOld + 1; } } if (newType <= 2 && cellOwner(tmpLoc) == owner && addDelete == 2 && TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_G1))) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_GR),0 ); FinishImprovements(tmpLoc); return 1; } elseif (newType > 2 && cellOwner(tmpLoc) == owner && addDelete == 2 && TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_G2))) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_GR),0 ); FinishImprovements(tmpLoc); return 1; } if (cellOwner(tmpLoc) == owner && addDelete == 2 && TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_U1))) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_UR),0 ); FinishImprovements(tmpLoc); return 1; } if (newType <= 2 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { FinishImprovements(tmpLoc); Terraform(tmpLoc, 1); FinishImprovements(tmpLoc); } } if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR2))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G2),0 ); FinishImprovements(tmpLoc); return 1; } elseif(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR1))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G2),0 ); FinishImprovements(tmpLoc); return 1; }elseif(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_GR))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G1),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA) ) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G1),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType > 2 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { FinishImprovements(tmpLoc); Terraform(tmpLoc, 1); FinishImprovements(tmpLoc); } } if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_GR))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G2),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA) ) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_G2),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType > 0 && cellOwner(tmpLoc) == owner && addDelete == 1) { if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_UR))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_U1),0 ); FinishImprovements(tmpLoc); return 1; }elseif (TType == TerrainDB(TERRAIN_WATER_DEEP) || TType == TerrainDB(TERRAIN_WATER_TRENCH) || TType == TerrainDB(TERRAIN_WATER_RIFT)) { if(HasAnyImps(tmpLoc)){ Event:CutImprovements(tmpLoc); } Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_U1),0 ); return 1; } } GetNeighbor(tmpLoc, searchDirection, tmp2Loc); tmpLoc = tmp2Loc; count = count - 1; } return 0; } int_f ReplaceALTile(int_t owner, location_t checkLoc, int_t range, int_t direction, int_t newType, int_t addDelete) { // Diamond age location_t tmpLoc; location_t tmp2Loc; int_t searchDirection; int_t TType; int_t count; int_t sucess; int_t replaceOld; tmpLoc = checkLoc; count = range; replaceOld = 0; // Searching through the tiles, clockwise. if (direction == 0) { // searchDirection = 4; } // NORTH if (direction == 1) { // 0 searchDirection = 4; } // 3 1 if (direction == 2) { // WEST 5 + 2 EAST searchDirection = 6; } // 6 4 if (direction == 3) { // 7 searchDirection = 1; } // SOUTH if (direction == 4) { // searchDirection = 6; } if (direction == 5) { searchDirection = 1; } if (direction == 6) { searchDirection = 3; } if (direction == 7) { searchDirection = 3; } while (count > 0) { TType = TerrainType(tmpLoc); if (replaceOld < 10) { if (cellOwner(tmpLoc) == owner && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M2)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_G1)) )) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_D1),0 ); FinishImprovements(tmpLoc); replaceOld = replaceOld + 1; } elseif (cellOwner(tmpLoc) == owner && (TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M3)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_M4)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_G2)) )) { FinishImprovements(tmpLoc); Event: CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_D2),0 ); FinishImprovements(tmpLoc); replaceOld = replaceOld + 1; } } if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 2 && (TilehasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_D1)) || TilehasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_D2)) )) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_DR),0 ); FinishImprovements(tmpLoc); return 1; } if (cellOwner(tmpLoc) == owner && addDelete == 2 && TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_U1))) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_UR),0 ); FinishImprovements(tmpLoc); return 1; } if (newType == 1 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { FinishImprovements(tmpLoc); Terraform(tmpLoc, 1); FinishImprovements(tmpLoc); } } if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_GR)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR1)) || TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MR2))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_D1),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA) ) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_D1),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType > 1 && cellOwner(tmpLoc) == owner && addDelete == 1) { if (TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_SWAMP)) { if(!IsHumanPlayer(owner)) { FinishImprovements(tmpLoc); Terraform(tmpLoc, 1); FinishImprovements(tmpLoc); } } if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_GR))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_D2),0 ); FinishImprovements(tmpLoc); return 1; } elseif (TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA) ) { FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_D2),0 ); FinishImprovements(tmpLoc); return 1; } } if (newType > 0 && cellOwner(tmpLoc) == owner && addDelete == 1) { if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_UR))){ FinishImprovements(tmpLoc); Event:CutImprovements(tmpLoc); Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_U1),0 ); FinishImprovements(tmpLoc); return 1; }elseif (TType == TerrainDB(TERRAIN_WATER_DEEP) || TType == TerrainDB(TERRAIN_WATER_TRENCH) || TType == TerrainDB(TERRAIN_WATER_RIFT)) { if(HasAnyImps(tmpLoc)){ Event:CutImprovements(tmpLoc); } Event:CreateImprovement(owner,tmpLoc, TerrainImprovementDB(TILEIMP_U1),0 ); return 1; } } GetNeighbor(tmpLoc, searchDirection, tmp2Loc); tmpLoc = tmp2Loc; count = count - 1; } return 0; } //========================================== // ExpandCity Fuction: // Given the location of the city 'cityLoc', fuction will attempt to fill the 'numOfType' of the subcity 'tileType' // around the city. The 'owner' parameter ensures that the tiles belong to the city owner. // // Fuction begins by searching all surrounding tiles 1 radius away from the city and look for proper tiles to put // the new subcity tile 'tileType' into. If it IWXls to find such a tile 1 radius away, it'll look 2 radius away, then 3, and finally // 4 radius away. If it cannot put in all the subcity tiles, then that means there are no more room for the city // to expand. // If all the tiles are placed, returns 1. // If all the tiles are not placed, returns 0. // ('addDelete' == 1) adds the tile // ('addDelete' == 2) deletes a tile int_f ExpandCity(int_t owner, location_t cityLoc, int_t cityRadius, int_t tileType, int_t addDelete) { location_t tmpLoc; location_t tmp2Loc; int_t i; int_t j; int_t k; int_t sucess; int_t newType; int_t searchRadius; int_t addDeleteYN; int_t ownerNum; for(i=0; i < IWX_MAXPLAYERS; i=i+1){ IWX_PlayerAge[i] = GetCityAge(i); } searchRadius = 1; sucess = 0; newType = tileType; addDeleteYN = addDelete; ownerNum = owner; j = random(6); if (j == 0 || j == 5 || j == 2 || j == 7) { j = 6; } while (searchRadius <= cityRadius && sucess == 0) { tmpLoc = cityLoc; for (k = 0; k < searchRadius; k = k + 1) { GetNeighbor(tmpLoc, j, tmp2Loc); tmpLoc = tmp2Loc; } if (IWX_PlayerAge[owner] == 1) { sucess = ReplacePCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } elseif (IWX_PlayerAge[owner] == 2) { sucess = ReplaceACTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } elseif (IWX_PlayerAge[owner] == 3) { sucess = ReplaceMCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); if(addDeleteYN == 2 && sucess == 0) { sucess = ReplaceMCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } } elseif (IWX_PlayerAge[owner] == 4) { sucess = ReplaceGCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); if(addDeleteYN == 2 && sucess == 0) { sucess = ReplaceMCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } } elseif (IWX_PlayerAge[owner] == 5) { sucess = ReplaceALTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); if(addDeleteYN == 2 && sucess == 0) { sucess = ReplaceGCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } } i = j + 1; while (i != j && sucess == 0) { tmpLoc = cityLoc; for (k = 0; k < searchRadius; k = k + 1) { GetNeighbor(tmpLoc, i, tmp2Loc); tmpLoc = tmp2Loc; } if (IWX_PlayerAge[owner] == 1) { sucess = ReplacePCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } elseif (IWX_PlayerAge[owner] == 2) { sucess = ReplaceACTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } elseif (IWX_PlayerAge[owner] == 3) { sucess = ReplaceMCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); if(addDeleteYN == 2 && sucess == 0) { sucess = ReplaceMCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } } elseif (IWX_PlayerAge[owner] == 4) { sucess = ReplaceGCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); if(addDeleteYN == 2 && sucess == 0) { sucess = ReplaceMCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } } elseif (IWX_PlayerAge[owner] == 5) { sucess = ReplaceALTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); if(addDeleteYN == 2 && sucess == 0) { sucess = ReplaceGCTile(ownerNum, tmpLoc, searchRadius, j, newType, addDeleteYN); } } i = i + 1; if (i == 8) { i = 0; } } searchRadius = searchRadius + 1; } return sucess; } //======================================== // The handlers that run the show //========================================== HandleEvent(MakePop) 'expanding city' post { city_t theCity; int_t sucess; if (CityIsValid(city[0])) { REPLACEOLD = 0; theCity = city[0]; sucess = 1; if (theCity.population == 7) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 1, 1); } elseif (theCity.population == 12) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 1, 2, 1); } } elseif (theCity.population == 17) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 1, 1); } elseif (theCity.population == 21) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 2, 2, 1); } } elseif (theCity.population == 25) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 1, 1); } elseif (theCity.population == 26) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 3, 2, 1); } } elseif (theCity.population == 27) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 3, 2, 1); ExpandCity(theCity.owner, theCity.location, 3, 2, 1); ExpandCity(theCity.owner, theCity.location, 3, 3, 1); } } elseif (theCity.population == 28) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); } elseif (theCity.population == 29) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); } } elseif (theCity.population == 30) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); ExpandCity(theCity.owner, theCity.location, 4, 2, 1); ExpandCity(theCity.owner, theCity.location, 4, 3, 1); } } elseif (theCity.population == 31) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); } } elseif (theCity.population == 32) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); } elseif (theCity.population == 33) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); } } elseif (theCity.population == 54) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); ExpandCity(theCity.owner, theCity.location, 4, 2, 1); ExpandCity(theCity.owner, theCity.location, 4, 3, 1); } } elseif (theCity.population == 57) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); } } elseif (theCity.population == 60) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 1); if (sucess == 1) { ExpandCity(theCity.owner, theCity.location, 4, 2, 1); ExpandCity(theCity.owner, theCity.location, 4, 2, 1); ExpandCity(theCity.owner, theCity.location, 4, 3, 1); } } if (sucess == 0) { DONTREDUCE1 = 1; Event: KillPop(theCity); } } } void_f ReduceCity1 (city_t redCity) { city_t theCity; int_t sucess; theCity = redCity; if (theCity.population == 6) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 1, 2); } elseif (theCity.population == 11) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 2, 1, 2); } } elseif (theCity.population == 16) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 1, 2); } elseif (theCity.population == 20) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 24) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } elseif (theCity.population == 28) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 32) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } } elseif (theCity.population == 35) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } elseif (theCity.population == 38) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 41) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } } elseif (theCity.population == 44) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 47) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } elseif (theCity.population == 50) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 53) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 3, 1, 2); } } } elseif (theCity.population == 56) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 2, 1); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 2, 1, 1); } } elseif (theCity.population == 59) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 1, 1, 2); } } } } void_f ReduceCity2 (city_t redCity) { city_t theCity; int_t sucess; theCity = redCity; if (theCity.population == 7) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 1, 2); } elseif (theCity.population == 12) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 2, 1, 2); } } elseif (theCity.population == 17) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 1, 2); } elseif (theCity.population == 21) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 25) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } elseif (theCity.population == 29) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 33) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } } elseif (theCity.population == 36) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } elseif (theCity.population == 39) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 42) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } } elseif (theCity.population == 45) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 48) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } elseif (theCity.population == 51) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } elseif (theCity.population == 54) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 3, 1, 2); } } } elseif (theCity.population == 57) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 2, 1); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 2, 1, 1); } } elseif (theCity.population == 60) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 1, 1, 2); } } } } void_f ReduceCity4 (city_t redCity) { city_t theCity; int_t sucess; theCity = redCity; if (theCity.population >= 7) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 1, 2); } if (theCity.population >= 12) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 2, 1, 2); } } if (theCity.population >= 17) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 1, 2); } if (theCity.population >= 21) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } if (theCity.population >= 25) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } if (theCity.population >= 29) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } if (theCity.population >= 33) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } } if (theCity.population >= 36) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } if (theCity.population >= 39) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } if (theCity.population >= 42) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } } if (theCity.population >= 45) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } if (theCity.population >= 48) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } if (theCity.population >= 51) { sucess = ExpandCity(theCity.owner, theCity.location, 4, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 4, 1, 2); } } if (theCity.population >= 54) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 3, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 3, 1, 2); } } } if (theCity.population >= 57) { sucess = ExpandCity(theCity.owner, theCity.location, 2, 2, 1); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 2, 1, 1); } } if (theCity.population >= 60) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 3, 2); if (sucess == 0) { sucess = ExpandCity(theCity.owner, theCity.location, 1, 2, 2); if (sucess == 0) { ExpandCity(theCity.owner, theCity.location, 1, 1, 2); } } } } //======================================== // What caused the gross loss of city? //========================================== HandleEvent(KillPop) 'reducing city' post { if (DONTREDUCE1 == 0) { if (CityIsValid(city[0])) { ReduceCity1 (city[0]); } } else { DONTREDUCE1 = 0; } } HandleEvent(SlaveRaidCity) 'slave raid' post { if (CityIsValid(city[0])) { ReduceCity1 (city[0]); } } HandleEvent(UndergroundRailwayUnit) 'free slaves' post { if (CityIsValid(city[0])) { ReduceCity1 (city[0]); } } HandleEvent(CreateUnit) 'settler built' post { if (IsHumanPlayer(player[0]) && (value[0] == UnitDB(UNIT_SETTLER) || value[0] == UnitDB(UNIT_URBAN_PLANNER) || value[0] == UnitDB(UNIT_SEA_ENGINEER))) { if (CityIsValid(city[0])) { ReduceCity2(city[0]); } } } HandleEvent(NukeCity) 'city nuked' pre { if (CityIsValid(city[0])) { ReduceCity4 (city[0]); } } HandleEvent(PlagueCity) 'city plagued' pre { if (CityIsValid(city[0])) { ReduceCity4 (city[0]); } } HandleEvent(KillCity) 'city destroyed' pre { if (CityIsValid(city[0])) { ReduceCity4 (city[0]); } } HandleEvent(CreateParkUnit) 'park created' pre { if (CityIsValid(city[0])) { ReduceCity4 (city[0]); } }