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);
435 AnimateNewHouseConstruction(tile);
479 const HouseSpec *hs = HouseSpec::Get(house_id);
489 Town *t = Town::GetByTile(tile);
495 for (uint i = 0; i < 256; i++) {
503 uint amt =
GB(callback, 0, 8);
504 if (amt == 0)
continue;
514 uint amt =
GB(r, 0, 8) / 8 + 1;
522 uint amt =
GB(r, 8, 8) / 8 + 1;
534 CanDeleteHouse(tile) &&
539 ClearTownHouse(t, tile);
551 if (!CanDeleteHouse(tile))
return CMD_ERROR;
559 Town *t = Town::GetByTile(tile);
570 ClearTownHouse(t, tile);
579 const HouseSpec *hs = HouseSpec::Get(house_id);
580 Town *t = Town::GetByTile(tile);
583 for (uint i = 0; i < 256; i++) {
595 produced[CT_PASSENGERS]++;
603 static inline void AddAcceptedCargoSetMask(
CargoID cargo, uint amount,
CargoArray &acceptance, uint32 *always_accepted)
605 if (cargo ==
CT_INVALID || amount == 0)
return;
606 acceptance[cargo] += amount;
607 SetBit(*always_accepted, cargo);
610 static void AddAcceptedCargo_Town(
TileIndex tile,
CargoArray &acceptance, uint32 *always_accepted)
616 for (uint8 i = 0; i <
lengthof(accepts); i++) {
635 AddAcceptedCargoSetMask(accepts[0],
GB(callback, 0, 4), acceptance, always_accepted);
636 AddAcceptedCargoSetMask(accepts[1],
GB(callback, 4, 4), acceptance, always_accepted);
639 AddAcceptedCargoSetMask(CT_FOOD,
GB(callback, 8, 4), acceptance, always_accepted);
641 AddAcceptedCargoSetMask(accepts[2],
GB(callback, 8, 4), acceptance, always_accepted);
648 for (uint8 i = 0; i <
lengthof(accepts); i++) {
649 AddAcceptedCargoSetMask(accepts[i], hs->
cargo_acceptance[i], acceptance, always_accepted);
656 const HouseSpec *hs = HouseSpec::Get(house);
661 uint16 callback_res = GetHouseCallback(
CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
663 if (callback_res > 0x400) {
667 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
673 if (!house_completed) {
675 td->
str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
706 if (
TileX(tile) % AcceptanceMatrix::GRID == 0 &&
TileY(tile) % AcceptanceMatrix::GRID == 0) {
730 AddAcceptedCargo_Town(tile, accepted, &dummy);
731 AddProducedCargo_Town(tile, produced);
736 for (uint cid = 0; cid <
NUM_CARGO; cid++) {
737 if (accepted[cid] >= 8)
SetBit(acc, cid);
757 if (
TileX(tile) % AcceptanceMatrix::GRID == 0 &&
TileY(tile) % AcceptanceMatrix::GRID == 0) {
772 FOR_ALL_TOWNS(town) {
779 static void TownTickHandler(
Town *t)
796 if (_game_mode == GM_EDITOR)
return;
843 dist_multi = (dist_multi + 1) * 4;
844 for (uint pos = 4; pos < dist_multi; pos++) {
849 if (pos & 2) cur += tid_lt[2];
891 if (desired_slope != cur_slope &&
ComplementSlope(desired_slope) != cur_slope) {
909 static bool TerraformTownTile(
TileIndex tile,
int edges,
int dir)
914 if (r.
Failed() || r.
GetCost() >= (_price[PR_TERRAFORM] + 2) * 8)
return false;
919 static void LevelTownLand(
TileIndex tile)
930 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, 0);
950 default: NOT_REACHED();
953 if ((grid_pos.
x % 3) == 0) rcmd |=
ROAD_Y;
954 if ((grid_pos.
y % 3) == 0) rcmd |=
ROAD_X;
958 if ((grid_pos.
x % 4) == 0) rcmd |=
ROAD_Y;
959 if ((grid_pos.
y % 4) == 0) rcmd |=
ROAD_X;
969 default: rb_template =
ROAD_ALL;
break;
1027 _grow_town_result = GROWTH_SUCCEED;
1047 _grow_town_result = GROWTH_SUCCEED;
1078 uint8 bridge_length = 0;
1086 if (bridge_length++ >= 4) {
1090 bridge_tile += delta;
1094 if (bridge_length++ >= 11) {
1098 bridge_tile += delta;
1103 if (bridge_length == 1)
return false;
1105 for (uint8 times = 0; times <= 22; times++) {
1111 _grow_town_result = GROWTH_SUCCEED;
1146 _grow_town_result = GROWTH_SEARCH_STOPPED;
1156 default: NOT_REACHED();
1172 do target_dir =
RandomDiagDir();
while (target_dir == source_dir);
1198 _grow_town_result = GROWTH_SEARCH_STOPPED;
1203 default: NOT_REACHED();
1216 bool allow_house =
true;
1242 default: NOT_REACHED();
1270 if (
Chance16(1, 6)) LevelTownLand(house_tile);
1275 _grow_town_result = GROWTH_SUCCEED;
1281 _grow_town_result = GROWTH_SEARCH_STOPPED;
1342 return _grow_town_result;
1358 _grow_town_result = GROWTH_SUCCEED;
1368 }
while (--_grow_town_result >= 0);
1370 return (_grow_town_result == -2);
1382 uint32 r = Random();
1383 uint a =
GB(r, 0, 2);
1384 uint b =
GB(r, 8, 2);
1419 for (ptr = _town_coord_mod; ptr !=
endof(_town_coord_mod); ++ptr) {
1432 for (ptr = _town_coord_mod; ptr !=
endof(_town_coord_mod); ++ptr) {
1449 void UpdateTownRadius(
Town *t)
1451 static const uint32 _town_squared_town_zone_radius_data[23][5] = {
1464 { 81, 36, 25, 0, 9},
1465 { 81, 36, 25, 16, 9},
1466 { 81, 49, 0, 25, 9},
1467 { 81, 64, 0, 25, 9},
1468 { 81, 64, 0, 36, 9},
1469 { 81, 64, 0, 36, 16},
1470 {100, 81, 0, 49, 16},
1471 {100, 81, 0, 49, 25},
1472 {121, 81, 0, 49, 25},
1473 {121, 81, 0, 49, 25},
1474 {121, 81, 0, 49, 36},
1492 void UpdateTownMaxPass(
Town *t)
1514 UpdateTownRadius(t);
1544 t->townnamegrfid = 0;
1551 t->townnameparts = townnameparts;
1560 int x = (int)size * 16 + 3;
1561 if (size ==
TSZ_RANDOM) x = (Random() & 0xF) + 8;
1566 UpdateTownRadius(t);
1574 UpdateTownRadius(t);
1575 UpdateTownMaxPass(t);
1614 if (t->
name != NULL && strcmp(t->
name, name) == 0)
return false;
1634 TownSize size = Extract<TownSize, 0, 2>(p1);
1635 bool city =
HasBit(p1, 2);
1636 TownLayout layout = Extract<TownLayout, 3, 3>(p1);
1638 bool random =
HasBit(p1, 6);
1639 uint32 townnameparts = p2;
1671 if (ret.
Failed())
return ret;
1674 static const byte price_mult[][
TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
1676 assert_compile(
lengthof(price_mult[0]) == 4);
1679 byte mult = price_mult[city][size];
1686 _additional_cash_required = cost.
GetCost();
1694 t = CreateRandomTown(20, townnameparts, size, city, layout);
1698 _new_town_id = t->
index;
1702 DoCreateTown(t, tile, townnameparts, size, city, layout,
true);
1705 old_generating_world.
Restore();
1707 if (t != NULL && !
StrEmpty(text)) {
1712 if (_game_mode != GM_EDITOR) {
1717 GetString(company_name, STR_COMPANY_NAME,
lastof(company_name));
1719 char *cn =
stredup(company_name);
1745 default:
return tile;
1763 default:
return true;
1845 static Town *CreateRandomTown(uint attempts, uint32 townnameparts,
TownSize size,
bool city,
TownLayout layout)
1868 DoCreateTown(t, tile, townnameparts, size, city, layout,
false);
1876 cur_company.Restore();
1884 }
while (--attempts != 0);
1889 static const byte _num_initial_towns[4] = {5, 11, 23, 46};
1900 uint current_number = 0;
1904 uint32 townnameparts;
1905 TownNames town_names;
1918 if (CreateRandomTown(20, townnameparts,
TSZ_RANDOM, city, layout) != NULL) current_number++;
1923 if (current_number != 0)
return true;
1953 HouseZonesBits smallest = HZB_TOWN_EDGE;
1954 for (HouseZonesBits i = HZB_BEGIN; i < HZB_END; i++) {
1955 if (dist < t->cache.squared_town_zone_radius[i]) smallest = i;
1979 if (HouseSpec::Get(type)->building_flags & BUILDING_IS_ANIMATED)
AddAnimatedTile(tile);
2090 if ((grid_pos.
x % 3) == 0 || (grid_pos.
y % 3) == 0)
return false;
2094 if ((grid_pos.
x % 4) == 0 || (grid_pos.
y % 4) == 0)
return false;
2124 if ((grid_pos.
x != 2 && grid_pos.
x != -1) ||
2125 (grid_pos.
y != 2 && grid_pos.
y != -1))
return false;
2129 if ((grid_pos.
x & 3) < 2 || (grid_pos.
y & 3) < 2)
return false;
2216 uint bitmask = (1 << rad) + (1 << (land + 12));
2224 uint probability_max = 0;
2228 const HouseSpec *hs = HouseSpec::Get(i);
2234 if (hs->
class_id != HOUSE_NO_CLASS) {
2244 probability_max += cur_prob;
2245 probs[num] = cur_prob;
2251 while (probability_max > 0) {
2261 for (i = 0; i < num; i++) {
2262 if (probs[i] > r)
break;
2267 probability_max -= probs[i];
2271 houses[i] = houses[num];
2272 probs[i] = probs[num];
2274 const HouseSpec *hs = HouseSpec::Get(house);
2292 if (t->
flags & oneof)
continue;
2296 if (noslope && slope !=
SLOPE_FLAT)
continue;
2308 byte random_bits = Random();
2321 byte construction_counter = 0;
2322 byte construction_stage = 0;
2325 uint32 r = Random();
2328 if (
Chance16(1, 7)) construction_stage =
GB(r, 0, 2);
2333 construction_counter =
GB(r, 2, 2);
2337 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
2338 UpdateTownRadius(t);
2357 DoClearSquare(tile);
2373 if (HouseSpec::Get(house - 1)->building_flags & TILE_SIZE_2x1) {
2376 }
else if (HouseSpec::Get(house - 1)->building_flags & BUILDING_2_TILES_Y) {
2379 }
else if (HouseSpec::Get(house - 2)->building_flags & BUILDING_HAS_4_TILES) {
2382 }
else if (HouseSpec::Get(house - 3)->building_flags & BUILDING_HAS_4_TILES) {
2399 const HouseSpec *hs = HouseSpec::Get(house);
2422 UpdateTownRadius(t);
2468 FOR_ALL_CARGOSPECS(cs) {
2494 uint16 index =
GB(p1, 0, 16);
2558 uint old_rate = t->
growth_rate & ~TOWN_GROW_RATE_CUSTOM;
2595 UpdateTownRadius(t);
2597 uint n = amount * 10;
2602 for (; p2 > 0; p2--) {
2604 for (uint i = 0; i < 25; i++)
if (
GrowTown(t))
break;
2607 UpdateTownRadius(t);
2609 UpdateTownMaxPass(t);
2632 FOR_ALL_STATIONS(st) {
2633 if (st->
town == t) {
2638 if (ret.
Failed())
return ret;
2650 bool try_clear =
false;
2691 if (ret.
Failed())
return ret;
2696 if (flags &
DC_EXEC)
delete t;
2706 2, 4, 9, 35, 48, 53, 117, 175
2743 GetString(company_name, STR_COMPANY_NAME,
lastof(company_name));
2745 char *cn =
stredup(company_name);
2785 static const int STATUE_NUMBER_INNER_TILES = 25;
2804 if (statue_data->
tile_count <= STATUE_NUMBER_INNER_TILES) {
2834 if (flags & DC_EXEC) {
2850 if (flags & DC_EXEC) {
2869 if (flags & DC_EXEC) {
2880 SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE);
2881 SetDParam(1, STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION);
2893 if (flags & DC_EXEC) {
2900 FOR_ALL_STATIONS(st) {
2926 static TownActionProc *
const _town_action_proc[] = {
2927 TownActionAdvertiseSmall,
2928 TownActionAdvertiseMedium,
2929 TownActionAdvertiseLarge,
2930 TownActionRoadRebuild,
2932 TownActionFundBuildings,
2933 TownActionBuyRights,
2957 for (uint i = 0; i !=
lengthof(_town_action_costs); i++) {
2975 if (avail >= _town_action_costs[i] * _price[PR_TOWN_ACTION] >> 8) {
2982 if (nump != NULL) *nump = num;
3006 CommandCost ret = _town_action_proc[p2](t, flags);
3007 if (ret.
Failed())
return ret;
3009 if (flags & DC_EXEC) {
3016 static void UpdateTownRating(
Town *t)
3020 FOR_ALL_COMPANIES(c) {
3027 FOR_ALL_STATIONS(st) {
3029 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3060 for (
int i = TE_BEGIN; i <
TE_END; i++) {
3061 switch (t->
goal[i]) {
3085 static const uint16 _grow_count_values[2][6] = {
3086 { 120, 120, 120, 100, 80, 60 },
3087 { 320, 420, 300, 220, 160, 100 }
3093 FOR_ALL_STATIONS(st) {
3095 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3104 m = _grow_count_values[0][
min(n, 5)];
3106 m = _grow_count_values[1][
min(n, 5)];
3107 if (n == 0 && !
Chance16(1, 12))
return;
3114 m >>= growth_multiplier;
3118 if (m <= t->grow_counter) {
3126 static void UpdateTownAmounts(
Town *t)
3135 static void UpdateTownUnwanted(
Town *t)
3139 FOR_ALL_COMPANIES(c) {
3174 uint best = threshold;
3175 Town *best_town = NULL;
3205 if (tid == (TownID)INVALID_TOWN) {
3222 return Town::GetByTile(tile);
3239 static int ref_count = 0;
3241 if (ref_count == 0) {
3242 _town_test_ratings.
Clear();
3246 assert(ref_count > 0);
3249 _town_rating_test = !(ref_count == 0);
3259 if (_town_rating_test) {
3261 if (it != _town_test_ratings.
End()) {
3288 if (rating < max) rating =
max;
3293 if (rating > max) rating =
max;
3296 if (_town_rating_test) {
3297 _town_test_ratings[t] = rating;
3342 void TownsMonthlyLoop()
3353 UpdateTownAmounts(t);
3354 UpdateTownRating(t);
3356 UpdateTownUnwanted(t);
3363 void TownsYearlyLoop()
3377 const HouseSpec *hs = HouseSpec::Get(house);
3382 bool allow_terraform =
true;
3386 hs = HouseSpec::Get(house);
3403 GetSlopePixelZ_Town,
3405 AddAcceptedCargo_Town,
3407 GetTileTrackStatus_Town,
3411 ChangeTileOwner_Town,
3412 AddProducedCargo_Town,
3423 memset(&_house_specs, 0,
sizeof(_house_specs));