diff --git a/src/citymania/cm_event.hpp b/src/citymania/cm_event.hpp index bf2c95bd8b..7f8a6d106f 100644 --- a/src/citymania/cm_event.hpp +++ b/src/citymania/cm_event.hpp @@ -17,8 +17,7 @@ namespace citymania { namespace event { -struct NewMonth { -}; +struct NewMonth {}; struct TownGrowthSucceeded { Town *town; @@ -31,6 +30,8 @@ struct TownGrowthFailed { TileIndex tile; }; +struct TownCachesRebuilt {}; + struct HouseRebuilt { Town *town; TileIndex tile; @@ -43,6 +44,13 @@ struct HouseBuilt { const HouseSpec *house_spec; }; +struct HouseCleared { + Town *town; + TileIndex tile; + const HouseSpec *house_spec; + bool was_completed; ///< whether house was completed before destruction +}; + struct HouseCompleted { Town *town; TileIndex tile; @@ -115,14 +123,14 @@ protected: class Dispatcher { protected: - std::map> dispacthers; + std::map> dispatchers; template TypeDispatcher &get_dispatcher() { - auto p = this->dispacthers.find(typeid(T)); - if (p == this->dispacthers.end()) { + auto p = this->dispatchers.find(typeid(T)); + if (p == this->dispatchers.end()) { auto x = make_up>(); - p = this->dispacthers.emplace_hint(p, typeid(T), std::move(x)); + p = this->dispatchers.emplace_hint(p, typeid(T), std::move(x)); } return *(static_cast *>((*p).second.get())); } diff --git a/src/citymania/cm_game.cpp b/src/citymania/cm_game.cpp index 187449f9d3..d544ac0d00 100644 --- a/src/citymania/cm_game.cpp +++ b/src/citymania/cm_game.cpp @@ -50,12 +50,34 @@ Game::Game() { this->events.listen([this] (const event::HouseBuilt &event) { event.town->cm.houses_constructing++; + event.town->cm.real_population += event.house_spec->population; this->towns_growth_tiles[event.tile] = TownGrowthTileState::NEW_HOUSE; }); + this->events.listen([this] (const event::HouseCleared &event) { + if (!event.was_completed) + event.town->cm.houses_constructing--; + event.town->cm.real_population -= event.house_spec->population; + }); + this->events.listen([this] (const event::HouseCompleted &event) { event.town->cm.houses_constructing--; }); + + this->events.listen([this] (const event::TownCachesRebuilt &event) { + for (Town *town : Town::Iterate()) { + town->cm.real_population = 0; + town->cm.houses_constructing = 0; + } + for (TileIndex t = 0; t < MapSize(); t++) { + if (!IsTileType(t, MP_HOUSE)) continue; + Town *town = Town::GetByTile(t); + if (!IsHouseCompleted(t)) + town->cm.houses_constructing++; + HouseID house_id = GetHouseType(t); + town->cm.real_population += HouseSpec::Get(house_id)->population; + } + }); } } // namespace citymania \ No newline at end of file diff --git a/src/citymania/cm_game.hpp b/src/citymania/cm_game.hpp index a1195bd569..0b1bcd13ca 100644 --- a/src/citymania/cm_game.hpp +++ b/src/citymania/cm_game.hpp @@ -35,21 +35,6 @@ public: auto bs = (b == this->towns_growth_tiles.end() ? TownGrowthTileState::NONE : (*b).second); return max(as, bs); } - - void rebuild_town_caches() { - for (Town *town : Town::Iterate()) { - town->cm.houses_constructing = 0; - town->cache.potential_pop = 0; - } - for (TileIndex t = 0; t < MapSize(); t++) { - if (!IsTileType(t, MP_HOUSE)) continue; - Town *town = Town::GetByTile(t); - if (!IsHouseCompleted(t)) - town->cm.houses_constructing++; - HouseID house_id = GetHouseType(t); - town->cache.potential_pop += HouseSpec::Get(house_id)->population; - } - } }; } // namespace citymania diff --git a/src/citymania/cm_main.hpp b/src/citymania/cm_main.hpp index 32cb44fc2f..d32a676fbc 100644 --- a/src/citymania/cm_main.hpp +++ b/src/citymania/cm_main.hpp @@ -8,6 +8,7 @@ namespace citymania { extern up _game; +void ResetGame(); void SwitchToMode(SwitchMode new_mode); template diff --git a/src/citymania/cm_type.hpp b/src/citymania/cm_type.hpp index 56bd4c7e45..445e8e9347 100644 --- a/src/citymania/cm_type.hpp +++ b/src/citymania/cm_type.hpp @@ -6,38 +6,6 @@ #include #include -/* C++14 implementation of make_unique */ -namespace std { - template struct _Unique_if { - typedef unique_ptr _Single_object; - }; - - template struct _Unique_if { - typedef unique_ptr _Unknown_bound; - }; - - template struct _Unique_if { - typedef void _Known_bound; - }; - - template - typename _Unique_if::_Single_object - make_unique(Args&&... args) { - return unique_ptr(new T(std::forward(args)...)); - } - - template - typename _Unique_if::_Unknown_bound - make_unique(size_t n) { - typedef typename remove_extent::type U; - return unique_ptr(new U[n]()); - } - - template - typename _Unique_if::_Known_bound - make_unique(Args&&...) = delete; -} // namespace std - namespace citymania { // Make smart pointers easier to type @@ -45,8 +13,39 @@ template using up=std::unique_ptr; template using sp=std::shared_ptr; template using wp=std::weak_ptr; -template const auto make_up = std::make_unique; -template const auto make_sp = std::make_shared; +/* C++14 implementation of make_unique */ +template struct _Unique_if { + typedef std::unique_ptr _Single_object; +}; + +template struct _Unique_if { + typedef std::unique_ptr _Unknown_bound; +}; + +template struct _Unique_if { + typedef void _Known_bound; +}; + +template + typename _Unique_if::_Single_object + make_up(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); + } + +template + typename _Unique_if::_Unknown_bound + make_up(size_t n) { + typedef typename std::remove_extent::type U; + return std::unique_ptr(new U[n]()); + } + +template + typename _Unique_if::_Known_bound + make_up(Args&&...) = delete; + + +// template const auto make_up = std::make_unique; +// template const auto make_sp = std::make_shared; } // namespace citymania diff --git a/src/citymania/extensions/cmext_town.hpp b/src/citymania/extensions/cmext_town.hpp index 9001b7d600..710a87e5b5 100644 --- a/src/citymania/extensions/cmext_town.hpp +++ b/src/citymania/extensions/cmext_town.hpp @@ -8,6 +8,7 @@ namespace ext { class Town { public: bool growing_by_chance = false; ///< whether town is growing due to 1/12 chance + uint32 real_population = 0; ///< population including unfinished houses uint32 hs_total = 0; ///< number of skipped house buildings (HS) in total uint16 hs_total_prev = 0; ///< number of skipped house buildings (HS) in total at the end of last month uint16 hs_last_month = 0; ///< number of skipped house buildings (HS) during last month diff --git a/src/openttd.cpp b/src/openttd.cpp index 1f56ee0ab1..04df4f573e 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -331,6 +331,8 @@ static void LoadIntroGame(bool load_newgrfs = true) ResetWindowSystem(); SetupColoursAndInitialWindow(); + citymania::ResetGame(); + /* Load the default opening screen savegame */ if (SaveOrLoad("opntitle.dat", SLO_LOAD, DFT_GAME_FILE, BASESET_DIR) != SL_OK) { GenerateWorld(GWM_EMPTY, 64, 64); // if failed loading, make empty world. diff --git a/src/rev.cpp b/src/rev.cpp index c5f63bf798..a45964a8a6 100644 --- a/src/rev.cpp +++ b/src/rev.cpp @@ -88,4 +88,4 @@ const byte _openttd_revision_tagged = 1; const uint32 _openttd_newgrf_version = 1 << 28 | 10 << 24 | 0 << 20 | 1 << 19 | 28004; -const char _citymania_version[] = "20200608-master-m2816c38d3d 08.06.20"; +const char _citymania_version[] = "20200619-master-m2010f236c6 20.06.20"; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 3535255b4c..0f758779c0 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -18,6 +18,7 @@ #include "newgrf_sl.h" #include "../citymania/cm_main.hpp" + #include "../safeguards.h" /** @@ -52,7 +53,7 @@ void RebuildTownCaches() UpdateTownCargoes(town); } UpdateTownCargoBitmap(); - citymania::_game->rebuild_town_caches(); + citymania::Emit(citymania::event::TownCachesRebuilt()); } /** diff --git a/src/town.h b/src/town.h index 55603989d2..7ee4f166c6 100644 --- a/src/town.h +++ b/src/town.h @@ -50,7 +50,6 @@ extern TownPool _town_pool; struct TownCache { uint32 num_houses; ///< Amount of houses uint32 population; ///< Current population of people - uint32 potential_pop; ///< Potential population (if all houses are finished) TrackedViewportSign sign; ///< Location of name sign, UpdateVirtCoord updates this PartOfSubsidy part_of_subsidy; ///< Is this town a source/destination of a subsidy? uint32 squared_town_zone_radius[HZB_END]; ///< UpdateTownRadius updates this given the house count diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 54b4a399fd..9c902b78df 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2865,7 +2865,6 @@ static bool BuildTownHouse(Town *t, TileIndex tile) /* build the house */ t->cache.num_houses++; - t->cache.potential_pop += hs->population; /* Special houses that there can be only one of. */ t->flags |= oneof; @@ -2959,12 +2958,12 @@ void ClearTownHouse(Town *t, TileIndex tile) const HouseSpec *hs = HouseSpec::Get(house); /* Remove population from the town if the house is finished. */ - if (IsHouseCompleted(tile)) { + bool is_completed = IsHouseCompleted(tile); + if (is_completed) { ChangePopulation(t, -hs->population); } t->cache.num_houses--; - t->cache.potential_pop -= hs->population; /* Clear flags for houses that only may exist once/town. */ if (hs->building_flags & BUILDING_IS_CHURCH) { @@ -2986,6 +2985,8 @@ void ClearTownHouse(Town *t, TileIndex tile) /* Update cargo acceptance. */ UpdateTownCargoes(t, tile); + + citymania::Emit(citymania::event::HouseCleared{t, tile, hs, is_completed}); } /** diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 6d6985572a..cfc967b12f 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -817,8 +817,8 @@ private: /** Sort by real population (default descending, as big towns are of the most interest). */ static bool TownRealPopulationSorter(const Town * const &a, const Town * const &b) { - uint32 a_population = a->cache.potential_pop; - uint32 b_population = b->cache.potential_pop; + uint32 a_population = a->cm.real_population; + uint32 b_population = b->cm.real_population; if (a_population == b_population) return TownDirectoryWindow::TownNameSorter(a, b); return a_population < b_population; } @@ -944,7 +944,7 @@ public: SetDParam(0, t->index); SetDParam(1, t->cache.population); - SetDParam(2, t->cache.potential_pop); + SetDParam(2, t->cm.real_population); SetDParam(3, t->cache.num_houses); /* CITIES DIFFERENT COLOUR*/ DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, t->larger_town ? STR_TOWN_DIRECTORY_CITY_COLOUR : STR_TOWN_DIRECTORY_TOWN_COLOUR); @@ -1390,7 +1390,7 @@ void InitializeTownGui() //CB static void DrawExtraTownInfo (const Rect &r, uint &y, Town *town, uint line, bool show_house_states_info) { //real pop and rating - SetDParam(0, town->cache.potential_pop); + SetDParam(0, town->cm.real_population); SetDParam(1, town->ratings[_current_company]); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += line, STR_TOWN_VIEW_REALPOP_RATE); //town stats