From 7bf1737a66966094407338661bda4a1352e3e691 Mon Sep 17 00:00:00 2001 From: rubidium Date: Thu, 24 Apr 2008 12:05:36 +0000 Subject: [PATCH] (svn r12866) [0.6] -Backport from trunk r12759, r12717, r12682, r12564, r12561: - Fix: Slope checking for NewGRFs failed (r12759) - Fix: Check the TILE_NOT_SLOPED flag of the _north_ tile of multi-tile houses to decide if autoslope is allowed (r12717) - Fix: Removing road pieces from a town gave you twice the intended penalty [FS#1920] (r12682) - Fix: Towns could not terraform when inflation rised terraform prices enough (r12564) - Fix: Do not affect town rating change by the order in which we examine stations (r12561) --- src/newgrf_industrytiles.cpp | 2 +- src/newgrf_spritegroup.cpp | 2 +- src/road_cmd.cpp | 10 +++--- src/town_cmd.cpp | 65 ++++++++++++++++++++++++------------ 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 9032b95634..70eafa161a 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -275,7 +275,7 @@ bool PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, return !IsSlopeRefused(GetTileSlope(ind_tile, NULL), its->slopes_refused); } if (its->grf_prop.grffile->grf_version < 7) { - return (callback_res & 0xFF) != 0; // mask to 8 bit callback result + return callback_res != 0; } /* Copy some parameters from the registers to the error message text ref. stack */ diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 65e8f29e21..f0820a25bd 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -97,7 +97,7 @@ static inline bool Is8BitCallback(const ResolverObject *object) case CBID_INDTILE_ACCEPT_CARGO: case CBID_VEHICLE_COLOUR_MAPPING: case CBID_HOUSE_PRODUCE_CARGO: - case CBID_INDTILE_SHAPE_CHECK: // depends on grf version, masked to 8 bit in PerformIndustryTileSlopeCheck() if needed + case CBID_INDTILE_SHAPE_CHECK: case CBID_VEHICLE_SOUND_EFFECT: case CBID_VEHICLE_MODIFY_PROPERTY: // depends on queried property case CBID_CARGO_PROFIT_CALC: diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 0f8f711019..33a53f9e08 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -103,7 +103,7 @@ static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_roa * @param rt roadtype to remove * @param crossing_check should we check if there is a tram track when we are removing road from crossing? */ -static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check) +static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true) { /* cost for removing inner/edge -roads */ static const uint16 road_remove_cost[2] = {50, 18}; @@ -141,7 +141,7 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa /* check if you're allowed to remove the street owned by a town * removal allowance depends on difficulty setting */ - if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; + if (town_check && !CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ @@ -192,7 +192,7 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa c &= present; if (c == ROAD_NONE) return CMD_ERROR; - ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); + if (town_check) ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); if (flags & DC_EXEC) { present ^= c; if (present == ROAD_NONE) { @@ -227,7 +227,7 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa if (rt == ROADTYPE_ROAD && HasTileRoadType(tile, ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR; if (rt == ROADTYPE_ROAD) { - ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); + if (town_check) ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); } if (flags & DC_EXEC) { @@ -756,7 +756,7 @@ CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint3 _additional_cash_required = DoCommand(end_tile, start_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost(); return cost; } - RemoveRoad(tile, flags, bits, rt, true); + RemoveRoad(tile, flags, bits, rt, true, false); } cost.AddCost(ret); } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 2b074c99f1..49c79940ce 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -767,7 +767,7 @@ static bool TerraformTownTile(TileIndex tile, int edges, int dir) TILE_ASSERT(tile); r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); - if (CmdFailed(r) || r.GetCost() >= 126 * 16) return false; + if (CmdFailed(r) || r.GetCost() >= (_price.terraform + 2) * 8) return false; DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND); return true; } @@ -1975,6 +1975,33 @@ static void DoClearTownHouseHelper(TileIndex tile) DeleteAnimatedTile(tile); } +/** + * Determines if a given HouseID is part of a multitile house. + * The given ID is set to the ID of the north tile and the TileDiff to the north tile is returned. + * + * @param house Is changed to the HouseID of the north tile of the same house + * @return TileDiff from the tile of the given HouseID to the north tile + */ +static TileIndex GetHouseNorthPart(HouseID &house) +{ + if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks. + if (GetHouseSpecs(house - 1)->building_flags & TILE_SIZE_2x1) { + house--; + return TileDiffXY(-1, 0); + } else if (GetHouseSpecs(house - 1)->building_flags & BUILDING_2_TILES_Y) { + house--; + return TileDiffXY(0, -1); + } else if (GetHouseSpecs(house - 2)->building_flags & BUILDING_HAS_4_TILES) { + house -= 2; + return TileDiffXY(-1, 0); + } else if (GetHouseSpecs(house - 3)->building_flags & BUILDING_HAS_4_TILES) { + house -= 3; + return TileDiffXY(-1, -1); + } + } + return 0; +} + void ClearTownHouse(Town *t, TileIndex tile) { HouseID house = GetHouseType(tile); @@ -1984,21 +2011,7 @@ void ClearTownHouse(Town *t, TileIndex tile) assert(IsTileType(tile, MP_HOUSE)); /* need to align the tile to point to the upper left corner of the house */ - if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks. - if (GetHouseSpecs(house-1)->building_flags & TILE_SIZE_2x1) { - house--; - tile += TileDiffXY(-1, 0); - } else if (GetHouseSpecs(house-1)->building_flags & BUILDING_2_TILES_Y) { - house--; - tile += TileDiffXY(0, -1); - } else if (GetHouseSpecs(house-2)->building_flags & BUILDING_HAS_4_TILES) { - house-=2; - tile += TileDiffXY(-1, 0); - } else if (GetHouseSpecs(house-3)->building_flags & BUILDING_HAS_4_TILES) { - house-=3; - tile += TileDiffXY(-1, -1); - } - } + tile += GetHouseNorthPart(house); // modifies house to the ID of the north tile hs = GetHouseSpecs(house); @@ -2284,15 +2297,24 @@ static void UpdateTownGrowRate(Town *t) if (DistanceSquare(st->xy, t->xy) <= t->radius[0]) { if (st->time_since_load <= 20 || st->time_since_unload <= 20) { n++; - if (IsValidPlayer(st->owner) && t->ratings[st->owner] <= 1000-12) - t->ratings[st->owner] += 12; + if (IsValidPlayer(st->owner)) { + int new_rating = t->ratings[st->owner] + 12; + t->ratings[st->owner] = min(new_rating, INT16_MAX); // do not let it overflow + } } else { - if (IsValidPlayer(st->owner) && t->ratings[st->owner] >= -1000+15) - t->ratings[st->owner] -= 15; + if (IsValidPlayer(st->owner)) { + int new_rating = t->ratings[st->owner] - 15; + t->ratings[st->owner] = max(new_rating, INT16_MIN); + } } } } + /* clamp all ratings to valid values */ + for (uint i = 0; i < MAX_PLAYERS; i++) { + t->ratings[i] = Clamp(t->ratings[i], -1000, 1000); + } + ClrBit(t->flags12, TOWN_IS_FUNDED); if (_patches.town_growth_rate == 0 && t->fund_buildings_months == 0) return; @@ -2536,7 +2558,8 @@ static CommandCost TerraformTile_Town(TileIndex tile, uint32 flags, uint z_new, { if (AutoslopeEnabled()) { HouseID house = GetHouseType(tile); - HouseSpec *hs = GetHouseSpecs(house); + GetHouseNorthPart(house); // modifies house to the ID of the north tile + const HouseSpec *hs = GetHouseSpecs(house); /* Here we differ from TTDP by checking TILE_NOT_SLOPED */ if (((hs->building_flags & TILE_NOT_SLOPED) == 0) && !IsSteepSlope(tileh_new) &&