# town.h

Go to the documentation of this file.

    00001 /* $Id: town.h 16355 2009-05-18 20:17:28Z rubidium $ */
    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   /* There can only be as many classes as there are new houses, plus one for
    00031    * NO_CLASS, as the original houses don't have classes. */
    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   /* Current population of people and amount of houses. */
    00109   uint32 num_houses;
    00110   uint32 population;
    00111
    00112   /* Town name */
    00113   uint32 townnamegrfid;
    00114   uint16 townnametype;
    00115   uint32 townnameparts;
    00116   char *name;
    00117
    00118   /* NOSAVE: Location of name sign, UpdateTownVirtCoord updates this. */
    00119   ViewportSign sign;
    00120
    00121   /* Makes sure we don't build certain house types twice.
    00122    * bit 0 = Building funds received
    00123    * bit 1 = CHURCH
    00124    * bit 2 = STADIUM */
    00125   byte flags12;
    00126
    00127   /* level of noise that all the airports are generating */
    00128   uint16 noise_reached;
    00129
    00130   /* Which companies have a statue? */
    00131   CompanyMask statues;
    00132
    00133   /* Company ratings as well as a mask that determines which companies have a rating. */
    00134   CompanyMask have_ratings;
    00135   uint8 unwanted[MAX_COMPANIES];
    00136   CompanyByte exclusivity;
    00137   uint8 exclusive_counter;
    00138   int16 ratings[MAX_COMPANIES];
    00139
    00140   /* Maximum amount of passengers and mail that can be transported. */
    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   /* Amount of passengers that were transported. */
    00151   byte pct_pass_transported;
    00152   byte pct_mail_transported;
    00153
    00154   /* Amount of food and paper that was transported. Actually a bit mask would be enough. */
    00155   uint16 act_food;
    00156   uint16 act_water;
    00157   uint16 new_act_food;
    00158   uint16 new_act_water;
    00159
    00160   /* Time until we rebuild a house. */
    00161   uint16 time_until_rebuild;
    00162
    00163   /* When to grow town next time. */
    00164   uint16 grow_counter;
    00165   int16 growth_rate;
    00166
    00167   /* Fund buildings program in action? */
    00168   byte fund_buildings_months;
    00169
    00170   /* Fund road reconstruction in action? */
    00171   byte road_build_months;
    00172
    00173   /* If this is a larger town, and should grow more quickly. */
    00174   bool larger_town;
    00175   TownLayoutByte layout;
    00176
    00177   /* NOSAVE: UpdateTownRadius updates this given the house count. */
    00178   uint32 squared_town_zone_radius[HZB_END];
    00179
    00180   /* NOSAVE: The number of each type of building in the town. */
    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; // no population? no noise
    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   /* Standard properties */
    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   /* NewHouses properties */
    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   /* grf file related properties*/
    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   /* TODO - This isn't the real content of the function, but
    00312    *  with the new pool-system this will be replaced with one that
    00313    *  _really_ returns the highest index. Now it just returns
    00314    *  the next safe value we are sure about everything is below.
    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     /* Make sure we have a valid town */
    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 /* TOWN_H */