Changeset - r13298:ddbc752190f3
[Not reviewed]
master
0 3 0
rubidium - 15 years ago 2009-10-20 12:31:11
rubidium@openttd.org
(svn r17817) -Codechange: MakeWater actually made sea tiles, so rename it to MakeSea and unduplicate the code to make sea, rivers and canals.
3 files changed with 42 insertions and 29 deletions:
0 comments (0 inline, 0 general)
src/saveload/afterload.cpp
Show inline comments
 
@@ -905,49 +905,49 @@ bool AfterLoadGame()
 
								t,
 
								GetTileOwner(t),
 
								axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
 
								GetRailType(t)
 
							);
 
						} else {
 
							TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0;
 

	
 
							MakeRoadNormal(
 
								t,
 
								axis == AXIS_X ? ROAD_Y : ROAD_X,
 
								ROADTYPES_ROAD,
 
								town,
 
								GetTileOwner(t), OWNER_NONE
 
							);
 
						}
 
					} else {
 
						if (GB(_m[t].m5, 3, 2) == 0) {
 
							MakeClear(t, CLEAR_GRASS, 3);
 
						} else {
 
							if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
 
								MakeShore(t);
 
							} else {
 
								if (GetTileOwner(t) == OWNER_WATER) {
 
									MakeWater(t);
 
									MakeSea(t);
 
								} else {
 
									MakeCanal(t, GetTileOwner(t), Random());
 
								}
 
							}
 
						}
 
					}
 
					SetBridgeMiddle(t, axis);
 
				} else { // ramp
 
					Axis axis = (Axis)GB(_m[t].m5, 0, 1);
 
					uint north_south = GB(_m[t].m5, 5, 1);
 
					DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south));
 
					TransportType type = (TransportType)GB(_m[t].m5, 1, 2);
 

	
 
					_m[t].m5 = 1 << 7 | type << 2 | dir;
 
				}
 
			}
 
		}
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_TRAIN && v->type != VEH_ROAD) continue;
 
			if (IsBridgeTile(v->tile)) {
 
				DiagDirection dir = GetTunnelBridgeDirection(v->tile);
 

	
 
				if (dir != DirToDiagDir(v->direction)) continue;
 
@@ -1463,49 +1463,49 @@ bool AfterLoadGame()
 
	if (CheckSavegameVersion(84)) {
 
		/* Set all share owners to INVALID_COMPANY for
 
		 * 1) all inactive companies
 
		 *     (when inactive companies were stored in the savegame - TTD, TTDP and some
 
		 *      *really* old revisions of OTTD; else it is already set in InitializeCompanies())
 
		 * 2) shares that are owned by inactive companies or self
 
		 *     (caused by cheating clients in earlier revisions) */
 
		FOR_ALL_COMPANIES(c) {
 
			for (uint i = 0; i < 4; i++) {
 
				CompanyID company = c->share_owners[i];
 
				if (company == INVALID_COMPANY) continue;
 
				if (!Company::IsValidID(company) || company == c->index) c->share_owners[i] = INVALID_COMPANY;
 
			}
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(86)) {
 
		for (TileIndex t = 0; t < map_size; t++) {
 
			/* Move river flag and update canals to use water class */
 
			if (IsTileType(t, MP_WATER)) {
 
				if (GetWaterClass(t) != WATER_CLASS_RIVER) {
 
					if (IsWater(t)) {
 
						Owner o = GetTileOwner(t);
 
						if (o == OWNER_WATER) {
 
							MakeWater(t);
 
							MakeSea(t);
 
						} else {
 
							MakeCanal(t, o, Random());
 
						}
 
					} else if (IsShipDepot(t)) {
 
						Owner o = (Owner)_m[t].m4; // Original water owner
 
						SetWaterClass(t, o == OWNER_WATER ? WATER_CLASS_SEA : WATER_CLASS_CANAL);
 
					}
 
				}
 
			}
 
		}
 

	
 
		/* Update locks, depots, docks and buoys to have a water class based
 
		 * on its neighbouring tiles. Done after river and canal updates to
 
		 * ensure neighbours are correct. */
 
		for (TileIndex t = 0; t < map_size; t++) {
 
			if (GetTileSlope(t, NULL) != SLOPE_FLAT) continue;
 

	
 
			if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false);
 
			if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t, false);
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(87)) {
 
		for (TileIndex t = 0; t < map_size; t++) {
src/water_cmd.cpp
Show inline comments
 
@@ -144,49 +144,49 @@ CommandCost CmdBuildShipDepot(TileIndex 
 
		depot->town_index = ClosestTownFromTile(tile, UINT_MAX)->index;
 

	
 
		MakeShipDepot(tile,  _current_company, depot->index, DEPOT_NORTH, axis, wc1);
 
		MakeShipDepot(tile2, _current_company, depot->index, DEPOT_SOUTH, axis, wc2);
 
		MarkTileDirtyByTile(tile);
 
		MarkTileDirtyByTile(tile2);
 
	}
 

	
 
	return CommandCost(EXPENSES_CONSTRUCTION, _price.build_ship_depot);
 
}
 

	
 
void MakeWaterKeepingClass(TileIndex tile, Owner o)
 
{
 
	assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile) || IsOilRig(tile))) || IsTileType(tile, MP_INDUSTRY));
 

	
 
	WaterClass wc = GetWaterClass(tile);
 

	
 
	/* Autoslope might turn an originally canal or river tile into land */
 
	uint z;
 
	if (GetTileSlope(tile, &z) != SLOPE_FLAT) wc = WATER_CLASS_INVALID;
 

	
 
	if (wc == WATER_CLASS_SEA && z > 0) wc = WATER_CLASS_CANAL;
 

	
 
	switch (wc) {
 
		case WATER_CLASS_SEA:   MakeWater(tile);              break;
 
		case WATER_CLASS_SEA:   MakeSea(tile);                break;
 
		case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break;
 
		case WATER_CLASS_RIVER: MakeRiver(tile, Random());    break;
 
		default:                DoClearSquare(tile);          break;
 
	}
 
}
 

	
 
