50 #include "table/strings.h"
67 if (CleaningPool())
return;
75 FOR_ALL_INDUSTRIES(i) assert(i->
town !=
this);
79 FOR_ALL_OBJECTS(o) assert(o->
town !=
this);
102 this->psa_list.clear();
171 return (_price[PR_CLEAR_HOUSE] * this->
removal_cost) >> 8;
175 static int _grow_town_result;
178 enum TownGrowthResult {
180 GROWTH_SEARCH_STOPPED = 0
185 static Town *CreateRandomTown(uint attempts, uint32 townnameparts,
TownSize size,
bool city,
TownLayout layout);
187 static void TownDrawHouseLift(
const TileInfo *ti)
192 typedef void TownDrawTileProc(
const TileInfo *ti);
193 static TownDrawTileProc *
const _town_draw_tile_procs[1] = {
220 if (HouseSpec::Get(house_id)->grf_prop.spritegroup[0] != NULL) {
221 DrawNewHouseTile(ti, house_id);
224 house_id = HouseSpec::Get(house_id)->
grf_prop.subst_id;
242 ti->
x + dcts->subtile_x,
243 ti->
y + dcts->subtile_y,
255 int proc = dcts->draw_proc - 1;
257 if (proc >= 0) _town_draw_tile_procs[proc](ti);
261 static int GetSlopePixelZ_Town(
TileIndex tile, uint x, uint y)
276 const HouseSpec *hs = HouseSpec::Get(hid);
294 AnimateNewHouseTile(tile);
304 if (!(HouseSpec::Get(
GetHouseType(tile))->building_flags & BUILDING_IS_ANIMATED)) {
325 pos += (pos < dest) ? 1 : -1;
347 const int tx =
TileX(tile);
348 const int ty =
TileY(tile);
350 TileXY(
max(0, tx - (
int) dist),
max(0, ty - (
int) dist)),
355 Town *t = Town::GetByTile(atile);
436 AnimateNewHouseConstruction(tile);
480 const HouseSpec *hs = HouseSpec::Get(house_id);
490 Town *t = Town::GetByTile(tile);
496 for (uint i = 0; i < 256; i++) {
504 uint amt =
GB(callback, 0, 8);
505 if (amt == 0)
continue;
515 uint amt =
GB(r, 0, 8) / 8 + 1;
523 uint amt =
GB(r, 8, 8) / 8 + 1;
535 CanDeleteHouse(tile) &&
540 ClearTownHouse(t, tile);
552 if (!CanDeleteHouse(tile))
return CMD_ERROR;
560 Town *t = Town::GetByTile(tile);
571 ClearTownHouse(t, tile);
580 const HouseSpec *hs = HouseSpec::Get(house_id);
581 Town *t = Town::GetByTile(tile);
584 for (uint i = 0; i < 256; i++) {
596 produced[CT_PASSENGERS]++;
604 static inline void AddAcceptedCargoSetMask(
CargoID cargo, uint amount,
CargoArray &acceptance, uint32 *always_accepted)
606 if (cargo ==
CT_INVALID || amount == 0)
return;
607 acceptance[cargo] += amount;
608 SetBit(*always_accepted, cargo);
611 static void AddAcceptedCargo_Town(
TileIndex tile,
CargoArray &acceptance, uint32 *always_accepted)
617 for (uint8 i = 0; i <
lengthof(accepts); i++) {
636 AddAcceptedCargoSetMask(accepts[0],
GB(callback, 0, 4), acceptance, always_accepted);
637 AddAcceptedCargoSetMask(accepts[1],
GB(callback, 4, 4), acceptance, always_accepted);
640 AddAcceptedCargoSetMask(CT_FOOD,
GB(callback, 8, 4), acceptance, always_accepted);
642 AddAcceptedCargoSetMask(accepts[2],
GB(callback, 8, 4), acceptance, always_accepted);
649 for (uint8 i = 0; i <
lengthof(accepts); i++) {
650 AddAcceptedCargoSetMask(accepts[i], hs->
cargo_acceptance[i], acceptance, always_accepted);
657 const HouseSpec *hs = HouseSpec::Get(house);
662 uint16 callback_res = GetHouseCallback(
CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
664 if (callback_res > 0x400) {
668 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
674 if (!house_completed) {
676 td->
str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
707 if (
TileX(tile) % AcceptanceMatrix::GRID == 0 &&
TileY(tile) % AcceptanceMatrix::GRID == 0) {
731 AddAcceptedCargo_Town(tile, accepted, &dummy);
732 AddProducedCargo_Town(tile, produced);
737 for (uint cid = 0; cid <
NUM_CARGO; cid++) {
738 if (accepted[cid] >= 8)
SetBit(acc, cid);
758 if (
TileX(tile) % AcceptanceMatrix::GRID == 0 &&
TileY(tile) % AcceptanceMatrix::GRID == 0) {
773 FOR_ALL_TOWNS(town) {
780 static void TownTickHandler(
Town *t)
797 if (_game_mode == GM_EDITOR)
return;
844 dist_multi = (dist_multi + 1) * 4;
845 for (uint pos = 4; pos < dist_multi; pos++) {
850 if (pos & 2) cur += tid_lt[2];
892 if (desired_slope != cur_slope &&
ComplementSlope(desired_slope) != cur_slope) {
910 static bool TerraformTownTile(
TileIndex tile,
int edges,
int dir)
915 if (r.
Failed() || r.
GetCost() >= (_price[PR_TERRAFORM] + 2) * 8)
return false;
920 static void LevelTownLand(
TileIndex tile)
931 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, 0);
951 default: NOT_REACHED();
954 if ((grid_pos.
x % 3) == 0) rcmd |=
ROAD_Y;
955 if ((grid_pos.
y % 3) == 0) rcmd |=
ROAD_X;
959 if ((grid_pos.
x % 4) == 0) rcmd |=
ROAD_Y;
960 if ((grid_pos.
y % 4) == 0) rcmd |=
ROAD_X;
970 default: rb_template =
ROAD_ALL;
break;
1028 _grow_town_result = GROWTH_SUCCEED;
1048 _grow_town_result = GROWTH_SUCCEED;
1079 uint8 bridge_length = 0;
1087 if (bridge_length++ >= 4) {
1091 bridge_tile += delta;
1095 if (bridge_length++ >= 11) {
1099 bridge_tile += delta;
1104 if (bridge_length == 1)
return false;
1106 for (uint8 times = 0; times <= 22; times++) {
1112 _grow_town_result = GROWTH_SUCCEED;
1147 _grow_town_result = GROWTH_SEARCH_STOPPED;
1157 default: NOT_REACHED();
1173 do target_dir =
RandomDiagDir();
while (target_dir == source_dir);
1199 _grow_town_result = GROWTH_SEARCH_STOPPED;
1204 default: NOT_REACHED();
1217 bool allow_house =
true;
1243 default: NOT_REACHED();
1271 if (
Chance16(1, 6)) LevelTownLand(house_tile);
1276 _grow_town_result = GROWTH_SUCCEED;
1282 _grow_town_result = GROWTH_SEARCH_STOPPED;
1339 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1381 if (_grow_town_result == GROWTH_SUCCEED)
return true;
1400 }
while (!(cur_rb & target_bits));
1401 cur_rb &= ~target_bits;
1419 }
while (--_grow_town_result >= 0);
1433 uint32 r = Random();
1434 uint a =
GB(r, 0, 2);
1435 uint b =
GB(r, 8, 2);
1470 for (ptr = _town_coord_mod; ptr !=
endof(_town_coord_mod); ++ptr) {
1483 for (ptr = _town_coord_mod; ptr !=
endof(_town_coord_mod); ++ptr) {
1500 void UpdateTownRadius(
Town *t)
1502 static const uint32 _town_squared_town_zone_radius_data[23][5] = {
1515 { 81, 36, 25, 0, 9},
1516 { 81, 36, 25, 16, 9},
1517 { 81, 49, 0, 25, 9},
1518 { 81, 64, 0, 25, 9},
1519 { 81, 64, 0, 36, 9},
1520 { 81, 64, 0, 36, 16},
1521 {100, 81, 0, 49, 16},
1522 {100, 81, 0, 49, 25},
1523 {121, 81, 0, 49, 25},
1524 {121, 81, 0, 49, 25},
1525 {121, 81, 0, 49, 36},
1543 void UpdateTownMaxPass(
Town *t)
1565 UpdateTownRadius(t);
1595 t->townnamegrfid = 0;
1602 t->townnameparts = townnameparts;
1611 int x = (int)size * 16 + 3;
1612 if (size ==
TSZ_RANDOM) x = (Random() & 0xF) + 8;
1617 UpdateTownRadius(t);
1625 UpdateTownRadius(t);
1626 UpdateTownMaxPass(t);
1665 if (t->
name != NULL && strcmp(t->
name, name) == 0)
return false;
1685 TownSize size = Extract<TownSize, 0, 2>(p1);
1686 bool city =
HasBit(p1, 2);
1687 TownLayout layout = Extract<TownLayout, 3, 3>(p1);
1689 bool random =
HasBit(p1, 6);
1690 uint32 townnameparts = p2;
1722 if (ret.
Failed())
return ret;
1725 static const byte price_mult[][
TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
1727 assert_compile(
lengthof(price_mult[0]) == 4);
1730 byte mult = price_mult[city][size];
1737 _additional_cash_required = cost.
GetCost();
1745 t = CreateRandomTown(20, townnameparts, size, city, layout);
1749 _new_town_id = t->
index;
1753 DoCreateTown(t, tile, townnameparts, size, city, layout,
true);
1756 old_generating_world.
Restore();
1758 if (t != NULL && !
StrEmpty(text)) {
1763 if (_game_mode != GM_EDITOR) {
1768 GetString(company_name, STR_COMPANY_NAME,
lastof(company_name));
1770 char *cn =
stredup(company_name);
1796 default:
return tile;
1814 default:
return true;
1896 static Town *CreateRandomTown(uint attempts, uint32 townnameparts,
TownSize size,
bool city,
TownLayout layout)
1919 DoCreateTown(t, tile, townnameparts, size, city, layout,
false);
1927 cur_company.Restore();
1935 }
while (--attempts != 0);
1940 static const byte _num_initial_towns[4] = {5, 11, 23, 46};
1951 uint current_number = 0;
1955 uint32 townnameparts;
1956 TownNames town_names;
1969 if (CreateRandomTown(20, townnameparts,
TSZ_RANDOM, city, layout) != NULL) current_number++;
1974 if (current_number != 0)
return true;
2004 HouseZonesBits smallest = HZB_TOWN_EDGE;
2005 for (HouseZonesBits i = HZB_BEGIN; i < HZB_END; i++) {
2006 if (dist < t->cache.squared_town_zone_radius[i]) smallest = i;
2030 if (HouseSpec::Get(type)->building_flags & BUILDING_IS_ANIMATED)
AddAnimatedTile(tile);
2141 if ((grid_pos.
x % 3) == 0 || (grid_pos.
y % 3) == 0)
return false;
2145 if ((grid_pos.
x % 4) == 0 || (grid_pos.
y % 4) == 0)
return false;
2175 if ((grid_pos.
x != 2 && grid_pos.
x != -1) ||
2176 (grid_pos.
y != 2 && grid_pos.
y != -1))
return false;
2180 if ((grid_pos.
x & 3) < 2 || (grid_pos.
y & 3) < 2)
return false;
2267 uint bitmask = (1 << rad) + (1 << (land + 12));
2275 uint probability_max = 0;
2279 const HouseSpec *hs = HouseSpec::Get(i);
2285 if (hs->
class_id != HOUSE_NO_CLASS) {
2295 probability_max += cur_prob;
2296 probs[num] = cur_prob;
2302 while (probability_max > 0) {
2312 for (i = 0; i < num; i++) {
2313 if (probs[i] > r)
break;
2318 probability_max -= probs[i];
2322 houses[i] = houses[num];
2323 probs[i] = probs[num];
2325 const HouseSpec *hs = HouseSpec::Get(house);
2343 if (t->
flags & oneof)
continue;
2347 if (noslope && slope !=
SLOPE_FLAT)
continue;
2359 byte random_bits = Random();
2372 byte construction_counter = 0;
2373 byte construction_stage = 0;
2376 uint32 r = Random();
2379 if (
Chance16(1, 7)) construction_stage =
GB(r, 0, 2);
2384 construction_counter =
GB(r, 2, 2);
2388 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
2389 UpdateTownRadius(t);
2408 DoClearSquare(tile);
2424 if (HouseSpec::Get(house - 1)->building_flags & TILE_SIZE_2x1) {
2427 }
else if (HouseSpec::Get(house - 1)->building_flags & BUILDING_2_TILES_Y) {
2430 }
else if (HouseSpec::Get(house - 2)->building_flags & BUILDING_HAS_4_TILES) {
2433 }
else if (HouseSpec::Get(house - 3)->building_flags & BUILDING_HAS_4_TILES) {
2450 const HouseSpec *hs = HouseSpec::Get(house);
2473 UpdateTownRadius(t);
2519 FOR_ALL_CARGOSPECS(cs) {
2545 uint16 index =
GB(p1, 0, 16);
2609 uint old_rate = t->
growth_rate & ~TOWN_GROW_RATE_CUSTOM;
2646 UpdateTownRadius(t);
2648 uint n = amount * 10;
2653 for (; p2 > 0; p2--) {
2655 for (uint i = 0; i < 25; i++)
if (
GrowTown(t))
break;
2658 UpdateTownRadius(t);
2660 UpdateTownMaxPass(t);
2683 FOR_ALL_STATIONS(st) {
2684 if (st->
town == t) {
2689 if (ret.
Failed())
return ret;
2701 bool try_clear =
false;
2742 if (ret.
Failed())
return ret;
2747 if (flags &
DC_EXEC)
delete t;
2757 2, 4, 9, 35, 48, 53, 117, 175
2794 GetString(company_name, STR_COMPANY_NAME,
lastof(company_name));
2796 char *cn =
stredup(company_name);
2836 static const int STATUE_NUMBER_INNER_TILES = 25;
2855 if (statue_data->
tile_count <= STATUE_NUMBER_INNER_TILES) {
2885 if (flags & DC_EXEC) {
2901 if (flags & DC_EXEC) {
2920 if (flags & DC_EXEC) {
2931 SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE);
2932 SetDParam(1, STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION);
2944 if (flags & DC_EXEC) {
2951 FOR_ALL_STATIONS(st) {
2977 static TownActionProc *
const _town_action_proc[] = {
2978 TownActionAdvertiseSmall,
2979 TownActionAdvertiseMedium,
2980 TownActionAdvertiseLarge,
2981 TownActionRoadRebuild,
2983 TownActionFundBuildings,
2984 TownActionBuyRights,
3008 for (uint i = 0; i !=
lengthof(_town_action_costs); i++) {
3026 if (avail >= _town_action_costs[i] * _price[PR_TOWN_ACTION] >> 8) {
3033 if (nump != NULL) *nump = num;
3057 CommandCost ret = _town_action_proc[p2](t, flags);
3058 if (ret.
Failed())
return ret;
3060 if (flags & DC_EXEC) {
3067 static void UpdateTownRating(
Town *t)
3071 FOR_ALL_COMPANIES(c) {
3078 FOR_ALL_STATIONS(st) {
3080 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3111 for (
int i = TE_BEGIN; i <
TE_END; i++) {
3112 switch (t->
goal[i]) {
3136 static const uint16 _grow_count_values[2][6] = {
3137 { 120, 120, 120, 100, 80, 60 },
3138 { 320, 420, 300, 220, 160, 100 }
3144 FOR_ALL_STATIONS(st) {
3146 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3155 m = _grow_count_values[0][
min(n, 5)];
3157 m = _grow_count_values[1][
min(n, 5)];
3158 if (n == 0 && !
Chance16(1, 12))
return;
3165 m >>= growth_multiplier;
3175 static void UpdateTownAmounts(
Town *t)
3184 static void UpdateTownUnwanted(
Town *t)
3188 FOR_ALL_COMPANIES(c) {
3223 uint best = threshold;
3224 Town *best_town = NULL;
3254 if (tid == (TownID)INVALID_TOWN) {
3271 return Town::GetByTile(tile);
3288 static int ref_count = 0;
3290 if (ref_count == 0) {
3291 _town_test_ratings.
Clear();
3295 assert(ref_count > 0);
3298 _town_rating_test = !(ref_count == 0);
3308 if (_town_rating_test) {
3310 if (it != _town_test_ratings.
End()) {
3337 if (rating < max) rating =
max;
3342 if (rating > max) rating =
max;
3345 if (_town_rating_test) {
3346 _town_test_ratings[t] = rating;
3391 void TownsMonthlyLoop()
3402 UpdateTownAmounts(t);
3403 UpdateTownRating(t);
3405 UpdateTownUnwanted(t);
3412 void TownsYearlyLoop()
3426 const HouseSpec *hs = HouseSpec::Get(house);
3431 bool allow_terraform =
true;
3435 hs = HouseSpec::Get(house);
3452 GetSlopePixelZ_Town,
3454 AddAcceptedCargo_Town,
3456 GetTileTrackStatus_Town,
3460 ChangeTileOwner_Town,
3461 AddProducedCargo_Town,
3472 memset(&_house_specs, 0,
sizeof(_house_specs));