src/road_cmd.cpp
branchcpp_gui
changeset 6268 4b5241e5dd10
parent 6253 23983700e3d7
child 6285 187e3ef04cc9
equal deleted inserted replaced
6267:7c8ec33959b1 6268:4b5241e5dd10
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 #include "stdafx.h"
     3 #include "stdafx.h"
     4 #include "openttd.h"
     4 #include "openttd.h"
     5 #include "bridge_map.h"
     5 #include "bridge_map.h"
       
     6 #include "cmd_helper.h"
     6 #include "rail_map.h"
     7 #include "rail_map.h"
     7 #include "road_map.h"
     8 #include "road_map.h"
     8 #include "sprite.h"
     9 #include "sprite.h"
     9 #include "table/sprites.h"
    10 #include "table/sprites.h"
    10 #include "table/strings.h"
    11 #include "table/strings.h"
    33 	if (r & ROAD_NE) ++count;
    34 	if (r & ROAD_NE) ++count;
    34 	return count;
    35 	return count;
    35 }
    36 }
    36 
    37 
    37 
    38 
    38 static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool* edge_road)
    39 bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road)
    39 {
    40 {
    40 	RoadBits present;
    41 	RoadBits present;
    41 	RoadBits n;
    42 	RoadBits n;
    42 	Owner owner;
       
    43 	*edge_road = true;
    43 	*edge_road = true;
    44 
    44 
    45 	if (_game_mode == GM_EDITOR) return true;
    45 	if (_game_mode == GM_EDITOR) return true;
    46 
    46 
    47 	// Only do the special processing for actual players.
    47 	// Only do the special processing for actual players.
    48 	if (!IsValidPlayer(_current_player)) return true;
    48 	if (!IsValidPlayer(_current_player)) return true;
    49 
       
    50 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
       
    51 
    49 
    52 	// Only do the special processing if the road is owned
    50 	// Only do the special processing if the road is owned
    53 	// by a town
    51 	// by a town
    54 	if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner);
    52 	if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner);
    55 
    53 
    79 	}
    77 	}
    80 
    78 
    81 	return true;
    79 	return true;
    82 }
    80 }
    83 
    81 
       
    82 static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road)
       
    83 {
       
    84 	return CheckAllowRemoveRoad(tile, remove, IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile), edge_road);
       
    85 }
    84 
    86 
    85 /** Delete a piece of road.
    87 /** Delete a piece of road.
    86  * @param tile tile where to remove road from
    88  * @param tile tile where to remove road from
    87  * @param p1 road piece flags
    89  * @param p1 bit 0..3 road pieces to remove (RoadBits)
    88  * @param p2 unused
    90  * @param p2 unused
    89  */
    91  */
    90 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
    92 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
    91 {
    93 {
    92 	// cost for removing inner/edge -roads
    94 	// cost for removing inner/edge -roads
    95 	Owner owner;
    97 	Owner owner;
    96 	Town *t;
    98 	Town *t;
    97 	/* true if the roadpiece was always removeable,
    99 	/* true if the roadpiece was always removeable,
    98 	 * false if it was a center piece. Affects town ratings drop */
   100 	 * false if it was a center piece. Affects town ratings drop */
    99 	bool edge_road;
   101 	bool edge_road;
   100 	RoadBits pieces;
       
   101 
   102 
   102 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   103 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   103 
       
   104 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
       
   105 	if (p1 >> 4) return CMD_ERROR;
       
   106 	pieces = (RoadBits)p1;
       
   107 
   104 
   108 	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
   105 	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
   109 
   106 
   110 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
   107 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
   111 
   108 
   112 	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
   109 	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
   113 		t = GetTownByTile(tile);
   110 		t = GetTownByTile(tile);
   114 	} else {
   111 	} else {
   115 		t = NULL;
   112 		t = NULL;
   116 	}
   113 	}
       
   114 
       
   115 	RoadBits pieces = Extract<RoadBits, 0>(p1);
   117 
   116 
   118 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
   117 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
   119 
   118 
   120 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   119 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   121 
   120 
   246 	return CMD_ERROR;
   245 	return CMD_ERROR;
   247 }
   246 }
   248 
   247 
   249 /** Build a piece of road.
   248 /** Build a piece of road.
   250  * @param tile tile where to build road
   249  * @param tile tile where to build road
   251  * @param p1 road piece flags
   250  * @param p1 bit 0..3 road pieces to build (RoadBits)
   252  * @param p2 the town that is building the road (0 if not applicable)
   251  * @param p2 the town that is building the road (0 if not applicable)
   253  */
   252  */
   254 int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   253 int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   255 {
   254 {
   256 	int32 cost = 0;
   255 	int32 cost = 0;
   257 	int32 ret;
   256 	int32 ret;
   258 	RoadBits existing = ROAD_NONE;
   257 	RoadBits existing = ROAD_NONE;
   259 	RoadBits pieces;
       
   260 	Slope tileh;
   258 	Slope tileh;
   261 
   259 
   262 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   260 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   263 
   261 
   264 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
   262 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
   265 	 * if a non-player is building the road */
   263 	 * if a non-player is building the road */
   266 	if ((p1 >> 4) || (IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
   264 	if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
   267 	pieces = (RoadBits)p1;
   265 
       
   266 	RoadBits pieces = Extract<RoadBits, 0>(p1);
   268 
   267 
   269 	tileh = GetTileSlope(tile, NULL);
   268 	tileh = GetTileSlope(tile, NULL);
   270 
   269 
   271 	switch (GetTileType(tile)) {
   270 	switch (GetTileType(tile)) {
   272 		case MP_STREET:
   271 		case MP_STREET:
   499 	return (cost == 0) ? CMD_ERROR : cost;
   498 	return (cost == 0) ? CMD_ERROR : cost;
   500 }
   499 }
   501 
   500 
   502 /** Build a road depot.
   501 /** Build a road depot.
   503  * @param tile tile where to build the depot
   502  * @param tile tile where to build the depot
   504  * @param p1 entrance direction (DiagDirection)
   503  * @param p1 bit 0..1 entrance direction (DiagDirection)
   505  * @param p2 unused
   504  * @param p2 unused
   506  *
   505  *
   507  * @todo When checking for the tile slope,
   506  * @todo When checking for the tile slope,
   508  * distingush between "Flat land required" and "land sloped in wrong direction"
   507  * distingush between "Flat land required" and "land sloped in wrong direction"
   509  */
   508  */
   513 	Depot *dep;
   512 	Depot *dep;
   514 	Slope tileh;
   513 	Slope tileh;
   515 
   514 
   516 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   515 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   517 
   516 
   518 	if (p1 > 3) return CMD_ERROR; // check direction
   517 	DiagDirection dir = Extract<DiagDirection, 0>(p1);
   519 
       
   520 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
       
   521 
   518 
   522 	tileh = GetTileSlope(tile, NULL);
   519 	tileh = GetTileSlope(tile, NULL);
   523 	if (tileh != SLOPE_FLAT && (
   520 	if (tileh != SLOPE_FLAT && (
   524 				!_patches.build_on_slopes ||
   521 				!_patches.build_on_slopes ||
   525 				IsSteepSlope(tileh) ||
   522 				IsSteepSlope(tileh) ||
   526 				!CanBuildDepotByTileh(p1, tileh)
   523 				!CanBuildDepotByTileh(dir, tileh)
   527 			)) {
   524 			)) {
   528 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
   525 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
   529 	}
   526 	}
   530 
   527 
   531 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   528 	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   538 
   535 
   539 	if (flags & DC_EXEC) {
   536 	if (flags & DC_EXEC) {
   540 		dep->xy = tile;
   537 		dep->xy = tile;
   541 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
   538 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
   542 
   539 
   543 		MakeRoadDepot(tile, _current_player, (DiagDirection)p1);
   540 		MakeRoadDepot(tile, _current_player, dir);
   544 		MarkTileDirtyByTile(tile);
   541 		MarkTileDirtyByTile(tile);
   545 	}
   542 	}
   546 	return cost + _price.build_road_depot;
   543 	return cost + _price.build_road_depot;
   547 }
   544 }
   548 
   545