Images
Natural Wonders
Ayers Rock
Grand Canyon
Angel Falls
Great Barrier Reef
Guillin Hills
Lake Baikal
Urgup Cones

Natural Wonders

Implementation of The Immortal Wombat’s Mod:

“This mod makes the world a little more interesting by adding up to 7 new features onto the map — seven of the most beautiful natural features of earth (in theory at least. my art’s not up to much).

They are: Ayers Rock, the Great Barrier Reef, the Grand Canyon, Angel Falls, Lake Baikal, the Guillin Hill, the Urgup Cones.”

The Script

//--------------------------------------------------------------------------
// MoT Mod for CTP2 (Apolyton Edition) by BureauBert
// v1.1
// http://motmod.ctp2.info
//--------------------------------------------------------------------------
//=========================================================
// Natural Wonders
// Another tile mod by the Immortal Wombat
//
// Thanks to Dale for the idea, and Martin Gühmann, for  
// GoodMod, from which the idea of using 'special' tile
// improvements and from which some of this code came.
//=========================================================


HandleEvent (CreateImprovement)'IWN_TimpOnNaturalWonderStop' pre {
	int_t IWN_tilimpcreate;
	location_t tmpLoc;
	IWN_tilimpcreate = value[0];
	tmpLoc = location[0];
	
	if (!IsHumanPlayer(player[0])&&(GetCurrentRound () > 1)) {
		if (TileHasNaturalWonder(tmpLoc)){
			return STOP;
		}
	}
	return CONTINUE;
}


//---------------------------------------
// Plant the wonders on the map
//

int_f DoNW(location_t NWonderLoc) {
	location_t	tmpLoc;
	unit_t	BarbUnit;
	tmpLoc = NWonderLoc;
	CreateUnit(0, UnitDB(UNIT_BOMBER), tmpLoc, 1, BarbUnit);
	Event:CreateImprovement(0,tmpLoc, TerrainImprovementDB(TILEIMP_BORDER), 0);
	Event: DisbandUnit(BarbUnit); 
	return 1;
}

int_f IWN_AllDone(int_t tilecounter) {
	if(IWN_AYERS && IWN_REEF && IWN_CANYON && IWN_FALL && IWN_GUILLIN && IWN_BAIKAL && IWN_URGUP) { 
		return 1;
	}
	if(tilecounter >= GetMapWidth() * GetMapHeight()) {
		return 1;
	}
	else {
		return 0;
	}
}

