00001
00002
00005 #ifndef TOWN_H
00006 #define TOWN_H
00007
00008 #include "oldpool.h"
00009 #include "core/random_func.hpp"
00010 #include "cargo_type.h"
00011 #include "tile_type.h"
00012 #include "date_type.h"
00013 #include "town_type.h"
00014 #include "player_type.h"
00015 #include "newgrf_string_type.h"
00016
00017 enum {
00018 HOUSE_NO_CLASS = 0,
00019 NEW_HOUSE_OFFSET = 110,
00020 HOUSE_MAX = 512,
00021 INVALID_TOWN = 0xFFFF,
00022 INVALID_HOUSE_ID = 0xFFFF,
00023
00024
00025
00026 HOUSE_CLASS_MAX = HOUSE_MAX - NEW_HOUSE_OFFSET + 1,
00027 };
00028
00029 enum BuildingFlags {
00030 TILE_NO_FLAG = 0,
00031 TILE_SIZE_1x1 = 1U << 0,
00032 TILE_NOT_SLOPED = 1U << 1,
00033 TILE_SIZE_2x1 = 1U << 2,
00034 TILE_SIZE_1x2 = 1U << 3,
00035 TILE_SIZE_2x2 = 1U << 4,
00036 BUILDING_IS_ANIMATED = 1U << 5,
00037 BUILDING_IS_CHURCH = 1U << 6,
00038 BUILDING_IS_STADIUM = 1U << 7,
00039 BUILDING_HAS_1_TILE = TILE_SIZE_1x1 | TILE_SIZE_2x1 | TILE_SIZE_1x2 | TILE_SIZE_2x2,
00040 BUILDING_2_TILES_X = TILE_SIZE_2x1 | TILE_SIZE_2x2,
00041 BUILDING_2_TILES_Y = TILE_SIZE_1x2 | TILE_SIZE_2x2,
00042 BUILDING_HAS_4_TILES = TILE_SIZE_2x2,
00043 };
00044
00045 DECLARE_ENUM_AS_BIT_SET(BuildingFlags)
00046
00047 enum HouseZonesBits {
00048 HZB_TOWN_EDGE = 0,
00049 HZB_TOWN_OUTSKIRT,
00050 HZB_TOWN_OUTER_SUBURB,
00051 HZB_TOWN_INNER_SUBURB,
00052 HZB_TOWN_CENTRE,
00053 };
00054
00055 enum HouseZones {
00056 HZ_NOZNS = 0x0000,
00057 HZ_ZON1 = 1U << HZB_TOWN_EDGE,
00058 HZ_ZON2 = 1U << HZB_TOWN_OUTSKIRT,
00059 HZ_ZON3 = 1U << HZB_TOWN_OUTER_SUBURB,
00060 HZ_ZON4 = 1U << HZB_TOWN_INNER_SUBURB,
00061 HZ_ZON5 = 1U << HZB_TOWN_CENTRE,
00062 HZ_ZONALL = 0x001F,
00063 HZ_SUBARTC_ABOVE = 0x0800,
00064 HZ_TEMP = 0x1000,
00065 HZ_SUBARTC_BELOW = 0x2000,
00066 HZ_SUBTROPIC = 0x4000,
00067 HZ_TOYLND = 0x8000
00068 };
00069
00070 DECLARE_ENUM_AS_BIT_SET(HouseZones)
00071
00072 enum HouseExtraFlags {
00073 NO_EXTRA_FLAG = 0,
00074 BUILDING_IS_HISTORICAL = 1U << 0,
00075 BUILDING_IS_PROTECTED = 1U << 1,
00076 SYNCHRONISED_CALLBACK_1B = 1U << 2,
00077 CALLBACK_1A_RANDOM_BITS = 1U << 3,
00078 };
00079
00080 DECLARE_ENUM_AS_BIT_SET(HouseExtraFlags)
00081
00082 struct BuildingCounts {
00083 uint8 id_count[HOUSE_MAX];
00084 uint8 class_count[HOUSE_CLASS_MAX];
00085 };
00086
00087 DECLARE_OLD_POOL(Town, Town, 3, 8000)
00088
00089 struct Town : PoolItem<Town, TownID, &_Town_pool> {
00090 TileIndex xy;
00091
00092
00093 uint32 num_houses;
00094 uint32 population;
00095
00096
00097 uint32 townnamegrfid;
00098 uint16 townnametype;
00099 uint32 townnameparts;
00100 char *name;
00101
00102
00103 ViewportSign sign;
00104
00105
00106
00107
00108
00109 byte flags12;
00110
00111
00112 byte statues;
00113
00114
00115 byte have_ratings;
00116 uint8 unwanted[MAX_PLAYERS];
00117 PlayerByte exclusivity;
00118 uint8 exclusive_counter;
00119 int16 ratings[MAX_PLAYERS];
00120 int16 test_rating;
00121
00122
00123 uint32 max_pass;
00124 uint32 max_mail;
00125 uint32 new_max_pass;
00126 uint32 new_max_mail;
00127 uint32 act_pass;
00128 uint32 act_mail;
00129 uint32 new_act_pass;
00130 uint32 new_act_mail;
00131
00132
00133 byte pct_pass_transported;
00134 byte pct_mail_transported;
00135
00136
00137 uint16 act_food;
00138 uint16 act_water;
00139 uint16 new_act_food;
00140 uint16 new_act_water;
00141
00142
00143 uint16 time_until_rebuild;
00144
00145
00146 uint16 grow_counter;
00147 int16 growth_rate;
00148
00149
00150 byte fund_buildings_months;
00151
00152
00153 byte road_build_months;
00154
00155
00156 bool larger_town;
00157
00158
00159 uint16 radius[5];
00160
00161
00162 BuildingCounts building_counts;
00163
00167 Town(TileIndex tile = 0);
00168
00170 ~Town();
00171
00172 inline bool IsValid() const { return this->xy != 0; }
00173 };
00174
00175 struct HouseSpec {
00176
00177 Year min_date;
00178 Year max_date;
00179 byte population;
00180 byte removal_cost;
00181 GRFMappedStringID building_name;
00182 uint16 remove_rating_decrease;
00183 byte mail_generation;
00184 byte cargo_acceptance[3];
00185 CargoID accepts_cargo[3];
00186 BuildingFlags building_flags;
00187 HouseZones building_availability;
00188 bool enabled;
00189
00190
00191 HouseID substitute_id;
00192 struct SpriteGroup *spritegroup;
00193 HouseID override;
00194 uint16 callback_mask;
00195 byte random_colour[4];
00196 byte probability;
00197 HouseExtraFlags extra_flags;
00198 HouseClassID class_id;
00199 byte animation_frames;
00200 byte animation_speed;
00201 byte processing_time;
00202 byte minimum_life;
00203
00204
00205 uint8 local_id;
00206 const struct GRFFile *grffile;
00207 };
00208
00209 extern HouseSpec _house_specs[HOUSE_MAX];
00210
00211 uint32 GetWorldPopulation();
00212
00213 void UpdateTownVirtCoord(Town *t);
00214 void UpdateAllTownVirtCoords();
00215 void InitializeTown();
00216 void ShowTownViewWindow(TownID town);
00217 void ExpandTown(Town *t);
00218 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size);
00219
00220 enum {
00221 ROAD_REMOVE = 0,
00222 UNMOVEABLE_REMOVE = 1,
00223 TUNNELBRIDGE_REMOVE = 1,
00224 INDUSTRY_REMOVE = 2
00225 };
00226
00230 static const byte TOWN_GROWTH_FREQUENCY = 70;
00231
00234 static const byte TOWN_HOUSE_COMPLETED = 3;
00235
00242 enum {
00243 TOWN_IS_FUNDED = 0,
00244 TOWN_HAS_CHURCH = 1,
00245 TOWN_HAS_STADIUM = 2
00246 };
00247
00248 bool CheckforTownRating(uint32 flags, Town *t, byte type);
00249
00250 static inline HouseSpec *GetHouseSpecs(HouseID house_id)
00251 {
00252 assert(house_id < HOUSE_MAX);
00253 return &_house_specs[house_id];
00254 }
00255
00261 static inline bool IsValidTownID(TownID index)
00262 {
00263 return index < GetTownPoolSize() && GetTown(index)->IsValid();
00264 }
00265
00266 static inline TownID GetMaxTownIndex()
00267 {
00268
00269
00270
00271
00272
00273 return GetTownPoolSize() - 1;
00274 }
00275
00276 static inline uint GetNumTowns()
00277 {
00278 extern uint _total_towns;
00279
00280 return _total_towns;
00281 }
00282
00286 static inline Town *GetRandomTown()
00287 {
00288 int num = RandomRange(GetNumTowns());
00289 TownID index = INVALID_TOWN;
00290
00291 while (num >= 0) {
00292 num--;
00293
00294 index++;
00295
00296 while (!IsValidTownID(index)) {
00297 index++;
00298 assert(index <= GetMaxTownIndex());
00299 }
00300 }
00301
00302 return GetTown(index);
00303 }
00304
00305 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold);
00306
00307 #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())
00308 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
00309
00310 extern bool _town_sort_dirty;
00311 extern byte _town_sort_order;
00312 extern const Town **_town_sort;
00313
00314 extern Town *_cleared_town;
00315 extern int _cleared_town_rating;
00316
00317 uint OriginalTileRandomiser(uint x, uint y);
00318 void ResetHouses();
00319
00320 void ClearTownHouse(Town *t, TileIndex tile);
00321 void AfterLoadTown();
00322 void UpdateTownMaxPass(Town *t);
00323 void UpdateTownRadius(Town *t);
00324 bool CheckIfAuthorityAllows(TileIndex tile);
00325 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00326 void ChangeTownRating(Town *t, int add, int max);
00327 HouseZonesBits GetTownRadiusGroup(const Town* t, TileIndex tile);
00328 void SetTownRatingTestMode(bool mode);
00329
00330 #endif