diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lang/english.txt | 9 | ||||
-rw-r--r-- | src/saveload/oldloader_sl.cpp | 2 | ||||
-rw-r--r-- | src/saveload/town_sl.cpp | 6 | ||||
-rw-r--r-- | src/town.h | 7 | ||||
-rw-r--r-- | src/town_cmd.cpp | 67 | ||||
-rw-r--r-- | src/town_gui.cpp | 110 |
6 files changed, 122 insertions, 79 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt index 119535d6c..144c75ad4 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2573,9 +2573,14 @@ STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populati STR_TOWN_VIEW_PASSENGERS_LAST_MONTH_MAX :{BLACK}Passengers last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX :{BLACK}Mail last month: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Cargo needed for town growth: -STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED :{ORANGE}{STRING}{BLACK} required +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} required STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} required in winter -STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_LAST_MONTH :{ORANGE}{CARGO_LONG}{BLACK} delivered last month +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} delivered +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{RED} (still required) +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED :{ORANGE}{CARGO_TINY} / {CARGO_LONG}{GREEN} (delivered) +STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK} day{P "" s} +STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK} day{P "" s} (funded) +STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Town is {RED}not{BLACK} growing STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centre the main view on town location. Ctrl+Click opens a new viewport on town location STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Local authority diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 04790f1bd..2f0bfead6 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -566,7 +566,7 @@ static const OldChunks town_chunk[] = { OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ), OCL_NULL( 2 ), ///< num_houses, no longer in use OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, time_until_rebuild ), - OCL_SVAR( OC_FILE_U8 | OC_VAR_I16, Town, growth_rate ), + OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Town, growth_rate ), OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_PASSENGERS].new_max ), OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, supplied[CT_MAIL].new_max ), diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 1c51cc703..c88754ca8 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -153,13 +153,17 @@ static const SaveLoad _town_desc[] = { SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, 0, 164), SLE_CONDVAR(Town, received[TE_WATER].new_act, SLE_UINT16, 0, 164), + SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TE, 165, SL_MAX_VERSION), + SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, 0, 53), SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, 0, 53), SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, 0, 53), SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, 54, SL_MAX_VERSION), SLE_CONDVAR(Town, grow_counter, SLE_UINT16, 54, SL_MAX_VERSION), - SLE_CONDVAR(Town, growth_rate, SLE_INT16, 54, SL_MAX_VERSION), + + SLE_CONDVAR(Town, growth_rate, SLE_FILE_I16 | SLE_VAR_U16, 54, 164), + SLE_CONDVAR(Town, growth_rate, SLE_UINT16, 165, SL_MAX_VERSION), SLE_VAR(Town, fund_buildings_months, SLE_UINT8), SLE_VAR(Town, road_build_months, SLE_UINT8), diff --git a/src/town.h b/src/town.h index c56b6d3de..c0c356735 100644 --- a/src/town.h +++ b/src/town.h @@ -32,6 +32,9 @@ static const uint CUSTOM_TOWN_MAX_NUMBER = 5000; ///< this is the maximum numbe static const uint INVALID_TOWN = 0xFFFF; +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) + typedef Pool<Town, TownID, 64, 64000> TownPool; extern TownPool _town_pool; @@ -69,13 +72,14 @@ struct Town : TownPool::PoolItem<&_town_pool> { TransportedCargoStat<uint32> supplied[NUM_CARGO]; ///< Cargo statistics about supplied cargo. TransportedCargoStat<uint16> received[NUM_TE]; ///< Cargo statistics about received cargotypes. + uint32 goal[NUM_TE]; ///< Amount of cargo required for the town to grow. inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); } uint16 time_until_rebuild; ///< time until we rebuild a house uint16 grow_counter; ///< counter to count when to grow - int16 growth_rate; ///< town growth rate + uint16 growth_rate; ///< town growth rate byte fund_buildings_months; ///< fund buildings program in action? byte road_build_months; ///< fund road reconstruction in action? @@ -178,6 +182,7 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile); void SetTownRatingTestMode(bool mode); uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t); bool GenerateTowns(TownLayout layout); +const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect); /** Town actions of a company. */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 6774292a9..7c67d064e 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1415,6 +1415,18 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize t->grow_counter = 0; t->growth_rate = 250; + /* Set the default cargo requirement for town growth */ + switch (_settings_game.game_creation.landscape) { + case LT_ARCTIC: + if (FindFirstCargoWithTownEffect(TE_FOOD) != NULL) t->goal[TE_FOOD] = TOWN_GROWTH_WINTER; + break; + + case LT_TROPIC: + if (FindFirstCargoWithTownEffect(TE_FOOD) != NULL) t->goal[TE_FOOD] = TOWN_GROWTH_DESERT; + if (FindFirstCargoWithTownEffect(TE_WATER) != NULL) t->goal[TE_WATER] = TOWN_GROWTH_DESERT; + break; + } + t->fund_buildings_months = 0; for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL; @@ -2325,6 +2337,20 @@ CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } /** + * Determines the first cargo with a certain town effect + * @param effect Town effect of interest + * @return first active cargo slot with that effect + */ +const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) +{ + const CargoSpec *cs; + FOR_ALL_CARGOSPECS(cs) { + if (cs->town_effect == effect) return cs; + } + return NULL; +} + +/** * Expand a town (scenario editor only). * @param tile Unused. * @param flags Type of operation. @@ -2559,6 +2585,8 @@ static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags) SetBit(t->flags, TOWN_IS_FUNDED); /* And grow for 3 months */ t->fund_buildings_months = 3; + + SetWindowDirty(WC_TOWN_VIEW, t->index); } return CommandCost(); } @@ -2699,7 +2727,7 @@ CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint return cost; } -static void UpdateTownGrowRate(Town *t) +static void UpdateTownRating(Town *t) { /* Increase company ratings if they're low */ const Company *c; @@ -2709,13 +2737,10 @@ static void UpdateTownGrowRate(Town *t) } } - int n = 0; - const Station *st; FOR_ALL_STATIONS(st) { if (DistanceSquare(st->xy, t->xy) <= t->squared_town_zone_radius[0]) { if (st->time_since_load <= 20 || st->time_since_unload <= 20) { - n++; if (Company::IsValidID(st->owner)) { int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP; t->ratings[st->owner] = min(new_rating, INT16_MAX); // do not let it overflow @@ -2735,10 +2760,22 @@ static void UpdateTownGrowRate(Town *t) } SetWindowDirty(WC_TOWN_AUTHORITY, t->index); +} +static void UpdateTownGrowRate(Town *t) +{ ClrBit(t->flags, TOWN_IS_FUNDED); + SetWindowDirty(WC_TOWN_VIEW, t->index); + if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return; + /* Check if all goals are reached for this town to grow */ + for (int i = TE_BEGIN; i < TE_END; i++) { + if (t->goal[i] == TOWN_GROWTH_WINTER && TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->population > 90) return; + if (t->goal[i] == TOWN_GROWTH_DESERT && GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->population > 60) return; + if (t->goal[i] > t->received[i].old_act) return; + } + /** * Towns are processed every TOWN_GROWTH_TICKS ticks, and this is the * number of times towns are processed before a new building is built. @@ -2748,6 +2785,17 @@ static void UpdateTownGrowRate(Town *t) { 320, 420, 300, 220, 160, 100 } // Normal values }; + int n = 0; + + const Station *st; + FOR_ALL_STATIONS(st) { + if (DistanceSquare(st->xy, t->xy) <= t->squared_town_zone_radius[0]) { + if (st->time_since_load <= 20 || st->time_since_unload <= 20) { + n++; + } + } + } + uint16 m; if (t->fund_buildings_months != 0) { @@ -2758,13 +2806,6 @@ static void UpdateTownGrowRate(Town *t) if (n == 0 && !Chance16(1, 12)) return; } - if (_settings_game.game_creation.landscape == LT_ARCTIC) { - if (TileHeight(t->xy) >= GetSnowLine() && t->received[TE_FOOD].old_act == 0 && t->population > 90) return; - - } else if (_settings_game.game_creation.landscape == LT_TROPIC) { - if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->received[TE_FOOD].old_act == 0 || t->received[TE_WATER].old_act == 0) && t->population > 60) return; - } - /* Use the normal growth rate values if new buildings have been funded in * this town and the growth rate is set to none. */ uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1; @@ -2778,6 +2819,7 @@ static void UpdateTownGrowRate(Town *t) } SetBit(t->flags, TOWN_IS_FUNDED); + SetWindowDirty(WC_TOWN_VIEW, t->index); } static void UpdateTownAmounts(Town *t) @@ -3006,8 +3048,9 @@ void TownsMonthlyLoop() if (--t->exclusive_counter == 0) t->exclusivity = INVALID_COMPANY; } - UpdateTownGrowRate(t); UpdateTownAmounts(t); + UpdateTownRating(t); + UpdateTownGrowRate(t); UpdateTownUnwanted(t); } } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 1097abb42..1ec5df500 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -344,20 +344,6 @@ public: if (widget == TVW_CAPTION) SetDParam(0, this->town->index); } - /** - * Determines the first cargo with a certain town effect - * @param effect Town effect of interest - * @return first active cargo slot with that effect - */ - const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) const - { - const CargoSpec *cs; - FOR_ALL_CARGOSPECS(cs) { - if (cs->town_effect == effect) return cs; - } - return NULL; - } - virtual void DrawWidget(const Rect &r, int widget) const { if (widget != TVW_INFOPANEL) return; @@ -376,55 +362,56 @@ public: SetDParam(1, this->town->supplied[CT_MAIL].old_max); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_MAIL_LAST_MONTH_MAX); - StringID required_text = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED; - uint cargo_needed_for_growth = 0; - switch (_settings_game.game_creation.landscape) { - case LT_ARCTIC: - if (TileHeight(this->town->xy) >= LowestSnowLine()) cargo_needed_for_growth = 1; - if (TileHeight(this->town->xy) < GetSnowLine()) required_text = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER; - break; - - case LT_TROPIC: - if (GetTropicZone(this->town->xy) == TROPICZONE_DESERT) cargo_needed_for_growth = 2; - break; - - default: break; - } + bool first = true; + for (int i = TE_BEGIN; i < TE_END; i++) { + if (this->town->goal[i] == 0) continue; + if (this->town->goal[i] == TOWN_GROWTH_WINTER && TileHeight(this->town->xy) < LowestSnowLine()) continue; - if (cargo_needed_for_growth > 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH); + if (first) { + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH); + first = false; + } bool rtl = _current_text_dir == TD_RTL; uint cargo_text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : 20); uint cargo_text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? 20 : 0); - const CargoSpec *food = FindFirstCargoWithTownEffect(TE_FOOD); - CargoID first_food_cargo = (food != NULL) ? food->Index() : (CargoID)CT_INVALID; - StringID food_name = (food != NULL) ? food->name : STR_CARGO_PLURAL_FOOD; + const CargoSpec *cargo = FindFirstCargoWithTownEffect((TownEffect)i); + assert(cargo != NULL); - const CargoSpec *water = FindFirstCargoWithTownEffect(TE_WATER); - CargoID first_water_cargo = (water != NULL) ? water->Index() : (CargoID)CT_INVALID; - StringID water_name = (water != NULL) ? water->name : STR_CARGO_PLURAL_WATER; + StringID string; - if (first_food_cargo != CT_INVALID && this->town->received[TE_FOOD].old_act > 0) { - SetDParam(0, first_food_cargo); - SetDParam(1, this->town->received[TE_FOOD].old_act); - DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_LAST_MONTH); - } else { - SetDParam(0, food_name); - DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, required_text); - } + if (this->town->goal[i] == TOWN_GROWTH_DESERT || this->town->goal[i] == TOWN_GROWTH_WINTER) { + /* For 'original' gameplay, don't show the amount required (you need 1 or more ..) */ + string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL; + if (this->town->received[i].old_act < this->town->goal[i]) { + string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL; - if (cargo_needed_for_growth > 1) { - if (first_water_cargo != CT_INVALID && this->town->received[TE_WATER].old_act > 0) { - SetDParam(0, first_water_cargo); - SetDParam(1, this->town->received[TE_WATER].old_act); - DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_LAST_MONTH); - } else { - SetDParam(0, water_name); - DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, required_text); + if (this->town->goal[i] == TOWN_GROWTH_WINTER && TileHeight(this->town->xy) < GetSnowLine()) { + string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER; + } } + + SetDParam(0, cargo->name); + } else { + string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED; + if (this->town->received[i].old_act < this->town->goal[i]) { + string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED; + } + + SetDParam(0, cargo->Index()); + SetDParam(1, this->town->received[i].old_act); + SetDParam(2, cargo->Index()); + SetDParam(3, this->town->goal[i]); } + DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, string); + } + + if (HasBit(this->town->flags, TOWN_IS_FUNDED)) { + SetDParam(0, (this->town->growth_rate * TOWN_GROWTH_TICKS + DAY_TICKS) / DAY_TICKS); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); + } else { + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_TOWN_GROW_STOPPED); } /* only show the town noise, if the noise option is activated. */ @@ -491,17 +478,16 @@ public: { uint aimed_height = 3 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - switch (_settings_game.game_creation.landscape) { - case LT_ARCTIC: - if (TileHeight(this->town->xy) >= LowestSnowLine()) aimed_height += 2 * FONT_HEIGHT_NORMAL; - break; - - case LT_TROPIC: - if (GetTropicZone(this->town->xy) == TROPICZONE_DESERT) aimed_height += 3 * FONT_HEIGHT_NORMAL; - break; - - default: break; + bool first = true; + for (int i = TE_BEGIN; i < TE_END; i++) { + if (this->town->goal[i] == 0) continue; + if (first) { + aimed_height += FONT_HEIGHT_NORMAL; + first = false; + } + aimed_height += FONT_HEIGHT_NORMAL; } + aimed_height += FONT_HEIGHT_NORMAL; if (_settings_game.economy.station_noise_level) aimed_height += FONT_HEIGHT_NORMAL; |