static CommandCost RemoveShipDepot(TileIndex tile, DoCommandFlag flags)
 
{
 
	if (!IsShipDepot(tile)) return CMD_ERROR;
 
	if (!CheckTileOwnership(tile)) return CMD_ERROR;
 

	
 
	TileIndex tile2 = GetOtherShipDepotTile(tile);
 

	
 
	/* do not check for ship on tile when company goes bankrupt */
 
	if (!(flags & DC_BANKRUPT)) {
 
		if (!EnsureNoVehicleOnGround(tile) || !EnsureNoVehicleOnGround(tile2)) return CMD_ERROR;
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		/* Kill the depot, which is registered at the northernmost tile. Use that one */
 
		delete Depot::GetByTile(tile);
 

	
 
		MakeWaterKeepingClass(tile,  GetTileOwner(tile));
 
		MakeWaterKeepingClass(tile2, GetTileOwner(tile2));
 
@@ -316,49 +316,49 @@ CommandCost CmdBuildCanal(TileIndex tile
 
	if (y < sy) Swap(y, sy);
 
	size_x = (x - sx) + 1;
 
	size_y = (y - sy) + 1;
 

	
 
	/* Outside the editor you can only drag canals, and not areas */
 
	if (_game_mode != GM_EDITOR && (sx != x && sy != y)) return CMD_ERROR;
 

	
 
	TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
 
		CommandCost ret;
 

	
 
		Slope slope = GetTileSlope(tile, NULL);
 
		if (slope != SLOPE_FLAT && (p2 != 2 || !IsInclinedSlope(slope))) {
 
			return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
 
		}
 

	
 
		/* can't make water of water! */
 
		if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || p2 == 1)) continue;
 

	
 
		ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
		if (CmdFailed(ret)) return ret;
 
		cost.AddCost(ret);
 

	
 
		if (flags & DC_EXEC) {
 
			if (TileHeight(tile) == 0 && p2 == 1) {
 
				MakeWater(tile);
 
				MakeSea(tile);
 
			} else if (p2 == 2) {
 
				MakeRiver(tile, Random());
 
			} else {
 
				MakeCanal(tile, _current_company, Random());
 
			}
 
			MarkTileDirtyByTile(tile);
 
			MarkCanalsAndRiversAroundDirty(tile);
 
		}
 

	
 
		cost.AddCost(_price.clear_water);
 
	}
 

	
 
	if (cost.GetCost() == 0) {
 
		return_cmd_error(STR_ERROR_ALREADY_BUILT);
 
	} else {
 
		return cost;
 
	}
 
}
 

	
 
