OpenTTD Source  20241120-master-g6d3adc6169
road_cmd.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "road.h"
12 #include "road_internal.h"
13 #include "viewport_func.h"
14 #include "command_func.h"
15 #include "company_func.h"
17 #include "depot_base.h"
18 #include "newgrf.h"
19 #include "autoslope.h"
20 #include "tunnelbridge_map.h"
21 #include "strings_func.h"
22 #include "vehicle_func.h"
23 #include "sound_func.h"
24 #include "tunnelbridge.h"
25 #include "cheat_type.h"
26 #include "effectvehicle_func.h"
27 #include "effectvehicle_base.h"
28 #include "elrail_func.h"
29 #include "roadveh.h"
30 #include "train.h"
31 #include "town.h"
32 #include "company_base.h"
33 #include "core/random_func.hpp"
34 #include "core/container_func.hpp"
35 #include "newgrf_debug.h"
36 #include "newgrf_railtype.h"
37 #include "newgrf_roadtype.h"
39 #include "genworld.h"
40 #include "company_gui.h"
41 #include "road_func.h"
42 #include "road_cmd.h"
43 #include "landscape_cmd.h"
44 #include "rail_cmd.h"
45 
46 #include "table/strings.h"
47 #include "table/roadtypes.h"
48 
49 #include "safeguards.h"
50 
52 typedef std::vector<RoadVehicle *> RoadVehicleList;
53 
54 RoadTypeInfo _roadtypes[ROADTYPE_END];
55 std::vector<RoadType> _sorted_roadtypes;
56 RoadTypes _roadtypes_hidden_mask;
57 
63 
68 {
69  static_assert(lengthof(_original_roadtypes) <= lengthof(_roadtypes));
70 
71  auto insert = std::copy(std::begin(_original_roadtypes), std::end(_original_roadtypes), std::begin(_roadtypes));
72  std::fill(insert, std::end(_roadtypes), RoadTypeInfo{});
73 
74  _roadtypes_hidden_mask = ROADTYPES_NONE;
76 }
77 
78 void ResolveRoadTypeGUISprites(RoadTypeInfo *rti)
79 {
81  if (cursors_base != 0) {
82  rti->gui_sprites.build_y_road = cursors_base + 0;
83  rti->gui_sprites.build_x_road = cursors_base + 1;
84  rti->gui_sprites.auto_road = cursors_base + 2;
85  rti->gui_sprites.build_depot = cursors_base + 3;
86  rti->gui_sprites.build_tunnel = cursors_base + 4;
87  rti->gui_sprites.convert_road = cursors_base + 5;
88  rti->cursor.road_swne = cursors_base + 6;
89  rti->cursor.road_nwse = cursors_base + 7;
90  rti->cursor.autoroad = cursors_base + 8;
91  rti->cursor.depot = cursors_base + 9;
92  rti->cursor.tunnel = cursors_base + 10;
93  rti->cursor.convert_road = cursors_base + 11;
94  }
95 }
96 
103 static bool CompareRoadTypes(const RoadType &first, const RoadType &second)
104 {
105  if (RoadTypeIsRoad(first) == RoadTypeIsRoad(second)) {
107  }
108  return RoadTypeIsTram(first) < RoadTypeIsTram(second);
109 }
110 
115 {
116  for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
117  RoadTypeInfo *rti = &_roadtypes[rt];
118  ResolveRoadTypeGUISprites(rti);
119  if (HasBit(rti->flags, ROTF_HIDDEN)) SetBit(_roadtypes_hidden_mask, rt);
120  }
121 
122  _sorted_roadtypes.clear();
123  for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
124  if (_roadtypes[rt].label != 0 && !HasBit(_roadtypes_hidden_mask, rt)) {
125  _sorted_roadtypes.push_back(rt);
126  }
127  }
128  std::sort(_sorted_roadtypes.begin(), _sorted_roadtypes.end(), CompareRoadTypes);
129 }
130 
134 RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
135 {
136  for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
137  RoadTypeInfo *rti = &_roadtypes[rt];
138 
139  if (rti->label == 0) {
140  /* Set up new road type */
141  *rti = _original_roadtypes[(rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD];
142  rti->label = label;
143  rti->alternate_labels.clear();
144  rti->flags = ROTFB_NONE;
146 
147  /* Make us compatible with ourself. */
148  rti->powered_roadtypes = (RoadTypes)(1ULL << rt);
149 
150  /* We also introduce ourself. */
151  rti->introduces_roadtypes = (RoadTypes)(1ULL << rt);
152 
153  /* Default sort order; order of allocation, but with some
154  * offsets so it's easier for NewGRF to pick a spot without
155  * changing the order of other (original) road types.
156  * The << is so you can place other roadtypes in between the
157  * other roadtypes, the 7 is to be able to place something
158  * before the first (default) road type. */
159  rti->sorting_order = rt << 2 | 7;
160 
161  /* Set bitmap of road/tram types */
162  if (rtt == RTT_TRAM) {
163  SetBit(_roadtypes_type, rt);
164  } else {
165  ClrBit(_roadtypes_type, rt);
166  }
167 
168  return rt;
169  }
170  }
171 
172  return INVALID_ROADTYPE;
173 }
174 
180 {
181  return !RoadVehicle::Iterate().empty();
182 }
183 
191 {
192  if (rt == INVALID_ROADTYPE) return;
193 
195  if (c == nullptr) return;
196 
197  c->infrastructure.road[rt] += count;
199 }
200 
202 static const RoadBits _invalid_tileh_slopes_road[2][15] = {
203  /* The inverse of the mixable RoadBits on a leveled slope */
204  {
205  ROAD_NONE, // SLOPE_FLAT
206  ROAD_NE | ROAD_SE, // SLOPE_W
207  ROAD_NE | ROAD_NW, // SLOPE_S
208 
209  ROAD_NE, // SLOPE_SW
210  ROAD_NW | ROAD_SW, // SLOPE_E
211  ROAD_NONE, // SLOPE_EW
212 
213  ROAD_NW, // SLOPE_SE
214  ROAD_NONE, // SLOPE_WSE
215  ROAD_SE | ROAD_SW, // SLOPE_N
216 
217  ROAD_SE, // SLOPE_NW
218  ROAD_NONE, // SLOPE_NS
219  ROAD_NONE, // SLOPE_ENW
220 
221  ROAD_SW, // SLOPE_NE
222  ROAD_NONE, // SLOPE_SEN
223  ROAD_NONE // SLOPE_NWS
224  },
225  /* The inverse of the allowed straight roads on a slope
226  * (with and without a foundation). */
227  {
228  ROAD_NONE, // SLOPE_FLAT
229  ROAD_NONE, // SLOPE_W Foundation
230  ROAD_NONE, // SLOPE_S Foundation
231 
232  ROAD_Y, // SLOPE_SW
233  ROAD_NONE, // SLOPE_E Foundation
234  ROAD_ALL, // SLOPE_EW
235 
236  ROAD_X, // SLOPE_SE
237  ROAD_ALL, // SLOPE_WSE
238  ROAD_NONE, // SLOPE_N Foundation
239 
240  ROAD_X, // SLOPE_NW
241  ROAD_ALL, // SLOPE_NS
242  ROAD_ALL, // SLOPE_ENW
243 
244  ROAD_Y, // SLOPE_NE
245  ROAD_ALL, // SLOPE_SEN
246  ROAD_ALL // SLOPE_NW
247  }
248 };
249 
250 static Foundation GetRoadFoundation(Slope tileh, RoadBits bits);
251 
262 CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadTramType rtt, DoCommandFlag flags, bool town_check)
263 {
264  if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return CommandCost();
265 
266  /* Water can always flood and towns can always remove "normal" road pieces.
267  * Towns are not be allowed to remove non "normal" road pieces, like tram
268  * tracks as that would result in trams that cannot turn. */
269  if (_current_company == OWNER_WATER ||
270  (rtt == RTT_ROAD && !Company::IsValidID(_current_company))) return CommandCost();
271 
272  /* Only do the special processing if the road is owned
273  * by a town */
274  if (owner != OWNER_TOWN) {
275  if (owner == OWNER_NONE) return CommandCost();
276  CommandCost ret = CheckOwnership(owner);
277  return ret;
278  }
279 
280  if (!town_check) return CommandCost();
281 
283 
284  Town *t = ClosestTownFromTile(tile, UINT_MAX);
285  if (t == nullptr) return CommandCost();
286 
287  /* check if you're allowed to remove the street owned by a town
288  * removal allowance depends on difficulty setting */
289  CommandCost ret = CheckforTownRating(flags, t, ROAD_REMOVE);
290  if (ret.Failed()) return ret;
291 
292  /* Get a bitmask of which neighbouring roads has a tile */
293  RoadBits n = ROAD_NONE;
294  RoadBits present = GetAnyRoadBits(tile, rtt);
295  if ((present & ROAD_NE) && (GetAnyRoadBits(TileAddXY(tile, -1, 0), rtt) & ROAD_SW)) n |= ROAD_NE;
296  if ((present & ROAD_SE) && (GetAnyRoadBits(TileAddXY(tile, 0, 1), rtt) & ROAD_NW)) n |= ROAD_SE;
297  if ((present & ROAD_SW) && (GetAnyRoadBits(TileAddXY(tile, 1, 0), rtt) & ROAD_NE)) n |= ROAD_SW;
298  if ((present & ROAD_NW) && (GetAnyRoadBits(TileAddXY(tile, 0, -1), rtt) & ROAD_SE)) n |= ROAD_NW;
299 
300  int rating_decrease = RATING_ROAD_DOWN_STEP_EDGE;
301  /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
302  * then allow it */
303  if (KillFirstBit(n) != ROAD_NONE && (n & remove) != ROAD_NONE) {
304  /* you can remove all kind of roads with extra dynamite */
306  SetDParam(0, t->index);
307  return_cmd_error(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS);
308  }
309  rating_decrease = RATING_ROAD_DOWN_STEP_INNER;
310  }
311  ChangeTownRating(t, rating_decrease, RATING_ROAD_MINIMUM, flags);
312 
313  return CommandCost();
314 }
315 
316 
325 static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadTramType rtt, bool town_check)
326 {
327  assert(pieces != ROAD_NONE);
328 
329  RoadType existing_rt = MayHaveRoad(tile) ? GetRoadType(tile, rtt) : INVALID_ROADTYPE;
330  /* The tile doesn't have the given road type */
331  if (existing_rt == INVALID_ROADTYPE) return_cmd_error((rtt == RTT_TRAM) ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD);
332 
333  switch (GetTileType(tile)) {
334  case MP_ROAD: {
336  if (ret.Failed()) return ret;
337  break;
338  }
339 
340  case MP_STATION: {
341  if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
342 
344  if (ret.Failed()) return ret;
345  break;
346  }
347 
348  case MP_TUNNELBRIDGE: {
351  if (ret.Failed()) return ret;
352  break;
353  }
354 
355  default:
356  return CMD_ERROR;
357  }
358 
359  CommandCost ret = CheckAllowRemoveRoad(tile, pieces, GetRoadOwner(tile, rtt), rtt, flags, town_check);
360  if (ret.Failed()) return ret;
361 
362  if (!IsTileType(tile, MP_ROAD)) {
363  /* If it's the last roadtype, just clear the whole tile */
364  if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
365 
367  if (IsTileType(tile, MP_TUNNELBRIDGE)) {
368  /* Removing any roadbit in the bridge axis removes the roadtype (that's the behaviour remove-long-roads needs) */
369  if ((AxisToRoadBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) & pieces) == ROAD_NONE) return_cmd_error((rtt == RTT_TRAM) ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD);
370 
371  TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
372  /* Pay for *every* tile of the bridge or tunnel */
373  uint len = GetTunnelBridgeLength(other_end, tile) + 2;
374  cost.AddCost(len * 2 * RoadClearCost(existing_rt));
375  if (flags & DC_EXEC) {
376  /* A full diagonal road tile has two road bits. */
377  UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR));
378 
379  SetRoadType(other_end, rtt, INVALID_ROADTYPE);
380  SetRoadType(tile, rtt, INVALID_ROADTYPE);
381 
382  /* If the owner of the bridge sells all its road, also move the ownership
383  * to the owner of the other roadtype, unless the bridge owner is a town. */
384  Owner other_owner = GetRoadOwner(tile, OtherRoadTramType(rtt));
385  if (!IsTileOwner(tile, other_owner) && !IsTileOwner(tile, OWNER_TOWN)) {
386  SetTileOwner(tile, other_owner);
387  SetTileOwner(other_end, other_owner);
388  }
389 
390  /* Mark tiles dirty that have been repaved */
391  if (IsBridge(tile)) {
392  MarkBridgeDirty(tile);
393  } else {
394  MarkTileDirtyByTile(tile);
395  MarkTileDirtyByTile(other_end);
396  }
397  }
398  } else {
399  assert(IsDriveThroughStopTile(tile));
400  cost.AddCost(RoadClearCost(existing_rt) * 2);
401  if (flags & DC_EXEC) {
402  /* A full diagonal road tile has two road bits. */
403  UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2);
404  SetRoadType(tile, rtt, INVALID_ROADTYPE);
405  MarkTileDirtyByTile(tile);
406  }
407  }
408  return cost;
409  }
410 
411  switch (GetRoadTileType(tile)) {
412  case ROAD_TILE_NORMAL: {
413  Slope tileh = GetTileSlope(tile);
414 
415  /* Steep slopes behave the same as slopes with one corner raised. */
416  if (IsSteepSlope(tileh)) {
418  }
419 
420  RoadBits present = GetRoadBits(tile, rtt);
421  const RoadBits other = GetRoadBits(tile, OtherRoadTramType(rtt));
422  const Foundation f = GetRoadFoundation(tileh, present);
423 
424  if (HasRoadWorks(tile) && _current_company != OWNER_WATER) return_cmd_error(STR_ERROR_ROAD_WORKS_IN_PROGRESS);
425 
426  /* Autocomplete to a straight road
427  * @li if the bits of the other roadtypes result in another foundation
428  * @li if build on slopes is disabled */
429  if ((IsStraightRoad(other) && (other & _invalid_tileh_slopes_road[0][tileh & SLOPE_ELEVATED]) != ROAD_NONE) ||
431  pieces |= MirrorRoadBits(pieces);
432  }
433 
434  /* limit the bits to delete to the existing bits. */
435  pieces &= present;
436  if (pieces == ROAD_NONE) return_cmd_error((rtt == RTT_TRAM) ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD);
437 
438  /* Now set present what it will be after the remove */
439  present ^= pieces;
440 
441  /* Check for invalid RoadBit combinations on slopes */
442  if (tileh != SLOPE_FLAT && present != ROAD_NONE &&
443  (present & _invalid_tileh_slopes_road[0][tileh & SLOPE_ELEVATED]) == present) {
444  return CMD_ERROR;
445  }
446 
447  if (flags & DC_EXEC) {
448  if (HasRoadWorks(tile)) {
449  /* flooding tile with road works, don't forget to remove the effect vehicle too */
450  assert(_current_company == OWNER_WATER);
452  if (TileVirtXY(v->x_pos, v->y_pos) == tile) {
453  delete v;
454  }
455  }
456  }
457 
458  UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)CountBits(pieces));
459 
460  if (present == ROAD_NONE) {
461  /* No other road type, just clear tile. */
462  if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) {
463  /* Includes MarkTileDirtyByTile() */
464  DoClearSquare(tile);
465  } else {
466  if (rtt == RTT_ROAD && IsRoadOwner(tile, rtt, OWNER_TOWN)) {
467  /* Update nearest-town index */
468  const Town *town = CalcClosestTownFromTile(tile);
469  SetTownIndex(tile, town == nullptr ? INVALID_TOWN : town->index);
470  }
471  if (rtt == RTT_ROAD) SetDisallowedRoadDirections(tile, DRD_NONE);
472  SetRoadBits(tile, ROAD_NONE, rtt);
473  SetRoadType(tile, rtt, INVALID_ROADTYPE);
474  MarkTileDirtyByTile(tile);
475  }
476  } else {
477  /* When bits are removed, you *always* end up with something that
478  * is not a complete straight road tile. However, trams do not have
479  * onewayness, so they cannot remove it either. */
480  if (rtt == RTT_ROAD) SetDisallowedRoadDirections(tile, DRD_NONE);
481  SetRoadBits(tile, present, rtt);
482  MarkTileDirtyByTile(tile);
483  }
484  }
485 
486  CommandCost cost(EXPENSES_CONSTRUCTION, CountBits(pieces) * RoadClearCost(existing_rt));
487  /* If we build a foundation we have to pay for it. */
488  if (f == FOUNDATION_NONE && GetRoadFoundation(tileh, present) != FOUNDATION_NONE) cost.AddCost(_price[PR_BUILD_FOUNDATION]);
489 
490  return cost;
491  }
492 
493  case ROAD_TILE_CROSSING: {
494  if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
495  return CMD_ERROR;
496  }
497 
498  if (flags & DC_EXEC) {
500 
501  /* A full diagonal road tile has two road bits. */
502  UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2);
503 
504  Track railtrack = GetCrossingRailTrack(tile);
505  if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) {
506  TrackBits tracks = GetCrossingRailBits(tile);
507  bool reserved = HasCrossingReservation(tile);
508  MakeRailNormal(tile, GetTileOwner(tile), tracks, GetRailType(tile));
509  if (reserved) SetTrackReservation(tile, tracks);
510 
511  /* Update rail count for level crossings. The plain track should still be accounted
512  * for, so only subtract the difference to the level crossing cost. */
514  if (c != nullptr) {
517  }
518  } else {
519  SetRoadType(tile, rtt, INVALID_ROADTYPE);
520  }
521  MarkTileDirtyByTile(tile);
522  YapfNotifyTrackLayoutChange(tile, railtrack);
523  }
524  return CommandCost(EXPENSES_CONSTRUCTION, RoadClearCost(existing_rt) * 2);
525  }
526 
527  default:
528  case ROAD_TILE_DEPOT:
529  return CMD_ERROR;
530  }
531 }
532 
533 
545 static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existing, RoadBits other)
546 {
547  /* Remove already build pieces */
548  CLRBITS(*pieces, existing);
549 
550  /* If we can't build anything stop here */
551  if (*pieces == ROAD_NONE) return CMD_ERROR;
552 
553  /* All RoadBit combos are valid on flat land */
554  if (tileh == SLOPE_FLAT) return CommandCost();
555 
556  /* Steep slopes behave the same as slopes with one corner raised. */
557  if (IsSteepSlope(tileh)) {
559  }
560 
561  /* Save the merge of all bits of the current type */
562  RoadBits type_bits = existing | *pieces;
563 
564  /* Roads on slopes */
565  if (_settings_game.construction.build_on_slopes && (_invalid_tileh_slopes_road[0][tileh] & (other | type_bits)) == ROAD_NONE) {
566 
567  /* If we add leveling we've got to pay for it */
568  if ((other | existing) == ROAD_NONE) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
569 
570  return CommandCost();
571  }
572 
573  /* Autocomplete uphill roads */
574  *pieces |= MirrorRoadBits(*pieces);
575  type_bits = existing | *pieces;
576 
577  /* Uphill roads */
578  if (IsStraightRoad(type_bits) && (other == type_bits || other == ROAD_NONE) &&
579  (_invalid_tileh_slopes_road[1][tileh] & (other | type_bits)) == ROAD_NONE) {
580 
581  /* Slopes with foundation ? */
582  if (IsSlopeWithOneCornerRaised(tileh)) {
583 
584  /* Prevent build on slopes if it isn't allowed */
586 
587  /* If we add foundation we've got to pay for it */
588  if ((other | existing) == ROAD_NONE) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
589 
590  return CommandCost();
591  }
592  } else {
593  if (HasExactlyOneBit(existing) && GetRoadFoundation(tileh, existing) == FOUNDATION_NONE) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
594  return CommandCost();
595  }
596  }
597  return CMD_ERROR;
598 }
599 
610 CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id)
611 {
612  CompanyID company = _current_company;
614 
615  RoadBits existing = ROAD_NONE;
616  RoadBits other_bits = ROAD_NONE;
617 
618  /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
619  * if a non-company is building the road */
620  if ((Company::IsValidID(company) && town_id != 0) || (company == OWNER_TOWN && !Town::IsValidID(town_id)) || (company == OWNER_DEITY && town_id != 0)) return CMD_ERROR;
621  if (company != OWNER_TOWN) {
622  const Town *town = CalcClosestTownFromTile(tile);
623  town_id = (town != nullptr) ? town->index : INVALID_TOWN;
624 
625  if (company == OWNER_DEITY) {
626  company = OWNER_TOWN;
627 
628  /* If we are not within a town, we are not owned by the town */
629  if (town == nullptr || DistanceSquare(tile, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) {
630  company = OWNER_NONE;
631  }
632  }
633  }
634 
635  /* do not allow building 'zero' road bits, code wouldn't handle it */
636  if (pieces == ROAD_NONE || !IsValidRoadBits(pieces) || !IsValidDisallowedRoadDirections(toggle_drd)) return CMD_ERROR;
637  if (!ValParamRoadType(rt)) return CMD_ERROR;
638 
639  Slope tileh = GetTileSlope(tile);
640  RoadTramType rtt = GetRoadTramType(rt);
641 
642  bool need_to_clear = false;
643  switch (GetTileType(tile)) {
644  case MP_ROAD:
645  switch (GetRoadTileType(tile)) {
646  case ROAD_TILE_NORMAL: {
647  if (HasRoadWorks(tile)) return_cmd_error(STR_ERROR_ROAD_WORKS_IN_PROGRESS);
648 
649  other_bits = GetRoadBits(tile, OtherRoadTramType(rtt));
650  if (!HasTileRoadType(tile, rtt)) break;
651 
652  existing = GetRoadBits(tile, rtt);
653  bool crossing = !IsStraightRoad(existing | pieces);
654  if (rtt == RTT_ROAD && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) {
655  /* Junctions cannot be one-way */
656  return_cmd_error(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
657  }
658  if ((existing & pieces) == pieces) {
659  /* We only want to set the (dis)allowed road directions */
660  if (toggle_drd != DRD_NONE && rtt == RTT_ROAD) {
661  if (crossing) return_cmd_error(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
662 
663  Owner owner = GetRoadOwner(tile, rtt);
664  if (owner != OWNER_NONE) {
665  CommandCost ret = CheckOwnership(owner, tile);
666  if (ret.Failed()) return ret;
667  }
668 
670  DisallowedRoadDirections dis_new = dis_existing ^ toggle_drd;
671 
672  /* We allow removing disallowed directions to break up
673  * deadlocks, but adding them can break articulated
674  * vehicles. As such, only when less is disallowed,
675  * i.e. bits are removed, we skip the vehicle check. */
676  if (CountBits(dis_existing) <= CountBits(dis_new)) {
678  if (ret.Failed()) return ret;
679  }
680 
681  /* Ignore half built tiles */
682  if ((flags & DC_EXEC) && IsStraightRoad(existing)) {
683  SetDisallowedRoadDirections(tile, dis_new);
684  MarkTileDirtyByTile(tile);
685  }
686  return CommandCost();
687  }
688  return_cmd_error(STR_ERROR_ALREADY_BUILT);
689  }
690  /* Disallow breaking end-of-line of someone else
691  * so trams can still reverse on this tile. */
692  if (rtt == RTT_TRAM && HasExactlyOneBit(existing)) {
693  Owner owner = GetRoadOwner(tile, rtt);
694  if (Company::IsValidID(owner)) {
695  CommandCost ret = CheckOwnership(owner);
696  if (ret.Failed()) return ret;
697  }
698  }
699  break;
700  }
701 
702  case ROAD_TILE_CROSSING:
703  if (RoadNoLevelCrossing(rt)) {
704  return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_ROAD);
705  }
706 
707  other_bits = GetCrossingRoadBits(tile);
708  if (pieces & ComplementRoadBits(other_bits)) goto do_clear;
709  pieces = other_bits; // we need to pay for both roadbits
710 
711  if (HasTileRoadType(tile, rtt)) return_cmd_error(STR_ERROR_ALREADY_BUILT);
712  break;
713 
714  case ROAD_TILE_DEPOT:
715  if ((GetAnyRoadBits(tile, rtt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT);
716  goto do_clear;
717 
718  default: NOT_REACHED();
719  }
720  break;
721 
722  case MP_RAILWAY: {
723  if (IsSteepSlope(tileh)) {
724  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
725  }
726 
727  /* Level crossings may only be built on these slopes */
728  if (!HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh)) {
729  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
730  }
731 
733  CommandCost ret = CheckTileOwnership(tile);
734  if (ret.Failed()) return ret;
735  }
736 
737  if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear;
738 
739  if (RoadNoLevelCrossing(rt)) {
740  return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_ROAD);
741  }
742 
743  if (RailNoLevelCrossings(GetRailType(tile))) {
744  return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_RAIL);
745  }
746 
747  Axis roaddir;
748  switch (GetTrackBits(tile)) {
749  case TRACK_BIT_X:
750  if (pieces & ROAD_X) goto do_clear;
751  roaddir = AXIS_Y;
752  break;
753 
754  case TRACK_BIT_Y:
755  if (pieces & ROAD_Y) goto do_clear;
756  roaddir = AXIS_X;
757  break;
758 
759  default: goto do_clear;
760  }
761 
763  if (ret.Failed()) return ret;
764 
765  if (flags & DC_EXEC) {
766  Track railtrack = AxisToTrack(OtherAxis(roaddir));
767  YapfNotifyTrackLayoutChange(tile, railtrack);
768  /* Update company infrastructure counts. A level crossing has two road bits. */
769  UpdateCompanyRoadInfrastructure(rt, company, 2);
770 
771  /* Update rail count for level crossings. The plain track is already
772  * counted, so only add the difference to the level crossing cost. */
774  if (c != nullptr) {
777  }
778 
779  /* Always add road to the roadtypes (can't draw without it) */
780  bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack);
781  MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id);
782  SetCrossingReservation(tile, reserved);
783  UpdateLevelCrossing(tile, false);
785  MarkTileDirtyByTile(tile);
786  }
788  }
789 
790  case MP_STATION: {
791  if ((GetAnyRoadBits(tile, rtt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT);
792  if (!IsDriveThroughStopTile(tile)) goto do_clear;
793 
795  if (pieces & ~curbits) goto do_clear;
796  pieces = curbits; // we need to pay for both roadbits
797 
798  if (HasTileRoadType(tile, rtt)) return_cmd_error(STR_ERROR_ALREADY_BUILT);
799  break;
800  }
801 
802  case MP_TUNNELBRIDGE: {
803  if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) goto do_clear;
804  /* Only allow building the outern roadbit, so building long roads stops at existing bridges */
805  if (MirrorRoadBits(DiagDirToRoadBits(GetTunnelBridgeDirection(tile))) != pieces) goto do_clear;
806  if (HasTileRoadType(tile, rtt)) return_cmd_error(STR_ERROR_ALREADY_BUILT);
807  /* Don't allow adding roadtype to the bridge/tunnel when vehicles are already driving on it */
809  if (ret.Failed()) return ret;
810  break;
811  }
812 
813  default: {
814 do_clear:;
815  need_to_clear = true;
816  break;
817  }
818  }
819 
820  if (need_to_clear) {
822  if (ret.Failed()) return ret;
823  cost.AddCost(ret);
824  }
825 
826  if (other_bits != pieces) {
827  /* Check the foundation/slopes when adding road/tram bits */
828  CommandCost ret = CheckRoadSlope(tileh, &pieces, existing, other_bits);
829  /* Return an error if we need to build a foundation (ret != 0) but the
830  * current setting is turned off */
831  if (ret.Failed() || (ret.GetCost() != 0 && !_settings_game.construction.build_on_slopes)) {
832  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
833  }
834  cost.AddCost(ret);
835  }
836 
837  if (!need_to_clear) {
838  if (IsTileType(tile, MP_ROAD)) {
839  /* Don't put the pieces that already exist */
840  pieces &= ComplementRoadBits(existing);
841 
842  /* Check if new road bits will have the same foundation as other existing road types */
843  if (IsNormalRoad(tile)) {
844  Slope slope = GetTileSlope(tile);
845  Foundation found_new = GetRoadFoundation(slope, pieces | existing);
846 
847  RoadBits bits = GetRoadBits(tile, OtherRoadTramType(rtt));
848  /* do not check if there are not road bits of given type */
849  if (bits != ROAD_NONE && GetRoadFoundation(slope, bits) != found_new) {
850  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
851  }
852  }
853  }
854 
856  if (ret.Failed()) return ret;
857 
858  if (IsNormalRoadTile(tile)) {
859  /* If the road types don't match, try to convert only if vehicles of
860  * the new road type are not powered on the present road type and vehicles of
861  * the present road type are powered on the new road type. */
862  RoadType existing_rt = GetRoadType(tile, rtt);
863  if (existing_rt != INVALID_ROADTYPE && existing_rt != rt) {
864  if (HasPowerOnRoad(rt, existing_rt)) {
865  rt = existing_rt;
866  } else if (HasPowerOnRoad(existing_rt, rt)) {
867  ret = Command<CMD_CONVERT_ROAD>::Do(flags, tile, tile, rt);
868  if (ret.Failed()) return ret;
869  cost.AddCost(ret);
870  } else {
871  return CMD_ERROR;
872  }
873  }
874  }
875  }
876 
877  uint num_pieces = (!need_to_clear && IsTileType(tile, MP_TUNNELBRIDGE)) ?
878  /* There are 2 pieces on *every* tile of the bridge or tunnel */
879  2 * (GetTunnelBridgeLength(GetOtherTunnelBridgeEnd(tile), tile) + 2) :
880  /* Count pieces */
881  CountBits(pieces);
882 
883  cost.AddCost(num_pieces * RoadBuildCost(rt));
884 
885  if (flags & DC_EXEC) {
886  switch (GetTileType(tile)) {
887  case MP_ROAD: {
888  RoadTileType rttype = GetRoadTileType(tile);
889  if (existing == ROAD_NONE || rttype == ROAD_TILE_CROSSING) {
890  SetRoadType(tile, rtt, rt);
891  SetRoadOwner(tile, rtt, company);
892  if (rtt == RTT_ROAD) SetTownIndex(tile, town_id);
893  }
894  if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt);
895  break;
896  }
897 
898  case MP_TUNNELBRIDGE: {
899  TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
900 
901  SetRoadType(other_end, rtt, rt);
902  SetRoadType(tile, rtt, rt);
903  SetRoadOwner(other_end, rtt, company);
904  SetRoadOwner(tile, rtt, company);
905 
906  /* Mark tiles dirty that have been repaved */
907  if (IsBridge(tile)) {
908  MarkBridgeDirty(tile);
909  } else {
910  MarkTileDirtyByTile(other_end);
911  MarkTileDirtyByTile(tile);
912  }
913  break;
914  }
915 
916  case MP_STATION: {
917  assert(IsDriveThroughStopTile(tile));
918  SetRoadType(tile, rtt, rt);
919  SetRoadOwner(tile, rtt, company);
920  break;
921  }
922 
923  default:
924  MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id, company, company);
925  break;
926  }
927 
928  /* Update company infrastructure count. */
929  if (IsTileType(tile, MP_TUNNELBRIDGE)) num_pieces *= TUNNELBRIDGE_TRACKBIT_FACTOR;
930  UpdateCompanyRoadInfrastructure(rt, GetRoadOwner(tile, rtt), num_pieces);
931 
932  if (rtt == RTT_ROAD && IsNormalRoadTile(tile)) {
933  existing |= pieces;
935  GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE);
936  }
937 
938  MarkTileDirtyByTile(tile);
939  }
940  return cost;
941 }
942 
951 {
952  tile += TileOffsByDiagDir(dir);
953  if (!IsValidTile(tile) || !MayHaveRoad(tile)) return false;
954 
955  RoadTramType rtt = GetRoadTramType(rt);
956  RoadType existing = GetRoadType(tile, rtt);
957  if (existing == INVALID_ROADTYPE) return false;
958  if (!HasPowerOnRoad(existing, rt) && !HasPowerOnRoad(rt, existing)) return false;
959 
960  RoadBits bits = GetAnyRoadBits(tile, rtt, false);
961  return (bits & DiagDirToRoadBits(ReverseDiagDir(dir))) != 0;
962 }
963 
979 CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai)
980 {
981  if (start_tile >= Map::Size()) return CMD_ERROR;
982 
983  if (!ValParamRoadType(rt) || !IsValidAxis(axis) || !IsValidDisallowedRoadDirections(drd)) return CMD_ERROR;
984 
985  /* Only drag in X or Y direction dictated by the direction variable */
986  if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
987  if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
988 
989  DiagDirection dir = AxisToDiagDir(axis);
990 
991  /* Swap direction, also the half-tile drag vars. */
992  if (start_tile > end_tile || (start_tile == end_tile && start_half)) {
993  dir = ReverseDiagDir(dir);
994  start_half = !start_half;
995  end_half = !end_half;
996  if (drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) drd ^= DRD_BOTH;
997  }
998 
999  /* On the X-axis, we have to swap the initial bits, so they
1000  * will be interpreted correctly in the GTTS. Furthermore
1001  * when you just 'click' on one tile to build them. */
1002  if ((drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) && (axis == AXIS_Y) == (start_tile == end_tile && start_half == end_half)) drd ^= DRD_BOTH;
1003 
1005  CommandCost last_error = CMD_ERROR;
1006  TileIndex tile = start_tile;
1007  bool had_bridge = false;
1008  bool had_tunnel = false;
1009  bool had_success = false;
1010 
1011  /* Start tile is the first tile clicked by the user. */
1012  for (;;) {
1013  RoadBits bits = AxisToRoadBits(axis);
1014 
1015  /* Determine which road parts should be built. */
1016  if (!is_ai && start_tile != end_tile) {
1017  /* Only build the first and last roadbit if they can connect to something. */
1018  if (tile == end_tile && !CanConnectToRoad(tile, rt, dir)) {
1019  bits = DiagDirToRoadBits(ReverseDiagDir(dir));
1020  } else if (tile == start_tile && !CanConnectToRoad(tile, rt, ReverseDiagDir(dir))) {
1021  bits = DiagDirToRoadBits(dir);
1022  }
1023  } else {
1024  /* Road parts only have to be built at the start tile or at the end tile. */
1025  if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir));
1026  if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir);
1027  }
1028 
1029  CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, bits, rt, drd, 0);
1030  if (ret.Failed()) {
1031  last_error = ret;
1032  if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
1033  if (is_ai) return last_error;
1034  if (had_success) break; // Keep going if we haven't constructed any road yet, skipping the start of the drag
1035  }
1036  } else {
1037  had_success = true;
1038  /* Only pay for the upgrade on one side of the bridges and tunnels */
1039  if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1040  if (IsBridge(tile)) {
1041  if (!had_bridge || GetTunnelBridgeDirection(tile) == dir) {
1042  cost.AddCost(ret);
1043  }
1044  had_bridge = true;
1045  } else { // IsTunnel(tile)
1046  if (!had_tunnel || GetTunnelBridgeDirection(tile) == dir) {
1047  cost.AddCost(ret);
1048  }
1049  had_tunnel = true;
1050  }
1051  } else {
1052  cost.AddCost(ret);
1053  }
1054  }
1055 
1056  if (tile == end_tile) break;
1057 
1058  tile += TileOffsByDiagDir(dir);
1059  }
1060 
1061  return had_success ? cost : last_error;
1062 }
1063 
1075 std::tuple<CommandCost, Money> CmdRemoveLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, bool start_half, bool end_half)
1076 {
1078 
1079  if (start_tile >= Map::Size()) return { CMD_ERROR, 0 };
1080  if (!ValParamRoadType(rt) || !IsValidAxis(axis)) return { CMD_ERROR, 0 };
1081 
1082  /* Only drag in X or Y direction dictated by the direction variable */
1083  if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return { CMD_ERROR, 0 }; // x-axis
1084  if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return { CMD_ERROR, 0 }; // y-axis
1085 
1086  /* Swap start and ending tile, also the half-tile drag vars. */
1087  if (start_tile > end_tile || (start_tile == end_tile && start_half)) {
1088  std::swap(start_tile, end_tile);
1089  std::swap(start_half, end_half);
1090  }
1091 
1092  Money money_available = GetAvailableMoneyForCommand();
1093  Money money_spent = 0;
1094  TileIndex tile = start_tile;
1095  CommandCost last_error = CMD_ERROR;
1096  bool had_success = false;
1097  /* Start tile is the small number. */
1098  for (;;) {
1099  RoadBits bits = AxisToRoadBits(axis);
1100 
1101  if (tile == end_tile && !end_half) bits &= ROAD_NW | ROAD_NE;
1102  if (tile == start_tile && start_half) bits &= ROAD_SE | ROAD_SW;
1103 
1104  /* try to remove the halves. */
1105  if (bits != 0) {
1106  RoadTramType rtt = GetRoadTramType(rt);
1107  CommandCost ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rtt, true);
1108  if (ret.Succeeded()) {
1109  if (flags & DC_EXEC) {
1110  money_spent += ret.GetCost();
1111  if (money_spent > 0 && money_spent > money_available) {
1112  return { cost, std::get<0>(Command<CMD_REMOVE_LONG_ROAD>::Do(flags & ~DC_EXEC, end_tile, start_tile, rt, axis, start_half, end_half)).GetCost() };
1113  }
1114  RemoveRoad(tile, flags, bits, rtt, false);
1115  }
1116  cost.AddCost(ret);
1117  had_success = true;
1118  } else {
1119  /* Some errors are more equal than others. */
1120  switch (last_error.GetErrorMessage()) {
1121  case STR_ERROR_OWNED_BY:
1122  case STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS:
1123  break;
1124  default:
1125  last_error = ret;
1126  }
1127  }
1128  }
1129 
1130  if (tile == end_tile) break;
1131 
1132  tile += TileOffsByAxis(axis);
1133  }
1134 
1135  return { had_success ? cost : last_error, 0 };
1136 }
1137 
1150 {
1151  if (!ValParamRoadType(rt) || !IsValidDiagDirection(dir)) return CMD_ERROR;
1152 
1154 
1155  Slope tileh = GetTileSlope(tile);
1156  if (tileh != SLOPE_FLAT) {
1158  return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
1159  }
1160  cost.AddCost(_price[PR_BUILD_FOUNDATION]);
1161  }
1162 
1163  /* Allow the user to rotate the depot instead of having to destroy it and build it again */
1164  bool rotate_existing_depot = false;
1165  if (IsRoadDepotTile(tile) && (HasRoadTypeTram(tile) ? rt == GetRoadTypeTram(tile) : rt == GetRoadTypeRoad(tile)))
1166  {
1167  CommandCost ret = CheckTileOwnership(tile);
1168  if (ret.Failed()) return ret;
1169 
1170  if (dir == GetRoadDepotDirection(tile)) return CommandCost();
1171 
1172  ret = EnsureNoVehicleOnGround(tile);
1173  if (ret.Failed()) return ret;
1174 
1175  rotate_existing_depot = true;
1176  }
1177 
1178  if (!rotate_existing_depot) {
1179  cost.AddCost(Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile));
1180  if (cost.Failed()) return cost;
1181 
1182  if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
1183 
1184  if (!Depot::CanAllocateItem()) return CMD_ERROR;
1185  }
1186 
1187  if (flags & DC_EXEC) {
1188  if (rotate_existing_depot) {
1189  SetRoadDepotExitDirection(tile, dir);
1190  } else {
1191  Depot *dep = new Depot(tile);
1193  MakeRoadDepot(tile, _current_company, dep->index, dir, rt);
1194  MakeDefaultName(dep);
1195 
1196  /* A road depot has two road bits. */
1198  }
1199 
1200  MarkTileDirtyByTile(tile);
1201  }
1202 
1203  cost.AddCost(_price[PR_BUILD_DEPOT_ROAD]);
1204  return cost;
1205 }
1206 
1207 static CommandCost RemoveRoadDepot(TileIndex tile, DoCommandFlag flags)
1208 {
1209  if (_current_company != OWNER_WATER) {
1210  CommandCost ret = CheckTileOwnership(tile);
1211  if (ret.Failed()) return ret;
1212  }
1213 
1215  if (ret.Failed()) return ret;
1216 
1217  if (flags & DC_EXEC) {
1219  if (c != nullptr) {
1220  /* A road depot has two road bits. */
1221  RoadType rt = GetRoadTypeRoad(tile);
1222  if (rt == INVALID_ROADTYPE) rt = GetRoadTypeTram(tile);
1225  }
1226 
1227  delete Depot::GetByTile(tile);
1228  DoClearSquare(tile);
1229  }
1230 
1231  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_ROAD]);
1232 }
1233 
1234 static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags)
1235 {
1236  switch (GetRoadTileType(tile)) {
1237  case ROAD_TILE_NORMAL: {
1238  RoadBits b = GetAllRoadBits(tile);
1239 
1240  /* Clear the road if only one piece is on the tile OR we are not using the DC_AUTO flag */
1241  if ((HasExactlyOneBit(b) && GetRoadBits(tile, RTT_TRAM) == ROAD_NONE) || !(flags & DC_AUTO)) {
1243  for (RoadTramType rtt : _roadtramtypes) {
1244  if (!MayHaveRoad(tile) || GetRoadType(tile, rtt) == INVALID_ROADTYPE) continue;
1245 
1246  CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rtt), rtt, true);
1247  if (tmp_ret.Failed()) return tmp_ret;
1248  ret.AddCost(tmp_ret);
1249  }
1250  return ret;
1251  }
1252  return_cmd_error(STR_ERROR_MUST_REMOVE_ROAD_FIRST);
1253  }
1254 
1255  case ROAD_TILE_CROSSING: {
1257 
1258  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_MUST_REMOVE_ROAD_FIRST);
1259 
1260  /* Must iterate over the roadtypes in a reverse manner because
1261  * tram tracks must be removed before the road bits. */
1262  for (RoadTramType rtt : { RTT_TRAM, RTT_ROAD }) {
1263  if (!MayHaveRoad(tile) || GetRoadType(tile, rtt) == INVALID_ROADTYPE) continue;
1264 
1265  CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rtt, true);
1266  if (tmp_ret.Failed()) return tmp_ret;
1267  ret.AddCost(tmp_ret);
1268  }
1269 
1270  if (flags & DC_EXEC) {
1271  Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
1272  }
1273  return ret;
1274  }
1275 
1276  default:
1277  case ROAD_TILE_DEPOT:
1278  if (flags & DC_AUTO) {
1279  return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
1280  }
1281  return RemoveRoadDepot(tile, flags);
1282  }
1283 }
1284 
1285 
1287  uint16_t image;
1288  uint8_t subcoord_x;
1289  uint8_t subcoord_y;
1290 };
1291 
1292 #include "table/road_land.h"
1293 
1302 {
1303  /* Flat land and land without a road doesn't require a foundation */
1304  if (tileh == SLOPE_FLAT || bits == ROAD_NONE) return FOUNDATION_NONE;
1305 
1306  /* Steep slopes behave the same as slopes with one corner raised. */
1307  if (IsSteepSlope(tileh)) {
1309  }
1310 
1311  /* Leveled RoadBits on a slope */
1312  if ((_invalid_tileh_slopes_road[0][tileh] & bits) == ROAD_NONE) return FOUNDATION_LEVELED;
1313 
1314  /* Straight roads without foundation on a slope */
1315  if (!IsSlopeWithOneCornerRaised(tileh) &&
1316  (_invalid_tileh_slopes_road[1][tileh] & bits) == ROAD_NONE)
1317  return FOUNDATION_NONE;
1318 
1319  /* Roads on steep Slopes or on Slopes with one corner raised */
1320  return (bits == ROAD_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
1321 }
1322 
1323 const uint8_t _road_sloped_sprites[14] = {
1324  0, 0, 2, 0,
1325  0, 1, 0, 0,
1326  3, 0, 0, 0,
1327  0, 0
1328 };
1329 
1336 static uint GetRoadSpriteOffset(Slope slope, RoadBits bits)
1337 {
1338  if (slope != SLOPE_FLAT) {
1339  switch (slope) {
1340  case SLOPE_NE: return 11;
1341  case SLOPE_SE: return 12;
1342  case SLOPE_SW: return 13;
1343  case SLOPE_NW: return 14;
1344  default: NOT_REACHED();
1345  }
1346  } else {
1347  static const uint offsets[] = {
1348  0, 18, 17, 7,
1349  16, 0, 10, 5,
1350  15, 8, 1, 4,
1351  9, 3, 6, 2
1352  };
1353  return offsets[bits];
1354  }
1355 }
1356 
1366 static bool DrawRoadAsSnowDesert(bool snow_or_desert, Roadside roadside)
1367 {
1368  return (snow_or_desert &&
1369  !(_settings_game.game_creation.landscape == LT_TROPIC && HasGrfMiscBit(GMB_DESERT_PAVED_ROADS) &&
1370  roadside != ROADSIDE_BARREN && roadside != ROADSIDE_GRASS && roadside != ROADSIDE_GRASS_ROAD_WORKS));
1371 }
1372 
1380 {
1381  /* Don't draw the catenary under a low bridge */
1383  int height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
1384 
1385  if (height <= GetTileMaxZ(ti->tile) + 1) return;
1386  }
1387 
1388  if (CountBits(rb) > 2) {
1389  /* On junctions we check whether neighbouring tiles also have catenary, and possibly
1390  * do not draw catenary towards those neighbours, which do not have catenary. */
1391  RoadBits rb_new = ROAD_NONE;
1392  for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1393  if (rb & DiagDirToRoadBits(dir)) {
1394  TileIndex neighbour = TileAddByDiagDir(ti->tile, dir);
1395  if (MayHaveRoad(neighbour)) {
1396  RoadType rt_road = GetRoadTypeRoad(neighbour);
1397  RoadType rt_tram = GetRoadTypeTram(neighbour);
1398 
1399  if ((rt_road != INVALID_ROADTYPE && HasRoadCatenary(rt_road)) ||
1400  (rt_tram != INVALID_ROADTYPE && HasRoadCatenary(rt_tram))) {
1401  rb_new |= DiagDirToRoadBits(dir);
1402  }
1403  }
1404  }
1405  }
1406  if (CountBits(rb_new) >= 2) rb = rb_new;
1407  }
1408 
1409  const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1412 
1413  if (front != 0 || back != 0) {
1414  if (front != 0) front += GetRoadSpriteOffset(ti->tileh, rb);
1415  if (back != 0) back += GetRoadSpriteOffset(ti->tileh, rb);
1416  } else if (ti->tileh != SLOPE_FLAT) {
1417  back = SPR_TRAMWAY_BACK_WIRES_SLOPED + _road_sloped_sprites[ti->tileh - 1];
1418  front = SPR_TRAMWAY_FRONT_WIRES_SLOPED + _road_sloped_sprites[ti->tileh - 1];
1419  } else {
1420  back = SPR_TRAMWAY_BASE + _road_backpole_sprites_1[rb];
1421  front = SPR_TRAMWAY_BASE + _road_frontwire_sprites_1[rb];
1422  }
1423 
1424  /* Catenary uses 1st company colour to help identify owner.
1425  * For tiles with OWNER_TOWN or OWNER_NONE, recolour CC to grey as a neutral colour. */
1426  Owner owner = GetRoadOwner(ti->tile, GetRoadTramType(rt));
1427  PaletteID pal = (owner == OWNER_NONE || owner == OWNER_TOWN ? GENERAL_SPRITE_COLOUR(COLOUR_GREY) : COMPANY_SPRITE_COLOUR(owner));
1428  int z_wires = (ti->tileh == SLOPE_FLAT ? 0 : TILE_HEIGHT) + BB_HEIGHT_UNDER_BRIDGE;
1429  if (back != 0) {
1430  /* The "back" sprite contains the west, north and east pillars.
1431  * We cut the sprite at 3/8 of the west/east edges to create 3 sprites.
1432  * 3/8 is chosen so that sprites can somewhat graphically extend into the tile. */
1433  static const int INF = 1000;
1434  static const SubSprite west = { -INF, -INF, -12, INF };
1435  static const SubSprite north = { -12, -INF, 12, INF };
1436  static const SubSprite east = { 12, -INF, INF, INF };
1437  AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 16, 1, z_wires, ti->z, IsTransparencySet(TO_CATENARY), 15, 0, GetSlopePixelZInCorner(ti->tileh, CORNER_W), &west);
1438  AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 1, 1, z_wires, ti->z, IsTransparencySet(TO_CATENARY), 0, 0, GetSlopePixelZInCorner(ti->tileh, CORNER_N), &north);
1439  AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 1, 16, z_wires, ti->z, IsTransparencySet(TO_CATENARY), 0, 15, GetSlopePixelZInCorner(ti->tileh, CORNER_E), &east);
1440  }
1441  if (front != 0) {
1442  /* Draw the "front" sprite (containing south pillar and wires) at a Z height that is both above the vehicles and above the "back" pillars. */
1443  AddSortableSpriteToDraw(front, pal, ti->x, ti->y, 16, 16, z_wires + 1, ti->z, IsTransparencySet(TO_CATENARY), 0, 0, z_wires);
1444  }
1445 }
1446 
1452 {
1453  RoadBits road = ROAD_NONE;
1454  RoadBits tram = ROAD_NONE;
1455 
1456  if (IsTileType(ti->tile, MP_ROAD)) {
1457  if (IsNormalRoad(ti->tile)) {
1458  road = GetRoadBits(ti->tile, RTT_ROAD);
1459  tram = GetRoadBits(ti->tile, RTT_TRAM);
1460  } else if (IsLevelCrossing(ti->tile)) {
1461  tram = road = (GetCrossingRailAxis(ti->tile) == AXIS_Y ? ROAD_X : ROAD_Y);
1462  }
1463  } else if (IsTileType(ti->tile, MP_STATION)) {
1464  if (IsAnyRoadStop(ti->tile)) {
1465  if (IsDriveThroughStopTile(ti->tile)) {
1466  Axis axis = GetDriveThroughStopAxis(ti->tile);
1467  tram = road = (axis == AXIS_X ? ROAD_X : ROAD_Y);
1468  } else {
1469  tram = road = DiagDirToRoadBits(GetBayRoadStopDir(ti->tile));
1470  }
1471  }
1472  } else {
1473  // No road here, no catenary to draw
1474  return;
1475  }
1476 
1477  RoadType rt = GetRoadTypeRoad(ti->tile);
1478  if (rt != INVALID_ROADTYPE && HasRoadCatenaryDrawn(rt)) {
1479  DrawRoadTypeCatenary(ti, rt, road);
1480  }
1481 
1482  rt = GetRoadTypeTram(ti->tile);
1483  if (rt != INVALID_ROADTYPE && HasRoadCatenaryDrawn(rt)) {
1484  DrawRoadTypeCatenary(ti, rt, tram);
1485  }
1486 }
1487 
1497 static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int h, bool transparent)
1498 {
1499  int x = ti->x | dx;
1500  int y = ti->y | dy;
1501  int z = ti->z;
1502  if (ti->tileh != SLOPE_FLAT) z = GetSlopePixelZ(x, y);
1503  AddSortableSpriteToDraw(img, PAL_NONE, x, y, 2, 2, h, z, transparent);
1504 }
1505 
1515 void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, uint road_offset, uint tram_offset, bool draw_underlay)
1516 {
1517  if (draw_underlay) {
1518  /* Road underlay takes precedence over tram */
1519  if (road_rti != nullptr) {
1520  if (road_rti->UsesOverlay()) {
1521  SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_GROUND);
1522  DrawGroundSprite(ground + road_offset, pal);
1523  }
1524  } else {
1525  if (tram_rti->UsesOverlay()) {
1526  SpriteID ground = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_GROUND);
1527  DrawGroundSprite(ground + tram_offset, pal);
1528  } else {
1529  DrawGroundSprite(SPR_TRAMWAY_TRAM + tram_offset, pal);
1530  }
1531  }
1532  }
1533 
1534  /* Draw road overlay */
1535  if (road_rti != nullptr) {
1536  if (road_rti->UsesOverlay()) {
1537  SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_OVERLAY);
1538  if (ground != 0) DrawGroundSprite(ground + road_offset, pal);
1539  }
1540  }
1541 
1542  /* Draw tram overlay */
1543  if (tram_rti != nullptr) {
1544  if (tram_rti->UsesOverlay()) {
1545  SpriteID ground = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_OVERLAY);
1546  if (ground != 0) DrawGroundSprite(ground + tram_offset, pal);
1547  } else if (road_rti != nullptr) {
1548  DrawGroundSprite(SPR_TRAMWAY_OVERLAY + tram_offset, pal);
1549  }
1550  }
1551 }
1552 
1562 static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const RoadTypeInfo *rti, uint offset, bool snow_or_desert, PaletteID *pal)
1563 {
1564  /* Draw bare ground sprite if no road or road uses overlay system. */
1565  if (rti == nullptr || rti->UsesOverlay()) {
1566  if (DrawRoadAsSnowDesert(snow_or_desert, roadside)) {
1567  return SPR_FLAT_SNOW_DESERT_TILE + SlopeToSpriteOffset(ti->tileh);
1568  }
1569 
1570  switch (roadside) {
1572  return SPR_FLAT_GRASS_TILE + SlopeToSpriteOffset(ti->tileh);
1573  case ROADSIDE_GRASS:
1574  case ROADSIDE_GRASS_ROAD_WORKS: return SPR_FLAT_GRASS_TILE + SlopeToSpriteOffset(ti->tileh);
1575  default: break; // Paved
1576  }
1577  }
1578 
1579  /* Draw original road base sprite */
1580  SpriteID image = SPR_ROAD_Y + offset;
1581  if (DrawRoadAsSnowDesert(snow_or_desert, roadside)) {
1582  image += 19;
1583  } else {
1584  switch (roadside) {
1585  case ROADSIDE_BARREN: *pal = PALETTE_TO_BARE_LAND; break;
1586  case ROADSIDE_GRASS: break;
1587  case ROADSIDE_GRASS_ROAD_WORKS: break;
1588  default: image -= 19; break; // Paved
1589  }
1590  }
1591 
1592  return image;
1593 }
1594 
1605 void DrawRoadGroundSprites(const TileInfo *ti, RoadBits road, RoadBits tram, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, Roadside roadside, bool snow_or_desert)
1606 {
1607  /* Determine sprite offsets */
1608  uint road_offset = GetRoadSpriteOffset(ti->tileh, road);
1609  uint tram_offset = GetRoadSpriteOffset(ti->tileh, tram);
1610 
1611  /* Draw baseset underlay */
1612  PaletteID pal = PAL_NONE;
1613  SpriteID image = GetRoadGroundSprite(ti, roadside, road_rti, road == ROAD_NONE ? tram_offset : road_offset, snow_or_desert, &pal);
1614  DrawGroundSprite(image, pal);
1615 
1616  DrawRoadOverlays(ti, pal, road_rti, tram_rti, road_offset, tram_offset);
1617 }
1618 
1623 static void DrawRoadBits(TileInfo *ti)
1624 {
1625  RoadBits road = GetRoadBits(ti->tile, RTT_ROAD);
1626  RoadBits tram = GetRoadBits(ti->tile, RTT_TRAM);
1627 
1628  RoadType road_rt = GetRoadTypeRoad(ti->tile);
1629  RoadType tram_rt = GetRoadTypeTram(ti->tile);
1630  const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt);
1631  const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt);
1632 
1633  if (ti->tileh != SLOPE_FLAT) {
1634  DrawFoundation(ti, GetRoadFoundation(ti->tileh, road | tram));
1635  /* DrawFoundation() modifies ti. */
1636  }
1637 
1638  DrawRoadGroundSprites(ti, road, tram, road_rti, tram_rti, GetRoadside(ti->tile), IsOnSnow(ti->tile));
1639 
1640  /* Draw one way */
1641  if (road_rti != nullptr) {
1643  if (drd != DRD_NONE) {
1644  SpriteID oneway = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_ONEWAY);
1645 
1646  if (oneway == 0) oneway = SPR_ONEWAY_BASE;
1647 
1648  if ((ti->tileh == SLOPE_NE) || (ti->tileh == SLOPE_NW)) {
1649  oneway += SPR_ONEWAY_SLOPE_N_OFFSET;
1650  } else if ((ti->tileh == SLOPE_SE) || (ti->tileh == SLOPE_SW)) {
1651  oneway += SPR_ONEWAY_SLOPE_S_OFFSET;
1652  }
1653 
1654  DrawGroundSpriteAt(oneway + drd - 1 + ((road == ROAD_X) ? 0 : 3), PAL_NONE, 8, 8, GetPartialPixelZ(8, 8, ti->tileh));
1655  }
1656  }
1657 
1658  if (HasRoadWorks(ti->tile)) {
1659  /* Road works */
1660  DrawGroundSprite((road | tram) & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y, PAL_NONE);
1661  return;
1662  }
1663 
1664  /* Draw road, tram catenary */
1665  DrawRoadCatenary(ti);
1666 
1667  /* Return if full detail is disabled, or we are zoomed fully out. */
1668  if (!HasBit(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return;
1669 
1670  /* Do not draw details (street lights, trees) under low bridge */
1671  Roadside roadside = GetRoadside(ti->tile);
1672  if (IsBridgeAbove(ti->tile) && (roadside == ROADSIDE_TREES || roadside == ROADSIDE_STREET_LIGHTS)) {
1673  int height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
1674  int minz = GetTileMaxZ(ti->tile) + 2;
1675 
1676  if (roadside == ROADSIDE_TREES) minz++;
1677 
1678  if (height < minz) return;
1679  }
1680 
1681  /* If there are no road bits, return, as there is nothing left to do */
1682  if (HasAtMostOneBit(road)) return;
1683 
1684  /* Do not draw details when invisible. */
1685  if (roadside == ROADSIDE_TREES && IsInvisibilitySet(TO_TREES)) return;
1686  if (roadside == ROADSIDE_STREET_LIGHTS && IsInvisibilitySet(TO_HOUSES)) return;
1687 
1688  /* Check whether details should be transparent. */
1689  bool is_transparent = false;
1690  if (roadside == ROADSIDE_TREES && IsTransparencySet(TO_TREES)) {
1691  is_transparent = true;
1692  }
1693  if (roadside == ROADSIDE_STREET_LIGHTS && IsTransparencySet(TO_HOUSES)) {
1694  is_transparent = true;
1695  }
1696 
1697  /* Draw extra details. */
1698  for (const DrawRoadTileStruct *drts = _road_display_table[roadside][road | tram]; drts->image != 0; drts++) {
1699  DrawRoadDetail(drts->image, ti, drts->subcoord_x, drts->subcoord_y, 0x10, is_transparent);
1700  }
1701 }
1702 
1704 static void DrawTile_Road(TileInfo *ti)
1705 {
1706  switch (GetRoadTileType(ti->tile)) {
1707  case ROAD_TILE_NORMAL:
1708  DrawRoadBits(ti);
1709  break;
1710 
1711  case ROAD_TILE_CROSSING: {
1713 
1714  Axis axis = GetCrossingRailAxis(ti->tile);
1715 
1716  const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
1717 
1718  RoadType road_rt = GetRoadTypeRoad(ti->tile);
1719  RoadType tram_rt = GetRoadTypeTram(ti->tile);
1720  const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt);
1721  const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt);
1722 
1723  PaletteID pal = PAL_NONE;
1724 
1725  /* Draw base ground */
1726  if (rti->UsesOverlay()) {
1727  SpriteID image = SPR_ROAD_Y + axis;
1728 
1729  Roadside roadside = GetRoadside(ti->tile);
1730  if (DrawRoadAsSnowDesert(IsOnSnow(ti->tile), roadside)) {
1731  image += 19;
1732  } else {
1733  switch (roadside) {
1734  case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break;
1735  case ROADSIDE_GRASS: break;
1736  default: image -= 19; break; // Paved
1737  }
1738  }
1739 
1740  DrawGroundSprite(image, pal);
1741  } else {
1742  SpriteID image = rti->base_sprites.crossing + axis;
1743  if (IsCrossingBarred(ti->tile)) image += 2;
1744 
1745  Roadside roadside = GetRoadside(ti->tile);
1746  if (DrawRoadAsSnowDesert(IsOnSnow(ti->tile), roadside)) {
1747  image += 8;
1748  } else {
1749  switch (roadside) {
1750  case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break;
1751  case ROADSIDE_GRASS: break;
1752  default: image += 4; break; // Paved
1753  }
1754  }
1755 
1756  DrawGroundSprite(image, pal);
1757  }
1758 
1759  DrawRoadOverlays(ti, pal, road_rti, tram_rti, axis, axis);
1760 
1761  /* Draw rail/PBS overlay */
1762  bool draw_pbs = _game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasCrossingReservation(ti->tile);
1763  if (rti->UsesOverlay()) {
1764  pal = draw_pbs ? PALETTE_CRASH : PAL_NONE;
1765  SpriteID rail = GetCustomRailSprite(rti, ti->tile, RTSG_CROSSING) + axis;
1766  DrawGroundSprite(rail, pal);
1767 
1768  const Axis road_axis = GetCrossingRoadAxis(ti->tile);
1769  const DiagDirection dir1 = AxisToDiagDir(road_axis);
1770  const DiagDirection dir2 = ReverseDiagDir(dir1);
1771  uint adjacent_diagdirs = 0;
1772  for (DiagDirection dir : { dir1, dir2 }) {
1773  const TileIndex t = TileAddByDiagDir(ti->tile, dir);
1774  if (t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) {
1775  SetBit(adjacent_diagdirs, dir);
1776  }
1777  }
1778 
1779  switch (adjacent_diagdirs) {
1780  case 0:
1781  DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE);
1782  break;
1783 
1784  case (1 << DIAGDIR_NE):
1785  DrawRailTileSeq(ti, &_crossing_layout_SW, TO_CATENARY, rail, 0, PAL_NONE);
1786  break;
1787 
1788  case (1 << DIAGDIR_SE):
1789  DrawRailTileSeq(ti, &_crossing_layout_NW, TO_CATENARY, rail, 0, PAL_NONE);
1790  break;
1791 
1792  case (1 << DIAGDIR_SW):
1793  DrawRailTileSeq(ti, &_crossing_layout_NE, TO_CATENARY, rail, 0, PAL_NONE);
1794  break;
1795 
1796  case (1 << DIAGDIR_NW):
1797  DrawRailTileSeq(ti, &_crossing_layout_SE, TO_CATENARY, rail, 0, PAL_NONE);
1798  break;
1799 
1800  default:
1801  /* Show no sprites */
1802  break;
1803  }
1804  } else if (draw_pbs || tram_rti != nullptr || road_rti->UsesOverlay()) {
1805  /* Add another rail overlay, unless there is only the base road sprite. */
1806  pal = draw_pbs ? PALETTE_CRASH : PAL_NONE;
1808  DrawGroundSprite(rail, pal);
1809  }
1810 
1811  /* Draw road, tram catenary */
1812  DrawRoadCatenary(ti);
1813 
1814  /* Draw rail catenary */
1816 
1817  break;
1818  }
1819 
1820  default:
1821  case ROAD_TILE_DEPOT: {
1823 
1824  PaletteID palette = COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile));
1825 
1826  RoadType road_rt = GetRoadTypeRoad(ti->tile);
1827  RoadType tram_rt = GetRoadTypeTram(ti->tile);
1828  const RoadTypeInfo *rti = GetRoadTypeInfo(road_rt == INVALID_ROADTYPE ? tram_rt : road_rt);
1829 
1830  int relocation = GetCustomRoadSprite(rti, ti->tile, ROTSG_DEPOT);
1831  bool default_gfx = relocation == 0;
1832  if (default_gfx) {
1833  if (HasBit(rti->flags, ROTF_CATENARY)) {
1834  if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && road_rt == INVALID_ROADTYPE && !rti->UsesOverlay()) {
1835  /* Sprites with track only work for default tram */
1836  relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT;
1837  default_gfx = false;
1838  } else {
1839  /* Sprites without track are always better, if provided */
1840  relocation = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_ROAD_DEPOT;
1841  }
1842  }
1843  } else {
1844  relocation -= SPR_ROAD_DEPOT;
1845  }
1846 
1848  const DrawTileSprites *dts = &_road_depot[dir];
1849  DrawGroundSprite(dts->ground.sprite, PAL_NONE);
1850 
1851  if (default_gfx) {
1852  uint offset = GetRoadSpriteOffset(SLOPE_FLAT, DiagDirToRoadBits(dir));
1853  if (rti->UsesOverlay()) {
1854  SpriteID ground = GetCustomRoadSprite(rti, ti->tile, ROTSG_OVERLAY);
1855  if (ground != 0) DrawGroundSprite(ground + offset, PAL_NONE);
1856  } else if (road_rt == INVALID_ROADTYPE) {
1857  DrawGroundSprite(SPR_TRAMWAY_OVERLAY + offset, PAL_NONE);
1858  }
1859  }
1860 
1861  DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, palette);
1862  break;
1863  }
1864  }
1865  DrawBridgeMiddle(ti);
1866 }
1867 
1875 void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt)
1876 {
1877  PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
1878 
1879  const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1880  int relocation = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_DEPOT);
1881  bool default_gfx = relocation == 0;
1882  if (default_gfx) {
1883  if (HasBit(rti->flags, ROTF_CATENARY)) {
1884  if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && RoadTypeIsTram(rt) && !rti->UsesOverlay()) {
1885  /* Sprites with track only work for default tram */
1886  relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT;
1887  default_gfx = false;
1888  } else {
1889  /* Sprites without track are always better, if provided */
1890  relocation = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_ROAD_DEPOT;
1891  }
1892  }
1893  } else {
1894  relocation -= SPR_ROAD_DEPOT;
1895  }
1896 
1897  const DrawTileSprites *dts = &_road_depot[dir];
1898  DrawSprite(dts->ground.sprite, PAL_NONE, x, y);
1899 
1900  if (default_gfx) {
1901  uint offset = GetRoadSpriteOffset(SLOPE_FLAT, DiagDirToRoadBits(dir));
1902  if (rti->UsesOverlay()) {
1904  if (ground != 0) DrawSprite(ground + offset, PAL_NONE, x, y);
1905  } else if (RoadTypeIsTram(rt)) {
1906  DrawSprite(SPR_TRAMWAY_OVERLAY + offset, PAL_NONE, x, y);
1907  }
1908  }
1909 
1910  DrawRailTileSeqInGUI(x, y, dts, relocation, 0, palette);
1911 }
1912 
1918 void UpdateNearestTownForRoadTiles(bool invalidate)
1919 {
1920  assert(!invalidate || _generating_world);
1921 
1922  for (TileIndex t = 0; t < Map::Size(); t++) {
1923  if (IsTileType(t, MP_ROAD) && !IsRoadDepot(t) && !HasTownOwnedRoad(t)) {
1924  TownID tid = INVALID_TOWN;
1925  if (!invalidate) {
1926  const Town *town = CalcClosestTownFromTile(t);
1927  if (town != nullptr) tid = town->index;
1928  }
1929  SetTownIndex(t, tid);
1930  }
1931  }
1932 }
1933 
1934 static int GetSlopePixelZ_Road(TileIndex tile, uint x, uint y, bool)
1935 {
1936 
1937  if (IsNormalRoad(tile)) {
1938  auto [tileh, z] = GetTilePixelSlope(tile);
1939  if (tileh == SLOPE_FLAT) return z;
1940 
1941  Foundation f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
1942  z += ApplyPixelFoundationToSlope(f, tileh);
1943  return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
1944  } else {
1945  return GetTileMaxPixelZ(tile);
1946  }
1947 }
1948 
1949 static Foundation GetFoundation_Road(TileIndex tile, Slope tileh)
1950 {
1951  if (IsNormalRoad(tile)) {
1952  return GetRoadFoundation(tileh, GetAllRoadBits(tile));
1953  } else {
1954  return FlatteningFoundation(tileh);
1955  }
1956 }
1957 
1958 static const Roadside _town_road_types[][2] = {
1964 };
1965 
1966 static_assert(lengthof(_town_road_types) == HZB_END);
1967 
1968 static const Roadside _town_road_types_2[][2] = {
1974 };
1975 
1976 static_assert(lengthof(_town_road_types_2) == HZB_END);
1977 
1978 
1979 static void TileLoop_Road(TileIndex tile)
1980 {
1982  case LT_ARCTIC: {
1983  /* Roads on flat foundations use the snow level of the height they are elevated to. All others use the snow level of their minimum height. */
1984  int tile_z = (std::get<Slope>(GetFoundationSlope(tile)) == SLOPE_FLAT) ? GetTileMaxZ(tile) : GetTileZ(tile);
1985  if (IsOnSnow(tile) != (tile_z > GetSnowLine())) {
1986  ToggleSnow(tile);
1987  MarkTileDirtyByTile(tile);
1988  }
1989  break;
1990  }
1991 
1992  case LT_TROPIC:
1993  if (GetTropicZone(tile) == TROPICZONE_DESERT && !IsOnDesert(tile)) {
1994  ToggleDesert(tile);
1995  MarkTileDirtyByTile(tile);
1996  }
1997  break;
1998  }
1999 
2000  if (IsRoadDepot(tile)) return;
2001 
2002  const Town *t = ClosestTownFromTile(tile, UINT_MAX);
2003  if (!HasRoadWorks(tile)) {
2004  HouseZonesBits grp = HZB_TOWN_EDGE;
2005 
2006  if (t != nullptr) {
2007  grp = GetTownRadiusGroup(t, tile);
2008 
2009  /* Show an animation to indicate road work */
2010  if (t->road_build_months != 0 &&
2011  (DistanceManhattan(t->xy, tile) < 8 || grp != HZB_TOWN_EDGE) &&
2012  IsNormalRoad(tile) && !HasAtMostOneBit(GetAllRoadBits(tile))) {
2013  if (std::get<0>(GetFoundationSlope(tile)) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile).Succeeded() && Chance16(1, 40)) {
2014  StartRoadWorks(tile);
2015 
2016  if (_settings_client.sound.ambient) SndPlayTileFx(SND_21_ROAD_WORKS, tile);
2018  TileX(tile) * TILE_SIZE + 7,
2019  TileY(tile) * TILE_SIZE + 7,
2020  0,
2021  EV_BULLDOZER);
2022  MarkTileDirtyByTile(tile);
2023  return;
2024  }
2025  }
2026  }
2027 
2028  {
2029  /* Adjust road ground type depending on 'grp' (grp is the distance to the center) */
2030  const Roadside *new_rs = (_settings_game.game_creation.landscape == LT_TOYLAND) ? _town_road_types_2[grp] : _town_road_types[grp];
2031  Roadside cur_rs = GetRoadside(tile);
2032 
2033  /* We have our desired type, do nothing */
2034  if (cur_rs == new_rs[0]) return;
2035 
2036  /* We have the pre-type of the desired type, switch to the desired type */
2037  if (cur_rs == new_rs[1]) {
2038  cur_rs = new_rs[0];
2039  /* We have barren land, install the pre-type */
2040  } else if (cur_rs == ROADSIDE_BARREN) {
2041  cur_rs = new_rs[1];
2042  /* We're totally off limits, remove any installation and make barren land */
2043  } else {
2044  cur_rs = ROADSIDE_BARREN;
2045  }
2046  SetRoadside(tile, cur_rs);
2047  MarkTileDirtyByTile(tile);
2048  }
2049  } else if (IncreaseRoadWorksCounter(tile)) {
2050  TerminateRoadWorks(tile);
2051 
2053  /* Generate a nicer town surface */
2054  const RoadBits old_rb = GetAnyRoadBits(tile, RTT_ROAD);
2055  const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
2056 
2057  if (old_rb != new_rb) {
2058  RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), RTT_ROAD, true);
2059 
2060  /* If new_rb is 0, there are now no road pieces left and the tile is no longer a road tile */
2061  if (new_rb == 0) {
2062  MarkTileDirtyByTile(tile);
2063  return;
2064  }
2065  }
2066  }
2067 
2068  /* Possibly change road type */
2069  if (GetRoadOwner(tile, RTT_ROAD) == OWNER_TOWN) {
2070  RoadType rt = GetTownRoadType();
2071  if (rt != GetRoadTypeRoad(tile)) {
2072  SetRoadType(tile, RTT_ROAD, rt);
2073  }
2074  }
2075 
2076  MarkTileDirtyByTile(tile);
2077  }
2078 }
2079 
2080 static bool ClickTile_Road(TileIndex tile)
2081 {
2082  if (!IsRoadDepot(tile)) return false;
2083 
2084  ShowDepotWindow(tile, VEH_ROAD);
2085  return true;
2086 }
2087 
2088 /* Converts RoadBits to TrackBits */
2089 static const TrackBits _road_trackbits[16] = {
2090  TRACK_BIT_NONE, // ROAD_NONE
2091  TRACK_BIT_NONE, // ROAD_NW
2092  TRACK_BIT_NONE, // ROAD_SW
2093  TRACK_BIT_LEFT, // ROAD_W
2094  TRACK_BIT_NONE, // ROAD_SE
2095  TRACK_BIT_Y, // ROAD_Y
2096  TRACK_BIT_LOWER, // ROAD_S
2097  TRACK_BIT_LEFT | TRACK_BIT_LOWER | TRACK_BIT_Y, // ROAD_Y | ROAD_SW
2098  TRACK_BIT_NONE, // ROAD_NE
2099  TRACK_BIT_UPPER, // ROAD_N
2100  TRACK_BIT_X, // ROAD_X
2101  TRACK_BIT_LEFT | TRACK_BIT_UPPER | TRACK_BIT_X, // ROAD_X | ROAD_NW
2102  TRACK_BIT_RIGHT, // ROAD_E
2103  TRACK_BIT_RIGHT | TRACK_BIT_UPPER | TRACK_BIT_Y, // ROAD_Y | ROAD_NE
2104  TRACK_BIT_RIGHT | TRACK_BIT_LOWER | TRACK_BIT_X, // ROAD_X | ROAD_SE
2105  TRACK_BIT_ALL, // ROAD_ALL
2106 };
2107 
2108 static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
2109 {
2110  TrackdirBits trackdirbits = TRACKDIR_BIT_NONE;
2111  TrackdirBits red_signals = TRACKDIR_BIT_NONE; // crossing barred
2112  switch (mode) {
2113  case TRANSPORT_RAIL:
2114  if (IsLevelCrossing(tile)) trackdirbits = TrackBitsToTrackdirBits(GetCrossingRailBits(tile));
2115  break;
2116 
2117  case TRANSPORT_ROAD: {
2118  RoadTramType rtt = (RoadTramType)sub_mode;
2119  if (!HasTileRoadType(tile, rtt)) break;
2120  switch (GetRoadTileType(tile)) {
2121  case ROAD_TILE_NORMAL: {
2122  const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 };
2123  RoadBits bits = GetRoadBits(tile, rtt);
2124 
2125  /* no roadbit at this side of tile, return 0 */
2126  if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) break;
2127 
2128  uint multiplier = drd_to_multiplier[(rtt == RTT_TRAM) ? DRD_NONE : GetDisallowedRoadDirections(tile)];
2129  if (!HasRoadWorks(tile)) trackdirbits = (TrackdirBits)(_road_trackbits[bits] * multiplier);
2130  break;
2131  }
2132 
2133  case ROAD_TILE_CROSSING: {
2134  Axis axis = GetCrossingRoadAxis(tile);
2135 
2136  if (side != INVALID_DIAGDIR && axis != DiagDirToAxis(side)) break;
2137 
2138  trackdirbits = TrackBitsToTrackdirBits(AxisToTrackBits(axis));
2139  if (IsCrossingBarred(tile)) {
2140  red_signals = trackdirbits;
2141  if (TrainOnCrossing(tile)) break;
2142 
2143  auto mask_red_signal_bits_if_crossing_barred = [&](TileIndex t, TrackdirBits mask) {
2144  if (IsLevelCrossingTile(t) && IsCrossingBarred(t)) red_signals &= mask;
2145  };
2146  /* Check for blocked adjacent crossing to south, keep only southbound red signal trackdirs, allow northbound traffic */
2147  mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, AxisToDiagDir(axis)), TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE);
2148  /* Check for blocked adjacent crossing to north, keep only northbound red signal trackdirs, allow southbound traffic */
2149  mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, ReverseDiagDir(AxisToDiagDir(axis))), TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW);
2150  }
2151  break;
2152  }
2153 
2154  default:
2155  case ROAD_TILE_DEPOT: {
2157 
2158  if (side != INVALID_DIAGDIR && side != dir) break;
2159 
2160  trackdirbits = TrackBitsToTrackdirBits(DiagDirToDiagTrackBits(dir));
2161  break;
2162  }
2163  }
2164  break;
2165  }
2166 
2167  default: break;
2168  }
2169  return CombineTrackStatus(trackdirbits, red_signals);
2170 }
2171 
2172 static const StringID _road_tile_strings[] = {
2173  STR_LAI_ROAD_DESCRIPTION_ROAD,
2174  STR_LAI_ROAD_DESCRIPTION_ROAD,
2175  STR_LAI_ROAD_DESCRIPTION_ROAD,
2176  STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS,
2177  STR_LAI_ROAD_DESCRIPTION_ROAD,
2178  STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD,
2179  STR_LAI_ROAD_DESCRIPTION_ROAD,
2180  STR_LAI_ROAD_DESCRIPTION_ROAD,
2181 };
2182 
2183 static void GetTileDesc_Road(TileIndex tile, TileDesc *td)
2184 {
2185  Owner rail_owner = INVALID_OWNER;
2186  Owner road_owner = INVALID_OWNER;
2187  Owner tram_owner = INVALID_OWNER;
2188 
2189  RoadType road_rt = GetRoadTypeRoad(tile);
2190  RoadType tram_rt = GetRoadTypeTram(tile);
2191  if (road_rt != INVALID_ROADTYPE) {
2192  const RoadTypeInfo *rti = GetRoadTypeInfo(road_rt);
2193  td->roadtype = rti->strings.name;
2194  td->road_speed = rti->max_speed / 2;
2195  road_owner = GetRoadOwner(tile, RTT_ROAD);
2196  }
2197  if (tram_rt != INVALID_ROADTYPE) {
2198  const RoadTypeInfo *rti = GetRoadTypeInfo(tram_rt);
2199  td->tramtype = rti->strings.name;
2200  td->tram_speed = rti->max_speed / 2;
2201  tram_owner = GetRoadOwner(tile, RTT_TRAM);
2202  }
2203 
2204  switch (GetRoadTileType(tile)) {
2205  case ROAD_TILE_CROSSING: {
2206  td->str = STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING;
2207  rail_owner = GetTileOwner(tile);
2208 
2209  const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
2210  td->railtype = rti->strings.name;
2211  td->rail_speed = rti->max_speed;
2212 
2213  break;
2214  }
2215 
2216  case ROAD_TILE_DEPOT:
2217  td->str = STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT;
2218  td->build_date = Depot::GetByTile(tile)->build_date;
2219  break;
2220 
2221  default: {
2222  td->str = (road_rt != INVALID_ROADTYPE ? _road_tile_strings[GetRoadside(tile)] : STR_LAI_ROAD_DESCRIPTION_TRAMWAY);
2223  break;
2224  }
2225  }
2226 
2227  /* Now we have to discover, if the tile has only one owner or many:
2228  * - Find a first_owner of the tile. (Currently road or tram must be present, but this will break when the third type becomes available)
2229  * - Compare the found owner with the other owners, and test if they differ.
2230  * Note: If road exists it will be the first_owner.
2231  */
2232  Owner first_owner = (road_owner == INVALID_OWNER ? tram_owner : road_owner);
2233  bool mixed_owners = (tram_owner != INVALID_OWNER && tram_owner != first_owner) || (rail_owner != INVALID_OWNER && rail_owner != first_owner);
2234 
2235  if (mixed_owners) {
2236  /* Multiple owners */
2237  td->owner_type[0] = (rail_owner == INVALID_OWNER ? STR_NULL : STR_LAND_AREA_INFORMATION_RAIL_OWNER);
2238  td->owner[0] = rail_owner;
2239  td->owner_type[1] = (road_owner == INVALID_OWNER ? STR_NULL : STR_LAND_AREA_INFORMATION_ROAD_OWNER);
2240  td->owner[1] = road_owner;
2241  td->owner_type[2] = (tram_owner == INVALID_OWNER ? STR_NULL : STR_LAND_AREA_INFORMATION_TRAM_OWNER);
2242  td->owner[2] = tram_owner;
2243  } else {
2244  /* One to rule them all */
2245  td->owner[0] = first_owner;
2246  }
2247 }
2248 
2253 static const uint8_t _roadveh_enter_depot_dir[4] = {
2255 };
2256 
2257 static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int, int)
2258 {
2259  switch (GetRoadTileType(tile)) {
2260  case ROAD_TILE_DEPOT: {
2261  if (v->type != VEH_ROAD) break;
2262 
2263  RoadVehicle *rv = RoadVehicle::From(v);
2264  if (rv->frame == RVC_DEPOT_STOP_FRAME &&
2266  rv->state = RVSB_IN_DEPOT;
2267  rv->vehstatus |= VS_HIDDEN;
2268  rv->direction = ReverseDir(rv->direction);
2269  if (rv->Next() == nullptr) VehicleEnterDepot(rv->First());
2270  rv->tile = tile;
2271 
2273  return VETSB_ENTERED_WORMHOLE;
2274  }
2275  break;
2276  }
2277 
2278  default: break;
2279  }
2280  return VETSB_CONTINUE;
2281 }
2282 
2283 
2284 static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owner)
2285 {
2286  if (IsRoadDepot(tile)) {
2287  if (GetTileOwner(tile) == old_owner) {
2288  if (new_owner == INVALID_OWNER) {
2290  } else {
2291  /* A road depot has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */
2292  RoadType rt = GetRoadTypeRoad(tile);
2293  if (rt == INVALID_ROADTYPE) rt = GetRoadTypeTram(tile);
2294  Company::Get(old_owner)->infrastructure.road[rt] -= 2;
2295  Company::Get(new_owner)->infrastructure.road[rt] += 2;
2296 
2297  SetTileOwner(tile, new_owner);
2298  for (RoadTramType rtt : _roadtramtypes) {
2299  if (GetRoadOwner(tile, rtt) == old_owner) {
2300  SetRoadOwner(tile, rtt, new_owner);
2301  }
2302  }
2303  }
2304  }
2305  return;
2306  }
2307 
2308  for (RoadTramType rtt : _roadtramtypes) {
2309  /* Update all roadtypes, no matter if they are present */
2310  if (GetRoadOwner(tile, rtt) == old_owner) {
2311  RoadType rt = GetRoadType(tile, rtt);
2312  if (rt != INVALID_ROADTYPE) {
2313  /* A level crossing has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */
2314  uint num_bits = IsLevelCrossing(tile) ? 2 : CountBits(GetRoadBits(tile, rtt));
2315  Company::Get(old_owner)->infrastructure.road[rt] -= num_bits;
2316  if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_bits;
2317  }
2318 
2319  SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner);
2320  }
2321  }
2322 
2323  if (IsLevelCrossing(tile)) {
2324  if (GetTileOwner(tile) == old_owner) {
2325  if (new_owner == INVALID_OWNER) {
2327  } else {
2328  /* Update infrastructure counts. No need to dirty windows here, we'll redraw the whole screen anyway. */
2329  Company::Get(old_owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR;
2330  Company::Get(new_owner)->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR;
2331 
2332  SetTileOwner(tile, new_owner);
2333  }
2334  }
2335  }
2336 }
2337 
2338 static CommandCost TerraformTile_Road(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
2339 {
2341  switch (GetRoadTileType(tile)) {
2342  case ROAD_TILE_CROSSING:
2343  if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2344  break;
2345 
2346  case ROAD_TILE_DEPOT:
2347  if (AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRoadDepotDirection(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2348  break;
2349 
2350  case ROAD_TILE_NORMAL: {
2351  RoadBits bits = GetAllRoadBits(tile);
2352  RoadBits bits_copy = bits;
2353  /* Check if the slope-road_bits combination is valid at all, i.e. it is safe to call GetRoadFoundation(). */
2354  if (CheckRoadSlope(tileh_new, &bits_copy, ROAD_NONE, ROAD_NONE).Succeeded()) {
2355  /* CheckRoadSlope() sometimes changes the road_bits, if it does not agree with them. */
2356  if (bits == bits_copy) {
2357  auto [tileh_old, z_old] = GetTileSlopeZ(tile);
2358 
2359  /* Get the slope on top of the foundation */
2360  z_old += ApplyFoundationToSlope(GetRoadFoundation(tileh_old, bits), tileh_old);
2361  z_new += ApplyFoundationToSlope(GetRoadFoundation(tileh_new, bits), tileh_new);
2362 
2363  /* The surface slope must not be changed */
2364  if ((z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2365  }
2366  }
2367  break;
2368  }
2369 
2370  default: NOT_REACHED();
2371  }
2372  }
2373 
2374  return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
2375 }
2376 
2378 static Vehicle *UpdateRoadVehPowerProc(Vehicle *v, void *data)
2379 {
2380  if (v->type != VEH_ROAD) return nullptr;
2381 
2382  RoadVehicleList *affected_rvs = static_cast<RoadVehicleList*>(data);
2383  include(*affected_rvs, RoadVehicle::From(v)->First());
2384 
2385  return nullptr;
2386 }
2387 
2394 static bool CanConvertUnownedRoadType(Owner owner, RoadTramType rtt)
2395 {
2396  return (owner == OWNER_NONE || (owner == OWNER_TOWN && rtt == RTT_ROAD));
2397 }
2398 
2407 static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, RoadType from_type, RoadType to_type)
2408 {
2409  // Scenario editor, maybe? Don't touch the owners when converting roadtypes...
2410  if (_current_company >= MAX_COMPANIES) return;
2411 
2412  // We can't get a company from invalid owners but we can get ownership of roads without an owner
2413  if (owner >= MAX_COMPANIES && owner != OWNER_NONE) return;
2414 
2415  Company *c;
2416 
2417  switch (owner) {
2418  case OWNER_NONE:
2419  SetRoadOwner(tile, GetRoadTramType(to_type), (Owner)_current_company);
2420  UpdateCompanyRoadInfrastructure(to_type, _current_company, num_pieces);
2421  break;
2422 
2423  default:
2424  c = Company::Get(owner);
2425  c->infrastructure.road[from_type] -= num_pieces;
2426  c->infrastructure.road[to_type] += num_pieces;
2428  break;
2429  }
2430 }
2431 
2443 {
2444  TileIndex area_end = tile;
2445 
2446  if (!ValParamRoadType(to_type)) return CMD_ERROR;
2447  if (area_start >= Map::Size()) return CMD_ERROR;
2448 
2449  RoadVehicleList affected_rvs;
2450  RoadTramType rtt = GetRoadTramType(to_type);
2451 
2453  CommandCost error = CommandCost((rtt == RTT_TRAM) ? STR_ERROR_NO_SUITABLE_TRAMWAY : STR_ERROR_NO_SUITABLE_ROAD); // by default, there is no road to convert.
2454  bool found_convertible_road = false; // whether we actually did convert any road/tram (see bug #7633)
2455 
2456  std::unique_ptr<TileIterator> iter = std::make_unique<OrthogonalTileIterator>(area_start, area_end);
2457  for (; (tile = *iter) != INVALID_TILE; ++(*iter)) {
2458  /* Is road present on tile? */
2459  if (!MayHaveRoad(tile)) continue;
2460 
2461  /* Converting to the same subtype? */
2462  RoadType from_type = GetRoadType(tile, rtt);
2463  if (from_type == INVALID_ROADTYPE || from_type == to_type) continue;
2464 
2465  /* Check if there is any infrastructure on tile */
2466  TileType tt = GetTileType(tile);
2467  switch (tt) {
2468  case MP_STATION:
2469  if (!IsAnyRoadStop(tile)) continue;
2470  break;
2471  case MP_ROAD:
2472  if (IsLevelCrossing(tile) && RoadNoLevelCrossing(to_type)) {
2473  error.MakeError(STR_ERROR_CROSSING_DISALLOWED_ROAD);
2474  continue;
2475  }
2476  break;
2477  case MP_TUNNELBRIDGE:
2478  if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) continue;
2479  break;
2480  default: continue;
2481  }
2482 
2483  /* Trying to convert other's road */
2484  Owner owner = GetRoadOwner(tile, rtt);
2485  if (!CanConvertUnownedRoadType(owner, rtt)) {
2486  CommandCost ret = CheckOwnership(owner, tile);
2487  if (ret.Failed()) {
2488  error = ret;
2489  continue;
2490  }
2491  }
2492 
2493  /* Base the ability to replace town roads and bridges on the town's
2494  * acceptance of destructive actions. */
2495  if (owner == OWNER_TOWN) {
2498  if (ret.Failed()) {
2499  error = ret;
2500  continue;
2501  }
2502  }
2503 
2504  /* Vehicle on the tile when not converting normal <-> powered
2505  * Tunnels and bridges have special check later */
2506  if (tt != MP_TUNNELBRIDGE) {
2507  if (!HasPowerOnRoad(from_type, to_type)) {
2509  if (ret.Failed()) {
2510  error = ret;
2511  continue;
2512  }
2513 
2514  if (rtt == RTT_ROAD && owner == OWNER_TOWN) {
2516  error.MakeError(STR_ERROR_OWNED_BY);
2517  continue;
2518  }
2519  }
2520 
2521  uint num_pieces = CountBits(GetAnyRoadBits(tile, rtt));
2522  if (tt == MP_STATION && IsBayRoadStopTile(tile)) {
2523  num_pieces *= ROAD_STOP_TRACKBIT_FACTOR;
2524  } else if (tt == MP_ROAD && IsRoadDepot(tile)) {
2525  num_pieces *= ROAD_DEPOT_TRACKBIT_FACTOR;
2526  }
2527 
2528  found_convertible_road = true;
2529  cost.AddCost(num_pieces * RoadConvertCost(from_type, to_type));
2530 
2531  if (flags & DC_EXEC) { // we can safely convert, too
2532  /* Call ConvertRoadTypeOwner() to update the company infrastructure counters. */
2533  if (owner == _current_company) {
2534  ConvertRoadTypeOwner(tile, num_pieces, owner, from_type, to_type);
2535  }
2536 
2537  /* Perform the conversion */
2538  SetRoadType(tile, rtt, to_type);
2539  MarkTileDirtyByTile(tile);
2540 
2541  /* update power of train on this tile */
2542  FindVehicleOnPos(tile, &affected_rvs, &UpdateRoadVehPowerProc);
2543 
2544  if (IsRoadDepotTile(tile)) {
2545  /* Update build vehicle window related to this depot */
2548  }
2549  }
2550  } else {
2551  TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
2552 
2553  /* If both ends of tunnel/bridge are in the range, do not try to convert twice -
2554  * it would cause assert because of different test and exec runs */
2555  if (endtile < tile) {
2556  if (OrthogonalTileArea(area_start, area_end).Contains(endtile)) continue;
2557  }
2558 
2559  /* When not converting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */
2560  if (!HasPowerOnRoad(from_type, to_type)) {
2561  CommandCost ret = TunnelBridgeIsFree(tile, endtile);
2562  if (ret.Failed()) {
2563  error = ret;
2564  continue;
2565  }
2566 
2567  if (rtt == RTT_ROAD && owner == OWNER_TOWN) {
2569  error.MakeError(STR_ERROR_OWNED_BY);
2570  continue;
2571  }
2572  }
2573 
2574  /* There are 2 pieces on *every* tile of the bridge or tunnel */
2575  uint num_pieces = (GetTunnelBridgeLength(tile, endtile) + 2) * 2;
2576  found_convertible_road = true;
2577  cost.AddCost(num_pieces * RoadConvertCost(from_type, to_type));
2578 
2579  if (flags & DC_EXEC) {
2580  /* Update the company infrastructure counters. */
2581  if (owner == _current_company) {
2582  /* Each piece should be counted TUNNELBRIDGE_TRACKBIT_FACTOR times
2583  * for the infrastructure counters (cause of #8297). */
2584  ConvertRoadTypeOwner(tile, num_pieces * TUNNELBRIDGE_TRACKBIT_FACTOR, owner, from_type, to_type);
2585  SetTunnelBridgeOwner(tile, endtile, _current_company);
2586  }
2587 
2588  /* Perform the conversion */
2589  SetRoadType(tile, rtt, to_type);
2590  SetRoadType(endtile, rtt, to_type);
2591 
2592  FindVehicleOnPos(tile, &affected_rvs, &UpdateRoadVehPowerProc);
2593  FindVehicleOnPos(endtile, &affected_rvs, &UpdateRoadVehPowerProc);
2594 
2595  if (IsBridge(tile)) {
2596  MarkBridgeDirty(tile);
2597  } else {
2598  MarkTileDirtyByTile(tile);
2599  MarkTileDirtyByTile(endtile);
2600  }
2601  }
2602  }
2603  }
2604 
2605  if (flags & DC_EXEC) {
2606  /* Roadtype changed, update roadvehicles as when entering different track */
2607  for (RoadVehicle *v : affected_rvs) {
2608  v->CargoChanged();
2609  }
2610  }
2611 
2612  return found_convertible_road ? cost : error;
2613 }
2614 
2615 
2617 extern const TileTypeProcs _tile_type_road_procs = {
2618  DrawTile_Road, // draw_tile_proc
2619  GetSlopePixelZ_Road, // get_slope_z_proc
2620  ClearTile_Road, // clear_tile_proc
2621  nullptr, // add_accepted_cargo_proc
2622  GetTileDesc_Road, // get_tile_desc_proc
2623  GetTileTrackStatus_Road, // get_tile_track_status_proc
2624  ClickTile_Road, // click_tile_proc
2625  nullptr, // animate_tile_proc
2626  TileLoop_Road, // tile_loop_proc
2627  ChangeTileOwner_Road, // change_tile_owner_proc
2628  nullptr, // add_produced_cargo_proc
2629  VehicleEnter_Road, // vehicle_enter_tile_proc
2630  GetFoundation_Road, // get_foundation_proc
2631  TerraformTile_Road, // terraform_tile_proc
2632 };
Functions related to autoslope.
bool AutoslopeCheckForEntranceEdge(TileIndex tile, int z_new, Slope tileh_new, DiagDirection entrance)
Autoslope check for tiles with an entrance on an edge.
Definition: autoslope.h:31
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition: autoslope.h:65
constexpr bool HasExactlyOneBit(T value)
Test whether value has exactly 1 bit set.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
#define CLRBITS(x, y)
Clears several bits in a variable.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
constexpr bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
constexpr T KillFirstBit(T value)
Clear the first bit in an integer.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
void DrawBridgeMiddle(const TileInfo *ti)
Draw the middle bits of a bridge.
TileIndex GetNorthernBridgeEnd(TileIndex t)
Finds the northern end of a bridge starting at a middle tile.
Definition: bridge_map.cpp:39
int GetBridgeHeight(TileIndex t)
Get the height ('z') of a bridge.
Definition: bridge_map.cpp:70
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
bool IsBridge(Tile t)
Checks if this is a bridge, instead of a tunnel.
Definition: bridge_map.h:24
Cheats _cheats
All the cheats.
Definition: cheat.cpp:16
Types related to cheating.
Common return value for all commands.
Definition: command_type.h:23
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:162
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Definition: command_type.h:63
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:83
bool Failed() const
Did this command fail?
Definition: command_type.h:171
StringID GetErrorMessage() const
Returns the error message of a command.
Definition: command_type.h:142
void MakeError(StringID message, StringID extra_message=INVALID_STRING_ID)
Makes this CommandCost behave like an error command.
Definition: command_type.h:101
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:127
SpriteID single_x
single piece of rail in X direction, without ground
Definition: rail.h:137
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition: rail.h:231
struct RailTypeInfo::@23 base_sprites
Struct containing the main sprites.
struct RailTypeInfo::@26 strings
Strings associated with the rail type.
SpriteID crossing
level crossing, rail in X direction
Definition: rail.h:144
SpriteID single_y
single piece of rail in Y direction, without ground
Definition: rail.h:138
StringID name
Name of this rail type.
Definition: rail.h:176
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition: road.h:147
RoadTypeLabelList alternate_labels
Road type labels this type provides in addition to the main label.
Definition: road.h:152
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
Definition: road.h:122
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition: road.h:177
struct RoadTypeInfo::@28 cursor
Cursors associated with the road type.
CursorID autoroad
Cursor for autorail tool.
Definition: road.h:96
TimerGameCalendar::Date introduction_date
Introduction date.
Definition: road.h:166
uint8_t sorting_order
The sorting order of this roadtype for the toolbar dropdown.
Definition: road.h:182
RoadTypeFlags flags
Bit mask of road type flags.
Definition: road.h:127
struct RoadTypeInfo::@29 strings
Strings associated with the rail type.
CursorID depot
Cursor for building a depot.
Definition: road.h:97
CursorID road_nwse
Cursor for building rail in Y direction.
Definition: road.h:95
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition: road.h:142
StringID name
Name of this rail type.
Definition: road.h:103
SpriteID build_y_road
button for building single rail in Y direction
Definition: road.h:86
CursorID tunnel
Cursor for building a tunnel.
Definition: road.h:98
SpriteID auto_road
button for the autoroad construction
Definition: road.h:87
struct RoadTypeInfo::@27 gui_sprites
struct containing the sprites for the road GUI.
SpriteID convert_road
button for converting road types
Definition: road.h:90
CursorID road_swne
Cursor for building rail in X direction.
Definition: road.h:94
SpriteID build_x_road
button for building single rail in X direction
Definition: road.h:85
SpriteID build_depot
button for building depots
Definition: road.h:88
SpriteID build_tunnel
button for building a tunnel
Definition: road.h:89
static Date date
Current date in days (day counter).
static constexpr TimerGame< struct Calendar >::Date INVALID_DATE
Representation of an invalid date.
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:28
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:38
DoCommandFlag
List of flags for a command.
Definition: command_type.h:374
@ DC_NONE
no flag is set
Definition: command_type.h:375
@ DC_AUTO
don't allow building on structures
Definition: command_type.h:377
@ DC_NO_WATER
don't allow building on water
Definition: command_type.h:379
@ DC_BANKRUPT
company bankrupts, skip money check, skip vehicle on tile check in some cases
Definition: command_type.h:382
@ DC_EXEC
execute the given command
Definition: command_type.h:376
Definition of stuff that is very close to a company, like the company struct itself.
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
void SetDParamsForOwnedBy(Owner owner, TileIndex tile)
Set the right DParams for STR_ERROR_OWNED_BY.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:52
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:53
Functions related to companies.
void DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
GUI Functions related to companies.
Owner
Enum for all companies/owners.
Definition: company_type.h:18
@ INVALID_OWNER
An invalid owner.
Definition: company_type.h:29
@ OWNER_DEITY
The object is owned by a superuser / goal script.
Definition: company_type.h:27
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
@ OWNER_WATER
The tile/execution is done by "water".
Definition: company_type.h:26
@ OWNER_TOWN
A town owns the tile, or a town is expanding.
Definition: company_type.h:24
@ MAX_COMPANIES
Maximum number of companies.
Definition: company_type.h:23
Some simple functions to help with accessing containers.
bool include(Container &container, typename Container::const_reference &item)
Helper function to append an item to a container if it is not already contained.
Base for all depots (except hangars)
bool CanBuildDepotByTileh(DiagDirection direction, Slope tileh)
Find out if the slope of the tile is suitable to build a depot of given direction.
Definition: depot_func.h:27
void ShowDepotWindow(TileIndex tile, VehicleType type)
Opens a depot window.
Definition: depot_gui.cpp:1164
bool IsValidAxis(Axis d)
Checks if an integer value is a valid Axis.
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Direction ReverseDir(Direction d)
Return the reverse of a direction.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
DiagDirection AxisToDiagDir(Axis a)
Converts an Axis to a DiagDirection.
Axis OtherAxis(Axis a)
Select the other axis as provided.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Axis
Allow incrementing of DiagDirDiff variables.
@ AXIS_X
The X axis.
@ AXIS_Y
The y axis.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
@ DIAGDIR_SW
Southwest.
static const uint LEVELCROSSING_TRACKBIT_FACTOR
Multiplier for how many regular track bits a level crossing counts.
Definition: economy_type.h:243
static const uint ROAD_STOP_TRACKBIT_FACTOR
Multiplier for how many regular track bits a bay stop counts.
Definition: economy_type.h:247
static const uint ROAD_DEPOT_TRACKBIT_FACTOR
Multiplier for how many regular track bits a road depot counts.
Definition: economy_type.h:245
@ EXPENSES_CONSTRUCTION
Construction costs.
Definition: economy_type.h:173
static const uint TUNNELBRIDGE_TRACKBIT_FACTOR
Multiplier for how many regular track bits a tunnel/bridge counts.
Definition: economy_type.h:241
EffectVehicle * CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular location.
Base class for all effect vehicles.
Functions related to effect vehicles.
@ EV_BULLDOZER
Bulldozer at roadworks.
void DrawRailCatenary(const TileInfo *ti)
Draws overhead wires and pylons for electric railways.
Definition: elrail.cpp:568
header file for electrified rail specific functions
bool HasRailCatenaryDrawn(RailType rt)
Test if we should draw rail catenary.
Definition: elrail_func.h:30
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:67
Functions related to world/map generation.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:988
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:18
uint32_t PaletteID
The number of the palette.
Definition: gfx_type.h:19
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:609
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:2057
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Definition: landscape.cpp:228
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:425
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Definition: landscape.cpp:382
uint ApplyFoundationToSlope(Foundation f, Slope &s)
Applies a foundation to a slope.
Definition: landscape.cpp:170
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
Return world Z coordinate of a given point of a tile.
Definition: landscape.cpp:303
uint ApplyPixelFoundationToSlope(Foundation f, Slope &s)
Applies a foundation to a slope.
Definition: landscape.h:126
int GetSlopePixelZInCorner(Slope tileh, Corner corner)
Determine the Z height of a corner relative to TileZ.
Definition: landscape.h:53
Command definitions related to landscape (slopes etc.).
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition: map.cpp:163
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition: map.cpp:146
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition: map_func.h:467
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition: map_func.h:608
TileIndexDiff TileOffsByAxis(Axis axis)
Convert an Axis to a TileIndexDiff.
Definition: map_func.h:552
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:415
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:567
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:404
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:84
Base for the NewGRF implementation.
bool HasGrfMiscBit(GrfMiscBit bit)
Check for grf miscellaneous bits.
Definition: newgrf.h:189
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition: newgrf.h:173
Functions/types related to NewGRF debugging.
SpriteID GetCustomRailSprite(const RailTypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results)
Get the sprite to draw for the given tile.
NewGRF handling of rail types.
SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSpriteGroup rtsg, TileContext context, uint *num_results)
Get the sprite to draw for the given tile.
NewGRF handling of road types.
@ DO_FULL_DETAIL
Also draw details of track and roads.
Definition: openttd.h:50
@ RTSG_CROSSING
Level crossing overlay images.
Definition: rail.h:57
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:307
bool RailNoLevelCrossings(RailType rt)
Test if a RailType disallows build of level crossings.
Definition: rail.h:345
Command definitions for rail.
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition: rail_map.h:115
static debug_inline RailTileType GetRailTileType(Tile t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition: rail_map.h:36
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition: rail_map.h:136
void SetTrackReservation(Tile t, TrackBits b)
Sets the reserved track bits of the tile.
Definition: rail_map.h:209
TrackBits GetRailReservationTrackBits(Tile t)
Returns the reserved track bits of the tile.
Definition: rail_map.h:194
@ RAIL_TILE_NORMAL
Normal rail tile without signals.
Definition: rail_map.h:24
Pseudo random number generator.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition: road.cpp:47
bool ValParamRoadType(RoadType roadtype)
Validate functions for rail building.
Definition: road.cpp:153
Road specific functions.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition: road.h:227
bool HasPowerOnRoad(RoadType enginetype, RoadType tiletype)
Checks if an engine of the given RoadType got power on a tile with a given RoadType.
Definition: road.h:242
@ ROTF_HIDDEN
Bit number for hidden from construction.
Definition: road.h:41
@ ROTF_CATENARY
Bit number for adding catenary.
Definition: road.h:38
Money RoadClearCost(RoadType roadtype)
Returns the cost of clearing the specified roadtype.
Definition: road.h:263
@ ROTFB_NONE
All flags cleared.
Definition: road.h:47
Money RoadConvertCost(RoadType from, RoadType to)
Calculates the cost of road conversion.
Definition: road.h:281
@ ROTSG_ONEWAY
Optional: One-way indicator images.
Definition: road.h:71
@ ROTSG_OVERLAY
Optional: Images for overlaying track.
Definition: road.h:61
@ ROTSG_GROUND
Required: Main group of ground images.
Definition: road.h:62
@ ROTSG_DEPOT
Optional: Depot images.
Definition: road.h:68
@ ROTSG_CURSORS
Optional: Cursor and toolbar icon images.
Definition: road.h:60
@ ROTSG_CATENARY_BACK
Optional: Catenary back.
Definition: road.h:65
@ ROTSG_CATENARY_FRONT
Optional: Catenary front.
Definition: road.h:64
bool RoadNoLevelCrossing(RoadType roadtype)
Test if road disallows level crossings.
Definition: road.h:295
Money RoadBuildCost(RoadType roadtype)
Returns the cost of building the specified roadtype.
Definition: road.h:252
void ResetRoadTypes()
Reset all road type information to its default values.
Definition: road_cmd.cpp:67
std::vector< RoadVehicle * > RoadVehicleList
Helper type for lists/vectors of road vehicles.
Definition: road_cmd.cpp:52
void InitRoadTypes()
Resolve sprites of custom road types.
Definition: road_cmd.cpp:114
RoadTypes _roadtypes_type
Bitmap of road/tram types.
Definition: road_cmd.cpp:62
CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadTramType rtt, DoCommandFlag flags, bool town_check)
Is it allowed to remove the given road bits from the given tile?
Definition: road_cmd.cpp:262
static const RoadBits _invalid_tileh_slopes_road[2][15]
Invalid RoadBits on slopes.
Definition: road_cmd.cpp:202
CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir)
Build a road depot.
Definition: road_cmd.cpp:1149
static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadTramType rtt, bool town_check)
Delete a piece of road.
Definition: road_cmd.cpp:325
static Foundation GetRoadFoundation(Slope tileh, RoadBits bits)
Get the foundationtype of a RoadBits Slope combination.
Definition: road_cmd.cpp:1301
static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir)
Checks whether a road or tram connection can be found when building a new road or tram.
Definition: road_cmd.cpp:950
static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existing, RoadBits other)
Calculate the costs for roads on slopes Aside modify the RoadBits to fit on the slopes.
Definition: road_cmd.cpp:545
void DrawRoadGroundSprites(const TileInfo *ti, RoadBits road, RoadBits tram, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, Roadside roadside, bool snow_or_desert)
Draw road ground sprites.
Definition: road_cmd.cpp:1605
CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id)
Build a piece of road.
Definition: road_cmd.cpp:610
static Vehicle * UpdateRoadVehPowerProc(Vehicle *v, void *data)
Update power of road vehicle under which is the roadtype being converted.
Definition: road_cmd.cpp:2378
bool RoadVehiclesAreBuilt()
Verify whether a road vehicle is available.
Definition: road_cmd.cpp:179
void DrawRoadCatenary(const TileInfo *ti)
Draws the catenary for the given tile.
Definition: road_cmd.cpp:1451
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Definition: road_cmd.cpp:1918
static void DrawTile_Road(TileInfo *ti)
Tile callback function for rendering a road tile to the screen.
Definition: road_cmd.cpp:1704
void DrawRoadTypeCatenary(const TileInfo *ti, RoadType rt, RoadBits rb)
Draws the catenary for the RoadType of the given tile.
Definition: road_cmd.cpp:1379
void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt)
Draw the road depot sprite.
Definition: road_cmd.cpp:1875
void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count)
Update road infrastructure counts for a company.
Definition: road_cmd.cpp:190
static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const RoadTypeInfo *rti, uint offset, bool snow_or_desert, PaletteID *pal)
Get ground sprite to draw for a road tile.
Definition: road_cmd.cpp:1562
CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai)
Build a long piece of road.
Definition: road_cmd.cpp:979
std::tuple< CommandCost, Money > CmdRemoveLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, bool start_half, bool end_half)
Remove a long piece of road.
Definition: road_cmd.cpp:1075
static bool CanConvertUnownedRoadType(Owner owner, RoadTramType rtt)
Checks the tile and returns whether the current player is allowed to convert the roadtype to another ...
Definition: road_cmd.cpp:2394
static void DrawRoadBits(TileInfo *ti)
Draw ground sprite and road pieces.
Definition: road_cmd.cpp:1623
static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int h, bool transparent)
Draws details on/around the road.
Definition: road_cmd.cpp:1497
static bool DrawRoadAsSnowDesert(bool snow_or_desert, Roadside roadside)
Should the road be drawn as a unpaved snow/desert road? By default, roads are always drawn as unpaved...
Definition: road_cmd.cpp:1366
const TileTypeProcs _tile_type_road_procs
Tile callback functions for road tiles.
Definition: landscape.cpp:50
CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type)
Convert one road subtype to another.
Definition: road_cmd.cpp:2442
static const uint8_t _roadveh_enter_depot_dir[4]
Given the direction the road depot is pointing, this is the direction the vehicle should be travellin...
Definition: road_cmd.cpp:2253
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
Allocate a new road type label.
Definition: road_cmd.cpp:134
static uint GetRoadSpriteOffset(Slope slope, RoadBits bits)
Get the sprite offset within a spritegroup.
Definition: road_cmd.cpp:1336
static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, RoadType from_type, RoadType to_type)
Convert the ownership of the RoadType of the tile if applicable.
Definition: road_cmd.cpp:2407
static bool CompareRoadTypes(const RoadType &first, const RoadType &second)
Compare roadtypes based on their sorting order.
Definition: road_cmd.cpp:103
void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, uint road_offset, uint tram_offset, bool draw_underlay)
Draw road underlay and overlay sprites.
Definition: road_cmd.cpp:1515
Road related functions.
Functions related to roads.
RoadBits AxisToRoadBits(Axis a)
Create the road-part which belongs to the given Axis.
Definition: road_func.h:111
bool IsValidRoadBits(RoadBits r)
Whether the given roadtype is valid.
Definition: road_func.h:23
bool HasRoadCatenaryDrawn(RoadType roadtype)
Test if we should draw road catenary.
Definition: road_func.h:145
void UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(TileIndex tile, Axis road_axis)
Update adjacent level crossing tiles in this multi-track crossing, due to removal of a level crossing...
Definition: train_cmd.cpp:1822
bool HasRoadCatenary(RoadType roadtype)
Test if a road type has catenary.
Definition: road_func.h:135
bool IsStraightRoad(RoadBits r)
Check if we've got a straight road.
Definition: road_func.h:81
RoadBits MirrorRoadBits(RoadBits r)
Calculate the mirrored RoadBits.
Definition: road_func.h:51
void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis)
Find adjacent level crossing tiles in this multi-track crossing and mark them dirty.
Definition: train_cmd.cpp:1805
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition: road_func.h:96
void UpdateLevelCrossing(TileIndex tile, bool sound=true, bool force_bar=false)
Update a level crossing to barred or open (crossing may include multiple adjacent tiles).
Definition: train_cmd.cpp:1773
RoadBits ComplementRoadBits(RoadBits r)
Calculate the complement of a RoadBits value.
Definition: road_func.h:37
Functions used internally by the roads.
Sprite constructs for road depots.
RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition: road_map.cpp:33
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition: road_map.h:251
bool HasCrossingReservation(Tile t)
Get the reservation state of the rail crossing.
Definition: road_map.h:380
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition: road_map.h:280
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition: road_map.h:74
static debug_inline bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition: road_map.h:106
#define IsOnDesert
Check if a road tile has snow/desert.
Definition: road_map.h:453
void SetRoadDepotExitDirection(Tile tile, DiagDirection dir)
Sets the exit direction of a road depot.
Definition: road_map.h:680
bool IsLevelCrossingTile(Tile t)
Return whether a tile is a level crossing tile.
Definition: road_map.h:95
bool IncreaseRoadWorksCounter(Tile t)
Increase the progress counter of road works.
Definition: road_map.h:523
RoadBits GetRoadBits(Tile t, RoadTramType rtt)
Get the present road bits for a specific road type.
Definition: road_map.h:128
RoadTileType
The different types of road tiles.
Definition: road_map.h:22
@ ROAD_TILE_NORMAL
Normal road.
Definition: road_map.h:23
@ ROAD_TILE_DEPOT
Depot (one entrance)
Definition: road_map.h:25
@ ROAD_TILE_CROSSING
Level crossing.
Definition: road_map.h:24
bool MayHaveRoad(Tile t)
Test whether a tile can have road/tram types.
Definition: road_map.h:33
bool IsValidDisallowedRoadDirections(DisallowedRoadDirections drt)
Checks if a DisallowedRoadDirections is valid.
Definition: road_map.h:291
Axis GetCrossingRoadAxis(Tile t)
Get the road axis of a level crossing.
Definition: road_map.h:325
TrackBits GetCrossingRailBits(Tile tile)
Get the rail track bits of a level crossing.
Definition: road_map.h:368
void SetDisallowedRoadDirections(Tile t, DisallowedRoadDirections drd)
Sets the disallowed directions.
Definition: road_map.h:312
Track GetCrossingRailTrack(Tile tile)
Get the rail track of a level crossing.
Definition: road_map.h:358
void StartRoadWorks(Tile t)
Start road works on a tile.
Definition: road_map.h:535
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition: road_map.h:301
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition: road_map.h:211
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition: road_map.h:565
#define ToggleDesert
Toggle the snow/desert state of a road tile.
Definition: road_map.h:465
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition: road_map.h:116
void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadType road_rt, RoadType tram_rt, uint town)
Make a level crossing.
Definition: road_map.h:660
void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tram_rt, TownID town, Owner road, Owner tram)
Make a normal road tile.
Definition: road_map.h:635
Roadside GetRoadside(Tile tile)
Get the decorations of a road.
Definition: road_map.h:493
RoadBits GetAllRoadBits(Tile tile)
Get all set RoadBits on the given tile.
Definition: road_map.h:141
void ToggleSnow(Tile t)
Toggle the snow/desert state of a road tile.
Definition: road_map.h:470
bool IsOnSnow(Tile t)
Check if a road tile has snow/desert.
Definition: road_map.h:459
Axis GetCrossingRailAxis(Tile t)
Get the rail axis of a level crossing.
Definition: road_map.h:337
void TerminateRoadWorks(Tile t)
Terminate road works on a tile.
Definition: road_map.h:551
RoadBits GetCrossingRoadBits(Tile tile)
Get the road bits of a level crossing.
Definition: road_map.h:348
void SetRoadType(Tile t, RoadTramType rtt, RoadType rt)
Set the road type of a tile.
Definition: road_map.h:604
Owner GetRoadOwner(Tile t, RoadTramType rtt)
Get the owner of a specific road type.
Definition: road_map.h:234
static debug_inline RoadTileType GetRoadTileType(Tile t)
Get the type of the road tile.
Definition: road_map.h:52
bool IsCrossingBarred(Tile t)
Check if the level crossing is barred.
Definition: road_map.h:416
void SetRoadside(Tile tile, Roadside s)
Set the decorations of a road.
Definition: road_map.h:503
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition: road_map.h:268
void MakeRoadDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RoadType rt)
Make a road depot.
Definition: road_map.h:694
void SetCrossingReservation(Tile t, bool b)
Set the reservation state of the rail crossing.
Definition: road_map.h:393
void SetRoadBits(Tile t, RoadBits r, RoadTramType rtt)
Set the present road bits for a specific road type.
Definition: road_map.h:153
Roadside
The possible road side decorations.
Definition: road_map.h:477
@ ROADSIDE_GRASS_ROAD_WORKS
Road on grass with road works.
Definition: road_map.h:484
@ ROADSIDE_PAVED
Road with paved sidewalks.
Definition: road_map.h:480
@ ROADSIDE_STREET_LIGHTS
Road with street lights on paved sidewalks.
Definition: road_map.h:481
@ ROADSIDE_BARREN
Road on barren land.
Definition: road_map.h:478
@ ROADSIDE_GRASS
Road on grass.
Definition: road_map.h:479
@ ROADSIDE_TREES
Road with trees on paved sidewalks.
Definition: road_map.h:483
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
Definition: road_map.h:85
bool HasRoadWorks(Tile t)
Check if a tile has road works.
Definition: road_map.h:513
static debug_inline bool IsNormalRoad(Tile t)
Return whether a tile is a normal road.
Definition: road_map.h:64
RoadBits
Enumeration for the road parts on a tile.
Definition: road_type.h:52
@ ROAD_SW
South-west part.
Definition: road_type.h:55
@ ROAD_ALL
Full 4-way crossing.
Definition: road_type.h:66
@ ROAD_NONE
No road-part is build.
Definition: road_type.h:53
@ ROAD_NE
North-east part.
Definition: road_type.h:57
@ ROAD_SE
South-east part.
Definition: road_type.h:56
@ ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition: road_type.h:59
@ ROAD_NW
North-west part.
Definition: road_type.h:54
@ ROAD_X
Full road along the x-axis (south-west + north-east)
Definition: road_type.h:58
RoadTypes
The different roadtypes we support, but then a bitmask of them.
Definition: road_type.h:38
@ ROADTYPES_TRAM
Trams.
Definition: road_type.h:41
@ ROADTYPES_NONE
No roadtypes.
Definition: road_type.h:39
RoadType
The different roadtypes we support.
Definition: road_type.h:25
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition: road_type.h:30
@ ROADTYPE_TRAM
Trams.
Definition: road_type.h:28
@ ROADTYPE_ROAD
Basic road type.
Definition: road_type.h:27
@ ROADTYPE_END
Used for iterations.
Definition: road_type.h:29
@ ROADTYPE_BEGIN
Used for iterations.
Definition: road_type.h:26
DisallowedRoadDirections
Which directions are disallowed ?
Definition: road_type.h:73
@ DRD_NORTHBOUND
All northbound traffic is disallowed.
Definition: road_type.h:76
@ DRD_END
Sentinel.
Definition: road_type.h:78
@ DRD_BOTH
All directions are disallowed.
Definition: road_type.h:77
@ DRD_NONE
None of the directions are disallowed.
Definition: road_type.h:74
@ DRD_SOUTHBOUND
All southbound traffic is disallowed.
Definition: road_type.h:75
All the roadtype-specific information is stored here.
static const RoadTypeInfo _original_roadtypes[]
Global Roadtype definition.
Definition: roadtypes.h:19
Road vehicle states.
@ RVSB_IN_DEPOT
The vehicle is in a depot.
Definition: roadveh.h:38
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:57
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
static constexpr int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Definition: slope_func.h:160
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition: slope_func.h:88
uint SlopeToSpriteOffset(Slope s)
Returns the Sprite offset for a given Slope.
Definition: slope_func.h:415
Corner GetHighestSlopeCorner(Slope s)
Returns the highest corner of a slope (one corner raised or a steep slope).
Definition: slope_func.h:126
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition: slope_func.h:36
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition: slope_func.h:369
Slope SlopeWithOneCornerRaised(Corner corner)
Returns the slope with a specific corner raised.
Definition: slope_func.h:99
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition: slope_type.h:61
@ SLOPE_SW
south and west corner are raised
Definition: slope_type.h:56
@ SLOPE_FLAT
a flat tile
Definition: slope_type.h:49
@ SLOPE_NE
north and east corner are raised
Definition: slope_type.h:58
@ SLOPE_SE
south and east corner are raised
Definition: slope_type.h:57
@ SLOPE_NW
north and west corner are raised
Definition: slope_type.h:55
Foundation
Enumeration for Foundations.
Definition: slope_type.h:93
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition: slope_type.h:95
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition: slope_type.h:94
@ FOUNDATION_INCLINED_X
The tile has an along X-axis inclined foundation.
Definition: slope_type.h:96
@ FOUNDATION_INCLINED_Y
The tile has an along Y-axis inclined foundation.
Definition: slope_type.h:97
static const uint32_t VALID_LEVEL_CROSSING_SLOPES
Constant bitset with safe slopes for building a level crossing.
Definition: slope_type.h:86
Functions related to sound.
@ SND_21_ROAD_WORKS
31 == 0x1F Road reconstruction animation
Definition: sound_type.h:70
void DrawRailTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32_t total_offset, uint32_t newgrf_offset, PaletteID default_palette)
Draw tile sprite sequence in GUI with railroad specifics.
Definition: sprite.h:99
void DrawRailTileSeq(const struct TileInfo *ti, const DrawTileSprites *dts, TransparencyOption to, int32_t total_offset, uint32_t newgrf_offset, PaletteID default_palette)
Draw tile sprite sequence on tile with railroad specifics.
Definition: sprite.h:89
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1605
static const SpriteID SPR_TRAMWAY_BASE
Tramway sprites.
Definition: sprites.h:272
static const PaletteID PALETTE_TO_BARE_LAND
sets colour to bare land stuff for rail, road and crossings
Definition: sprites.h:1593
static const SpriteID SPR_ONEWAY_BASE
One way road sprites.
Definition: sprites.h:293
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
Definition: station_map.h:266
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Definition: station_map.h:276
bool IsAnyRoadStop(Tile t)
Is the station at t a road station?
Definition: station_map.h:245
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
Definition: station_map.h:356
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
Definition: station_map.h:344
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition: stdafx.h:280
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings.cpp:104
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:51
bool value
tells if the bool cheat is active or not
Definition: cheat_type.h:18
Cheat magic_bulldozer
dynamite industries, objects
Definition: cheat_type.h:27
SoundSettings sound
sound effect settings
GUISettings gui
settings related to the GUI
std::array< uint32_t, ROADTYPE_END > road
Count of company owned track bits for each road type.
Definition: company_base.h:34
std::array< uint32_t, RAILTYPE_END > rail
Count of company owned track bits for each rail type.
Definition: company_base.h:33
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
Definition: company_base.h:147
bool build_on_slopes
allow building on slopes
bool extra_dynamite
extra dynamite
bool crossing_with_competitor
allow building of level crossings with competitor roads or rails
TimerGameCalendar::Date build_date
Date of construction.
Definition: depot_base.h:26
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
bool mod_road_rebuild
roadworks remove unnecessary RoadBits
uint8_t dist_local_authority
distance for town local authority, default 20
A special vehicle is one of the following:
TramReplacement tram
In which way tram depots were replaced.
Definition: newgrf.h:181
bool show_track_reservation
highlight reserved tracks.
uint8_t landscape
the landscape we're currently in
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
GameCreationSettings game_creation
settings used during the creation of a game (map)
static debug_inline uint Size()
Get the size of the map.
Definition: map_func.h:288
Represents the covered area of e.g.
Definition: tilearea_type.h:18
SpriteID sprite
The 'real' sprite.
Definition: gfx_type.h:24
Tindex index
Index of this pool item.
Definition: pool_type.hpp:238
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:328
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:309
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:350
Buses, trucks and trams belong to this class.
Definition: roadveh.h:98
uint8_t state
Definition: roadveh.h:100
bool ambient
Play ambient, industry and town sounds.
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
T * Next() const
Get next vehicle in the chain.
static Pool::IterateWrapper< T > Iterate(size_t from=0)
Returns an iterable ensemble of all valid vehicles of type T.
T * First() const
Get the first vehicle in the chain.
Used to only draw a part of the sprite.
Definition: gfx_type.h:231
Tile description for the 'land area information' tool.
Definition: tile_cmd.h:52
uint16_t rail_speed
Speed limit of rail (bridges and track)
Definition: tile_cmd.h:65
StringID str
Description of the tile.
Definition: tile_cmd.h:53
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition: tile_cmd.h:57
uint16_t tram_speed
Speed limit of tram (bridges and track)
Definition: tile_cmd.h:69
StringID roadtype
Type of road on the tile.
Definition: tile_cmd.h:66
StringID tramtype
Type of tram on the tile.
Definition: tile_cmd.h:68
StringID railtype
Type of rail on the tile.
Definition: tile_cmd.h:64
uint16_t road_speed
Speed limit of road (bridges and track)
Definition: tile_cmd.h:67
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
StringID owner_type[4]
Type of each owner.
Definition: tile_cmd.h:56
Tile information, used while rendering the tile.
Definition: tile_cmd.h:43
int z
Height.
Definition: tile_cmd.h:48
int x
X position of the tile in unit coordinates.
Definition: tile_cmd.h:44
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:46
TileIndex tile
Tile index.
Definition: tile_cmd.h:47
int y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:45
Set of callback functions for performing tile operations of a given tile type.
Definition: tile_cmd.h:158
std::array< uint32_t, HZB_END > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition: town.h:47
Town data structure.
Definition: town.h:54
TileIndex xy
town center tile
Definition: town.h:55
TownCache cache
Container for all cacheable data.
Definition: town.h:57
uint8_t road_build_months
fund road reconstruction in action?
Definition: town.h:99
Vehicle data structure.
Definition: vehicle_base.h:244
Direction direction
facing
Definition: vehicle_base.h:307
uint8_t vehstatus
Status.
Definition: vehicle_base.h:354
TileIndex tile
Current tile index.
Definition: vehicle_base.h:264
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:21
@ VETSB_ENTERED_WORMHOLE
The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/...
Definition: tile_cmd.h:37
@ VETSB_CONTINUE
Bit sets of the above specified bits.
Definition: tile_cmd.h:35
std::tuple< Slope, int > GetTileSlopeZ(TileIndex tile)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:55
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition: tile_map.cpp:136
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:116
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition: tile_map.h:214
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition: tile_map.h:178
void SetTileOwner(Tile tile, Owner owner)
Sets the owner of a tile.
Definition: tile_map.h:198
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition: tile_map.h:312
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition: tile_map.h:96
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition: tile_map.h:161
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition: tile_map.h:238
std::tuple< Slope, int > GetTilePixelSlope(TileIndex tile)
Return the slope of a given tile.
Definition: tile_map.h:289
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition: tile_map.h:279
@ TROPICZONE_DESERT
Tile is desert.
Definition: tile_type.h:78
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in #ZOOM_BASE.
Definition: tile_type.h:18
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:15
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
TileType
The different types of tiles.
Definition: tile_type.h:47
@ MP_ROAD
A tile with road (or tram tracks)
Definition: tile_type.h:50
@ MP_STATION
A tile of a station.
Definition: tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition: tile_type.h:57
@ MP_RAILWAY
A railway.
Definition: tile_type.h:49
Definition of the game-calendar-timer.
Base of the town class.
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:2447
@ ROAD_REMOVE
Removal of a road owned by the town.
Definition: town.h:176
@ TUNNELBRIDGE_REMOVE
Removal of a tunnel or bridge owned by the towb.
Definition: town.h:177
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
Definition: town_cmd.cpp:3852
void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags)
Changes town rating of the current company.
Definition: town_cmd.cpp:3949
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition: town_cmd.cpp:926
CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
Definition: town_cmd.cpp:3986
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
Definition: town_cmd.cpp:3870
void MakeDefaultName(T *obj)
Set the default name for a depot/waypoint.
Definition: town.h:253
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition: town_map.h:35
static constexpr int RATING_ROAD_DOWN_STEP_EDGE
removing a roadpiece at the edge
Definition: town_type.h:65
static constexpr int RATING_ROAD_DOWN_STEP_INNER
removing a roadpiece in the middle
Definition: town_type.h:64
static constexpr int RATING_ROAD_MINIMUM
minimum rating after removing town owned road
Definition: town_type.h:66
TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
Converts TrackBits to TrackdirBits while allowing both directions.
Definition: track_func.h:319
TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
Builds a TrackStatus.
Definition: track_func.h:388
TrackBits AxisToTrackBits(Axis a)
Maps an Axis to the corresponding TrackBits value.
Definition: track_func.h:88
TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal track bits incidating with that diagdir.
Definition: track_func.h:524
Track AxisToTrack(Axis a)
Convert an Axis to the corresponding Track AXIS_X -> TRACK_X AXIS_Y -> TRACK_Y Uses the fact that the...
Definition: track_func.h:66
TrackBits
Allow incrementing of Track variables.
Definition: track_type.h:35
@ TRACK_BIT_UPPER
Upper track.
Definition: track_type.h:39
@ TRACK_BIT_LEFT
Left track.
Definition: track_type.h:41
@ TRACK_BIT_Y
Y-axis track.
Definition: track_type.h:38
@ TRACK_BIT_NONE
No track.
Definition: track_type.h:36
@ TRACK_BIT_X
X-axis track.
Definition: track_type.h:37
@ TRACK_BIT_LOWER
Lower track.
Definition: track_type.h:40
@ TRACK_BIT_ALL
All possible tracks.
Definition: track_type.h:50
@ TRACK_BIT_RIGHT
Right track.
Definition: track_type.h:42
@ TRACKDIR_X_NE
X-axis and direction to north-east.
Definition: track_type.h:69
@ TRACKDIR_Y_SE
Y-axis and direction to south-east.
Definition: track_type.h:70
@ TRACKDIR_X_SW
X-axis and direction to south-west.
Definition: track_type.h:77
@ TRACKDIR_Y_NW
Y-axis and direction to north-west.
Definition: track_type.h:78
TrackdirBits
Allow incrementing of Trackdir variables.
Definition: track_type.h:98
@ TRACKDIR_BIT_Y_NW
Track y-axis, direction north-west.
Definition: track_type.h:108
@ TRACKDIR_BIT_X_NE
Track x-axis, direction north-east.
Definition: track_type.h:100
@ TRACKDIR_BIT_Y_SE
Track y-axis, direction south-east.
Definition: track_type.h:101
@ TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:99
@ TRACKDIR_BIT_X_SW
Track x-axis, direction south-west.
Definition: track_type.h:107
Track
These are used to specify a single track.
Definition: track_type.h:19
Base for the train class.
bool TrainOnCrossing(TileIndex tile)
Check if a level crossing tile has a train on it.
Definition: train_cmd.cpp:1683
@ TO_BUILDINGS
company buildings - depots, stations, HQ, ...
Definition: transparency.h:27
@ TO_CATENARY
catenary
Definition: transparency.h:30
@ TO_TREES
trees
Definition: transparency.h:24
@ TO_HOUSES
town buildings
Definition: transparency.h:25
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
Definition: transparency.h:48
uint8_t _display_opt
What do we want to draw/do?
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
Definition: transparency.h:59
TransportType
Available types of transport.
@ TRANSPORT_RAIL
Transport by train.
@ TRANSPORT_ROAD
Transport by road vehicle.
Header file for things common for tunnels and bridges.
void SetTunnelBridgeOwner(TileIndex begin, TileIndex end, Owner owner)
Sets the ownership of the bridge/tunnel ramps.
Definition: tunnelbridge.h:41
void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height)
Mark bridge tiles dirty.
uint GetTunnelBridgeLength(TileIndex begin, TileIndex end)
Calculates the length of a tunnel or a bridge (without end tiles)
Definition: tunnelbridge.h:25
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:546
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it,...
Definition: vehicle.cpp:1552
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:505
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
Finds vehicle in tunnel / bridge.
Definition: vehicle.cpp:575
@ VS_HIDDEN
Vehicle is not visible.
Definition: vehicle_base.h:33
Functions related to vehicles.
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition: viewport.cpp:671
void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32_t x, int32_t y, int z, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite at a specific world-coordinate relative to the current tile.
Definition: viewport.cpp:564
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition: viewport.cpp:587
Functions related to (drawing on) viewports.
static const uint BB_HEIGHT_UNDER_BRIDGE
Some values for constructing bounding boxes (BB).
Definition: viewport_type.h:88
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3211
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
Definition: window_type.h:351
@ WC_BUILD_VEHICLE
Build vehicle; Window numbers:
Definition: window_type.h:389
Entry point for OpenTTD to YAPF's cache.
void YapfNotifyTrackLayoutChange(TileIndex tile, Track track)
Use this function to notify YAPF that track layout (or signal configuration) has change.
Definition: yapf_rail.cpp:635
@ ZOOM_LVL_DETAIL
All zoom levels below or equal to this will result in details on the screen, like road-work,...
Definition: zoom_type.h:38