mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-21 22:54:37 -04:00
add support for patching objects in stage.dzs
This commit is contained in:
+34
-23
@@ -1600,33 +1600,44 @@ static void dStage_actorCreate(stage_actor_data_class* i_actorData, fopAcM_prm_c
|
||||
if (randomizer_IsActive()) {
|
||||
// Get the current stage/room/layer key
|
||||
auto currentStageKey = getActorPatchesCurrentStageKey(i_actorPrm->room_no);
|
||||
// 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);
|
||||
// Iterate twice, once with the current room number, and once with the room set to 0xFF
|
||||
// to indicate overriding an actor in the stage file instead of room file
|
||||
for (auto i = 0; i < 2; ++i) {
|
||||
// change to check for stage objects for 2nd iteration
|
||||
if (i == 1) {
|
||||
currentStageKey |= RandomizerContext::ROOM_STAGE << 8;
|
||||
}
|
||||
// If we have patches for this stage/room/layer
|
||||
if (randomizer_GetContext().mObjectPatches.contains(currentStageKey)) {
|
||||
auto& patches = randomizer_GetContext().mObjectPatches.at(currentStageKey);
|
||||
|
||||
// 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());
|
||||
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);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
@@ -1042,7 +1042,13 @@ RandomizerContext WriteSeedData(const std::unique_ptr<randomizer::logic::world::
|
||||
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>();
|
||||
u8 roomNo{};
|
||||
// Special value for
|
||||
if (roomNode.first.as<std::string>() == "Stage") {
|
||||
roomNo = RandomizerContext::ROOM_STAGE;
|
||||
} else {
|
||||
roomNo = roomNode.first.as<u8>();
|
||||
}
|
||||
for (const auto& objectNode : roomNode.second) {
|
||||
const auto& action = objectNode["action"].as<std::string>();
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
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;
|
||||
static constexpr u8 ROOM_STAGE = 0xFF;
|
||||
|
||||
RandomizerContext() = default;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user