00001
00002
00005 #ifndef TOWN_H
00006 #define TOWN_H
00007
00008 #include "oldpool.h"
00009 #include "core/bitmath_func.hpp"
00010 #include "core/random_func.hpp"
00011 #include "cargo_type.h"
00012 #include "tile_type.h"
00013 #include "date_type.h"
00014 #include "town_type.h"
00015 #include "company_type.h"
00016 #include "settings_type.h"
00017 #include "strings_type.h"
00018 #include "viewport_type.h"
00019 #include "economy_type.h"
00020 #include "map_type.h"
00021 #include "command_type.h"
00022
00023 enum {
00024 HOUSE_NO_CLASS = 0,
00025 NEW_HOUSE_OFFSET = 110,
00026 HOUSE_MAX = 512,
00027 INVALID_TOWN = 0xFFFF,
00028 INVALID_HOUSE_ID = 0xFFFF,
00029
00030
00031
00032 HOUSE_CLASS_MAX = HOUSE_MAX - NEW_HOUSE_OFFSET + 1,
00033 };
00034
00035 enum BuildingFlags {
00036 TILE_NO_FLAG = 0,
00037 TILE_SIZE_1x1 = 1U << 0,
00038 TILE_NOT_SLOPED = 1U << 1,
00039 TILE_SIZE_2x1 = 1U << 2,
00040 TILE_SIZE_1x2 = 1U << 3,
00041 TILE_SIZE_2x2 = 1U << 4,
00042 BUILDING_IS_ANIMATED = 1U << 5,
00043 BUILDING_IS_CHURCH = 1U << 6,
00044 BUILDING_IS_STADIUM = 1U << 7,
00045 BUILDING_HAS_1_TILE = TILE_SIZE_1x1 | TILE_SIZE_2x1 | TILE_SIZE_1x2 | TILE_SIZE_2x2,
00046 BUILDING_2_TILES_X = TILE_SIZE_2x1 | TILE_SIZE_2x2,
00047 BUILDING_2_TILES_Y = TILE_SIZE_1x2 | TILE_SIZE_2x2,
00048 BUILDING_HAS_4_TILES = TILE_SIZE_2x2,
00049 };
00050
00051 DECLARE_ENUM_AS_BIT_SET(BuildingFlags)
00052
00053 enum HouseZonesBits {
00054 HZB_BEGIN = 0,
00055 HZB_TOWN_EDGE = 0,
00056 HZB_TOWN_OUTSKIRT,
00057 HZB_TOWN_OUTER_SUBURB,
00058 HZB_TOWN_INNER_SUBURB,
00059 HZB_TOWN_CENTRE,
00060 HZB_END,
00061 };
00062 assert_compile(HZB_END == 5);
00063
00064 DECLARE_POSTFIX_INCREMENT(HouseZonesBits)
00065
00066 enum HouseZones {
00067 HZ_NOZNS = 0x0000,
00068 HZ_ZON1 = 1U << HZB_TOWN_EDGE,
00069 HZ_ZON2 = 1U << HZB_TOWN_OUTSKIRT,
00070 HZ_ZON3 = 1U << HZB_TOWN_OUTER_SUBURB,
00071 HZ_ZON4 = 1U << HZB_TOWN_INNER_SUBURB,
00072 HZ_ZON5 = 1U << HZB_TOWN_CENTRE,
00073 HZ_ZONALL = 0x001F,
00074 HZ_SUBARTC_ABOVE = 0x0800,
00075 HZ_TEMP = 0x1000,
00076 HZ_SUBARTC_BELOW = 0x2000,
00077 HZ_SUBTROPIC = 0x4000,
00078 HZ_TOYLND = 0x8000
00079 };
00080
00081 DECLARE_ENUM_AS_BIT_SET(HouseZones)
00082
00083 enum HouseExtraFlags {
00084 NO_EXTRA_FLAG = 0,
00085 BUILDING_IS_HISTORICAL = 1U << 0,
00086 BUILDING_IS_PROTECTED = 1U << 1,
00087 SYNCHRONISED_CALLBACK_1B = 1U << 2,
00088 CALLBACK_1A_RANDOM_BITS = 1U << 3,
00089 };
00090
00091 DECLARE_ENUM_AS_BIT_SET(HouseExtraFlags)
00092
00093 template <typename T>
00094 struct BuildingCounts {
00095 T id_count[HOUSE_MAX];
00096 T class_count[HOUSE_CLASS_MAX];
00097 };
00098
00099 static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4;
00100 static const uint CUSTOM_TOWN_MAX_NUMBER = 5000;
00101
00102 DECLARE_OLD_POOL(Town, Town, 3, 8000)
00103
00104 struct Town : PoolItem<Town, TownID, &_Town_pool> {
00105 TileIndex xy;
00106
00107
00108 uint32 num_houses;
00109 uint32 population;
00110
00111
00112 uint32 townnamegrfid;
00113 uint16 townnametype;
00114 uint32 townnameparts;
00115 char *name;
00116
00117
00118 ViewportSign sign;
00119
00120
00121
00122
00123
00124 byte flags12;
00125
00126
00127 uint16 noise_reached;
00128
00129
00130 CompanyMask statues;
00131
00132
00133 CompanyMask have_ratings;
00134 uint8 unwanted[MAX_COMPANIES];
00135 CompanyByte exclusivity;
00136 uint8 exclusive_counter;
00137 int16 ratings[MAX_COMPANIES];
00138
00139
00140 uint32 max_pass;
00141 uint32 max_mail;
00142 uint32 new_max_pass;
00143 uint32 new_max_mail;
00144 uint32 act_pass;
00145 uint32 act_mail;
00146 uint32 new_act_pass;
00147 uint32 new_act_mail;
00148
00149
00150 byte pct_pass_transported;
00151 byte pct_mail_transported;
00152
00153
00154 uint16 act_food;
00155 uint16 act_water;
00156 uint16 new_act_food;
00157 uint16 new_act_water;
00158
00159
00160 uint16 time_until_rebuild;
00161
00162
00163 uint16 grow_counter;
00164 int16 growth_rate;
00165
00166
00167 byte fund_buildings_months;
00168
00169
00170 byte road_build_months;
00171
00172
00173 bool larger_town;
00174 TownLayoutByte layout;
00175
00176
00177 uint32 squared_town_zone_radius[HZB_END];
00178
00179
00180 BuildingCounts<uint16> building_counts;
00181
00185 Town(TileIndex tile = INVALID_TILE);
00186
00188 ~Town();
00189
00190 inline bool IsValid() const { return this->xy != INVALID_TILE; }
00191
00192 void InitializeLayout(TownLayout layout);
00193
00200 inline uint16 MaxTownNoise() const
00201 {
00202 if (this->population == 0) return 0;
00203
00204 return ((this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3);
00205 }
00206 };
00207
00208 struct HouseSpec {
00209
00210 Year min_year;
00211 Year max_year;
00212 byte population;
00213 byte removal_cost;
00214 StringID building_name;
00215 uint16 remove_rating_decrease;
00216 byte mail_generation;
00217 byte cargo_acceptance[3];
00218 CargoID accepts_cargo[3];
00219 BuildingFlags building_flags;
00220 HouseZones building_availability;
00221 bool enabled;
00222
00223
00224 HouseID substitute_id;
00225 struct SpriteGroup *spritegroup;
00226 HouseID override;
00227 uint16 callback_mask;
00228 byte random_colour[4];
00229 byte probability;
00230 HouseExtraFlags extra_flags;
00231 HouseClassID class_id;
00232 byte animation_frames;
00233 byte animation_speed;
00234 byte processing_time;
00235 byte minimum_life;
00236
00237
00238 uint8 local_id;
00239 const struct GRFFile *grffile;
00240
00245 Money GetRemovalCost() const;
00246
00247 };
00248
00249 extern HouseSpec _house_specs[HOUSE_MAX];
00250
00251 uint32 GetWorldPopulation();
00252
00253 void UpdateTownVirtCoord(Town *t);
00254 void UpdateAllTownVirtCoords();
00255 void InitializeTown();
00256 void ShowTownViewWindow(TownID town);
00257 void ExpandTown(Town *t);
00258 Town *CreateRandomTown(uint attempts, TownSize size, bool city, TownLayout layout);
00259
00260 enum {
00261 ROAD_REMOVE = 0,
00262 UNMOVEABLE_REMOVE = 1,
00263 TUNNELBRIDGE_REMOVE = 1,
00264 INDUSTRY_REMOVE = 2
00265 };
00266
00270 static const byte TOWN_GROWTH_FREQUENCY = 70;
00271
00274 static const byte TOWN_HOUSE_COMPLETED = 3;
00275
00282 enum {
00283 TOWN_IS_FUNDED = 0,
00284 TOWN_HAS_CHURCH = 1,
00285 TOWN_HAS_STADIUM = 2
00286 };
00287
00288 bool CheckforTownRating(DoCommandFlag flags, Town *t, byte type);
00289
00290 static inline HouseSpec *GetHouseSpecs(HouseID house_id)
00291 {
00292 assert(house_id < HOUSE_MAX);
00293 return &_house_specs[house_id];
00294 }
00295
00296 TileIndexDiff GetHouseNorthPart(HouseID &house);
00297
00303 static inline bool IsValidTownID(TownID index)
00304 {
00305 return index < GetTownPoolSize() && GetTown(index)->IsValid();
00306 }
00307
00308 static inline TownID GetMaxTownIndex()
00309 {
00310
00311
00312
00313
00314
00315 return GetTownPoolSize() - 1;
00316 }
00317
00318 static inline uint GetNumTowns()
00319 {
00320 extern uint _total_towns;
00321
00322 return _total_towns;
00323 }
00324
00328 static inline Town *GetRandomTown()
00329 {
00330 int num = RandomRange(GetNumTowns());
00331 TownID index = INVALID_TOWN;
00332
00333 while (num >= 0) {
00334 num--;
00335
00336 index++;
00337
00338 while (!IsValidTownID(index)) {
00339 index++;
00340 assert(index <= GetMaxTownIndex());
00341 }
00342 }
00343
00344 return GetTown(index);
00345 }
00346
00347 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
00348
00349 #define FOR_ALL_TOWNS_FROM(t, start) for (t = GetTown(start); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) if (t->IsValid())
00350 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
00351
00352 extern Town *_cleared_town;
00353 extern int _cleared_town_rating;
00354 extern uint32 _cur_town_ctr;
00355 extern uint32 _cur_town_iter;
00356
00357 void ResetHouses();
00358
00359 void ClearTownHouse(Town *t, TileIndex tile);
00360 void UpdateTownMaxPass(Town *t);
00361 void UpdateTownRadius(Town *t);
00362 bool CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
00363 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00364 void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
00365 HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile);
00366 void SetTownRatingTestMode(bool mode);
00367 uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
00368 bool GenerateTowns(TownLayout layout);
00369 bool GenerateTownName(uint32 *townnameparts);
00370
00378 static inline uint TileHash(uint x, uint y)
00379 {
00380 uint hash = x >> 4;
00381 hash ^= x >> 6;
00382 hash ^= y >> 4;
00383 hash -= y >> 6;
00384 return hash;
00385 }
00386
00396 static inline uint TileHash2Bit(uint x, uint y)
00397 {
00398 return GB(TileHash(x, y), 0, 2);
00399 }
00400
00401 #endif