From 2bb1d53752cde15fc0c3fb6fb474037ed5773aa8 Mon Sep 17 00:00:00 2001 From: Hat Kid <6624576+Hat-Kid@users.noreply.github.com> Date: Sun, 21 Jan 2024 03:49:55 +0100 Subject: [PATCH] custom levels: `cell-info` and `buzzer-info` lumps (#3324) Adds two new lump types: `cell-info` and `buzzer-info`. `cell-info` takes a `game-task` enum value and defines an `eco-info` lump for power cells. `buzzer-info` takes a `game-task` enum value and an integer and automatically calculates the required value for the buzzer task with the formula `task + buzzer * (1 << 16)`. --- custom_levels/jak1/test-zone/test-zone.jsonc | 14 ++++++-- goalc/build_level/common/Entity.cpp | 36 +++++++++++++++++++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/custom_levels/jak1/test-zone/test-zone.jsonc b/custom_levels/jak1/test-zone/test-zone.jsonc index 342edc56dc..b1ce3dd2b2 100644 --- a/custom_levels/jak1/test-zone/test-zone.jsonc +++ b/custom_levels/jak1/test-zone/test-zone.jsonc @@ -21,9 +21,10 @@ "double_sided_collide": false, // available res-lump tag types: - // value types: int32, uint32, enum-int32, enum-uint32, float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°) + // integer types: int32, uint32, enum-int32, enum-uint32 + // float types: float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°) // vector types: vector (normal floats), vector4m (meters), vector3m (meters with w set to 1.0), vector-vol (normal floats with w in meters), movie-pos (meters with w in degrees) - // special types: eco-info, water-height + // special types: eco-info, cell-info, buzzer-info, water-height // // examples: // @@ -44,6 +45,12 @@ // // adds an eco-info tag: // "eco-info": ["eco-info", "(pickup-type health)", 2] + // + // adds a cell-info tag: + // "eco-info": ["cell-info", "(game-task training-gimmie)"] + // + // adds a buzzer-info tag: + // "eco-info": ["buzzer-info", "(game-task training-buzzer)", 5] // The base actor id for your custom level. If you have multiple levels this should be unique! "base_id": 100, @@ -93,7 +100,8 @@ "quat": [0, 0, 0, 1], // quaternion "bsphere": [-21.6238, 19.3496, 17.1191, 10], // bounding sphere "lump": { - "name": "test-fuel-cell" + "name": "test-fuel-cell", + "eco-info": ["cell-info", "(game-task none)"] } }, diff --git a/goalc/build_level/common/Entity.cpp b/goalc/build_level/common/Entity.cpp index e1c51135f1..34c81197ce 100644 --- a/goalc/build_level/common/Entity.cpp +++ b/goalc/build_level/common/Entity.cpp @@ -84,6 +84,14 @@ u64 get_enum_val(const std::string& val, decompiler::DecompilerTypeSystem& dts) return parse_enum(enum_def, rest); } +u64 get_enum_or_int(const nlohmann::json& value, decompiler::DecompilerTypeSystem& dts) { + if (value.is_string()) { + return get_enum_val(value.get(), dts); + } else { + ASSERT(value.is_number()); + return value.get(); + } +} template std::vector enum_from_json(const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) { std::vector result; @@ -98,6 +106,7 @@ static std::unordered_map> lump_map = { + // integers {"int32", [](const std::string& name, const nlohmann::json& json, @@ -140,6 +149,7 @@ static std::unordered_map(name, data, -1000000000.0000); }}, + // special lumps {"eco-info", [](const std::string& name, const nlohmann::json& json, @@ -148,7 +158,29 @@ static std::unordered_map(get_enum_val(json[1].get(), dts))); // amount - data.push_back(json[2].get()); + data.push_back(static_cast(get_enum_or_int(json[2], dts))); + return std::make_unique(name, data, -1000000000.0000); + }}, + {"cell-info", + [](const std::string& name, + const nlohmann::json& json, + decompiler::DecompilerTypeSystem& dts) { + std::vector data; + // (pickup-type fuel-cell) + data.push_back(6); + data.push_back(static_cast(get_enum_or_int(json[1], dts))); + return std::make_unique(name, data, -1000000000.0000); + }}, + {"buzzer-info", + [](const std::string& name, + const nlohmann::json& json, + decompiler::DecompilerTypeSystem& dts) { + std::vector data; + // (pickup-type buzzer) + data.push_back(8); + auto task = static_cast(get_enum_val(json[1].get(), dts)); + auto buzzer = json[2].get(); + data.push_back(task + (buzzer * (1 << 16))); return std::make_unique(name, data, -1000000000.0000); }}, {"water-height", @@ -170,6 +202,7 @@ static std::unordered_map(name, data, -1000000000.0000); }}, + // vectors {"vector", [](const std::string& name, const nlohmann::json& json, @@ -225,6 +258,7 @@ static std::unordered_map(name, data, -1000000000.0000); }}, + // floats {"float", [](const std::string& name, const nlohmann::json& json,