custom levels: sort actors by aid and check for duplicates (#3315)

When giving entities custom actor IDs in your level JSON, it is possible
to break entity lookups by actor ID if the actors are not sorted by ID
because `entity-by-aid` expects them to be in order.

This sorts the actor list by ID before generating the level file and
also checks for any duplicates.
This commit is contained in:
Hat Kid 2024-01-18 10:29:30 +01:00 committed by GitHub
parent 13f1aa1785
commit b06d63ba83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 12 additions and 0 deletions

View file

@ -48,6 +48,12 @@ bool run_build_level(const std::string& input_file,
auto dts = decompiler::DecompilerTypeSystem(GameVersion::Jak1);
dts.parse_enum_defs({"decompiler", "config", "jak1", "all-types.gc"});
add_actors_from_json(level_json.at("actors"), actors, level_json.value("base_id", 1234), dts);
std::sort(actors.begin(), actors.end(), [](auto& a, auto& b) { return a.aid < b.aid; });
auto duplicates = std::adjacent_find(actors.begin(), actors.end(),
[](auto& a, auto& b) { return a.aid == b.aid; });
ASSERT_MSG(duplicates == actors.end(),
fmt::format("Actor IDs must be unique. Found at least two actors with ID {}",
duplicates->aid));
file.actors = std::move(actors);
// ambients
std::vector<EntityAmbient> ambients;

View file

@ -47,6 +47,12 @@ bool run_build_level(const std::string& input_file,
dts.parse_enum_defs({"decompiler", "config", "jak2", "all-types.gc"});
std::vector<EntityActor> actors;
add_actors_from_json(level_json.at("actors"), actors, level_json.value("base_id", 1234), dts);
std::sort(actors.begin(), actors.end(), [](auto& a, auto& b) { return a.aid < b.aid; });
auto duplicates = std::adjacent_find(actors.begin(), actors.end(),
[](auto& a, auto& b) { return a.aid == b.aid; });
ASSERT_MSG(duplicates == actors.end(),
fmt::format("Actor IDs must be unique. Found at least two actors with ID {}",
duplicates->aid));
file.actors = std::move(actors);
// cameras
// nodes