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 static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4;
00099 static const uint CUSTOM_TOWN_MAX_NUMBER = 5000;
00100
00101 DECLARE_OLD_POOL(Town, Town, 3, 8000)
00102
00103 struct Town : PoolItem<Town, TownID, &_Town_pool> {
00104 TileIndex xy;
00105
00106
00107 uint32 num_houses;
00108 uint32 population;
00109
00110
00111 uint32 townnamegrfid;
00112 uint16 townnametype;
00113 uint32 townnameparts;
00114 char *name;
00115
00116
00117 ViewportSign sign;
00118
00119
00120
00121
00122
00123 byte flags12;
00124
00125
00126 uint16 noise_reached;
00127
00128
00129 CompanyMask statues;
00130
00131
00132 CompanyMask have_ratings;
00133 uint8 unwanted[MAX_COMPANIES];
00134 CompanyByte exclusivity;
00135 uint8 exclusive_counter;
00136 int16 ratings[MAX_COMPANIES];
00137
00138
00139 uint32 max_pass;
00140 uint32 max_mail;
00141 uint32 new_max_pass;
00142 uint32 new_max_mail;
00143 uint32 act_pass;
00144 uint32 act_mail;
00145 uint32 new_act_pass;
00146 uint32 new_act_mail;
00147
00148
00149 byte pct_pass_transported;
00150 byte pct_mail_transported;
00151
00152
00153 uint16 act_food;
00154 uint16 act_water;
00155 uint16 new_act_food;
00156 uint16 new_act_water;
00157
00158
00159 uint16 time_until_rebuild;
00160
00161
00162 uint16 grow_counter;
00163 int16 growth_rate;
00164
00165
00166 byte fund_buildings_months;
00167
00168
00169 byte road_build_months;
00170
00171
00172 bool larger_town;
00173 TownLayoutByte layout;
00174
00175
00176 uint32 squared_town_zone_radius[HZB_END];
00177
00178
00179 BuildingCounts building_counts;
00180
00184 Town(TileIndex tile = INVALID_TILE);
00185
00187 ~Town();
00188
00189 inline bool IsValid() const { return this->xy != INVALID_TILE; }
00190
00191 void InitializeLayout(TownLayout layout);
00192
00199 inline uint16 MaxTownNoise() const
00200 {
00201 if (this->population == 0) return 0;
00202
00203 return ((this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3);
00204 }
00205 };
00206
00207 struct HouseSpec {
00208
00209 Year min_year;
00210 Year max_year;
00211 byte population;
00212 byte removal_cost;
00213 StringID building_name;
00214 uint16 remove_rating_decrease;
00215 byte mail_generation;
00216 byte cargo_acceptance[3];
00217 CargoID accepts_cargo[3];
00218 BuildingFlags building_flags;
00219 HouseZones building_availability;
00220 bool enabled;
00221
00222
00223 HouseID substitute_id;
00224 struct SpriteGroup *spritegroup;
00225 HouseID override;
00226 uint16 callback_mask;
00227 byte random_colour[4];
00228 byte probability;
00229 HouseExtraFlags extra_flags;
00230 HouseClassID class_id;
00231 byte animation_frames;
00232 byte animation_speed;
00233 byte processing_time;
00234 byte minimum_life;
00235
00236
00237 uint8 local_id;
00238 const struct GRFFile *grffile;
00239
00244 Money GetRemovalCost() const;
00245
00246 };
00247
00248 extern HouseSpec _house_specs[HOUSE_MAX];
00249
00250 uint32 GetWorldPopulation();
00251
00252 void UpdateTownVirtCoord(Town *t);
00253 void UpdateAllTownVirtCoords();
00254 void InitializeTown();
00255 void ShowTownViewWindow(TownID town);
00256 void ExpandTown(Town *t);
00257 Town *CreateRandomTown(uint attempts, TownSize size, bool city, TownLayout layout);
00258
00259 enum {
00260 ROAD_REMOVE = 0,
00261 UNMOVEABLE_REMOVE = 1,
00262 TUNNELBRIDGE_REMOVE = 1,
00263 INDUSTRY_REMOVE = 2
00264 };
00265
00269 static const byte TOWN_GROWTH_FREQUENCY = 70;
00270
00273 static const byte TOWN_HOUSE_COMPLETED = 3;
00274
00281 enum {
00282 TOWN_IS_FUNDED = 0,
00283 TOWN_HAS_CHURCH = 1,
00284 TOWN_HAS_STADIUM = 2
00285 };
00286
00287 bool CheckforTownRating(DoCommandFlag flags, Town *t, byte type);
00288
00289 static inline HouseSpec *GetHouseSpecs(HouseID house_id)
00290 {
00291 assert(house_id < HOUSE_MAX);
00292 return &_house_specs[house_id];
00293 }
00294
00295 TileIndexDiff GetHouseNorthPart(HouseID &house);
00296
00302 static inline bool IsValidTownID(TownID index)
00303 {
00304 return index < GetTownPoolSize() && GetTown(index)->IsValid();
00305 }
00306
00307 static inline TownID GetMaxTownIndex()
00308 {
00309
00310
00311
00312
00313
00314 return GetTownPoolSize() - 1;
00315 }
00316
00317 static inline uint GetNumTowns()
00318 {
00319 extern uint _total_towns;
00320
00321 return _total_towns;
00322 }
00323
00327 static inline Town *GetRandomTown()
00328 {
00329 int num = RandomRange(GetNumTowns());
00330 TownID index = INVALID_TOWN;
00331
00332 while (num >= 0) {
00333 num--;
00334
00335 index++;
00336
00337 while (!IsValidTownID(index)) {
00338 index++;
00339 assert(index <= GetMaxTownIndex());
00340 }
00341 }
00342
00343 return GetTown(index);
00344 }
00345
00346 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
00347
00348 #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())
00349 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
00350
00351 extern Town *_cleared_town;
00352 extern int _cleared_town_rating;
00353 extern uint32 _cur_town_ctr;
00354 extern uint32 _cur_town_iter;
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