static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
 
{
 
	switch (GetWaterTileType(tile)) {
 
		case WATER_TILE_CLEAR:
 
			if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
 
@@ -926,49 +926,49 @@ void DoFloodTile(TileIndex target)
 
				if (!IsSlopeWithOneCornerRaised(tileh)) {
 
					SetTreeGroundDensity(target, TREE_GROUND_SHORE, 3);
 
					MarkTileDirtyByTile(target);
 
					flooded = true;
 
					break;
 
				}
 
			/* FALL THROUGH */
 
			case MP_CLEAR:
 
				if (CmdSucceeded(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
 
					MakeShore(target);
 
					MarkTileDirtyByTile(target);
 
					flooded = true;
 
				}
 
				break;
 

	
 
			default:
 
				break;
 
		}
 
	} else {
 
		/* Flood vehicles */
 
		FloodVehicles(target);
 

	
 
		/* flood flat tile */
 
		if (CmdSucceeded(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
 
			MakeWater(target);
 
			MakeSea(target);
 
			MarkTileDirtyByTile(target);
 
			flooded = true;
 
		}
 
	}
 

	
 
	if (flooded) {
 
		/* Mark surrounding canal tiles dirty too to avoid glitches */
 
		MarkCanalsAndRiversAroundDirty(target);
 

	
 
		/* update signals if needed */
 
		UpdateSignalsInBuffer();
 
	}
 

	
 
	_current_company = OWNER_NONE;
 
}
 

	
 
/**
 
 * Drys a tile up.
 
 */
 
static void DoDryUp(TileIndex tile)
 
{
 
	_current_company = OWNER_WATER;
 

	
 
	switch (GetTileType(tile)) {
 
@@ -1046,49 +1046,49 @@ void TileLoop_Water(TileIndex tile)
 
				if ((dest_behaviour == FLOOD_ACTIVE) || (dest_behaviour == FLOOD_PASSIVE)) return;
 
			}
 
			DoDryUp(tile);
 
			break;
 
		}
 

	
 
		default: return;
 
	}
 
}
 

	
 
void ConvertGroundTilesIntoWaterTiles()
 
{
 
	TileIndex tile;
 
	uint z;
 
	Slope slope;
 

	
 
	for (tile = 0; tile < MapSize(); ++tile) {
 
		slope = GetTileSlope(tile, &z);
 
		if (IsTileType(tile, MP_CLEAR) && z == 0) {
 
			/* Make both water for tiles at level 0
 
			 * and make shore, as that looks much better
 
			 * during the generation. */
 
			switch (slope) {
 
				case SLOPE_FLAT:
 
					MakeWater(tile);
 
					MakeSea(tile);
 
					break;
 

	
 
				case SLOPE_N:
 
				case SLOPE_E:
 
				case SLOPE_S:
 
				case SLOPE_W:
 
					MakeShore(tile);
 
					break;
 

	
 
				default:
 
					uint check_dirs = _flood_from_dirs[slope & ~SLOPE_STEEP];
 
					uint dir;
 
					FOR_EACH_SET_BIT(dir, check_dirs) {
 
						TileIndex dest = TILE_ADD(tile, TileOffsByDir((Direction)dir));
 
						Slope slope_dest = GetTileSlope(dest, NULL) & ~SLOPE_STEEP;
 
						if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest)) {
 
							MakeShore(tile);
 
							break;
 
						}
 
					}
 
					break;
 
			}
 
		}
 
	}
