/* $Id$ */ #ifndef TOWN_H #define TOWN_H #include "oldpool.h" #include "player.h" enum { INVALID_TOWN = 0xFFFF, }; struct Town { TileIndex xy; // Current population of people and amount of houses. uint16 num_houses; uint32 population; // Town name uint16 townnametype; uint32 townnameparts; // NOSAVE: Location of name sign, UpdateTownVirtCoord updates this. ViewportSign sign; // Makes sure we don't build certain house types twice. // bit 0 = Building funds received // bit 1 = CHURCH // bit 2 = STADIUM byte flags12; // Which players have a statue? byte statues; // Player ratings as well as a mask that determines which players have a rating. byte have_ratings; uint8 unwanted[MAX_PLAYERS]; // how many months companies aren't wanted by towns (bribe) PlayerByte exclusivity; // which player has exslusivity uint8 exclusive_counter; // months till the exclusivity expires int16 ratings[MAX_PLAYERS]; // Maximum amount of passengers and mail that can be transported. uint32 max_pass; uint32 max_mail; uint32 new_max_pass; uint32 new_max_mail; uint32 act_pass; uint32 act_mail; uint32 new_act_pass; uint32 new_act_mail; // Amount of passengers that were transported. byte pct_pass_transported; byte pct_mail_transported; // Amount of food and paper that was transported. Actually a bit mask would be enough. uint16 act_food; uint16 act_water; uint16 new_act_food; uint16 new_act_water; // Time until we rebuild a house. byte time_until_rebuild; // When to grow town next time. byte grow_counter; byte growth_rate; // Fund buildings program in action? byte fund_buildings_months; // Fund road reconstruction in action? byte road_build_months; // Index in town array TownID index; // NOSAVE: UpdateTownRadius updates this given the house count. uint16 radius[5]; }; uint32 GetWorldPopulation(void); void UpdateTownVirtCoord(Town *t); void InitializeTown(void); void ShowTownViewWindow(TownID town); void ExpandTown(Town *t); Town *CreateRandomTown(uint attempts, uint size_mode); enum { ROAD_REMOVE = 0, UNMOVEABLE_REMOVE = 1, TUNNELBRIDGE_REMOVE = 1, INDUSTRY_REMOVE = 2 }; enum { // These refer to the maximums, so Appalling is -1000 to -400 // MAXIMUM RATINGS BOUNDARIES RATING_MINIMUM = -1000, RATING_APPALLING = -400, RATING_VERYPOOR = -200, RATING_POOR = 0, RATING_MEDIOCRE = 200, RATING_GOOD = 400, RATING_VERYGOOD = 600, RATING_EXCELLENT = 800, RATING_OUTSTANDING = 1000, // OUTSTANDING RATING_MAXIMUM = RATING_OUTSTANDING, // RATINGS AFFECTING NUMBERS RATING_TREE_DOWN_STEP = -35, RATING_TREE_MINIMUM = RATING_MINIMUM, RATING_TREE_UP_STEP = 7, RATING_TREE_MAXIMUM = 220, RATING_TUNNEL_BRIDGE_DOWN_STEP = -250, RATING_TUNNEL_BRIDGE_MINIMUM = 0, RATING_INDUSTRY_DOWN_STEP = -1500, RATING_INDUSTRY_MINIMUM = RATING_MINIMUM, RATING_ROAD_DOWN_STEP = -50, RATING_ROAD_MINIMUM = -100, RATING_HOUSE_MINIMUM = RATING_MINIMUM, RATING_BRIBE_UP_STEP = 200, RATING_BRIBE_MAXIMUM = 800, RATING_BRIBE_DOWN_TO = -50 // XXX SHOULD BE SOMETHING LOWER? }; enum { /* This is the base "normal" number of towns on the 8x8 map, when * one town should get grown per tick. The other numbers of towns * are then scaled based on that. */ TOWN_GROWTH_FREQUENCY = 23, /* Simple value that indicates the house has reached final stage of construction*/ TOWN_HOUSE_COMPLETED = 3, }; /* This enum is used in conjonction with town->flags12. * 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. * And there are 5 more bits available on flags12... */ enum { TOWN_IS_FUNDED = 0, // Town has received some funds for TOWN_HAS_CHURCH = 1, // There can be only one church by town. TOWN_HAS_STADIUM = 2 // There can be only one stadium by town. }; bool CheckforTownRating(uint32 flags, Town *t, byte type); VARDEF const Town** _town_sort; DECLARE_OLD_POOL(Town, Town, 3, 8000) /** * Check if a Town really exists. */ static inline bool IsValidTown(const Town* town) { return town->xy != 0; } static inline bool IsValidTownID(TownID index) { return index < GetTownPoolSize() && IsValidTown(GetTown(index)); } VARDEF uint _total_towns; static inline TownID GetMaxTownIndex(void) { /* TODO - This isn't the real content of the function, but * with the new pool-system this will be replaced with one that * _really_ returns the highest index. Now it just returns * the next safe value we are sure about everything is below. */ return GetTownPoolSize() - 1; } static inline uint GetNumTowns(void) { return _total_towns; } /** * Return a random valid town. */ static inline Town *GetRandomTown(void) { int num = RandomRange(GetNumTowns()); TownID index = INVALID_TOWN; while (num >= 0) { num--; index++; /* Make sure we have a valid industry */ while (!IsValidTownID(index)) { index++; assert(index <= GetMaxTownIndex()); } } return GetTown(index); } void DestroyTown(Town *t); static inline void DeleteTown(Town *t) { DestroyTown(t); t->xy = 0; } #define FOR_ALL_TOWNS_FROM(t, start) for (t = GetTown(start); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) if (IsValidTown(t)) #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0) VARDEF bool _town_sort_dirty; VARDEF byte _town_sort_order; VARDEF Town *_cleared_town; VARDEF int _cleared_town_rating; #endif /* TOWN_H */