town.h

Go to the documentation of this file.
00001 /* $Id: town.h 15764 2009-03-18 19:47:05Z 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_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 template <typename T>
00094 struct BuildingCounts {
00095   T id_count[HOUSE_MAX];
00096   T class_count[HOUSE_CLASS_MAX];
00097 };
00098 
00099 static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY  = 4; 
00100 static const uint CUSTOM_TOWN_MAX_NUMBER = 5000;  
00101 
00102 DECLARE_OLD_POOL(Town, Town, 3, 8000)
00103 
00104 struct Town : PoolItem<Town, TownID, &_Town_pool> {
00105   TileIndex xy;
00106 
00107   /* Current population of people and amount of houses. */
00108   uint32 num_houses;
00109   uint32 population;
00110 
00111   /* Town name */
00112   uint32 townnamegrfid;
00113   uint16 townnametype;
00114   uint32 townnameparts;
00115   char *name;
00116 
00117   /* NOSAVE: Location of name sign, UpdateTownVirtCoord updates this. */
00118   ViewportSign sign;
00119 
00120   /* Makes sure we don't build certain house types twice.
00121    * bit 0 = Building funds received
00122    * bit 1 = CHURCH
00123    * bit 2 = STADIUM */
00124   byte flags12;
00125 
00126   /* level of noise that all the airports are generating */
00127   uint16 noise_reached;
00128 
00129   /* Which companies have a statue? */
00130   CompanyMask statues;
00131 
00132   /* Company ratings as well as a mask that determines which companies have a rating. */
00133   CompanyMask have_ratings;
00134   uint8 unwanted[MAX_COMPANIES]; 
00135   CompanyByte exclusivity;       
00136   uint8 exclusive_counter;       
00137   int16 ratings[MAX_COMPANIES];
00138 
00139   /* Maximum amount of passengers and mail that can be transported. */
00140   uint32 max_pass;
00141   uint32 max_mail;
00142   uint32 new_max_pass;
00143   uint32 new_max_mail;
00144   uint32 act_pass;
00145   uint32 act_mail;
00146   uint32 new_act_pass;
00147   uint32 new_act_mail;
00148 
00149   /* Amount of passengers that were transported. */
00150   byte pct_pass_transported;
00151   byte pct_mail_transported;
00152 
00153   /* Amount of food and paper that was transported. Actually a bit mask would be enough. */
00154   uint16 act_food;
00155   uint16 act_water;
00156   uint16 new_act_food;
00157   uint16 new_act_water;
00158 
00159   /* Time until we rebuild a house. */
00160   uint16 time_until_rebuild;
00161 
00162   /* When to grow town next time. */
00163   uint16 grow_counter;
00164   int16 growth_rate;
00165 
00166   /* Fund buildings program in action? */
00167   byte fund_buildings_months;
00168 
00169   /* Fund road reconstruction in action? */
00170   byte road_build_months;
00171 
00172   /* If this is a larger town, and should grow more quickly. */
00173   bool larger_town;
00174   TownLayoutByte layout; 
00175 
00176   /* NOSAVE: UpdateTownRadius updates this given the house count. */
00177   uint32 squared_town_zone_radius[HZB_END];
00178 
00179   /* NOSAVE: The number of each type of building in the town. */
00180   BuildingCounts<uint16> building_counts;
00181 
00185   Town(TileIndex tile = INVALID_TILE);
00186 
00188   ~Town();
00189 
00190   inline bool IsValid() const { return this->xy != INVALID_TILE; }
00191 
00192   void InitializeLayout(TownLayout layout);
00193 
00200   inline uint16 MaxTownNoise() const
00201   {
00202     if (this->population == 0) return 0; // no population? no noise
00203 
00204     return ((this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3);
00205   }
00206 };
00207 
00208 struct HouseSpec {
00209   /* Standard properties */
00210   Year min_year;                     
00211   Year max_year;                     
00212   byte population;                   
00213   byte removal_cost;                 
00214   StringID building_name;            
00215   uint16 remove_rating_decrease;     
00216   byte mail_generation;              
00217   byte cargo_acceptance[3];          
00218   CargoID accepts_cargo[3];          
00219   BuildingFlags building_flags;      
00220   HouseZones building_availability;  
00221   bool enabled;                      
00222 
00223   /* NewHouses properties */
00224   HouseID substitute_id;             
00225   struct SpriteGroup *spritegroup;   
00226   HouseID override;                  
00227   uint16 callback_mask;              
00228   byte random_colour[4];             
00229   byte probability;                  
00230   HouseExtraFlags extra_flags;       
00231   HouseClassID class_id;             
00232   byte animation_frames;             
00233   byte animation_speed;              
00234   byte processing_time;              
00235   byte minimum_life;                 
00236 
00237   /* grf file related properties*/
00238   uint8 local_id;                    
00239   const struct GRFFile *grffile;     
00240 
00245   Money GetRemovalCost() const;
00246 
00247 };
00248 
00249 extern HouseSpec _house_specs[HOUSE_MAX];
00250 
00251 uint32 GetWorldPopulation();
00252 
00253 void UpdateTownVirtCoord(Town *t);
00254 void UpdateAllTownVirtCoords();
00255 void InitializeTown();
00256 void ShowTownViewWindow(TownID town);
00257 void ExpandTown(Town *t);
00258 Town *CreateRandomTown(uint attempts, TownSize size, bool city, TownLayout layout);
00259 
00260 enum {
00261   ROAD_REMOVE         = 0,
00262   UNMOVEABLE_REMOVE   = 1,
00263   TUNNELBRIDGE_REMOVE = 1,
00264   INDUSTRY_REMOVE     = 2
00265 };
00266 
00270 static const byte TOWN_GROWTH_FREQUENCY = 70;
00271 
00274 static const byte TOWN_HOUSE_COMPLETED = 3;
00275 
00282 enum {
00283   TOWN_IS_FUNDED      = 0,   
00284   TOWN_HAS_CHURCH     = 1,   
00285   TOWN_HAS_STADIUM    = 2    
00286 };
00287 
00288 bool CheckforTownRating(DoCommandFlag flags, Town *t, byte type);
00289 
00290 static inline HouseSpec *GetHouseSpecs(HouseID house_id)
00291 {
00292   assert(house_id < HOUSE_MAX);
00293   return &_house_specs[house_id];
00294 }
00295 
00296 TileIndexDiff GetHouseNorthPart(HouseID &house);
00297 
00303 static inline bool IsValidTownID(TownID index)
00304 {
00305   return index < GetTownPoolSize() && GetTown(index)->IsValid();
00306 }
00307 
00308 static inline TownID GetMaxTownIndex()
00309 {
00310   /* TODO - This isn't the real content of the function, but
00311    *  with the new pool-system this will be replaced with one that
00312    *  _really_ returns the highest index. Now it just returns
00313    *  the next safe value we are sure about everything is below.
00314    */
00315   return GetTownPoolSize() - 1;
00316 }
00317 
00318 static inline uint GetNumTowns()
00319 {
00320   extern uint _total_towns;
00321 
00322   return _total_towns;
00323 }
00324 
00328 static inline Town *GetRandomTown()
00329 {
00330   int num = RandomRange(GetNumTowns());
00331   TownID index = INVALID_TOWN;
00332 
00333   while (num >= 0) {
00334     num--;
00335 
00336     index++;
00337     /* Make sure we have a valid town */
00338     while (!IsValidTownID(index)) {
00339       index++;
00340       assert(index <= GetMaxTownIndex());
00341     }
00342   }
00343 
00344   return GetTown(index);
00345 }
00346 
00347 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
00348 
00349 #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())
00350 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
00351 
00352 extern Town *_cleared_town;
00353 extern int _cleared_town_rating;
00354 extern uint32 _cur_town_ctr;
00355 extern uint32 _cur_town_iter;
00356 
00357 void ResetHouses();
00358 
00359 void ClearTownHouse(Town *t, TileIndex tile);
00360 void UpdateTownMaxPass(Town *t);
00361 void UpdateTownRadius(Town *t);
00362 bool CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
00363 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00364 void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
00365 HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile);
00366 void SetTownRatingTestMode(bool mode);
00367 uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
00368 bool GenerateTowns(TownLayout layout);
00369 bool GenerateTownName(uint32 *townnameparts);
00370 
00378 static inline uint TileHash(uint x, uint y)
00379 {
00380   uint hash = x >> 4;
00381   hash ^= x >> 6;
00382   hash ^= y >> 4;
00383   hash -= y >> 6;
00384   return hash;
00385 }
00386 
00396 static inline uint TileHash2Bit(uint x, uint y)
00397 {
00398   return GB(TileHash(x, y), 0, 2);
00399 }
00400 
00401 #endif /* TOWN_H */

Generated on Mon May 11 15:48:08 2009 for OpenTTD by  doxygen 1.5.6