diff -r 9a27928bcd5e -r ebf0ece7d8f6 src/town_cmd.cpp --- a/src/town_cmd.cpp Thu Nov 22 23:01:41 2007 +0000 +++ b/src/town_cmd.cpp Fri Nov 23 16:59:30 2007 +0000 @@ -43,6 +43,7 @@ #include "misc/autoptr.hpp" #include "autoslope.h" #include "waypoint.h" +#include "transparency.h" /* Initialize the town-pool */ DEFINE_OLD_POOL_GENERIC(Town, Town) @@ -183,10 +184,10 @@ dcts->height, dcts->dz, ti->z, - HASBIT(_transparent_opt, TO_HOUSES) + IsTransparencySet(TO_HOUSES) ); - if (HASBIT(_transparent_opt, TO_HOUSES)) return; + if (IsTransparencySet(TO_HOUSES)) return; } { @@ -355,7 +356,7 @@ if (GetHouseConstructionTick(tile) != 0) return; /* Check and/or */ - if (HASBIT(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_HOUSE_CONSTRUCTION_STATE_CHANGE)) { + if (HasBit(GetHouseSpecs(GetHouseType(tile))->callback_mask, CBM_HOUSE_CONSTRUCTION_STATE_CHANGE)) { uint16 callback_res = GetHouseCallback(CBID_HOUSE_CONSTRUCTION_STATE_CHANGE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(tile, callback_res); } @@ -412,7 +413,7 @@ r = Random(); - if (HASBIT(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) { + if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) { for (uint i = 0; i < 256; i++) { uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile); @@ -466,7 +467,7 @@ _current_player = OWNER_TOWN; if (hs->building_flags & BUILDING_HAS_1_TILE && - HASBIT(t->flags12, TOWN_IS_FUNDED) && + HasBit(t->flags12, TOWN_IS_FUNDED) && CanDeleteHouse(tile) && max(_cur_year - GetHouseConstructionYear(tile), 0) >= hs->minimum_life && --t->time_until_rebuild == 0) { @@ -532,7 +533,7 @@ } /* Check for custom accepted cargo types */ - if (HASBIT(hs->callback_mask, CBM_HOUSE_ACCEPT_CARGO)) { + if (HasBit(hs->callback_mask, CBM_HOUSE_ACCEPT_CARGO)) { uint16 callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback != CALLBACK_FAILED) { /* Replace accepted cargo types with translated values from callback */ @@ -543,12 +544,12 @@ } /* Check for custom cargo acceptance */ - if (HASBIT(hs->callback_mask, CBM_HOUSE_CARGO_ACCEPTANCE)) { + if (HasBit(hs->callback_mask, CBM_HOUSE_CARGO_ACCEPTANCE)) { uint16 callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile); if (callback != CALLBACK_FAILED) { if (accepts[0] != CT_INVALID) ac[accepts[0]] = GB(callback, 0, 4); if (accepts[1] != CT_INVALID) ac[accepts[1]] = GB(callback, 4, 4); - if (_opt.landscape != LT_TEMPERATE && HASBIT(callback, 12)) { + if (_opt.landscape != LT_TEMPERATE && HasBit(callback, 12)) { /* The 'S' bit indicates food instead of goods */ ac[CT_FOOD] = GB(callback, 8, 4); } else { @@ -590,7 +591,7 @@ static void TownTickHandler(Town *t) { - if (HASBIT(t->flags12, TOWN_IS_FUNDED)) { + if (HasBit(t->flags12, TOWN_IS_FUNDED)) { int i = t->grow_counter - 1; if (i < 0) { if (GrowTown(t)) { @@ -728,20 +729,16 @@ /* If the tile is not a slope in the right direction, then * maybe terraform some. */ - desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NE : SLOPE_NW; + desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE; if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) { - uint32 r = Random(); - - if (CHANCE16I(1, 8, r) && !_generating_world) { - CommandCost res; - - if (CHANCE16I(1, 16, r)) { - res = DoCommand(tile, cur_slope, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); - } else { + if (CHANCE16(1, 8)) { + CommandCost res = CMD_ERROR; + if (!_generating_world && CHANCE16(1, 10)) { /* Note: Do not replace " ^ 0xF" with ComplementSlope(). The slope might be steep. */ - res = DoCommand(tile, cur_slope ^ 0xF, 1, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); + res = DoCommand(tile, CHANCE16(1, 16) ? cur_slope : cur_slope ^ 0xF, 0, + DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); } - if (CmdFailed(res) && CHANCE16I(1, 3, r)) { + if (CmdFailed(res) && CHANCE16(1, 3)) { /* We can consider building on the slope, though. */ goto no_slope; } @@ -810,38 +807,33 @@ break; } - /* Stop if the tile is not a part of the grid lines */ - if (rcmd == ROAD_NONE) return rcmd; - /* Optimise only X-junctions */ - if (COUNTBITS(rcmd) != 2) { - RoadBits rb_template; - - switch (GetTileSlope(tile, NULL)) { - default: rb_template = ROAD_ALL; break; - case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break; - case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break; - case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break; - case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break; - case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break; - case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break; - case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break; - case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break; - case SLOPE_STEEP_W: - case SLOPE_STEEP_S: - case SLOPE_STEEP_E: - case SLOPE_STEEP_N: - rb_template = ROAD_NONE; - break; - } - - /* Stop if the template is compatible to the growth dir */ - if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template; - /* If not generate a straight road in the direction of the growth */ - return DiagDirToRoadBits(dir) | DiagDirToRoadBits(ReverseDiagDir(dir)); + if (rcmd != ROAD_ALL) return rcmd; + + RoadBits rb_template; + + switch (GetTileSlope(tile, NULL)) { + default: rb_template = ROAD_ALL; break; + case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break; + case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break; + case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break; + case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break; + case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break; + case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break; + case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break; + case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break; + case SLOPE_STEEP_W: + case SLOPE_STEEP_S: + case SLOPE_STEEP_E: + case SLOPE_STEEP_N: + rb_template = ROAD_NONE; + break; } - return rcmd; + /* Stop if the template is compatible to the growth dir */ + if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template; + /* If not generate a straight road in the direction of the growth */ + return DiagDirToRoadBits(dir) | DiagDirToRoadBits(ReverseDiagDir(dir)); } /** @@ -902,38 +894,44 @@ * * @param t The current town * @param tile The current tile - * @param rcmd The RoadBits which are possible on this tile + * @param bridge_dir The valid direction in which to grow a bridge * @return true if a bridge has been build else false */ -static bool GrowTownWithBridge(const Town *t, TileIndex tile, RoadBits rcmd) +static bool GrowTownWithBridge(const Town *t, TileIndex tile, DiagDirection bridge_dir) { - DiagDirection bridge_dir; // The direction of a bridge we maybe want to build - - /* Determine direction of slope, - * and build a road if not a special slope. */ - switch (GetTileSlope(tile, NULL)) { - case SLOPE_SW: bridge_dir = DIAGDIR_NE; break; - case SLOPE_SE: bridge_dir = DIAGDIR_NW; break; - case SLOPE_NW: bridge_dir = DIAGDIR_SE; break; - case SLOPE_NE: bridge_dir = DIAGDIR_SW; break; - - default: return false; - } - - /* Check if the bridge will be compatible to the RoadBits */ - if (!(rcmd & DiagDirToRoadBits(ReverseDiagDir(bridge_dir)))) return false; + assert(bridge_dir < DIAGDIR_END); + + const Slope slope = GetTileSlope(tile, NULL); + if (slope == SLOPE_FLAT) return false; // no slope, no bridge + + /* Make sure the direction is compatible with the slope. + * If any of the following bits match, the slope is forbidden for + * that diagdir. This means 5 non-steep slopes, and 3 steep-slopes + * per diagdir. + * 0 -> 0b1100 + * 1 -> 0b0110 + * 2 -> 0b0011 + * 3 -> 0b1001 + * 0xCC is 0b11001100, so we just shift it right with + * the direction to get the forbidden slope mask. */ + if (HASBITS(slope & 0x0F, 0xCC >> bridge_dir)) return false; + + /* Assure that the bridge is connectable to the start side */ + if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false; /* We are in the right direction */ - uint32 bridge_length = 0; // This value stores the length of the possible bridge + uint8 bridge_length = 0; // This value stores the length of the possible bridge TileIndex bridge_tile = tile; // Used to store the other waterside + int delta = TileOffsByDiagDir(bridge_dir); + do { if (bridge_length++ >= 11) { /* Max 11 tile long bridges */ return false; } - bridge_tile = TILE_MASK(bridge_tile + TileOffsByDiagDir(bridge_dir)); - } while (IsWaterTile(bridge_tile)); + bridge_tile += delta; + } while (TileX(bridge_tile) != 0 && TileY(bridge_tile) != 0 && IsWaterTile(bridge_tile) && TileX(bridge_tile) != 0); /* no water tiles in between? */ if (bridge_length == 1) return false; @@ -1106,7 +1104,7 @@ /* Build a house, but not if there already is a house there. */ if (!IsTileType(house_tile, MP_HOUSE)) { /* Level the land if possible */ - LevelTownLand(house_tile); + if (CHANCE16(1, 6)) LevelTownLand(house_tile); /* And build a house. * Set result to -1 if we managed to build it. */ @@ -1127,7 +1125,10 @@ rcmd = CleanUpRoadBits(tile, rcmd); if (rcmd == ROAD_NONE) return; - if (GrowTownWithBridge(t1, tile, rcmd)) return; + /* Only use the target direction for bridges to ensure they're connected. + * The target_dir is as computed previously according to town layout, so + * it will match it perfectly. */ + if (GrowTownWithBridge(t1, tile, target_dir)) return; GrowTownWithRoad(t1, tile, rcmd); } @@ -1714,7 +1715,7 @@ if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue; - if (HASBIT(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { + if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile); if (callback_res != CALLBACK_FAILED && callback_res == 0) continue; } @@ -1724,9 +1725,9 @@ /* Special houses that there can be only one of. */ if (hs->building_flags & BUILDING_IS_CHURCH) { - SETBIT(oneof, TOWN_HAS_CHURCH); + SetBit(oneof, TOWN_HAS_CHURCH); } else if (hs->building_flags & BUILDING_IS_STADIUM) { - SETBIT(oneof, TOWN_HAS_STADIUM); + SetBit(oneof, TOWN_HAS_STADIUM); } else { oneof = 0; } @@ -1848,9 +1849,9 @@ /* Clear flags for houses that only may exist once/town. */ if (hs->building_flags & BUILDING_IS_CHURCH) { - CLRBIT(t->flags12, TOWN_HAS_CHURCH); + ClrBit(t->flags12, TOWN_HAS_CHURCH); } else if (hs->building_flags & BUILDING_IS_STADIUM) { - CLRBIT(t->flags12, TOWN_HAS_STADIUM); + ClrBit(t->flags12, TOWN_HAS_STADIUM); } /* Do the actual clearing of tiles */ @@ -2011,7 +2012,7 @@ TileIndex tile = t->xy; if (CircularTileSearch(tile, 9, SearchTileForStatue, t->index)) - SETBIT(t->statues, _current_player); // Once found and built, "inform" the Town + SetBit(t->statues, _current_player); // Once found and built, "inform" the Town } static void TownActionFundBuildings(Town* t) @@ -2019,7 +2020,7 @@ /* Build next tick */ t->grow_counter = 1; /* If we were not already growing */ - SETBIT(t->flags12, TOWN_IS_FUNDED); + SetBit(t->flags12, TOWN_IS_FUNDED); /* And grow for 3 months */ t->fund_buildings_months = 3; } @@ -2097,7 +2098,7 @@ t = GetTown(p1); - if (!HASBIT(GetMaskOfTownActions(NULL, _current_player, t), p2)) return CMD_ERROR; + if (!HasBit(GetMaskOfTownActions(NULL, _current_player, t), p2)) return CMD_ERROR; SET_EXPENSES_TYPE(EXPENSES_OTHER); @@ -2139,7 +2140,7 @@ } } - CLRBIT(t->flags12, TOWN_IS_FUNDED); + ClrBit(t->flags12, TOWN_IS_FUNDED); if (_patches.town_growth_rate == 0 && t->fund_buildings_months == 0) return; /** Towns are processed every TOWN_GROWTH_FREQUENCY ticks, and this is the @@ -2176,7 +2177,7 @@ if (m <= t->grow_counter) t->grow_counter = m; - SETBIT(t->flags12, TOWN_IS_FUNDED); + SetBit(t->flags12, TOWN_IS_FUNDED); } static void UpdateTownAmounts(Town *t) @@ -2266,7 +2267,7 @@ return; } - SETBIT(t->have_ratings, _current_player); + SetBit(t->have_ratings, _current_player); rating = t->ratings[_current_player];