Changeset - r6134:aa2aee9f9144
[Not reviewed]
master
0 5 1
tron - 17 years ago 2007-02-24 09:42:39
tron@openttd.org
(svn r8876) -Fix

Replace tests with magic numbers by a simple extraction template for command parameters
6 files changed with 58 insertions and 28 deletions:
0 comments (0 inline, 0 general)
src/cmd_helper.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#ifndef CMD_HELPER_H
 
#define CMD_HELPER_H
 

	
 
#include "direction.h"
 
#include "macros.h"
 
#include "road.h"
 

	
 

	
 
template<uint N> static inline void ExtractValid();
 
template<> static inline void ExtractValid<1>() {}
 

	
 

	
 
template<typename T> struct ExtractBits;
 
template<> struct ExtractBits<Axis>          { static const uint Count =  1; };
 
template<> struct ExtractBits<DiagDirection> { static const uint Count =  2; };
 
template<> struct ExtractBits<RoadBits>      { static const uint Count =  4; };
 

	
 

	
 
template<typename T, uint N, typename U> static inline T Extract(U v)
 
{
 
	// Check if there are enough bits in v
 
	ExtractValid<N + ExtractBits<T>::Count <= sizeof(U) * 8>();
 
	return (T)GB(v, N, ExtractBits<T>::Count);
 
}
 

	
 
#endif
src/depot.h
Show inline comments
 
@@ -82,26 +82,26 @@ static inline bool IsTileDepotType(TileI
 
	}
 
}
 

	
 

	
 
/**
 
 * Find out if the slope of the tile is suitable to build a depot of given direction
 
 * @param direction The direction in which the depot's exit points. Starts with 0 as NE and goes Clockwise
 
 * @param direction The direction in which the depot's exit points
 
 * @param tileh The slope of the tile in question
 
 * @return true if the construction is possible
 

	
 
 * This is checked by the ugly 0x4C >> direction magic, which does the following:
 
 * 0x4C is 0100 1100 and tileh has only bits 0..3 set (steep tiles are ruled out)
 
 * So: for direction (only the significant bits are shown)<p>
 
 * 00 (exit towards NE) we need either bit 2 or 3 set in tileh: 0x4C >> 0 = 1100<p>
 
 * 01 (exit towards SE) we need either bit 1 or 2 set in tileh: 0x4C >> 1 = 0110<p>
 
 * 02 (exit towards SW) we need either bit 0 or 1 set in tileh: 0x4C >> 2 = 0011<p>
 
 * 03 (exit towards NW) we need either bit 0 or 4 set in tileh: 0x4C >> 3 = 1001<p>
 
 * So ((0x4C >> direction) & tileh) determines whether the depot can be built on the current tileh
 
 */
 
static inline bool CanBuildDepotByTileh(uint32 direction, Slope tileh)
 
static inline bool CanBuildDepotByTileh(DiagDirection direction, Slope tileh)
 
{
 
	return ((0x4C >> direction) & tileh) != 0;
 
}
 

	
 
Depot *GetDepotByTile(TileIndex tile);
 
void InitializeDepots(void);
src/rail_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "cmd_helper.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "rail_map.h"
 
#include "road_map.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
@@ -537,13 +538,13 @@ int32 CmdRemoveRailroadTrack(TileIndex t
 
	return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
 
}
 

	
 
/** Build a train depot
 
 * @param tile position of the train depot
 
 * @param p1 rail type
 
 * @param p2 entrance direction (DiagDirection)
 
 * @param p2 bit 0..1 entrance direction (DiagDirection)
 
 *
 
 * @todo When checking for the tile slope,
 
 * distingush between "Flat land required" and "land sloped in wrong direction"
 
 */
 
