diff options
Diffstat (limited to 'src/road_cmd.cpp')
-rw-r--r-- | src/road_cmd.cpp | 88 |
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 |