summaryrefslogtreecommitdiff
path: root/src/road_cmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/road_cmd.cpp')
-rw-r--r--src/road_cmd.cpp88
1 files changed, 67 insertions, 21 deletions
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index 7931fa965..5954b6547 100644
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -35,6 +35,7 @@
#include "date_func.h"
#include "genworld.h"
#include "company_gui.h"
+#include "trafficlight_func.h"
#include "table/strings.h"
@@ -173,9 +174,10 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R
* @param pieces roadbits to remove
* @param rt roadtype to remove
* @param crossing_check should we check if there is a tram track when we are removing road from crossing?
+ * @param trafficlights_check Should we check if there is a traffic light before removing road bits?
* @param town_check should we check if the town allows removal?
*/
-static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true)
+static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadType rt, bool crossing_check, bool trafficlights_check, bool town_check = true)
{
RoadTypes rts = GetRoadTypes(tile);
/* The tile doesn't have the given road type */
@@ -299,6 +301,11 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
/* Now set present what it will be after the remove */
present ^= pieces;
+ /* Check if traffic lights are present and if removing them would cause the tile to have less than three roadbits (of any kind!). */
+ if (trafficlights_check && HasTrafficLights(tile) && (CountBits(present | GetOtherRoadBits(tile, rt)) < 3)) {
+ return_cmd_error(STR_ERROR_MUST_REMOVE_TRAFFIC_LIGHTS_FIRST);
+ }
+
/* Check for invalid RoadBit combinations on slopes */
if (tileh != SLOPE_FLAT && present != ROAD_NONE &&
(present & _invalid_tileh_slopes_road[0][tileh & SLOPE_ELEVATED]) == present) {
@@ -399,7 +406,6 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
}
}
-
/**
* Calculate the costs for roads on slopes
* Aside modify the RoadBits to fit on the slopes
@@ -956,7 +962,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32
/* try to remove the halves. */
if (bits != 0) {
- CommandCost ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rt, true);
+ CommandCost ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rt, true, true);
if (ret.Succeeded()) {
if (flags & DC_EXEC) {
money -= ret.GetCost();
@@ -964,7 +970,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32
_additional_cash_required = DoCommand(start_tile, end_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost();
return cost;
}
- RemoveRoad(tile, flags, bits, rt, true, false);
+ RemoveRoad(tile, flags, bits, rt, true, true, false);
}
cost.AddCost(ret);
had_success = true;
@@ -1067,9 +1073,18 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags)
/* Clear the road if only one piece is on the tile OR we are not using the DC_AUTO flag */
if ((HasExactlyOneBit(b) && GetRoadBits(tile, ROADTYPE_TRAM) == ROAD_NONE) || !(flags & DC_AUTO)) {
CommandCost ret(EXPENSES_CONSTRUCTION);
+
+ /* Remove traffic light if necessary. */
+ if (HasTrafficLights(tile)) {
+ CommandCost tl_ret = CmdRemoveTrafficLights(tile, flags, 0, 0, 0);
+ if (tl_ret.Failed()) return tl_ret;
+ ret.AddCost(tl_ret);
+ }
+
+ /* Remove road bits. */
RoadType rt;
FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) {
- CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rt), rt, true);
+ CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rt), rt, true, false);
if (tmp_ret.Failed()) return tmp_ret;
ret.AddCost(tmp_ret);
}
@@ -1089,7 +1104,7 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags)
RoadType rt = ROADTYPE_TRAM;
do {
if (HasBit(rts, rt)) {
- CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rt, false);
+ CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rt, false, false);
if (tmp_ret.Failed()) return tmp_ret;
ret.AddCost(tmp_ret);
}
@@ -1212,7 +1227,7 @@ void DrawTramCatenary(const TileInfo *ti, RoadBits tram)
* @param dy the offset from the top of the BB of the tile
* @param h the height of the sprite to draw
*/
-static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int h)
+void DrawRoadDetail(SpriteID img, TileInfo *ti, int dx, int dy, int h)
{
int x = ti->x | dx;
int y = ti->y | dy;
@@ -1278,6 +1293,8 @@ static void DrawRoadBits(TileInfo *ti)
}
}
+ if (_settings_game.construction.traffic_lights && HasTrafficLights(ti->tile) && _cur_dpi->zoom <= ZOOM_LVL_DETAIL) DrawTrafficLights(ti);
+
if (HasRoadWorks(ti->tile)) {
/* Road works */
DrawGroundSprite((road | tram) & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y, PAL_NONE);
@@ -1466,6 +1483,19 @@ static Foundation GetFoundation_Road(TileIndex tile, Slope tileh)
}
}
+/**
+ * Animates the traffic lights on a tile.
+ * @param tile This tile.
+ * @pre The setting must be anabled.
+ * @pre The tile must have trafficlights.
+ */
+static void AnimateTile_Road(TileIndex tile)
+{
+ if (_settings_game.construction.traffic_lights && HasTrafficLights(tile)) {
+ if (_tick_counter % 16 == 0) MarkTileDirtyByTile(tile);
+ }
+}
+
static const Roadside _town_road_types[][2] = {
{ ROADSIDE_GRASS, ROADSIDE_GRASS },
{ ROADSIDE_PAVED, ROADSIDE_PAVED },
@@ -1511,7 +1541,7 @@ static void TileLoop_Road(TileIndex tile)
grp = GetTownRadiusGroup(t, tile);
/* Show an animation to indicate road work */
- if (t->road_build_months != 0 &&
+ if ((t->road_build_months != 0 || Chance16(_settings_game.economy.random_road_construction, 100)) &&
(DistanceManhattan(t->xy, tile) < 8 || grp != HZB_TOWN_EDGE) &&
IsNormalRoad(tile) && !HasAtMostOneBit(GetAllRoadBits(tile))) {
if (GetFoundationSlope(tile) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile).Succeeded() && Chance16(1, 40)) {
@@ -1550,20 +1580,29 @@ static void TileLoop_Road(TileIndex tile)
SetRoadside(tile, cur_rs);
MarkTileDirtyByTile(tile);
}
- } else if (IncreaseRoadWorksCounter(tile)) {
- TerminateRoadWorks(tile);
+ } else {
+ /* In the first half of roadworks, generate traffic lights with a certain chance. */
+ if (_settings_game.construction.traffic_lights && _settings_game.construction.towns_build_traffic_lights &&
+ (GetRoadWorksCounter(tile) < 8) && (CountBits(GetRoadBits(tile, ROADTYPE_ROAD)) >= 3) &&
+ !HasTrafficLights(tile) && Chance16(1, 20)) {
+ CmdBuildTrafficLights(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, 0, 0, 0);
+ MarkTileDirtyByTile(tile);
+ }
+ if (IncreaseRoadWorksCounter(tile)) {
+ TerminateRoadWorks(tile);
- if (_settings_game.economy.mod_road_rebuild) {
- /* Generate a nicer town surface */
- const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
- const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
+ if (_settings_game.economy.mod_road_rebuild) {
+ /* Generate a nicer town surface. */
+ const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
+ const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
- if (old_rb != new_rb) {
- RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), ROADTYPE_ROAD, true);
+ if (old_rb != new_rb) {
+ RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), ROADTYPE_ROAD, true, true);
+ }
}
- }
- MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(tile);
+ }
}
}
@@ -1598,7 +1637,7 @@ static const TrackBits _road_trackbits[16] = {
static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
TrackdirBits trackdirbits = TRACKDIR_BIT_NONE;
- TrackdirBits red_signals = TRACKDIR_BIT_NONE; // crossing barred
+ TrackdirBits red_signals = TRACKDIR_BIT_NONE; // Crossing barred or red traffic light.
switch (mode) {
case TRANSPORT_RAIL:
if (IsLevelCrossing(tile)) trackdirbits = TrackBitsToTrackdirBits(GetCrossingRailBits(tile));
@@ -1617,6 +1656,8 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, u
uint multiplier = drd_to_multiplier[rt == ROADTYPE_TRAM ? DRD_NONE : GetDisallowedRoadDirections(tile)];
if (!HasRoadWorks(tile)) trackdirbits = (TrackdirBits)(_road_trackbits[bits] * multiplier);
+ if (_settings_game.construction.traffic_lights && HasTrafficLights(tile))
+ red_signals = trackdirbits & GetTrafficLightDisallowedDirections(tile);
break;
}
@@ -1686,11 +1727,16 @@ static void GetTileDesc_Road(TileIndex tile, TileDesc *td)
default: {
RoadTypes rts = GetRoadTypes(tile);
- td->str = (HasBit(rts, ROADTYPE_ROAD) ? _road_tile_strings[GetRoadside(tile)] : STR_LAI_ROAD_DESCRIPTION_TRAMWAY);
+ if (HasTrafficLights(tile)) {
+ td->str = STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_TRAFFIC_LIGHTS;
+ } else {
+ td->str = (HasBit(rts, ROADTYPE_ROAD) ? _road_tile_strings[GetRoadside(tile)] : STR_LAI_ROAD_DESCRIPTION_TRAMWAY);
+ }
if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM);
break;
}
+
}
/* Now we have to discover, if the tile has only one owner or many:
@@ -1846,7 +1892,7 @@ extern const TileTypeProcs _tile_type_road_procs = {
GetTileDesc_Road, // get_tile_desc_proc
GetTileTrackStatus_Road, // get_tile_track_status_proc
ClickTile_Road, // click_tile_proc
- NULL, // animate_tile_proc
+ AnimateTile_Road, // animate_tile_proc
TileLoop_Road, // tile_loop_proc
ChangeTileOwner_Road, // change_tile_owner_proc
NULL, // add_produced_cargo_proc