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