From 130c301c2c7642e514947f2376247c0498a38a3c Mon Sep 17 00:00:00 2001 From: dP Date: Mon, 6 Jul 2020 23:24:52 +0300 Subject: [PATCH] Add some citymania settings to extra save data --- src/citymania/cm_saveload.cpp | 50 +++++++++++++++++++------ src/citymania/cm_settings.hpp | 69 +++++++++++++++++++++++++++++++++++ src/settings_type.h | 4 ++ 3 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 src/citymania/cm_settings.hpp diff --git a/src/citymania/cm_saveload.cpp b/src/citymania/cm_saveload.cpp index c9b272a3a9..e5861c2ba3 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" @@ -227,8 +228,34 @@ bool CBController_saveload_decode(BitIStream &bs) { 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() { @@ -236,29 +263,30 @@ 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.cm.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.cm.game_type, 1); bs.WriteBytes(0, 3); // Reserved bs.WriteBytes(0, 4); // Reserved - + EncodeSettings(bs, _settings_game.cm); 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.cm.controller_type == 4) CBController_saveload_encode(bs); return bs.GetVector(); } static void DecodeDataV2(BitIStream &bs) { + DecodeSettings(bs, _settings_game.cm); 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.cm.controller_type == 4) CBController_saveload_decode(bs); } static void DecodeTownsCargoV1(BitIStream &bs) @@ -304,7 +332,7 @@ static void DecodeTownsCargoV1(BitIStream &bs) } static void DecodeDataV1(BitIStream &bs) { - if (_controller_type != 0) DecodeTownsCargoV1(bs); + if (_settings_game.cm.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); @@ -351,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.cm.controller_type = bs.ReadBytes(1); + if (version <= 1) _settings_game.cm.controller_type = (_settings_game.cm.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.cm.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/settings_type.h b/src/settings_type.h index fdb2b0f862..69de20a2a6 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 { @@ -558,6 +560,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 cm; }; /** All settings that are only important for the local client. */