town.h

Go to the documentation of this file.
00001 /* $Id: town.h 14828 2009-01-04 15:32:25Z smatz $ */
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 
00022 enum {
00023   HOUSE_NO_CLASS   = 0,
00024   NEW_HOUSE_OFFSET = 110,
00025   HOUSE_MAX        = 512,
00026   INVALID_TOWN     = 0xFFFF,
00027   INVALID_HOUSE_ID = 0xFFFF,
00028 
00029   /* There can only be as many classes as there are new houses, plus one for
00030    * NO_CLASS, as the original houses don't have classes. */
00031   HOUSE_CLASS_MAX  = HOUSE_MAX - NEW_HOUSE_OFFSET + 1,
00032 };
00033 
00034 enum BuildingFlags {
00035   TILE_NO_FLAG         =       0,
00036   TILE_SIZE_1x1        = 1U << 0,
00037   TILE_NOT_SLOPED      = 1U << 1,
00038   TILE_SIZE_2x1        = 1U << 2,
00039   TILE_SIZE_1x2        = 1U << 3,
00040   TILE_SIZE_2x2        = 1U << 4,
00041   BUILDING_IS_ANIMATED = 1U << 5,
00042   BUILDING_IS_CHURCH   = 1U << 6,
00043   BUILDING_IS_STADIUM  = 1U << 7,
00044   BUILDING_HAS_1_TILE  = TILE_SIZE_1x1 | TILE_SIZE_2x1 | TILE_SIZE_1x2 | TILE_SIZE_2x2,
00045   BUILDING_2_TILES_X   = TILE_SIZE_2x1 | TILE_SIZE_2x2,
00046   BUILDING_2_TILES_Y   = TILE_SIZE_1x2 | TILE_SIZE_2x2,
00047   BUILDING_HAS_4_TILES = TILE_SIZE_2x2,
00048 };
00049 
00050 DECLARE_ENUM_AS_BIT_SET(BuildingFlags)
00051 
00052 enum HouseZonesBits {
00053   HZB_BEGIN     = 0,
00054   HZB_TOWN_EDGE = 0,
00055   HZB_TOWN_OUTSKIRT,
00056   HZB_TOWN_OUTER_SUBURB,
00057   HZB_TOWN_INNER_SUBURB,
00058   HZB_TOWN_CENTRE,
00059   HZB_END,
00060 };
00061 assert_compile(HZB_END == 5);
00062 
00063 DECLARE_POSTFIX_INCREMENT(HouseZonesBits)
00064 
00065 enum HouseZones {                  
00066   HZ_NOZNS             = 0x0000,  
00067   HZ_ZON1              = 1U << HZB_TOWN_EDGE,    
00068   HZ_ZON2              = 1U << HZB_TOWN_OUTSKIRT,
00069   HZ_ZON3              = 1U << HZB_TOWN_OUTER_SUBURB,
00070   HZ_ZON4              = 1U << HZB_TOWN_INNER_SUBURB,
00071   HZ_ZON5              = 1U << HZB_TOWN_CENTRE,  
00072   HZ_ZONALL            = 0x001F,  
00073   HZ_SUBARTC_ABOVE     = 0x0800,  
00074   HZ_TEMP              = 0x1000,  
00075   HZ_SUBARTC_BELOW     = 0x2000,  
00076   HZ_SUBTROPIC         = 0x4000,  
00077   HZ_TOYLND            = 0x8000   
00078 };
00079 
00080 DECLARE_ENUM_AS_BIT_SET(HouseZones)
00081 
00082 enum HouseExtraFlags {
00083   NO_EXTRA_FLAG            =       0,
00084   BUILDING_IS_HISTORICAL   = 1U << 0,  
00085   BUILDING_IS_PROTECTED    = 1U << 1,  
00086   SYNCHRONISED_CALLBACK_1B = 1U << 2,  
00087   CALLBACK_1A_RANDOM_BITS  = 1U << 3,  
00088 };
00089 
00090 DECLARE_ENUM_AS_BIT_SET(HouseExtraFlags)
00091 
00092 struct BuildingCounts {
00093   uint8 id_count[HOUSE_MAX];
00094   uint8 class_count[HOUSE_CLASS_MAX];
00095 };
00096 
00097 DECLARE_OLD_POOL(Town, Town, 3, 8000)
00098 
00099 struct Town : PoolItem<Town, TownID, &_Town_pool> {
00100   TileIndex xy;
00101 
00102   /* Current population of people and amount of houses. */
00103   uint32 num_houses;
00104   uint32 population;
00105 
00106   /* Town name */
00107   uint32 townnamegrfid;
00108   uint16 townnametype;
00109   uint32 townnameparts;
00110   char *name;
00111 
00112   /* NOSAVE: Location of name sign, UpdateTownVirtCoord updates this. */
00113   ViewportSign sign;
00114 
00115   /* Makes sure we don't build certain house types twice.
00116    * bit 0 = Building funds received
00117    * bit 1 = CHURCH
00118    * bit 2 = STADIUM */
00119   byte flags12;
00120 
00121   /* level of noise that all the airports are generating */
00122   uint16 noise_reached;
00123 
00124   /* Which companies have a statue? */
00125   CompanyMask statues;
00126 
00127   /* Company ratings as well as a mask that determines which companies have a rating. */
00128   CompanyMask have_ratings;
00129   uint8 unwanted[MAX_COMPANIES]; 
00130   CompanyByte exclusivity;       
00131   uint8 exclusive_counter;       
00132   int16 ratings[MAX_COMPANIES];
00133 
00134   /* Maximum amount of passengers and mail that can be transported. */
00135   uint32 max_pass;
00136   uint32 max_mail;
00137   uint32 new_max_pass;
00138   uint32 new_max_mail;
00139   uint32 act_pass;
00140   uint32 act_mail;
00141   uint32 new_act_pass;
00142   uint32 new_act_mail;
00143 
00144   /* Amount of passengers that were transported. */
00145   byte pct_pass_transported;
00146   byte pct_mail_transported;
00147 
00148   /* Amount of food and paper that was transported. Actually a bit mask would be enough. */
00149   uint16 act_food;
00150   uint16 act_water;
00151   uint16 new_act_food;
00152   uint16 new_act_water;
00153 
00154   /* Time until we rebuild a house. */
00155   uint16 time_until_rebuild;
00156 
00157   /* When to grow town next time. */
00158   uint16 grow_counter;
00159   int16 growth_rate;
00160 
00161   /* Fund buildings program in action? */
00162   byte fund_buildings_months;
00163 
00164   /* Fund road reconstruction in action? */
00165   byte road_build_months;
00166 
00167   /* If this is a larger town, and should grow more quickly. */
00168   bool larger_town;
00169 
00170   /* NOSAVE: UpdateTownRadius updates this given the house count. */
00171   uint32 squared_town_zone_radius[HZB_END];
00172 
00173   /* NOSAVE: The number of each type of building in the town. */
00174   BuildingCounts building_counts;
00175 
00176   /* NOSAVE: The town specific road layout */
00177   TownLayout layout;
00178 
00182   Town(TileIndex tile = INVALID_TILE);
00183 
00185   ~Town();
00186 
00187   inline bool IsValid() const { return this->xy != INVALID_TILE; }
00188 
00189   void InitializeLayout();
00190 
00191   inline TownLayout GetActiveLayout() const;
00192 
00199   inline uint16 MaxTownNoise() const {
00200     if (this->population == 0) return 0; // no population? no noise
00201 
00202     return ((this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3);
00203   }
00204 };
00205 
00210 inline TownLayout Town::GetActiveLayout() const
00211 {
00212   return (_settings_game.economy.town_layout == TL_RANDOM) ? this->layout : _settings_game.economy.town_layout;
00213 }
00214 
00215 struct HouseSpec {
00216   /* Standard properties */
00217   Year min_year;                     
00218   Year max_year;                     
00219   byte population;                   
00220   byte removal_cost;                 
00221   StringID building_name;            
00222   uint16 remove_rating_decrease;     
00223   byte mail_generation;              
00224   byte cargo_acceptance[3];          
00225   CargoID accepts_cargo[3];          
00226   BuildingFlags building_flags;      
00227   HouseZones building_availability;  
00228   bool enabled;                      
00229 
00230   /* NewHouses properties */
00231   HouseID substitute_id;             
00232   struct SpriteGroup *spritegroup;   
00233   HouseID override;                  
00234   uint16 callback_mask;              
00235   byte random_colour[4];             
00236   byte probability;                  
00237   HouseExtraFlags extra_flags;       
00238   HouseClassID class_id;             
00239   byte animation_frames;             
00240   byte animation_speed;              
00241   byte processing_time;              
00242   byte minimum_life;                 
00243 
00244   /* grf file related properties*/
00245   uint8 local_id;                    
00246   const struct GRFFile *grffile;     
00247 
00252   Money GetRemovalCost() const;
00253 
00254 };
00255 
00256 extern HouseSpec _house_specs[HOUSE_MAX];
00257 
00258 uint32 GetWorldPopulation();
00259 
00260 void UpdateTownVirtCoord(Town *t);
00261 void UpdateAllTownVirtCoords();
00262 void InitializeTown();
00263 void ShowTownViewWindow(TownID town);
00264 void ExpandTown(Town *t);
00265 Town *CreateRandomTown(uint attempts, TownSizeMode mode, uint size);
00266 
00267 enum {
00268   ROAD_REMOVE = 0,
00269   UNMOVEABLE_REMOVE = 1,
00270   TUNNELBRIDGE_REMOVE = 1,
00271   INDUSTRY_REMOVE = 2
00272 };
00273 
00277 static const byte TOWN_GROWTH_FREQUENCY = 70;
00278 
00281 static const byte TOWN_HOUSE_COMPLETED = 3;
00282 
00289 enum {
00290   TOWN_IS_FUNDED      = 0,   
00291   TOWN_HAS_CHURCH     = 1,   
00292   TOWN_HAS_STADIUM    = 2    
00293 };
00294 
00295 bool CheckforTownRating(uint32 flags, Town *t, byte type);
00296 
00297 static inline HouseSpec *GetHouseSpecs(HouseID house_id)
00298 {
00299   assert(house_id < HOUSE_MAX);
00300   return &_house_specs[house_id];
00301 }
00302 
00303 TileIndexDiff GetHouseNorthPart(HouseID &house);
00304 
00310 static inline bool IsValidTownID(TownID index)
00311 {
00312   return index < GetTownPoolSize() && GetTown(index)->IsValid();
00313 }
00314 
00315 static inline TownID GetMaxTownIndex()
00316 {
00317   /* TODO - This isn't the real content of the function, but
00318    *  with the new pool-system this will be replaced with one that
00319    *  _really_ returns the highest index. Now it just returns
00320    *  the next safe value we are sure about everything is below.
00321    */
00322   return GetTownPoolSize() - 1;
00323 }
00324 
00325 static inline uint GetNumTowns()
00326 {
00327   extern uint _total_towns;
00328 
00329   return _total_towns;
00330 }
00331 
00335 static inline Town *GetRandomTown()
00336 {
00337   int num = RandomRange(GetNumTowns());
00338   TownID index = INVALID_TOWN;
00339 
00340   while (num >= 0) {
00341     num--;
00342 
00343     index++;
00344     /* Make sure we have a valid town */
00345     while (!IsValidTownID(index)) {
00346       index++;
00347       assert(index <= GetMaxTownIndex());
00348     }
00349   }
00350 
00351   return GetTown(index);
00352 }
00353 
00354 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold);
00355 
00356 #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())
00357 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
00358 
00359 extern Town *_cleared_town;
00360 extern int _cleared_town_rating;
00361 
00362 void ResetHouses();
00363 
00364 void ClearTownHouse(Town *t, TileIndex tile);
00365 void UpdateTownMaxPass(Town *t);
00366 void UpdateTownRadius(Town *t);
00367 bool CheckIfAuthorityAllows(TileIndex tile);
00368 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00369 void ChangeTownRating(Town *t, int add, int max);
00370 HouseZonesBits GetTownRadiusGroup(const Town* t, TileIndex tile);
00371 void SetTownRatingTestMode(bool mode);
00372 
00380 static inline uint TileHash(uint x, uint y)
00381 {
00382   uint hash = x >> 4;
00383   hash ^= x >> 6;
00384   hash ^= y >> 4;
00385   hash -= y >> 6;
00386   return hash;
00387 }
00388 
00398 static inline uint TileHash2Bit(uint x, uint y)
00399 {
00400   return GB(TileHash(x, y), 0, 2);
00401 }
00402 
00403 #endif /* TOWN_H */

Generated on Fri Jan 9 19:01:52 2009 for openttd by  doxygen 1.5.6