HandleEvent(BeginTurn) 'IWN_placeborders' pre {
	int_t i;
	int_t j;
	int_t k;
	int_t rnd;
	int_t count;
	int_t total;
	location_t tmpLoc;
	location_t tmp2Loc;
	location_t tmp3Loc;
	location_t BorderLoc;

	IWN_AYERS = 0;
	IWN_REEF = 0;
	IWN_CANYON = 0;
	IWN_FALL = 0;
	IWN_GUILLIN = 0;
	IWN_BAIKAL = 0;
	IWN_URGUP = 0;

	if(GetCurrentRound () == 0) {
		if(!HasAdvance(0, ID_ADVANCE_SUBNEURAL_ADS)) {
			GrantAdvance(0, AdvanceDB(ADVANCE_SUBNEURAL_ADS));
		}
		total = 0;
		while(!IWN_AllDone(total)) {
			i = random(GetMapWidth() - 1);
			j = random(GetMapHeight() - 1);
			MakeLocation(tmpLoc, i, j);
			
			total = total + 1;

			if(TerrainType(tmpLoc) == TerrainDB(TERRAIN_WATER_BEACH) && IWN_BAIKAL == 0) {
				count = 0;
				for(k = 0; k < 8; k = k + 1){
					if(GetNeighbor(tmpLoc, k, tmp2Loc)) {
						if(IsWater(tmp2Loc)){
							count = count + 1;
						}
					}
				}
				if(count == 0){
					if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
						IWN_BAIKAL_LOC = tmpLoc;
						IWN_BAIKAL = DoNW(BorderLoc);
					}
				}
			}
			// Find any single tile of beach surrounded by land
			//
			elseif(TerrainType(tmpLoc) == TerrainDB(TERRAIN_PLAINS) && UnitsInCell(tmpLoc) < 1 && IWN_AYERS == 0 && !TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_NW_CANYON))) {
				if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
					IWN_AYERS_LOC = tmpLoc;
					IWN_AYERS = DoNW(BorderLoc);
				}
			}
			// any plains tile
			//
			elseif(TerrainType(tmpLoc) == TerrainDB(TERRAIN_PLAINS) && UnitsInCell(tmpLoc) < 1 && IWN_CANYON == 0 && !TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_NW_AYERS))) {
				if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
					IWN_CANYON_LOC = tmpLoc;
					IWN_CANYON = DoNW(BorderLoc);
				}
			}
			// any plains tile
			//
			elseif(TerrainType(tmpLoc) == TerrainDB(TERRAIN_WATER_REEF) && IWN_REEF == 0) {
				if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
					for(k = 0; k < 8; k = k + 1) {
						if(GetNeighbor(tmpLoc, k, tmp2Loc)) {
							if(TerrainType(tmp2Loc) == TerrainDB(TERRAIN_WATER_REEF)) {
								IWN_REEF_DIR = k;
								IWN_REEF_LOC = tmpLoc;
								IWN_REEF = DoNW(BorderLoc);
							}
						}
					}
				}
			}
			// start on any reef tile, then move in a random direction, placing up to 4 more reef tile imps, 
			// to create a line of them
			//
			elseif(TerrainType(tmpLoc) == TerrainDB(TERRAIN_GRASSLAND) && UnitsInCell(tmpLoc) < 1 && IWN_GUILLIN == 0) {
				if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
					IWN_GUILLIN_LOC = tmpLoc;
					IWN_GUILLIN = DoNW(BorderLoc);
				}
			}
			// any grassland tile
			//
			elseif(TerrainType(tmpLoc) == TerrainDB(TERRAIN_HILL) && UnitsInCell(tmpLoc) < 1 && IWN_FALL == 0 && HasRiver(tmpLoc)) {
				if(GetNeighbor(tmpLoc, 6, tmp2Loc)) {
					if(HasRiver(tmp2Loc)) {
						count = 0;
						for(k = 1; k < 5; k = k + 1) {
							if(GetNeighbor(tmpLoc, k, tmp3Loc)) {
								if(k != 2 && HasRiver(tmp3Loc)) {
									count = count + 1;
								}
							}
							if(count == 0){
								if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
									IWN_FALL_LOC = tmpLoc;
									IWN_FALL = DoNW(BorderLoc);
								}
							}
						}
					}
				}
			}
			//
			// Complicated one. Only creates falls when the neighbouring tile to the south west has a river, and 
			// the other surrounding tiles do not. This creates the falls as an end-point at the source of a river
			// hence the placement in the hills.
			//
			elseif(TerrainType(tmpLoc) == TerrainDB(TERRAIN_DESERT) && UnitsInCell(tmpLoc) < 1 && IWN_URGUP == 0) {
				if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
					IWN_URGUP_LOC = tmpLoc;
					IWN_URGUP = DoNW(BorderLoc);
				}
			}
			// any desert tile
			//
		}
		Disabletrigger('IWN_placeborders');
		return CONTINUE;
	}
}

HandleEvent(BeginTurnProduction)'IWN_finishborders' post {
	int_t i;
	int_t j;
	location_t tmpLoc;
	location_t BorderLoc;

	for(i = 0; i < GetMapWidth() - 1; i = i + 1) {
		for(j = 0; j < GetMapHeight() - 1; j = j + 1) {
			MakeLocation(tmpLoc, i, j);
			if(tmpLoc == IWN_AYERS_LOC ||
			tmpLoc == IWN_REEF_LOC ||
			tmpLoc == IWN_CANYON_LOC ||
			tmpLoc == IWN_FALL_LOC ||
			tmpLoc == IWN_GUILLIN_LOC ||
			tmpLoc == IWN_BAIKAL_LOC ||
			tmpLoc == IWN_URGUP_LOC) {
				if(GetNeighbor(tmpLoc, 7, BorderLoc)) {
					FinishImprovements(BorderLoc);
				}
			}
		}
	}
	Disabletrigger('IWN_finishborders');
}

