refactor object overrides

This commit is contained in:
gymnast86
2026-05-09 04:38:38 -07:00
parent ced018794f
commit 8333ae35a8
6 changed files with 812 additions and 564 deletions
+41 -36
View File
@@ -1596,30 +1596,36 @@ u8 dStage_roomControl_c::mNoArcBank;
static void dStage_actorCreate(stage_actor_data_class* i_actorData, fopAcM_prm_class* i_actorPrm) {
#if TARGET_PC
// If randomizer is active,
// In rando, potentially override this object's data
if (randomizer_IsActive()) {
// override the data for this actor if it's in the actorPatches
// Get the current stage/room/layer key
auto currentStageKey = getActorPatchesCurrentStageKey(i_actorPrm->room_no);
if (randomizer_GetContext().mActorPatches.contains(currentStageKey)) {
const auto& patches = randomizer_GetContext().mActorPatches.at(currentStageKey);
auto actorKey = getStageObjCRC32(reinterpret_cast<u8*>(i_actorData), RandomizerContext::ACTOR_CRC_SIZE);
if (patches.contains(actorKey)) {
const auto& patchedActorData = patches.at(actorKey);
std::memcpy(i_actorPrm, patchedActorData.data() + 8, RandomizerContext::ACTOR_CRC_SIZE - 8);
std::memcpy(i_actorData, patchedActorData.data(), RandomizerContext::ACTOR_CRC_SIZE);
// If we have patches for this stage/room/layer
if (randomizer_GetContext().mObjectPatches.contains(currentStageKey)) {
auto& patches = randomizer_GetContext().mObjectPatches.at(currentStageKey);
auto actrKey = getStageObjCRC32(reinterpret_cast<u8*>(i_actorData), RandomizerContext::ACTR_CRC_SIZE);
auto tgscKey = getStageObjCRC32(reinterpret_cast<u8*>(i_actorData), RandomizerContext::TGSC_CRC_SIZE);
std::vector<u8>* bytes = NULL;
// See if the patches contain either key and the correct size for the key
if (patches.contains(actrKey) &&
(patches[actrKey].size() == RandomizerContext::ACTR_CRC_SIZE || patches[actrKey].size() == RandomizerContext::OBJ_DELETE_SIZE)) {
bytes = &patches.at(actrKey);
} else if (patches.contains(tgscKey) &&
(patches[tgscKey].size() == RandomizerContext::TGSC_CRC_SIZE || patches[tgscKey].size() == RandomizerContext::OBJ_DELETE_SIZE)) {
bytes = &patches.at(tgscKey);
}
}
// Return early if this actor is in objectDeletions so it never spawns
if (randomizer_GetContext().mTgscDeletions.contains(currentStageKey)) {
const auto& deletions = randomizer_GetContext().mTgscDeletions.at(currentStageKey);
stage_tgsc_data_class tgscData{};
strncpy(tgscData.name, i_actorData->name, 8);
tgscData.base = i_actorPrm->base;
tgscData.scale = i_actorPrm->scale;
auto actorKey = getStageObjCRC32(reinterpret_cast<u8*>(&tgscData), RandomizerContext::TGSC_CRC_SIZE);
if (deletions.contains(actorKey)) {
// If we found a match with a size of OBJ_DELETE_SIZE, this is a signal to delete the actor.
// Return early so we just don't spawn it
if (bytes != NULL && bytes->size() == RandomizerContext::OBJ_DELETE_SIZE) {
return;
}
// If we found a match, override the actor data
if (bytes != NULL) {
std::memcpy(i_actorPrm, bytes->data() + 8, bytes->size() - 8);
std::memcpy(i_actorData, bytes->data(), bytes->size());
}
}
}
#endif
@@ -1645,25 +1651,24 @@ static void dStage_actorCreate(stage_actor_data_class* i_actorData, fopAcM_prm_c
}
#if TARGET_PC
// Custom function to spawn additional actors in randomizer
static void dStage_createActorAdditions(dStage_dt_c* i_stage) {
// Custom function to spawn additional objects in randomizer
static void dStage_createObjectAdditions(dStage_dt_c* i_stage) {
if (randomizer_IsActive()) {
u32 stageRoomLayer = getActorPatchesCurrentStageKey(i_stage->getRoomNo());
const auto& actorAdditions = randomizer_GetContext().mActorAdditions;
for (const auto& [type, newActors] : actorAdditions) {
if (newActors.contains(stageRoomLayer)) {
for (const auto& actorData : newActors.at(stageRoomLayer)) {
stage_actor_data_class actor{};
std::memcpy(&actor, actorData.data(), actorData.size());
actor.base.setID = 0xFFFF;
// Code below copied from base game
fopAcM_prm_class* appen = fopAcM_CreateAppend();
const auto& objectAdditions = randomizer_GetContext().mObjectAdditions;
if (objectAdditions.contains(stageRoomLayer)) {
for (const auto& actorData : objectAdditions.at(stageRoomLayer)) {
stage_tgsc_data_class object{};
object.scale = fopAcM_prmScale_class{0, 0, 0};
std::memcpy(&object, actorData.data(), actorData.size());
// Code below copied from base game
fopAcM_prm_class* appen = fopAcM_CreateAppend();
if (appen != NULL) {
appen->base = actor.base;
appen->room_no = (int)i_stage->getRoomNo();
dStage_actorCreate(&actor, appen);
}
if (appen != NULL) {
appen->base = object.base;
appen->room_no = (int)i_stage->getRoomNo();
appen->scale = object.scale;
dStage_actorCreate(reinterpret_cast<stage_actor_data_class*>(&object), appen);
}
}
}
@@ -2768,7 +2773,7 @@ void dStage_dt_c_roomReLoader(void* i_data, dStage_dt_c* i_stage, int param_2) {
#if TARGET_PC
// Spawn our custom actors in randomizer
if (randomizer_IsActive()) {
dStage_createActorAdditions(i_stage);
dStage_createObjectAdditions(i_stage);
}
#endif
layerActorLoader(i_data, i_stage, param_2);
+122 -196
View File
@@ -78,25 +78,18 @@ std::optional<std::string> RandomizerContext::WriteToFile() {
out["mStartHour"] = static_cast<u16>(this->mStartHour);
out["mMapBits"] = static_cast<u16>(this->mMapBits);
for (const auto& [stageRoomLayer, actorPatches] : this->mActorPatches) {
for (const auto& [stageRoomLayer, actorPatches] : this->mObjectPatches) {
for (const auto& [actorCRC, actorPatch] : actorPatches) {
out["mActorPatches"][stageRoomLayer][actorCRC] = ContainerToHexString(actorPatch);
out["mObjectPatches"][stageRoomLayer][actorCRC] = ContainerToHexString(actorPatch);
}
}
for (const auto& [actorType, stages] : this->mActorAdditions) {
for (const auto& [stageRoomLayer, newActors] : stages) {
for (const auto& actor : newActors) {
out["mActorAdditions"][actorType][stageRoomLayer].push_back(ContainerToHexString(actor));
}
for (const auto& [stageRoomLayer, newActors] : this->mObjectAdditions) {
for (const auto& actor : newActors) {
out["mObjectAdditions"][stageRoomLayer].push_back(ContainerToHexString(actor));
}
}
for (const auto& [stageRoomLayer, actorPatches] : this->mTgscDeletions) {
for (const auto& actorCRC : actorPatches) {
out["mTgscDeletions"][stageRoomLayer].push_back(actorCRC);
}
}
out["mFlowPatches"] = this->mFlowPatches;
@@ -216,36 +209,20 @@ std::optional<std::string> RandomizerContext::LoadFromHash(const std::string& ha
// Starting map bits
this->mMapBits = in["mMapBits"].as<u8>();
// Actor Patches
for (const auto& stageRoomLayerNode: in["mActorPatches"]) {
// Object Patches
for (const auto& stageRoomLayerNode: in["mObjectPatches"]) {
u32 stageRoomLayer = stageRoomLayerNode.first.as<u32>();
for (const auto& actorPatchNode : stageRoomLayerNode.second) {
u32 actorCRC = actorPatchNode.first.as<u32>();
auto actorBytes = HexToBytes(actorPatchNode.second.as<std::string>());
auto& patchedActor = this->mActorPatches[stageRoomLayer][actorCRC];
std::copy_n(actorBytes.begin(), actorBytes.size(), patchedActor.begin());
this->mObjectPatches[stageRoomLayer][actorCRC] = HexToBytes(actorPatchNode.second.as<std::string>());
}
}
// Actor Additions
for (const auto& typeNode: in["mActorAdditions"]) {
u32 type = typeNode.first.as<u32>();
for (const auto& stageNode : typeNode.second) {
u32 stageRoomLayer = stageNode.first.as<u32>();
for (const auto& actorNode : stageNode.second) {
auto actorBytes = HexToBytes(actorNode.as<std::string>());
auto& patchedActor = this->mActorAdditions[type][stageRoomLayer].emplace_back();
std::copy_n(actorBytes.begin(), actorBytes.size(), patchedActor.begin());
}
}
}
// Actor Deletions
for (const auto& stageRoomLayerNode: in["mTgscDeletions"]) {
u32 stageRoomLayer = stageRoomLayerNode.first.as<u32>();
for (const auto& actorPatchNode : stageRoomLayerNode.second) {
u32 actorCRC = actorPatchNode.as<u32>();
this->mTgscDeletions[stageRoomLayer].insert(actorCRC);
// Object Additions
for (const auto& stageNode: in["mObjectAdditions"]) {
u32 stageRoomLayer = stageNode.first.as<u32>();
for (const auto& objectData : stageNode.second) {
this->mObjectAdditions[stageRoomLayer].emplace_back(HexToBytes(objectData.as<std::string>()));
}
}
@@ -745,6 +722,82 @@ u32 getStageObjCRC32(u8* data, size_t size) {
return zng_crc32(0, (data), size);
}
stage_tgsc_data_class parseObjData(const YAML::Node& objectNode) {
using namespace Utility::Endian;
// Get all the data for the actor (with endian shenanigans)
stage_tgsc_data_class object{};
const auto& actorName = objectNode["name"].as<std::string>();
strncpy(object.name, actorName.c_str(), 8);
object.base.parameters = toPlatform(target, objectNode["parameters"].as<u32>());
object.base.position.x = toPlatform(target, objectNode["position"]["x"].as<f32>());
object.base.position.y = toPlatform(target, objectNode["position"]["y"].as<f32>());
object.base.position.z = toPlatform(target, objectNode["position"]["z"].as<f32>());
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
object.base.angle.x = toPlatform(target, static_cast<s16>(objectNode["angle"]["x"].as<u16>()));
object.base.angle.y = toPlatform(target, static_cast<s16>(objectNode["angle"]["y"].as<u16>()));
object.base.angle.z = toPlatform(target, static_cast<s16>(objectNode["angle"]["z"].as<u16>()));
object.base.setID = toPlatform(target, static_cast<s16>(objectNode["set id"].as<u16>()));
if (objectNode["scale"]) {
object.scale.x = objectNode["scale"]["x"].as<u8>();
object.scale.y = objectNode["scale"]["y"].as<u8>();
object.scale.z = objectNode["scale"]["z"].as<u8>();
} else {
object.scale = fopAcM_prmScale_class{0, 0, 0};
}
return object;
}
void parseObjPatchData(stage_tgsc_data_class& object, const YAML::Node& patchNode) {
using namespace Utility::Endian;
if (patchNode["name"]) {
const auto& newName = patchNode["name"].as<std::string>();
strncpy(object.name, newName.c_str(), 8);
}
if (patchNode["parameters"]) {
object.base.parameters = toPlatform(target, patchNode["parameters"].as<u32>());
}
if (auto patchPosition = patchNode["position"]) {
if (patchPosition["x"]) {
object.base.position.x = toPlatform(target, patchPosition["x"].as<f32>());
}
if (patchPosition["y"]) {
object.base.position.y = toPlatform(target, patchPosition["y"].as<f32>());
}
if (patchPosition["z"]) {
object.base.position.z = toPlatform(target, patchPosition["z"].as<f32>());
}
}
if (auto patchAngle = patchNode["angle"]) {
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
if (patchAngle["x"]) {
object.base.angle.x = toPlatform(target, static_cast<s16>(patchAngle["x"].as<u16>()));
}
if (patchAngle["y"]) {
object.base.angle.y = toPlatform(target, static_cast<s16>(patchAngle["y"].as<u16>()));
}
if (patchAngle["z"]) {
object.base.angle.z = toPlatform(target, static_cast<s16>(patchAngle["z"].as<u16>()));
}
}
if (auto patchScale = patchNode["scale"]) {
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
if (patchScale["x"]) {
object.scale.x = toPlatform(target, static_cast<s16>(patchScale["x"].as<u16>()));
}
if (patchScale["y"]) {
object.scale.y = toPlatform(target, static_cast<s16>(patchScale["y"].as<u16>()));
}
if (patchScale["z"]) {
object.scale.z = toPlatform(target, static_cast<s16>(patchScale["z"].as<u16>()));
}
}
}
RandomizerContext WriteSeedData(const std::unique_ptr<randomizer::logic::world::World>& world) {
RandomizerContext randoData{};
@@ -943,183 +996,56 @@ RandomizerContext WriteSeedData(const std::unique_ptr<randomizer::logic::world::
randoData.mStartHour = 24;
// Actor Patches
auto actorPatches = LoadYAML(RANDO_DATA_PATH "actor_patches.yaml");
auto actorPatches = LoadYAML(RANDO_DATA_PATH "object_patches.yaml");
for (const auto& stageNode : actorPatches) {
const auto& stageName = stageNode.first.as<std::string>();
for (const auto& roomNode : stageNode.second) {
u8 roomNo = roomNode.first.as<u8>();
for (const auto& actorNode : roomNode.second) {
using namespace Utility::Endian;
for (const auto& objectNode : roomNode.second) {
const auto& action = objectNode["action"].as<std::string>();
// Get all the data for the actor (with endian shenanigans)
stage_actor_data_class actor{};
const auto& actorName = actorNode["name"].as<std::string>();
strncpy(actor.name, actorName.c_str(), 8);
actor.base.parameters = toPlatform(target, actorNode["parameters"].as<u32>());
actor.base.position.x = toPlatform(target, actorNode["position"]["x"].as<f32>());
actor.base.position.y = toPlatform(target, actorNode["position"]["y"].as<f32>());
actor.base.position.z = toPlatform(target, actorNode["position"]["z"].as<f32>());
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
actor.base.angle.x = toPlatform(target, static_cast<s16>(actorNode["angle"]["x"].as<u16>()));
actor.base.angle.y = toPlatform(target, static_cast<s16>(actorNode["angle"]["y"].as<u16>()));
actor.base.angle.z = toPlatform(target, static_cast<s16>(actorNode["angle"]["z"].as<u16>()));
auto object = parseObjData(objectNode);
size_t objDataSize = RandomizerContext::TGSC_CRC_SIZE;
// If the scale of this object is all zeros, it's an ACTR
if (object.scale.x == 0 && object.scale.y == 0 && object.scale.z == 0) {
objDataSize = RandomizerContext::ACTR_CRC_SIZE;
}
// Create unique hash based off of actor data
u32 actorCRC32 = getStageObjCRC32(reinterpret_cast<u8*>(&actor), RandomizerContext::ACTOR_CRC_SIZE);
u32 objectCRC32 = getStageObjCRC32(reinterpret_cast<u8*>(&object), objDataSize);
// Then override the actor with whatever parts are being patched
const auto& patchNode = actorNode["patch"];
if (patchNode["name"]) {
const auto& newName = patchNode["name"].as<std::string>();
strncpy(actor.name, newName.c_str(), 8);
}
if (patchNode["parameters"]) {
actor.base.parameters = toPlatform(target, patchNode["parameters"].as<u32>());
}
if (auto patchPosition = patchNode["position"]) {
if (patchPosition["x"]) {
actor.base.position.x = toPlatform(target, patchPosition["x"].as<f32>());
}
if (patchPosition["y"]) {
actor.base.position.y = toPlatform(target, patchPosition["y"].as<f32>());
}
if (patchPosition["z"]) {
actor.base.position.z = toPlatform(target, patchPosition["z"].as<f32>());
}
}
if (auto patchAngle = patchNode["angle"]) {
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
if (patchAngle["x"]) {
actor.base.angle.x = toPlatform(target, static_cast<s16>(patchAngle["x"].as<u16>()));
}
if (patchAngle["y"]) {
actor.base.angle.y = toPlatform(target, static_cast<s16>(patchAngle["y"].as<u16>()));
}
if (patchAngle["z"]) {
actor.base.angle.z = toPlatform(target, static_cast<s16>(patchAngle["z"].as<u16>()));
}
// Depending on the action, store data on this actor
std::vector<u8> actorData(0);
// If we're patching this object, Then override the object with whatever parts are being patched
// and add that patch data to our actorData
if (action == "patch") {
parseObjPatchData(object, objectNode["patch"]);
actorData.resize(objDataSize);
std::memcpy(actorData.data(), &object, objDataSize);
} else if (action == "add") {
// If we're adding the object, add it's regular data to the actorData
actorData.resize(objDataSize);
std::memcpy(actorData.data(), &object, objDataSize);
} else if (action == "delete") {
// If we're deleting this actor, give it a specific size to indicate we're deleting it
actorData.resize(RandomizerContext::OBJ_DELETE_SIZE);
}
// Insert the actor patch into the context with our crc32 as the key and the
// raw actor patch data as the value
std::array<u8, RandomizerContext::ACTOR_CRC_SIZE> patchedActorData{};
std::memcpy(patchedActorData.data(), &actor, RandomizerContext::ACTOR_CRC_SIZE);
for (const auto& layerNode : actorNode["layers"]) {
// Loop through all of our layers to apply this action to
for (const auto& layerNode : objectNode["layers"]) {
u8 layerNo = layerNode.as<u8>();
// Create key based off of stage index, room, and layer
u32 stageRoomLayerKey{};
stageRoomLayerKey |= getStageID(stageName.c_str()) << 16;
stageRoomLayerKey |= roomNo << 8;
stageRoomLayerKey |= layerNo;
randoData.mActorPatches[stageRoomLayerKey][actorCRC32] = patchedActorData;
}
}
}
}
// Actor Additions
auto actorAdditions = LoadYAML(RANDO_DATA_PATH "actor_additions.yaml");
for (const auto& typeNode : actorAdditions) {
const auto& actorTypeStr = typeNode.first.as<std::string>();
// Get the integer interpretation of the multi-char type literal
u32 actorType = *(reinterpret_cast<const u32*>(actorTypeStr.c_str()));
// For each stage
for (const auto& stageNode : typeNode.second) {
const auto& stageName = stageNode.first.as<std::string>();
// For each room
for (const auto& roomNode : stageNode.second) {
u8 roomNo = roomNode.first.as<u8>();
// Get data on new actors
for (const auto& actorNode : roomNode.second) {
using namespace Utility::Endian;
// Get all the data for the actor (with endian shenanigans)
stage_actor_data_class actor{};
const auto& actorName = actorNode["name"].as<std::string>();
strncpy(actor.name, actorName.c_str(), 8);
actor.base.parameters = toPlatform(target, actorNode["parameters"].as<u32>());
actor.base.position.x = toPlatform(target, actorNode["position"]["x"].as<f32>());
actor.base.position.y = toPlatform(target, actorNode["position"]["y"].as<f32>());
actor.base.position.z = toPlatform(target, actorNode["position"]["z"].as<f32>());
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
actor.base.angle.x = toPlatform(target, static_cast<s16>(actorNode["angle"]["x"].as<u16>()));
actor.base.angle.y = toPlatform(target, static_cast<s16>(actorNode["angle"]["y"].as<u16>()));
actor.base.angle.z = toPlatform(target, static_cast<s16>(actorNode["angle"]["z"].as<u16>()));
// Insert the actor into the context keyed by type and the stage/layer/room combo
std::array<u8, RandomizerContext::ACTOR_CRC_SIZE> newActorData{};
std::memcpy(newActorData.data(), &actor, RandomizerContext::ACTOR_CRC_SIZE);
for (const auto& layerNode : actorNode["layers"]) {
u8 layerNo = layerNode.as<u8>();
// Create key based off of stage index, room, and layer
u32 stageRoomLayerKey{};
stageRoomLayerKey |= getStageID(stageName.c_str()) << 16;
stageRoomLayerKey |= roomNo << 8;
stageRoomLayerKey |= layerNo;
randoData.mActorAdditions[actorType][stageRoomLayerKey].push_back(newActorData);
}
}
}
}
}
// Actor Deletions
auto actorDeletions = LoadYAML(RANDO_DATA_PATH "actor_deletions.yaml");
for (const auto& typeNode : actorDeletions) {
const auto& actorTypeStr = typeNode.first.as<std::string>();
// Get the integer interpretation of the multi-char type literal
u32 actorType = *(reinterpret_cast<const u32*>(actorTypeStr.c_str()));
// For each stage
for (const auto& stageNode : typeNode.second) {
const auto& stageName = stageNode.first.as<std::string>();
// For each room
for (const auto& roomNode : stageNode.second) {
u8 roomNo = roomNode.first.as<u8>();
// Get data on actors to delete
for (const auto& actorNode : roomNode.second) {
using namespace Utility::Endian;
// Get all the data for the actor (with endian shenanigans)
stage_tgsc_data_class actor{};
const auto& actorName = actorNode["name"].as<std::string>();
auto parameters = toPlatform(target, actorNode["parameters"].as<u32>());
auto posX = toPlatform(target, actorNode["position"]["x"].as<f32>());
auto posY = toPlatform(target, actorNode["position"]["y"].as<f32>());
auto posZ = toPlatform(target, actorNode["position"]["z"].as<f32>());
// Have to retrieve as u16 and then cast as s16 because otherwise yaml-cpp
// complains about values over 32767 not fitting in s16
auto angX = toPlatform(target, static_cast<s16>(actorNode["angle"]["x"].as<u16>()));
auto angY = toPlatform(target, static_cast<s16>(actorNode["angle"]["y"].as<u16>()));
auto angZ = toPlatform(target, static_cast<s16>(actorNode["angle"]["z"].as<u16>()));
u8 scaleX, scaleY, scaleZ;
if (actorNode["scale"]) {
scaleX = actorNode["scale"]["x"].as<u8>();
scaleY = actorNode["scale"]["y"].as<u8>();
scaleZ = actorNode["scale"]["z"].as<u8>();
}
strncpy(actor.name, actorName.c_str(), 8);
actor.base.parameters = parameters;
actor.base.position = cXyz{posX, posY, posZ};
actor.base.angle = csXyz{angX, angY, angZ};
actor.base.setID = 0xFFFF; // Always seems to be 0xFFFF
actor.scale = fopAcM_prmScale_class{scaleX, scaleY, scaleZ};
u32 objCRC32 = getStageObjCRC32(reinterpret_cast<u8*>(&actor), RandomizerContext::TGSC_CRC_SIZE);
// Insert the actor into the context keyed by type and the stage/layer/room combo
std::array<u8, RandomizerContext::TGSC_CRC_SIZE> actorData{};
std::memcpy(actorData.data(), &actor, RandomizerContext::TGSC_CRC_SIZE);
for (const auto& layerNode : actorNode["layers"]) {
u8 layerNo = layerNode.as<u8>();
// Create key based off of stage index, room, and layer
u32 stageRoomLayerKey{};
stageRoomLayerKey |= getStageID(stageName.c_str()) << 16;
stageRoomLayerKey |= roomNo << 8;
stageRoomLayerKey |= layerNo;
randoData.mTgscDeletions[stageRoomLayerKey].insert(objCRC32);
if (action == "add") {
randoData.mObjectAdditions[stageRoomLayerKey].push_back(actorData);
} else { // patch or delete
randoData.mObjectPatches[stageRoomLayerKey][objectCRC32] = actorData;
}
}
}
@@ -18,8 +18,9 @@
*/
class RandomizerContext {
public:
static constexpr size_t ACTOR_CRC_SIZE = 30;
static constexpr size_t TGSC_CRC_SIZE = 35;
static constexpr size_t ACTR_CRC_SIZE = 32;
static constexpr size_t TGSC_CRC_SIZE = 35; // 3 extra bytes for scale x, y, z
static constexpr size_t OBJ_DELETE_SIZE = 1;
RandomizerContext() = default;
@@ -45,9 +46,9 @@ public:
u8 mStartHour{0};
u8 mMapBits{};
std::unordered_map<u32, std::unordered_map<u32, std::array<u8, ACTOR_CRC_SIZE>>> mActorPatches{};
std::unordered_map<u32, std::unordered_map<u32, std::list<std::array<u8, ACTOR_CRC_SIZE>>>> mActorAdditions{};
std::unordered_map<u32, std::unordered_set<u32>> mTgscDeletions{};
std::unordered_map<u32, std::unordered_map<u32, std::vector<u8>>> mObjectPatches{};
std::unordered_map<u32, std::list<std::vector<u8>>> mObjectAdditions{};
// std::unordered_map<u32, std::unordered_set<u32>> mTgscDeletions{};
std::unordered_map<u32, u64> mFlowPatches{};
// struct TextOverride {
@@ -1,136 +0,0 @@
# New actors to spawn in
# NOTE: All data is expressed in little endian format
# Objects which have the ACTR dzx type
ACTR:
# Faron Woods
F_SP108:
# Room 6 - North Faron Woods
6:
# Spawn Item for Golden Wolf in North Faron Woods layer 3
- name: htPiece
parameters: 0xFFFFFFE1
position:
x: -36699.4375
y: 428.600311279297
z: -23663.64453125
angle:
x: 0x0000
y: 0x0000
z: 0x00FF
layers:
- 3
# Lake Hylia
F_SP115:
# Room 0 - Main Lake
0:
# Spawn Auru on layers 1 & 3
- name: Rafrel
parameters: 0x00001D01
position:
x: -116486.945
y: -13860.0
z: 58533.0078
angle:
x: 0x0000
y: 0xCCCD
z: 0x0000
layers:
- 1
- 3
# Spawn red rupee behind canon so players always have
# enough money for the canon
- name: item
parameters: 0xF3FFFF04
position:
x: -108290.086
y: -18654.748
z: 45935.2969
angle:
x: 0x0000
y: 0x0001
z: 0x003F
layers:
- 1
- 2
- 3
# Sacred Grove
F_SP117:
# Room 1 - Pedestal of Time
1:
# Spawn in the Master Sword actor
- name: mstrsrd
parameters: 0x00020110
position:
x: 0.0
y: 1700.0
z: -5435.0
angle:
x: 0x0147
y: 0x0000
z: 0x0000
layers:
- 2
# Outside Arbiters Grounds
F_SP118:
# Room 1 - Bulblin Camp
1:
# Spawn in the item for the Bulblin Guard Key on
# the layer where the camp is already beaten
- name: htPiece
parameters: 0x00FF9AD7
position:
x: 4000
y: 300
z: -3500
angle:
x: 0x0000
y: 0x0000
z: 0x0000
layers:
- 1
- 2
- 3
# Kakariko Interiors
R_SP109:
# Kak Malo Mart
3:
# Spawn in a middle item Sold Out Sign
- name: TGSPITM
parameters: 0x02FFFFFF
position:
x: -650.0
y: 450.0
z: -500.0
angle:
x: 0x0147
y: 0x8000
z: 0x05FF
layers:
- 2
- 3
# Castle Town Shops
R_SP160:
# Jovani's House
5:
# Spawn the poe in Jovani's House
- name: E_hp
parameters: 0xFF031E00
position:
x: 4531.19
y: -30.0
z: 2631.961
angle:
x: 0x0000
y: 0x0000
z: 0x0000
layers:
- 0
- 1
@@ -1,26 +0,0 @@
# Stage Objects to not spawn in
# Actors which have the SCOB dzx type
SCOB:
# Palace of Twilight
D_MN08:
# Room 0 - Main Entrance
0:
# Delete invisible wall that blocks north access
# in Palace of Twilight unless both Sols are placed
- name: ClearB
parameters: 0x00003F81
position:
x: 255.0
y: 1600.0
z: 2560.0
angle:
x: 0x4000
y: 0x0000
z: 0x0000
scale:
x: 20
y: 10
z: 20
layers:
- 14