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 struct BuildingCounts {
00094 uint8 id_count[HOUSE_MAX];
00095 uint8 class_count[HOUSE_CLASS_MAX];
00096 };
00097
00098 DECLARE_OLD_POOL(Town, Town, 3, 8000)
00099
00100 struct Town : PoolItem<Town, TownID, &_Town_pool> {
00101 TileIndex xy;
00102
00103
00104 uint32 num_houses;
00105 uint32 population;
00106
00107
00108 uint32 townnamegrfid;
00109 uint16 townnametype;
00110 uint32 townnameparts;
00111 char *name;
00112
00113
00114 ViewportSign sign;
00115
00116
00117
00118
00119
00120 byte flags12;
00121
00122
00123 uint16 noise_reached;
00124
00125
00126 CompanyMask statues;
00127
00128
00129 CompanyMask have_ratings;
00130 uint8 unwanted[MAX_COMPANIES];
00131 CompanyByte exclusivity;
00132 uint8 exclusive_counter;
00133 int16 ratings[MAX_COMPANIES];
00134
00135
00136 uint32 max_pass;
00137 uint32 max_mail;
00138 uint32 new_max_pass;
00139 uint32 new_max_mail;
00140 uint32 act_pass;
00141 uint32 act_mail;
00142 uint32 new_act_pass;
00143 uint32 new_act_mail;
00144
00145
00146 byte pct_pass_transported;
00147 byte pct_mail_transported;
00148
00149
00150 uint16 act_food;
00151 uint16 act_water;
00152 uint16 new_act_food;
00153 uint16 new_act_water;
00154
00155
00156 uint16 time_until_rebuild;
00157
00158
00159 uint16 grow_counter;
00160 int16 growth_rate;
00161
00162
00163 byte fund_buildings_months;
00164
00165
00166 byte road_build_months;
00167
00168
00169 bool larger_town;
00170 TownLayoutByte layout;
00171
00172
00173 uint32 squared_town_zone_radius[HZB_END];
00174
00175
00176 BuildingCounts building_counts;
00177
00181 Town(TileIndex tile = INVALID_TILE);
00182
00184 ~Town();
00185
00186 inline bool IsValid() const { return this->xy != INVALID_TILE; }
00187
00188 void InitializeLayout(TownLayout layout);
00189
00196 inline uint16 MaxTownNoise() const
00197 {
00198 if (this->population == 0) return 0;
00199
00200 return ((this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3);
00201 }
00202 };
00203
00204 struct HouseSpec {
00205
00206 Year min_year;
00207 Year max_year;
00208 byte population;
00209 byte removal_cost;
00210 StringID building_name;
00211 uint16 remove_rating_decrease;
00212 byte mail_generation;
00213 byte cargo_acceptance[3];
00214 CargoID accepts_cargo[3];
00215 BuildingFlags building_flags;
00216 HouseZones building_availability;
00217 bool enabled;
00218
00219
00220 HouseID substitute_id;
00221 struct SpriteGroup *spritegroup;
00222 HouseID override;
00223 uint16 callback_mask;
00224 byte random_colour[4];
00225 byte probability;
00226 HouseExtraFlags extra_flags;
00227 HouseClassID class_id;
00228 byte animation_frames;
00229 byte animation_speed;
00230 byte processing_time;
00231 byte minimum_life;
00232
00233
00234 uint8 local_id;
00235 const struct GRFFile *grffile;
00236
00241 Money GetRemovalCost() const;
00242
00243 };
00244
00245 extern HouseSpec _house_specs[HOUSE_MAX];
00246
00247 uint32 GetWorldPopulation();
00248
00249 void UpdateTownVirtCoord(Town *t);
00250 void UpdateAllTownVirtCoords();
00251 void InitializeTown();
00252 void ShowTownViewWindow(TownID town);
00253 void ExpandTown(Town *t);
00254 Town *CreateRandomTown(uint attempts, TownSize size, bool city, TownLayout layout);
00255
00256 enum {
00257 ROAD_REMOVE = 0,
00258 UNMOVEABLE_REMOVE = 1,
00259 TUNNELBRIDGE_REMOVE = 1,
00260 INDUSTRY_REMOVE = 2
00261 };
00262
00266 static const byte TOWN_GROWTH_FREQUENCY = 70;
00267
00270 static const byte TOWN_HOUSE_COMPLETED = 3;
00271
00278 enum {
00279 TOWN_IS_FUNDED = 0,
00280 TOWN_HAS_CHURCH = 1,
00281 TOWN_HAS_STADIUM = 2
00282 };
00283
00284 bool CheckforTownRating(DoCommandFlag flags, Town *t, byte type);
00285
00286 static inline HouseSpec *GetHouseSpecs(HouseID house_id)
00287 {
00288 assert(house_id < HOUSE_MAX);
00289 return &_house_specs[house_id];
00290 }
00291
00292 TileIndexDiff GetHouseNorthPart(HouseID &house);
00293
00299 static inline bool IsValidTownID(TownID index)
00300 {
00301 return index < GetTownPoolSize() && GetTown(index)->IsValid();
00302 }
00303
00304 static inline TownID GetMaxTownIndex()
00305 {
00306
00307
00308
00309
00310
00311 return GetTownPoolSize() - 1;
00312 }
00313
00314 static inline uint GetNumTowns()
00315 {
00316 extern uint _total_towns;
00317
00318 return _total_towns;
00319 }
00320
00324 static inline Town *GetRandomTown()
00325 {
00326 int num = RandomRange(GetNumTowns());
00327 TownID index = INVALID_TOWN;
00328
00329 while (num >= 0) {
00330 num--;
00331
00332 index++;
00333
00334 while (!IsValidTownID(index)) {
00335 index++;
00336 assert(index <= GetMaxTownIndex());
00337 }
00338 }
00339
00340 return GetTown(index);
00341 }
00342
00343 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
00344
00345 #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())
00346 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
00347
00348 extern Town *_cleared_town;
00349 extern int _cleared_town_rating;
00350 extern uint32 _cur_town_ctr;
00351 extern uint32 _cur_town_iter;
00352
00353 void ResetHouses();
00354
00355 void ClearTownHouse(Town *t, TileIndex tile);
00356 void UpdateTownMaxPass(Town *t);
00357 void UpdateTownRadius(Town *t);
00358 bool CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
00359 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00360 void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
00361 HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile);
00362 void SetTownRatingTestMode(bool mode);
00363 uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
00364 bool GenerateTowns(TownLayout layout);
00365 bool GenerateTownName(uint32 *townnameparts);
00366
00374 static inline uint TileHash(uint x, uint y)
00375 {
00376 uint hash = x >> 4;
00377 hash ^= x >> 6;
00378 hash ^= y >> 4;
00379 hash -= y >> 6;
00380 return hash;
00381 }
00382
00392 static inline uint TileHash2Bit(uint x, uint y)
00393 {
00394 return GB(TileHash(x, y), 0, 2);
00395 }
00396
00397 #endif