HandleEvent(BeginTurnImprovements) 'IWN_place_nw' pre{
	int_t k;
	location_t BorderLoc;
	location_t tmp2Loc;
	location_t tmpLoc;

	if(GetCurrentRound () <= 1) {
		if(IWN_BAIKAL) {
			Event:CreateImprovement(0, IWN_BAIKAL_LOC, TerrainImprovementDB(TILEIMP_NW_BAIKAL), 0);
			if(GetNeighbor(IWN_BAIKAL_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
		if(IWN_AYERS) {
			Event:CreateImprovement(0, IWN_AYERS_LOC, TerrainImprovementDB(TILEIMP_NW_AYERS), 0);
			if(GetNeighbor(IWN_AYERS_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
		if(IWN_CANYON) {
			Event:CreateImprovement(0, IWN_CANYON_LOC, TerrainImprovementDB(TILEIMP_NW_CANYON), 0);
			if(GetNeighbor(IWN_CANYON_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
		if(IWN_REEF) {
			Event:CreateImprovement(0, IWN_REEF_LOC, TerrainImprovementDB(TILEIMP_NW_REEF), 0);
			tmpLoc = IWN_REEF_LOC;
			for(k=0; k < 4; k = k + 1) {
				if(GetNeighbor(tmpLoc, IWN_REEF_DIR, tmp2Loc)) {
					tmpLoc = tmp2Loc;
					if(TerrainType(tmpLoc) == TerrainDB(TERRAIN_WATER_REEF)) {
						Event:CreateImprovement(0, tmpLoc, TerrainImprovementDB(TILEIMP_NW_REEF), 0);
					} else {
						k = 4;
					}
				}
			}
			if(GetNeighbor(IWN_REEF_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
		if(IWN_GUILLIN) {
			Event:CreateImprovement(0, IWN_GUILLIN_LOC, TerrainImprovementDB(TILEIMP_NW_GUILLIN), 0);
			if(GetNeighbor(IWN_GUILLIN_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
		if(IWN_FALL) {
			Event:CreateImprovement(0, IWN_FALL_LOC, TerrainImprovementDB(TILEIMP_NW_FALL), 0);
			if(GetNeighbor(IWN_FALL_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
		if(IWN_URGUP) {
			Event:CreateImprovement(0, IWN_URGUP_LOC, TerrainImprovementDB(TILEIMP_NW_URGUP), 0);
			if(GetNeighbor(IWN_URGUP_LOC, 7, BorderLoc)) {
				Event:CutImprovements(BorderLoc);
			}
		}
	}
	Disabletrigger('IWN_place_nw');
	return CONTINUE;
}

//---------------------------------------------------------
// finish imp and remove advance functions have to fire
// on separate handlers to place tile imp and grant advance
//

HandleEvent(BeginTurn) 'IWN_remove_sub_ads' post {
	int_t i;
	int_t j;
	location_t tmpLoc;

	if(HasAdvance(player[0], ID_ADVANCE_SUBNEURAL_ADS)) {
		RemoveAdvance(player[0], AdvanceDB(ADVANCE_SUBNEURAL_ADS));
	}
	for(i = 0; i < GetMapWidth() - 1; i = i + 1){
		for(j = 0; j < GetMapHeight() - 1; j = j + 1){
			MakeLocation(i, j, tmpLoc);
			if(TileHasNaturalWonder(tmpLoc)) {
				FinishImprovements(tmpLoc);
			}
		}
	}
}