mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-29 08:12:52 -04:00
remove invisible wall blocking north palace
This commit is contained in:
+15
-2
@@ -1596,18 +1596,31 @@ 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, override the data for this actor if it's in the actorPatches
|
||||
// If randomizer is active,
|
||||
if (randomizer_IsActive()) {
|
||||
// override the data for this actor if it's in the actorPatches
|
||||
auto currentStageKey = getActorPatchesCurrentStageKey(i_actorPrm->room_no);
|
||||
if (randomizer_GetContext().mActorPatches.contains(currentStageKey)) {
|
||||
const auto& patches = randomizer_GetContext().mActorPatches.at(currentStageKey);
|
||||
auto actorKey = getActorCRC32(i_actorData);
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -92,6 +92,12 @@ std::optional<std::string> RandomizerContext::WriteToFile() {
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [stageRoomLayer, actorPatches] : this->mTgscDeletions) {
|
||||
for (const auto& actorCRC : actorPatches) {
|
||||
out["mTgscDeletions"][stageRoomLayer].push_back(actorCRC);
|
||||
}
|
||||
}
|
||||
|
||||
out["mFlowPatches"] = this->mFlowPatches;
|
||||
|
||||
// Dump text overrides as binary to avoid losing intentional null characters
|
||||
@@ -234,6 +240,15 @@ std::optional<std::string> RandomizerContext::LoadFromHash(const std::string& ha
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Flow Patches
|
||||
for (const auto& flowNode: in["mFlowPatches"]) {
|
||||
auto key = flowNode.first.as<u32>();
|
||||
@@ -726,8 +741,8 @@ u32 getActorPatchesCurrentStageKey(u8 roomNo) {
|
||||
return actorPatchesStageKey;
|
||||
}
|
||||
|
||||
u32 getActorCRC32(stage_actor_data_class* actor) {
|
||||
return zng_crc32(0, reinterpret_cast<u8*>(actor), RandomizerContext::ACTOR_CRC_SIZE);
|
||||
u32 getStageObjCRC32(u8* data, size_t size) {
|
||||
return zng_crc32(0, (data), size);
|
||||
}
|
||||
|
||||
RandomizerContext WriteSeedData(const std::unique_ptr<randomizer::logic::world::World>& world) {
|
||||
@@ -950,7 +965,7 @@ RandomizerContext WriteSeedData(const std::unique_ptr<randomizer::logic::world::
|
||||
actor.base.angle.z = toPlatform(target, static_cast<s16>(actorNode["angle"]["z"].as<u16>()));
|
||||
|
||||
// Create unique hash based off of actor data
|
||||
u32 actorCRC32 = getActorCRC32(&actor);
|
||||
u32 actorCRC32 = getStageObjCRC32(reinterpret_cast<u8*>(&actor), RandomizerContext::ACTOR_CRC_SIZE);
|
||||
|
||||
// Then override the actor with whatever parts are being patched
|
||||
const auto& patchNode = actorNode["patch"];
|
||||
@@ -1049,6 +1064,68 @@ RandomizerContext WriteSeedData(const std::unique_ptr<randomizer::logic::world::
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flow Patches
|
||||
auto flowPatches = LoadYAML(RANDO_DATA_PATH "flow_patches.yaml");
|
||||
for (const auto& groupNode : flowPatches) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
/*
|
||||
* Class holding all the information necessary for playing
|
||||
@@ -18,6 +19,7 @@
|
||||
class RandomizerContext {
|
||||
public:
|
||||
static constexpr size_t ACTOR_CRC_SIZE = 30;
|
||||
static constexpr size_t TGSC_CRC_SIZE = 35;
|
||||
|
||||
RandomizerContext() = default;
|
||||
|
||||
@@ -43,8 +45,9 @@ public:
|
||||
u8 mStartHour{0};
|
||||
u8 mMapBits{};
|
||||
|
||||
std::unordered_map<u32, std::unordered_map<u32, std::array<u8, 30>>> mActorPatches{};
|
||||
std::unordered_map<u32, std::unordered_map<u32, std::list<std::array<u8, 30>>>> mActorAdditions{};
|
||||
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, u64> mFlowPatches{};
|
||||
|
||||
// struct TextOverride {
|
||||
@@ -201,7 +204,7 @@ class stage_actor_data_class;
|
||||
/*
|
||||
* Gets the CRC32 hash of an actors name, parameters, position, and angle
|
||||
*/
|
||||
u32 getActorCRC32(stage_actor_data_class*);
|
||||
u32 getStageObjCRC32(u8* data, size_t size);
|
||||
|
||||
void GenerateAndWriteSeed(std::string& generationStatusMsg);
|
||||
#endif //DUSK_RANDOMIZER_CONTEXT_HPP
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user