00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef TOWN_H
00013 #define TOWN_H
00014
00015 #include "core/pool_type.hpp"
00016 #include "viewport_type.h"
00017 #include "command_type.h"
00018 #include "town_map.h"
00019 #include "subsidy_type.h"
00020 #include "cargodest_base.h"
00021 #include "tilematrix_type.hpp"
00022
00023 template <typename T>
00024 struct BuildingCounts {
00025 T id_count[HOUSE_MAX];
00026 T class_count[HOUSE_CLASS_MAX];
00027 };
00028
00029 typedef TileMatrix<uint32, 4> AcceptanceMatrix;
00030
00031 static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4;
00032 static const uint CUSTOM_TOWN_MAX_NUMBER = 5000;
00033
00034 static const uint INVALID_TOWN = 0xFFFF;
00035
00036 typedef Pool<Town, TownID, 64, 64000> TownPool;
00037 extern TownPool _town_pool;
00038
00040 struct Town : TownPool::PoolItem<&_town_pool>, CargoSourceSink {
00041 TileIndex xy;
00042 TileIndex xy_aligned;
00043
00044
00045 uint32 num_houses;
00046 uint32 population;
00047
00048
00049 uint32 townnamegrfid;
00050 uint16 townnametype;
00051 uint32 townnameparts;
00052 char *name;
00053
00054
00055 ViewportSign sign;
00056
00057
00058
00059
00060
00061 byte flags;
00062
00063
00064 uint16 noise_reached;
00065
00066
00067 CompanyMask statues;
00068
00069
00070 CompanyMask have_ratings;
00071 uint8 unwanted[MAX_COMPANIES];
00072 CompanyByte exclusivity;
00073 uint8 exclusive_counter;
00074 int16 ratings[MAX_COMPANIES];
00075
00076
00077 TransportedCargoStat pass;
00078 TransportedCargoStat mail;
00079
00080
00081 byte pct_pass_transported;
00082 byte pct_mail_transported;
00083
00084
00085 uint16 act_food;
00086 uint16 act_water;
00087 uint16 new_act_food;
00088 uint16 new_act_water;
00089
00090
00091 uint16 time_until_rebuild;
00092
00093
00094 uint16 grow_counter;
00095 int16 growth_rate;
00096
00097
00098 byte fund_buildings_months;
00099
00100
00101 byte road_build_months;
00102
00103
00104 bool larger_town;
00105 TownLayoutByte layout;
00106
00107
00108 uint32 cargo_produced;
00109 AcceptanceMatrix cargo_accepted;
00110 uint32 cargo_accepted_total;
00111 uint32 cargo_accepted_weights[NUM_CARGO];
00112 uint32 cargo_accepted_max_weight;
00113
00114 PartOfSubsidyByte part_of_subsidy;
00115
00116
00117 uint32 squared_town_zone_radius[HZB_END];
00118
00119 BuildingCounts<uint16> building_counts;
00120
00124 Town(TileIndex tile = INVALID_TILE) : xy(tile) { }
00125
00127 ~Town();
00128
00129 void InitializeLayout(TownLayout layout);
00130
00131 SourceType GetType() const
00132 {
00133 return ST_TOWN;
00134 }
00135
00136 SourceID GetID() const
00137 {
00138 return this->index;
00139 }
00140
00141 bool AcceptsCargo(CargoID cid) const
00142 {
00143 return HasBit(this->cargo_accepted_total, cid);
00144 }
00145
00146 bool SuppliesCargo(CargoID cid) const
00147 {
00148 return HasBit(this->cargo_produced, cid);
00149 }
00150
00151 uint GetDestinationWeight(CargoID cid, byte weight_mod) const;
00152 void CreateSpecialLinks(CargoID cid);
00153 TileArea GetTileForDestination(CargoID cid);
00154
00161 inline uint16 MaxTownNoise() const
00162 {
00163 if (this->population == 0) return 0;
00164
00165
00166 return (this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3;
00167 }
00168
00169 void UpdateVirtCoord();
00170
00171 static FORCEINLINE Town *GetByTile(TileIndex tile)
00172 {
00173 return Town::Get(GetTownIndex(tile));
00174 }
00175
00177 typedef bool (*EnumTownProc)(const Town *t, void *data);
00178
00179 static Town *GetRandom(EnumTownProc enum_proc = NULL, TownID skip = INVALID_TOWN, void *data = NULL);
00180 static void PostDestructor(size_t index);
00181 };
00182
00183 uint32 GetWorldPopulation();
00184
00185 void UpdateAllTownVirtCoords();
00186 void ShowTownViewWindow(TownID town);
00187 void ExpandTown(Town *t);
00188
00193 enum TownRatingCheckType {
00194 ROAD_REMOVE = 0,
00195 TUNNELBRIDGE_REMOVE = 1,
00196 TOWN_RATING_CHECK_TYPE_COUNT,
00197 };
00198
00204 static const byte TOWN_GROWTH_FREQUENCY = 70;
00205
00213 enum TownFlags {
00214 TOWN_IS_FUNDED = 0,
00215 TOWN_HAS_CHURCH = 1,
00216 TOWN_HAS_STADIUM = 2
00217 };
00218
00219 CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type);
00220
00221
00222 TileIndexDiff GetHouseNorthPart(HouseID &house);
00223
00224 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
00225
00226 #define FOR_ALL_TOWNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Town, town_index, var, start)
00227 #define FOR_ALL_TOWNS(var) FOR_ALL_TOWNS_FROM(var, 0)
00228
00229 void ResetHouses();
00230
00231 void ClearTownHouse(Town *t, TileIndex tile);
00232 void UpdateTownMaxPass(Town *t);
00233 void UpdateTownRadius(Town *t);
00234 void UpdateTownCargos(Town *t);
00235 void UpdateTownCargoTotal(Town *t);
00236 CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
00237 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00238 void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
00239 HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile);
00240 void SetTownRatingTestMode(bool mode);
00241 uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
00242 bool GenerateTowns(TownLayout layout);
00243
00244
00246 enum TownActions {
00247 TACT_NONE = 0x00,
00248
00249 TACT_ADVERTISE_SMALL = 0x01,
00250 TACT_ADVERTISE_MEDIUM = 0x02,
00251 TACT_ADVERTISE_LARGE = 0x04,
00252 TACT_ROAD_REBUILD = 0x08,
00253 TACT_BUILD_STATUE = 0x10,
00254 TACT_FOUND_BUILDINGS = 0x20,
00255 TACT_BUY_RIGHTS = 0x40,
00256 TACT_BRIBE = 0x80,
00257
00258 TACT_COUNT = 8,
00259
00260 TACT_ADVERTISE = TACT_ADVERTISE_SMALL | TACT_ADVERTISE_MEDIUM | TACT_ADVERTISE_LARGE,
00261 TACT_CONSTRUCTION = TACT_ROAD_REBUILD | TACT_BUILD_STATUE | TACT_FOUND_BUILDINGS,
00262 TACT_FUNDS = TACT_BUY_RIGHTS | TACT_BRIBE,
00263 TACT_ALL = TACT_ADVERTISE | TACT_CONSTRUCTION | TACT_FUNDS,
00264 };
00265 DECLARE_ENUM_AS_BIT_SET(TownActions)
00266
00267 extern const byte _town_action_costs[TACT_COUNT];
00268 extern TownID _new_town_id;
00269
00270
00276 template <class T>
00277 void MakeDefaultName(T *obj)
00278 {
00279
00280 assert(obj->name == NULL || obj->town_cn == UINT16_MAX);
00281
00282 obj->town = ClosestTownFromTile(obj->xy, UINT_MAX);
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 uint32 used = 0;
00296 uint32 next = 0;
00297 uint32 idx = 0;
00298 uint32 cid = 0;
00299
00300 do {
00301 T *lobj = T::GetIfValid(cid);
00302
00303
00304 if (lobj != NULL && obj != lobj) {
00305
00306 if (lobj->town == obj->town && lobj->IsOfType(obj)) {
00307
00308 uint i = (uint)lobj->town_cn - next;
00309
00310 if (i < 32) {
00311 SetBit(used, i);
00312 if (i == 0) {
00313
00314
00315 do {
00316 used >>= 1;
00317 next++;
00318 } while (HasBit(used, 0));
00319
00320
00321
00322 idx = cid;
00323 }
00324 }
00325 }
00326 }
00327
00328 cid++;
00329 if (cid == T::GetPoolSize()) cid = 0;
00330 } while (cid != idx);
00331
00332 obj->town_cn = (uint16)next;
00333 }
00334
00335 #endif