2009-08-21 20:21:05 +00:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-05-06 15:11:33 +00:00
/** @file town.h Base of the town class. */
2007-04-04 03:21:14 +00:00
2004-08-09 17:04:08 +00:00
# ifndef TOWN_H
# define TOWN_H
2008-05-07 13:10:15 +00:00
# include "viewport_type.h"
2009-06-26 13:44:14 +00:00
# include "town_map.h"
2009-08-08 16:42:55 +00:00
# include "subsidy_type.h"
2011-06-12 20:49:07 +00:00
# include "newgrf_storage.h"
2011-11-23 16:05:19 +00:00
# include "cargotype.h"
2015-08-05 23:19:35 +00:00
# include "openttd.h"
# include "table/strings.h"
# include "company_func.h"
2020-05-21 22:50:48 +00:00
# include "core/tinystring_type.hpp"
2011-06-12 20:49:07 +00:00
# include <list>
2019-05-12 17:03:57 +00:00
# include <memory>
2007-03-19 11:27:30 +00:00
2009-03-17 19:40:10 +00:00
template < typename T >
2007-03-19 11:27:30 +00:00
struct BuildingCounts {
2013-10-12 16:33:19 +00:00
T id_count [ NUM_HOUSES ] ;
2009-03-17 19:40:10 +00:00
T class_count [ HOUSE_CLASS_MAX ] ;
2006-12-09 14:18:08 +00:00
} ;
2009-03-13 00:48:03 +00:00
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4 ; ///< value for custom town number in difficulty settings
static const uint CUSTOM_TOWN_MAX_NUMBER = 5000 ; ///< this is the maximum number of towns a user can specify in customisation
2009-03-12 23:54:20 +00:00
2019-01-12 23:20:10 +00:00
static const TownID INVALID_TOWN = 0xFFFF ;
2009-06-26 13:44:14 +00:00
2011-11-23 16:07:14 +00:00
static const uint TOWN_GROWTH_WINTER = 0xFFFFFFFE ; ///< The town only needs this cargo in the winter (any amount)
static const uint TOWN_GROWTH_DESERT = 0xFFFFFFFF ; ///< The town needs the cargo for growth when on desert (any amount)
2018-05-02 19:01:30 +00:00
static const uint16 TOWN_GROWTH_RATE_NONE = 0xFFFF ; ///< Special value for Town::growth_rate to disable town growth.
2019-09-29 20:27:32 +00:00
static const uint16 MAX_TOWN_GROWTH_TICKS = 930 ; ///< Max amount of original town ticks that still fit into uint16, about equal to UINT16_MAX / TOWN_GROWTH_TICKS but slightly less to simplify calculations
2011-11-23 16:07:14 +00:00
2020-08-27 05:05:59 +00:00
static const byte TOWN_COUNCIL_INDIFFERENT = 0xFF ;
2009-05-22 15:13:50 +00:00
typedef Pool < Town , TownID , 64 , 64000 > TownPool ;
extern TownPool _town_pool ;
2007-08-02 21:05:54 +00:00
2012-04-25 20:50:13 +00:00
/** Data structure with cached data of towns. */
struct TownCache {
uint32 num_houses ; ///< Amount of houses
uint32 population ; ///< Current population of people
2019-12-01 22:17:33 +00:00
TrackedViewportSign sign ; ///< Location of name sign, UpdateVirtCoord updates this
2019-04-22 09:53:40 +00:00
PartOfSubsidy part_of_subsidy ; ///< Is this town a source/destination of a subsidy?
2012-04-25 20:50:13 +00:00
uint32 squared_town_zone_radius [ HZB_END ] ; ///< UpdateTownRadius updates this given the house count
BuildingCounts < uint16 > building_counts ; ///< The number of each type of building in the town
} ;
2010-08-01 17:45:53 +00:00
/** Town data structure. */
2009-05-22 15:13:50 +00:00
struct Town : TownPool : : PoolItem < & _town_pool > {
2011-09-04 09:06:07 +00:00
TileIndex xy ; ///< town center tile
2004-08-09 17:04:08 +00:00
2012-04-25 20:50:13 +00:00
TownCache cache ; ///< Container for all cacheable data.
2004-09-10 19:02:27 +00:00
2007-04-04 03:21:14 +00:00
/* Town name */
2007-06-18 23:00:55 +00:00
uint32 townnamegrfid ;
2004-08-09 17:04:08 +00:00
uint16 townnametype ;
uint32 townnameparts ;
2020-05-21 22:50:48 +00:00
TinyString name ; ///< Custom town name. If empty, the town was not renamed and uses the generated name.
2020-01-06 20:40:31 +00:00
mutable std : : string cached_name ; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name
2004-09-10 19:02:27 +00:00
2013-10-06 10:16:33 +00:00
byte flags ; ///< See #TownFlags.
2020-08-03 19:21:02 +00:00
uint16 church_count ; ///< Number of church buildings in the town.
uint16 stadium_count ; ///< Number of stadium buildings in the town.
2004-08-09 17:04:08 +00:00
2011-09-04 09:06:07 +00:00
uint16 noise_reached ; ///< level of noise that all the airports are generating
2008-05-24 02:54:47 +00:00
2011-09-04 09:06:07 +00:00
CompanyMask statues ; ///< which companies have a statue?
2004-08-09 17:04:08 +00:00
2011-09-04 09:06:07 +00:00
/* Company ratings. */
CompanyMask have_ratings ; ///< which companies have a rating
2008-09-30 20:39:50 +00:00
uint8 unwanted [ MAX_COMPANIES ] ; ///< how many months companies aren't wanted by towns (bribe)
2019-04-22 08:10:04 +00:00
CompanyID exclusivity ; ///< which company has exclusivity
2008-09-30 20:39:50 +00:00
uint8 exclusive_counter ; ///< months till the exclusivity expires
2011-09-04 09:06:07 +00:00
int16 ratings [ MAX_COMPANIES ] ; ///< ratings of each company for this town
2015-08-05 23:19:35 +00:00
StringID town_label ; ///< Label dependent on _local_company rating.
2004-09-10 19:02:27 +00:00
2011-11-23 16:05:19 +00:00
TransportedCargoStat < uint32 > supplied [ NUM_CARGO ] ; ///< Cargo statistics about supplied cargo.
TransportedCargoStat < uint16 > received [ NUM_TE ] ; ///< Cargo statistics about received cargotypes.
2011-11-23 16:07:14 +00:00
uint32 goal [ NUM_TE ] ; ///< Amount of cargo required for the town to grow.
2004-08-09 17:04:08 +00:00
2020-05-17 21:31:59 +00:00
std : : string text ; ///< General text with additional information.
2011-12-19 21:00:55 +00:00
2011-11-23 16:05:19 +00:00
inline byte GetPercentTransported ( CargoID cid ) const { return this - > supplied [ cid ] . old_act * 256 / ( this - > supplied [ cid ] . old_max + 1 ) ; }
2004-09-10 19:02:27 +00:00
2019-02-14 21:07:15 +00:00
StationList stations_near ; ///< NOSAVE: List of nearby stations.
2011-12-03 22:21:27 +00:00
2019-04-21 21:56:35 +00:00
uint16 time_until_rebuild ; ///< time until we rebuild a house
2004-08-09 17:04:08 +00:00
2019-04-21 21:56:35 +00:00
uint16 grow_counter ; ///< counter to count when to grow, value is smaller than or equal to growth_rate
uint16 growth_rate ; ///< town growth rate
2004-08-09 17:04:08 +00:00
2019-04-21 21:56:35 +00:00
byte fund_buildings_months ; ///< fund buildings program in action?
byte road_build_months ; ///< fund road reconstruction in action?
2004-09-10 19:02:27 +00:00
2019-04-21 21:56:35 +00:00
bool larger_town ; ///< if this is a larger town and should grow more quickly
TownLayout layout ; ///< town specific road layout
2007-04-18 14:23:30 +00:00
2019-01-05 13:22:07 +00:00
bool show_zone ; ///< NOSAVE: mark town to show the local authority zone in the viewports
2011-06-12 20:49:07 +00:00
std : : list < PersistentStorage * > psa_list ;
2007-08-02 21:05:54 +00:00
/**
2011-09-04 09:06:07 +00:00
* Creates a new town .
* @ param tile center tile of the town
2007-08-02 21:05:54 +00:00
*/
2009-05-22 15:13:50 +00:00
Town ( TileIndex tile = INVALID_TILE ) : xy ( tile ) { }
2007-08-02 21:05:54 +00:00
2011-09-04 09:06:07 +00:00
/** Destroy the town. */
2007-08-02 21:05:54 +00:00
~ Town ( ) ;
2009-02-04 22:52:34 +00:00
void InitializeLayout ( TownLayout layout ) ;
2008-04-01 16:27:01 +00:00
2015-08-05 23:19:35 +00:00
void UpdateLabel ( ) ;
/**
* Returns the correct town label , based on rating .
*/
inline StringID Label ( ) const {
if ( ! ( _game_mode = = GM_EDITOR ) & & ( _local_company < MAX_COMPANIES ) ) {
2019-03-13 18:41:44 +00:00
return ( _settings_client . gui . population_in_label ? STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING : STR_VIEWPORT_TOWN_VERY_POOR_RATING ) + this - > town_label ;
2015-08-05 23:19:35 +00:00
} else {
return _settings_client . gui . population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN ;
}
}
/**
* Returns the correct town small label , based on rating .
*/
inline StringID SmallLabel ( ) const {
if ( ! ( _game_mode = = GM_EDITOR ) & & ( _local_company < MAX_COMPANIES ) ) {
return STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING + this - > town_label ;
} else {
return STR_VIEWPORT_TOWN_TINY_WHITE ;
}
}
2010-08-01 17:45:53 +00:00
/**
* Calculate the max town noise .
2008-05-24 02:54:47 +00:00
* The value is counted using the population divided by the content of the
2010-08-01 17:45:53 +00:00
* entry in town_noise_population corresponding to the town ' s tolerance .
* @ return the maximum noise level the town will tolerate .
*/
2009-02-04 20:17:25 +00:00
inline uint16 MaxTownNoise ( ) const
{
2021-06-16 19:31:38 +00:00
if ( _settings_game . difficulty . town_council_tolerance = = TOWN_COUNCIL_INDIFFERENT ) return UINT16_MAX ;
if ( this - > cache . population = = 0 ) return 0 ; // no population? no noise
2008-05-24 02:54:47 +00:00
2010-08-01 17:45:53 +00:00
/* 3 is added (the noise of the lowest airport), so the user can at least build a small airfield. */
2012-04-25 20:50:13 +00:00
return ( this - > cache . population / _settings_game . economy . town_noise_population [ _settings_game . difficulty . town_council_tolerance ] ) + 3 ;
2008-05-24 02:54:47 +00:00
}
2004-08-09 17:04:08 +00:00
2009-07-13 22:33:25 +00:00
void UpdateVirtCoord ( ) ;
2019-05-12 17:03:57 +00:00
inline const char * GetCachedName ( ) const
{
2020-05-17 21:31:59 +00:00
if ( ! this - > name . empty ( ) ) return this - > name . c_str ( ) ;
2020-01-06 20:40:31 +00:00
if ( this - > cached_name . empty ( ) ) this - > FillCachedName ( ) ;
return this - > cached_name . c_str ( ) ;
2019-05-12 17:03:57 +00:00
}
2011-12-20 17:57:56 +00:00
static inline Town * GetByTile ( TileIndex tile )
2009-06-26 13:46:23 +00:00
{
return Town : : Get ( GetTownIndex ( tile ) ) ;
}
2009-06-26 15:08:54 +00:00
static Town * GetRandom ( ) ;
2009-07-05 13:21:51 +00:00
static void PostDestructor ( size_t index ) ;
2019-05-12 17:03:57 +00:00
2020-01-06 20:40:31 +00:00
private :
void FillCachedName ( ) const ;
2009-06-26 13:46:23 +00:00
} ;
2007-03-19 11:27:30 +00:00
2007-03-07 11:47:46 +00:00
uint32 GetWorldPopulation ( ) ;
2004-08-09 17:04:08 +00:00
2007-11-25 20:20:16 +00:00
void UpdateAllTownVirtCoords ( ) ;
2019-05-12 17:03:57 +00:00
void ClearAllTownCachedNames ( ) ;
2006-03-26 22:41:56 +00:00
void ShowTownViewWindow ( TownID town ) ;
2004-08-09 17:04:08 +00:00
void ExpandTown ( Town * t ) ;
2019-02-18 16:32:53 +00:00
void RebuildTownKdtree ( ) ;
2010-08-01 19:22:34 +00:00
/**
* Action types that a company must ask permission for to a town authority .
2010-03-13 15:13:19 +00:00
* @ see CheckforTownRating
*/
2009-05-11 11:55:41 +00:00
enum TownRatingCheckType {
2010-03-13 15:13:19 +00:00
ROAD_REMOVE = 0 , ///< Removal of a road owned by the town.
TUNNELBRIDGE_REMOVE = 1 , ///< Removal of a tunnel or bridge owned by the towb.
TOWN_RATING_CHECK_TYPE_COUNT , ///< Number of town checking action types.
2004-08-09 17:04:08 +00:00
} ;
2019-07-22 19:27:39 +00:00
/** Special values for town list window for the data parameter of #InvalidateWindowData. */
enum TownDirectoryInvalidateWindowData {
TDIWD_FORCE_REBUILD ,
2020-01-06 20:19:50 +00:00
TDIWD_POPULATION_CHANGE ,
2020-01-05 21:55:57 +00:00
TDIWD_FORCE_RESORT ,
2019-07-22 19:27:39 +00:00
} ;
2010-08-01 19:22:34 +00:00
/**
2010-08-02 20:47:27 +00:00
* This enum is used in conjunction with town - > flags .
2006-04-03 14:56:07 +00:00
* IT simply states what bit is used for .
* It is pretty unrealistic ( IMHO ) to only have one church / stadium
* per town , NO MATTER the population of it .
2009-06-23 09:52:26 +00:00
* And there are 5 more bits available on flags . . .
2006-04-03 14:56:07 +00:00
*/
2010-05-13 09:44:44 +00:00
enum TownFlags {
2013-10-28 10:55:34 +00:00
TOWN_IS_GROWING = 0 , ///< Conditions for town growth are met. Grow according to Town::growth_rate.
2020-08-03 17:46:52 +00:00
// TOWN_HAS_CHURCH = 1, ///< There can be only one church per town. Replaced by church_count.
// TOWN_HAS_STADIUM = 2, ///< There can be only one stadium per town. Replaced by stadium_count.
2018-05-02 19:01:30 +00:00
TOWN_CUSTOM_GROWTH = 3 , ///< Growth rate is controlled by GS.
2005-01-14 09:20:12 +00:00
} ;
2010-03-13 15:33:07 +00:00
CommandCost CheckforTownRating ( DoCommandFlag flags , Town * t , TownRatingCheckType type ) ;
2004-08-09 17:04:08 +00:00
2007-03-19 11:27:30 +00:00
2016-05-12 21:35:39 +00:00
TileIndexDiff GetHouseNorthPart ( HouseID & house ) ;
2008-06-25 20:04:27 +00:00
2009-07-05 13:21:51 +00:00
Town * CalcClosestTownFromTile ( TileIndex tile , uint threshold = UINT_MAX ) ;
2007-02-09 16:21:03 +00:00
2007-03-19 11:27:30 +00:00
void ResetHouses ( ) ;
void ClearTownHouse ( Town * t , TileIndex tile ) ;
2007-12-25 11:26:07 +00:00
void UpdateTownMaxPass ( Town * t ) ;
2008-03-18 12:28:21 +00:00
void UpdateTownRadius ( Town * t ) ;
2010-02-27 17:42:55 +00:00
CommandCost CheckIfAuthorityAllowsNewStation ( TileIndex tile , DoCommandFlag flags ) ;
2007-12-25 11:26:07 +00:00
Town * ClosestTownFromTile ( TileIndex tile , uint threshold ) ;
2009-02-11 18:50:47 +00:00
void ChangeTownRating ( Town * t , int add , int max , DoCommandFlag flags ) ;
2016-05-12 21:35:39 +00:00
HouseZonesBits TryGetTownRadiusGroup ( const Town * t , TileIndex tile ) ;
2009-01-10 00:31:47 +00:00
HouseZonesBits GetTownRadiusGroup ( const Town * t , TileIndex tile ) ;
2008-01-09 17:47:05 +00:00
void SetTownRatingTestMode ( bool mode ) ;
2009-01-19 12:07:01 +00:00
uint GetMaskOfTownActions ( int * nump , CompanyID cid , const Town * t ) ;
2009-02-04 22:52:34 +00:00
bool GenerateTowns ( TownLayout layout ) ;
2011-11-23 16:07:14 +00:00
const CargoSpec * FindFirstCargoWithTownEffect ( TownEffect effect ) ;
2007-03-19 11:27:30 +00:00
2009-09-20 10:08:10 +00:00
/** Town actions of a company. */
enum TownActions {
TACT_NONE = 0x00 , ///< Empty action set.
TACT_ADVERTISE_SMALL = 0x01 , ///< Small advertising campaign.
TACT_ADVERTISE_MEDIUM = 0x02 , ///< Medium advertising campaign.
TACT_ADVERTISE_LARGE = 0x04 , ///< Large advertising campaign.
TACT_ROAD_REBUILD = 0x08 , ///< Rebuild the roads.
TACT_BUILD_STATUE = 0x10 , ///< Build a statue.
2011-11-23 13:42:23 +00:00
TACT_FUND_BUILDINGS = 0x20 , ///< Fund new buildings.
2009-09-20 10:08:10 +00:00
TACT_BUY_RIGHTS = 0x40 , ///< Buy exclusive transport rights.
2013-01-08 22:46:42 +00:00
TACT_BRIBE = 0x80 , ///< Try to bribe the council.
2009-09-20 10:08:10 +00:00
TACT_COUNT = 8 , ///< Number of available town actions.
TACT_ADVERTISE = TACT_ADVERTISE_SMALL | TACT_ADVERTISE_MEDIUM | TACT_ADVERTISE_LARGE , ///< All possible advertising actions.
2011-11-23 13:42:23 +00:00
TACT_CONSTRUCTION = TACT_ROAD_REBUILD | TACT_BUILD_STATUE | TACT_FUND_BUILDINGS , ///< All possible construction actions.
2009-09-20 10:08:10 +00:00
TACT_FUNDS = TACT_BUY_RIGHTS | TACT_BRIBE , ///< All possible funding actions.
TACT_ALL = TACT_ADVERTISE | TACT_CONSTRUCTION | TACT_FUNDS , ///< All possible actions.
} ;
2010-03-23 22:25:43 +00:00
DECLARE_ENUM_AS_BIT_SET ( TownActions )
2009-09-20 10:08:10 +00:00
extern const byte _town_action_costs [ TACT_COUNT ] ;
2009-09-21 20:22:56 +00:00
extern TownID _new_town_id ;
2009-09-20 10:08:10 +00:00
2010-05-12 18:31:39 +00:00
/**
* Set the default name for a depot / waypoint
* @ tparam T The type / class to make a default name for
* @ param obj The object / instance we want to find the name for
*/
template < class T >
void MakeDefaultName ( T * obj )
{
2010-09-16 16:31:57 +00:00
/* We only want to set names if it hasn't been set before, or when we're calling from afterload. */
2020-05-17 21:31:59 +00:00
assert ( obj - > name . empty ( ) | | obj - > town_cn = = UINT16_MAX ) ;
2010-05-12 18:31:39 +00:00
obj - > town = ClosestTownFromTile ( obj - > xy , UINT_MAX ) ;
/* Find first unused number belonging to this town. This can never fail,
* as long as there can be at most 65535 waypoints / depots in total .
*
* This does ' n * m ' search , but with 32 bit ' used ' bitmap , it needs at
* most ' n * ( 1 + ceil ( m / 32 ) ) ' steps ( n - number of waypoints in pool ,
* m - number of waypoints near this town ) .
* Usually , it needs only ' n ' steps .
*
* If it wasn ' t using ' used ' and ' idx ' , it would just search for increasing ' next ' ,
* but this way it is faster */
uint32 used = 0 ; // bitmap of used waypoint numbers, sliding window with 'next' as base
uint32 next = 0 ; // first number in the bitmap
uint32 idx = 0 ; // index where we will stop
uint32 cid = 0 ; // current index, goes to T::GetPoolSize()-1, then wraps to 0
do {
T * lobj = T : : GetIfValid ( cid ) ;
/* check only valid waypoints... */
2019-04-10 21:07:06 +00:00
if ( lobj ! = nullptr & & obj ! = lobj ) {
2010-09-16 16:31:57 +00:00
/* only objects within the same city and with the same type */
if ( lobj - > town = = obj - > town & & lobj - > IsOfType ( obj ) ) {
2010-05-12 18:31:39 +00:00
/* if lobj->town_cn < next, uint will overflow to '+inf' */
uint i = ( uint ) lobj - > town_cn - next ;
if ( i < 32 ) {
SetBit ( used , i ) ; // update bitmap
if ( i = = 0 ) {
/* shift bitmap while the lowest bit is '1';
* increase the base of the bitmap too */
do {
used > > = 1 ;
next + + ;
} while ( HasBit ( used , 0 ) ) ;
/* when we are at 'idx' again at end of the loop and
* ' next ' hasn ' t changed , then no object had town_cn = = next ,
* so we can safely use it */
idx = cid ;
}
}
}
}
cid + + ;
if ( cid = = T : : GetPoolSize ( ) ) cid = 0 ; // wrap to zero...
} while ( cid ! = idx ) ;
obj - > town_cn = ( uint16 ) next ; // set index...
}
2018-05-02 19:01:30 +00:00
/*
* Converts original town ticks counters to plain game ticks . Note that
* tick 0 is a valid tick so actual amount is one more than the counter value .
*/
static inline uint16 TownTicksToGameTicks ( uint16 ticks ) {
2021-01-08 10:16:18 +00:00
return ( std : : min ( ticks , MAX_TOWN_GROWTH_TICKS ) + 1 ) * TOWN_GROWTH_TICKS - 1 ;
2018-05-02 19:01:30 +00:00
}
2019-04-06 06:46:15 +00:00
RoadType GetTownRoadType ( const Town * t ) ;
2020-10-16 21:12:57 +00:00
bool MayTownModifyRoad ( TileIndex tile ) ;
2019-04-06 06:46:15 +00:00
2004-08-09 17:04:08 +00:00
# endif /* TOWN_H */