mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-13 21:15:12 -05:00
Merge branch 'rando-next' of https://github.com/HarbourMasters/Shipwright into shopsanity
This commit is contained in:
commit
4c7424f848
@ -186,9 +186,9 @@ cmake --build build-cmake --target ExtractAssets
|
||||
# Setup cmake project for building for Wii U
|
||||
cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
||||
# Build project and generate rpx
|
||||
cmake --build build-wiiu --target soh
|
||||
cmake --build build-wiiu --target soh # --target soh_wuhb (for building .wuhb)
|
||||
|
||||
# Now you can run the executable in ./build-wiiu/soh/soh.rpx
|
||||
# Now you can run the executable in ./build-wiiu/soh/soh.rpx or the Wii U Homebrew Bundle in ./build-wiiu/soh/soh.wuhb
|
||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||
```
|
||||
|
||||
|
3
Jenkinsfile
vendored
3
Jenkinsfile
vendored
@ -206,9 +206,10 @@ pipeline {
|
||||
docker exec sohwiiucont scripts/wiiu/build.sh
|
||||
|
||||
mv build-wiiu/soh/*.rpx soh.rpx
|
||||
mv build-wiiu/soh/*.wuhb soh.wuhb
|
||||
mv README.md readme.txt
|
||||
|
||||
7z a soh-wiiu.7z soh.rpx readme.txt
|
||||
7z a soh-wiiu.7z soh.rpx soh.wuhb readme.txt
|
||||
|
||||
'''
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ extern "C" void DeinitOTR(void);
|
||||
#include <dlfcn.h> // for dladdr
|
||||
#include <execinfo.h>
|
||||
#include <unistd.h>
|
||||
#include <SDL.h>
|
||||
|
||||
|
||||
|
||||
@ -135,9 +136,11 @@ static void ErrorHandler(int sig, siginfo_t* sigInfo, void* data) {
|
||||
|
||||
SPDLOG_CRITICAL("{} {}", i, functionName.c_str());
|
||||
}
|
||||
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SoH has crashed", "SoH Has crashed. Please upload the logs to the support channel in discord.", nullptr);
|
||||
free(symbols);
|
||||
DeinitOTR();
|
||||
Ship::Window::GetInstance()->GetLogger()->flush();
|
||||
spdlog::shutdown();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ namespace Ship {
|
||||
ToLoad->resource = Res;
|
||||
ResourceCache[Res->file->path] = Res;
|
||||
|
||||
SPDLOG_DEBUG("Loaded Resource {} on ResourceMgr thread", ToLoad->file->path);
|
||||
SPDLOG_TRACE("Loaded Resource {} on ResourceMgr thread", ToLoad->file->path);
|
||||
|
||||
Res->file = nullptr;
|
||||
} else {
|
||||
|
@ -540,13 +540,12 @@ namespace Ship {
|
||||
|
||||
if (!ResMan->DidLoadSuccessfully())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
||||
#elif defined(__SWITCH__)
|
||||
#if defined(__SWITCH__)
|
||||
printf("Main OTR file not found!\n");
|
||||
#elif defined(__WIIU__)
|
||||
Ship::WiiU::ThrowMissingOTR(MainPath.c_str());
|
||||
#else
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "OTR file not found", "Main OTR file not found. Please generate one", nullptr);
|
||||
SPDLOG_ERROR("Main OTR file not found!");
|
||||
#endif
|
||||
exit(1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake -DCMAKE_BUILD_TYPE:STRING=Release
|
||||
cmake --build build-wiiu --target soh --config Release
|
||||
cmake --build build-wiiu --target soh_wuhb --config Release
|
||||
|
@ -186,6 +186,7 @@ set(Header_Files__soh__Enhancements__randomizer
|
||||
"soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
"soh/Enhancements/randomizer/randomizer_check_objects.h"
|
||||
"soh/Enhancements/randomizer/draw.h"
|
||||
"soh/Enhancements/randomizer/rando_hash.h"
|
||||
)
|
||||
source_group("Header Files\\soh\\Enhancements\\randomizer" FILES ${Header_Files__soh__Enhancements__randomizer})
|
||||
|
||||
@ -2039,6 +2040,13 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "CafeOS")
|
||||
|
||||
wut_create_rpx(${PROJECT_NAME})
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/soh.rpx DESTINATION . COMPONENT ship)
|
||||
wut_create_wuhb(${PROJECT_NAME}
|
||||
NAME "Ship of Harkinian"
|
||||
SHORTNAME "SoH"
|
||||
AUTHOR "Harbour Masters"
|
||||
ICON ${CMAKE_CURRENT_SOURCE_DIR}/icon.jpg
|
||||
)
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/soh.rpx ${CMAKE_CURRENT_BINARY_DIR}/soh.wuhb DESTINATION . COMPONENT ship)
|
||||
|
||||
endif()
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <libultraship/ImGuiImpl.h>
|
||||
#include "../../UIWidgets.hpp"
|
||||
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <map>
|
||||
@ -699,12 +700,14 @@ void DrawFlagArray32(const std::string& name, uint32_t& flags) {
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void DrawFlagArray16(const std::string& name, uint16_t& flags) {
|
||||
ImGui::PushID(name.c_str());
|
||||
void DrawFlagArray16(const FlagTable& flagTable, uint16_t row, uint16_t& flags) {
|
||||
ImGui::PushID((std::to_string(row) + flagTable.name).c_str());
|
||||
for (int32_t flagIndex = 15; flagIndex >= 0; flagIndex--) {
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(flagIndex);
|
||||
bool hasDescription = !!flagTable.flagDescriptions.contains(row * 16 + flagIndex);
|
||||
uint32_t bitMask = 1 << flagIndex;
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, hasDescription ? ImVec4(0.16f, 0.29f, 0.48f, 0.54f) : ImVec4(0.16f, 0.29f, 0.48f, 0.24f));
|
||||
bool flag = (flags & bitMask) != 0;
|
||||
if (ImGui::Checkbox("##check", &flag)) {
|
||||
if (flag) {
|
||||
@ -713,6 +716,12 @@ void DrawFlagArray16(const std::string& name, uint16_t& flags) {
|
||||
flags &= ~bitMask;
|
||||
}
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::IsItemHovered() && hasDescription) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s", UIWidgets::WrappedText(flagTable.flagDescriptions.at(row * 16 + flagIndex), 60));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopID();
|
||||
@ -927,122 +936,37 @@ void DrawFlagsTab() {
|
||||
}
|
||||
});
|
||||
|
||||
if (ImGui::TreeNode("Event Check Inf Flags")) {
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("0");
|
||||
UIWidgets::InsertHelpHoverText("Mostly Kokiri Forest related");
|
||||
DrawFlagArray16("eci0", gSaveContext.eventChkInf[0]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("1");
|
||||
UIWidgets::InsertHelpHoverText("Mostly Lon Lon Ranch related");
|
||||
DrawFlagArray16("eci1", gSaveContext.eventChkInf[1]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("2");
|
||||
UIWidgets::InsertHelpHoverText("Dodongo Related?");
|
||||
DrawFlagArray16("eci2", gSaveContext.eventChkInf[2]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("3");
|
||||
UIWidgets::InsertHelpHoverText("Mostly Zora related");
|
||||
DrawFlagArray16("eci3", gSaveContext.eventChkInf[3]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("4");
|
||||
UIWidgets::InsertHelpHoverText("Random");
|
||||
DrawFlagArray16("eci4", gSaveContext.eventChkInf[4]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("5");
|
||||
UIWidgets::InsertHelpHoverText("Mostly song learning related");
|
||||
DrawFlagArray16("eci5", gSaveContext.eventChkInf[5]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("6");
|
||||
UIWidgets::InsertHelpHoverText("Random");
|
||||
DrawFlagArray16("eci6", gSaveContext.eventChkInf[6]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("7");
|
||||
UIWidgets::InsertHelpHoverText("Boss Battle related");
|
||||
DrawFlagArray16("eci7", gSaveContext.eventChkInf[7]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("8");
|
||||
UIWidgets::InsertHelpHoverText("Mask related?");
|
||||
DrawFlagArray16("eci8", gSaveContext.eventChkInf[8]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("9");
|
||||
UIWidgets::InsertHelpHoverText("Mostly carpenter related");
|
||||
DrawFlagArray16("eci9", gSaveContext.eventChkInf[9]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("A");
|
||||
UIWidgets::InsertHelpHoverText("First-time overworld entrance cs related");
|
||||
DrawFlagArray16("eci10", gSaveContext.eventChkInf[10]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("B");
|
||||
UIWidgets::InsertHelpHoverText("First-time dungeon entrance cs/trial cs related");
|
||||
DrawFlagArray16("eci11", gSaveContext.eventChkInf[11]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("C");
|
||||
UIWidgets::InsertHelpHoverText("Random");
|
||||
DrawFlagArray16("eci12", gSaveContext.eventChkInf[12]);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("D");
|
||||
UIWidgets::InsertHelpHoverText("Frog songs/GS rewards");
|
||||
DrawFlagArray16("eci13", gSaveContext.eventChkInf[13]);
|
||||
});
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Inf Table Flags")) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
std::string it_id = "it" + std::to_string(i);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("%2d", i);
|
||||
DrawFlagArray16(it_id, gSaveContext.infTable[i]);
|
||||
});
|
||||
for (int i = 0; i < flagTables.size(); i++) {
|
||||
const FlagTable& flagTable = flagTables[i];
|
||||
if (flagTable.flagTableType == RANDOMIZER_INF && !gSaveContext.n64ddFlag) {
|
||||
continue;
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Item Get Inf Flags")) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::string igi_id = "igi" + std::to_string(i);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("%d", i);
|
||||
DrawFlagArray16(igi_id, gSaveContext.itemGetInf[i]);
|
||||
});
|
||||
|
||||
if (ImGui::TreeNode(flagTable.name)) {
|
||||
for (int j = 0; j < flagTable.size + 1; j++) {
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text(fmt::format("{:<2x}", j).c_str());
|
||||
switch (flagTable.flagTableType) {
|
||||
case EVENT_CHECK_INF:
|
||||
DrawFlagArray16(flagTable, j, gSaveContext.eventChkInf[j]);
|
||||
break;
|
||||
case ITEM_GET_INF:
|
||||
DrawFlagArray16(flagTable, j, gSaveContext.itemGetInf[j]);
|
||||
break;
|
||||
case INF_TABLE:
|
||||
DrawFlagArray16(flagTable, j, gSaveContext.infTable[j]);
|
||||
break;
|
||||
case EVENT_INF:
|
||||
DrawFlagArray16(flagTable, j, gSaveContext.eventInf[j]);
|
||||
break;
|
||||
case RANDOMIZER_INF:
|
||||
DrawFlagArray16(flagTable, j, gSaveContext.randomizerInf[j]);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Event Inf Flags")) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::string ei_id = "ei" + std::to_string(i);
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("%d", i);
|
||||
DrawFlagArray16(ei_id, gSaveContext.eventInf[i]);
|
||||
});
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,415 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <soh/Enhancements/randomizer/randomizer_inf.h>
|
||||
|
||||
void InitSaveEditor();
|
||||
|
||||
typedef enum {
|
||||
EVENT_CHECK_INF,
|
||||
ITEM_GET_INF,
|
||||
INF_TABLE,
|
||||
EVENT_INF,
|
||||
RANDOMIZER_INF,
|
||||
} FlagTableType;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
FlagTableType flagTableType;
|
||||
uint32_t size;
|
||||
std::map<uint16_t, const char*> flagDescriptions;
|
||||
} FlagTable;
|
||||
|
||||
// Reference https://tcrf.net/Proto:The_Legend_of_Zelda:_Ocarina_of_Time_Master_Quest/Event_Editor
|
||||
// The source was last referenced on 2022-09-03 and had a last updated value of 2020-05-02
|
||||
const std::vector<FlagTable> flagTables = {
|
||||
{ "Event Check Inf Flags", EVENT_CHECK_INF, 0x0D, {
|
||||
{ 0x02, "First Spoke to Mido" },
|
||||
{ 0x03, "Complained About Mido to Saria" },
|
||||
{ 0x04, "Showed Mido Sword & Shield" },
|
||||
{ 0x05, "Deku Tree Opened Mouth" },
|
||||
{ 0x06, "Spoke to Saria After Deku Tree's Death" },
|
||||
{ 0x07, "Obtained Kokiri Emerald & Deku Tree Dead" },
|
||||
{ 0x09, "Used Deku Tree Blue Warp" },
|
||||
{ 0x0A, "Played Saria's Song for Mido as Adult" },
|
||||
{ 0x0C, "Met Deku Tree" },
|
||||
{ 0x10, "Spoke to Child Malon at Castle or Market" },
|
||||
{ 0x11, "Spoke to Ingo at Ranch before Talon returns" },
|
||||
{ 0x12, "Obtained Pocket Egg" },
|
||||
{ 0x13, "Woke Talon" },
|
||||
{ 0x14, "Talon Fled Hyrule Castle" },
|
||||
{ 0x15, "Spoke to Child Malon at Ranch" },
|
||||
{ 0x16, "Invited to Sing With Child Malon" },
|
||||
{ 0x17, "Great Deku Tree is Dead" },
|
||||
{ 0x18, "Obtained Epona" },
|
||||
{ 0x19, "Obtained Kokiri's Emerald" },
|
||||
{ 0x1B, "Rented Horse From Ingo" },
|
||||
{ 0x1C, "Spoke to Mido After Deku Tree's Death" },
|
||||
{ 0x1D, "Destroyed the Royal Family's Tomb" },
|
||||
{ 0x1E, "Won the Cow in Malon's Race" },
|
||||
{ 0x23, "Bombed Dodongo's Cavern Entrance" },
|
||||
{ 0x25, "Used Dodongo's Cavern Blue Warp" },
|
||||
{ 0x2F, "Death Mountain Erupted" },
|
||||
{ 0x30, "Spoke to a Zora" },
|
||||
{ 0x31, "Obtained Ruto's Letter" },
|
||||
{ 0x33, "King Zora Moved Aside" },
|
||||
{ 0x37, "Used Jabu-Jabu Blue Warp" },
|
||||
{ 0x38, "Obtained Silver Scale" },
|
||||
{ 0x39, "Opened Entrance to Zora's Domain" },
|
||||
{ 0x3A, "Offered Fish to Jabu-Jabu" },
|
||||
{ 0x3B, "Began Nabooru Battle" },
|
||||
{ 0x3C, "Finished Nabooru Battle" },
|
||||
{ 0x40, "Obtained Zelda's Letter" },
|
||||
{ 0x43, "Obtained Ocarina of Time" },
|
||||
{ 0x45, "Pulled Master Sword from Pedestal" },
|
||||
{ 0x48, "Used Forest Temple Blue Warp" },
|
||||
{ 0x49, "Used Fire Temple Blue Warp" },
|
||||
{ 0x4A, "Used Water Temple Blue Warp" },
|
||||
{ 0x4B, "Opened the Door of Time" },
|
||||
{ 0x4D, "Rainbow Bridge Built by Sages" },
|
||||
{ 0x4E, "Caught by Hyrule Castle Guards" },
|
||||
{ 0x4F, "Entered the Master Sword Chamber" },
|
||||
{ 0x50, "Learned Minuet of Forest" },
|
||||
{ 0x51, "Learned Bolero of Fire" },
|
||||
{ 0x52, "Learned Serenade of Water" },
|
||||
{ 0x54, "Learned Nocturne of Shadow" },
|
||||
{ 0x55, "Sheik Moved From Sword Pedestal" },
|
||||
{ 0x57, "Learned Saria's Song" },
|
||||
{ 0x59, "Learned Zelda's Lullaby" },
|
||||
{ 0x5A, "Learned Sun's Song" },
|
||||
{ 0x5B, "Learned Song of Storms" },
|
||||
{ 0x65, "Played Song of Storms in Windmill" },
|
||||
{ 0x67, "Drained Well in Kakariko Village" },
|
||||
{ 0x68, "Played Gerudo Archery Minigame" },
|
||||
{ 0x69, "Restored Lake Hylia's Water" },
|
||||
{ 0x6A, "Woke Talon in Kakariko" },
|
||||
{ 0x6B, "Spoke to Talon After Saving Ranch" },
|
||||
{ 0x6F, "Spoke to Kaepora Gaebora by Lost Woods" },
|
||||
{ 0x70, "Began Gohma Battle" },
|
||||
{ 0x71, "Began King Dodongo Battle" },
|
||||
{ 0x72, "Began Phantom Ganon Battle" },
|
||||
{ 0x73, "Began Volvagia Battle" },
|
||||
{ 0x74, "Began Morpha Battle" },
|
||||
{ 0x75, "Began Twinrova Battle" },
|
||||
{ 0x76, "Began Barinade Battle" },
|
||||
{ 0x77, "Began Bongo Bongo Battle" },
|
||||
{ 0x78, "Began Ganondorf Battle" },
|
||||
{ 0x80, "Zelda Fled Hyrule Castle" },
|
||||
{ 0x82, "Bridge Unlocked (After Zelda Escape Cutscene)" },
|
||||
{ 0x8C, "Paid Back Keaton Mask Fee" },
|
||||
{ 0x8D, "Paid Back Skull Mask Fee" },
|
||||
{ 0x8E, "Paid Back Spooky Mask Fee" },
|
||||
{ 0x8F, "Paid Back Bunny Hood Fee" },
|
||||
{ 0x90, "Rescued Red Carpenter" },
|
||||
{ 0x91, "Rescued Yellow Carpenter" },
|
||||
{ 0x92, "Rescued Blue Carpenter" },
|
||||
{ 0x93, "Rescued Green Carpenter" },
|
||||
{ 0x94, "Spoke to Nabooru in Spirit Temple" },
|
||||
{ 0x95, "Nabooru Captured by Twinrova" },
|
||||
{ 0x96, "Spoke to Cursed Man in Skulltula House" },
|
||||
{ 0x9C, "Played Song for Scarecrow as Adult" },
|
||||
{ 0xA0, "Entered Hyrule Field" },
|
||||
{ 0xA1, "Entered Death Mountain Trail" },
|
||||
{ 0xA3, "Entered Kakariko Village" },
|
||||
{ 0xA4, "Entered Zora's Domain" },
|
||||
{ 0xA5, "Entered Hyrule Castle" },
|
||||
{ 0xA6, "Entered Goron City" },
|
||||
{ 0xA7, "Entered Temple of Time" },
|
||||
{ 0xA8, "Entered Deku Tree" },
|
||||
{ 0xA9, "Learned Song of Time" },
|
||||
{ 0xAA, "Bongo Bongo Escaped Well" },
|
||||
{ 0xAC, "Learned Requiem of Spirit" },
|
||||
{ 0xAD, "Completed Spirit Trial" },
|
||||
{ 0xB0, "Entered Dodongo's Cavern" },
|
||||
{ 0xB1, "Entered Lake Hylia" },
|
||||
{ 0xB2, "Entered Gerudo Valley" },
|
||||
{ 0xB3, "Entered Gerudo's Fortress" },
|
||||
{ 0xB4, "Entered Lon Lon Ranch" },
|
||||
{ 0xB5, "Entered Jabu-Jabu's Belly" },
|
||||
{ 0xB6, "Entered Graveyard" },
|
||||
{ 0xB7, "Entered Zora's Fountain" },
|
||||
{ 0xB8, "Entered Desert Colossus" },
|
||||
{ 0xB9, "Entered Death Mountain Crater" },
|
||||
{ 0xBA, "Entered Ganon's Castle (Exterior)" },
|
||||
{ 0xBB, "Completed Forest Trial" },
|
||||
{ 0xBC, "Completed Water Trial" },
|
||||
{ 0xBD, "Completed Shadow Trial" },
|
||||
{ 0xBE, "Completed Fire Trial" },
|
||||
{ 0xBF, "Completed Light Trial" },
|
||||
{ 0xC0, "Nabooru Ordered to Fight by Twinrova" },
|
||||
{ 0xC1, "Spoke to Saria on Lost Woods Bridge" },
|
||||
{ 0xC3, "Dispelled Ganon's Tower Barrier" },
|
||||
{ 0xC4, "Returned to Temple of Time With All Medallions" },
|
||||
{ 0xC5, "Sheik, Spawned at Master Sword Pedestal as Adult" },
|
||||
{ 0xC6, "Spoke to Deku Tree Sprout" },
|
||||
{ 0xC7, "Watched Ganon's Tower Collapse / Caught by Gerudo" },
|
||||
{ 0xC8, "Obtained Spirit Medallion" },
|
||||
{ 0xC9, "Demo_Effect, Temple of Time Warp in blue aura + sfx the first time you spawn as Adult" },
|
||||
{ 0xD0, "Obtained Frogs' Piece of Heart" },
|
||||
{ 0xD1, "Played Zelda's Lullaby for Frogs" },
|
||||
{ 0xD2, "Played Epona's Song for Frogs" },
|
||||
{ 0xD3, "Played Sun's Song for Frogs" },
|
||||
{ 0xD4, "Played Saria's Song for Frogs" },
|
||||
{ 0xD5, "Played Song of Time for Frogs" },
|
||||
{ 0xD6, "Played Song of Storms for Frogs" },
|
||||
{ 0xDA, "Obtained Adult's Wallet" },
|
||||
{ 0xDB, "Obtained Stone of Agony" },
|
||||
{ 0xDC, "Obtained Giant's Wallet" },
|
||||
{ 0xDD, "Obtained Skulltula House's Bombchu" },
|
||||
{ 0xDE, "Obtained Skulltula House's Piece of Heart" },
|
||||
} },
|
||||
{ "Item Get Inf Flags", ITEM_GET_INF, 0x03, {
|
||||
{ 0x02, "Obtained Super Cucco Bottle" },
|
||||
{ 0x03, "Bought Bombchu (Shelf 2: Top Right)" },
|
||||
{ 0x04, "Bought Bombchu (Shelf 1: Bot. Right)" },
|
||||
{ 0x05, "Bought Bombchu (Shelf 1: Top Left)" },
|
||||
{ 0x06, "Bought Bombchu (Shelf 2: Bot. Left)" },
|
||||
{ 0x07, "Bought Bombchu (Shelf 2: Bot. Right)" },
|
||||
{ 0x08, "Bought Bombchu (Shelf 1: Top Right)" },
|
||||
{ 0x09, "Bought Bombchu (Shelf 1: Bot. Left)" },
|
||||
{ 0x0A, "Bought Bombchu (Shelf 2: Top Left)" },
|
||||
{ 0x0B, "Obtained Scrub's Heart Piece" },
|
||||
{ 0x0C, "Obtained Cucco Lady's Bottle" },
|
||||
{ 0x0D, "Obtained Bullet Bag Upgrade (Market)" },
|
||||
{ 0x0E, "Obtained Big Quiver" },
|
||||
{ 0x0F, "Obtained Biggest Quiver" },
|
||||
{ 0x10, "Obtained Scientist's Heart Piece" },
|
||||
{ 0x11, "Obtained Bowling Bomb Bag Upgrade" },
|
||||
{ 0x12, "Obtained Bowling Heart Piece" },
|
||||
{ 0x13, "Obtained Deku Seeds" },
|
||||
{ 0x15, "Obtained Roof Guy's Heart Piece" },
|
||||
{ 0x16, "Obtained Skullkid's Heart Piece" },
|
||||
{ 0x17, "Obtained Skullkids' Heart Piece" },
|
||||
{ 0x18, "Obtained Farore's Wind" },
|
||||
{ 0x19, "Obtained Din's Fire" },
|
||||
{ 0x1A, "Obtained Nayru's Love" },
|
||||
{ 0x1C, "Obtained Grave-Dig Heart Piece" },
|
||||
{ 0x1D, "Obtained Bullet Bag Upgrade (Woods)" },
|
||||
{ 0x1E, "Obtained Deku Stick Upgrade (Stage)" },
|
||||
{ 0x1F, "Obtained Deku Nut Upgrade (Stage)" },
|
||||
{ 0x23, "Obtained Keaton Mask" },
|
||||
{ 0x24, "Obtained Skull Mask" },
|
||||
{ 0x25, "Obtained Spooky Mask" },
|
||||
{ 0x26, "Obtained Bunny Hood" },
|
||||
{ 0x2A, "Obtained Mask of Truth" },
|
||||
{ 0x2C, "Obtained Pocket Egg" },
|
||||
{ 0x2E, "Obtained Cojiro" },
|
||||
{ 0x30, "Obtained Odd Potion" },
|
||||
{ 0x31, "Obtained Poacher's Saw" },
|
||||
{ 0x38, "Sold Keaton Mask" },
|
||||
{ 0x39, "Sold Skull Mask" },
|
||||
{ 0x3A, "Sold Spooky Mask" },
|
||||
{ 0x3B, "Sold Bunny Hood" },
|
||||
{ 0x3F, "Obtained Mask of Truth" },
|
||||
} },
|
||||
{ "Inf Flags", INF_TABLE, 0x1D, {
|
||||
{ 0x00, "Greeted by Saria" },
|
||||
{ 0x01, "Spoke to Saria About Obtaining Fairy" },
|
||||
{ 0x03, "Complained About Mido to Saria" },
|
||||
{ 0x05, "Spoke to Saria in Saria's House" },
|
||||
{ 0x0C, "Mido Asked to See Sword & Shield" },
|
||||
{ 0x15, "Spoke to Mido in Lost Woods as Adult" },
|
||||
{ 0x19, "Told Mido Saria Won't Return" },
|
||||
{ 0x1E, "Spoke to Kokiri Girl by Jumping Stones" },
|
||||
{ 0x22, "Spoke to Kokiri Boy Guarding Forest Exit" },
|
||||
{ 0x24, "Spoke to Kokiri Boy Cutting Grass" },
|
||||
{ 0x26, "Spoke to Kokiri Girl on Shop Awning" },
|
||||
{ 0x28, "Spoke to Kokiri Girl About Training Center" },
|
||||
{ 0x31, "Spoke to Kokiri Boy on Bed in Mido's House" },
|
||||
{ 0x51, "Spoke to Kokiri Girl in Saria's House" },
|
||||
{ 0x59, "Spoke to Know-It-All Bro. About Temple" },
|
||||
{ 0x61, "Spoke to Know-It-All Bro. About Saria" },
|
||||
{ 0x66, "Spoke to Deku Tree Sprout After Cutscene" },
|
||||
{ 0x6C, "Spoke to Dying Knight" },
|
||||
{ 0x76, "Showed Zelda's Letter to Gate Guard" },
|
||||
{ 0x77, "Gate Guard Put On Keaton Mask" },
|
||||
{ 0x7E, "Spoke to Talon in Lon Lon Ranch House" },
|
||||
{ 0x84, "Spoke to Child Malon at Castle or Market" },
|
||||
{ 0x85, "Child Malon Said Epona Was Afraid of You" },
|
||||
{ 0x8B, "Entered Hyrule Castle" },
|
||||
{ 0x94, "Spoke to Ingo at Ranch Before Talon's Return" },
|
||||
{ 0x97, "Spoke to Ingo at Ranch" },
|
||||
{ 0x9A, "Spoke to Ingo as Adult" },
|
||||
{ 0xA2, "Refused Ingo's 50 Rupee Rental Request" },
|
||||
{ 0xAB, "Rode a Horse at Ingo's Ranch" },
|
||||
{ 0xB0, "Spoke to Medigoron as Child" },
|
||||
{ 0xB1, "Spoke to Medigoron as Adult" },
|
||||
{ 0xB6, "Spoke to Poe Collector in Ruined Market" },
|
||||
{ 0xB7, "Spoke to Fado in Kokiri Forest as Child" },
|
||||
{ 0xB8, "Spoke to Malon After Saving Ranch" },
|
||||
{ 0xB9, "Spoke to Malon on Horseback" },
|
||||
{ 0xBC, "Spoke to Carpenter Boss by Tent" },
|
||||
{ 0xC0, "Spoke to Fat Woman by Market Potion Shop" },
|
||||
{ 0xC1, "Spoke to Fat Woman After Zelda's Escape" },
|
||||
{ 0xC2, "Spoke to Burly Man About Talon Search" },
|
||||
{ 0xC3, "Spoke to Burly Man After Zelda's Escape" },
|
||||
{ 0xC4, "Spoke to Thief After Zelda's Escape" },
|
||||
{ 0xC5, "Spoke to Thin Man by Market Target Shop" },
|
||||
{ 0xC6, "Spoke to Old Woman by Market Fountain" },
|
||||
{ 0xC7, "Spoke to Old Man by Bombchu Bowling" },
|
||||
{ 0xC8, "Spoke to Thin Lady by Bombchu Bowling" },
|
||||
{ 0xC9, "Spoke to Thin Lady After Zelda's Escape (1.0)" },
|
||||
{ 0xCA, "Spoke to Red Joker in Market" },
|
||||
{ 0xCB, "Spoke to Blue Joker in Market (1.0) / Dog Lady as Adult (DBG)" },
|
||||
{ 0xCC, "Spoke to Itchy Lady After Malon Left Town" },
|
||||
{ 0xCD, "Spoke to Blue Jokester in Market (DBG)" },
|
||||
{ 0xCE, "Spoke to Thin Lady After Zelda's Escape (DBG)" },
|
||||
{ 0xD9, "Spoke to Dampé as Child" },
|
||||
{ 0xE0, "Spoke to Goron by Cavern" },
|
||||
{ 0xE3, "Spoke to Goron Hiding Stick" },
|
||||
{ 0xE6, "Spoke to Goron by Woods Exit" },
|
||||
{ 0xEB, "Spoke to Goron by Bomb Flowers" },
|
||||
{ 0xF0, "Spoke to Goron at City? Entrance" },
|
||||
{ 0xF4, "Spoke to Ruby-Crazed Goron" },
|
||||
{ 0xFC, "Spoke to Goron Shop Owner" },
|
||||
{ 0x109, "Goron City Doors Unlocked" },
|
||||
{ 0x10B, "Spoke to Goron Link About Volvagia" },
|
||||
{ 0x10C, "Stopped Goron Link's Rolling" },
|
||||
{ 0x10E, "Spoke to Goron Link" },
|
||||
{ 0x113, "Spoke to Darunia in Goron City" },
|
||||
{ 0x11A, "Spoke to Darunia in Fire Temple" },
|
||||
{ 0x11E, "Obtained Bomb Bag Upgrade (Goron City)" },
|
||||
{ 0x124, "Spoke to Zora Near Zora Shop?" },
|
||||
{ 0x128, "Spoke to Zora Beside Zora Shop?" },
|
||||
{ 0x129, "Spoke to Zora Swimming Behind Zora Shop" },
|
||||
{ 0x138, "Thawed King Zora" },
|
||||
{ 0x139, "Obtained Zora Tunic" },
|
||||
{ 0x140, "Ruto in JJ (M7) on Blue Switch" },
|
||||
{ 0x141, "Ruto in JJ (M2) Meet Ruto" },
|
||||
{ 0x142, "Ruto in JJ (M3) Talk First Time" },
|
||||
{ 0x143, "Ruto in JJ (M10) Can Be Escorted" },
|
||||
{ 0x144, "Ruto in JJ (?) Wants to be Tossed to Sapphire" },
|
||||
{ 0x145, "Ruto in JJ (M6) on Sapphire platform" },
|
||||
{ 0x146, "Ruto in JJ (M6) Kidnapped" },
|
||||
{ 0x147, "Ruto in JJ, Spawns on F1 Instead of B1" },
|
||||
{ 0x160, "Spoke to Man in Impa's House During Day" },
|
||||
{ 0x161, "Spoke to Man in Impa's House at Night" },
|
||||
{ 0x162, "Spoke to Man in Impa's House as Adult" },
|
||||
{ 0x163, "Spoke to Carpenter Boss's Wife as Child" },
|
||||
{ 0x164, "Spoke to Carpenter Boss's Wife as Adult" },
|
||||
{ 0x16C, "Refused Nabooru's Request" },
|
||||
{ 0x170, "Spoke to Carpenter Boss in Valley" },
|
||||
{ 0x172, "Spoke to Carpenter Boss in Kakariko" },
|
||||
{ 0x176, "Spoke to Blue Carpenter in Tent" },
|
||||
{ 0x178, "Spoke to Green Carpenter in Tent" },
|
||||
{ 0x17F, "Running Man Suggested a Race" },
|
||||
{ 0x190, "Obtained Gerudo Archery Piece of Heart" },
|
||||
{ 0x191, "Obtained Dog Lady's Piece of Heart" },
|
||||
{ 0x192, "Obtained Deku Stick Upgrade (Lost Woods)" },
|
||||
{ 0x193, "Obtained Deku Nut Upgrade (Grotto)" },
|
||||
{ 0x195, "Spoke to Kaepora in Lake Hylia" },
|
||||
{ 0x196, "Spoke to Cursed Man With <10 Tokens" },
|
||||
{ 0x197, "Spoke to Cursed Man With 10 Tokens" },
|
||||
{ 0x198, "Obtained Small Magic Jar" },
|
||||
{ 0x199, "Caught Cucco by Field Entrance" },
|
||||
{ 0x19A, "Caught Cucco by Bazaar" },
|
||||
{ 0x19B, "Caught Cucco by Cucco Pen" },
|
||||
{ 0x19C, "Caught Cucco Behind Windmill" },
|
||||
{ 0x19D, "Caught Cucco in Crate" },
|
||||
{ 0x19E, "Caught Cucco by Skulltula House" },
|
||||
{ 0x19F, "Caught Cucco Behind Potion Shop" },
|
||||
{ 0x1A0, "Entered Deku Tree" },
|
||||
{ 0x1A1, "Entered Dodongo's Cavern" },
|
||||
{ 0x1A2, "Entered Jabu-Jabu's Belly" },
|
||||
{ 0x1A3, "Entered Forest Temple" },
|
||||
{ 0x1A4, "Entered Fire Temple" },
|
||||
{ 0x1A5, "Entered Water Temple" },
|
||||
{ 0x1A6, "Entered Spirit Temple" },
|
||||
{ 0x1A7, "Entered Shadow Temple" },
|
||||
{ 0x1A8, "Entered Bottom of the Well" },
|
||||
{ 0x1A9, "Entered Ice Cavern" },
|
||||
{ 0x1AA, "Entered Ganon's Tower" },
|
||||
{ 0x1AB, "Entered Gerudo Training Ground" },
|
||||
{ 0x1AC, "Entered Thieves' Hideout" },
|
||||
{ 0x1AD, "Entered Ganon's Castle" },
|
||||
{ 0x1AE, "Entered Ganon's Tower (Collapsing)" },
|
||||
{ 0x1AF, "Entered Ganon's Castle (Collapsing)" },
|
||||
{ 0x1D0, "No Sword on B" },
|
||||
} },
|
||||
{ "Event Inf Flags", EVENT_INF, 0x03, {
|
||||
{ 0x00, "Rented Horse From Ingo" },
|
||||
{ 0x01, "Racing Ingo" },
|
||||
{ 0x02, "Won First Race With Ingo?" },
|
||||
{ 0x05, "Lost Race With Ingo?" },
|
||||
{ 0x06, "Racing Ingo For the Second Time" },
|
||||
{ 0x08, "Finished Special Cucco Minigame / Began Gerudo Archery" },
|
||||
{ 0x0A, "Won Special Cucco Minigame?" },
|
||||
{ 0x0F, "Rented Horse From Ingo" },
|
||||
{ 0x10, "Racing Running Man" },
|
||||
{ 0x20, "Market Crowd Text Randomizer" },
|
||||
{ 0x21, "Market Crowd Text Randomizer" },
|
||||
{ 0x22, "Market Crowd Text Randomizer" },
|
||||
{ 0x23, "Market Crowd Text Randomizer" },
|
||||
{ 0x24, "Market Crowd Text Randomizer" },
|
||||
{ 0x30, "Entered the Market" },
|
||||
} },
|
||||
{ "Randomizer Inf Flags", RANDOMIZER_INF, 0x03, {
|
||||
{ RAND_INF_DUNGEONS_DONE_DEKU_TREE, "DUNGEONS_DONE_DEKU_TREE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, "DUNGEONS_DONE_DODONGOS_CAVERN" },
|
||||
{ RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, "DUNGEONS_DONE_JABU_JABUS_BELLY" },
|
||||
{ RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE, "DUNGEONS_DONE_FOREST_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE, "DUNGEONS_DONE_FIRE_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_WATER_TEMPLE, "DUNGEONS_DONE_WATER_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" },
|
||||
{ RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" },
|
||||
|
||||
{ RAND_INF_TRIALS_DONE_LIGHT_TRIAL, "TRIALS_DONE_LIGHT_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_FOREST_TRIAL, "TRIALS_DONE_FOREST_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_FIRE_TRIAL, "TRIALS_DONE_FIRE_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_WATER_TRIAL, "TRIALS_DONE_WATER_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, "TRIALS_DONE_SPIRIT_TRIAL" },
|
||||
{ RAND_INF_TRIALS_DONE_SHADOW_TRIAL, "TRIALS_DONE_SHADOW_TRIAL" },
|
||||
|
||||
{ RAND_INF_COWS_MILKED_LINKS_HOUSE_COW, "COWS_MILKED_LINKS_HOUSE_COW" },
|
||||
{ RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" },
|
||||
{ RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" },
|
||||
{ RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW, "COWS_MILKED_LLR_STABLES_RIGHT_COW" },
|
||||
{ RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW, "COWS_MILKED_LLR_TOWER_LEFT_COW" },
|
||||
{ RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW, "COWS_MILKED_LLR_TOWER_RIGHT_COW" },
|
||||
{ RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW, "COWS_MILKED_KAK_IMPAS_HOUSE_COW" },
|
||||
{ RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW, "COWS_MILKED_DMT_COW_GROTTO_COW" },
|
||||
{ RAND_INF_COWS_MILKED_GV_COW, "COWS_MILKED_GV_COW" },
|
||||
{ RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW, "COWS_MILKED_JABU_JABUS_BELLY_MQ_COW" },
|
||||
{ RAND_INF_COWS_MILKED_HF_COW_GROTTO_GOSSIP_STONE, "COWS_MILKED_HF_COW_GROTTO_GOSSIP_STONE" },
|
||||
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB, "SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO, "SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE" },
|
||||
{ RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB" },
|
||||
} },
|
||||
};
|
@ -2,6 +2,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <ctime>
|
||||
|
||||
#include "cosmetics.hpp"
|
||||
@ -541,8 +542,18 @@ std::string GenerateRandomizer(std::unordered_map<RandomizerSettingKey, uint8_t>
|
||||
}
|
||||
Settings::Keysanity.RestoreDelayedOption();
|
||||
}
|
||||
|
||||
return "./Randomizer/" + Settings::seed + ".json";
|
||||
std::ostringstream fileNameStream;
|
||||
for (int i = 0; i < Settings::hashIconIndexes.size(); i++) {
|
||||
if (i) {
|
||||
fileNameStream << '-';
|
||||
}
|
||||
if (Settings::hashIconIndexes[i] < 10) {
|
||||
fileNameStream << '0';
|
||||
}
|
||||
fileNameStream << std::to_string(Settings::hashIconIndexes[i]);
|
||||
}
|
||||
std::string fileName = fileNameStream.str();
|
||||
return "./Randomizer/" + fileName + ".json";
|
||||
}
|
||||
|
||||
std::string GetInput(const char* hintText) {
|
||||
|
@ -39,6 +39,7 @@ int Playthrough_Init(uint32_t seed, std::unordered_map<RandomizerSettingKey, uin
|
||||
}
|
||||
unsigned int finalHash = std::hash<std::string>{}(Settings::seed + settingsStr);
|
||||
Random_Init(finalHash);
|
||||
Settings::hash = std::to_string(finalHash);
|
||||
|
||||
Logic::UpdateHelpers();
|
||||
|
||||
|
@ -20,6 +20,7 @@ using namespace SFX;
|
||||
|
||||
namespace Settings {
|
||||
std::string seed;
|
||||
std::string hash;
|
||||
std::string version = RANDOMIZER_VERSION "-" COMMIT_NUMBER;
|
||||
std::array<uint8_t, 5> hashIconIndexes;
|
||||
|
||||
|
@ -863,6 +863,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
|
||||
extern std::string seed;
|
||||
extern std::string version;
|
||||
extern std::array<uint8_t, 5> hashIconIndexes;
|
||||
extern std::string hash;
|
||||
|
||||
extern bool skipChildZelda;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
@ -36,12 +37,16 @@ namespace {
|
||||
std::string placementtxt;
|
||||
} // namespace
|
||||
|
||||
static RandomizerHash randomizerHash;
|
||||
static SpoilerData spoilerData;
|
||||
|
||||
void GenerateHash() {
|
||||
for (size_t i = 0; i < Settings::hashIconIndexes.size(); i++) {
|
||||
int number = Settings::seed[i] - '0';
|
||||
std::string hash = Settings::hash;
|
||||
// adds leading 0s to the hash string if it has less than 10 digits.
|
||||
while (hash.length() < 10) {
|
||||
hash = "0" + hash;
|
||||
}
|
||||
for (size_t i = 0, j = 0; i < Settings::hashIconIndexes.size(); i++, j += 2) {
|
||||
int number = std::stoi(hash.substr(j, 2));
|
||||
Settings::hashIconIndexes[i] = number;
|
||||
}
|
||||
|
||||
@ -49,20 +54,6 @@ void GenerateHash() {
|
||||
// spoilerData = { 0 };
|
||||
}
|
||||
|
||||
const RandomizerHash& GetRandomizerHash() {
|
||||
return randomizerHash;
|
||||
}
|
||||
|
||||
// Returns the randomizer hash as concatenated string, separated by comma.
|
||||
const std::string GetRandomizerHashAsString() {
|
||||
std::string hash = "";
|
||||
for (const std::string& str : randomizerHash) {
|
||||
hash += str + ", ";
|
||||
}
|
||||
hash.erase(hash.length() - 2); // Erase last comma
|
||||
return hash;
|
||||
}
|
||||
|
||||
const SpoilerData& GetSpoilerData() {
|
||||
return spoilerData;
|
||||
}
|
||||
@ -703,7 +694,6 @@ const char* SpoilerLog_Write(int language) {
|
||||
|
||||
rootNode->SetAttribute("version", Settings::version.c_str());
|
||||
rootNode->SetAttribute("seed", Settings::seed.c_str());
|
||||
rootNode->SetAttribute("hash", GetRandomizerHashAsString().c_str());
|
||||
|
||||
jsonData.clear();
|
||||
|
||||
@ -739,12 +729,23 @@ const char* SpoilerLog_Write(int language) {
|
||||
}
|
||||
|
||||
std::string jsonString = jsonData.dump(4);
|
||||
std::ostringstream fileNameStream;
|
||||
for (int i = 0; i < Settings::hashIconIndexes.size(); i ++) {
|
||||
if (i) {
|
||||
fileNameStream << '-';
|
||||
}
|
||||
if (Settings::hashIconIndexes[i] < 10) {
|
||||
fileNameStream << '0';
|
||||
}
|
||||
fileNameStream << std::to_string(Settings::hashIconIndexes[i]);
|
||||
}
|
||||
std::string fileName = fileNameStream.str();
|
||||
std::ofstream jsonFile(Ship::Window::GetPathRelativeToAppDirectory(
|
||||
(std::string("Randomizer/") + std::string(Settings::seed) + std::string(".json")).c_str()));
|
||||
(std::string("Randomizer/") + fileName + std::string(".json")).c_str()));
|
||||
jsonFile << std::setw(4) << jsonString << std::endl;
|
||||
jsonFile.close();
|
||||
|
||||
return Settings::seed.c_str();
|
||||
return fileName.c_str();
|
||||
}
|
||||
|
||||
void PlacementLog_Msg(std::string_view msg) {
|
||||
@ -764,7 +765,6 @@ bool PlacementLog_Write() {
|
||||
|
||||
rootNode->SetAttribute("version", Settings::version.c_str());
|
||||
rootNode->SetAttribute("seed", Settings::seed.c_str());
|
||||
rootNode->SetAttribute("hash", GetRandomizerHashAsString().c_str());
|
||||
|
||||
// WriteSettings(placementLog, true); // Include hidden settings.
|
||||
// WriteExcludedLocations(placementLog);
|
||||
|
111
soh/soh/Enhancements/randomizer/rando_hash.h
Normal file
111
soh/soh/Enhancements/randomizer/rando_hash.h
Normal file
@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include <array>
|
||||
#include "variables.h"
|
||||
#include <string>
|
||||
#include <textures/icon_item_static/icon_item_static.h>
|
||||
#include <textures/icon_item_24_static/icon_item_24_static.h>
|
||||
|
||||
std::array<Sprite, 100> gSeedTextures = { {
|
||||
{ dgDekuNutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 0 },
|
||||
{ dgDekuStickIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 1 },
|
||||
{ dgBombIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 2 },
|
||||
{ dgFairyBowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 3 },
|
||||
{ dgFireArrowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 4 },
|
||||
{ dgDinsFireIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 5 },
|
||||
{ dgFairySlingshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 6 },
|
||||
{ dgFairyOcarinaIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 7 },
|
||||
{ dgOcarinaofTimeIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 8 },
|
||||
{ dgBombchuIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 9 },
|
||||
{ dgHookshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 10 },
|
||||
{ dgLongshotIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 11 },
|
||||
{ dgIceArrowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 12 },
|
||||
{ dgFaroresWindIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 13 },
|
||||
{ dgBoomerangIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 14 },
|
||||
{ dgLensofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 15 },
|
||||
{ dgMagicBeansIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16 },
|
||||
{ dgMegatonHammerIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 17 },
|
||||
{ dgLightArrowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 18 },
|
||||
{ dgNayrusLoveIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 19 },
|
||||
{ dgEmptyBottleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 20 },
|
||||
{ dgRedPotionIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 21 },
|
||||
{ dgGreenPotionIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 22 },
|
||||
{ dgBluePotionIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 23 },
|
||||
{ dgBottledFairyIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24 },
|
||||
{ dgFishIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 25 },
|
||||
{ dgMilkFullIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 26 },
|
||||
{ dgRutosLetterIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 27 },
|
||||
{ dgBlueFireIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 28 },
|
||||
{ dgBugIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 29 },
|
||||
{ dgBigPoeIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 30 },
|
||||
{ dgMilkhalfIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 31 },
|
||||
{ dgPoeIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32 },
|
||||
{ dgZeldasLetterIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 33 },
|
||||
{ dgKeatonMaskIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 34 },
|
||||
{ dgSkullMaskIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 35 },
|
||||
{ dgSpookyMaskIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 36 },
|
||||
{ dgBunnyHoodIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 37 },
|
||||
{ dgGoronMaskIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 38 },
|
||||
{ dgZoraMaskIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 39 },
|
||||
{ dgGerudoMaskIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 40 },
|
||||
{ dgMaskofTruthIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 41 },
|
||||
{ dgSoldOutIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 42 },
|
||||
{ dgPocketEggIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 43 },
|
||||
{ dgPocketCuccoIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 44 },
|
||||
{ dgCojiroIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 45 },
|
||||
{ dgOddMushroomIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 46 },
|
||||
{ dgOddPotionIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 47 },
|
||||
{ dgPoachersSawIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 48 },
|
||||
{ dgBrokenBiggoronSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 49 },
|
||||
{ dgPrescriptionIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 50 },
|
||||
{ dgEyeBallFrogIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 51 },
|
||||
{ dgEyeDropsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 52 },
|
||||
{ dgClaimCheckIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 53 },
|
||||
{ dgKokiriSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 54 },
|
||||
{ dgMasterSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 55 },
|
||||
{ dgBiggoronSwordIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 56 },
|
||||
{ dgDekuShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 57 },
|
||||
{ dgHylianShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 58 },
|
||||
{ dgMirrorShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 59 },
|
||||
{ dgKokiriTunicIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 60 },
|
||||
{ dgGoronTunicIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 61 },
|
||||
{ dgZoraTunicIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 62 },
|
||||
{ dgKokiriBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 63 },
|
||||
{ dgIronBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 64 },
|
||||
{ dgHoverBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 65 },
|
||||
{ dgBulletBag30IconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 66 },
|
||||
{ dgBulletBag40IconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 67 },
|
||||
{ dgBulletBag50IconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 68 },
|
||||
{ dgQuiver30IconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 69 },
|
||||
{ dgBombBag20IconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 70 },
|
||||
{ dgGoronsBraceletIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 71 },
|
||||
{ dgSilverGauntletsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 72 },
|
||||
{ dgGoldenGauntletsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 73 },
|
||||
{ dgSilverScaleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 74 },
|
||||
{ dgGoldenScaleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 75 },
|
||||
{ dgBrokenGiantsKnifeIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 76 },
|
||||
{ dgAdultsWalletIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 77 },
|
||||
{ dgGiantsWalletIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 78 },
|
||||
{ dgDekuSeedsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 79 },
|
||||
{ dgFishingPoleIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 80 },
|
||||
{ dgForestMedallionIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 81 },
|
||||
{ dgFireMedallionIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 82 },
|
||||
{ dgWaterMedallionIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 83 },
|
||||
{ dgSpiritMedallionIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 84 },
|
||||
{ dgShadowMedallionIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 85 },
|
||||
{ dgLightMedallionIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 86 },
|
||||
{ dgKokiriEmeraldIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 87 },
|
||||
{ dgGoronRubyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 88 },
|
||||
{ dgZoraSapphireIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 89 },
|
||||
{ dgStoneOfAgonyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 90 },
|
||||
{ dgGerudosCardIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 91 },
|
||||
{ dgGoldSkulltulaIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 92 },
|
||||
{ dgHeartContainerIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 93 },
|
||||
{ dgBossKeyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 94 },
|
||||
{ dgCompassIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 95 },
|
||||
{ dgDungeonMapIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 96 },
|
||||
{ dgSmallKeyIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 97 },
|
||||
{ dgSmallMagicJarIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 98 },
|
||||
{ dgBigMagicJarIconTex, 24, 24, G_IM_FMT_RGBA, G_IM_SIZ_32b, 99 },
|
||||
} };
|
@ -20,11 +20,11 @@
|
||||
#include "randomizer_check_objects.h"
|
||||
#include <sstream>
|
||||
#include "draw.h"
|
||||
#include "rando_hash.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
std::unordered_map<uint8_t, Sprite> gSeedTextures;
|
||||
std::unordered_map<std::string, RandomizerCheck> SpoilerfileCheckNameToEnum;
|
||||
std::unordered_map<std::string, RandomizerGet> SpoilerfileGetNameToEnum;
|
||||
std::unordered_map<RandomizerGet, std::vector<std::string>> EnumToSpoilerfileGetName;
|
||||
@ -66,36 +66,6 @@ static const char* frenchRupeeNames[36] = {
|
||||
};
|
||||
|
||||
Randomizer::Randomizer() {
|
||||
Sprite bowSprite = { dgFairyBowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 0 };
|
||||
gSeedTextures[0] = bowSprite;
|
||||
|
||||
Sprite bombchuSprite = { dgBombchuIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 1 };
|
||||
gSeedTextures[1] = bombchuSprite;
|
||||
|
||||
Sprite beansSprite = { dgMagicBeansIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 2 };
|
||||
gSeedTextures[2] = beansSprite;
|
||||
|
||||
Sprite milkSprite = { dgMilkFullIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 3 };
|
||||
gSeedTextures[3] = milkSprite;
|
||||
|
||||
Sprite frogSprite = { dgEyeBallFrogIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 4 };
|
||||
gSeedTextures[4] = frogSprite;
|
||||
|
||||
Sprite mirrorShieldSprite = { dgMirrorShieldIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 5 };
|
||||
gSeedTextures[5] = mirrorShieldSprite;
|
||||
|
||||
Sprite hoverBootsSprite = { dgHoverBootsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 6 };
|
||||
gSeedTextures[6] = hoverBootsSprite;
|
||||
|
||||
Sprite megatonHammerSprite = { dgMegatonHammerIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 7 };
|
||||
gSeedTextures[7] = megatonHammerSprite;
|
||||
|
||||
Sprite silverGauntletsSprite = { dgSilverGauntletsIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 8 };
|
||||
gSeedTextures[8] = silverGauntletsSprite;
|
||||
|
||||
Sprite ootOcarinaSprite = { dgOcarinaofTimeIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 9 };
|
||||
gSeedTextures[9] = ootOcarinaSprite;
|
||||
|
||||
for (auto areaIt : RandomizerCheckObjects::GetAllRCObjects()) {
|
||||
for (auto locationIt : areaIt.second) {
|
||||
SpoilerfileCheckNameToEnum[locationIt.rcSpoilerName] = locationIt.rc;
|
||||
|
@ -238,6 +238,10 @@ namespace GameMenuBar {
|
||||
CVar_SetS32("gInjectSkulltulaCount", 0);
|
||||
// Pull grave during the day
|
||||
CVar_SetS32("gDayGravePull", 0);
|
||||
// Blue Fire Arrows
|
||||
CVar_SetS32("gBlueFireArrows", 0);
|
||||
// Sunlight Arrows
|
||||
CVar_SetS32("gSunlightArrows", 0);
|
||||
|
||||
// Rotate link (0 to 2)
|
||||
CVar_SetS32("gPauseLiveLinkRotation", 0);
|
||||
@ -655,8 +659,6 @@ namespace GameMenuBar {
|
||||
UIWidgets::Tooltip("Allows the D-pad to be used as extra C buttons");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow the cursor to be on any slot", "gPauseAnyCursor", true, false);
|
||||
UIWidgets::Tooltip("Allows the cursor on the pause menu to be over any slot\nSimilar to Rando and Spaceworld 97");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Prevent Dropped Ocarina Inputs", "gDpadNoDropOcarinaInput", true, false);
|
||||
UIWidgets::Tooltip("Prevent dropping inputs when playing the ocarina quickly");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", "gNaviOnL", true, false);
|
||||
UIWidgets::Tooltip("Speak to Navi with L but enter first-person camera with C-Up");
|
||||
ImGui::EndMenu();
|
||||
@ -680,8 +682,6 @@ namespace GameMenuBar {
|
||||
UIWidgets::Tooltip("Prevent forced Navi conversations");
|
||||
UIWidgets::PaddedEnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze", true, false);
|
||||
UIWidgets::Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas");
|
||||
UIWidgets::PaddedEnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood", true, false);
|
||||
UIWidgets::Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Fast Chests", "gFastChests", true, false);
|
||||
UIWidgets::Tooltip("Kick open every chest");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false);
|
||||
@ -697,15 +697,26 @@ namespace GameMenuBar {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", "gSkipScarecrow", true, false,
|
||||
forceSkipScarecrow, forceSkipScarecrowText, UIWidgets::CheckboxGraphics::Checkmark);
|
||||
UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", true, false);
|
||||
UIWidgets::Tooltip("When loading a save, places Link at the last entrance he went through.\n"
|
||||
"This doesn't work if the save was made in a grotto.");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Items"))
|
||||
{
|
||||
UIWidgets::PaddedEnhancementCheckbox("Instant Putaway", "gInstantPutaway", true, false);
|
||||
UIWidgets::Tooltip("Allow Link to put items away without having to wait around");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Instant Boomerang Recall", "gFastBoomerang", true, false);
|
||||
UIWidgets::Tooltip("Instantly return the boomerang to Link by pressing its item button while it's in the air");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Prevent Dropped Ocarina Inputs", "gDpadNoDropOcarinaInput", true, false);
|
||||
UIWidgets::Tooltip("Prevent dropping inputs when playing the ocarina quickly");
|
||||
UIWidgets::PaddedEnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood", true, false);
|
||||
UIWidgets::Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Mask Select in Inventory", "gMaskSelect", true, false);
|
||||
UIWidgets::Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", true, false);
|
||||
UIWidgets::Tooltip("When loading a save, places Link at the last entrance he went through.\n"
|
||||
"This doesn't work if the save was made in a grotto.");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
@ -884,6 +895,10 @@ namespace GameMenuBar {
|
||||
UIWidgets::Tooltip("Injects Golden Skulltula total count in pickup messages");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Pull grave during the day", "gDayGravePull", true, false);
|
||||
UIWidgets::Tooltip("Allows graves to be pulled when child during the day");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Blue Fire Arrows", "gBlueFireArrows", true, false);
|
||||
UIWidgets::Tooltip("Allows Ice Arrows to melt red ice.\nMay require a room reload if toggled during gameplay.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Sunlight Arrows", "gSunlightArrows", true, false);
|
||||
UIWidgets::Tooltip("Allows Light Arrows to activate sun switches.\nMay require a room reload if toggled during gameplay.");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
const char gBuildVersion[] = "ZHORA ALFA (3.1.0)";
|
||||
const char gBuildVersion[] = "ZHORA ALFA (4.0.0)";
|
||||
const char gBuildTeam[] = "github.com/harbourmasters";
|
||||
const char gBuildDate[] = __DATE__ " " __TIME__;
|
||||
const char gBuildMakeOption[] = "";
|
||||
|
@ -218,7 +218,8 @@ void GivePlayerRandoRewardNocturne(GlobalContext* globalCtx, RandomizerCheck che
|
||||
!Player_InBlockingCsMode(globalCtx, player) && !Flags_GetEventChkInf(0xAA)) {
|
||||
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_NOCTURNE_OF_SHADOW);
|
||||
GiveItemEntryWithoutActor(globalCtx, getItemEntry);
|
||||
Flags_SetEventChkInf(0xAA);
|
||||
player->pendingFlag.flagID = 0xAA;
|
||||
player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +231,8 @@ void GivePlayerRandoRewardRequiem(GlobalContext* globalCtx, RandomizerCheck chec
|
||||
!Player_InBlockingCsMode(globalCtx, player)) {
|
||||
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME);
|
||||
GiveItemEntryWithoutActor(globalCtx, getItemEntry);
|
||||
Flags_SetEventChkInf(0xAC);
|
||||
player->pendingFlag.flagID = 0xAC;
|
||||
player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ void GiveLinksPocketItem() {
|
||||
gSaveContext.bgsFlag = true;
|
||||
}
|
||||
Item_Give(NULL, getItemEntry.itemId);
|
||||
} else if (getItemEntry.modIndex == MOD_RANDOMIZER) {
|
||||
} else if (getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId != RG_ICE_TRAP) {
|
||||
Randomizer_Item_Give(NULL, getItemEntry);
|
||||
}
|
||||
}
|
||||
@ -406,7 +406,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
gSaveContext.bgsFlag = true;
|
||||
}
|
||||
Item_Give(NULL, getItem.itemId);
|
||||
} else if (getItem.modIndex == MOD_RANDOMIZER) {
|
||||
} else if (getItem.modIndex == MOD_RANDOMIZER && getItem.getItemId != RG_ICE_TRAP) {
|
||||
Randomizer_Item_Give(NULL, getItem);
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,27 @@ static ColliderQuadInit sQuadInit = {
|
||||
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
|
||||
};
|
||||
|
||||
// Replacement quad used for "Blue Fire Arrows" enhancement
|
||||
static ColliderQuadInit sIceArrowQuadInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_NONE,
|
||||
AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER,
|
||||
OC1_NONE,
|
||||
OC2_TYPE_2,
|
||||
COLSHAPE_QUAD,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00000048, 0x00, 0x00 },
|
||||
{ 0x00001048, 0x00, 0x00 },
|
||||
TOUCH_NONE,
|
||||
BUMP_ON,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
|
||||
};
|
||||
|
||||
static BombableWallInfo sBombableWallInfo[] = {
|
||||
{ &object_bwall_Col_000118, object_bwall_DL_000040, 0 },
|
||||
{ &object_bwall_Col_000118, object_bwall_DL_000040, 0 },
|
||||
@ -73,6 +94,8 @@ static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
bool blueFireArrowsEnabledOnMudwallLoad = false;
|
||||
|
||||
void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
@ -82,6 +105,9 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF;
|
||||
|
||||
// Initialize this with the mud wall, so it can't be affected by toggling while the actor is loaded
|
||||
blueFireArrowsEnabledOnMudwallLoad = (CVar_GetS32("gBlueFireArrows", 0));
|
||||
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
DynaPolyActor_Init(&this->dyna, DPM_UNK);
|
||||
this->bombableWallDList = sBombableWallInfo[wallType].dList;
|
||||
@ -98,8 +124,15 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f);
|
||||
Collider_InitQuad(globalCtx, &this->collider);
|
||||
Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit);
|
||||
|
||||
// If "Blue Fire Arrows" are enabled, set up this collider for them
|
||||
if (blueFireArrowsEnabledOnMudwallLoad) {
|
||||
Collider_InitQuad(globalCtx, &this->collider);
|
||||
Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sIceArrowQuadInit);
|
||||
} else {
|
||||
Collider_InitQuad(globalCtx, &this->collider);
|
||||
Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit);
|
||||
}
|
||||
} else {
|
||||
this->dyna.actor.world.pos.y -= 40.0f;
|
||||
}
|
||||
@ -227,7 +260,21 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, GlobalContext* globalCtx) {
|
||||
* despawn itself.
|
||||
*/
|
||||
void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) {
|
||||
if (this->collider.base.acFlags & 2) {
|
||||
bool blueFireArrowHit = false;
|
||||
// If "Blue Fire Arrows" enabled, check this collider for a hit
|
||||
if (blueFireArrowsEnabledOnMudwallLoad) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
if ((this->collider.base.ac != NULL) && (this->collider.base.ac->id == ACTOR_EN_ARROW)) {
|
||||
|
||||
if (this->collider.base.ac->child != NULL &&
|
||||
this->collider.base.ac->child->id == ACTOR_ARROW_ICE) {
|
||||
blueFireArrowHit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->collider.base.acFlags & 2 || blueFireArrowHit) {
|
||||
Vec3f effectPos;
|
||||
s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF;
|
||||
|
||||
|
@ -14,6 +14,9 @@ void func_808911BC(BgIceShelter* this);
|
||||
void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx);
|
||||
void func_808911D4(BgIceShelter* this, GlobalContext* globalCtx);
|
||||
|
||||
// For "Blue Fire Arrows" enhancement
|
||||
void MeltOnIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, GlobalContext* globalCtx);
|
||||
|
||||
const ActorInit Bg_Ice_Shelter_InitVars = {
|
||||
ACTOR_BG_ICE_SHELTER,
|
||||
ACTORCAT_BG,
|
||||
@ -32,7 +35,7 @@ static f32 sScales[] = { 0.1f, 0.06f, 0.1f, 0.1f, 0.25f };
|
||||
static Color_RGBA8 sDustPrimColor = { 250, 250, 250, 255 };
|
||||
static Color_RGBA8 sDustEnvColor = { 180, 180, 180, 255 };
|
||||
|
||||
static ColliderCylinderInit D_8089170C = {
|
||||
static ColliderCylinderInit sCylinder1Init = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_NONE,
|
||||
@ -52,7 +55,7 @@ static ColliderCylinderInit D_8089170C = {
|
||||
{ 0, 0, 0, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
static ColliderCylinderInit D_80891738 = {
|
||||
static ColliderCylinderInit sCylinder2Init = {
|
||||
{
|
||||
COLTYPE_HARD,
|
||||
AT_NONE,
|
||||
@ -72,14 +75,45 @@ static ColliderCylinderInit D_80891738 = {
|
||||
{ 0, 0, 0, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
// This cylinder only used for "Blue Fire Arrows" enhancement
|
||||
static ColliderCylinderInit sIceArrowCylinderInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_NONE,
|
||||
AC_ON | AC_TYPE_OTHER | AC_TYPE_PLAYER,
|
||||
OC1_ON | OC1_TYPE_ALL,
|
||||
OC2_TYPE_2,
|
||||
COLSHAPE_CYLINDER,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00000000, 0x00, 0x00 },
|
||||
{ 0xFFCFFFFF, 0x00, 0x00 },
|
||||
TOUCH_NONE,
|
||||
BUMP_ON,
|
||||
OCELEM_ON,
|
||||
},
|
||||
{ 0, 0, 0, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
bool blueFireArrowsEnabledOnRedIceLoad = false;
|
||||
|
||||
void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) {
|
||||
static s16 cylinderRadii[] = { 47, 33, 44, 41, 100 };
|
||||
static s16 cylinderHeights[] = { 80, 54, 90, 60, 200 };
|
||||
s32 pad;
|
||||
s32 type = (this->dyna.actor.params >> 8) & 7;
|
||||
|
||||
// Initialize this with the red ice, so it can't be affected by toggling while the actor is loaded
|
||||
blueFireArrowsEnabledOnRedIceLoad = (CVar_GetS32("gBlueFireArrows", 0));
|
||||
|
||||
Collider_InitCylinder(globalCtx, &this->cylinder1);
|
||||
Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &D_8089170C);
|
||||
// If "Blue Fire Arrows" is enabled, set up a collider on the red ice that responds to them
|
||||
if (blueFireArrowsEnabledOnRedIceLoad) {
|
||||
Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &sIceArrowCylinderInit);
|
||||
} else {
|
||||
Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &sCylinder1Init);
|
||||
}
|
||||
Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder1);
|
||||
|
||||
this->cylinder1.dim.radius = cylinderRadii[type];
|
||||
@ -87,7 +121,7 @@ void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) {
|
||||
|
||||
if (type == 0 || type == 1 || type == 4) {
|
||||
Collider_InitCylinder(globalCtx, &this->cylinder2);
|
||||
Collider_SetCylinder(globalCtx, &this->cylinder2, &this->dyna.actor, &D_80891738);
|
||||
Collider_SetCylinder(globalCtx, &this->cylinder2, &this->dyna.actor, &sCylinder2Init);
|
||||
Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder2);
|
||||
this->cylinder2.dim.radius = cylinderRadii[type];
|
||||
this->cylinder2.dim.height = cylinderHeights[type];
|
||||
@ -292,7 +326,12 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) {
|
||||
this->dyna.actor.parent->freezeTimer = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have "Blue Fire Arrows" enabled, check both cylinders for a hit
|
||||
if (blueFireArrowsEnabledOnRedIceLoad) {
|
||||
MeltOnIceArrowHit(this, this->cylinder1, type, globalCtx);
|
||||
MeltOnIceArrowHit(this, this->cylinder2, type, globalCtx);
|
||||
}
|
||||
// Default blue fire check
|
||||
if (this->cylinder1.base.acFlags & AC_HIT) {
|
||||
this->cylinder1.base.acFlags &= ~AC_HIT;
|
||||
|
||||
@ -320,6 +359,24 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->cylinder1.base);
|
||||
}
|
||||
|
||||
// For "Blue Fire Arrows" enhancement: If hit by an Ice Arrow, melt the red ice (copied from the default blue fire function above).
|
||||
void MeltOnIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, GlobalContext* globalCtx) {
|
||||
if (cylinder.base.acFlags & AC_HIT) {
|
||||
cylinder.base.acFlags &= ~AC_HIT;
|
||||
if ((cylinder.base.ac != NULL) && (cylinder.base.ac->id == ACTOR_EN_ARROW)) {
|
||||
if (cylinder.base.ac->child != NULL && cylinder.base.ac->child->id == ACTOR_ARROW_ICE) {
|
||||
if (type == 4) {
|
||||
if (this->dyna.actor.parent != NULL) {
|
||||
this->dyna.actor.parent->freezeTimer = 50;
|
||||
}
|
||||
}
|
||||
func_808911BC(this);
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_ICE_MELT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_808911BC(BgIceShelter* this) {
|
||||
this->actionFunc = func_808911D4;
|
||||
this->alpha = 255;
|
||||
|
@ -96,7 +96,15 @@ void BgJyaLift_DelayMove(BgJyaLift* this, GlobalContext* globalCtx) {
|
||||
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F) || (this->moveDelay > 0)) {
|
||||
this->moveDelay++;
|
||||
if (this->moveDelay >= 20) {
|
||||
OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM);
|
||||
// The cutscene of the platform lowering will show the central room in an unloaded state if
|
||||
// Link is not standing on the platform as it lowers. Therefore check for the Sunlight arrows
|
||||
// enhancement and if it's enabled, check that Link is on the platform. Otherwise skip it.
|
||||
if (!CVar_GetS32("gSunlightArrows", 0) || (GET_PLAYER(globalCtx)->actor.world.pos.x > -19.0f &&
|
||||
GET_PLAYER(globalCtx)->actor.world.pos.x < 139.0f &&
|
||||
GET_PLAYER(globalCtx)->actor.world.pos.z > -1172.0f &&
|
||||
GET_PLAYER(globalCtx)->actor.world.pos.z < -1009.0f)) {
|
||||
OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM);
|
||||
}
|
||||
BgJyaLift_SetupMove(this);
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,36 @@ static ColliderJntSphInit sColliderJntSphInit = {
|
||||
1,
|
||||
sColliderJntSphElementInit,
|
||||
};
|
||||
// Collider info used for "Sunlight Arrows"
|
||||
static ColliderJntSphElementInit sColliderLightArrowElementInit[] = {
|
||||
{
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00000000, 0x00, 0x00 },
|
||||
{ 0x00202000, 0x00, 0x00 },
|
||||
TOUCH_NONE,
|
||||
BUMP_ON,
|
||||
OCELEM_ON,
|
||||
},
|
||||
{ 0, { { 0, 0, 0 }, 19 }, 100 },
|
||||
},
|
||||
};
|
||||
// Sphere collider used for "Sunlight Arrows"
|
||||
static ColliderJntSphInit sColliderLightArrowInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_NONE,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_ON | OC1_TYPE_ALL,
|
||||
OC2_TYPE_2,
|
||||
COLSHAPE_JNTSPH,
|
||||
},
|
||||
1,
|
||||
sColliderLightArrowElementInit,
|
||||
};
|
||||
|
||||
bool sunSwitchActivatedByLightArrow = false;
|
||||
bool sunLightArrowsEnabledOnSunSwitchLoad = false;
|
||||
|
||||
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE };
|
||||
|
||||
@ -92,8 +122,16 @@ static InitChainEntry sInitChain[] = {
|
||||
void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
|
||||
// Initialize this with the sun switch, so it can't be affected by toggling while the actor is loaded
|
||||
sunLightArrowsEnabledOnSunSwitchLoad = (CVar_GetS32("gSunlightArrows", 0));
|
||||
|
||||
Collider_InitJntSph(globalCtx, &this->collider);
|
||||
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems);
|
||||
// If "Sunlight Arrows" is enabled, set up the collider to allow Light Arrow hits
|
||||
if (sunLightArrowsEnabledOnSunSwitchLoad) {
|
||||
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderLightArrowInit, this->colliderItems);
|
||||
} else {
|
||||
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems);
|
||||
}
|
||||
Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x,
|
||||
this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y),
|
||||
this->actor.world.pos.z, &this->actor.shape.rot);
|
||||
@ -211,6 +249,26 @@ void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
GlobalContext* globalCtx = globalCtx2;
|
||||
ObjLightswitch* this = (ObjLightswitch*)thisx;
|
||||
|
||||
// Unset the switch flag on room exit to prevent the rock in the wall from
|
||||
// vanishing on its own after activating the sun switch by Light Arrow
|
||||
// Also prevents the cobra mirror from rotating to face the sun on its own
|
||||
// Makes sun switches temporary when activated by Light Arrows (will turn off on room exit)
|
||||
if (sunSwitchActivatedByLightArrow) {
|
||||
switch (this->actor.params >> 4 & 3) {
|
||||
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
||||
case OBJLIGHTSWITCH_TYPE_2:
|
||||
case OBJLIGHTSWITCH_TYPE_1:
|
||||
// Except for this one, because we want the chain platform to stay down for good
|
||||
if (this->actor.room != 25) {
|
||||
Flags_UnsetSwitch(globalCtx, this->actor.params >> 8 & 0x3F);
|
||||
}
|
||||
sunSwitchActivatedByLightArrow = false;
|
||||
break;
|
||||
case OBJLIGHTSWITCH_TYPE_BURN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Collider_DestroyJntSph(globalCtx, &this->collider);
|
||||
}
|
||||
|
||||
@ -221,8 +279,11 @@ void ObjLightswitch_SetupOff(ObjLightswitch* this) {
|
||||
this->color[1] = 125 << 6;
|
||||
this->color[2] = 255 << 6;
|
||||
this->alpha = 255 << 6;
|
||||
if (sunLightArrowsEnabledOnSunSwitchLoad) {
|
||||
sunSwitchActivatedByLightArrow = false;
|
||||
}
|
||||
}
|
||||
|
||||
// A Sun Switch that is currently turned off
|
||||
void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||
switch (this->actor.params >> 4 & 3) {
|
||||
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
||||
@ -230,6 +291,13 @@ void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
ObjLightswitch_SetupTurnOn(this);
|
||||
ObjLightswitch_SetSwitchFlag(this, globalCtx);
|
||||
// Remember if we've been activated by a Light Arrow, so we can
|
||||
// prevent the switch from immediately turning back off
|
||||
if (sunLightArrowsEnabledOnSunSwitchLoad) {
|
||||
if (this->collider.base.ac != NULL && this->collider.base.ac->id == ACTOR_EN_ARROW) {
|
||||
sunSwitchActivatedByLightArrow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OBJLIGHTSWITCH_TYPE_1:
|
||||
@ -289,13 +357,19 @@ void ObjLightswitch_SetupOn(ObjLightswitch* this) {
|
||||
this->flameRingRotSpeed = -0xAA;
|
||||
this->timer = 0;
|
||||
}
|
||||
|
||||
// A Sun Switch that is currently turned on
|
||||
void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||
switch (this->actor.params >> 4 & 3) {
|
||||
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
||||
if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) {
|
||||
ObjLightswitch_SetupTurnOff(this);
|
||||
}
|
||||
// If hit by sunlight after already being turned on, then behave as if originally activated by sunlight
|
||||
if (sunLightArrowsEnabledOnSunSwitchLoad && (this->collider.base.acFlags & AC_HIT)) {
|
||||
if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) {
|
||||
sunSwitchActivatedByLightArrow = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OBJLIGHTSWITCH_TYPE_1:
|
||||
if (this->collider.base.acFlags & AC_HIT && !(this->prevFrameACflags & AC_HIT)) {
|
||||
@ -304,10 +378,19 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
break;
|
||||
case OBJLIGHTSWITCH_TYPE_2:
|
||||
// If hit by sunlight after already being turned on, then behave as if originally activated by sunlight
|
||||
if (sunLightArrowsEnabledOnSunSwitchLoad && (this->collider.base.acFlags & AC_HIT)) {
|
||||
if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) {
|
||||
sunSwitchActivatedByLightArrow = false;
|
||||
}
|
||||
}
|
||||
if (!(this->collider.base.acFlags & AC_HIT)) {
|
||||
if (this->timer >= 7) {
|
||||
ObjLightswitch_SetupTurnOff(this);
|
||||
ObjLightswitch_ClearSwitchFlag(this, globalCtx);
|
||||
// If we aren't using Enhanced Light Arrows, let the switch turn off normally
|
||||
if (!sunSwitchActivatedByLightArrow) {
|
||||
ObjLightswitch_SetupTurnOff(this);
|
||||
ObjLightswitch_ClearSwitchFlag(this, globalCtx);
|
||||
}
|
||||
} else {
|
||||
this->timer++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user