int32 CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
@@ -551,29 +552,31 @@ int32 CmdBuildTrainDepot(TileIndex tile,
 
	int32 cost, ret;
 
	Slope tileh;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* check railtype and valid direction for depot (0 through 3), 4 in total */
 
	if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
 
	if (!ValParamRailtype(p1)) return CMD_ERROR;
 

	
 
	tileh = GetTileSlope(tile, NULL);
 

	
 
	DiagDirection dir = Extract<DiagDirection, 0>(p2);
 

	
 
	/* Prohibit construction if
 
	 * The tile is non-flat AND
 
	 * 1) The AI is "old-school"
 
	 * 2) build-on-slopes is disabled
 
	 * 3) the tile is steep i.e. spans two height levels
 
	 * 4) the exit points in the wrong direction
 
	 */
 

	
 
	if (tileh != SLOPE_FLAT && (
 
				_is_old_ai_player ||
 
				!_patches.build_on_slopes ||
 
				IsSteepSlope(tileh) ||
 
				!CanBuildDepotByTileh(p2, tileh)
 
				!CanBuildDepotByTileh(dir, tileh)
 
			)) {
 
		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 

	
 
	ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(ret)) return CMD_ERROR;
 
@@ -582,13 +585,12 @@ int32 CmdBuildTrainDepot(TileIndex tile,
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	d = AllocateDepot();
 
	if (d == NULL) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DiagDirection dir = (DiagDirection)p2;
 
		MakeRailDepot(tile, _current_player, dir, (RailType)p1);
 
		MarkTileDirtyByTile(tile);
 

	
 
		d->xy = tile;
 
		d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 

	
src/road_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "cmd_helper.h"
 
#include "rail_map.h"
 
#include "road_map.h"
 
#include "sprite.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "functions.h"
 
@@ -82,43 +83,40 @@ static bool CheckAllowRemoveRoad(TileInd
 
{
 
	return CheckAllowRemoveRoad(tile, remove, IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile), edge_road);
 
}
 

	
 
/** Delete a piece of road.
 
 * @param tile tile where to remove road from
 
 * @param p1 road piece flags
 
 * @param p1 bit 0..3 road pieces to remove (RoadBits)
 
 * @param p2 unused
 
 */
 
int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	// cost for removing inner/edge -roads
 
	static const uint16 road_remove_cost[2] = {50, 18};
 

	
 
	Owner owner;
 
	Town *t;
 
	/* true if the roadpiece was always removeable,
 
	 * false if it was a center piece. Affects town ratings drop */
 
	bool edge_road;
 
	RoadBits pieces;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
 
	if (p1 >> 4) return CMD_ERROR;
 
	pieces = (RoadBits)p1;
 

	
 
	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
 

	
 
	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
 

	
 
	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
 
		t = GetTownByTile(tile);
 
	} else {
 
		t = NULL;
 
	}
 

	
 
	RoadBits pieces = Extract<RoadBits, 0>(p1);
 

	
 
	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	// check if you're allowed to remove the street owned by a town
 
	// removal allowance depends on difficulty setting
 
@@ -246,29 +244,29 @@ static uint32 CheckRoadSlope(Slope tileh
 
	}
 
	return CMD_ERROR;
 
}
 

	
 
/** Build a piece of road.
 
 * @param tile tile where to build road
 
 * @param p1 road piece flags
 
 * @param p1 bit 0..3 road pieces to build (RoadBits)
 
 * @param p2 the town that is building the road (0 if not applicable)
 
 */
 
