diff --git a/source.list b/source.list index c037ad4d81..1092264b86 100644 --- a/source.list +++ b/source.list @@ -613,23 +613,6 @@ water_cmd.cpp waypoint_cmd.cpp zoning_cmd.cpp -# CityMania files -citymania/base64.h -citymania/base64.cpp -citymania/cm_bitstream.hpp -citymania/cm_bitstream.cpp -citymania/highlight.hpp -citymania/highlight.cpp -citymania/locations.hpp -citymania/locations.cpp -citymania/minimap.hpp -citymania/minimap.cpp -citymania/cm_saveload.hpp -citymania/cm_saveload.cpp -citymania/station_ui.hpp -citymania/station_ui.cpp -newgrf_revisions.hpp - # Save/Load handlers saveload/afterload.cpp saveload/ai_sl.cpp @@ -1220,6 +1203,8 @@ sound/null_s.cpp thread.h # CityMania +citymania/cm_bitstream.hpp +citymania/cm_bitstream.cpp citymania/cm_console_cmds.hpp citymania/cm_console_cmds.cpp citymania/cm_event.hpp @@ -1232,5 +1217,21 @@ citymania/cm_main.cpp citymania/cm_tooltips.hpp citymania/cm_tooltips.cpp citymania/cm_type.hpp +citymania/cm_saveload.hpp +citymania/cm_saveload.cpp +citymania/cm_settings.hpp citymania/extensions/cmext_town.hpp citymania/extensions/cmext_company.hpp + +# CityMania client +citymania/base64.h +citymania/base64.cpp +citymania/highlight.hpp +citymania/highlight.cpp +citymania/locations.hpp +citymania/locations.cpp +citymania/minimap.hpp +citymania/minimap.cpp +citymania/station_ui.hpp +citymania/station_ui.cpp +newgrf_revisions.hpp diff --git a/src/citymania/cm_event.hpp b/src/citymania/cm_event.hpp index f0b73ccc6c..4c0bde4fdd 100644 --- a/src/citymania/cm_event.hpp +++ b/src/citymania/cm_event.hpp @@ -2,6 +2,8 @@ #define CM_EVENT_HPP #include "cm_type.hpp" + +#include "../console_func.h" #include "../cargo_type.h" #include "../company_type.h" #include "../economy_type.h" @@ -42,12 +44,15 @@ struct HouseRebuilt { struct HouseBuilt { Town *town; TileIndex tile; + HouseID house_id; const HouseSpec *house_spec; + bool is_rebuilding; }; struct HouseCleared { Town *town; TileIndex tile; + HouseID house_id; const HouseSpec *house_spec; bool was_completed; ///< whether house was completed before destruction }; @@ -55,6 +60,7 @@ struct HouseCleared { struct HouseCompleted { Town *town; TileIndex tile; + HouseID house_id; const HouseSpec *house_spec; }; @@ -100,6 +106,13 @@ struct CompanyBalanceChanged { Money delta; }; +enum class Slot : uint8 { + GOAL = 10, + CONTROLLER = 20, + GAME = 30, + CONTROLLER_POST = 40, + RECORDER = 50, +}; class TypeDispatcherBase { public: @@ -115,14 +128,16 @@ public: TypeDispatcher() { } virtual ~TypeDispatcher() {} - void listen(Handler &handler) { - this->new_handlers.push_back(handler); + void listen(Slot slot, Handler &handler) { + this->handler_map.insert(std::make_pair(slot, handler)); } void emit(const T &event) { - if (!this->new_handlers.empty()) { - this->handlers.insert(this->handlers.end(), this->new_handlers.begin(), this->new_handlers.end()); - this->new_handlers.clear(); + if (this->new_handlers) { // only rebuild handlers while not iterating + this->handlers.clear(); + for (auto &p : this->handler_map) { + this->handlers.push_back(p.second); + } } for (auto &h : this->handlers) { h(event); @@ -131,7 +146,8 @@ public: protected: std::vector handlers; - std::vector new_handlers; + std::multimap handler_map; + bool new_handlers = false; }; @@ -151,8 +167,8 @@ protected: public: template - void listen(std::function handler) { - this->get_dispatcher().listen(handler); + void listen(Slot slot, std::function handler) { + this->get_dispatcher().listen(slot, handler); } template diff --git a/src/citymania/cm_game.cpp b/src/citymania/cm_game.cpp index fc3891fc0d..c4e035daef 100644 --- a/src/citymania/cm_game.cpp +++ b/src/citymania/cm_game.cpp @@ -9,7 +9,7 @@ namespace citymania { Game::Game() { - this->events.listen([this] (const event::NewMonth &) { + this->events.listen(event::Slot::GAME, [this] (const event::NewMonth &) { for (Town *t : Town::Iterate()) { t->cm.hs_last_month = t->cm.hs_total - t->cm.hs_total_prev; t->cm.hs_total_prev = t->cm.hs_total; @@ -28,45 +28,45 @@ Game::Game() { this->towns_growth_tiles.clear(); }); - this->events.listen([this] (const event::TownGrowthSucceeded &event) { + this->events.listen(event::Slot::GAME, [this] (const event::TownGrowthSucceeded &event) { if (event.town->cache.num_houses <= event.prev_houses) { event.town->cm.hs_total++; - this->towns_growth_tiles[event.tile] = TownGrowthTileState::HS; + this->set_town_growth_tile(event.tile, TownGrowthTileState::HS); } }); - this->events.listen([this] (const event::TownGrowthFailed &event) { + this->events.listen(event::Slot::GAME, [this] (const event::TownGrowthFailed &event) { event.town->cm.cs_total++; - this->towns_growth_tiles[event.tile] = TownGrowthTileState::CS; + this->set_town_growth_tile(event.tile, TownGrowthTileState::CS); }); - this->events.listen([this] (const event::HouseRebuilt &event) { + this->events.listen(event::Slot::GAME, [this] (const event::HouseRebuilt &event) { if (event.was_successful) { event.town->cm.houses_reconstructed_this_month++; - this->towns_growth_tiles[event.tile] = TownGrowthTileState::RH_REBUILT; + this->set_town_growth_tile(event.tile, TownGrowthTileState::RH_REBUILT); } else { event.town->cm.houses_demolished_this_month++; - this->towns_growth_tiles[event.tile] = TownGrowthTileState::RH_REMOVED; + this->set_town_growth_tile(event.tile, TownGrowthTileState::RH_REMOVED); } }); - this->events.listen([this] (const event::HouseBuilt &event) { + this->events.listen(event::Slot::GAME, [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->set_town_growth_tile(event.tile, TownGrowthTileState::NEW_HOUSE); }); - this->events.listen([this] (const event::HouseCleared &event) { + this->events.listen(event::Slot::GAME, [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) { + this->events.listen(event::Slot::GAME, [this] (const event::HouseCompleted &event) { event.town->cm.houses_constructing--; }); - this->events.listen([this] (const event::TownCachesRebuilt &event) { + this->events.listen(event::Slot::GAME, [this] (const event::TownCachesRebuilt &event) { for (Town *town : Town::Iterate()) { town->cm.real_population = 0; town->cm.houses_constructing = 0; @@ -81,9 +81,13 @@ Game::Game() { } }); - this->events.listen([this] (const event::CargoAccepted &event) { + this->events.listen(event::Slot::GAME, [this] (const event::CargoAccepted &event) { event.company->cur_economy.cm.cargo_income[event.cargo_type] += event.profit; }); } +void Game::set_town_growth_tile(TileIndex tile, TownGrowthTileState state) { + if (this->towns_growth_tiles[tile] < state) this->towns_growth_tiles[tile] = state; +} + } // namespace citymania \ No newline at end of file diff --git a/src/citymania/cm_game.hpp b/src/citymania/cm_game.hpp index 0b1bcd13ca..a9835e0781 100644 --- a/src/citymania/cm_game.hpp +++ b/src/citymania/cm_game.hpp @@ -1,5 +1,5 @@ -#ifndef CMEXT_GAME_HPP -#define CMEXT_GAME_HPP +#ifndef CM_GAME_HPP +#define CM_GAME_HPP #include "../town.h" @@ -20,13 +20,14 @@ enum class TownGrowthTileState : uint8 { class Game { public: - event::Dispatcher events; - typedef std::map TownsGrowthTilesIndex; TownsGrowthTilesIndex towns_growth_tiles_last_month; TownsGrowthTilesIndex towns_growth_tiles; + event::Dispatcher events; + Game(); + void set_town_growth_tile(TileIndex tile, TownGrowthTileState state); TownGrowthTileState get_town_growth_tile(TileIndex tile) { auto a = this->towns_growth_tiles.find(tile); diff --git a/src/citymania/cm_main.cpp b/src/citymania/cm_main.cpp index b7cab34ad2..4d7ba9e8a8 100644 --- a/src/citymania/cm_main.cpp +++ b/src/citymania/cm_main.cpp @@ -16,7 +16,7 @@ void ResetGame() { } void SwitchToMode(SwitchMode new_mode) { - ResetGame(); + if (new_mode != SM_SAVE_GAME) ResetGame(); } void ToggleSmallMap() { diff --git a/src/citymania/cm_saveload.cpp b/src/citymania/cm_saveload.cpp index 9d1d2026e8..9919d44b2f 100644 --- a/src/citymania/cm_saveload.cpp +++ b/src/citymania/cm_saveload.cpp @@ -8,6 +8,7 @@ #include "cm_bitstream.hpp" #include "cm_saveload.hpp" +#include "cm_settings.hpp" #include "cm_game.hpp" #include "cm_main.hpp" @@ -116,7 +117,8 @@ void CBController_saveload_encode(BitOStream &bs) { bs.WriteBytes(0 /* version */, 2); // Controller::saveload_encode(bs); bs.WriteBytes(0, 1); - bs.WriteBytes(_settings_client.gui.cb_distance_check, 1); + bs.WriteBytes(0, 1); + // bs.WriteBytes(_settings_client.gui.cb_distance_check, 1); bs.WriteBytes(0, 1); bs.WriteBytes(0, 1); bs.WriteBytes(0, 1); @@ -124,43 +126,43 @@ void CBController_saveload_encode(BitOStream &bs) { bs.WriteBytes(0, 1); bs.WriteBytes(0, 1); std::vector cb_cargos; - for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++) { - if (CB_GetReq(cargo) > 0) - cb_cargos.push_back(cargo); - } + // for(CargoID cargo = 0; cargo < NUM_CARGO; cargo++) { + // if (CB_GetReq(cargo) > 0) + // cb_cargos.push_back(cargo); + // } - for (auto cargo_id : cb_cargos) { - // bs.WriteBytes(req.cargo_id, 1); - // bs.WriteBytes(req.amount, 4); - // bs.WriteBytes(req.from, 4); - // bs.WriteBytes(req.decay, 1); - bs.WriteBytes(cargo_id, 1); - bs.WriteBytes(CB_GetReq(cargo_id), 4); - bs.WriteBytes(CB_GetFrom(cargo_id), 4); - bs.WriteBytes(CB_GetDecay(cargo_id), 1); - } - // uint16 cb_towns = 0; - // ForEachCBTown([this, &cb_towns](Town *, Company *) { cb_towns++; }); - bs.WriteBytes(Town::GetNumItems(), 2); - for (Town *t : Town::Iterate()) { - auto &tcb = t->cb; - bs.WriteBytes(t->index, 2); - bs.WriteBytes(tcb.pax_delivered, 4); - bs.WriteBytes(tcb.mail_delivered, 4); - bs.WriteBytes(tcb.pax_delivered_last_month, 4); - bs.WriteBytes(tcb.mail_delivered_last_month, 4); - bs.WriteBytes((uint8)tcb.growth_state, 1); - bs.WriteBytes(tcb.shrink_effeciency, 1); - bs.WriteBytes(tcb.shrink_rate, 2); - bs.WriteBytes(tcb.shrink_counter, 2); - for (auto cargo_id : cb_cargos) { - bs.WriteBytes(tcb.stored[cargo_id], 4); - bs.WriteBytes(tcb.delivered[cargo_id], 4); - bs.WriteBytes(tcb.required[cargo_id], 4); - bs.WriteBytes(tcb.delivered_last_month[cargo_id], 4); - bs.WriteBytes(tcb.required_last_month[cargo_id], 4); - } - } + // for (auto cargo_id : cb_cargos) { + // // bs.WriteBytes(req.cargo_id, 1); + // // bs.WriteBytes(req.amount, 4); + // // bs.WriteBytes(req.from, 4); + // // bs.WriteBytes(req.decay, 1); + // bs.WriteBytes(cargo_id, 1); + // bs.WriteBytes(CB_GetReq(cargo_id), 4); + // bs.WriteBytes(CB_GetFrom(cargo_id), 4); + // bs.WriteBytes(CB_GetDecay(cargo_id), 1); + // } + // // uint16 cb_towns = 0; + // // ForEachCBTown([this, &cb_towns](Town *, Company *) { cb_towns++; }); + // bs.WriteBytes(Town::GetNumItems(), 2); + // for (Town *t : Town::Iterate()) { + // auto &tcb = t->cb; + // bs.WriteBytes(t->index, 2); + // bs.WriteBytes(tcb.pax_delivered, 4); + // bs.WriteBytes(tcb.mail_delivered, 4); + // bs.WriteBytes(tcb.pax_delivered_last_month, 4); + // bs.WriteBytes(tcb.mail_delivered_last_month, 4); + // bs.WriteBytes((uint8)tcb.growth_state, 1); + // bs.WriteBytes(tcb.shrink_effeciency, 1); + // bs.WriteBytes(tcb.shrink_rate, 2); + // bs.WriteBytes(tcb.shrink_counter, 2); + // for (auto cargo_id : cb_cargos) { + // bs.WriteBytes(tcb.stored[cargo_id], 4); + // bs.WriteBytes(tcb.delivered[cargo_id], 4); + // bs.WriteBytes(tcb.required[cargo_id], 4); + // bs.WriteBytes(tcb.delivered_last_month[cargo_id], 4); + // bs.WriteBytes(tcb.required_last_month[cargo_id], 4); + // } + // } } bool CBController_saveload_decode(BitIStream &bs) { @@ -171,7 +173,8 @@ bool CBController_saveload_decode(BitIStream &bs) { // if (!Controller::saveload_decode(bs)) // return false; bs.ReadBytes(1); /* _settings_game.citymania.cb.requirements_type */ - _settings_client.gui.cb_distance_check = bs.ReadBytes(1); /* _settings_game.citymania.cb.acceptance_range */ + bs.ReadBytes(1); /* _settings_game.citymania.cb.acceptance_range */ + // _settings_client.gui.cb_distance_check = bs.ReadBytes(1); /* _settings_game.citymania.cb.acceptance_range */ bs.ReadBytes(1); /* _settings_game.citymania.cb.storage_size */ bs.ReadBytes(1); /* _settings_game.citymania.cb.town_protection_range */ bs.ReadBytes(2); /* _settings_game.citymania.cb.claim_max_houses */ @@ -191,7 +194,7 @@ bool CBController_saveload_decode(BitIStream &bs) { auto required = bs.ReadBytes(4); auto from = bs.ReadBytes(4); auto decay = bs.ReadBytes(1); - CB_SetRequirements(cargo_id, required, from, decay); + // CB_SetRequirements(cargo_id, required, from, decay); // _settings_game.citymania.cb.requirements.push_back(CBRequirement(cargo_id, from, required, decay, i, "")); } @@ -205,28 +208,54 @@ bool CBController_saveload_decode(BitIStream &bs) { return false; } - auto &tcb = t->cb; - tcb.pax_delivered = bs.ReadBytes(4); - tcb.mail_delivered = bs.ReadBytes(4); - tcb.pax_delivered_last_month = bs.ReadBytes(4); - tcb.mail_delivered_last_month = bs.ReadBytes(4); - tcb.growth_state = (TownGrowthState)bs.ReadBytes(1); - tcb.shrink_effeciency = bs.ReadBytes(1); - tcb.shrink_rate = bs.ReadBytes(2); - tcb.shrink_counter = bs.ReadBytes(2); - for (auto cargo_id : cb_cargos) { - tcb.stored[cargo_id] = bs.ReadBytes(4); - tcb.delivered[cargo_id] = bs.ReadBytes(4); - tcb.required[cargo_id] = bs.ReadBytes(4); - tcb.delivered_last_month[cargo_id] = bs.ReadBytes(4); - tcb.required_last_month[cargo_id] = bs.ReadBytes(4); - } + // auto &tcb = t->cb; + // tcb.pax_delivered = bs.ReadBytes(4); + // tcb.mail_delivered = bs.ReadBytes(4); + // tcb.pax_delivered_last_month = bs.ReadBytes(4); + // tcb.mail_delivered_last_month = bs.ReadBytes(4); + // tcb.growth_state = (TownGrowthState)bs.ReadBytes(1); + // tcb.shrink_effeciency = bs.ReadBytes(1); + // tcb.shrink_rate = bs.ReadBytes(2); + // tcb.shrink_counter = bs.ReadBytes(2); + // for (auto cargo_id : cb_cargos) { + // tcb.stored[cargo_id] = bs.ReadBytes(4); + // tcb.delivered[cargo_id] = bs.ReadBytes(4); + // tcb.required[cargo_id] = bs.ReadBytes(4); + // tcb.delivered_last_month[cargo_id] = bs.ReadBytes(4); + // tcb.required_last_month[cargo_id] = bs.ReadBytes(4); + // } }; return true; } -uint8 _controller_type = 0; -uint8 _game_type = 0; +void EncodeSettings(BitOStream &bs, Settings &settings) { + bs.WriteBytes(settings.max_players_in_company, 1); + bs.WriteBytes(settings.destroyed_houses_per_month, 2); + bs.WriteBytes(settings.game_length_years, 2); + bs.WriteBytes(settings.protect_funded_industries, 1); + bs.WriteBytes(settings.same_depot_sell_years, 2); + bs.WriteBytes(settings.economy.cashback_for_extra_land_clear, 1); + bs.WriteBytes(settings.economy.cashback_for_bridges_and_tunnels, 1); + bs.WriteBytes(settings.economy.cashback_for_foundations, 1); + bs.WriteBytes(settings.limits.max_airports, 2); + bs.WriteBytes(settings.limits.disable_canals, 1); + bs.WriteBytes(settings.limits.min_distance_between_docks, 2); +} + +void DecodeSettings(BitIStream &bs, Settings &settings) { + settings.max_players_in_company = bs.ReadBytes(1); + settings.destroyed_houses_per_month = bs.ReadBytes(2); + settings.game_length_years = bs.ReadBytes(2); + settings.protect_funded_industries = bs.ReadBytes(1); + settings.same_depot_sell_years = bs.ReadBytes(2); + settings.economy.cashback_for_extra_land_clear = bs.ReadBytes(1); + settings.economy.cashback_for_bridges_and_tunnels = bs.ReadBytes(1); + settings.economy.cashback_for_foundations = bs.ReadBytes(1); + settings.limits.max_airports = bs.ReadBytes(2); + settings.limits.disable_canals = bs.ReadBytes(1); + settings.limits.min_distance_between_docks = bs.ReadBytes(2); +} + uint16 _last_client_version = 1512; static u8vector EncodeData() { @@ -234,37 +263,39 @@ static u8vector EncodeData() { bs.Reserve(1000); bs.WriteBytes(SAVEGAME_DATA_FORMAT_VERSION, 2); bs.WriteBytes(_last_client_version, 2); - bs.WriteBytes(_controller_type, 1); + bs.WriteBytes(_settings_game.citymania.controller_type, 1); bs.WriteBytes(_date, 4); // Just in case we'll need to detect that game bs.WriteBytes(_date_fract, 1); // was saved by unmodified client - bs.WriteBytes(_game_type, 1); + bs.WriteBytes(_settings_game.citymania.game_type, 1); bs.WriteBytes(0, 3); // Reserved bs.WriteBytes(0, 4); // Reserved - + EncodeSettings(bs, _settings_game.citymania); EncodeCompanies(bs); EncodeTowns(bs); EncodeTownsGrowthTiles(bs, _game->towns_growth_tiles); EncodeTownsGrowthTiles(bs, _game->towns_growth_tiles_last_month); - if (_controller_type == 4) + if (_settings_game.citymania.controller_type == 4) CBController_saveload_encode(bs); return bs.GetVector(); } static void DecodeDataV2(BitIStream &bs) { + DecodeSettings(bs, _settings_game.citymania); DecodeCompanies(bs); DecodeTowns(bs); DecodeTownsGrowthTiles(bs, _game->towns_growth_tiles); DecodeTownsGrowthTiles(bs, _game->towns_growth_tiles_last_month); - if (_controller_type == 4) CBController_saveload_decode(bs); + if (_settings_game.citymania.controller_type == 4) CBController_saveload_decode(bs); } static void DecodeTownsCargoV1(BitIStream &bs) { - CB_SetStorage(bs.ReadBytes(1)); - _settings_client.gui.cb_distance_check = bs.ReadBytes(1); + bs.ReadBytes(1);bs.ReadBytes(1); + // CB_SetStorage(bs.ReadBytes(1)); + // _settings_client.gui.cb_distance_check = bs.ReadBytes(1); uint n_cb_cargos = bs.ReadBytes(1); - CB_ResetRequirements(); + // CB_ResetRequirements(); std::vector cb_cargos; for (uint i = 0; i < n_cb_cargos; i++) { uint cargo = bs.ReadBytes(1); @@ -276,7 +307,7 @@ static void DecodeTownsCargoV1(BitIStream &bs) uint req = bs.ReadBytes(4); uint from = bs.ReadBytes(4); uint decay = bs.ReadBytes(1); - CB_SetRequirements(cargo, req, from, decay); + // CB_SetRequirements(cargo, req, from, decay); } Town *t; uint n_affected_towns = bs.ReadBytes(2); @@ -287,21 +318,21 @@ static void DecodeTownsCargoV1(BitIStream &bs) DEBUG(sl, 0, "Invalid TownID in CB towns cargo data (%u)", town_id); return; } - auto &tcb = t->cb; - for (auto cargo_id : cb_cargos) { - tcb.stored[cargo_id] = bs.ReadBytes(4); - tcb.delivered_last_month[cargo_id] = bs.ReadBytes(4); - tcb.delivered[cargo_id] = bs.ReadBytes(4); - bs.ReadBytes(1); /* delivered enough */ + // auto &tcb = t->cb; + // for (auto cargo_id : cb_cargos) { + // tcb.stored[cargo_id] = bs.ReadBytes(4); + // tcb.delivered_last_month[cargo_id] = bs.ReadBytes(4); + // tcb.delivered[cargo_id] = bs.ReadBytes(4); + // bs.ReadBytes(1); /* delivered enough */ - tcb.required[cargo_id] = 0; - tcb.required_last_month[cargo_id] = 0; - } + // tcb.required[cargo_id] = 0; + // tcb.required_last_month[cargo_id] = 0; + // } } } static void DecodeDataV1(BitIStream &bs) { - if (_controller_type != 0) DecodeTownsCargoV1(bs); + if (_settings_game.citymania.controller_type != 0) DecodeTownsCargoV1(bs); for (Town *t : Town::Iterate()) { t->cm.growing_by_chance = bs.ReadBytes(1); t->cm.houses_reconstructed_this_month = bs.ReadBytes(2); @@ -348,15 +379,15 @@ static void DecodeData(u8vector &data) { } DEBUG(sl, 2, "CityMania savegame data version %u", version); _last_client_version = bs.ReadBytes(2); - _controller_type = bs.ReadBytes(1); - if (version <= 1) _controller_type = (_controller_type ? 4 : 0); + _settings_game.citymania.controller_type = bs.ReadBytes(1); + if (version <= 1) _settings_game.citymania.controller_type = (_settings_game.citymania.controller_type ? 4 : 0); int32 date = bs.ReadBytes(4); uint32 date_fract = bs.ReadBytes(1); if (date != _date || date_fract != _date_fract) { DEBUG(sl, 0, "Savegame was run in unmodified client, extra save data " "preserved, but may not be accurate"); } - _game_type = bs.ReadBytes(1); + _settings_game.citymania.game_type = bs.ReadBytes(1); bs.ReadBytes(3); // reserved bs.ReadBytes(4); // reserved if (version == 1) DecodeDataV1(bs); diff --git a/src/citymania/cm_settings.hpp b/src/citymania/cm_settings.hpp new file mode 100644 index 0000000000..fafb17bcf7 --- /dev/null +++ b/src/citymania/cm_settings.hpp @@ -0,0 +1,69 @@ +#ifndef CM_SETTINGS_HPP +#define CM_SETTINGS_HPP + +#include +#include + +// #include "types.hpp" + +namespace citymania { + +class CBRequirement { +public: + CargoID cargo_id; + uint32 from; + uint32 amount; + uint8 decay; + uint8 index; + std::string name; + bool has_storage; + + static CBRequirement Parse(const char *name, const char *value, uint8 index); + + CBRequirement(CargoID cargo_id, uint32 from, uint32 amount, uint8 decay, + uint8 index, std::string name) + :cargo_id{cargo_id}, from{from}, amount{amount}, decay{decay}, + index{index}, name{name}, has_storage{decay < 100} {} +}; + +struct EconomySettings { + bool cashback_for_extra_land_clear; + bool cashback_for_bridges_and_tunnels; + bool cashback_for_foundations; +}; + +struct LimitsSettings { + uint16 max_airports; ///< maximum number of airports per company, 0=unlimited + bool disable_canals; + uint16 min_distance_between_docks; ///< docks can be build only x tiles apart another, 0=disable check +}; + + +struct CBSettings { + uint8 requirements_type; // 0 - regular 1 - income-based requirements (new cb only) + std::vector requirements; + uint8 acceptance_range; // How far can station be to count towards requiremnts + uint8 storage_size; // cargo storage multiplier (x * monthly requirements) + uint8 town_protection_range; // Claimed town protection range (square from centre), overlaped with tz0 + uint16 claim_max_houses; // Max amount of houses claimable town can have + bool smooth_growth_rate; // Calculate growth rate precisely instead of rounding to 50 houses and allow going below 70 ticks (default max) + bool allow_negative_growth; // Make town shrink (with the same speed as growth) if requirements aren't satisfied +}; + +struct Settings { + CBSettings cb; + EconomySettings economy; + LimitsSettings limits; + + uint8 game_type; // GameType + uint8 controller_type; // ControllerType + uint8 max_players_in_company; + uint16 destroyed_houses_per_month; // max amount of houses a company can destroy per month + uint16 game_length_years; // game length in years(0 = disabled) + bool protect_funded_industries; + uint16 same_depot_sell_years; // can only sell vehicles in the same place (20 tiles radius) for first x yearss of its lifetime (0 = disabled) +}; + +}; // namespace citymania + +#endif diff --git a/src/citymania/extensions/cmext_company.hpp b/src/citymania/extensions/cmext_company.hpp index 5bca9ec691..bf485386de 100644 --- a/src/citymania/extensions/cmext_company.hpp +++ b/src/citymania/extensions/cmext_company.hpp @@ -18,7 +18,7 @@ public: bool is_scored; ///< whether company is eligible for scoring }; -} // namespace ext +} // namespace citymania } // namespace citymania diff --git a/src/settings_type.h b/src/settings_type.h index 10eb72c216..eea0d40f52 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -20,6 +20,8 @@ #include "zoom_type.h" #include "openttd.h" +#include "citymania/cm_settings.hpp" + /** Settings profiles and highscore tables. */ enum SettingsProfile { @@ -585,6 +587,8 @@ struct GameSettings { LinkGraphSettings linkgraph; ///< settings for link graph calculations StationSettings station; ///< settings related to station management LocaleSettings locale; ///< settings related to used currency/unit system in the current game + + citymania::Settings citymania; }; /** All settings that are only important for the local client. */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 9c902b78df..c725179a6a 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -258,7 +258,7 @@ enum TownGrowthResult { // GROWTH_SEARCH_RUNNING >= 1 }; -static bool BuildTownHouse(Town *t, TileIndex tile); +static bool BuildTownHouse(Town *t, TileIndex tile, bool is_rebuilding = false); static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size, bool city, TownLayout layout); static void TownDrawHouseLift(const TileInfo *ti) @@ -537,7 +537,7 @@ static void MakeSingleHouseBigger(TileIndex tile) ResetHouseAge(tile); if (hs->building_flags & BUILDING_HAS_1_TILE) - citymania::Emit(citymania::event::HouseCompleted{town, tile, hs}); + citymania::Emit(citymania::event::HouseCompleted{town, tile, house_id, hs}); } MarkTileDirtyByTile(tile); } @@ -673,7 +673,7 @@ static void TileLoop_Town(TileIndex tile) /* Rebuild with another house? */ bool rebuild_res = false; - if (GB(r, 24, 8) >= 12) rebuild_res = BuildTownHouse(t, tile); + if (GB(r, 24, 8) >= 12) rebuild_res = BuildTownHouse(t, tile, true); citymania::Emit(citymania::event::HouseRebuilt{t, tile, rebuild_res}); } @@ -2745,7 +2745,7 @@ static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool nosl * @param tile where the house will be built * @return false iff no house can be built at this tile */ -static bool BuildTownHouse(Town *t, TileIndex tile) +static bool BuildTownHouse(Town *t, TileIndex tile, bool is_rebuilding) { /* forbidden building here by town layout */ if (!TownLayoutAllowsHouseHere(t, tile)) return false; @@ -2894,8 +2894,10 @@ static bool BuildTownHouse(Town *t, TileIndex tile) UpdateTownGrowthRate(t); UpdateTownCargoes(t, tile); - citymania::Emit(citymania::event::HouseBuilt{t, tile, hs}); - if (completed) citymania::Emit(citymania::event::HouseCompleted{t, tile, hs}); + if (!_generating_world) { + citymania::Emit(citymania::event::HouseBuilt{t, tile, house, hs, is_rebuilding}); + if (completed) citymania::Emit(citymania::event::HouseCompleted{t, tile, house, hs}); + } return true; } @@ -2986,7 +2988,7 @@ void ClearTownHouse(Town *t, TileIndex tile) /* Update cargo acceptance. */ UpdateTownCargoes(t, tile); - citymania::Emit(citymania::event::HouseCleared{t, tile, hs, is_completed}); + citymania::Emit(citymania::event::HouseCleared{t, tile, house, hs, is_completed}); } /**