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 |