diff --git a/src/citymania/cm_game.cpp b/src/citymania/cm_game.cpp index 833504ba8f..246da3ef24 100644 --- a/src/citymania/cm_game.cpp +++ b/src/citymania/cm_game.cpp @@ -14,16 +14,23 @@ Game::Game() { t->cm.hs_last_month = t->cm.hs_this_month; t->cm.cs_last_month = t->cm.cs_this_month; t->cm.hr_last_month = t->cm.hr_this_month; + t->cm.hs_this_month = 0; + t->cm.cs_this_month = 0; + t->cm.hr_this_month = 0; t->cm.houses_reconstructed_last_month = t->cm.houses_reconstructed_this_month; t->cm.houses_reconstructed_this_month = 0; t->cm.houses_demolished_last_month = t->cm.houses_demolished_this_month; t->cm.houses_demolished_this_month = 0; + + t->cm.growth_tiles_last_month.swap(t->cm.growth_tiles); + t->cm.growth_tiles.clear(); } - this->towns_growth_tiles_last_month = this->towns_growth_tiles; + this->towns_growth_tiles_last_month.swap(this->towns_growth_tiles); this->towns_growth_tiles.clear(); }); + this->events.listen(event::Slot::GAME, [this] (const event::TownBuilt &event) { auto t = event.town; t->cm.hs_total = t->cm.hs_last_month = t->cm.hs_this_month = 0; @@ -35,30 +42,30 @@ Game::Game() { if (event.town->cache.num_houses <= event.prev_houses) { event.town->cm.hs_total++; event.town->cm.hs_this_month++; - this->set_town_growth_tile(event.tile, TownGrowthTileState::HS); + this->set_town_growth_tile(event.town, event.tile, TownGrowthTileState::HS); } }); this->events.listen(event::Slot::GAME, [this] (const event::TownGrowthFailed &event) { event.town->cm.cs_total++; event.town->cm.cs_this_month++; - this->set_town_growth_tile(event.tile, TownGrowthTileState::CS); + this->set_town_growth_tile(event.town, event.tile, TownGrowthTileState::CS); }); this->events.listen(event::Slot::GAME, [this] (const event::HouseRebuilt &event) { if (event.was_successful) { event.town->cm.houses_reconstructed_this_month++; - this->set_town_growth_tile(event.tile, TownGrowthTileState::RH_REBUILT); + this->set_town_growth_tile(event.town, event.tile, TownGrowthTileState::RH_REBUILT); } else { event.town->cm.houses_demolished_this_month++; - this->set_town_growth_tile(event.tile, TownGrowthTileState::RH_REMOVED); + this->set_town_growth_tile(event.town, event.tile, TownGrowthTileState::RH_REMOVED); } }); 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->set_town_growth_tile(event.tile, TownGrowthTileState::NEW_HOUSE); + this->set_town_growth_tile(event.town, event.tile, TownGrowthTileState::NEW_HOUSE); }); this->events.listen(event::Slot::GAME, [this] (const event::HouseCleared &event) { @@ -67,22 +74,30 @@ Game::Game() { event.town->cm.real_population -= event.house_spec->population; }); - this->events.listen(event::Slot::GAME, [this] (const event::HouseDestroyed &event) { - const Company *company = Company::GetIfValid(event.company_id); - if (company && company->cm.is_server) { - this->set_town_growth_tile(event.tile, TownGrowthTileState::HR); - event.town->cm.hr_total++; - } - }); - this->events.listen(event::Slot::GAME, [this] (const event::HouseCompleted &event) { event.town->cm.houses_constructing--; }); + this->events.listen(event::Slot::GAME, [this] (const event::HouseDestroyed &event) { + const Company *company = Company::GetIfValid(event.company_id); + if (company && company->cm.is_server) { + this->set_town_growth_tile(event.town, event.tile, TownGrowthTileState::HR); + event.town->cm.hr_total++; + } + }); + this->events.listen(event::Slot::GAME, [this] (const event::TownCachesRebuilt &event) { + this->towns_growth_tiles.clear(); + this->towns_growth_tiles_last_month.clear(); for (Town *town : Town::Iterate()) { town->cm.real_population = 0; town->cm.houses_constructing = 0; + for (auto &[tile, state] : town->cm.growth_tiles) { + if (this->towns_growth_tiles[tile] < state) this->towns_growth_tiles[tile] = state; + } + for (auto &[tile, state] : town->cm.growth_tiles_last_month) { + if (this->towns_growth_tiles_last_month[tile] < state) this->towns_growth_tiles_last_month[tile] = state; + } } for (TileIndex t = 0; t < MapSize(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; @@ -99,8 +114,9 @@ Game::Game() { }); } -void Game::set_town_growth_tile(TileIndex tile, TownGrowthTileState state) { +void Game::set_town_growth_tile(Town *town, TileIndex tile, TownGrowthTileState state) { if (this->towns_growth_tiles[tile] < state) this->towns_growth_tiles[tile] = state; + if (town->cm.growth_tiles[tile] < state) town->cm.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 5a7f03393d..e6948006a9 100644 --- a/src/citymania/cm_game.hpp +++ b/src/citymania/cm_game.hpp @@ -7,28 +7,17 @@ namespace citymania { -/* BEGIN CMClient growth tiles */ -enum class TownGrowthTileState : uint8 { - NONE = 0, - RH_REMOVED, - NEW_HOUSE, - RH_REBUILT, // rebuilt and removed houses are also - CS, - HS, - HR -}; - class Game { -public: - typedef std::map TownsGrowthTilesIndex; +protected: TownsGrowthTilesIndex towns_growth_tiles_last_month; TownsGrowthTilesIndex towns_growth_tiles; +public: event::Dispatcher events; Game(); - void set_town_growth_tile(TileIndex tile, TownGrowthTileState state); - + void set_town_growth_tile(Town *town, TileIndex tile, TownGrowthTileState state); + TownGrowthTileState get_town_growth_tile(TileIndex tile) { auto a = this->towns_growth_tiles.find(tile); auto b = this->towns_growth_tiles_last_month.find(tile); diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index efafff64e3..06cc5c7e9b 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -966,7 +966,7 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) void CalcCBAcceptanceBorders(TileHighlight &th, TileIndex tile, SpriteID border_pal, SpriteID ground_pal) { int tx = TileX(tile), ty = TileY(tile); - uint16 radius = _settings_client.gui.cm_cb_distance; + uint16 radius = _settings_game.citymania.cb.acceptance_range; bool in_zone = false; ZoningBorder border = ZoningBorder::NONE; _town_kdtree.FindContained( diff --git a/src/citymania/cm_saveload.cpp b/src/citymania/cm_saveload.cpp index 9dc43d7976..217e85b49b 100644 --- a/src/citymania/cm_saveload.cpp +++ b/src/citymania/cm_saveload.cpp @@ -15,469 +15,32 @@ namespace citymania { -static const uint SAVEGAME_DATA_FORMAT_VERSION = 2; -static const uint CITYMANIA_GRFID = 0x534B0501U; // Luukland_Citybuilder grf id actually +void SlTownGrowthTiles::Save(Town *t) const { + SlSetStructListLength(t->cm.growth_tiles.size()); + for (auto &p : t->cm.growth_tiles) SlObject(&p, this->GetDescription()); +} - -// copied form storage_sl.cpp -static const SaveLoad _storage_desc[] = { - SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE), - SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION), -}; - - -static void EncodeTowns(BitOStream &bs) -{ - for (const Town *t : Town::Iterate()) { - bs.WriteBytes(t->cm.growing_by_chance, 1); - bs.WriteBytes(t->cm.houses_reconstructed_this_month, 2); - bs.WriteBytes(t->cm.houses_reconstructed_last_month, 2); - bs.WriteBytes(t->cm.houses_demolished_this_month, 2); - bs.WriteBytes(t->cm.houses_demolished_last_month, 2); - bs.WriteBytes(t->cm.hs_total, 4); - bs.WriteBytes(t->cm.hs_this_month, 2); - bs.WriteBytes(t->cm.hs_last_month, 2); - bs.WriteBytes(t->cm.cs_total, 4); - bs.WriteBytes(t->cm.cs_this_month, 2); - bs.WriteBytes(t->cm.cs_last_month, 2); - bs.WriteBytes(t->cm.hr_total, 4); - bs.WriteBytes(t->cm.hr_this_month, 2); - bs.WriteBytes(t->cm.hr_last_month, 2); +void SlTownGrowthTiles::Load(Town *t) const { + citymania::TownsGrowthTilesIndex::value_type tmp; + size_t length = SlGetStructListLength(10000); + for (size_t i = 0; i < length; i++) { + SlObject(&tmp, this->GetLoadDescription()); + t->cm.growth_tiles.insert(tmp); } } -static void DecodeTowns(BitIStream &bs) -{ - for (Town *t : Town::Iterate()) { - t->cm.growing_by_chance = bs.ReadBytes(1); - t->cm.houses_reconstructed_this_month = bs.ReadBytes(2); - t->cm.houses_reconstructed_last_month = bs.ReadBytes(2); - t->cm.houses_demolished_this_month = bs.ReadBytes(2); - t->cm.houses_demolished_last_month = bs.ReadBytes(2); - t->cm.hs_total = bs.ReadBytes(4); - t->cm.hs_this_month = bs.ReadBytes(2); - t->cm.hs_last_month = bs.ReadBytes(2); - t->cm.cs_total = bs.ReadBytes(4); - t->cm.cs_this_month = bs.ReadBytes(2); - t->cm.cs_last_month = bs.ReadBytes(2); - t->cm.hr_total = bs.ReadBytes(4); - t->cm.hr_this_month = bs.ReadBytes(2); - t->cm.hr_last_month = bs.ReadBytes(2); - } +void SlTownGrowthTilesLastMonth::Save(Town *t) const { + SlSetStructListLength(t->cm.growth_tiles_last_month.size()); + for (auto &p : t->cm.growth_tiles_last_month) SlObject(&p, this->GetDescription()); } -static void EncodeTownsGrowthTiles(BitOStream &bs, Game::TownsGrowthTilesIndex &tiles) -{ - bs.WriteBytes(tiles.size(), 4); - for (Game::TownsGrowthTilesIndex::iterator p = tiles.begin(); - p != tiles.end(); p++) { - bs.WriteBytes(p->first, 4); - bs.WriteBytes((uint8)p->second, 1); +void SlTownGrowthTilesLastMonth::Load(Town *t) const { + citymania::TownsGrowthTilesIndex::value_type tmp; + size_t length = SlGetStructListLength(10000); + for (size_t i = 0; i < length; i++) { + SlObject(&tmp, this->GetLoadDescription()); + t->cm.growth_tiles_last_month.insert(tmp); } } -static void DecodeTownsGrowthTiles(BitIStream &bs, Game::TownsGrowthTilesIndex &tiles) -{ - uint n = bs.ReadBytes(4); - for (uint i = 0; i < n; i++) { - TileIndex tile = bs.ReadBytes(4); - TownGrowthTileState state = (TownGrowthTileState)bs.ReadBytes(1); - tiles[tile] = state; - } -} - -static void EncodeCompanies(BitOStream &bs) -{ - for (const Company *c : Company::Iterate()) { - bs.WriteBytes(c->cm.is_server, 1); - bs.WriteBytes(c->cm.is_scored, 1); - for (uint i = 0; i < NUM_CARGO; i++) - bs.WriteMoney(c->cur_economy.cm.cargo_income[i]); - for (uint j = 0; j < MAX_HISTORY_QUARTERS; j++) - for (uint i = 0; i < NUM_CARGO; i++) - bs.WriteMoney(c->old_economy[j].cm.cargo_income[i]); - } -} - -static void DecodeCompanies(BitIStream &bs) -{ - for (Company *c : Company::Iterate()) { - c->cm.is_server = bs.ReadBytes(1); - c->cm.is_scored = bs.ReadBytes(1); - for (uint i = 0; i < NUM_CARGO; i++) - c->cur_economy.cm.cargo_income[i] = bs.ReadMoney(); - for (uint j = 0; j < MAX_HISTORY_QUARTERS; j++) - for (uint i = 0; i < NUM_CARGO; i++) - c->old_economy[j].cm.cargo_income[i] = bs.ReadMoney(); - } -} - -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(0, 1); - // bs.WriteBytes(0, 1); - // bs.WriteBytes(0, 1); - // bs.WriteBytes(0, 1); - // bs.WriteBytes(0, 2); - // 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 (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) { - auto version = bs.ReadBytes(2); - // if (version != 0) - // ConsoleError("Save uses incompatible CB data version {}", version); - // ConsoleError("Server is not supposed to load CB games"); - // if (!Controller::saveload_decode(bs)) - // return false; - bs.ReadBytes(1); /* _settings_game.citymania.cb.acceptance_range / _settings_client.gui.cb_distance_check */ - return true; - // bs.ReadBytes(1); /* _settings_game.citymania.cb.requirements_type */ - // 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 */ - // bs.ReadBytes(1); /* _settings_game.citymania.cb.smooth_growth_rate */ - // bs.ReadBytes(1); /* _settings_game.citymania.cb.allow_negative_growth */ - // // _settings_game.citymania.cb.requirements.clear(); - // auto n_cargos = bs.ReadBytes(1); - // std::vector cb_cargos; - // for (uint i = 0; i < n_cargos; i++) { - // auto cargo_id = (CargoID)bs.ReadBytes(1); - // if (cargo_id >= NUM_CARGO) { - // DEBUG(sl, 0, "Invalid CargoID in CB towns cargo data (%u)", cargo_id); - // // ConsoleError("Invalid CargoID in CB towns cargo data ({})", cargo_id); - // return false; - // } - // cb_cargos.push_back(cargo_id); - // auto required = bs.ReadBytes(4); - // auto from = bs.ReadBytes(4); - // auto decay = bs.ReadBytes(1); - // // CB_SetRequirements(cargo_id, required, from, decay); - // // _settings_game.citymania.cb.requirements.push_back(CBRequirement(cargo_id, from, required, decay, i, "")); - // } - - // auto n_towns = bs.ReadBytes(2); - // for (uint i = 0; i < n_towns; i++) { - // auto town_id = bs.ReadBytes(2); - // auto t = Town::GetIfValid(town_id); - // if (!t) { - // DEBUG(sl, 0, "Invalid TownID in CB towns cargo data (%u)", town_id); - // // ConsoleError("Invalid TownID in CB towns cargo data ({})", town_id); - // 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); - // // } - // }; - // return true; -} - -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() { - // Skip if game is not initialized for some reason (i.e. -d desync) - if (!_game) return {}; - - BitOStream bs; - bs.Reserve(1000); - bs.WriteBytes(SAVEGAME_DATA_FORMAT_VERSION, 2); - bs.WriteBytes(_last_client_version, 2); - bs.WriteBytes((uint8)_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((uint8)_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 (_settings_game.citymania.controller_type == ControllerType::CB) - 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 (_settings_game.citymania.controller_type == ControllerType::CB) CBController_saveload_decode(bs); -} - -static void DecodeTownsCargoV1(BitIStream &bs) -{ - 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(); - std::vector cb_cargos; - for (uint i = 0; i < n_cb_cargos; i++) { - uint cargo = bs.ReadBytes(1); - if (cargo >= NUM_CARGO) { - Debug(sl, 0, "Invalid CargoID in CB towns cargo data (%u)", cargo); - return; - } - cb_cargos.push_back(cargo); - uint req = bs.ReadBytes(4); - uint from = bs.ReadBytes(4); - uint decay = bs.ReadBytes(1); - // CB_SetRequirements(cargo, req, from, decay); - } - Town *t; - uint n_affected_towns = bs.ReadBytes(2); - for (uint i = 0; i < n_affected_towns; i++) { - uint town_id = bs.ReadBytes(2); - t = Town::GetIfValid(town_id); - if (!t) { - Debug(sl, 0, "Invalid TownID in CB towns cargo data (%u)", town_id); - return; - } - // auto &tcb = t->cb; - for (auto cargo_id : cb_cargos) { - - bs.ReadBytes(4); // tcb.stored[cargo_id] - bs.ReadBytes(4); // tcb.delivered_last_month[cargo_id] - bs.ReadBytes(4); // tcb.delivered[cargo_id] - bs.ReadBytes(1); /* delivered enough */ - - // tcb.required[cargo_id] = 0; - // tcb.required_last_month[cargo_id] = 0; - } - } -} - -static void DecodeDataV1(BitIStream &bs) { - if (_settings_game.citymania.controller_type != ControllerType::GENERIC) DecodeTownsCargoV1(bs); - for (Town *t : Town::Iterate()) { - t->cm.growing_by_chance = bs.ReadBytes(1); - t->cm.houses_reconstructed_this_month = bs.ReadBytes(2); - t->cm.houses_reconstructed_last_month = bs.ReadBytes(2); - t->cm.houses_demolished_this_month = bs.ReadBytes(2); - t->cm.houses_demolished_last_month = bs.ReadBytes(2); - } - - Town *t; - uint n_affected_towns = bs.ReadBytes(2); - for (uint i = 0; i < n_affected_towns; i++) { - uint town_id = bs.ReadBytes(2); - t = Town::GetIfValid(town_id); - if (!t) { - Debug(sl, 0, "Invalid TownID in CB towns layout errors (%u)", town_id); - continue; - } - t->cm.hs_total = bs.ReadBytes(4); - t->cm.hs_this_month = t->cm.hs_total - bs.ReadBytes(2); - t->cm.hs_last_month = bs.ReadBytes(2); - t->cm.cs_total = bs.ReadBytes(4); - t->cm.cs_this_month = t->cm.cs_total - bs.ReadBytes(2); - t->cm.cs_last_month = bs.ReadBytes(2); - t->cm.hr_total = bs.ReadBytes(4); - t->cm.hr_this_month = t->cm.hr_total -bs.ReadBytes(2); - t->cm.hr_last_month = bs.ReadBytes(2); - } - DecodeTownsGrowthTiles(bs, _game->towns_growth_tiles); - DecodeTownsGrowthTiles(bs, _game->towns_growth_tiles_last_month); -} - -static void DecodeData(u8vector &data) { - if (data.size() == 0) { - Debug(sl, 2, "No CityMania save data"); - return; - } - Debug(sl, 2, "CityMania save data takes %lu bytes", data.size()); - BitIStream bs(data); - try { - uint version = bs.ReadBytes(2); - if (version > SAVEGAME_DATA_FORMAT_VERSION) { - Debug(sl, 0, "Savegame was made with newer version of client, extra save data was not loaded"); - return; - } - Debug(sl, 2, "CityMania savegame data version %u", version); - _last_client_version = bs.ReadBytes(2); - _settings_game.citymania.controller_type = (ControllerType)bs.ReadBytes(1); - if (version <= 1 && _settings_game.citymania.controller_type != ControllerType::GENERIC) - _settings_game.citymania.controller_type = ControllerType::CLASSIC_CB; - 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"); - } - _settings_game.citymania.game_type = (GameType)bs.ReadBytes(1); - bs.ReadBytes(3); // reserved - bs.ReadBytes(4); // reserved - if (version == 1) DecodeDataV1(bs); - else DecodeDataV2(bs); - } - catch (BitIStreamUnexpectedEnd &e) { - Debug(sl, 0, "Invalid CityMania save data"); - } -} - -struct FakePersistentStorage { - uint32 grfid; - uint8 *storage; -}; - -void PSACChunkHandler::Save() const { - /* Write the industries */ - SlTableHeader(_storage_desc); - for (PersistentStorage *ps : PersistentStorage::Iterate()) { - if (ps->grfid == CITYMANIA_GRFID) { - continue; - } - ps->ClearChanges(); - SlSetArrayIndex(ps->index); - SlObject(ps, _storage_desc); - } - - if (_game_mode == GM_EDITOR) { - Debug(sl, 2, "Saving scenario, skip CityMania extra data"); - return; - } - - uint index = 0; - for (PersistentStorage *ps : PersistentStorage::Iterate()) { - if (ps->grfid != CITYMANIA_GRFID) - index = std::max(index, ps->index + 1); - } - - u8vector data = EncodeData(); - int n_chunks = (data.size() + 1023) / 1024; - data.resize(n_chunks * 1024); - Debug(sl, 2, "Citybuilder data takes %u bytes", (uint)data.size()); - FakePersistentStorage ps{CITYMANIA_GRFID, &data[0]}; - - static const SaveLoad _desc[] = { - SLE_CONDVAR(FakePersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDARR(FakePersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION), - }; - - for (int i = 0; i < n_chunks; i++, ps.storage += 1024) { - SlSetArrayIndex(index + i); - SlObject(&ps, _desc); - } -} - -void PSACChunkHandler::Load() const { - int index; - - /* - CITYMANIA_GRFID is used to hide extra data in persitant storages. - To save a bit of memory we only keep at most one PS with this - grfid and it is later discarded on save. - */ - PersistentStorage *ps = NULL; - u8vector cmdata; - uint chunk_size = IsSavegameVersionBefore(SLV_EXTEND_PERSISTENT_STORAGE) ? 64 : 1024; - - const std::vector slt = SlCompatTableHeader(_storage_desc, _storage_sl_compat); - - while ((index = SlIterateArray()) != -1) { - if (ps == NULL) { - assert(PersistentStorage::CanAllocateItem()); - ps = new (index) PersistentStorage(0, 0, 0); - } - SlObject(ps, slt); - - if (ps->grfid == CITYMANIA_GRFID) { - uint8 *data = (uint8 *)(ps->storage); - cmdata.insert(cmdata.end(), data, data + chunk_size); - } else { - ps = NULL; - } - } - - DecodeData(cmdata); -} - } // namespace citymania diff --git a/src/citymania/cm_saveload.hpp b/src/citymania/cm_saveload.hpp index f175e6189b..5df06cda26 100644 --- a/src/citymania/cm_saveload.hpp +++ b/src/citymania/cm_saveload.hpp @@ -2,16 +2,39 @@ #define CITYMANIA_SAVELOAD_HPP #include "../saveload/saveload.h" +#include "../town.h" + +#define CM_SLE_GENERAL(name, cmd, base, variable, type, length, from, to, extra) SaveLoad {name, cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast(static_cast(std::addressof(static_cast(b)->variable))); }, extra, nullptr} +#define CM_SLE_VAR(name, base, variable, type) CM_SLE_GENERAL(name, SL_VAR, base, variable, type, 0, SLV_TABLE_CHUNKS, SL_MAX_VERSION, 0) +#define CM_SLE_VAR(name, base, variable, type) CM_SLE_GENERAL(name, SL_VAR, base, variable, type, 0, SLV_TABLE_CHUNKS, SL_MAX_VERSION, 0) +#define CM_SLE_ARR(name, base, variable, type, length) CM_SLE_GENERAL(name, SL_ARR, base, variable, type, length, SLV_TABLE_CHUNKS, SL_MAX_VERSION, 0) + namespace citymania { -struct PSACChunkHandler : ChunkHandler { - PSACChunkHandler() : ChunkHandler('PSAC', CH_TABLE) {} +class SlTownGrowthTiles : public DefaultSaveLoadHandler { +public: + inline static const SaveLoad description[] = { + CM_SLE_VAR("tile", TownsGrowthTilesIndex::value_type, first, SLE_UINT32), + CM_SLE_VAR("state", TownsGrowthTilesIndex::value_type, second, SLE_UINT8), + }; + inline const static SaveLoadCompatTable compat_description; - void Load() const override; - void Save() const override; + void Save(Town *t) const override; + void Load(Town *t) const override; }; -} // namespace citymania +class SlTownGrowthTilesLastMonth : public DefaultSaveLoadHandler { +public: + inline static const SaveLoad description[] = { + CM_SLE_VAR("tile", TownsGrowthTilesIndex::value_type, first, SLE_UINT32), + CM_SLE_VAR("state", TownsGrowthTilesIndex::value_type, second, SLE_UINT8), + }; + inline const static SaveLoadCompatTable compat_description; + void Save(Town *t) const override; + void Load(Town *t) const override; +}; + +} // namespace citymania #endif diff --git a/src/citymania/cm_settings.hpp b/src/citymania/cm_settings.hpp index c7e47f9912..b83c0db8fb 100644 --- a/src/citymania/cm_settings.hpp +++ b/src/citymania/cm_settings.hpp @@ -53,7 +53,7 @@ struct LimitsSettings { 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 + uint16 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 diff --git a/src/citymania/cm_zoning_cmd.cpp b/src/citymania/cm_zoning_cmd.cpp index e97da18cdb..de55c3a100 100644 --- a/src/citymania/cm_zoning_cmd.cpp +++ b/src/citymania/cm_zoning_cmd.cpp @@ -286,7 +286,7 @@ SpriteID TileZoneCheckNewCBBorders(TileIndex tile) { //Check CB town acceptance area SpriteID TileZoneCheckCBBorders(TileIndex tile) { for (Town *town : Town::Iterate()) { - if (DistanceMax(town->xy, tile) <= _settings_client.gui.cm_cb_distance) + if (DistanceMax(town->xy, tile) <= _settings_game.citymania.cb.acceptance_range) return CM_SPR_PALETTE_ZONING_LIGHT_BLUE; } return INVALID_SPRITE_ID; // no town diff --git a/src/citymania/extensions/cmext_town.hpp b/src/citymania/extensions/cmext_town.hpp index 2ef9f3f4d4..29addac4f3 100644 --- a/src/citymania/extensions/cmext_town.hpp +++ b/src/citymania/extensions/cmext_town.hpp @@ -1,8 +1,22 @@ #ifndef CMEXT_TOWN_HPP #define CMEXT_TOWN_HPP +#include + namespace citymania { +enum class TownGrowthTileState : uint8 { + NONE = 0, + RH_REMOVED, + NEW_HOUSE, + RH_REBUILT, // rebuilt and removed houses are also + CS, + HS, + HR +}; + +typedef std::map TownsGrowthTilesIndex; + namespace ext { class Town { @@ -23,6 +37,9 @@ public: uint16 houses_reconstructed_last_month = 0; ///< number of houses rebuild last month uint16 houses_demolished_this_month = 0; ///< number of houses demolished this month uint16 houses_demolished_last_month = 0; ///< number of houses demolished last month + + TownsGrowthTilesIndex growth_tiles_last_month; + TownsGrowthTilesIndex growth_tiles; }; } // namespace ext diff --git a/src/economy.cpp b/src/economy.cpp index e19eddfd52..ec9b1c5918 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1121,7 +1121,7 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti /* Increase town's counter for all goods types only if delivered near town*/ if(CB_Enabled()){ - if (_settings_client.gui.cm_cb_distance == 0 || (DistanceManhattan(st->town->xy, st->xy) <= _settings_client.gui.cm_cb_distance)) { + if (_settings_game.citymania.cb.acceptance_range == 0 || (DistanceManhattan(st->town->xy, st->xy) <= _settings_game.citymania.cb.acceptance_range)) { st->town->cb.delivered[cargo_type] += accepted_total; InvalidateWindowData(WC_CB_TOWN, st->town->index); } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index cc8a9f9cb6..aaa617d9af 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -22,6 +22,8 @@ #include "table/strings.h" +#include "../citymania/cm_saveload.hpp" + #include "../safeguards.h" /** @@ -316,6 +318,8 @@ public: void LoadCheck(CompanyProperties *c) const override { this->Load(c); } }; +static_assert(NUM_CARGO == 64); // cargo_income needs version bump + class SlCompanyEconomy : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { @@ -330,6 +334,7 @@ public: SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, SLV_170, SLV_EXTEND_CARGOTYPES), SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32), + CM_SLE_ARR("__cm_cargo_income", CompanyEconomyEntry, cm.cargo_income, SLE_INT64, NUM_CARGO), }; inline const static SaveLoadCompatTable compat_description = _company_economy_compat; @@ -495,6 +500,8 @@ static const SaveLoad _company_desc[] = { SLEG_STRUCT("cur_economy", SlCompanyEconomy), SLEG_STRUCTLIST("old_economy", SlCompanyOldEconomy), SLEG_CONDSTRUCTLIST("liveries", SlCompanyLiveries, SLV_34, SL_MAX_VERSION), + CM_SLE_VAR("__cm_is_server", CompanyProperties, cm.is_server, SLE_BOOL), + CM_SLE_VAR("__cm_is_scored", CompanyProperties, cm.is_scored, SLE_BOOL), }; struct PLYRChunkHandler : ChunkHandler { diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index 1b1db8fa61..76f8c6593e 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -171,6 +171,7 @@ struct PATSChunkHandler : ChunkHandler { _pathfinding_settings, _script_settings, _world_settings, + citymania::_settings, }; static std::vector settings_table; diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index c5b4e7bbd0..4db185e9af 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -14,8 +14,6 @@ #include "../newgrf_storage.h" -#include "../citymania/cm_saveload.hpp" - #include "../safeguards.h" /** Description of the data to save and load in #PersistentStorage. */ @@ -55,7 +53,7 @@ struct PSACChunkHandler : ChunkHandler { } }; -static const citymania::PSACChunkHandler PSAC; +static const PSACChunkHandler PSAC; static const ChunkHandlerRef persistent_storage_chunk_handlers[] = { PSAC, }; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 1bd9d29a7a..b563b59e0a 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -21,6 +21,7 @@ #include "../tilematrix_type.hpp" #include "../citymania/cm_main.hpp" +#include "../citymania/cm_saveload.hpp" #include "../safeguards.h" @@ -273,6 +274,23 @@ static const SaveLoad _town_desc[] = { SLEG_CONDSTRUCTLIST("supplied", SlTownSupplied, SLV_165, SL_MAX_VERSION), SLEG_CONDSTRUCTLIST("received", SlTownReceived, SLV_165, SL_MAX_VERSION), SLEG_CONDSTRUCTLIST("acceptance_matrix", SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE), + + CM_SLE_VAR("__cm_growing_by_chance", Town, cm.growing_by_chance, SLE_BOOL), + CM_SLE_VAR("__cm_houses_reconstructed_this_month", Town, cm.houses_reconstructed_this_month, SLE_UINT16), + CM_SLE_VAR("__cm_houses_reconstructed_last_month", Town, cm.houses_reconstructed_last_month, SLE_UINT16), + CM_SLE_VAR("__cm_houses_demolished_this_month", Town, cm.houses_demolished_this_month, SLE_UINT16), + CM_SLE_VAR("__cm_houses_demolished_last_month", Town, cm.houses_demolished_last_month, SLE_UINT16), + CM_SLE_VAR("__cm_hs_total", Town, cm.hs_total, SLE_UINT32), + CM_SLE_VAR("__cm_hs_this_month", Town, cm.hs_this_month, SLE_UINT16), + CM_SLE_VAR("__cm_hs_last_month", Town, cm.hs_last_month, SLE_UINT16), + CM_SLE_VAR("__cm_cs_total", Town, cm.cs_total, SLE_UINT32), + CM_SLE_VAR("__cm_cs_this_month", Town, cm.cs_this_month, SLE_UINT16), + CM_SLE_VAR("__cm_cs_last_month", Town, cm.cs_last_month, SLE_UINT16), + CM_SLE_VAR("__cm_hr_total", Town, cm.hr_total, SLE_UINT32), + CM_SLE_VAR("__cm_hr_this_month", Town, cm.hr_this_month, SLE_UINT16), + CM_SLE_VAR("__cm_hr_last_month", Town, cm.hr_last_month, SLE_UINT16), + SLEG_CONDSTRUCTLIST("__cm_growth_tiles", citymania::SlTownGrowthTiles, SLV_TABLE_CHUNKS, SL_MAX_VERSION), + SLEG_CONDSTRUCTLIST("__cm_growth_tiles_last_month", citymania::SlTownGrowthTilesLastMonth, SLV_TABLE_CHUNKS, SL_MAX_VERSION), }; struct HIDSChunkHandler : NewGRFMappingChunkHandler { diff --git a/src/settings.cpp b/src/settings.cpp index 9de649082d..451f0f8607 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -86,6 +86,7 @@ static auto &GenericSettingTables() _script_settings, _world_settings, citymania::_settings, + citymania::_cmclient_settings, }; return _generic_setting_tables; } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index f976ccf7d8..1973f32f50 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1640,7 +1640,6 @@ static SettingsContainer &GetSettingsTree() viewports->Add(new SettingEntry("gui.measure_tooltip")); viewports->Add(new SettingEntry("gui.loading_indicators")); viewports->Add(new SettingEntry("gui.show_track_reservation")); - viewports->Add(new SettingEntry("gui.cm_cb_distance")); viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_industries")); viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_stations")); viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_houses")); diff --git a/src/settings_table.cpp b/src/settings_table.cpp index 3fffa3be18..f2aa0bba09 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -74,6 +74,7 @@ SettingTable _win32_settings{ _win32_settings_table }; #endif /* _WIN32 */ namespace citymania { SettingTable _settings{ _citymania_settings_table }; + SettingTable _cmclient_settings{ _cmclient_settings_table }; } // namespace citymania /* Begin - Callback Functions for the various settings. */ diff --git a/src/settings_table.h b/src/settings_table.h index f4f870b4d2..c9695f6327 100644 --- a/src/settings_table.h +++ b/src/settings_table.h @@ -39,6 +39,7 @@ extern SettingTable _win32_settings; #endif /* _WIN32 */ namespace citymania { extern SettingTable _settings; + extern SettingTable _cmclient_settings; } // namespace citymania static const uint GAME_DIFFICULTY_NUM = 18; diff --git a/src/settings_type.h b/src/settings_type.h index 529255ffdf..ae5c77d3c7 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -203,7 +203,6 @@ struct GUISettings { bool newgrf_show_old_versions; ///< whether to show old versions in the NewGRF list uint8 newgrf_default_palette; ///< default palette to use for NewGRFs without action 14 palette information - uint8 cm_cb_distance; ///< zoning cb distance bool cm_show_industry_forbidden_tiles; ///< higlight areas where industry placement is forbidden regardless of terrain bool cm_runway_too_short_warning; ///< warn about aircrafts using too short runways diff --git a/src/table/settings/CMakeLists.txt b/src/table/settings/CMakeLists.txt index 1ea2edb2f4..401c3b372c 100644 --- a/src/table/settings/CMakeLists.txt +++ b/src/table/settings/CMakeLists.txt @@ -2,6 +2,8 @@ set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated) set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table) set(TABLE_INI_SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/citymania_settings.ini + ${CMAKE_CURRENT_SOURCE_DIR}/cmclient_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/company_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/difficulty_settings.ini @@ -22,7 +24,6 @@ set(TABLE_INI_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/world_settings.ini - ${CMAKE_CURRENT_SOURCE_DIR}/citymania_settings.ini ) if (HOST_BINARY_DIR) diff --git a/src/table/settings/citymania_settings.ini b/src/table/settings/citymania_settings.ini index d461dfb9c0..8d452ea62a 100644 --- a/src/table/settings/citymania_settings.ini +++ b/src/table/settings/citymania_settings.ini @@ -1,21 +1,15 @@ [pre-amble] -static void cm_v_RedrawStatusBar(int32 p1); - -static std::initializer_list _order_mod_actions{"nothing", "full_load", "transfer", "unload_all", "feeder_load", "feeder_unload", "no_load"}; - static const SettingVariant _citymania_settings_table[] = { [post-amble] }; [templates] -SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), -SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), [validation] -SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); +SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size"); [defaults] -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +flags = SF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT @@ -23,252 +17,17 @@ strval = STR_NULL pre_cb = nullptr post_cb = nullptr load = nullptr -from = SL_MIN_VERSION +from = SLV_TABLE_CHUNKS to = SL_MAX_VERSION cat = SC_ADVANCED extra = 0 startup = false -[SDTC_BOOL] -var = gui.cm_keep_depot_tools -def = false -str = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS -strhelp = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT -cat = SC_BASIC +; Common CityMania settings -[SDTC_BOOL] -var = gui.cm_pause_after_load -def = false -str = STR_CM_CONFIG_SETTING_PAUSE_AFTER_LOAD -strhelp = STR_CM_CONFIG_SETTING_PAUSE_AFTER_LOAD_HELPTEXT -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.cm_no_loading_on_transfer_order -def = true -str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_TRANSFER - -[SDTC_BOOL] -var = gui.cm_no_loading_on_unload_order -def = true -str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD - -[SDTC_OMANY] -var = gui.cm_ctrl_order_mod -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 1 -max = 6 -full = _order_mod_actions -str = STR_CM_CONFIG_SETTING_ORDER_MOD_CTRL -strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE -cat = SC_BASIC - -[SDTC_OMANY] -var = gui.cm_shift_order_mod -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 0 -max = 6 -full = _order_mod_actions -str = STR_CM_CONFIG_SETTING_ORDER_MOD_SHIFT -strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE -cat = SC_BASIC - -[SDTC_OMANY] -var = gui.cm_ctrl_shift_order_mod -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 2 -max = 6 -full = _order_mod_actions -str = STR_CM_CONFIG_SETTING_ORDER_MOD_CTRL_SHIFT -strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE -cat = SC_BASIC - -[SDTC_OMANY] -var = gui.cm_alt_order_mod -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 4 -max = 6 -full = _order_mod_actions -str = STR_CM_CONFIG_SETTING_ORDER_MOD_ALT -strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE -cat = SC_BASIC - -[SDTC_OMANY] -var = gui.cm_alt_shift_order_mod -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 3 -max = 6 -full = _order_mod_actions -str = STR_CM_CONFIG_SETTING_ORDER_MOD_ALT_SHIFT -strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE -cat = SC_BASIC - -[SDTC_OMANY] -var = gui.cm_alt_ctrl_order_mod -type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN -def = 5 -max = 6 -full = _order_mod_actions -str = STR_CM_CONFIG_SETTING_ORDER_MOD_ALT_CTRL -strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.cm_show_industry_forbidden_tiles -def = false -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.cm_runway_too_short_warning -def = true -str = STR_CONFIG_SETTING_WARN_IF_RUNWAY_IS_TOO_SHORT - -[SDTC_VAR] -var = gui.cm_powerfund_money -type = SLE_UINT -guiflags = SGF_CURRENCY -def = 200000 -min = 0 -max = 2000000 -str = STR_CONFIG_SETTING_POWERFUND_MONEY -strval = STR_JUST_CURRENCY_LONG - -[SDTC_VAR] -var = gui.cm_powerfund_houses +[SDT_VAR] +var = citymania.cb.acceptance_range type = SLE_UINT16 -def = 10000 -min = 0 -max = 10000 -interval = 10 -str = STR_CONFIG_SETTING_POWERFUND_HOUSES -strval = STR_JUST_COMMA - -[SDTC_VAR] -var = gui.cm_cb_distance -type = SLE_UINT8 def = 25 min = 0 -max = 100 -interval = 5 -str = STR_CB_DISTANCE_CHECK -strval = STR_JUST_COMMA -post_cb = [](auto) { MarkWholeScreenDirty(); } - -[SDTC_BOOL] -var = gui.cm_land_tooltips_for_industries -def = true -str = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_INDUSTRIES -strhelp = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_INDUSTRIES_HELPTEXT - -[SDTC_BOOL] -var = gui.cm_land_tooltips_for_stations -def = true -str = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_STATIONS -strhelp = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_STATIONS_HELPTEXT - -[SDTC_BOOL] -var = gui.cm_land_tooltips_for_houses -def = false -str = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_HOUSES -strhelp = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_HOUSES_HELPTEXT - -[SDTC_VAR] -var = gui.cm_fn_mod -type = SLE_UINT8 -guiflags = SGF_MULTISTRING -def = 2 -min = 0 -max = 3 -str = STR_CM_CONFIG_SETTING_MODIFIER_FN -strhelp = STR_CM_CONFIG_SETTING_MODIFIER_FN_HELPTEXT -strval = STR_CM_CONFIG_SETTING_MODIFIER_NONE -cat = SC_ADVANCED - -[SDTC_VAR] -var = gui.cm_remove_mod -type = SLE_UINT8 -guiflags = SGF_MULTISTRING -def = 2 -min = 0 -max = 3 -str = STR_CM_CONFIG_SETTING_MODIFIER_REMOVE -strhelp = STR_CM_CONFIG_SETTING_MODIFIER_REMOVE_HELPTEXT -strval = STR_CM_CONFIG_SETTING_MODIFIER_NONE -cat = SC_ADVANCED - -[SDTC_VAR] -var = gui.cm_estimate_mod -type = SLE_UINT8 -guiflags = SGF_MULTISTRING -def = 1 -min = 0 -max = 3 -str = STR_CM_CONFIG_SETTING_MODIFIER_ESTIMATE -strhelp = STR_CM_CONFIG_SETTING_MODIFIER_ESTIMATE_HELPTEXT -strval = STR_CM_CONFIG_SETTING_MODIFIER_NONE -cat = SC_ADVANCED - -[SDTC_VAR] -var = gui.cm_shaded_trees -type = SLE_UINT8 -guiflags = SGF_MULTISTRING -def = 2 -min = 0 -max = 2 -str = STR_CM_CONFIG_SETTING_SHADED_TREES -strhelp = STR_CM_CONFIG_SETTING_SHADED_TREES_HELPTEXT -strval = STR_CM_CONFIG_SETTING_SHADED_TREES_OFF -cat = SC_ADVANCED -post_cb = [](auto) { MarkWholeScreenDirty(); } - -[SDTC_BOOL] -var = gui.cm_show_apm -def = false -str = STR_CM_CONFIG_SETTING_SHOW_APM -strhelp = STR_CM_CONFIG_SETTING_SHOW_APM_HELPTEXT -cat = SC_ADVANCED -post_cb = cm_v_RedrawStatusBar - -[SDTC_VAR] -var = gui.cm_graph_background -type = SLE_UINT8 -guiflags = SGF_MULTISTRING -def = 0 -min = 0 -max = 1 -str = STR_CM_CONFIG_SETTING_GRAPH_BACKGROUND -strhelp = STR_CM_CONFIG_SETTING_GRAPH_BACKGROUND_HELPTEXT -strval = STR_CM_CONFIG_SETTING_GRAPH_BACKGROUND_BLACK -cat = SC_ADVANCED - -[SDTC_BOOL] -var = gui.cm_open_vehicle_for_shared_clone -def = false -str = STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE -strhelp = STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE_HELPTEXT -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.cm_open_orders_for_new_vehicles -def = false -str = STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES -strhelp = STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES_HELPTEXT -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.cm_use_improved_station_join -def = false -str = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN -strhelp = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT -cat = SC_BASIC - -[SDTC_BOOL] -var = gui.cm_show_client_overlay -def = false -cat = SC_BASIC +max = UINT16_MAX diff --git a/src/table/settings/cmclient_settings.ini b/src/table/settings/cmclient_settings.ini new file mode 100644 index 0000000000..e04ef2d22e --- /dev/null +++ b/src/table/settings/cmclient_settings.ini @@ -0,0 +1,264 @@ +[pre-amble] +static void cm_v_RedrawStatusBar(int32 p1); + +static std::initializer_list _order_mod_actions{"nothing", "full_load", "transfer", "unload_all", "feeder_load", "feeder_unload", "no_load"}; + +static const SettingVariant _cmclient_settings_table[] = { +[post-amble] +}; +[templates] +SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), + +[validation] +SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); + +[defaults] +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +interval = 0 +str = STR_NULL +strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT +strval = STR_NULL +pre_cb = nullptr +post_cb = nullptr +load = nullptr +from = SL_MIN_VERSION +to = SL_MAX_VERSION +cat = SC_ADVANCED +extra = 0 +startup = false + +[SDTC_BOOL] +var = gui.cm_keep_depot_tools +def = false +str = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS +strhelp = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_pause_after_load +def = false +str = STR_CM_CONFIG_SETTING_PAUSE_AFTER_LOAD +strhelp = STR_CM_CONFIG_SETTING_PAUSE_AFTER_LOAD_HELPTEXT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_no_loading_on_transfer_order +def = true +str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_TRANSFER + +[SDTC_BOOL] +var = gui.cm_no_loading_on_unload_order +def = true +str = STR_CONFIG_SETTING_AUTOSET_NOLOAD_ON_UNLOAD + +[SDTC_OMANY] +var = gui.cm_ctrl_order_mod +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 6 +full = _order_mod_actions +str = STR_CM_CONFIG_SETTING_ORDER_MOD_CTRL +strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_shift_order_mod +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 0 +max = 6 +full = _order_mod_actions +str = STR_CM_CONFIG_SETTING_ORDER_MOD_SHIFT +strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_ctrl_shift_order_mod +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 2 +max = 6 +full = _order_mod_actions +str = STR_CM_CONFIG_SETTING_ORDER_MOD_CTRL_SHIFT +strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_alt_order_mod +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 4 +max = 6 +full = _order_mod_actions +str = STR_CM_CONFIG_SETTING_ORDER_MOD_ALT +strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_alt_shift_order_mod +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 3 +max = 6 +full = _order_mod_actions +str = STR_CM_CONFIG_SETTING_ORDER_MOD_ALT_SHIFT +strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_OMANY] +var = gui.cm_alt_ctrl_order_mod +type = SLE_UINT8 +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 5 +max = 6 +full = _order_mod_actions +str = STR_CM_CONFIG_SETTING_ORDER_MOD_ALT_CTRL +strval = STR_CM_CONFIG_SETTING_ORDER_MOD_ACTION_NONE +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_show_industry_forbidden_tiles +def = false +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_runway_too_short_warning +def = true +str = STR_CONFIG_SETTING_WARN_IF_RUNWAY_IS_TOO_SHORT + +[SDTC_VAR] +var = gui.cm_powerfund_money +type = SLE_UINT +guiflags = SGF_CURRENCY +def = 200000 +min = 0 +max = 2000000 +str = STR_CONFIG_SETTING_POWERFUND_MONEY +strval = STR_JUST_CURRENCY_LONG + +[SDTC_VAR] +var = gui.cm_powerfund_houses +type = SLE_UINT16 +def = 10000 +min = 0 +max = 10000 +interval = 10 +str = STR_CONFIG_SETTING_POWERFUND_HOUSES +strval = STR_JUST_COMMA + +[SDTC_BOOL] +var = gui.cm_land_tooltips_for_industries +def = true +str = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_INDUSTRIES +strhelp = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_INDUSTRIES_HELPTEXT + +[SDTC_BOOL] +var = gui.cm_land_tooltips_for_stations +def = true +str = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_STATIONS +strhelp = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_STATIONS_HELPTEXT + +[SDTC_BOOL] +var = gui.cm_land_tooltips_for_houses +def = false +str = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_HOUSES +strhelp = STR_CM_CONFIG_SETTING_LAND_TOOLTIPS_FOR_HOUSES_HELPTEXT + +[SDTC_VAR] +var = gui.cm_fn_mod +type = SLE_UINT8 +guiflags = SGF_MULTISTRING +def = 2 +min = 0 +max = 3 +str = STR_CM_CONFIG_SETTING_MODIFIER_FN +strhelp = STR_CM_CONFIG_SETTING_MODIFIER_FN_HELPTEXT +strval = STR_CM_CONFIG_SETTING_MODIFIER_NONE +cat = SC_ADVANCED + +[SDTC_VAR] +var = gui.cm_remove_mod +type = SLE_UINT8 +guiflags = SGF_MULTISTRING +def = 2 +min = 0 +max = 3 +str = STR_CM_CONFIG_SETTING_MODIFIER_REMOVE +strhelp = STR_CM_CONFIG_SETTING_MODIFIER_REMOVE_HELPTEXT +strval = STR_CM_CONFIG_SETTING_MODIFIER_NONE +cat = SC_ADVANCED + +[SDTC_VAR] +var = gui.cm_estimate_mod +type = SLE_UINT8 +guiflags = SGF_MULTISTRING +def = 1 +min = 0 +max = 3 +str = STR_CM_CONFIG_SETTING_MODIFIER_ESTIMATE +strhelp = STR_CM_CONFIG_SETTING_MODIFIER_ESTIMATE_HELPTEXT +strval = STR_CM_CONFIG_SETTING_MODIFIER_NONE +cat = SC_ADVANCED + +[SDTC_VAR] +var = gui.cm_shaded_trees +type = SLE_UINT8 +guiflags = SGF_MULTISTRING +def = 2 +min = 0 +max = 2 +str = STR_CM_CONFIG_SETTING_SHADED_TREES +strhelp = STR_CM_CONFIG_SETTING_SHADED_TREES_HELPTEXT +strval = STR_CM_CONFIG_SETTING_SHADED_TREES_OFF +cat = SC_ADVANCED +post_cb = [](auto) { MarkWholeScreenDirty(); } + +[SDTC_BOOL] +var = gui.cm_show_apm +def = false +str = STR_CM_CONFIG_SETTING_SHOW_APM +strhelp = STR_CM_CONFIG_SETTING_SHOW_APM_HELPTEXT +cat = SC_ADVANCED +post_cb = cm_v_RedrawStatusBar + +[SDTC_VAR] +var = gui.cm_graph_background +type = SLE_UINT8 +guiflags = SGF_MULTISTRING +def = 0 +min = 0 +max = 1 +str = STR_CM_CONFIG_SETTING_GRAPH_BACKGROUND +strhelp = STR_CM_CONFIG_SETTING_GRAPH_BACKGROUND_HELPTEXT +strval = STR_CM_CONFIG_SETTING_GRAPH_BACKGROUND_BLACK +cat = SC_ADVANCED + +[SDTC_BOOL] +var = gui.cm_open_vehicle_for_shared_clone +def = false +str = STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE +strhelp = STR_CM_CONFIG_SETTING_OPEN_VEHICLE_FOR_SHARED_CLONE_HELPTEXT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_open_orders_for_new_vehicles +def = false +str = STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES +strhelp = STR_CM_CONFIG_SETTING_OPEN_ORDERS_FOR_NEW_VEHICLES_HELPTEXT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_use_improved_station_join +def = false +str = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN +strhelp = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT +cat = SC_BASIC + +[SDTC_BOOL] +var = gui.cm_show_client_overlay +def = false +cat = SC_BASIC +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC