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)`.
This commit is contained in:
Hat Kid 2024-01-21 03:49:55 +01:00 committed by GitHub
parent 076f8aa6dd
commit 2bb1d53752
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 4 deletions

View file

@ -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)"]
}
},

View file

@ -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<std::string>(), dts);
} else {
ASSERT(value.is_number());
return value.get<int>();
}
}
template <typename T>
std::vector<T> enum_from_json(const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) {
std::vector<T> result;
@ -98,6 +106,7 @@ static std::unordered_map<std::string,
const nlohmann::json&,
decompiler::DecompilerTypeSystem&)>>
lump_map = {
// integers
{"int32",
[](const std::string& name,
const nlohmann::json& json,
@ -140,6 +149,7 @@ static std::unordered_map<std::string,
}
return std::make_unique<ResUint32>(name, data, -1000000000.0000);
}},
// special lumps
{"eco-info",
[](const std::string& name,
const nlohmann::json& json,
@ -148,7 +158,29 @@ static std::unordered_map<std::string,
// pickup-type
data.push_back(static_cast<s32>(get_enum_val(json[1].get<std::string>(), dts)));
// amount
data.push_back(json[2].get<int>());
data.push_back(static_cast<s32>(get_enum_or_int(json[2], dts)));
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
}},
{"cell-info",
[](const std::string& name,
const nlohmann::json& json,
decompiler::DecompilerTypeSystem& dts) {
std::vector<s32> data;
// (pickup-type fuel-cell)
data.push_back(6);
data.push_back(static_cast<s32>(get_enum_or_int(json[1], dts)));
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
}},
{"buzzer-info",
[](const std::string& name,
const nlohmann::json& json,
decompiler::DecompilerTypeSystem& dts) {
std::vector<s32> data;
// (pickup-type buzzer)
data.push_back(8);
auto task = static_cast<s32>(get_enum_val(json[1].get<std::string>(), dts));
auto buzzer = json[2].get<int>();
data.push_back(task + (buzzer * (1 << 16)));
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
}},
{"water-height",
@ -170,6 +202,7 @@ static std::unordered_map<std::string,
}
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
}},
// vectors
{"vector",
[](const std::string& name,
const nlohmann::json& json,
@ -225,6 +258,7 @@ static std::unordered_map<std::string,
}
return std::make_unique<ResVector>(name, data, -1000000000.0000);
}},
// floats
{"float",
[](const std::string& name,
const nlohmann::json& json,