Merge branch 'master' into town_cargo_adj
Conflicts: src/settings_gui.cpp
This commit is contained in:
185
src/town_cmd.cpp
185
src/town_cmd.cpp
@@ -50,6 +50,8 @@
|
||||
#include "table/strings.h"
|
||||
#include "table/town_land.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
TownID _new_town_id;
|
||||
uint32 _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses.
|
||||
|
||||
@@ -169,7 +171,7 @@ Money HouseSpec::GetRemovalCost() const
|
||||
return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
|
||||
}
|
||||
|
||||
// Local
|
||||
/* Local */
|
||||
static int _grow_town_result;
|
||||
|
||||
/* Describe the possible states */
|
||||
@@ -339,6 +341,24 @@ static void AnimateTile_Town(TileIndex tile)
|
||||
*/
|
||||
static bool IsCloseToTown(TileIndex tile, uint dist)
|
||||
{
|
||||
/* On a large map with many towns, it may be faster to check the surroundings of the tile.
|
||||
* An iteration in TILE_AREA_LOOP() is generally 2 times faster than one in FOR_ALL_TOWNS(). */
|
||||
if (Town::GetNumItems() > (size_t) (dist * dist * 2)) {
|
||||
const int tx = TileX(tile);
|
||||
const int ty = TileY(tile);
|
||||
TileArea tile_area = TileArea(
|
||||
TileXY(max(0, tx - (int) dist), max(0, ty - (int) dist)),
|
||||
TileXY(min(MapMaxX(), tx + (int) dist), min(MapMaxY(), ty + (int) dist))
|
||||
);
|
||||
TILE_AREA_LOOP(atile, tile_area) {
|
||||
if (GetTileType(atile) == MP_HOUSE) {
|
||||
Town *t = Town::GetByTile(atile);
|
||||
if (DistanceManhattan(tile, t->xy) < dist) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const Town *t;
|
||||
|
||||
FOR_ALL_TOWNS(t) {
|
||||
@@ -357,7 +377,8 @@ void Town::UpdateVirtCoord()
|
||||
SetDParam(0, this->index);
|
||||
SetDParam(1, this->cache.population);
|
||||
this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_LVL_BASE,
|
||||
_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN);
|
||||
_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN,
|
||||
STR_VIEWPORT_TOWN);
|
||||
|
||||
SetWindowDirty(WC_TOWN_VIEW, this->index);
|
||||
}
|
||||
@@ -558,7 +579,7 @@ static void TileLoop_Town(TileIndex tile)
|
||||
Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
|
||||
|
||||
if ((hs->building_flags & BUILDING_HAS_1_TILE) &&
|
||||
HasBit(t->flags, TOWN_IS_FUNDED) &&
|
||||
HasBit(t->flags, TOWN_IS_GROWING) &&
|
||||
CanDeleteHouse(tile) &&
|
||||
GetHouseAge(tile) >= hs->minimum_life &&
|
||||
--t->time_until_rebuild == 0) {
|
||||
@@ -806,7 +827,7 @@ static bool GrowTown(Town *t);
|
||||
|
||||
static void TownTickHandler(Town *t)
|
||||
{
|
||||
if (HasBit(t->flags, TOWN_IS_FUNDED)) {
|
||||
if (HasBit(t->flags, TOWN_IS_GROWING)) {
|
||||
int i = t->grow_counter - 1;
|
||||
if (i < 0) {
|
||||
if (GrowTown(t)) {
|
||||
@@ -896,7 +917,7 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
|
||||
if (DistanceFromEdge(tile) == 0) return false;
|
||||
|
||||
/* Prevent towns from building roads under bridges along the bridge. Looks silly. */
|
||||
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
|
||||
if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
|
||||
|
||||
/* Check if there already is a road at this point? */
|
||||
if (GetTownRoadBits(tile) == ROAD_NONE) {
|
||||
@@ -1324,13 +1345,56 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
GrowTownWithRoad(t1, tile, rcmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a road can be followed or is a dead end, that can not be extended to the next tile.
|
||||
* This only checks trivial but often cases.
|
||||
* @param tile Start tile for road.
|
||||
* @param dir Direction for road to follow or build.
|
||||
* @return true If road is or can be connected in the specified direction.
|
||||
*/
|
||||
static bool CanFollowRoad(TileIndex tile, DiagDirection dir)
|
||||
{
|
||||
TileIndex target_tile = tile + TileOffsByDiagDir(dir);
|
||||
if (!IsValidTile(target_tile)) return false;
|
||||
if (HasTileWaterGround(target_tile)) return false;
|
||||
|
||||
RoadBits target_rb = GetTownRoadBits(target_tile);
|
||||
if (_settings_game.economy.allow_town_roads || _generating_world) {
|
||||
/* Check whether a road connection exists or can be build. */
|
||||
switch (GetTileType(target_tile)) {
|
||||
case MP_ROAD:
|
||||
return target_rb != ROAD_NONE;
|
||||
|
||||
case MP_STATION:
|
||||
return IsDriveThroughStopTile(target_tile);
|
||||
|
||||
case MP_TUNNELBRIDGE:
|
||||
return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
|
||||
|
||||
case MP_HOUSE:
|
||||
case MP_INDUSTRY:
|
||||
case MP_OBJECT:
|
||||
return false;
|
||||
|
||||
default:
|
||||
/* Checked for void and water earlier */
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
/* Check whether a road connection already exists,
|
||||
* and it leads somewhere else. */
|
||||
RoadBits back_rb = DiagDirToRoadBits(ReverseDiagDir(dir));
|
||||
return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "growth" if a house was built, or no if the build failed.
|
||||
* @param t town to inquiry
|
||||
* @param tile to inquiry
|
||||
* @return something other than zero(0)if town expansion was possible
|
||||
* @return true if town expansion was possible
|
||||
*/
|
||||
static int GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
{
|
||||
/* Special case.
|
||||
* @see GrowTownInTile Check the else if
|
||||
@@ -1365,9 +1429,9 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
|
||||
/* Exclude the source position from the bitmask
|
||||
* and return if no more road blocks available */
|
||||
cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
|
||||
if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
|
||||
if (cur_rb == ROAD_NONE) {
|
||||
return _grow_town_result;
|
||||
return _grow_town_result == GROWTH_SUCCEED;
|
||||
}
|
||||
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
||||
@@ -1376,14 +1440,22 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
} else {
|
||||
/* Select a random bit from the blockmask, walk a step
|
||||
* and continue the search from there. */
|
||||
do target_dir = RandomDiagDir(); while (!(cur_rb & DiagDirToRoadBits(target_dir)));
|
||||
do {
|
||||
if (cur_rb == ROAD_NONE) return false;
|
||||
RoadBits target_bits;
|
||||
do {
|
||||
target_dir = RandomDiagDir();
|
||||
target_bits = DiagDirToRoadBits(target_dir);
|
||||
} while (!(cur_rb & target_bits));
|
||||
cur_rb &= ~target_bits;
|
||||
} while (!CanFollowRoad(tile, target_dir));
|
||||
}
|
||||
tile = TileAddByDiagDir(tile, target_dir);
|
||||
|
||||
if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, ROADTYPE_ROAD)) {
|
||||
/* Don't allow building over roads of other cities */
|
||||
if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
|
||||
_grow_town_result = GROWTH_SUCCEED;
|
||||
return false;
|
||||
} else if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
|
||||
/* If we are in the SE, and this road-piece has no town owner yet, it just found an
|
||||
* owner :) (happy happy happy road now) */
|
||||
@@ -1395,7 +1467,7 @@ static int GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
/* Max number of times is checked. */
|
||||
} while (--_grow_town_result >= 0);
|
||||
|
||||
return (_grow_town_result == -2);
|
||||
return _grow_town_result == GROWTH_SUCCEED - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1417,7 +1489,7 @@ static RoadBits GenRandomRoadBits()
|
||||
/**
|
||||
* Grow the town
|
||||
* @param t town to grow
|
||||
* @return true iff a house was built
|
||||
* @return true iff something (house, road, bridge, ...) was built
|
||||
*/
|
||||
static bool GrowTown(Town *t)
|
||||
{
|
||||
@@ -1446,9 +1518,9 @@ static bool GrowTown(Town *t)
|
||||
const TileIndexDiffC *ptr;
|
||||
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
|
||||
if (GetTownRoadBits(tile) != ROAD_NONE) {
|
||||
int r = GrowTownAtRoad(t, tile);
|
||||
bool success = GrowTownAtRoad(t, tile);
|
||||
cur_company.Restore();
|
||||
return r != 0;
|
||||
return success;
|
||||
}
|
||||
tile = TILE_ADD(tile, ToTileIndexDiff(*ptr));
|
||||
}
|
||||
@@ -1459,7 +1531,7 @@ static bool GrowTown(Town *t)
|
||||
tile = t->xy;
|
||||
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
|
||||
/* Only work with plain land that not already has a house */
|
||||
if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile) == SLOPE_FLAT) {
|
||||
if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
|
||||
if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) {
|
||||
DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD);
|
||||
cur_company.Restore();
|
||||
@@ -1622,7 +1694,7 @@ static CommandCost TownCanBePlacedHere(TileIndex tile)
|
||||
}
|
||||
|
||||
/* Can only build on clear flat areas, possibly with trees. */
|
||||
if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || GetTileSlope(tile) != SLOPE_FLAT) {
|
||||
if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
|
||||
return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
|
||||
}
|
||||
|
||||
@@ -1669,14 +1741,17 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
if (size >= TSZ_END) return CMD_ERROR;
|
||||
if (layout >= NUM_TLS) return CMD_ERROR;
|
||||
|
||||
/* Some things are allowed only in the scenario editor */
|
||||
if (_game_mode != GM_EDITOR) {
|
||||
/* Some things are allowed only in the scenario editor and for game scripts. */
|
||||
if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
|
||||
if (_settings_game.economy.found_town == TF_FORBIDDEN) return CMD_ERROR;
|
||||
if (size == TSZ_LARGE) return CMD_ERROR;
|
||||
if (random) return CMD_ERROR;
|
||||
if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
} else if (_current_company == OWNER_DEITY && random) {
|
||||
/* Random parameter is not allowed for Game Scripts. */
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (StrEmpty(text)) {
|
||||
@@ -1712,7 +1787,7 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
return CommandCost(EXPENSES_OTHER);
|
||||
}
|
||||
|
||||
_generating_world = true;
|
||||
Backup<bool> old_generating_world(_generating_world, true, FILE_LINE);
|
||||
UpdateNearestTownForRoadTiles(true);
|
||||
Town *t;
|
||||
if (random) {
|
||||
@@ -1727,10 +1802,10 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
DoCreateTown(t, tile, townnameparts, size, city, layout, true);
|
||||
}
|
||||
UpdateNearestTownForRoadTiles(false);
|
||||
_generating_world = false;
|
||||
old_generating_world.Restore();
|
||||
|
||||
if (t != NULL && !StrEmpty(text)) {
|
||||
t->name = strdup(text);
|
||||
t->name = stredup(text);
|
||||
t->UpdateVirtCoord();
|
||||
}
|
||||
|
||||
@@ -1741,7 +1816,7 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
SetDParam(0, _current_company);
|
||||
GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
|
||||
|
||||
char *cn = strdup(company_name);
|
||||
char *cn = stredup(company_name);
|
||||
SetDParamStr(0, cn);
|
||||
SetDParam(1, t->index);
|
||||
|
||||
@@ -1820,7 +1895,7 @@ static bool FindFurthestFromWater(TileIndex tile, void *user_data)
|
||||
uint dist = GetClosestWaterDistance(tile, true);
|
||||
|
||||
if (IsTileType(tile, MP_CLEAR) &&
|
||||
GetTileSlope(tile) == SLOPE_FLAT &&
|
||||
IsTileFlat(tile) &&
|
||||
IsTileAlignedToGrid(tile, sp->layout) &&
|
||||
dist > sp->max_dist) {
|
||||
sp->tile = tile;
|
||||
@@ -1925,7 +2000,9 @@ bool GenerateTowns(TownLayout layout)
|
||||
uint current_number = 0;
|
||||
uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.number_towns : 0;
|
||||
uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : ScaleByMapSize(_num_initial_towns[difficulty] + (Random() & 7));
|
||||
total = min(TownPool::MAX_SIZE, total);
|
||||
uint32 townnameparts;
|
||||
TownNames town_names;
|
||||
|
||||
SetGeneratingWorldProgress(GWP_TOWN, total);
|
||||
|
||||
@@ -1936,11 +2013,13 @@ bool GenerateTowns(TownLayout layout)
|
||||
bool city = (_settings_game.economy.larger_towns != 0 && Chance16(1, _settings_game.economy.larger_towns));
|
||||
IncreaseGeneratingWorldProgress(GWP_TOWN);
|
||||
/* Get a unique name for the town. */
|
||||
if (!GenerateTownName(&townnameparts)) continue;
|
||||
if (!GenerateTownName(&townnameparts, &town_names)) continue;
|
||||
/* try 20 times to create a random-sized town for the first loop. */
|
||||
if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != NULL) current_number++; // If creation was successful, raise a flag.
|
||||
} while (--total);
|
||||
|
||||
town_names.clear();
|
||||
|
||||
if (current_number != 0) return true;
|
||||
|
||||
/* If current_number is still zero at this point, it means that not a single town has been created.
|
||||
@@ -2039,7 +2118,7 @@ static inline bool CanBuildHouseHere(TileIndex tile, TownID town, bool noslope)
|
||||
if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
|
||||
|
||||
/* building under a bridge? */
|
||||
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
|
||||
if (IsBridgeAbove(tile)) return false;
|
||||
|
||||
/* do not try to build over house owned by another town */
|
||||
if (IsTileType(tile, MP_HOUSE) && GetTownIndex(tile) != town) return false;
|
||||
@@ -2239,13 +2318,13 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||
/* bits 0-4 are used
|
||||
* bits 11-15 are used
|
||||
* bits 5-10 are not used. */
|
||||
HouseID houses[HOUSE_MAX];
|
||||
HouseID houses[NUM_HOUSES];
|
||||
uint num = 0;
|
||||
uint probs[HOUSE_MAX];
|
||||
uint probs[NUM_HOUSES];
|
||||
uint probability_max = 0;
|
||||
|
||||
/* Generate a list of all possible houses that can be built. */
|
||||
for (uint i = 0; i < HOUSE_MAX; i++) {
|
||||
for (uint i = 0; i < NUM_HOUSES; i++) {
|
||||
const HouseSpec *hs = HouseSpec::Get(i);
|
||||
|
||||
/* Verify that the candidate house spec matches the current tile status */
|
||||
@@ -2469,7 +2548,7 @@ CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
free(t->name);
|
||||
t->name = reset ? NULL : strdup(text);
|
||||
t->name = reset ? NULL : stredup(text);
|
||||
|
||||
t->UpdateVirtCoord();
|
||||
InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1);
|
||||
@@ -2510,7 +2589,7 @@ CommandCost CmdTownCargoGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||
|
||||
TownEffect te = (TownEffect)GB(p1, 16, 8);
|
||||
if (te < TE_BEGIN || te > TE_END) return CMD_ERROR;
|
||||
if (te < TE_BEGIN || te >= TE_END) return CMD_ERROR;
|
||||
|
||||
uint16 index = GB(p1, 0, 16);
|
||||
Town *t = Town::GetIfValid(index);
|
||||
@@ -2546,7 +2625,7 @@ CommandCost CmdTownSetText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
free(t->text);
|
||||
t->text = StrEmpty(text) ? NULL : strdup(text);
|
||||
t->text = StrEmpty(text) ? NULL : stredup(text);
|
||||
InvalidateWindowData(WC_TOWN_VIEW, p1);
|
||||
}
|
||||
|
||||
@@ -2558,21 +2637,34 @@ CommandCost CmdTownSetText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
* @param tile Unused.
|
||||
* @param flags Type of operation.
|
||||
* @param p1 Town ID to cargo game of.
|
||||
* @param p2 Amount of days between growth.
|
||||
* @param p2 Amount of days between growth, or TOWN_GROW_RATE_CUSTOM_NONE, or 0 to reset custom growth rate.
|
||||
* @param text Unused.
|
||||
* @return Empty cost or an error.
|
||||
*/
|
||||
CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||
if ((p2 & TOWN_GROW_RATE_CUSTOM) != 0) return CMD_ERROR;
|
||||
if ((p2 & TOWN_GROW_RATE_CUSTOM) != 0 && p2 != TOWN_GROW_RATE_CUSTOM_NONE) return CMD_ERROR;
|
||||
if (GB(p2, 16, 16) != 0) return CMD_ERROR;
|
||||
|
||||
Town *t = Town::GetIfValid(p1);
|
||||
if (t == NULL) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
t->growth_rate = (p2 == 0) ? 0 : p2 | TOWN_GROW_RATE_CUSTOM;
|
||||
if (p2 == 0) {
|
||||
/* Clear TOWN_GROW_RATE_CUSTOM, UpdateTownGrowRate will determine a proper value */
|
||||
t->growth_rate = 0;
|
||||
} else {
|
||||
uint old_rate = t->growth_rate & ~TOWN_GROW_RATE_CUSTOM;
|
||||
if (t->grow_counter >= old_rate) {
|
||||
/* This also catches old_rate == 0 */
|
||||
t->grow_counter = p2;
|
||||
} else {
|
||||
/* Scale grow_counter, so half finished houses stay half finished */
|
||||
t->grow_counter = t->grow_counter * p2 / old_rate;
|
||||
}
|
||||
t->growth_rate = p2 | TOWN_GROW_RATE_CUSTOM;
|
||||
}
|
||||
UpdateTownGrowRate(t);
|
||||
InvalidateWindowData(WC_TOWN_VIEW, p1);
|
||||
}
|
||||
@@ -2680,7 +2772,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
} else {
|
||||
Object *o = Object::GetByTile(tile);
|
||||
if (o->town == t) {
|
||||
if (GetObjectType(tile) == OBJECT_STATUE) {
|
||||
if (o->type == OBJECT_STATUE) {
|
||||
/* Statue... always remove. */
|
||||
try_clear = true;
|
||||
} else {
|
||||
@@ -2750,7 +2842,7 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags)
|
||||
SetDParam(0, _current_company);
|
||||
GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
|
||||
|
||||
char *cn = strdup(company_name);
|
||||
char *cn = stredup(company_name);
|
||||
SetDParam(0, t->index);
|
||||
SetDParamStr(1, cn);
|
||||
|
||||
@@ -2798,7 +2890,7 @@ static bool SearchTileForStatue(TileIndex tile, void *user_data)
|
||||
/* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
|
||||
if (IsSteepSlope(GetTileSlope(tile))) return false;
|
||||
/* Don't build statues under bridges. */
|
||||
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
|
||||
if (IsBridgeAbove(tile)) return false;
|
||||
|
||||
/* A clear-able open space is always preferred. */
|
||||
if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && TryClearTile(tile)) {
|
||||
@@ -2858,11 +2950,12 @@ static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags)
|
||||
if (flags & DC_EXEC) {
|
||||
/* Build next tick */
|
||||
t->grow_counter = 1;
|
||||
/* If we were not already growing */
|
||||
SetBit(t->flags, TOWN_IS_FUNDED);
|
||||
/* And grow for 3 months */
|
||||
t->fund_buildings_months = 3;
|
||||
|
||||
/* Enable growth (also checking GameScript's opinion) */
|
||||
UpdateTownGrowRate(t);
|
||||
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
}
|
||||
return CommandCost();
|
||||
@@ -3057,7 +3150,7 @@ static void UpdateTownRating(Town *t)
|
||||
|
||||
static void UpdateTownGrowRate(Town *t)
|
||||
{
|
||||
ClrBit(t->flags, TOWN_IS_FUNDED);
|
||||
ClrBit(t->flags, TOWN_IS_GROWING);
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
|
||||
if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
|
||||
@@ -3080,7 +3173,7 @@ static void UpdateTownGrowRate(Town *t)
|
||||
}
|
||||
|
||||
if ((t->growth_rate & TOWN_GROW_RATE_CUSTOM) != 0) {
|
||||
SetBit(t->flags, TOWN_IS_FUNDED);
|
||||
if (t->growth_rate != TOWN_GROW_RATE_CUSTOM_NONE) SetBit(t->flags, TOWN_IS_GROWING);
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
return;
|
||||
}
|
||||
@@ -3122,11 +3215,9 @@ static void UpdateTownGrowRate(Town *t)
|
||||
if (t->larger_town) m /= 2;
|
||||
|
||||
t->growth_rate = m / (t->cache.num_houses / 50 + 1);
|
||||
if (m <= t->grow_counter) {
|
||||
t->grow_counter = m;
|
||||
}
|
||||
t->grow_counter = min(t->growth_rate, t->grow_counter);
|
||||
|
||||
SetBit(t->flags, TOWN_IS_FUNDED);
|
||||
SetBit(t->flags, TOWN_IS_GROWING);
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
}
|
||||
|
||||
@@ -3423,7 +3514,7 @@ extern const TileTypeProcs _tile_type_town_procs = {
|
||||
};
|
||||
|
||||
|
||||
HouseSpec _house_specs[HOUSE_MAX];
|
||||
HouseSpec _house_specs[NUM_HOUSES];
|
||||
|
||||
void ResetHouses()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user