Merge remote-tracking branch 'upstream/master'

This commit is contained in:
dP
2021-10-01 23:42:21 +03:00
21 changed files with 407 additions and 750 deletions

View File

@@ -14,16 +14,23 @@ Game::Game() {
t->cm.hs_last_month = t->cm.hs_this_month; t->cm.hs_last_month = t->cm.hs_this_month;
t->cm.cs_last_month = t->cm.cs_this_month; t->cm.cs_last_month = t->cm.cs_this_month;
t->cm.hr_last_month = t->cm.hr_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_last_month = t->cm.houses_reconstructed_this_month;
t->cm.houses_reconstructed_this_month = 0; t->cm.houses_reconstructed_this_month = 0;
t->cm.houses_demolished_last_month = t->cm.houses_demolished_this_month; t->cm.houses_demolished_last_month = t->cm.houses_demolished_this_month;
t->cm.houses_demolished_this_month = 0; 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->towns_growth_tiles.clear();
}); });
this->events.listen<event::TownBuilt>(event::Slot::GAME, [this] (const event::TownBuilt &event) { this->events.listen<event::TownBuilt>(event::Slot::GAME, [this] (const event::TownBuilt &event) {
auto t = event.town; auto t = event.town;
t->cm.hs_total = t->cm.hs_last_month = t->cm.hs_this_month = 0; 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) { if (event.town->cache.num_houses <= event.prev_houses) {
event.town->cm.hs_total++; event.town->cm.hs_total++;
event.town->cm.hs_this_month++; 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::TownGrowthFailed>(event::Slot::GAME, [this] (const event::TownGrowthFailed &event) { this->events.listen<event::TownGrowthFailed>(event::Slot::GAME, [this] (const event::TownGrowthFailed &event) {
event.town->cm.cs_total++; event.town->cm.cs_total++;
event.town->cm.cs_this_month++; 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::HouseRebuilt>(event::Slot::GAME, [this] (const event::HouseRebuilt &event) { this->events.listen<event::HouseRebuilt>(event::Slot::GAME, [this] (const event::HouseRebuilt &event) {
if (event.was_successful) { if (event.was_successful) {
event.town->cm.houses_reconstructed_this_month++; 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 { } else {
event.town->cm.houses_demolished_this_month++; 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::HouseBuilt>(event::Slot::GAME, [this] (const event::HouseBuilt &event) { this->events.listen<event::HouseBuilt>(event::Slot::GAME, [this] (const event::HouseBuilt &event) {
event.town->cm.houses_constructing++; event.town->cm.houses_constructing++;
event.town->cm.real_population += event.house_spec->population; 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::HouseCleared>(event::Slot::GAME, [this] (const event::HouseCleared &event) { this->events.listen<event::HouseCleared>(event::Slot::GAME, [this] (const event::HouseCleared &event) {
@@ -67,22 +74,30 @@ Game::Game() {
event.town->cm.real_population -= event.house_spec->population; event.town->cm.real_population -= event.house_spec->population;
}); });
this->events.listen<event::HouseDestroyed>(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::HouseCompleted>(event::Slot::GAME, [this] (const event::HouseCompleted &event) { this->events.listen<event::HouseCompleted>(event::Slot::GAME, [this] (const event::HouseCompleted &event) {
event.town->cm.houses_constructing--; event.town->cm.houses_constructing--;
}); });
this->events.listen<event::HouseDestroyed>(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::TownCachesRebuilt>(event::Slot::GAME, [this] (const event::TownCachesRebuilt &event) { this->events.listen<event::TownCachesRebuilt>(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()) { for (Town *town : Town::Iterate()) {
town->cm.real_population = 0; town->cm.real_population = 0;
town->cm.houses_constructing = 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++) { for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_HOUSE)) continue; 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 (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 } // namespace citymania

View File

@@ -7,27 +7,16 @@
namespace citymania { 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 { class Game {
public: protected:
typedef std::map<TileIndex, TownGrowthTileState> TownsGrowthTilesIndex;
TownsGrowthTilesIndex towns_growth_tiles_last_month; TownsGrowthTilesIndex towns_growth_tiles_last_month;
TownsGrowthTilesIndex towns_growth_tiles; TownsGrowthTilesIndex towns_growth_tiles;
public:
event::Dispatcher events; event::Dispatcher events;
Game(); 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) { TownGrowthTileState get_town_growth_tile(TileIndex tile) {
auto a = this->towns_growth_tiles.find(tile); auto a = this->towns_growth_tiles.find(tile);

View File

@@ -966,7 +966,7 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th)
void CalcCBAcceptanceBorders(TileHighlight &th, TileIndex tile, SpriteID border_pal, SpriteID ground_pal) { void CalcCBAcceptanceBorders(TileHighlight &th, TileIndex tile, SpriteID border_pal, SpriteID ground_pal) {
int tx = TileX(tile), ty = TileY(tile); 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; bool in_zone = false;
ZoningBorder border = ZoningBorder::NONE; ZoningBorder border = ZoningBorder::NONE;
_town_kdtree.FindContained( _town_kdtree.FindContained(

View File

@@ -15,469 +15,32 @@
namespace citymania { namespace citymania {
static const uint SAVEGAME_DATA_FORMAT_VERSION = 2; void SlTownGrowthTiles::Save(Town *t) const {
static const uint CITYMANIA_GRFID = 0x534B0501U; // Luukland_Citybuilder grf id actually SlSetStructListLength(t->cm.growth_tiles.size());
for (auto &p : t->cm.growth_tiles) SlObject(&p, this->GetDescription());
}
void SlTownGrowthTiles::Load(Town *t) const {
// copied form storage_sl.cpp citymania::TownsGrowthTilesIndex::value_type tmp;
static const SaveLoad _storage_desc[] = { size_t length = SlGetStructListLength(10000);
SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION), for (size_t i = 0; i < length; i++) {
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE), SlObject(&tmp, this->GetLoadDescription());
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION), t->cm.growth_tiles.insert(tmp);
};
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);
} }
} }
static void DecodeTowns(BitIStream &bs) void SlTownGrowthTilesLastMonth::Save(Town *t) const {
{ SlSetStructListLength(t->cm.growth_tiles_last_month.size());
for (Town *t : Town::Iterate()) { for (auto &p : t->cm.growth_tiles_last_month) SlObject(&p, this->GetDescription());
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);
}
} }
static void EncodeTownsGrowthTiles(BitOStream &bs, Game::TownsGrowthTilesIndex &tiles) void SlTownGrowthTilesLastMonth::Load(Town *t) const {
{ citymania::TownsGrowthTilesIndex::value_type tmp;
bs.WriteBytes(tiles.size(), 4); size_t length = SlGetStructListLength(10000);
for (Game::TownsGrowthTilesIndex::iterator p = tiles.begin(); for (size_t i = 0; i < length; i++) {
p != tiles.end(); p++) { SlObject(&tmp, this->GetLoadDescription());
bs.WriteBytes(p->first, 4); t->cm.growth_tiles_last_month.insert(tmp);
bs.WriteBytes((uint8)p->second, 1);
} }
} }
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<CargoID> 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<CargoID> 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<CargoID> 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<SaveLoad> 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 } // namespace citymania

View File

@@ -2,16 +2,39 @@
#define CITYMANIA_SAVELOAD_HPP #define CITYMANIA_SAVELOAD_HPP
#include "../saveload/saveload.h" #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<void *>(static_cast<const void *>(std::addressof(static_cast<base *>(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 { namespace citymania {
struct PSACChunkHandler : ChunkHandler { class SlTownGrowthTiles : public DefaultSaveLoadHandler<SlTownGrowthTiles, Town> {
PSACChunkHandler() : ChunkHandler('PSAC', CH_TABLE) {} 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(Town *t) const override;
void Save() const override; void Load(Town *t) const override;
};
class SlTownGrowthTilesLastMonth : public DefaultSaveLoadHandler<SlTownGrowthTilesLastMonth, Town> {
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 } // namespace citymania
#endif #endif

View File

@@ -53,7 +53,7 @@ struct LimitsSettings {
struct CBSettings { struct CBSettings {
uint8 requirements_type; // 0 - regular 1 - income-based requirements (new cb only) uint8 requirements_type; // 0 - regular 1 - income-based requirements (new cb only)
std::vector<CBRequirement> requirements; std::vector<CBRequirement> 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 storage_size; // cargo storage multiplier (x * monthly requirements)
uint8 town_protection_range; // Claimed town protection range (square from centre), overlaped with tz0 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 uint16 claim_max_houses; // Max amount of houses claimable town can have

View File

@@ -286,7 +286,7 @@ SpriteID TileZoneCheckNewCBBorders(TileIndex tile) {
//Check CB town acceptance area //Check CB town acceptance area
SpriteID TileZoneCheckCBBorders(TileIndex tile) { SpriteID TileZoneCheckCBBorders(TileIndex tile) {
for (Town *town : Town::Iterate()) { 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 CM_SPR_PALETTE_ZONING_LIGHT_BLUE;
} }
return INVALID_SPRITE_ID; // no town return INVALID_SPRITE_ID; // no town

View File

@@ -1,8 +1,22 @@
#ifndef CMEXT_TOWN_HPP #ifndef CMEXT_TOWN_HPP
#define CMEXT_TOWN_HPP #define CMEXT_TOWN_HPP
#include <map>
namespace citymania { 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<TileIndex, TownGrowthTileState> TownsGrowthTilesIndex;
namespace ext { namespace ext {
class Town { class Town {
@@ -23,6 +37,9 @@ public:
uint16 houses_reconstructed_last_month = 0; ///< number of houses rebuild last month 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_this_month = 0; ///< number of houses demolished this month
uint16 houses_demolished_last_month = 0; ///< number of houses demolished last month uint16 houses_demolished_last_month = 0; ///< number of houses demolished last month
TownsGrowthTilesIndex growth_tiles_last_month;
TownsGrowthTilesIndex growth_tiles;
}; };
} // namespace ext } // namespace ext

View File

@@ -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*/ /* Increase town's counter for all goods types only if delivered near town*/
if(CB_Enabled()){ 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; st->town->cb.delivered[cargo_type] += accepted_total;
InvalidateWindowData(WC_CB_TOWN, st->town->index); InvalidateWindowData(WC_CB_TOWN, st->town->index);
} }

View File

@@ -22,6 +22,8 @@
#include "table/strings.h" #include "table/strings.h"
#include "../citymania/cm_saveload.hpp"
#include "../safeguards.h" #include "../safeguards.h"
/** /**
@@ -316,6 +318,8 @@ public:
void LoadCheck(CompanyProperties *c) const override { this->Load(c); } void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
}; };
static_assert(NUM_CARGO == 64); // cargo_income needs version bump
class SlCompanyEconomy : public DefaultSaveLoadHandler<SlCompanyEconomy, CompanyProperties> { class SlCompanyEconomy : public DefaultSaveLoadHandler<SlCompanyEconomy, CompanyProperties> {
public: public:
inline static const SaveLoad description[] = { 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, 32, SLV_170, SLV_EXTEND_CARGOTYPES),
SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32), 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; inline const static SaveLoadCompatTable compat_description = _company_economy_compat;
@@ -495,6 +500,8 @@ static const SaveLoad _company_desc[] = {
SLEG_STRUCT("cur_economy", SlCompanyEconomy), SLEG_STRUCT("cur_economy", SlCompanyEconomy),
SLEG_STRUCTLIST("old_economy", SlCompanyOldEconomy), SLEG_STRUCTLIST("old_economy", SlCompanyOldEconomy),
SLEG_CONDSTRUCTLIST("liveries", SlCompanyLiveries, SLV_34, SL_MAX_VERSION), 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 { struct PLYRChunkHandler : ChunkHandler {

View File

@@ -171,6 +171,7 @@ struct PATSChunkHandler : ChunkHandler {
_pathfinding_settings, _pathfinding_settings,
_script_settings, _script_settings,
_world_settings, _world_settings,
citymania::_settings,
}; };
static std::vector<SettingVariant> settings_table; static std::vector<SettingVariant> settings_table;

View File

@@ -14,8 +14,6 @@
#include "../newgrf_storage.h" #include "../newgrf_storage.h"
#include "../citymania/cm_saveload.hpp"
#include "../safeguards.h" #include "../safeguards.h"
/** Description of the data to save and load in #PersistentStorage. */ /** 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[] = { static const ChunkHandlerRef persistent_storage_chunk_handlers[] = {
PSAC, PSAC,
}; };

View File

@@ -21,6 +21,7 @@
#include "../tilematrix_type.hpp" #include "../tilematrix_type.hpp"
#include "../citymania/cm_main.hpp" #include "../citymania/cm_main.hpp"
#include "../citymania/cm_saveload.hpp"
#include "../safeguards.h" #include "../safeguards.h"
@@ -273,6 +274,23 @@ static const SaveLoad _town_desc[] = {
SLEG_CONDSTRUCTLIST("supplied", SlTownSupplied, SLV_165, SL_MAX_VERSION), SLEG_CONDSTRUCTLIST("supplied", SlTownSupplied, SLV_165, SL_MAX_VERSION),
SLEG_CONDSTRUCTLIST("received", SlTownReceived, 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), 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 { struct HIDSChunkHandler : NewGRFMappingChunkHandler {

View File

@@ -86,6 +86,7 @@ static auto &GenericSettingTables()
_script_settings, _script_settings,
_world_settings, _world_settings,
citymania::_settings, citymania::_settings,
citymania::_cmclient_settings,
}; };
return _generic_setting_tables; return _generic_setting_tables;
} }

View File

@@ -1640,7 +1640,6 @@ static SettingsContainer &GetSettingsTree()
viewports->Add(new SettingEntry("gui.measure_tooltip")); viewports->Add(new SettingEntry("gui.measure_tooltip"));
viewports->Add(new SettingEntry("gui.loading_indicators")); viewports->Add(new SettingEntry("gui.loading_indicators"));
viewports->Add(new SettingEntry("gui.show_track_reservation")); 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_industries"));
viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_stations")); viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_stations"));
viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_houses")); viewports->Add(new SettingEntry("gui.cm_land_tooltips_for_houses"));

View File

@@ -74,6 +74,7 @@ SettingTable _win32_settings{ _win32_settings_table };
#endif /* _WIN32 */ #endif /* _WIN32 */
namespace citymania { namespace citymania {
SettingTable _settings{ _citymania_settings_table }; SettingTable _settings{ _citymania_settings_table };
SettingTable _cmclient_settings{ _cmclient_settings_table };
} // namespace citymania } // namespace citymania
/* Begin - Callback Functions for the various settings. */ /* Begin - Callback Functions for the various settings. */

View File

@@ -39,6 +39,7 @@ extern SettingTable _win32_settings;
#endif /* _WIN32 */ #endif /* _WIN32 */
namespace citymania { namespace citymania {
extern SettingTable _settings; extern SettingTable _settings;
extern SettingTable _cmclient_settings;
} // namespace citymania } // namespace citymania
static const uint GAME_DIFFICULTY_NUM = 18; static const uint GAME_DIFFICULTY_NUM = 18;

View File

@@ -203,7 +203,6 @@ struct GUISettings {
bool newgrf_show_old_versions; ///< whether to show old versions in the NewGRF list 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 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_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 bool cm_runway_too_short_warning; ///< warn about aircrafts using too short runways

View File

@@ -2,6 +2,8 @@ set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated)
set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table) set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table)
set(TABLE_INI_SOURCE_FILES 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}/company_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/difficulty_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}/win32_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/world_settings.ini ${CMAKE_CURRENT_SOURCE_DIR}/world_settings.ini
${CMAKE_CURRENT_SOURCE_DIR}/citymania_settings.ini
) )
if (HOST_BINARY_DIR) if (HOST_BINARY_DIR)

View File

@@ -1,21 +1,15 @@
[pre-amble] [pre-amble]
static void cm_v_RedrawStatusBar(int32 p1);
static std::initializer_list<const char*> _order_mod_actions{"nothing", "full_load", "transfer", "unload_all", "feeder_load", "feeder_unload", "no_load"};
static const SettingVariant _citymania_settings_table[] = { static const SettingVariant _citymania_settings_table[] = {
[post-amble] [post-amble]
}; };
[templates] [templates]
SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $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),
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] [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] [defaults]
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC flags = SF_NONE
interval = 0 interval = 0
str = STR_NULL str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT
@@ -23,252 +17,17 @@ strval = STR_NULL
pre_cb = nullptr pre_cb = nullptr
post_cb = nullptr post_cb = nullptr
load = nullptr load = nullptr
from = SL_MIN_VERSION from = SLV_TABLE_CHUNKS
to = SL_MAX_VERSION to = SL_MAX_VERSION
cat = SC_ADVANCED cat = SC_ADVANCED
extra = 0 extra = 0
startup = false startup = false
[SDTC_BOOL] ; Common CityMania settings
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] [SDT_VAR]
var = gui.cm_pause_after_load var = citymania.cb.acceptance_range
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 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 def = 25
min = 0 min = 0
max = 100 max = UINT16_MAX
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

View File

@@ -0,0 +1,264 @@
[pre-amble]
static void cm_v_RedrawStatusBar(int32 p1);
static std::initializer_list<const char*> _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