From 5e681193def096d810d834670391129ac68ff4d6 Mon Sep 17 00:00:00 2001 From: dP Date: Sat, 20 Jun 2020 01:30:56 +0300 Subject: [PATCH 1/3] Use uint16 for some town counteres --- src/citymania/extensions/cmext_town.hpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/citymania/extensions/cmext_town.hpp b/src/citymania/extensions/cmext_town.hpp index dc51ccd17d..710a87e5b5 100644 --- a/src/citymania/extensions/cmext_town.hpp +++ b/src/citymania/extensions/cmext_town.hpp @@ -10,20 +10,19 @@ public: bool growing_by_chance = false; ///< whether town is growing due to 1/12 chance uint32 real_population = 0; ///< population including unfinished houses uint32 hs_total = 0; ///< number of skipped house buildings (HS) in total - uint32 hs_total_prev = 0; ///< number of skipped house buildings (HS) in total at the end of last month - uint32 hs_last_month = 0; ///< number of skipped house buildings (HS) during last month + uint16 hs_total_prev = 0; ///< number of skipped house buildings (HS) in total at the end of last month + uint16 hs_last_month = 0; ///< number of skipped house buildings (HS) during last month uint32 cs_total = 0; ///< number of skipped growth cycles (CS) in total - uint32 cs_total_prev = 0; ///< number of skipped growth cycles (CS) in total at the end of last month - uint32 cs_last_month = 0; ///< number of skipped growth cycles (CS) during last month + uint16 cs_total_prev = 0; ///< number of skipped growth cycles (CS) in total at the end of last month + uint16 cs_last_month = 0; ///< number of skipped growth cycles (CS) during last month uint32 hr_total = 0; ///< number of houses removed by the server (HR) in total - uint32 hr_total_prev = 0; ///< number of houses removed by the server (HR) in total at the end of last month - uint32 hr_last_month = 0; ///< number of houses removed by the server (HR) during last month - uint32 houses_constructing = 0; ///< number of houses currently being built - uint32 houses_reconstructed_this_month = 0; ///< number of houses rebuilt this month - uint32 houses_reconstructed_last_month = 0; ///< number of houses rebuild last month - uint32 houses_demolished_this_month = 0; ///< number of houses demolished this month - uint32 houses_demolished_last_month = 0; ///< number of houses demolished last month - + uint16 hr_total_prev = 0; ///< number of houses removed by the server (HR) in total at the end of last month + uint16 hr_last_month = 0; ///< number of houses removed by the server (HR) during last month + uint16 houses_constructing = 0; ///< number of houses currently being built + uint16 houses_reconstructed_this_month = 0; ///< number of houses rebuilt this 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_last_month = 0; ///< number of houses demolished last month }; } // namespace citymania From b054653146c3c2a59d6d370a3664dd10f16d36d0 Mon Sep 17 00:00:00 2001 From: dP Date: Wed, 1 Jul 2020 00:23:06 +0300 Subject: [PATCH 2/3] Add cmexport console command to dump various data into json file --- source.list | 4 + src/citymania/cm_console_cmds.cpp | 31 ++++ src/citymania/cm_console_cmds.hpp | 12 ++ src/citymania/cm_export.cpp | 273 ++++++++++++++++++++++++++++++ src/citymania/cm_export.hpp | 12 ++ src/console_cmds.cpp | 4 + src/train_cmd.cpp | 4 + 7 files changed, 340 insertions(+) create mode 100644 src/citymania/cm_console_cmds.cpp create mode 100644 src/citymania/cm_console_cmds.hpp create mode 100644 src/citymania/cm_export.cpp create mode 100644 src/citymania/cm_export.hpp diff --git a/source.list b/source.list index 3d1d04c4b1..c12ba62391 100644 --- a/source.list +++ b/source.list @@ -1193,7 +1193,11 @@ sound/null_s.cpp thread.h # CityMania +citymania/cm_console_cmds.hpp +citymania/cm_console_cmds.cpp citymania/cm_event.hpp +citymania/cm_export.hpp +citymania/cm_export.cpp citymania/cm_game.hpp citymania/cm_game.cpp citymania/cm_main.hpp diff --git a/src/citymania/cm_console_cmds.cpp b/src/citymania/cm_console_cmds.cpp new file mode 100644 index 0000000000..8414c50a3e --- /dev/null +++ b/src/citymania/cm_console_cmds.cpp @@ -0,0 +1,31 @@ +#include "../stdafx.h" + +#include "cm_console_cmds.hpp" + +#include "cm_export.hpp" + +#include "../console_func.h" +#include "../console_type.h" + +#include "../safeguards.h" + +namespace citymania { + +static void IConsoleHelp(const char *str) +{ + IConsolePrintF(CC_WARNING, "- %s", str); +} + +bool ConExport(byte argc, char *argv[]) { + if (argc == 0) { + IConsoleHelp("Exports various game data in json format to openttd.json file"); + return true; + } + + auto filename = "openttd.json"; + citymania::ExportOpenttdData(filename); + IConsolePrintF(CC_DEFAULT, "Data successfully saved to %s", filename); + return true; +} + +} // namespace citymania diff --git a/src/citymania/cm_console_cmds.hpp b/src/citymania/cm_console_cmds.hpp new file mode 100644 index 0000000000..b01e03fd6e --- /dev/null +++ b/src/citymania/cm_console_cmds.hpp @@ -0,0 +1,12 @@ +#ifndef CM_CONSOLE_CMDS_HPP +#define CM_CONSOLE_CMDS_HPP + +namespace citymania { + +bool ConExport(byte argc, char *argv[]); + +} // namespace citymania + +#endif + + diff --git a/src/citymania/cm_export.cpp b/src/citymania/cm_export.cpp new file mode 100644 index 0000000000..1e247e1868 --- /dev/null +++ b/src/citymania/cm_export.cpp @@ -0,0 +1,273 @@ +#include "../stdafx.h" + +#include "cm_export.hpp" + +#include "../cargotype.h" +#include "../gfx_func.h" +#include "../gfx_type.h" +#include "../engine_base.h" +#include "../spritecache.h" +#include "../strings_func.h" +#include "../strings_type.h" +#include "../table/palettes.h" +#include "../table/sprites.h" +#include "../table/train_cmd.h" + +#include +#include +#include +#include + +#include "../safeguards.h" + +namespace citymania { + +extern SpriteID (*GetDefaultTrainSprite)(uint8, Direction); // train_cmd.cpp + +namespace data_export { + +class JsonWriter { +protected: + int i = 0; + bool no_comma = true; + char buffer[128]; + +public: + std::ofstream f; + + JsonWriter(const std::string &fname) { + f.open(fname.c_str()); + f << "OPENTTD = {"; + no_comma = true; + } + + ~JsonWriter() { + this->ident(false); + f << "}" << std::endl; + f.close(); + } + + void ident(bool comma=true) { + if (comma && !no_comma) f << ","; + no_comma = false; + f << std::endl; + for(int j = 0; j < i; j++) f << " "; + } + + void key(const char *k) { + const char *kn; + for (kn = k + strlen(k); kn >= k && *kn != '>' && *kn != '.'; kn--); + kn++; + this->ident(); + f << "\"" << kn << "\": "; + } + + void value(bool val) { + f << (val ? "true" : "false"); + } + + void value(unsigned int val) { + f << val; + } + + void value(uint64 val) { + f << val; + } + + void value(Money val) { + f << val; + } + + void value(int val) { + f << val; + } + + void value(const char *v) { + f << "\"" << v << "\""; + } + + void value(const std::string &s) { + f << "\"" << s << "\""; + } + + template + void kv(const char *k, T v) { + key(k); + value(v); + } + + void ks(const char *k, StringID s) { + GetString(buffer, s, lastof(buffer)); + key(k); + value(buffer); + } + + void begin_dict_with_key(const char *k) { + key(k); + f << "{"; + no_comma = true; + i++; + } + + void begin_dict() { + this->ident(); + f << "{"; + no_comma = true; + i++; + } + + void end_dict() { + i--; + this->ident(false); + f << "}"; + } + + void begin_list_with_key(const char *k) { + key(k); + f << "["; + no_comma = true; + i++; + } + + void end_list() { + i--; + this->ident(false); + f << "]"; + } +}; + +#define JKV(j, field) j.kv(#field, field) + +void WriteHouseSpecInfo(JsonWriter &j) { + j.begin_list_with_key("cargo_specs"); + const CargoSpec *cs; + char buffer[128]; + char cargo_label[16]; + bool first = true; + SetDParam(0, 123); + FOR_ALL_CARGOSPECS(cs) { + j.begin_dict(); + JKV(j, cs->initial_payment); + j.kv("id", cs->bitnum); + j.kv("transit_days_1", cs->transit_days[0]); + j.kv("transit_days_2", cs->transit_days[1]); + JKV(j, cs->weight); + JKV(j, cs->multiplier); + JKV(j, cs->is_freight); + JKV(j, cs->legend_colour); + JKV(j, cs->rating_colour); + JKV(j, cs->sprite); + j.ks("name", cs->name); + j.ks("name_single", cs->name_single); + j.ks("units_volume", cs->units_volume); + j.ks("quantifier", cs->quantifier); + j.ks("abbrev", cs->abbrev); + + for (uint i = 0; i < sizeof(cs->label); i++) { + cargo_label[i] = GB(cs->label, (uint8)(sizeof(cs->label) - i - 1) * 8, 8); + } + cargo_label[sizeof(cs->label)] = '\0'; + JKV(j, cs->label); + j.kv("label_str", cargo_label); + j.end_dict(); + } + j.end_list(); +} + +// extern const Palette _palette; +void WritePaletteInfo(JsonWriter &j) { + j.begin_list_with_key("palette"); + for (uint i = 0; i < 256; i++) { + j.begin_dict(); + auto &c = _palette.palette[i]; + JKV(j, c.r); + JKV(j, c.g); + JKV(j, c.b); + std::ostringstream hex; + hex << "#" << std::hex << std::setfill('0'); + hex << std::setw(2) << (int)c.r; + hex << std::setw(2) << (int)c.g; + hex << std::setw(2) << (int)c.b; + j.kv("hex", hex.str()); + j.end_dict(); + } + j.end_list(); + j.begin_list_with_key("gradients"); + for (auto i = 0; i < COLOUR_END; i++) { + if (i != 0) j.f << ","; + j.f << std::endl << "["; + for (auto k = 0; k < 8; k++) { + if (k != 0) j.f << ", "; + j.f << (int)_colour_gradient[i][k] << " "; + } + j.f << "]"; + } + j.end_list(); + const byte *remap = GetNonSprite(GB(PALETTE_TO_RED, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1; +} + +void WriteEngineInfo(JsonWriter &j) { + j.begin_list_with_key("engines"); + const Engine *e; + for (const Engine *e : Engine::Iterate()) { + if (e->type != VEH_TRAIN) continue; + j.begin_dict(); + JKV(j, e->index); + j.kv("name", (e->name ? e->name : "null")); + j.kv("cost", e->GetCost()); + j.kv("running_cost", e->GetRunningCost()); + { + j.begin_dict_with_key("info"); + JKV(j, e->info.cargo_type); + JKV(j, e->info.cargo_age_period); + JKV(j, e->info.climates); + JKV(j, e->info.base_intro); + JKV(j, e->info.lifelength); + JKV(j, e->info.base_life); + JKV(j, e->info.refit_mask); + JKV(j, e->info.refit_cost); + JKV(j, e->info.load_amount); + j.ks("name", e->info.string_id); + j.end_dict(); + } + { + const RailVehicleInfo *rvi = &e->u.rail; + j.begin_dict_with_key("rail"); + JKV(j, rvi->image_index); + JKV(j, rvi->railveh_type); + JKV(j, rvi->railtype); + JKV(j, rvi->max_speed); + JKV(j, rvi->power); + JKV(j, rvi->weight); + JKV(j, rvi->running_cost); + JKV(j, rvi->running_cost_class); + JKV(j, rvi->engclass); + JKV(j, rvi->tractive_effort); + JKV(j, rvi->air_drag); + JKV(j, rvi->capacity); + SpriteID sprite = GetDefaultTrainSprite(e->original_image_index, DIR_W); + JKV(j, sprite); + if (rvi->railveh_type == RAILVEH_MULTIHEAD) { + j.kv("rev_sprite", + GetDefaultTrainSprite(e->original_image_index + 1, DIR_W)); + } else if (rvi->railveh_type == RAILVEH_WAGON) { + j.kv("full_sprite", + sprite + _wagon_full_adder[e->original_image_index]); + } + j.end_dict(); + } + j.end_dict(); + } + j.end_list(); +} + +} // namespace export + +void ExportOpenttdData(const std::string &filename) { + data_export::JsonWriter j(filename); + data_export::WriteHouseSpecInfo(j); + data_export::WritePaletteInfo(j); + data_export::WriteEngineInfo(j); +} + +} // namespace citymania diff --git a/src/citymania/cm_export.hpp b/src/citymania/cm_export.hpp new file mode 100644 index 0000000000..b83259500a --- /dev/null +++ b/src/citymania/cm_export.hpp @@ -0,0 +1,12 @@ +#ifndef CM_EXPORT_HPP +#define CM_EXPORT_HPP + +namespace citymania { + +void ExportOpenttdData(const std::string &filename); + +} // namespace citymania + +#endif + + diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 4706bfd914..a6a6bb4922 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -40,6 +40,8 @@ #include "table/strings.h" #include +#include "citymania/cm_console_cmds.hpp" + #include "safeguards.h" /* scriptfile handling */ @@ -2207,4 +2209,6 @@ void IConsoleStdLibRegister() /* NewGRF development stuff */ IConsoleCmdRegister("reload_newgrfs", ConNewGRFReload, ConHookNewGRFDeveloperTool); IConsoleCmdRegister("newgrf_profile", ConNewGRFProfile, ConHookNewGRFDeveloperTool); + + IConsoleCmdRegister("cmexport", citymania::ConExport); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 5d02764b55..886d2b274b 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4018,3 +4018,7 @@ Trackdir Train::GetVehicleTrackdir() const return TrackDirectionToTrackdir(FindFirstTrack(this->track), this->direction); } + +namespace citymania { + auto GetDefaultTrainSprite = &::GetDefaultTrainSprite; +} From 46bd8ab608784b010bf1072d5fe8b201ef1461fe Mon Sep 17 00:00:00 2001 From: dP Date: Wed, 1 Jul 2020 22:35:30 +0300 Subject: [PATCH 3/3] Track income by cargo type in company economy stats --- projects/openttd_vs140.vcxproj | 5 +++++ projects/openttd_vs140.vcxproj.filters | 15 +++++++++++++++ projects/openttd_vs141.vcxproj | 5 +++++ projects/openttd_vs141.vcxproj.filters | 15 +++++++++++++++ projects/openttd_vs142.vcxproj | 5 +++++ projects/openttd_vs142.vcxproj.filters | 15 +++++++++++++++ source.list | 1 + src/citymania/cm_event.hpp | 14 ++++++++++++++ src/citymania/cm_game.cpp | 6 ++++++ src/citymania/extensions/cmext_company.hpp | 18 ++++++++++++++++++ src/company_base.h | 3 +++ src/economy.cpp | 12 ++++++++++++ 12 files changed, 114 insertions(+) create mode 100644 src/citymania/extensions/cmext_company.hpp diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index 835d1e8ebd..9c9f909492 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -1348,13 +1348,18 @@ + + + + + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index f7f90603a6..ac8f9a6b0b 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -3135,9 +3135,21 @@ Threading + + CityMania + + + CityMania + CityMania + + CityMania + + + CityMania + CityMania @@ -3156,6 +3168,9 @@ CityMania + + CityMania + diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj index d290f90500..2720c85438 100644 --- a/projects/openttd_vs141.vcxproj +++ b/projects/openttd_vs141.vcxproj @@ -1348,13 +1348,18 @@ + + + + + diff --git a/projects/openttd_vs141.vcxproj.filters b/projects/openttd_vs141.vcxproj.filters index f7f90603a6..ac8f9a6b0b 100644 --- a/projects/openttd_vs141.vcxproj.filters +++ b/projects/openttd_vs141.vcxproj.filters @@ -3135,9 +3135,21 @@ Threading + + CityMania + + + CityMania + CityMania + + CityMania + + + CityMania + CityMania @@ -3156,6 +3168,9 @@ CityMania + + CityMania + diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj index 3b8e8e34fe..25b3d0b6dd 100644 --- a/projects/openttd_vs142.vcxproj +++ b/projects/openttd_vs142.vcxproj @@ -1348,13 +1348,18 @@ + + + + + diff --git a/projects/openttd_vs142.vcxproj.filters b/projects/openttd_vs142.vcxproj.filters index f7f90603a6..ac8f9a6b0b 100644 --- a/projects/openttd_vs142.vcxproj.filters +++ b/projects/openttd_vs142.vcxproj.filters @@ -3135,9 +3135,21 @@ Threading + + CityMania + + + CityMania + CityMania + + CityMania + + + CityMania + CityMania @@ -3156,6 +3168,9 @@ CityMania + + CityMania + diff --git a/source.list b/source.list index c12ba62391..7aa7e52f5f 100644 --- a/source.list +++ b/source.list @@ -1204,3 +1204,4 @@ citymania/cm_main.hpp citymania/cm_main.cpp citymania/cm_type.hpp citymania/extensions/cmext_town.hpp +citymania/extensions/cmext_company.hpp diff --git a/src/citymania/cm_event.hpp b/src/citymania/cm_event.hpp index 7f8a6d106f..f0b73ccc6c 100644 --- a/src/citymania/cm_event.hpp +++ b/src/citymania/cm_event.hpp @@ -5,6 +5,7 @@ #include "../cargo_type.h" #include "../company_type.h" #include "../economy_type.h" +#include "../industry_type.h" #include "../station_type.h" #include "../town_type.h" @@ -61,6 +62,19 @@ struct CompanyEvent { Company *company; }; +struct CargoDeliveredToIndustry { + Industry *industry; + CargoID cargo_type; + uint amount; + const Station *station; +}; + +struct CargoDeliveredToUnknown { + CargoID cargo_type; + uint amount; + const Station *station; +}; + struct CargoAccepted { Company *company; CargoID cargo_type; diff --git a/src/citymania/cm_game.cpp b/src/citymania/cm_game.cpp index d544ac0d00..fc3891fc0d 100644 --- a/src/citymania/cm_game.cpp +++ b/src/citymania/cm_game.cpp @@ -2,6 +2,8 @@ #include "cm_game.hpp" +#include "../company_base.h" + #include "../safeguards.h" namespace citymania { @@ -78,6 +80,10 @@ Game::Game() { town->cm.real_population += HouseSpec::Get(house_id)->population; } }); + + this->events.listen([this] (const event::CargoAccepted &event) { + event.company->cur_economy.cm.cargo_income[event.cargo_type] += event.profit; + }); } } // namespace citymania \ No newline at end of file diff --git a/src/citymania/extensions/cmext_company.hpp b/src/citymania/extensions/cmext_company.hpp new file mode 100644 index 0000000000..57b73a826c --- /dev/null +++ b/src/citymania/extensions/cmext_company.hpp @@ -0,0 +1,18 @@ +#ifndef CMEXT_COMPANY_HPP +#define CMEXT_COMPANY_HPP + +#include "../../cargo_type.h" + +namespace citymania { + +namespace ext { +class CompanyEconomyEntry { +public: + Money cargo_income[NUM_CARGO]; ///< Cargo income from each cargo type +}; + +} // namespace citymania + +} // namespace citymania + +#endif diff --git a/src/company_base.h b/src/company_base.h index 095f7d9e6c..df5137f74a 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -17,6 +17,8 @@ #include "settings_type.h" #include "group.h" +#include "citymania/extensions/cmext_company.hpp" + /** Statistics about the economy. */ struct CompanyEconomyEntry { Money income; ///< The amount of income. @@ -24,6 +26,7 @@ struct CompanyEconomyEntry { CargoArray delivered_cargo; ///< The amount of delivered cargo. int32 performance_history; ///< Company score (scale 0-1000) Money company_value; ///< The value of the company. + citymania::ext::CompanyEconomyEntry cm; ///< CityMania extra economy data. }; struct CompanyInfrastructure { diff --git a/src/economy.cpp b/src/economy.cpp index 00bdd6f534..9af0e9e825 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -52,6 +52,8 @@ #include "table/strings.h" #include "table/pricebase.h" +#include "citymania/cm_main.hpp" + #include "safeguards.h" @@ -1053,6 +1055,10 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n /* Update the cargo monitor. */ AddCargoDelivery(cargo_type, company, amount, ST_INDUSTRY, source, st, ind->index); + + if (amount > 0) + citymania::Emit(citymania::event::CargoDeliveredToIndustry{ind, cargo_type, amount, st}); + } return accepted; @@ -1113,6 +1119,12 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, Ti } } + if (accepted_total > 0) { + if (accepted_ind != accepted_total) + citymania::Emit(citymania::event::CargoDeliveredToUnknown{cargo_type, accepted_total - accepted_ind, st}); + citymania::Emit(citymania::event::CargoAccepted{company, cargo_type, accepted_total, st, profit, src_type, src}); + } + return profit; }