src/water_map.h
Show inline comments
 
@@ -127,95 +127,108 @@ static inline DiagDirection GetShipDepot
 
}
 

	
 
static inline bool IsLock(TileIndex t)
 
{
 
	return IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END);
 
}
 

	
 
static inline DiagDirection GetLockDirection(TileIndex t)
 
{
 
	return (DiagDirection)GB(_m[t].m5, 0, 2);
 
}
 

	
 
static inline byte GetSection(TileIndex t)
 
{
 
	assert(GetWaterTileType(t) == WATER_TILE_LOCK || GetWaterTileType(t) == WATER_TILE_DEPOT);
 
	return GB(_m[t].m5, 0, 4);
 
}
 

	
 
static inline byte GetWaterTileRandomBits(TileIndex t)
 
{
 
	return _m[t].m4;
 
}
 

	
 

	
 
static inline void MakeWater(TileIndex t)
 
{
 
	SetTileType(t, MP_WATER);
 
	SetTileOwner(t, OWNER_WATER);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = WATER_CLASS_SEA;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = 0;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
 
}
 

	
 
static inline void MakeShore(TileIndex t)
 
{
 
	SetTileType(t, MP_WATER);
 
	SetTileOwner(t, OWNER_WATER);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = 0;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = 1;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
 
}
 

	
 
static inline void MakeRiver(TileIndex t, uint8 random_bits)
 
/**
 
 * Helper function for making a watery tile.
 
 * @param t The tile to change into water
 
 * @param o The owner of the water
 
 * @param wc The class of water the tile has to be
 
 * @param random_bits Eventual random bits to be set for this tile
 
 */
 
static inline void MakeWater(TileIndex t, Owner o, WaterClass wc, uint8 random_bits)
 
{
 
	SetTileType(t, MP_WATER);
 
	SetTileOwner(t, OWNER_WATER);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = WATER_CLASS_RIVER;
 
	_m[t].m3 = wc;
 
	_m[t].m4 = random_bits;
 
	_m[t].m5 = 0;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
 
}
 

	
 
/**
 
 * Make a sea tile.
 
 * @param t The tile to change into sea
 
 */
 
static inline void MakeSea(TileIndex t)
 
{
 
	MakeWater(t, OWNER_WATER, WATER_CLASS_SEA, 0);
 
}
 

	
 
/**
 
 * Make a river tile
 
 * @param t The tile to change into river
 
 * @param random_bits Random bits to be set for this tile
 
 */
 
static inline void MakeRiver(TileIndex t, uint8 random_bits)
 
{
 
	MakeWater(t, OWNER_WATER, WATER_CLASS_RIVER, random_bits);
 
}
 

	
 
/**
 
 * Make a canal tile
 
 * @param t The tile to change into canal
 
 * @param o The owner of the canal
 
 * @param random_bits Random bits to be set for this tile
 
 */
 
static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits)
 
{
 
	assert(o != OWNER_WATER);
 
	SetTileType(t, MP_WATER);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = WATER_CLASS_CANAL;
 
	_m[t].m4 = random_bits;
 
	_m[t].m5 = 0;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
 
	MakeWater(t, o, WATER_CLASS_CANAL, random_bits);
 
}
 

	
 
static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart base, Axis a, WaterClass original_water_class)
 
{
 
	SetTileType(t, MP_WATER);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = did;
 
	_m[t].m3 = original_water_class;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = base + a * 2;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
 
}
 

	
 
static inline void MakeLockTile(TileIndex t, Owner o, byte section, WaterClass original_water_class)
 
{
 
	SetTileType(t, MP_WATER);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = original_water_class;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = section;
 
	SB(_m[t].m6, 2, 4, 0);
 
	_me[t].m7 = 0;
0 comments (0 inline, 0 general)