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
00206 enum TownFlags {
00207 TOWN_IS_FUNDED = 0,
00208 TOWN_HAS_CHURCH = 1,
00209 TOWN_HAS_STADIUM = 2
00210 };
00211
00212 CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type);
00213
00214
00215 TileIndexDiff GetHouseNorthPart(HouseID &house);
00216
00217 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX);
00218
00219 #define FOR_ALL_TOWNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Town, town_index, var, start)
00220 #define FOR_ALL_TOWNS(var) FOR_ALL_TOWNS_FROM(var, 0)
00221
00222 void ResetHouses();
00223
00224 void ClearTownHouse(Town *t, TileIndex tile);
00225 void UpdateTownMaxPass(Town *t);
00226 void UpdateTownRadius(Town *t);
00227 void UpdateTownCargos(Town *t);
00228 void UpdateTownCargoTotal(Town *t);
00229 CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
00230 Town *ClosestTownFromTile(TileIndex tile, uint threshold);
00231 void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
00232 HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile);
00233 void SetTownRatingTestMode(bool mode);
00234 uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t);
00235 bool GenerateTowns(TownLayout layout);
00236
00237
00239 enum TownActions {
00240 TACT_NONE = 0x00,
00241
00242 TACT_ADVERTISE_SMALL = 0x01,
00243 TACT_ADVERTISE_MEDIUM = 0x02,
00244 TACT_ADVERTISE_LARGE = 0x04,
00245 TACT_ROAD_REBUILD = 0x08,
00246 TACT_BUILD_STATUE = 0x10,
00247 TACT_FOUND_BUILDINGS = 0x20,
00248 TACT_BUY_RIGHTS = 0x40,
00249 TACT_BRIBE = 0x80,
00250
00251 TACT_COUNT = 8,
00252
00253 TACT_ADVERTISE = TACT_ADVERTISE_SMALL | TACT_ADVERTISE_MEDIUM | TACT_ADVERTISE_LARGE,
00254 TACT_CONSTRUCTION = TACT_ROAD_REBUILD | TACT_BUILD_STATUE | TACT_FOUND_BUILDINGS,
00255 TACT_FUNDS = TACT_BUY_RIGHTS | TACT_BRIBE,
00256 TACT_ALL = TACT_ADVERTISE | TACT_CONSTRUCTION | TACT_FUNDS,
00257 };
00258 DECLARE_ENUM_AS_BIT_SET(TownActions)
00259
00260 extern const byte _town_action_costs[TACT_COUNT];
00261 extern TownID _new_town_id;
00262
00263
00269 template <class T>
00270 void MakeDefaultName(T *obj)
00271 {
00272
00273 assert(obj->name == NULL || obj->town_cn == UINT16_MAX);
00274
00275 obj->town = ClosestTownFromTile(obj->xy, UINT_MAX);
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 uint32 used = 0;
00289 uint32 next = 0;
00290 uint32 idx = 0;
00291 uint32 cid = 0;
00292
00293 do {
00294 T *lobj = T::GetIfValid(cid);
00295
00296
00297 if (lobj != NULL && obj != lobj) {
00298
00299 if (lobj->town == obj->town && lobj->IsOfType(obj)) {
00300
00301 uint i = (uint)lobj->town_cn - next;
00302
00303 if (i < 32) {
00304 SetBit(used, i);
00305 if (i == 0) {
00306
00307
00308 do {
00309 used >>= 1;
00310 next++;
00311 } while (HasBit(used, 0));
00312
00313
00314
00315 idx = cid;
00316 }
00317 }
00318 }
00319 }
00320
00321 cid++;
00322 if (cid == T::GetPoolSize()) cid = 0;
00323 } while (cid != idx);
00324
00325 obj->town_cn = (uint16)next;
00326 }
00327
00328 #endif