# town.h

Go to the documentation of this file.

    00001 /* $Id: town.h 12381 2008-03-18 12:28:21Z skidd13 $ */
    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   /* There can only be as many classes as there are new houses, plus one for
    00025    * NO_CLASS, as the original houses don't have classes. */
    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   /* Current population of people and amount of houses. */
    00093   uint32 num_houses;
    00094   uint32 population;
    00095
    00096   /* Town name */
    00097   uint32 townnamegrfid;
    00098   uint16 townnametype;
    00099   uint32 townnameparts;
    00100   char *name;
    00101
    00102   /* NOSAVE: Location of name sign, UpdateTownVirtCoord updates this. */
    00103   ViewportSign sign;
    00104
    00105   /* Makes sure we don't build certain house types twice.
    00106    * bit 0 = Building funds received
    00107    * bit 1 = CHURCH
    00108    * bit 2 = STADIUM */
    00109   byte flags12;
    00110
    00111   /* Which players have a statue? */
    00112   byte statues;
    00113
    00114   /* Player ratings as well as a mask that determines which players have a rating. */
    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   /* Maximum amount of passengers and mail that can be transported. */
    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   /* Amount of passengers that were transported. */
    00133   byte pct_pass_transported;
    00134   byte pct_mail_transported;
    00135
    00136   /* Amount of food and paper that was transported. Actually a bit mask would be enough. */
    00137   uint16 act_food;
    00138   uint16 act_water;
    00139   uint16 new_act_food;
    00140   uint16 new_act_water;
    00141
    00142   /* Time until we rebuild a house. */
    00143   uint16 time_until_rebuild;
    00144
    00145   /* When to grow town next time. */
    00146   uint16 grow_counter;
    00147   int16 growth_rate;
    00148
    00149   /* Fund buildings program in action? */
    00150   byte fund_buildings_months;
    00151
    00152   /* Fund road reconstruction in action? */
    00153   byte road_build_months;
    00154
    00155   /* If this is a larger town, and should grow more quickly. */
    00156   bool larger_town;
    00157
    00158   /* NOSAVE: UpdateTownRadius updates this given the house count. */
    00159   uint16 radius[5];
    00160
    00161   /* NOSAVE: The number of each type of building in the town. */
    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   /* Standard properties */
    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   /* NewHouses properties */
    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   /* grf file related properties*/
    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   /* TODO - This isn't the real content of the function, but
    00269    *  with the new pool-system this will be replaced with one that
    00270    *  _really_ returns the highest index. Now it just returns
    00271    *  the next safe value we are sure about everything is below.
    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     /* Make sure we have a valid town */
    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 /* TOWN_H */