mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 15:28:58 -04:00
custom levels: enum lump support (#3305)
This adds support for using enums in lumps using the new lump types `enum-int32` and `enum-uint32`. Also adds these other new lump types: - `water-height` (takes 3 meter floats, an enum and another optional meter float) - `eco-info` (takes an enum and an int) - `vector3m` (3 meter floats + `w` set to 1.0)
This commit is contained in:
@@ -20,16 +20,30 @@
|
||||
// this makes collision 2x slower and bigger, so only use if really needed
|
||||
"double_sided_collide": false,
|
||||
|
||||
// available res-lump tag data types:
|
||||
// int32, float, meters, vector, vector4m (meters)
|
||||
// available res-lump tag types:
|
||||
// value types: int32, uint32, enum-int32, enum-uint32, 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
|
||||
//
|
||||
// examples:
|
||||
//
|
||||
// adds a float tag 'spring-height' with value of 200 meters (1 meter = 4096.0 units):
|
||||
// "spring-height": ["meters", 200.0]
|
||||
//
|
||||
// adds a vector tag 'movie-pos':
|
||||
// "movie-pos": ["vector", [4096000.0, -176128.0, 1353973.76, 1.0]]
|
||||
// adds a degrees tag 'rotoffset':
|
||||
// "rotoffset": ["degrees", -45.0]
|
||||
//
|
||||
// adds a movie-pos tag:
|
||||
// "movie-pos": ["movie-pos", [100.22, -25.3, 99.5, 180.0]]
|
||||
//
|
||||
// adds an enum tag 'options':
|
||||
// "options": ["enum-int32", "(fact-options large)"]
|
||||
//
|
||||
// adds a water-height tag:
|
||||
// "water-height": ["water-height", 25.0, 0.5, 2.0, "(water-flags wt08 wt03 wt01)"]
|
||||
//
|
||||
// adds an eco-info tag:
|
||||
// "eco-info": ["eco-info", "(pickup-type health)", 2]
|
||||
|
||||
// The base actor id for your custom level. If you have multiple levels this should be unique!
|
||||
"base_id": 100,
|
||||
@@ -65,7 +79,7 @@
|
||||
"lump": {
|
||||
"name": "test-ambient",
|
||||
"type": "'hint",
|
||||
"text-id": ["int32", 557], // text id for the "POWER CELL" text
|
||||
"text-id": ["enum-uint32", "(text-id fuel-cell)"], // text id for the "POWER CELL" text
|
||||
"play-mode": "'notice"
|
||||
}
|
||||
}
|
||||
@@ -75,7 +89,7 @@
|
||||
{
|
||||
"trans": [-21.6238, 20.0496, 17.1191], // translation
|
||||
"etype": "fuel-cell", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-21.6238, 19.3496, 17.1191, 10], // bounding sphere
|
||||
"lump": {
|
||||
@@ -86,20 +100,20 @@
|
||||
{
|
||||
"trans": [-15.2818, 15.2461, 17.1360], // translation
|
||||
"etype": "crate", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-crate",
|
||||
"crate-type": "'steel",
|
||||
"eco-info": ["int32", 5, 10]
|
||||
"eco-info": ["eco-info", "(pickup-type money)", 10]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"trans": [-5.4630, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
|
||||
"lump": {
|
||||
@@ -109,7 +123,7 @@
|
||||
// {
|
||||
// "trans": [-7.41, 3.5, 28.42], // translation
|
||||
// "etype": "plat", // actor type
|
||||
// "game_task": 0, // associated game task (for powercells, etc)
|
||||
// "game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
// "quat": [0, 0, 0, 1], // quaternion
|
||||
// "bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere
|
||||
// "lump": {
|
||||
|
||||
@@ -20,24 +20,37 @@
|
||||
// this makes collision 2x slower and bigger, so only use if really needed
|
||||
"double_sided_collide": false,
|
||||
|
||||
// available res-lump tag data types:
|
||||
// int32, float, meters, vector, vector4m (meters)
|
||||
// available res-lump tag types:
|
||||
// value types: int32, uint32, enum-int32, enum-uint32, 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
|
||||
//
|
||||
// examples:
|
||||
//
|
||||
// adds a float tag 'spring-height' with value of 200 meters (1 meter = 4096.0 units):
|
||||
// "spring-height": ["meters", 200.0]
|
||||
//
|
||||
// adds a vector tag 'movie-pos':
|
||||
// "movie-pos": ["vector", [4096000.0, -176128.0, 1353973.76, 1.0]]
|
||||
// adds a degrees tag 'rotoffset':
|
||||
// "rotoffset": ["degrees", -45.0]
|
||||
//
|
||||
// adds a movie-pos tag:
|
||||
// "movie-pos": ["movie-pos", [100.22, -25.3, 99.5, 180.0]]
|
||||
//
|
||||
// adds an enum tag 'options':
|
||||
// "options": ["enum-int32", "(fact-options large)"]
|
||||
//
|
||||
// adds a water-height tag:
|
||||
// "water-height": ["water-height", 25.0, 0.5, 2.0, "(water-flags can-swim can-wade)"]
|
||||
//
|
||||
// adds an eco-info tag:
|
||||
// "eco-info": ["eco-info", "(pickup-type health)", 2]
|
||||
|
||||
// The base actor id for your custom level. If you have multiple levels, this should be unique!
|
||||
"base_id": 100,
|
||||
|
||||
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
|
||||
// Removed so that the release builds don't have to double-decompile the game
|
||||
//"art_groups": ["prsn-torture-ag"],
|
||||
"art_groups": [],
|
||||
// "art_groups": ["prsn-torture-ag"],
|
||||
|
||||
// Any textures you want to include in your custom level.
|
||||
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
|
||||
@@ -55,14 +68,14 @@
|
||||
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
|
||||
"lump": {
|
||||
"name": "test-crate",
|
||||
"eco-info": ["int32", 18, 2]
|
||||
"eco-info": ["eco-info", "(pickup-type health)", 2]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"trans": [-5.4630, 17.4553, 1.6169], // translation
|
||||
"etype": "eco-yellow", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"kill_mask": 0,
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
|
||||
@@ -74,7 +87,7 @@
|
||||
{
|
||||
"trans": [-7.41, 13.5, 28.42], // translation
|
||||
"etype": "prsn-torture", // actor type
|
||||
"game_task": 0, // associated game task (for powercells, etc)
|
||||
"game_task": "(game-task none)", // associated game task (for powercells, etc)
|
||||
"quat": [0, 0, 0, 1], // quaternion
|
||||
"bsphere": [-7.41, 13.5, 28.42, 10], // bounding sphere
|
||||
"lump": {
|
||||
|
||||
@@ -115,6 +115,29 @@ void DecompilerTypeSystem::parse_type_defs(const std::vector<std::string>& file_
|
||||
});
|
||||
}
|
||||
|
||||
void DecompilerTypeSystem::parse_enum_defs(const std::vector<std::string>& file_path) {
|
||||
auto read = m_reader.read_from_file(file_path);
|
||||
auto& data = cdr(read);
|
||||
|
||||
for_each_in_list(data, [&](goos::Object& o) {
|
||||
try {
|
||||
if (car(o).as_symbol() == "defenum") {
|
||||
auto symbol_metadata = DefinitionMetadata();
|
||||
parse_defenum(cdr(o), &ts, &symbol_metadata);
|
||||
symbol_metadata.definition_info = m_reader.db.get_short_info_for(o);
|
||||
auto* rest = &cdr(o);
|
||||
const auto& enum_name = car(*rest).as_symbol();
|
||||
symbol_metadata_map[enum_name.name_ptr] = symbol_metadata;
|
||||
// so far, enums are never runtime types so there's no symbol for them.
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
auto info = m_reader.db.get_info_for(o);
|
||||
lg::error("{} when parsing decompiler type file:{}", e.what(), info);
|
||||
throw;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TypeSpec DecompilerTypeSystem::parse_type_spec(const std::string& str) const {
|
||||
auto read = m_reader.read_from_string(str);
|
||||
auto data = cdr(read);
|
||||
|
||||
@@ -56,6 +56,7 @@ class DecompilerTypeSystem {
|
||||
const TypeSpec& type_spec,
|
||||
const DefinitionMetadata& symbol_metadata);
|
||||
void parse_type_defs(const std::vector<std::string>& file_path);
|
||||
void parse_enum_defs(const std::vector<std::string>& file_path);
|
||||
TypeSpec parse_type_spec(const std::string& str) const;
|
||||
void add_type_flags(const std::string& name, u64 flags);
|
||||
void add_type_parent(const std::string& child, const std::string& parent);
|
||||
|
||||
@@ -38,58 +38,233 @@ math::Vector4f vector_from_json(const nlohmann::json& json) {
|
||||
return result;
|
||||
}
|
||||
|
||||
math::Vector4f vector_vol_from_json(const nlohmann::json& json) {
|
||||
ASSERT(json.size() == 4);
|
||||
math::Vector4f result;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result[i] = json[i].get<float>();
|
||||
}
|
||||
result[3] = json[3].get<float>() * METER_LENGTH;
|
||||
return result;
|
||||
}
|
||||
|
||||
u64 parse_enum(EnumType* e, goos::Object& rest) {
|
||||
if (e->is_bitfield()) {
|
||||
u64 value = 0;
|
||||
for_each_in_list(rest, [&](const goos::Object& o) {
|
||||
auto kv = e->entries().find(o.as_symbol().name_ptr);
|
||||
ASSERT_MSG(kv != e->entries().end(),
|
||||
fmt::format("The value {} was not found in enum.", o.print()));
|
||||
value |= ((u64)1 << (u64)kv->second);
|
||||
});
|
||||
return value;
|
||||
} else {
|
||||
u64 value = 0;
|
||||
bool got = false;
|
||||
for_each_in_list(rest, [&](const goos::Object& o) {
|
||||
ASSERT_MSG(!got, "Invalid enum lookup.");
|
||||
auto kv = e->entries().find(o.as_symbol().name_ptr);
|
||||
ASSERT_MSG(kv != e->entries().end(),
|
||||
fmt::format("The value {} was not found in enum.", o.print()));
|
||||
value = kv->second;
|
||||
got = true;
|
||||
});
|
||||
ASSERT_MSG(got, "Invalid enum lookup.");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
u64 get_enum_val(const std::string& val, decompiler::DecompilerTypeSystem& dts) {
|
||||
auto& reader = pretty_print::get_pretty_printer_reader();
|
||||
auto value = reader.read_from_string(val).as_pair()->cdr.as_pair()->car;
|
||||
auto type = value.as_pair()->car.as_symbol().name_ptr;
|
||||
auto rest = value.as_pair()->cdr;
|
||||
auto enum_def = dts.ts.try_enum_lookup(type);
|
||||
ASSERT_MSG(enum_def, fmt::format("Enum {} was not found.", type));
|
||||
return parse_enum(enum_def, rest);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> enum_from_json(const nlohmann::json& json, decompiler::DecompilerTypeSystem& dts) {
|
||||
std::vector<T> result;
|
||||
for (const auto& entry : json) {
|
||||
result.push_back(static_cast<T>(get_enum_val(entry.get<std::string>(), dts)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string,
|
||||
std::function<std::unique_ptr<Res>(const std::string&,
|
||||
const nlohmann::json&,
|
||||
decompiler::DecompilerTypeSystem&)>>
|
||||
lump_map = {
|
||||
{"int32",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<s32> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(json[i].get<int>());
|
||||
}
|
||||
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"uint32",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<u32> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(json[i].get<u32>());
|
||||
}
|
||||
return std::make_unique<ResUint32>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"enum-int32",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
std::vector<s32> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data = enum_from_json<s32>(json[i], dts);
|
||||
}
|
||||
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"enum-uint32",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
std::vector<u32> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data = enum_from_json<u32>(json[i], dts);
|
||||
}
|
||||
return std::make_unique<ResUint32>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"eco-info",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
std::vector<s32> data;
|
||||
// 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>());
|
||||
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"water-height",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
std::vector<float> data;
|
||||
// water-height
|
||||
data.push_back(json[1].get<float>() * METER_LENGTH);
|
||||
// wade-height
|
||||
data.push_back(json[2].get<float>() * METER_LENGTH);
|
||||
// swim-height
|
||||
data.push_back(json[3].get<float>() * METER_LENGTH);
|
||||
// water-flags
|
||||
data.push_back(static_cast<float>(get_enum_val(json[4].get<std::string>(), dts)));
|
||||
// bottom-height
|
||||
if (json.size() >= 6) {
|
||||
data.push_back(json[5].get<float>() * METER_LENGTH);
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"vector",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(vector_from_json(json[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"vector4m",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(vectorm4_from_json(json[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"vector3m",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(vectorm3_from_json(json[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"movie-pos",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(movie_pos_from_json(json[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"vector-vol",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(vector_vol_from_json(json[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"float",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<float> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(json[i].get<float>());
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"meters",
|
||||
[](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<float> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(json[i].get<float>() * METER_LENGTH);
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
}},
|
||||
{"degrees", [](const std::string& name,
|
||||
const nlohmann::json& json,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
(void)dts;
|
||||
std::vector<float> data;
|
||||
for (size_t i = 1; i < json.size(); i++) {
|
||||
data.push_back(json[i].get<float>() * DEGREES_LENGTH);
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
}}};
|
||||
|
||||
std::unique_ptr<Res> res_from_json_array(const std::string& name,
|
||||
const nlohmann::json& json_array) {
|
||||
ASSERT(json_array.size() > 0);
|
||||
const nlohmann::json& json_array,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
ASSERT(!json_array.empty());
|
||||
std::string array_type = json_array[0].get<std::string>();
|
||||
if (array_type == "int32") {
|
||||
std::vector<s32> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(json_array[i].get<int>());
|
||||
}
|
||||
return std::make_unique<ResInt32>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "uint32") {
|
||||
std::vector<u32> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(json_array[i].get<u32>());
|
||||
}
|
||||
return std::make_unique<ResUint32>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "vector") {
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(vector_from_json(json_array[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "vector4m") {
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(vectorm4_from_json(json_array[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "movie-pos") {
|
||||
std::vector<math::Vector4f> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(movie_pos_from_json(json_array[i]));
|
||||
}
|
||||
return std::make_unique<ResVector>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "float") {
|
||||
std::vector<float> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(json_array[i].get<float>());
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "meters") {
|
||||
std::vector<float> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(json_array[i].get<float>() * METER_LENGTH);
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
} else if (array_type == "degrees") {
|
||||
std::vector<float> data;
|
||||
for (size_t i = 1; i < json_array.size(); i++) {
|
||||
data.push_back(json_array[i].get<float>() * DEGREES_LENGTH);
|
||||
}
|
||||
return std::make_unique<ResFloat>(name, data, -1000000000.0000);
|
||||
if (lump_map.find(array_type) != lump_map.end()) {
|
||||
return lump_map[array_type](name, json_array, dts);
|
||||
} else {
|
||||
ASSERT_MSG(false, fmt::format("unsupported array type: {}\n", array_type));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/goal_constants.h"
|
||||
#include "common/goos/ParseHelpers.h"
|
||||
#include "common/goos/Printer.h"
|
||||
#include "common/util/Assert.h"
|
||||
|
||||
#include "decompiler/util/DecompilerTypeSystem.h"
|
||||
#include "goalc/build_level/common/ResLump.h"
|
||||
#include "goalc/data_compiler/DataObjectGenerator.h"
|
||||
|
||||
@@ -11,4 +14,7 @@
|
||||
math::Vector4f vectorm3_from_json(const nlohmann::json& json);
|
||||
math::Vector4f vectorm4_from_json(const nlohmann::json& json);
|
||||
math::Vector4f vector_from_json(const nlohmann::json& json);
|
||||
std::unique_ptr<Res> res_from_json_array(const std::string& name, const nlohmann::json& json_array);
|
||||
u64 get_enum_val(const std::string& val, decompiler::DecompilerTypeSystem& dts);
|
||||
std::unique_ptr<Res> res_from_json_array(const std::string& name,
|
||||
const nlohmann::json& json_array,
|
||||
decompiler::DecompilerTypeSystem& dts);
|
||||
@@ -69,13 +69,18 @@ size_t generate_inline_array_actors(DataObjectGenerator& gen,
|
||||
|
||||
void add_actors_from_json(const nlohmann::json& json,
|
||||
std::vector<EntityActor>& actor_list,
|
||||
u32 base_aid) {
|
||||
u32 base_aid,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
for (const auto& actor_json : json) {
|
||||
auto& actor = actor_list.emplace_back();
|
||||
actor.aid = actor_json.value("aid", base_aid + actor_list.size());
|
||||
actor.trans = vectorm3_from_json(actor_json.at("trans"));
|
||||
actor.etype = actor_json.at("etype").get<std::string>();
|
||||
actor.game_task = actor_json.value("game_task", 0);
|
||||
if (actor_json.contains("game_task") && actor_json.at("game_task").is_string()) {
|
||||
actor.game_task = get_enum_val(actor_json.at("game_task").get<std::string>(), dts);
|
||||
} else {
|
||||
actor.game_task = actor_json.value("game_task", 0);
|
||||
}
|
||||
actor.vis_id = actor_json.value("vis_id", 0);
|
||||
actor.quat = math::Vector4f(0, 0, 0, 1);
|
||||
if (actor_json.find("quat") != actor_json.end()) {
|
||||
@@ -98,7 +103,7 @@ void add_actors_from_json(const nlohmann::json& json,
|
||||
}
|
||||
|
||||
if (value.is_array()) {
|
||||
actor.res_lump.add_res(res_from_json_array(key, value));
|
||||
actor.res_lump.add_res(res_from_json_array(key, value, dts));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +164,8 @@ size_t generate_inline_array_ambients(DataObjectGenerator& gen,
|
||||
|
||||
void add_ambients_from_json(const nlohmann::json& json,
|
||||
std::vector<EntityAmbient>& ambient_list,
|
||||
u32 base_aid) {
|
||||
u32 base_aid,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
for (const auto& ambient_json : json) {
|
||||
auto& ambient = ambient_list.emplace_back();
|
||||
ambient.aid = ambient_json.value("aid", base_aid + ambient_list.size());
|
||||
@@ -180,7 +186,7 @@ void add_ambients_from_json(const nlohmann::json& json,
|
||||
continue;
|
||||
}
|
||||
if (value.is_array()) {
|
||||
ambient.res_lump.add_res(res_from_json_array(key, value));
|
||||
ambient.res_lump.add_res(res_from_json_array(key, value, dts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ size_t generate_inline_array_actors(DataObjectGenerator& gen,
|
||||
|
||||
void add_actors_from_json(const nlohmann::json& json,
|
||||
std::vector<EntityActor>& actor_list,
|
||||
u32 base_aid);
|
||||
u32 base_aid,
|
||||
decompiler::DecompilerTypeSystem& dts);
|
||||
|
||||
struct EntityAmbient {
|
||||
ResLump res_lump;
|
||||
@@ -47,5 +48,6 @@ size_t generate_inline_array_ambients(DataObjectGenerator& gen,
|
||||
const std::vector<EntityAmbient>& ambients);
|
||||
void add_ambients_from_json(const nlohmann::json& json,
|
||||
std::vector<EntityAmbient>& ambient_list,
|
||||
u32 base_aid);
|
||||
u32 base_aid,
|
||||
decompiler::DecompilerTypeSystem& dts);
|
||||
} // namespace jak1
|
||||
@@ -45,12 +45,14 @@ bool run_build_level(const std::string& input_file,
|
||||
// vis infos
|
||||
// actors
|
||||
std::vector<EntityActor> actors;
|
||||
add_actors_from_json(level_json.at("actors"), actors, level_json.value("base_id", 1234));
|
||||
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);
|
||||
file.actors = std::move(actors);
|
||||
// ambients
|
||||
std::vector<EntityAmbient> ambients;
|
||||
jak1::add_ambients_from_json(level_json.at("ambients"), ambients,
|
||||
level_json.value("base_id", 12345));
|
||||
level_json.value("base_id", 12345), dts);
|
||||
file.ambients = std::move(ambients);
|
||||
auto& ambient_drawable_tree = file.drawable_trees.ambients.emplace_back();
|
||||
(void)ambient_drawable_tree;
|
||||
|
||||
@@ -69,14 +69,23 @@ size_t generate_inline_array_actors(DataObjectGenerator& gen,
|
||||
|
||||
void add_actors_from_json(const nlohmann::json& json,
|
||||
std::vector<EntityActor>& actor_list,
|
||||
u32 base_aid) {
|
||||
u32 base_aid,
|
||||
decompiler::DecompilerTypeSystem& dts) {
|
||||
for (const auto& actor_json : json) {
|
||||
auto& actor = actor_list.emplace_back();
|
||||
actor.aid = actor_json.value("aid", base_aid + actor_list.size());
|
||||
actor.trans = vectorm3_from_json(actor_json.at("trans"));
|
||||
actor.etype = actor_json.at("etype").get<std::string>();
|
||||
actor.kill_mask = actor_json.value("kill_mask", 0);
|
||||
actor.game_task = actor_json.value("game_task", 0);
|
||||
if (actor_json.contains("kill_mask") && actor_json.at("kill_mask").is_string()) {
|
||||
actor.kill_mask = get_enum_val(actor_json.at("kill_mask").get<std::string>(), dts);
|
||||
} else {
|
||||
actor.kill_mask = actor_json.value("kill_mask", 0);
|
||||
}
|
||||
if (actor_json.contains("game_task") && actor_json.at("game_task").is_string()) {
|
||||
actor.game_task = get_enum_val(actor_json.at("game_task").get<std::string>(), dts);
|
||||
} else {
|
||||
actor.game_task = actor_json.value("game_task", 0);
|
||||
}
|
||||
actor.vis_id = actor_json.value("vis_id", 0);
|
||||
actor.quat = math::Vector4f(0, 0, 0, 1);
|
||||
if (actor_json.find("quat") != actor_json.end()) {
|
||||
@@ -99,7 +108,7 @@ void add_actors_from_json(const nlohmann::json& json,
|
||||
}
|
||||
|
||||
if (value.is_array()) {
|
||||
actor.res_lump.add_res(res_from_json_array(key, value));
|
||||
actor.res_lump.add_res(res_from_json_array(key, value, dts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ size_t generate_inline_array_actors(DataObjectGenerator& gen,
|
||||
|
||||
void add_actors_from_json(const nlohmann::json& json,
|
||||
std::vector<EntityActor>& actor_list,
|
||||
u32 base_aid);
|
||||
|
||||
struct Region {};
|
||||
u32 base_aid,
|
||||
decompiler::DecompilerTypeSystem& dts);
|
||||
} // namespace jak2
|
||||
@@ -43,8 +43,10 @@ bool run_build_level(const std::string& input_file,
|
||||
file.nickname = level_json.at("nickname").get<std::string>();
|
||||
// vis infos
|
||||
// actors
|
||||
auto dts = decompiler::DecompilerTypeSystem(GameVersion::Jak2);
|
||||
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));
|
||||
add_actors_from_json(level_json.at("actors"), actors, level_json.value("base_id", 1234), dts);
|
||||
file.actors = std::move(actors);
|
||||
// cameras
|
||||
// nodes
|
||||
|
||||
Reference in New Issue
Block a user