GunChleoc has proposed merging lp:~widelands-dev/widelands/elk_moose into lp:widelands.
Commit message: Rename "elk" to "moose" and add map compatibility code - Add support for critter renamings depending on packet version to WorldLegacyLookupTable - New map version property "needs_widelands_version_after" for the website Requested reviews: Widelands Developers (widelands-dev) Related bugs: Bug #1833662 in widelands: "Better handling of 'This map requires widelands Version >x'" https://bugs.launchpad.net/widelands/+bug/1833662 For more details, see: https://code.launchpad.net/~widelands-dev/widelands/elk_moose/+merge/369201 -- Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/elk_moose into lp:widelands.
=== renamed directory 'data/world/critters/elk' => 'data/world/critters/moose' === modified file 'data/world/critters/moose/init.lua' --- data/world/critters/elk/init.lua 2019-04-21 14:57:55 +0000 +++ data/world/critters/moose/init.lua 2019-06-22 11:17:12 +0000 @@ -15,8 +15,8 @@ add_directional_animation(animations, "walk", dirname, "walk", {21, 34}, 20) world:new_critter_type{ - name = "elk", - descname = _ "Elk", + name = "moose", + descname = _ "Moose", editor_category = "critters_herbivores", attributes = { "eatable" }, programs = { === modified file 'data/world/init.lua' --- data/world/init.lua 2017-09-03 10:56:44 +0000 +++ data/world/init.lua 2019-06-22 11:17:12 +0000 @@ -288,7 +288,7 @@ include "world/critters/deer/init.lua" include "world/critters/reindeer/init.lua" include "world/critters/stag/init.lua" - include "world/critters/elk/init.lua" + include "world/critters/moose/init.lua" -- Carnivores world:new_editor_critter_category { === modified file 'data/world/map_generation.lua' --- data/world/map_generation.lua 2017-02-12 09:10:57 +0000 +++ data/world/map_generation.lua 2019-06-22 11:17:12 +0000 @@ -77,17 +77,17 @@ "alder_summer_old", "birch_summer_old", "beech_summer_old", "larch_summer_old", "rowan_summer_old" }, - critters = { "brownbear", "chamois", "elk", "lynx", "reindeer", "stag", "wildboar", "wolf" }, + critters = { "brownbear", "chamois", "moose", "lynx", "reindeer", "stag", "wildboar", "wolf" }, }, { name = "bushes", immovables = { "bush1", "bush2", "bush3", "bush4", "bush5" }, - critters = { "bunny", "elk", "fox", "lynx", "marten", "sheep", "sheep", "wildboar", "wisent", "wolf", "wolf" }, + critters = { "bunny", "moose", "fox", "lynx", "marten", "sheep", "sheep", "wildboar", "wisent", "wolf", "wolf" }, }, { name = "grasses", immovables = { "grass1", "grass2", "grass3" }, - critters = { "bunny", "elk", "fox", "lynx", "marten", "sheep", "sheep", "wolf" }, + critters = { "bunny", "moose", "fox", "lynx", "marten", "sheep", "sheep", "wolf" }, }, { name = "standing_stones", @@ -614,13 +614,13 @@ "birch_summer_old", "beech_summer_old", "larch_summer_old", "rowan_summer_old", }, - critters = { "deer", "elk", "lynx", "reindeer", "wolf" }, + critters = { "deer", "moose", "lynx", "reindeer", "wolf" }, }, { name = "bushes", immovables = { "bush1", "bush2", "bush3", "bush4", "bush5" }, critters = { - "wisent", "wolf", "bunny", "elk", "fox", "lynx", + "wisent", "wolf", "bunny", "moose", "fox", "lynx", "wolf", "marten", "sheep" }, }, @@ -628,7 +628,7 @@ name = "grasses", immovables = { "grass1", "grass2", "grass3" }, critters = { - "wisent", "wolf", "bunny", "elk", "fox", "lynx", + "wisent", "wolf", "bunny", "moose", "fox", "lynx", "wolf", "marten", "sheep" }, }, === modified file 'src/logic/map.cc' --- src/logic/map.cc 2019-05-16 09:15:03 +0000 +++ src/logic/map.cc 2019-06-22 11:17:12 +0000 @@ -714,6 +714,22 @@ pathfieldmgr_->set_size(field_size); } +int Map::needs_widelands_version_after() const { + return map_version_.needs_widelands_version_after; +} + +void Map::calculate_needs_widelands_version_after(bool is_post_one_world) { + if (map_version_.needs_widelands_version_after == 0) { + if (nrplayers_ > 8) { + // We introduced support for 16 payers after Build 19 + map_version_.needs_widelands_version_after = 19; + } else if (is_post_one_world) { + // We merged the worlds in the engine after Build 18 + map_version_.needs_widelands_version_after = 18; + } + } +} + /* * The scenario get/set functions */ === modified file 'src/logic/map.h' --- src/logic/map.h 2019-05-16 09:15:03 +0000 +++ src/logic/map.h 2019-06-22 11:17:12 +0000 @@ -289,6 +289,9 @@ return height_; } + // Map compatibility information for the website + int needs_widelands_version_after() const; + // The next few functions are only valid when the map is loaded as a // scenario. const std::string& get_scenario_player_tribe(PlayerNumber) const; @@ -518,6 +521,10 @@ std::map<Coords, FieldData> resize(EditorGameBase& egbase, const Coords coords, int32_t w, int32_t h); +protected: + // Calculate map compatibility information for the website if it wasn't defined in the map packet + void calculate_needs_widelands_version_after(bool is_post_one_world); + private: void recalc_border(const FCoords&); void recalc_brightness(const FCoords&); === modified file 'src/logic/map_objects/world/critter.cc' --- src/logic/map_objects/world/critter.cc 2019-05-25 08:51:42 +0000 +++ src/logic/map_objects/world/critter.cc 2019-06-22 11:17:12 +0000 @@ -268,7 +268,8 @@ ============================== */ -constexpr uint8_t kCurrentPacketVersion = 1; +// We need to bump this packet version every time we rename a critter, so that the world legacy lookup table will work. +constexpr uint8_t kCurrentPacketVersion = 2; Critter::Loader::Loader() { } @@ -303,7 +304,7 @@ const CritterDescr* descr = nullptr; if (critter_owner == "world") { - critter_name = lookup_table.lookup_critter(critter_name); + critter_name = lookup_table.lookup_critter(critter_name, packet_version); descr = egbase.world().get_critter_descr(critter_name); } else { throw GameDataError( === modified file 'src/logic/map_revision.h' --- src/logic/map_revision.h 2019-02-23 11:00:49 +0000 +++ src/logic/map_revision.h 2019-06-22 11:17:12 +0000 @@ -37,6 +37,8 @@ int32_t map_version_major; int32_t map_version_minor; uint32_t map_version_timestamp; + // Map compatibility information for the website + int needs_widelands_version_after; MapVersion(); }; === modified file 'src/map_io/map_bob_packet.cc' --- src/map_io/map_bob_packet.cc 2019-02-23 11:00:49 +0000 +++ src/map_io/map_bob_packet.cc 2019-06-22 11:17:12 +0000 @@ -36,7 +36,7 @@ EditorGameBase& egbase, MapObjectLoader&, const Coords& coords, - const WorldLegacyLookupTable& lookup_table) { + const WorldLegacyLookupTable& lookup_table, uint16_t packet_version) { const std::string owner = fr.c_string(); char const* const read_name = fr.c_string(); uint8_t subtype = fr.unsigned_8(); @@ -47,7 +47,7 @@ throw GameDataError("unknown legacy bob %s/%s", owner.c_str(), read_name); } - const std::string name = lookup_table.lookup_critter(read_name); + const std::string name = lookup_table.lookup_critter(read_name, packet_version); try { const World& world = egbase.world(); DescriptionIndex const idx = world.get_critter(name.c_str()); @@ -84,7 +84,7 @@ for (uint16_t x = 0; x < map->get_width(); ++x) { uint32_t const nr_bobs = fr.unsigned_32(); for (uint32_t i = 0; i < nr_bobs; ++i) - read_bob(fr, egbase, mol, Coords(x, y), lookup_table); + read_bob(fr, egbase, mol, Coords(x, y), lookup_table, packet_version); } } else { === modified file 'src/map_io/map_bob_packet.h' --- src/map_io/map_bob_packet.h 2019-02-23 11:00:49 +0000 +++ src/map_io/map_bob_packet.h 2019-06-22 11:17:12 +0000 @@ -42,7 +42,7 @@ EditorGameBase&, MapObjectLoader&, const Coords&, - const WorldLegacyLookupTable& lookup_table); + const WorldLegacyLookupTable& lookup_table, uint16_t packet_version); }; } // namespace Widelands === modified file 'src/map_io/map_saver.cc' --- src/map_io/map_saver.cc 2019-03-09 10:01:09 +0000 +++ src/map_io/map_saver.cc 2019-06-22 11:17:12 +0000 @@ -156,7 +156,7 @@ log("Writing Map Version ... "); { MapVersionPacket p; - p.write(fs_, egbase_, *mos_); + p.write(fs_, egbase_); } log("took %ums\n ", timer.ms_since_last_query()); === modified file 'src/map_io/map_version_packet.cc' --- src/map_io/map_version_packet.cc 2019-02-23 11:00:49 +0000 +++ src/map_io/map_version_packet.cc 2019-06-22 11:17:12 +0000 @@ -30,11 +30,17 @@ namespace Widelands { constexpr uint16_t kCurrentPacketVersion = 1; +// Map compatibility information for the website +constexpr int kCurrentNeedsWidelandsVersionAfter = 20; void MapVersionPacket::read(FileSystem& fs, EditorGameBase& egbase, - bool const skip, - MapObjectLoader&) { + bool const skip, bool is_post_one_world) { + + pre_read(fs, egbase.mutable_map(), skip, is_post_one_world); +} + +void MapVersionPacket::pre_read(FileSystem& fs, Map* map, bool skip, bool is_post_one_world) { if (skip) return; @@ -42,7 +48,6 @@ try { prof.read("version", nullptr, fs); } catch (...) { - Map* map = egbase.mutable_map(); map->map_version_.map_version_timestamp = 0; map->map_version_.map_creator_version = "unknown"; return; @@ -55,7 +60,6 @@ if ((packet_version == kCurrentPacketVersion) || (packet_version > kCurrentPacketVersion && forward_compatibility <= kCurrentPacketVersion)) { - Map* map = egbase.mutable_map(); map->map_version_.map_source_url = globv.get_safe_string("map_source_url"); map->map_version_.map_source_release = globv.get_safe_string("map_release"); map->map_version_.map_creator_version = globv.get_safe_string("map_creator_version"); @@ -63,6 +67,8 @@ map->map_version_.map_version_minor = globv.get_safe_int("map_version_minor"); uint32_t ts = static_cast<uint32_t>(globv.get_safe_int("map_version_timestamp")); map->map_version_.map_version_timestamp = ts; + map->map_version_.needs_widelands_version_after = globv.get_int("needs_widelands_version_after", 0); + map->calculate_needs_widelands_version_after(is_post_one_world); } else { throw UnhandledVersionError("MapVersionPacket", packet_version, kCurrentPacketVersion); } @@ -71,7 +77,7 @@ } } -void MapVersionPacket::write(FileSystem& fs, EditorGameBase& egbase, MapObjectSaver&) { +void MapVersionPacket::write(FileSystem& fs, EditorGameBase& egbase) { Profile prof; Section& globs = prof.create_section("global"); @@ -117,6 +123,7 @@ globs.set_int("map_version_timestamp", static_cast<uint32_t>(time(nullptr))); globs.set_int("packet_version", kCurrentPacketVersion); globs.set_int("packet_compatibility", kCurrentPacketVersion); + globs.set_int("needs_widelands_version_after", kCurrentNeedsWidelandsVersionAfter); prof.write("version", false, fs); } === modified file 'src/map_io/map_version_packet.h' --- src/map_io/map_version_packet.h 2019-02-23 11:00:49 +0000 +++ src/map_io/map_version_packet.h 2019-06-22 11:17:12 +0000 @@ -20,11 +20,26 @@ #ifndef WL_MAP_IO_MAP_VERSION_PACKET_H #define WL_MAP_IO_MAP_VERSION_PACKET_H -#include "map_io/map_data_packet.h" +class FileSystem; + +namespace Widelands { + +class EditorGameBase; +class Map; +class MapObjectLoader; +struct MapObjectSaver; /* * This packet contains the version information of the map. */ -MAP_DATA_PACKET(MapVersionPacket) +class MapVersionPacket { +public: + void read(FileSystem&, EditorGameBase&, bool skip, bool is_post_one_world); + void write(FileSystem&, EditorGameBase&); + + void pre_read(FileSystem&, Map*, bool skip, bool is_post_one_world); +}; + +} // namespace Widelands #endif // end of include guard: WL_MAP_IO_MAP_VERSION_PACKET_H === modified file 'src/map_io/widelands_map_loader.cc' --- src/map_io/widelands_map_loader.cc 2019-05-26 03:14:41 +0000 +++ src/map_io/widelands_map_loader.cc 2019-06-22 11:17:12 +0000 @@ -82,6 +82,10 @@ mp.pre_read(*fs_, &map_); old_world_name_ = mp.old_world_name(); } + { + MapVersionPacket version_packet; + version_packet.pre_read(*fs_, &map_, false, old_world_name_.empty()); + } { MapPlayerNamesAndTribesPacket p; @@ -198,7 +202,7 @@ log("Reading Map Version Data ... "); { MapVersionPacket p; - p.read(*fs_, egbase, is_game, *mol_); + p.read(*fs_, egbase, is_game, old_world_name_.empty()); } log("took %ums\n ", timer.ms_since_last_query()); === modified file 'src/map_io/world_legacy_lookup_table.cc' --- src/map_io/world_legacy_lookup_table.cc 2019-02-23 11:00:49 +0000 +++ src/map_io/world_legacy_lookup_table.cc 2019-06-22 11:17:12 +0000 @@ -33,16 +33,24 @@ // Implements OneWorldLegacyLookupTable. std::string lookup_resource(const std::string& resource) const override; std::string lookup_terrain(const std::string& terrain) const override; - std::string lookup_critter(const std::string& critter) const override; + std::string lookup_critter(const std::string& critter, uint16_t packet_version) const override; std::string lookup_immovable(const std::string& immovable) const override; private: + // Old name, <packet version when it got changed, new name> + const std::map<std::string, std::map<uint16_t, std::string>> critters_; const std::map<std::string, std::string> immovables_; const std::map<std::string, std::string> resources_; const std::map<std::string, std::string> terrains_; }; PostOneWorldLegacyLookupTable::PostOneWorldLegacyLookupTable() : +critters_ +{ + // We need to bump the packet version in Critter every time we rename a critter. + // Also, don't forget to edit the OneWorldLegacyLookupTable! You can look up which world had which units in Build 18. + {"elk", {{2, "moose"}}}, +}, immovables_ { {"blackland_stones1", "blackland_rocks1"}, @@ -113,8 +121,16 @@ return i->second; } -std::string PostOneWorldLegacyLookupTable::lookup_critter(const std::string& critter) const { - return critter; +std::string PostOneWorldLegacyLookupTable::lookup_critter(const std::string& critter, uint16_t packet_version) const { + std::string result = critter; + if (critters_.count(critter) == 1) { + for (const auto& candidate : critters_.at(result)) { + if (candidate.first >= packet_version) { + result = candidate.second; + } + } + } + return result; } std::string PostOneWorldLegacyLookupTable::lookup_immovable(const std::string& immovable) const { @@ -132,7 +148,7 @@ // Implements OneWorldLegacyLookupTable. std::string lookup_resource(const std::string& resource) const override; std::string lookup_terrain(const std::string& terrain) const override; - std::string lookup_critter(const std::string& critter) const override; + std::string lookup_critter(const std::string& critter, uint16_t packet_version) const override; std::string lookup_immovable(const std::string& immovable) const override; private: @@ -205,6 +221,7 @@ std::make_pair("greenland", std::map<std::string, std::string>{ {"deer", "stag"}, + {"elk", "moose"}, }), std::make_pair("blackland", std::map<std::string, std::string>{ @@ -213,6 +230,7 @@ std::make_pair("winterland", std::map<std::string, std::string>{ {"deer", "stag"}, + {"elk", "moose"}, }), std::make_pair("desert", std::map<std::string, std::string>{ @@ -418,7 +436,7 @@ return terrain; } -std::string OneWorldLegacyLookupTable::lookup_critter(const std::string& critter) const { +std::string OneWorldLegacyLookupTable::lookup_critter(const std::string& critter, uint16_t) const { const std::map<std::string, std::string>& world_critters = critters_.at(old_world_name_); const auto& i = world_critters.find(critter); if (i != world_critters.end()) { === modified file 'src/map_io/world_legacy_lookup_table.h' --- src/map_io/world_legacy_lookup_table.h 2019-02-23 11:00:49 +0000 +++ src/map_io/world_legacy_lookup_table.h 2019-06-22 11:17:12 +0000 @@ -38,7 +38,7 @@ virtual std::string lookup_terrain(const std::string& terrain) const = 0; /// Looks up the new name for the 'critter'. - virtual std::string lookup_critter(const std::string& critter) const = 0; + virtual std::string lookup_critter(const std::string& critter, uint16_t packet_version) const = 0; /// Looks up the new name for the 'immovable'. virtual std::string lookup_immovable(const std::string& immovable) const = 0; === modified file 'src/website/map_info.cc' --- src/website/map_info.cc 2019-02-23 11:00:49 +0000 +++ src/website/map_info.cc 2019-06-22 11:17:12 +0000 @@ -92,6 +92,7 @@ json->add_int("width", map->get_width()); json->add_int("height", map->get_height()); json->add_int("nr_players", map->get_nrplayers()); + json->add_int("needs_widelands_version_after", map->needs_widelands_version_after()); const std::string world_name = static_cast<Widelands::WidelandsMapLoader*>(ml.get())->old_world_name();
_______________________________________________ Mailing list: https://launchpad.net/~widelands-dev Post to : widelands-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~widelands-dev More help : https://help.launchpad.net/ListHelp