int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	int32 cost = 0;
 
	int32 ret;
 
	RoadBits existing = ROAD_NONE;
 
	RoadBits pieces;
 
	Slope tileh;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
 
	 * if a non-player is building the road */
 
	if ((p1 >> 4) || (IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
 
	pieces = (RoadBits)p1;
 
	if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
 

	
 
	RoadBits pieces = Extract<RoadBits, 0>(p1);
 

	
 
	tileh = GetTileSlope(tile, NULL);
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_STREET:
 
			switch (GetRoadTileType(tile)) {
 
@@ -499,13 +497,13 @@ int32 CmdRemoveLongRoad(TileIndex end_ti
 

	
 
	return (cost == 0) ? CMD_ERROR : cost;
 
}
 

	
 
/** Build a road depot.
 
 * @param tile tile where to build the depot
 
 * @param p1 entrance direction (DiagDirection)
 
 * @param p1 bit 0..1 entrance direction (DiagDirection)
 
 * @param p2 unused
 
 *
 
 * @todo When checking for the tile slope,
 
 * distingush between "Flat land required" and "land sloped in wrong direction"
 
 */
 
int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
@@ -513,19 +511,19 @@ int32 CmdBuildRoadDepot(TileIndex tile, 
 
	int32 cost;
 
	Depot *dep;
 
	Slope tileh;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (p1 > 3) return CMD_ERROR; // check direction
 
	DiagDirection dir = Extract<DiagDirection, 0>(p1);
 

	
 
	tileh = GetTileSlope(tile, NULL);
 
	if (tileh != SLOPE_FLAT && (
 
				!_patches.build_on_slopes ||
 
				IsSteepSlope(tileh) ||
 
				!CanBuildDepotByTileh(p1, tileh)
 
				!CanBuildDepotByTileh(dir, tileh)
 
			)) {
 
		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 

	
 
	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(cost)) return CMD_ERROR;
 
@@ -536,13 +534,13 @@ int32 CmdBuildRoadDepot(TileIndex tile, 
 
	if (dep == NULL) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		dep->xy = tile;
 
		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 

	
 
		MakeRoadDepot(tile, _current_player, (DiagDirection)p1);
 
		MakeRoadDepot(tile, _current_player, dir);
 
		MarkTileDirtyByTile(tile);
 
	}
 
	return cost + _price.build_road_depot;
 
}
 

	
 
static int32 RemoveRoadDepot(TileIndex tile, uint32 flags)
src/station_cmd.cpp
Show inline comments
 
@@ -3,12 +3,13 @@
 
/** @file station_cmd.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "aircraft.h"
 
#include "bridge_map.h"
 
#include "cmd_helper.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "station_map.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "map.h"
 
@@ -784,13 +785,13 @@ static void GetStationLayout(byte *layou
 
	}
 
}
 

	
 
/** Build railroad station
 
 * @param tile_org starting position of station dragging/placement
 
 * @param p1 various bitstuffed elements
 
 * - p1 = (bit  0)    - orientation (p1 & 1)
 
 * - p1 = (bit  0)    - orientation (Axis)
 
 * - p1 = (bit  8-15) - number of tracks
 
 * - p1 = (bit 16-23) - platform length
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit  0- 3) - railtype (p2 & 0xF)
 
 * - p2 = (bit  8-15) - custom station class
 
 * - p2 = (bit 16-23) - custom station id
 
@@ -804,13 +805,13 @@ int32 CmdBuildRailroadStation(TileIndex 
 

	
 
	/* Does the authority allow this? */
 
	if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile_org)) return CMD_ERROR;
 
	if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
 

	
 
	/* unpack parameters */
 
	Axis axis = (Axis)GB(p1, 0, 1);
 
	Axis axis = Extract<Axis, 0>(p1);
 
	uint numtracks = GB(p1,  8, 8);
 
	uint plat_len  = GB(p1, 16, 8);
 
	if (axis == AXIS_X) {
 
		w_org = plat_len;
 
		h_org = numtracks;
 
	} else {
src/water_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "cmd_helper.h"
 
#include "station_map.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "functions.h"
 
#include "map.h"
 
#include "tile.h"
 
@@ -42,29 +43,29 @@ static const SpriteID _water_shore_sprit
 

	
 
static Vehicle *FindFloodableVehicleOnTile(TileIndex tile);
 
static void FloodVehicle(Vehicle *v);
 

	
 
/** Build a ship depot.
 
 * @param tile tile where ship depot is built
 
 * @param p1 depot direction (0 == X or 1 == Y)
 
 * @param p1 bit 0 depot orientation (Axis)
 
 * @param p2 unused
 
 */
 
int32 CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	TileIndex tile2;
 

	
 
	int32 cost, ret;
 
	Depot *depot;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (p1 > 1) return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	tile2 = tile + (p1 ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
 
	Axis axis = Extract<Axis, 0>(p1);
 

	
 
	tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
 
	if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
 

	
 
	if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2))
 
		return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER);
 

	
 
	if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
@@ -81,14 +82,14 @@ int32 CmdBuildShipDepot(TileIndex tile, 
 
	if (depot == NULL) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		depot->xy = tile;
 
		depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 

	
 
		MakeShipDepot(tile, _current_player, DEPOT_NORTH, (Axis)p1);
 
		MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, (Axis)p1);
 
		MakeShipDepot(tile,  _current_player, DEPOT_NORTH, axis);
 
		MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, axis);
 
		MarkTileDirtyByTile(tile);
 
		MarkTileDirtyByTile(tile2);
 
	}
 

	
 
	return cost + _price.build_ship_depot;
 
}
0 comments (0 inline, 0 general)