diff --git a/CMakeLists.txt b/CMakeLists.txt index f42fb69cb..38739bc8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,195 +1,213 @@ -cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR) - -set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE) -set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") -#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use") - issue with soh compile with MSVC - -if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") -set(MACOSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) -endif() - -project(Ship C CXX) - -set(PROJECT_VERSION_MAJOR "3") -set(PROJECT_VERSION_MINOR "0") -set(PROJECT_VERSION_PATCH "0") - -set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) -add_compile_options($<$:/MP>) - -if (CMAKE_SYSTEM_NAME STREQUAL "Windows") -include(CMake/automate-vcpkg.cmake) - -set(VCPKG_TRIPLET x64-windows-static) -set(VCPKG_TARGET_TRIPLET x64-windows-static) - -vcpkg_bootstrap() -vcpkg_install_packages(zlib bzip2 libpng SDL2 GLEW glfw3) -endif() - -################################################################################ -# Set target arch type if empty. Visual studio solution generator provides it. -################################################################################ -if (CMAKE_SYSTEM_NAME STREQUAL "Windows") - if(NOT CMAKE_VS_PLATFORM_NAME) - set(CMAKE_VS_PLATFORM_NAME "x64") - endif() - message("${CMAKE_VS_PLATFORM_NAME} architecture in use") - - if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" - OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")) - message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!") - endif() -endif() - -################################################################################ -# Global configuration types -################################################################################ -if (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch") -set(CMAKE_C_FLAGS_DEBUG "-O3 -ffast-math") -set(CMAKE_CXX_FLAGS_DEBUG "-O3 -ffast-math") -set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG") -set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG") -else() -set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") -set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") -set(CMAKE_OBJCXX_FLAGS_RELEASE "-O2 -DNDEBUG") -endif() - -if(NOT CMAKE_BUILD_TYPE ) - set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE) -endif() - -################################################################################ -# Global compiler options -################################################################################ -if(MSVC) - # remove default flags provided with CMake for MSVC - set(CMAKE_C_FLAGS "") - set(CMAKE_C_FLAGS_DEBUG "") - set(CMAKE_C_FLAGS_RELEASE "") - set(CMAKE_CXX_FLAGS "") - set(CMAKE_CXX_FLAGS_DEBUG "") - set(CMAKE_CXX_FLAGS_RELEASE "") -endif() - -################################################################################ -# Global linker options -################################################################################ -if(MSVC) - # remove default flags provided with CMake for MSVC - set(CMAKE_EXE_LINKER_FLAGS "") - set(CMAKE_MODULE_LINKER_FLAGS "") - set(CMAKE_SHARED_LINKER_FLAGS "") - set(CMAKE_STATIC_LINKER_FLAGS "") - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}") - set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}") - set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}") - set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}") - set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}") - set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}") - set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}") -endif() - -################################################################################ -# Common utils -################################################################################ -include(CMake/Utils.cmake) - -if(CMAKE_SYSTEM_NAME MATCHES "Linux") - get_linux_lsb_release_information() - message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}") -else() - message(STATUS ${CMAKE_SYSTEM_NAME}) -endif() - -################################################################################ -# Additional Global Settings(add specific info there) -################################################################################ -include(CMake/GlobalSettingsInclude.cmake OPTIONAL) - -################################################################################ -# Use solution folders feature -################################################################################ -set_property(GLOBAL PROPERTY USE_FOLDERS ON) - -################################################################################ -# Sub-projects -################################################################################ -add_subdirectory(libultraship/libultraship ${CMAKE_BINARY_DIR}/libultraship) -add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) -add_subdirectory(ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils) -add_subdirectory(OTRExporter) -add_subdirectory(soh) -if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|NintendoSwitch|CafeOS") -add_subdirectory(OTRGui) -endif() - -set_property(TARGET soh PROPERTY APPIMAGE_DESKTOP_FILE_TERMINAL YES) -set_property(TARGET soh PROPERTY APPIMAGE_DESKTOP_FILE "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.desktop") -set_property(TARGET soh PROPERTY APPIMAGE_ICON_FILE "${CMAKE_BINARY_DIR}/sohIcon.png") - -if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") -INSTALL(PROGRAMS "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.sh" DESTINATION . COMPONENT appimage) -endif() - -find_package(Python3 COMPONENTS Interpreter) - -add_custom_target( - ExtractAssets - # CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions - COMMAND ${CMAKE_COMMAND} -E $,remove,rm> -f oot.otr - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$" - COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_SOURCE_DIR} - COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_BINARY_DIR}/soh - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter - COMMENT "Running asset extraction..." - DEPENDS ZAPD - BYPRODUCTS oot.otr ${CMAKE_SOURCE_DIR}/oot.otr -) - -if(CMAKE_SYSTEM_NAME MATCHES "Linux") - find_package(ImageMagick COMPONENTS convert) - if (ImageMagick_FOUND) - execute_process ( - COMMAND ${ImageMagick_convert_EXECUTABLE} soh/macosx/sohIcon.png -resize 512x512 ${CMAKE_BINARY_DIR}/sohIcon.png - OUTPUT_VARIABLE outVar - ) - endif() -endif() - -if(CMAKE_SYSTEM_NAME MATCHES "Darwin") -add_custom_target(CreateOSXIcons - COMMAND mkdir -p ${CMAKE_BINARY_DIR}/macosx/soh.iconset - COMMAND sips -z 16 16 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16.png - COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16@2x.png - COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32.png - COMMAND sips -z 64 64 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32@2x.png - COMMAND sips -z 128 128 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128.png - COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128@2x.png - COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256.png - COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256@2x.png - COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512.png - COMMAND cp soh/macosx/sohIcon.png ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512@2x.png - COMMAND iconutil -c icns -o ${CMAKE_BINARY_DIR}/macosx/soh.icns ${CMAKE_BINARY_DIR}/macosx/soh.iconset - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMENT "Creating OSX icons ..." - ) -add_dependencies(soh CreateOSXIcons) -endif() - -if(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS") -INSTALL(FILES ${CMAKE_SOURCE_DIR}/README.md DESTINATION . COMPONENT ship RENAME readme.txt ) -endif() - -if(CMAKE_SYSTEM_NAME MATCHES "Linux") - set(CPACK_GENERATOR "External") -elseif(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS") - set(CPACK_GENERATOR "ZIP") -elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") - set(CPACK_GENERATOR "Bundle") -endif() - -set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_SOURCE_DIR}/CMake/Packaging-2.cmake) -include(CMake/Packaging.cmake) +cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR) + +set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE) +set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") +#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use") - issue with soh compile with MSVC + +if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") +set(MACOSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) +endif() + +project(Ship C CXX) + +set(PROJECT_VERSION_MAJOR "3") +set(PROJECT_VERSION_MINOR "0") +set(PROJECT_VERSION_PATCH "0") + +set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) +add_compile_options($<$:/MP>) + +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") +include(CMake/automate-vcpkg.cmake) + +set(VCPKG_TRIPLET x64-windows-static) +set(VCPKG_TARGET_TRIPLET x64-windows-static) + +vcpkg_bootstrap() +vcpkg_install_packages(zlib bzip2 libpng SDL2 GLEW glfw3) +endif() + +################################################################################ +# Set target arch type if empty. Visual studio solution generator provides it. +################################################################################ +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + if(NOT CMAKE_VS_PLATFORM_NAME) + set(CMAKE_VS_PLATFORM_NAME "x64") + endif() + message("${CMAKE_VS_PLATFORM_NAME} architecture in use") + + if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" + OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")) + message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!") + endif() +endif() + +################################################################################ +# Global configuration types +################################################################################ +if (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch") +set(CMAKE_C_FLAGS_DEBUG "-O3 -ffast-math") +set(CMAKE_CXX_FLAGS_DEBUG "-O3 -ffast-math") +set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG") +else() +set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") +set(CMAKE_OBJCXX_FLAGS_RELEASE "-O2 -DNDEBUG") +endif() + +if(NOT CMAKE_BUILD_TYPE ) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE) +endif() + +################################################################################ +# Global compiler options +################################################################################ +if(MSVC) + # remove default flags provided with CMake for MSVC + set(CMAKE_C_FLAGS "") + set(CMAKE_C_FLAGS_DEBUG "") + set(CMAKE_C_FLAGS_RELEASE "") + set(CMAKE_CXX_FLAGS "") + set(CMAKE_CXX_FLAGS_DEBUG "") + set(CMAKE_CXX_FLAGS_RELEASE "") +endif() + +################################################################################ +# Global linker options +################################################################################ +if(MSVC) + # remove default flags provided with CMake for MSVC + set(CMAKE_EXE_LINKER_FLAGS "") + set(CMAKE_MODULE_LINKER_FLAGS "") + set(CMAKE_SHARED_LINKER_FLAGS "") + set(CMAKE_STATIC_LINKER_FLAGS "") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}") + set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}") + set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}") +endif() + +################################################################################ +# Common utils +################################################################################ +include(CMake/Utils.cmake) + +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + get_linux_lsb_release_information() + message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}") +else() + message(STATUS ${CMAKE_SYSTEM_NAME}) +endif() + +################################################################################ +# Additional Global Settings(add specific info there) +################################################################################ +include(CMake/GlobalSettingsInclude.cmake OPTIONAL) + +################################################################################ +# Use solution folders feature +################################################################################ +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +################################################################################ +# Sub-projects +################################################################################ +add_subdirectory(libultraship/libultraship ${CMAKE_BINARY_DIR}/libultraship) +add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) +add_subdirectory(ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils) +add_subdirectory(OTRExporter) +add_subdirectory(soh) +if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|NintendoSwitch|CafeOS") +add_subdirectory(OTRGui) +endif() + +set_property(TARGET soh PROPERTY APPIMAGE_DESKTOP_FILE_TERMINAL YES) +set_property(TARGET soh PROPERTY APPIMAGE_DESKTOP_FILE "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.desktop") +set_property(TARGET soh PROPERTY APPIMAGE_ICON_FILE "${CMAKE_BINARY_DIR}/sohIcon.png") + +if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") +install(PROGRAMS "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.sh" DESTINATION . COMPONENT appimage) +endif() + +find_package(Python3 COMPONENTS Interpreter) + +add_custom_target( + ExtractAssets + # CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions + COMMAND ${CMAKE_COMMAND} -E $,remove,rm> -f oot.otr + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$" + COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_BINARY_DIR}/soh + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter + COMMENT "Running asset extraction..." + DEPENDS ZAPD + BYPRODUCTS oot.otr ${CMAKE_SOURCE_DIR}/oot.otr +) + +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + find_package(ImageMagick COMPONENTS convert) + if (ImageMagick_FOUND) + execute_process ( + COMMAND ${ImageMagick_convert_EXECUTABLE} soh/macosx/sohIcon.png -resize 512x512 ${CMAKE_BINARY_DIR}/sohIcon.png + OUTPUT_VARIABLE outVar + ) + endif() +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Darwin") +add_custom_target(CreateOSXIcons + COMMAND mkdir -p ${CMAKE_BINARY_DIR}/macosx/soh.iconset + COMMAND sips -z 16 16 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16.png + COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16@2x.png + COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32.png + COMMAND sips -z 64 64 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32@2x.png + COMMAND sips -z 128 128 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128.png + COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128@2x.png + COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256.png + COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256@2x.png + COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512.png + COMMAND cp soh/macosx/sohIcon.png ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512@2x.png + COMMAND iconutil -c icns -o ${CMAKE_BINARY_DIR}/macosx/soh.icns ${CMAKE_BINARY_DIR}/macosx/soh.iconset + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Creating OSX icons ..." + ) +add_dependencies(soh CreateOSXIcons) + +add_custom_target(Assets ALL + COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/OTRGui/assets/extractor" -Ddst_dir="${CMAKE_BINARY_DIR}/assets/extractor" -P "${CMAKE_SOURCE_DIR}/OTRGui/Overwrite.cmake" + COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/OTRExporter/assets" -Ddst_dir="${CMAKE_BINARY_DIR}/assets/game" -P "${CMAKE_SOURCE_DIR}/OTRGui/Overwrite.cmake" + COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/soh/assets/xml" -Ddst_dir="${CMAKE_BINARY_DIR}/assets/extractor/xmls" -P "${CMAKE_SOURCE_DIR}/OTRGui/Overwrite.cmake" + ) +add_dependencies(soh Assets) + +install(TARGETS ZAPD DESTINATION ${CMAKE_BINARY_DIR}/assets/extractor) + +set(PROGRAM_PERMISSIONS_EXECUTE OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) + +install(DIRECTORY ${CMAKE_BINARY_DIR}/assets + DESTINATION . + PATTERN ZAPD.out + PERMISSIONS ${PROGRAM_PERMISSIONS_EXECUTE} + ) + +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS") +install(FILES ${CMAKE_SOURCE_DIR}/README.md DESTINATION . COMPONENT ship RENAME readme.txt ) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(CPACK_GENERATOR "External") +elseif(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS") + set(CPACK_GENERATOR "ZIP") +elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") + set(CPACK_GENERATOR "Bundle") +endif() + +set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_SOURCE_DIR}/CMake/Packaging-2.cmake) +include(CMake/Packaging.cmake) diff --git a/Jenkinsfile b/Jenkinsfile index ca6c9aef5..55c4b4f28 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -23,7 +23,7 @@ pipeline { ]) sh ''' cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64 - cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release + cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" cmake --build build-cmake --target ExtractAssets --config Release ''' stash includes: 'soh/assets/**/*', name: 'assets' diff --git a/libultraship/libultraship/ControlDeck.cpp b/libultraship/libultraship/ControlDeck.cpp index 6e3328053..36e581fc7 100644 --- a/libultraship/libultraship/ControlDeck.cpp +++ b/libultraship/libultraship/ControlDeck.cpp @@ -73,12 +73,7 @@ namespace Ship { } void ControlDeck::WriteToPad(OSContPad* pad) const { - - #ifdef __SWITCH__ - bool shouldBlockGameInput = CVar_GetS32("gOpenMenuBar", 0); - #else bool shouldBlockGameInput = CVar_GetS32("gOpenMenuBar", 0) && CVar_GetS32("gControlNav", 0); - #endif for (size_t i = 0; i < virtualDevices.size(); i++) { const std::shared_ptr backend = physicalDevices[virtualDevices[i]]; diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index ac7ab9d73..cac675a93 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -484,12 +484,7 @@ namespace SohImGui { io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; } - #ifdef __SWITCH__ - bool enableControllerNavigation = true; - #else - bool enableControllerNavigation = CVar_GetS32("gControlNav", 0); - #endif - if (enableControllerNavigation && CVar_GetS32("gOpenMenuBar", 0)) { + if (CVar_GetS32("gControlNav", 0) && CVar_GetS32("gOpenMenuBar", 0)) { io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard; } else { io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; @@ -921,19 +916,15 @@ namespace SohImGui { ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None | ImGuiDockNodeFlags_NoDockingInCentralNode); - if (ImGui::IsKeyPressed(TOGGLE_BTN) || ImGui::IsKeyPressed(TOGGLE_PAD_BTN)) { + if (ImGui::IsKeyPressed(TOGGLE_BTN) || + (ImGui::IsKeyPressed(TOGGLE_PAD_BTN) && CVar_GetS32("gControlNav", 0))) { bool menu_bar = CVar_GetS32("gOpenMenuBar", 0); CVar_SetS32("gOpenMenuBar", !menu_bar); needs_save = true; GlobalCtx2::GetInstance()->GetWindow()->SetMenuBar(menu_bar); ShowCursor(menu_bar, Dialogues::dMenubar); GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->SaveControllerSettings(); - #ifdef __SWITCH__ - bool enableControllerNavigation = true; - #else - bool enableControllerNavigation = CVar_GetS32("gControlNav", 0); - #endif - if (enableControllerNavigation && CVar_GetS32("gOpenMenuBar", 0)) { + if (CVar_GetS32("gControlNav", 0) && CVar_GetS32("gOpenMenuBar", 0)) { io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard; } else { io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; diff --git a/libultraship/libultraship/WiiUController.cpp b/libultraship/libultraship/WiiUController.cpp index cfaa9dbd7..19835a548 100644 --- a/libultraship/libultraship/WiiUController.cpp +++ b/libultraship/libultraship/WiiUController.cpp @@ -406,6 +406,14 @@ namespace Ship { x *= scale; y *= scale; } + + if (isRightStick) { + getRightStickX(virtualSlot) = x; + getRightStickY(virtualSlot) = y; + } else { + getLeftStickX(virtualSlot) = x; + getLeftStickY(virtualSlot) = y; + } } void WiiUController::CreateDefaultBinding(int32_t virtualSlot) { diff --git a/libultraship/libultraship/WiiUGamepad.cpp b/libultraship/libultraship/WiiUGamepad.cpp index 79d41b35f..64ef9e90f 100644 --- a/libultraship/libultraship/WiiUGamepad.cpp +++ b/libultraship/libultraship/WiiUGamepad.cpp @@ -279,6 +279,14 @@ namespace Ship { x *= scale; y *= scale; } + + if (isRightStick) { + getRightStickX(virtualSlot) = x; + getRightStickY(virtualSlot) = y; + } else { + getLeftStickX(virtualSlot) = x; + getLeftStickY(virtualSlot) = y; + } } void WiiUGamepad::CreateDefaultBinding(int32_t virtualSlot) { diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index fec894735..a8693eb35 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -220,6 +220,7 @@ set(Header_Files__soh__Enhancements__randomizer__3drando "soh/Enhancements/randomizer/3drando/trial.hpp" "soh/Enhancements/randomizer/3drando/utils.hpp" ) + source_group("Header Files\\soh\\Enhancements\\randomizer\\3drando" FILES ${Header_Files__soh__Enhancements__randomizer__3drando}) set(Header_Files__soh__Enhancements__custom_message @@ -229,6 +230,13 @@ set(Header_Files__soh__Enhancements__custom_message source_group("Header Files\\soh\\Enhancements\\custom-message" FILES ${Header_Files__soh__Enhancements__custom_message}) +set(Header_Files__soh__Enhancements__item_tables + "soh/Enhancements/item-tables/ItemTableManager.h" + "soh/Enhancements/item-tables/ItemTableTypes.h" +) + +source_group("Header Files\\soh\\Enhancements\\item-tables" FILES ${Header_Files__soh__Enhancements__item_tables}) + set(Source_Files__soh "soh/GbiWrap.cpp" "soh/OTRAudio.h" @@ -353,6 +361,12 @@ set(Source_Files__soh__Enhancements__custom_message source_group("Source Files\\soh\\Enhancements\\custom-message" FILES ${Source_Files__soh__Enhancements__custom_message}) +set(Source_Files__soh__Enhancements__item_tables + "soh/Enhancements/item-tables/ItemTableManager.cpp" +) + +source_group("Source Files\\soh\\Enhancements\\item-tables" FILES ${Source_Files__soh__Enhancements__item_tables}) + set(Source_Files__src__boot "src/boot/assert.c" "src/boot/boot_main.c" @@ -1562,6 +1576,7 @@ set(ALL_FILES ${Header_Files__soh__Enhancements__debugger} ${Header_Files__soh__Enhancements__randomizer} ${Header_Files__soh__Enhancements__randomizer__3drando} + ${Header_Files__soh__Enhancements__item_tables} ${Header_Files__soh__Enhancements__custom_message} ${Source_Files__soh} ${Source_Files__soh__Enhancements} @@ -1572,6 +1587,7 @@ set(ALL_FILES ${Source_Files__soh__Enhancements__randomizer__3drando} ${Source_Files__soh__Enhancements__randomizer__3drando__hint_list} ${Source_Files__soh__Enhancements__randomizer__3drando__location_access} + ${Source_Files__soh__Enhancements__item_tables} ${Source_Files__soh__Enhancements__custom_message} ${Source_Files__src__boot} ${Source_Files__src__buffers} diff --git a/soh/include/functions.h b/soh/include/functions.h index 81802459e..a458505e7 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -10,6 +10,7 @@ extern "C" #endif #include "../../libultraship/libultraship/luslog.h" +#include #if defined(INCLUDE_GAME_PRINTF) && !defined(NDEBUG) #define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__) @@ -453,7 +454,10 @@ u32 Actor_TextboxIsClosing(Actor* actor, GlobalContext* globalCtx); s8 func_8002F368(GlobalContext* globalCtx); void Actor_GetScreenPos(GlobalContext* globalCtx, Actor* actor, s16* x, s16* y); u32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx); -s32 GiveItemWithoutActor(GlobalContext* globalCtx, s32 getItemId); +// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename func_8002F434 and func_8002F554. +s32 GiveItemEntryWithoutActor(GlobalContext* globalCtx, GetItemEntry getItemEntry); +s32 GiveItemEntryFromActor(Actor* actor, GlobalContext* globalCtx, GetItemEntry getItemEntry, f32 xzRange, f32 yRange); +void GiveItemEntryFromActorWithFixedRange(Actor* actor, GlobalContext* globalCtx, GetItemEntry getItemEntry); s32 func_8002F434(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzRange, f32 yRange); void func_8002F554(Actor* actor, GlobalContext* globalCtx, s32 getItemId); void func_8002F580(Actor* actor, GlobalContext* globalCtx); @@ -1050,6 +1054,7 @@ void Interface_LoadItemIcon1(GlobalContext* globalCtx, u16 button); void Interface_LoadItemIcon2(GlobalContext* globalCtx, u16 button); void func_80084BF4(GlobalContext* globalCtx, u16 flag); u8 Item_Give(GlobalContext* globalCtx, u8 item); +u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry); u8 Item_CheckObtainability(u8 item); void Inventory_DeleteItem(u16 item, u16 invSlot); s32 Inventory_ReplaceItem(GlobalContext* globalCtx, u16 oldItem, u16 newItem); diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 3a409a705..65f6e93d9 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -244,50 +244,6 @@ typedef enum { /* 0x99 */ ITEM_STICK_UPGRADE_30, /* 0x9A */ ITEM_NUT_UPGRADE_30, /* 0x9B */ ITEM_NUT_UPGRADE_40, - /* 0x9C */ ITEM_BOTTLE_WITH_RED_POTION, - /* 0x9D */ ITEM_BOTTLE_WITH_GREEN_POTION, - /* 0x9E */ ITEM_BOTTLE_WITH_BLUE_POTION, - /* 0x9F */ ITEM_BOTTLE_WITH_FAIRY, - /* 0xA0 */ ITEM_BOTTLE_WITH_FISH, - /* 0xA1 */ ITEM_BOTTLE_WITH_BLUE_FIRE, - /* 0xA2 */ ITEM_BOTTLE_WITH_BUGS, - /* 0xA3 */ ITEM_BOTTLE_WITH_POE, - /* 0xA4 */ ITEM_BOTTLE_WITH_BIG_POE, - /* 0xA5 */ ITEM_GERUDO_FORTRESS_SMALL_KEY, - /* 0xA6 */ ITEM_FOREST_TEMPLE_SMALL_KEY, - /* 0xA7 */ ITEM_FIRE_TEMPLE_SMALL_KEY, - /* 0xA8 */ ITEM_WATER_TEMPLE_SMALL_KEY, - /* 0xA9 */ ITEM_SPIRIT_TEMPLE_SMALL_KEY, - /* 0xAA */ ITEM_SHADOW_TEMPLE_SMALL_KEY, - /* 0xAB */ ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY, - /* 0xAC */ ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY, - /* 0xAD */ ITEM_GANONS_CASTLE_SMALL_KEY, - /* 0xAE */ ITEM_FOREST_TEMPLE_BOSS_KEY, - /* 0xAF */ ITEM_FIRE_TEMPLE_BOSS_KEY, - /* 0xB0 */ ITEM_WATER_TEMPLE_BOSS_KEY, - /* 0xB1 */ ITEM_SPIRIT_TEMPLE_BOSS_KEY, - /* 0xB2 */ ITEM_SHADOW_TEMPLE_BOSS_KEY, - /* 0xB3 */ ITEM_GANONS_CASTLE_BOSS_KEY, - /* 0xB4 */ ITEM_DEKU_TREE_MAP, - /* 0xB5 */ ITEM_DODONGOS_CAVERN_MAP, - /* 0xB6 */ ITEM_JABU_JABUS_BELLY_MAP, - /* 0xB7 */ ITEM_FOREST_TEMPLE_MAP, - /* 0xB8 */ ITEM_FIRE_TEMPLE_MAP, - /* 0xB9 */ ITEM_WATER_TEMPLE_MAP, - /* 0xBA */ ITEM_SPIRIT_TEMPLE_MAP, - /* 0xBB */ ITEM_SHADOW_TEMPLE_MAP, - /* 0xBC */ ITEM_BOTTOM_OF_THE_WELL_MAP, - /* 0xBD */ ITEM_ICE_CAVERN_MAP, - /* 0xBE */ ITEM_DEKU_TREE_COMPASS, - /* 0xBF */ ITEM_DODONGOS_CAVERN_COMPASS, - /* 0xC0 */ ITEM_JABU_JABUS_BELLY_COMPASS, - /* 0xC1 */ ITEM_FOREST_TEMPLE_COMPASS, - /* 0xC2 */ ITEM_FIRE_TEMPLE_COMPASS, - /* 0xC3 */ ITEM_WATER_TEMPLE_COMPASS, - /* 0xC4 */ ITEM_SPIRIT_TEMPLE_COMPASS, - /* 0xC5 */ ITEM_SHADOW_TEMPLE_COMPASS, - /* 0xC6 */ ITEM_BOTTOM_OF_THE_WELL_COMPASS, - /* 0xC7 */ ITEM_ICE_CAVERN_COMPASS, /* 0xFC */ ITEM_LAST_USED = 0xFC, /* 0xFE */ ITEM_NONE_FE = 0xFE, /* 0xFF */ ITEM_NONE = 0xFF @@ -423,87 +379,8 @@ typedef enum { /* 0x7A */ GI_NUT_UPGRADE_40, /* 0x7B */ GI_BULLET_BAG_50, /* 0x7C */ GI_ICE_TRAP, // freezes link when opened from a chest - /* 0x7D */ GI_TEXT_0, // no model appears over Link, shows text id 0 (pocket egg) - - /* 0x7E */ GI_MEDALLION_LIGHT, - /* 0x7F */ GI_MEDALLION_FOREST, - /* 0x80 */ GI_MEDALLION_FIRE, - /* 0x81 */ GI_MEDALLION_WATER, - /* 0x82 */ GI_MEDALLION_SHADOW, - /* 0x83 */ GI_MEDALLION_SPIRIT, - - /* 0x84 */ GI_STONE_KOKIRI, - /* 0x85 */ GI_STONE_GORON, - /* 0x86 */ GI_STONE_ZORA, - - /* 0x87 */ GI_ZELDAS_LULLABY, - /* 0x88 */ GI_SUNS_SONG, - /* 0x89 */ GI_EPONAS_SONG, - /* 0x8A */ GI_SONG_OF_STORMS, - /* 0x8B */ GI_SONG_OF_TIME, - /* 0x8C */ GI_SARIAS_SONG, - - /* 0x8D */ GI_MINUET_OF_FOREST, - /* 0x8E */ GI_BOLERO_OF_FIRE, - /* 0x8F */ GI_SERENADE_OF_WATER, - /* 0x90 */ GI_NOCTURNE_OF_SHADOW, - /* 0x91 */ GI_REQUIEM_OF_SPIRIT, - /* 0x92 */ GI_PRELUDE_OF_LIGHT, - - /* 0x93 */ GI_SINGLE_MAGIC, - /* 0x94 */ GI_DOUBLE_MAGIC, - /* 0x95 */ GI_DOUBLE_DEFENSE, - - /* 0x96 */ GI_BOTTLE_WITH_RED_POTION, - /* 0x97 */ GI_BOTTLE_WITH_GREEN_POTION, - /* 0x98 */ GI_BOTTLE_WITH_BLUE_POTION, - /* 0x99 */ GI_BOTTLE_WITH_FAIRY, - /* 0x9A */ GI_BOTTLE_WITH_FISH, - /* 0x9B */ GI_BOTTLE_WITH_BLUE_FIRE, - /* 0x9C */ GI_BOTTLE_WITH_BUGS, - /* 0x9D */ GI_BOTTLE_WITH_POE, - /* 0x9E */ GI_BOTTLE_WITH_BIG_POE, - - /* 0x9F */ GI_GERUDO_FORTRESS_SMALL_KEY, - /* 0xA0 */ GI_FOREST_TEMPLE_SMALL_KEY, - /* 0xA1 */ GI_FIRE_TEMPLE_SMALL_KEY, - /* 0xA2 */ GI_WATER_TEMPLE_SMALL_KEY, - /* 0xA3 */ GI_SPIRIT_TEMPLE_SMALL_KEY, - /* 0xA4 */ GI_SHADOW_TEMPLE_SMALL_KEY, - /* 0xA5 */ GI_BOTTOM_OF_THE_WELL_SMALL_KEY, - /* 0xA6 */ GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, - /* 0xA7 */ GI_GANONS_CASTLE_SMALL_KEY, - - /* 0xA8 */ GI_FOREST_TEMPLE_BOSS_KEY, - /* 0xA9 */ GI_FIRE_TEMPLE_BOSS_KEY, - /* 0xAA */ GI_WATER_TEMPLE_BOSS_KEY, - /* 0xAB */ GI_SPIRIT_TEMPLE_BOSS_KEY, - /* 0xAC */ GI_SHADOW_TEMPLE_BOSS_KEY, - /* 0xAD */ GI_GANONS_CASTLE_BOSS_KEY, - - /* 0xAE */ GI_DEKU_TREE_MAP, - /* 0xAF */ GI_DODONGOS_CAVERN_MAP, - /* 0xB0 */ GI_JABU_JABUS_BELLY_MAP, - /* 0xB1 */ GI_FOREST_TEMPLE_MAP, - /* 0xB2 */ GI_FIRE_TEMPLE_MAP, - /* 0xB3 */ GI_WATER_TEMPLE_MAP, - /* 0xB4 */ GI_SPIRIT_TEMPLE_MAP, - /* 0xB5 */ GI_SHADOW_TEMPLE_MAP, - /* 0xB6 */ GI_BOTTOM_OF_THE_WELL_MAP, - /* 0xB7 */ GI_ICE_CAVERN_MAP, - - /* 0xB8 */ GI_DEKU_TREE_COMPASS, - /* 0xB9 */ GI_DODONGOS_CAVERN_COMPASS, - /* 0xBA */ GI_JABU_JABUS_BELLY_COMPASS, - /* 0xBB */ GI_FOREST_TEMPLE_COMPASS, - /* 0xBC */ GI_FIRE_TEMPLE_COMPASS, - /* 0xBD */ GI_WATER_TEMPLE_COMPASS, - /* 0xBE */ GI_SPIRIT_TEMPLE_COMPASS, - /* 0xBF */ GI_SHADOW_TEMPLE_COMPASS, - /* 0xC0 */ GI_BOTTOM_OF_THE_WELL_COMPASS, - /* 0xC1 */ GI_ICE_CAVERN_COMPASS, - - /* 0xAE */ GI_MAX + /* 0x7D */ GI_TEXT_0, // no model appears over Link, shows text id 0 (pocket egg) + /* 0x84 */ GI_MAX } GetItemID; typedef enum { diff --git a/soh/include/z64player.h b/soh/include/z64player.h index 33ae4c6d9..72d28e7c2 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -2,17 +2,10 @@ #define Z64PLAYER_H #include "z64actor.h" +#include "soh/Enhancements/item-tables/ItemTableTypes.h" struct Player; -typedef struct { - /* 0x00 */ u8 itemId; - /* 0x01 */ u8 field; // various bit-packed data - /* 0x02 */ s8 gi; // defines the draw id and chest opening animation - /* 0x03 */ u8 textId; - /* 0x04 */ u16 objectId; -} GetItemEntry; // size = 0x06 - extern GetItemEntry sGetItemTable[195]; typedef enum { @@ -374,6 +367,7 @@ typedef enum { FLAG_SCENE_TREASURE, FLAG_SCENE_CLEAR, FLAG_SCENE_COLLECTIBLE, + FLAG_EVENT_CHECK_INF, FLAG_COW_MILKED } FlagType; @@ -639,6 +633,7 @@ typedef struct Player { /* 0x0A89 */ bool pendingIceTrap; /* 0x0A95 */ PendingFlag pendingFlag; /* 0x0AA1 */ u8 boomerangQuickRecall; // Has the player pressed the boomerang button while it's in the air still? -} Player; // size = 0xAA2 + /* 0x0AA2 */ GetItemEntry getItemEntry; +} Player; // size = 0xAAA #endif diff --git a/soh/macosx/soh-macos.sh b/soh/macosx/soh-macos.sh index 6ce17f55d..790c649fd 100755 --- a/soh/macosx/soh-macos.sh +++ b/soh/macosx/soh-macos.sh @@ -1,8 +1,69 @@ -#!/bin/sh -BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/.*//'`" -RESOURCES="$BUNDLE/Contents/Resources" +#!/bin/bash -export DYLD_FRAMEWORK_PATH=$RESOURCES/Frameworks -export DYLD_LIBRARY_PATH=$RESOURCES/bin +SNAME="$(dirname $0)" +export DATA_SHARE="$HOME/Library/Application Support/com.shipofharkinian.soh" +export SNAME +export RESPATH="${SNAME%/MacOS*}/Resources" +export LIBPATH="${SNAME%/MacOS*}/Frameworks" +export DYLD_FALLBACK_LIBRARY_PATH="$LIBPATH" -exec "$RESOURCES/soh-macos" +while [ ! -e "$DATA_SHARE/oot.otr" ]; do + ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)" + export ASSETDIR + cp -r "$RESPATH/assets" "$ASSETDIR" + mkdir -p "$ASSETDIR"/tmp + mkdir -p "$ASSETDIR"/Extract/assets + DROPROM="$(osascript -ss - "$ASSETDIR" <<-EOF + set romFile to choose file of type {"b64","n64","v64","z64"} with prompt "Please select your ROM:" + set destinationFolder to POSIX file "$ASSETDIR" + tell application "Finder" + duplicate romFile to destinationFolder + end tell + EOF + )" + "$DROPROM" + for rom in "$ASSETDIR"/*.*64 + do + if [ ! -e "$rom" ]; then + echo "no ROM" + osascript -e 'display dialog "Select ROM to generate OTR" giving up after 5' + rm -r "$ASSETDIR" + exit + fi + done + cp "$ASSETDIR"/*.*64 "$ASSETDIR"/tmp/rom.z64 + cp -r "$ASSETDIR"/assets/game/ship_of_harkinian "$ASSETDIR"/Extract/assets/ + cd "$ASSETDIR" || return + ROMHASH="$(shasum "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')" + case "$ROMHASH" in + cee6bc3c2a634b41728f2af8da54d9bf8cc14099) + export ROM=GC_NMQ_D;; + 0227d7c0074f2d0ac935631990da8ec5914597b4) + export ROM=GC_NMQ_PAL_F;; + *) + WRONGHASH="$(osascript -ss - "$ROMHASH" <<-EOF + display dialog "Incompatible ROM hash $ROMHASH" \ + with title "Incompatible ROM hash" \ + with icon caution \ + giving up after 5 + EOF + )" + "$WRONGHASH" + rm -r "$ASSETDIR" + exit;; + esac + echo "$ROM" + + osascript -e 'display notification "Processing OTR..." with title "SOH: Generating OTR"' + assets/extractor/ZAPD.out ed -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR + if [ -e "$PWD"/oot.otr ]; then + osascript -e 'display notification "OTR Successfully Generated" with title "SOH: Generating OTR"' + if [ ! -e "$DATA_SHARE" ]; then mkdir "$DATA_SHARE"; fi + cp "$ASSETDIR"/oot.otr "$DATA_SHARE" + rm -r "$ASSETDIR" + fi + break +done + +"$RESPATH"/soh-macos +exit diff --git a/soh/soh/Enhancements/bootcommands.c b/soh/soh/Enhancements/bootcommands.c index c766049ae..fc6d043e2 100644 --- a/soh/soh/Enhancements/bootcommands.c +++ b/soh/soh/Enhancements/bootcommands.c @@ -25,6 +25,9 @@ void BootCommands_Init() CVar_RegisterS32("gDebugEnabled", 0); CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French CVar_RegisterS32("gHudColors", 1); //0 = N64 / 1 = NGC / 2 = Custom +#if defined(__SWITCH__) || defined(__WIIU__) + CVar_RegisterS32("gControlNav", 1); // always enable controller nav on switch/wii u +#endif } //void BootCommands_ParseBootArgs(char* str) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp index 8a42bef95..00c7153ea 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp @@ -1,5 +1,6 @@ #include "CustomMessageManager.h" #include +#include using namespace std::literals::string_literals; @@ -80,9 +81,8 @@ bool CustomMessageManager::InsertCustomMessage(std::string tableID, uint16_t tex return messageInsertResult.second; } - - -bool CustomMessageManager::CreateGetItemMessage(std::string tableID, GetItemID giid, ItemID iid, CustomMessageEntry messageEntry) { +bool CustomMessageManager::CreateGetItemMessage(std::string tableID, uint16_t giid, ItemID iid, + CustomMessageEntry messageEntry) { FormatCustomMessage(messageEntry.english, iid); FormatCustomMessage(messageEntry.german, iid); FormatCustomMessage(messageEntry.french, iid); diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 0681073b8..389457d00 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -89,7 +89,7 @@ class CustomMessageManager { with the provided giid (getItemID) as its key. This function also inserts the icon corresponding to the provided iid (itemID) at the beginning of each page of the textbox. */ - bool CreateGetItemMessage(std::string tableID, GetItemID giid, ItemID iid, CustomMessageEntry messages); + bool CreateGetItemMessage(std::string tableID, uint16_t giid, ItemID iid, CustomMessageEntry messages); /* Formats the provided Custom Message Entry and inserts it into the table with the provided tableID, diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 1859e83a5..39dceea1d 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -17,7 +17,7 @@ typedef enum { #ifdef __cplusplus typedef struct { - GetItemID giid; + u16 giid; ItemID iid; std::string english; std::string german; diff --git a/soh/soh/Enhancements/item-tables/ItemTableManager.cpp b/soh/soh/Enhancements/item-tables/ItemTableManager.cpp new file mode 100644 index 000000000..57f6464e3 --- /dev/null +++ b/soh/soh/Enhancements/item-tables/ItemTableManager.cpp @@ -0,0 +1,42 @@ +#include "ItemTableManager.h" +#include + +ItemTableManager::ItemTableManager() { +} + +ItemTableManager::~ItemTableManager() { + this->itemTables.clear(); +} + +bool ItemTableManager::AddItemTable(uint16_t tableID) { + ItemTable newItemTable; + return itemTables.emplace(tableID, newItemTable).second; +} + +bool ItemTableManager::AddItemEntry(uint16_t tableID, uint16_t getItemID, GetItemEntry getItemEntry) { + try { + ItemTable* itemTable = RetrieveItemTable(tableID); + return itemTable->emplace(getItemID, getItemEntry).second; + } catch (const std::out_of_range& oor) { return false; } +} + +GetItemEntry ItemTableManager::RetrieveItemEntry(uint16_t tableID, uint16_t itemID) { + try { + ItemTable* itemTable = RetrieveItemTable(tableID); + return itemTable->at(itemID); + } catch (std::out_of_range& oor) { return GET_ITEM_NONE; } +} + +bool ItemTableManager::ClearItemTable(uint16_t tableID) { + try { + ItemTable* itemTable = RetrieveItemTable(tableID); + itemTable->clear(); + return true; + } catch (const std::out_of_range& oor) { return false; } +} + +ItemTable* ItemTableManager::RetrieveItemTable(uint16_t tableID) { + try { + return &itemTables.at(tableID); + } catch (const std::out_of_range& oor) { throw(oor); } +} diff --git a/soh/soh/Enhancements/item-tables/ItemTableManager.h b/soh/soh/Enhancements/item-tables/ItemTableManager.h new file mode 100644 index 000000000..622782265 --- /dev/null +++ b/soh/soh/Enhancements/item-tables/ItemTableManager.h @@ -0,0 +1,23 @@ +#pragma once +#include "ItemTableTypes.h" +#include "z64item.h" + +#include + +typedef std::unordered_map ItemTable; + +class ItemTableManager { + public: + static ItemTableManager* Instance; + ItemTableManager(); + ~ItemTableManager(); + bool AddItemTable(uint16_t tableID); + bool AddItemEntry(uint16_t tableID, uint16_t getItemID, GetItemEntry getItemEntry); + GetItemEntry RetrieveItemEntry(uint16_t tableID, uint16_t itemID); + bool ClearItemTable(uint16_t tableID); + + private: + std::unordered_map itemTables; + + ItemTable* RetrieveItemTable(uint16_t tableID); +}; diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h new file mode 100644 index 000000000..7e5f1a9a3 --- /dev/null +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -0,0 +1,25 @@ +#pragma once +#ifdef __cplusplus +#include +#endif + +#define CHEST_ANIM_SHORT 0 +#define CHEST_ANIM_LONG 1 + +#define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, modIndex, getItemId) \ + { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, getItemId, drawId, true } + +#define GET_ITEM_NONE \ + { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, false } + +typedef struct { + /* 0x00 */ uint16_t itemId; + /* 0x01 */ uint16_t field; // various bit-packed data + /* 0x02 */ int16_t gi; // defines the draw id and chest opening animation + /* 0x03 */ uint16_t textId; + /* 0x04 */ uint16_t objectId; + /* 0x06 */ uint16_t modIndex; // 0 = Vanilla, 1 = Randomizer, future mods will increment up? + /* 0x08 */ int16_t getItemId; + /* 0x0A */ uint16_t gid; // Stores the GID value unmodified for future reference. + /* 0x0C */ uint16_t collectable; // determines whether the item can be collected on the overworld. Will be true in most cases. +} GetItemEntry; // size = 0x0F diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 2891bea1e..60c198ed4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -16,6 +16,8 @@ #include "Lib/ImGui/imgui_internal.h" #include #include +#include +#include #include "randomizer_check_objects.h" #include @@ -123,195 +125,6 @@ std::unordered_map getItemIdToItemId = { { GI_CLAIM_CHECK, ITEM_CLAIM_CHECK } }; -std::unordered_map itemIdToModel = { { GI_NONE, GID_MAXIMUM }, - { GI_BOMBS_5, GID_BOMB }, - { GI_NUTS_5, GID_NUTS }, - { GI_BOMBCHUS_10, GID_BOMBCHU }, - { GI_BOW, GID_BOW }, - { GI_SLINGSHOT, GID_SLINGSHOT }, - { GI_BOOMERANG, GID_BOOMERANG }, - { GI_STICKS_1, GID_STICK }, - { GI_HOOKSHOT, GID_HOOKSHOT }, - { GI_LONGSHOT, GID_LONGSHOT }, - { GI_LENS, GID_LENS }, - { GI_LETTER_ZELDA, GID_LETTER_ZELDA }, - { GI_OCARINA_OOT, GID_OCARINA_TIME }, - { GI_HAMMER, GID_HAMMER }, - { GI_COJIRO, GID_COJIRO }, - { GI_LETTER_RUTO, GID_LETTER_RUTO }, - { GI_LETTER_RUTO, GID_LETTER_RUTO }, - { GI_BOTTLE, GID_BOTTLE }, - { GI_POTION_RED, GID_POTION_RED }, - { GI_POTION_GREEN, GID_POTION_GREEN }, - { GI_POTION_BLUE, GID_POTION_BLUE }, - { GI_FAIRY, GID_FAIRY }, - { GI_MILK_BOTTLE, GID_MILK }, - { GI_LETTER_RUTO, GID_LETTER_RUTO }, - { GI_BEAN, GID_BEAN }, - { GI_MASK_SKULL, GID_MASK_SKULL }, - { GI_MASK_SPOOKY, GID_MASK_SPOOKY }, - { GI_CHICKEN, GID_CHICKEN }, - { GI_MASK_KEATON, GID_MASK_KEATON }, - { GI_MASK_BUNNY, GID_MASK_BUNNY }, - { GI_MASK_TRUTH, GID_MASK_TRUTH }, - { GI_POCKET_EGG, GID_EGG }, - { GI_POCKET_CUCCO, GID_CHICKEN }, - { GI_ODD_MUSHROOM, GID_ODD_MUSHROOM }, - { GI_ODD_POTION, GID_ODD_POTION }, - { GI_SAW, GID_SAW }, - { GI_SWORD_BROKEN, GID_SWORD_BROKEN }, - { GI_PRESCRIPTION, GID_PRESCRIPTION }, - { GI_FROG, GID_FROG }, - { GI_EYEDROPS, GID_EYEDROPS }, - { GI_CLAIM_CHECK, GID_CLAIM_CHECK }, - { GI_SWORD_KOKIRI, GID_SWORD_KOKIRI }, - { GI_SWORD_KNIFE, GID_SWORD_BGS }, - { GI_SHIELD_DEKU, GID_SHIELD_DEKU }, - { GI_SHIELD_HYLIAN, GID_SHIELD_HYLIAN }, - { GI_SHIELD_MIRROR, GID_SHIELD_MIRROR }, - { GI_TUNIC_GORON, GID_TUNIC_GORON }, - { GI_TUNIC_ZORA, GID_TUNIC_ZORA }, - { GI_BOOTS_IRON, GID_BOOTS_IRON }, - { GI_BOOTS_HOVER, GID_BOOTS_HOVER }, - { GI_QUIVER_40, GID_QUIVER_40 }, - { GI_QUIVER_50, GID_QUIVER_50 }, - { GI_BOMB_BAG_20, GID_BOMB_BAG_20 }, - { GI_BOMB_BAG_30, GID_BOMB_BAG_30 }, - { GI_BOMB_BAG_40, GID_BOMB_BAG_40 }, - { GI_GAUNTLETS_SILVER, GID_GAUNTLETS_SILVER }, - { GI_GAUNTLETS_GOLD, GID_GAUNTLETS_GOLD }, - { GI_SCALE_SILVER, GID_SCALE_SILVER }, - { GI_SCALE_GOLD, GID_SCALE_GOLDEN }, - { GI_STONE_OF_AGONY, GID_STONE_OF_AGONY }, - { GI_GERUDO_CARD, GID_GERUDO_CARD }, - { GI_OCARINA_FAIRY, GID_OCARINA_FAIRY }, - { GI_SEEDS_5, GID_SEEDS }, - { GI_HEART_CONTAINER, GID_HEART_CONTAINER }, - { GI_HEART_PIECE, GID_HEART_PIECE }, - { GI_KEY_BOSS, GID_KEY_BOSS }, - { GI_COMPASS, GID_COMPASS }, - { GI_MAP, GID_DUNGEON_MAP }, - { GI_KEY_SMALL, GID_KEY_SMALL }, - { GI_MAGIC_SMALL, GID_MAGIC_SMALL }, - { GI_MAGIC_LARGE, GID_MAGIC_LARGE }, - { GI_WALLET_ADULT, GID_WALLET_ADULT }, - { GI_WALLET_GIANT, GID_WALLET_GIANT }, - { GI_WEIRD_EGG, GID_EGG }, - { GI_HEART, GID_HEART }, - { GI_ARROWS_SMALL, GID_ARROWS_SMALL }, - { GI_ARROWS_MEDIUM, GID_ARROWS_MEDIUM }, - { GI_ARROWS_LARGE, GID_ARROWS_LARGE }, - { GI_RUPEE_GREEN, GID_RUPEE_GREEN }, - { GI_RUPEE_BLUE, GID_RUPEE_BLUE }, - { GI_RUPEE_RED, GID_RUPEE_RED }, - { GI_HEART_CONTAINER_2, GI_HEART_CONTAINER_2 }, - { GI_MILK, GID_MILK }, - { GI_MASK_GORON, GID_MASK_GORON }, - { GI_MASK_ZORA, GID_MASK_ZORA }, - { GI_MASK_GERUDO, GID_MASK_GERUDO }, - { GI_BRACELET, GID_BRACELET }, - { GI_RUPEE_PURPLE, GID_RUPEE_PURPLE }, - { GI_RUPEE_GOLD, GID_RUPEE_GOLD }, - { GI_SWORD_BGS, GID_SWORD_BGS }, - { GI_ARROW_FIRE, GID_ARROW_FIRE }, - { GI_ARROW_ICE, GID_ARROW_ICE }, - { GI_ARROW_LIGHT, GID_ARROW_LIGHT }, - { GI_SKULL_TOKEN, GID_SKULL_TOKEN }, - { GI_DINS_FIRE, GID_DINS_FIRE }, - { GI_FARORES_WIND, GID_FARORES_WIND }, - { GI_NAYRUS_LOVE, GID_NAYRUS_LOVE }, - { GI_BULLET_BAG_30, GID_BULLET_BAG }, - { GI_BULLET_BAG_40, GID_BULLET_BAG }, - { GI_STICKS_5, GID_STICK }, - { GI_STICKS_10, GID_STICK }, - { GI_NUTS_5_2, GID_NUTS }, - { GI_NUTS_10, GID_NUTS }, - { GI_BOMBS_1, GID_BOMB }, - { GI_BOMBS_10, GID_BOMB }, - { GI_BOMBS_20, GID_BOMB }, - { GI_BOMBS_30, GID_BOMB }, - { GI_SEEDS_30, GID_SEEDS }, - { GI_BOMBCHUS_5, GID_BOMBCHU }, - { GI_BOMBCHUS_20, GID_BOMBCHU }, - { GI_FISH, GID_FISH }, - { GI_BUGS, GID_BUG }, - { GI_BLUE_FIRE, GID_BLUE_FIRE }, - { GI_POE, GID_POE }, - { GI_BIG_POE, GID_BIG_POE }, - { GI_DOOR_KEY, GID_KEY_SMALL }, - { GI_RUPEE_GREEN_LOSE, GID_RUPEE_GREEN }, - { GI_RUPEE_BLUE_LOSE, GID_RUPEE_BLUE }, - { GI_RUPEE_RED_LOSE, GID_RUPEE_RED }, - { GI_RUPEE_PURPLE_LOSE, GID_RUPEE_PURPLE }, - { GI_HEART_PIECE_WIN, GID_HEART_PIECE }, - { GI_STICK_UPGRADE_20, GID_STICK }, - { GI_STICK_UPGRADE_30, GID_STICK }, - { GI_NUT_UPGRADE_30, GID_NUTS }, - { GI_NUT_UPGRADE_40, GID_NUTS }, - { GI_BULLET_BAG_50, GID_BULLET_BAG_50 }, - { GI_ZELDAS_LULLABY, GID_SONG_ZELDA }, - { GI_EPONAS_SONG, GID_SONG_EPONA }, - { GI_SARIAS_SONG, GID_SONG_SARIA }, - { GI_SUNS_SONG, GID_SONG_SUN }, - { GI_SONG_OF_TIME, GID_SONG_TIME }, - { GI_SONG_OF_STORMS, GID_SONG_STORM }, - { GI_MINUET_OF_FOREST, GID_SONG_MINUET }, - { GI_BOLERO_OF_FIRE, GID_SONG_BOLERO }, - { GI_SERENADE_OF_WATER, GID_SONG_SERENADE }, - { GI_REQUIEM_OF_SPIRIT, GID_SONG_REQUIEM }, - { GI_NOCTURNE_OF_SHADOW, GID_SONG_NOCTURNE }, - { GI_PRELUDE_OF_LIGHT, GID_SONG_PRELUDE }, - { GI_DOUBLE_DEFENSE, GID_HEART_CONTAINER }, - { GI_STONE_KOKIRI, GID_KOKIRI_EMERALD }, - { GI_STONE_GORON, GID_GORON_RUBY }, - { GI_STONE_ZORA, GID_ZORA_SAPPHIRE }, - { GI_MEDALLION_FOREST, GID_MEDALLION_FOREST }, - { GI_MEDALLION_FIRE, GID_MEDALLION_FIRE }, - { GI_MEDALLION_WATER, GID_MEDALLION_WATER }, - { GI_MEDALLION_SPIRIT, GID_MEDALLION_SPIRIT }, - { GI_MEDALLION_SHADOW, GID_MEDALLION_SHADOW }, - { GI_MEDALLION_LIGHT, GID_MEDALLION_LIGHT }, - { GI_SINGLE_MAGIC, GID_MAGIC_SMALL }, - { GI_DOUBLE_MAGIC, GID_MAGIC_LARGE }, - { GI_GERUDO_FORTRESS_SMALL_KEY, GID_KEY_SMALL }, - { GI_FOREST_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, - { GI_FIRE_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, - { GI_WATER_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, - { GI_SPIRIT_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, - { GI_SHADOW_TEMPLE_SMALL_KEY, GID_KEY_SMALL }, - { GI_BOTTOM_OF_THE_WELL_SMALL_KEY, GID_KEY_SMALL }, - { GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, GID_KEY_SMALL }, - { GI_GANONS_CASTLE_SMALL_KEY, GID_KEY_SMALL }, - { GI_FOREST_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_FIRE_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_WATER_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_SPIRIT_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_SHADOW_TEMPLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_GANONS_CASTLE_BOSS_KEY, GID_KEY_BOSS }, - { GI_DEKU_TREE_MAP, GID_DUNGEON_MAP }, - { GI_DODONGOS_CAVERN_MAP, GID_DUNGEON_MAP }, - { GI_JABU_JABUS_BELLY_MAP, GID_DUNGEON_MAP }, - { GI_FOREST_TEMPLE_MAP, GID_DUNGEON_MAP }, - { GI_FIRE_TEMPLE_MAP, GID_DUNGEON_MAP }, - { GI_WATER_TEMPLE_MAP, GID_DUNGEON_MAP }, - { GI_SPIRIT_TEMPLE_MAP, GID_DUNGEON_MAP }, - { GI_SHADOW_TEMPLE_MAP, GID_DUNGEON_MAP }, - { GI_BOTTOM_OF_THE_WELL_MAP, GID_DUNGEON_MAP }, - { GI_ICE_CAVERN_MAP, GID_DUNGEON_MAP }, - { GI_DEKU_TREE_COMPASS, GID_COMPASS }, - { GI_DODONGOS_CAVERN_COMPASS, GID_COMPASS }, - { GI_JABU_JABUS_BELLY_COMPASS, GID_COMPASS }, - { GI_FOREST_TEMPLE_COMPASS, GID_COMPASS }, - { GI_FIRE_TEMPLE_COMPASS, GID_COMPASS }, - { GI_WATER_TEMPLE_COMPASS, GID_COMPASS }, - { GI_SPIRIT_TEMPLE_COMPASS, GID_COMPASS }, - { GI_SHADOW_TEMPLE_COMPASS, GID_COMPASS }, - { GI_BOTTOM_OF_THE_WELL_COMPASS, GID_COMPASS }, - { GI_ICE_CAVERN_COMPASS, GID_COMPASS }, - { GI_ICE_TRAP, GID_RUPEE_GOLD }, - { GI_ICE_TRAP, GID_MAXIMUM }, - { GI_TEXT_0, GID_MAXIMUM } }; - std::unordered_map SpoilerfileGetNameToEnum = { { "No Item", RG_NONE }, { "Rien", RG_NONE }, @@ -736,18 +549,6 @@ std::unordered_map SpoilerfileSettingNameToEn { "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES }, }; -s32 Randomizer::GetItemIDFromGetItemID(s32 getItemId) { - if (getItemIdToItemId.count(getItemId) == 0) { - return -1; - } - - return getItemIdToItemId[getItemId]; -} - -s16 Randomizer::GetItemModelFromId(s16 itemId) { - return itemIdToModel[itemId]; -} - std::string sanitize(std::string stringValue) { // Add backslashes. for (auto i = stringValue.begin();;) { @@ -1301,16 +1102,16 @@ void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent } } -GetItemID Randomizer::GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) { - GetItemID itemId = GetItemFromActor(actorId, actorParams, sceneNum, ogId); +s16 Randomizer::GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) { + s16 itemId = GetItemFromActor(actorId, actorParams, sceneNum, ogId); return itemId; } -GetItemID Randomizer::GetItemFromActor(s16 actorId, s16 actorParams, s16 sceneNum, GetItemID ogItemId) { +s16 Randomizer::GetItemFromActor(s16 actorId, s16 actorParams, s16 sceneNum, GetItemID ogItemId) { return GetItemFromGet(this->itemLocations[GetCheckFromActor(sceneNum, actorId, actorParams)], ogItemId); } -GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) { +s16 Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) { switch (randoGet) { case RG_NONE: return ogItemId; @@ -1364,6 +1165,9 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) return INV_CONTENT(ITEM_ARROW_ICE) == ITEM_NONE ? GI_ARROW_ICE : GI_RUPEE_BLUE; case RG_LIGHT_ARROWS: return INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_NONE ? GI_ARROW_LIGHT : GI_RUPEE_BLUE; + + case RG_DOUBLE_DEFENSE: + return !gSaveContext.doubleDefense ? (GetItemID)RG_DOUBLE_DEFENSE : GI_RUPEE_BLUE; case RG_GERUDO_MEMBERSHIP_CARD: return GI_GERUDO_CARD; @@ -1373,14 +1177,13 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) case RG_MAGIC_BEAN_PACK: return GI_BEAN; //todo make it 10 of them - case RG_DOUBLE_DEFENSE: - return !gSaveContext.doubleDefense ? GI_DOUBLE_DEFENSE : GI_RUPEE_BLUE; - case RG_WEIRD_EGG: return GI_WEIRD_EGG; case RG_ZELDAS_LETTER: return GI_LETTER_ZELDA; + case RG_RUTOS_LETTER: + return GI_LETTER_RUTO; case RG_POCKET_EGG: return GI_POCKET_EGG; @@ -1503,9 +1306,9 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) case RG_PROGRESSIVE_MAGIC_METER: switch (gSaveContext.magicLevel) { case 0: - return GI_SINGLE_MAGIC; + return (GetItemID)RG_MAGIC_SINGLE; case 1: - return GI_DOUBLE_MAGIC; + return (GetItemID)RG_MAGIC_DOUBLE; } return GI_RUPEE_BLUE; @@ -1525,126 +1328,6 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) return GI_BOTTLE; case RG_BOTTLE_WITH_MILK: return GI_MILK_BOTTLE; - case RG_BOTTLE_WITH_RED_POTION: - return GI_BOTTLE_WITH_RED_POTION; - case RG_BOTTLE_WITH_GREEN_POTION: - return GI_BOTTLE_WITH_GREEN_POTION; - case RG_BOTTLE_WITH_BLUE_POTION: - return GI_BOTTLE_WITH_BLUE_POTION; - case RG_BOTTLE_WITH_FAIRY: - return GI_BOTTLE_WITH_FAIRY; - case RG_BOTTLE_WITH_FISH: - return GI_BOTTLE_WITH_FISH; - case RG_BOTTLE_WITH_BLUE_FIRE: - return GI_BOTTLE_WITH_BLUE_FIRE; - case RG_BOTTLE_WITH_BUGS: - return GI_BOTTLE_WITH_BUGS; - case RG_BOTTLE_WITH_POE: - return GI_BOTTLE_WITH_POE; - case RG_RUTOS_LETTER: - return GI_LETTER_RUTO; - case RG_BOTTLE_WITH_BIG_POE: - return GI_BOTTLE_WITH_BIG_POE; - - case RG_ZELDAS_LULLABY: - return GI_ZELDAS_LULLABY; - case RG_EPONAS_SONG: - return GI_EPONAS_SONG; - case RG_SARIAS_SONG: - return GI_SARIAS_SONG; - case RG_SUNS_SONG: - return GI_SUNS_SONG; - case RG_SONG_OF_TIME: - return GI_SONG_OF_TIME; - case RG_SONG_OF_STORMS: - return GI_SONG_OF_STORMS; - - case RG_MINUET_OF_FOREST: - return GI_MINUET_OF_FOREST; - case RG_BOLERO_OF_FIRE: - return GI_BOLERO_OF_FIRE; - case RG_SERENADE_OF_WATER: - return GI_SERENADE_OF_WATER; - case RG_REQUIEM_OF_SPIRIT: - return GI_REQUIEM_OF_SPIRIT; - case RG_NOCTURNE_OF_SHADOW: - return GI_NOCTURNE_OF_SHADOW; - case RG_PRELUDE_OF_LIGHT: - return GI_PRELUDE_OF_LIGHT; - - case RG_DEKU_TREE_MAP: - return GI_DEKU_TREE_MAP; - case RG_DODONGOS_CAVERN_MAP: - return GI_DODONGOS_CAVERN_MAP; - case RG_JABU_JABUS_BELLY_MAP: - return GI_JABU_JABUS_BELLY_MAP; - case RG_FOREST_TEMPLE_MAP: - return GI_FOREST_TEMPLE_MAP; - case RG_FIRE_TEMPLE_MAP: - return GI_FIRE_TEMPLE_MAP; - case RG_WATER_TEMPLE_MAP: - return GI_WATER_TEMPLE_MAP; - case RG_SPIRIT_TEMPLE_MAP: - return GI_SPIRIT_TEMPLE_MAP; - case RG_SHADOW_TEMPLE_MAP: - return GI_SHADOW_TEMPLE_MAP; - case RG_BOTTOM_OF_THE_WELL_MAP: - return GI_BOTTOM_OF_THE_WELL_MAP; - case RG_ICE_CAVERN_MAP: - return GI_ICE_CAVERN_MAP; - - case RG_DEKU_TREE_COMPASS: - return GI_DEKU_TREE_COMPASS; - case RG_DODONGOS_CAVERN_COMPASS: - return GI_DODONGOS_CAVERN_COMPASS; - case RG_JABU_JABUS_BELLY_COMPASS: - return GI_JABU_JABUS_BELLY_COMPASS; - case RG_FOREST_TEMPLE_COMPASS: - return GI_FOREST_TEMPLE_COMPASS; - case RG_FIRE_TEMPLE_COMPASS: - return GI_FIRE_TEMPLE_COMPASS; - case RG_WATER_TEMPLE_COMPASS: - return GI_WATER_TEMPLE_COMPASS; - case RG_SPIRIT_TEMPLE_COMPASS: - return GI_SPIRIT_TEMPLE_COMPASS; - case RG_SHADOW_TEMPLE_COMPASS: - return GI_SHADOW_TEMPLE_COMPASS; - case RG_BOTTOM_OF_THE_WELL_COMPASS: - return GI_BOTTOM_OF_THE_WELL_COMPASS; - case RG_ICE_CAVERN_COMPASS: - return GI_ICE_CAVERN_COMPASS; - - case RG_FOREST_TEMPLE_BOSS_KEY: - return GI_FOREST_TEMPLE_BOSS_KEY; - case RG_FIRE_TEMPLE_BOSS_KEY: - return GI_FIRE_TEMPLE_BOSS_KEY; - case RG_WATER_TEMPLE_BOSS_KEY: - return GI_WATER_TEMPLE_BOSS_KEY; - case RG_SPIRIT_TEMPLE_BOSS_KEY: - return GI_SPIRIT_TEMPLE_BOSS_KEY; - case RG_SHADOW_TEMPLE_BOSS_KEY: - return GI_SHADOW_TEMPLE_BOSS_KEY; - case RG_GANONS_CASTLE_BOSS_KEY: - return GI_GANONS_CASTLE_BOSS_KEY; - - case RG_FOREST_TEMPLE_SMALL_KEY: - return GI_FOREST_TEMPLE_SMALL_KEY; - case RG_FIRE_TEMPLE_SMALL_KEY: - return GI_FIRE_TEMPLE_SMALL_KEY; - case RG_WATER_TEMPLE_SMALL_KEY: - return GI_WATER_TEMPLE_SMALL_KEY; - case RG_SPIRIT_TEMPLE_SMALL_KEY: - return GI_SPIRIT_TEMPLE_SMALL_KEY; - case RG_SHADOW_TEMPLE_SMALL_KEY: - return GI_SHADOW_TEMPLE_SMALL_KEY; - case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: - return GI_BOTTOM_OF_THE_WELL_SMALL_KEY; - case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - return GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY; - case RG_GERUDO_FORTRESS_SMALL_KEY: - return GI_GERUDO_FORTRESS_SMALL_KEY; - case RG_GANONS_CASTLE_SMALL_KEY: - return GI_GANONS_CASTLE_SMALL_KEY; // todo test this with keys in own dungeon case RG_TREASURE_GAME_SMALL_KEY: @@ -1662,26 +1345,6 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) case RG_GANONS_CASTLE_KEY_RING: return GI_RUPEE_BLUE; - case RG_KOKIRI_EMERALD: - return GI_STONE_KOKIRI; - case RG_GORON_RUBY: - return GI_STONE_GORON; - case RG_ZORA_SAPPHIRE: - return GI_STONE_ZORA; - - case RG_FOREST_MEDALLION: - return GI_MEDALLION_FOREST; - case RG_FIRE_MEDALLION: - return GI_MEDALLION_FIRE; - case RG_WATER_MEDALLION: - return GI_MEDALLION_WATER; - case RG_SPIRIT_MEDALLION: - return GI_MEDALLION_SPIRIT; - case RG_SHADOW_MEDALLION: - return GI_MEDALLION_SHADOW; - case RG_LIGHT_MEDALLION: - return GI_MEDALLION_LIGHT; - case RG_RECOVERY_HEART: return GI_HEART; @@ -1701,10 +1364,6 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) case RG_HEART_CONTAINER: // todo figure out what GI_HEART_CONTAINER_2 is return GI_HEART_CONTAINER; - - case RG_ICE_TRAP: - return GI_ICE_TRAP; - case RG_MILK: return GI_MILK; //todo logic around needing a bottle? @@ -1760,8 +1419,134 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) return GI_RUPEE_BLUE; //todo default: + if (!IsItemVanilla(randoGet)) { + return randoGet; + } return ogItemId; + } } + +bool Randomizer::IsItemVanilla(RandomizerGet randoGet) { + switch (randoGet) { + case RG_NONE: + case RG_KOKIRI_SWORD: + case RG_GIANTS_KNIFE: + case RG_BIGGORON_SWORD: + case RG_DEKU_SHIELD: + case RG_HYLIAN_SHIELD: + case RG_MIRROR_SHIELD: + case RG_GORON_TUNIC: + case RG_ZORA_TUNIC: + case RG_IRON_BOOTS: + case RG_HOVER_BOOTS: + case RG_BOOMERANG: + case RG_LENS_OF_TRUTH: + case RG_MEGATON_HAMMER: + case RG_STONE_OF_AGONY: + case RG_DINS_FIRE: + case RG_FARORES_WIND: + case RG_NAYRUS_LOVE: + case RG_FIRE_ARROWS: + case RG_ICE_ARROWS: + case RG_LIGHT_ARROWS: + case RG_GERUDO_MEMBERSHIP_CARD: + case RG_MAGIC_BEAN: + case RG_WEIRD_EGG: + case RG_ZELDAS_LETTER: + case RG_RUTOS_LETTER: + case RG_POCKET_EGG: + case RG_COJIRO: + case RG_ODD_MUSHROOM: + case RG_ODD_POTION: + case RG_POACHERS_SAW: + case RG_BROKEN_SWORD: + case RG_PRESCRIPTION: + case RG_EYEBALL_FROG: + case RG_EYEDROPS: + case RG_CLAIM_CHECK: + case RG_GOLD_SKULLTULA_TOKEN: + case RG_PROGRESSIVE_HOOKSHOT: + case RG_PROGRESSIVE_STRENGTH: + case RG_PROGRESSIVE_BOMB_BAG: + case RG_PROGRESSIVE_BOW: + case RG_PROGRESSIVE_SLINGSHOT: + case RG_PROGRESSIVE_WALLET: + case RG_PROGRESSIVE_SCALE: + case RG_PROGRESSIVE_NUT_UPGRADE: + case RG_PROGRESSIVE_STICK_UPGRADE: + case RG_PROGRESSIVE_BOMBCHUS: + case RG_PROGRESSIVE_OCARINA: + case RG_PROGRESSIVE_GORONSWORD: + case RG_EMPTY_BOTTLE: + case RG_BOTTLE_WITH_MILK: + case RG_RECOVERY_HEART: + case RG_GREEN_RUPEE: + case RG_BLUE_RUPEE: + case RG_RED_RUPEE: + case RG_PURPLE_RUPEE: + case RG_HUGE_RUPEE: + case RG_PIECE_OF_HEART: + case RG_HEART_CONTAINER: + case RG_MILK: + case RG_BOMBS_5: + case RG_BOMBS_10: + case RG_BOMBS_20: + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + case RG_BOMBCHU_DROP: + case RG_ARROWS_5: + case RG_ARROWS_10: + case RG_ARROWS_30: + case RG_DEKU_NUTS_5: + case RG_DEKU_NUTS_10: + case RG_DEKU_SEEDS_30: + case RG_DEKU_STICK_1: + case RG_RED_POTION_REFILL: + case RG_GREEN_POTION_REFILL: + case RG_BLUE_POTION_REFILL: + case RG_TREASURE_GAME_HEART: + case RG_TREASURE_GAME_GREEN_RUPEE: + case RG_BUY_DEKU_NUT_5: + case RG_BUY_ARROWS_30: + case RG_BUY_ARROWS_50: + case RG_BUY_BOMBS_525: + case RG_BUY_DEKU_NUT_10: + case RG_BUY_DEKU_STICK_1: + case RG_BUY_BOMBS_10: + case RG_BUY_FISH: + case RG_BUY_RED_POTION_30: + case RG_BUY_GREEN_POTION: + case RG_BUY_BLUE_POTION: + case RG_BUY_HYLIAN_SHIELD: + case RG_BUY_DEKU_SHIELD: + case RG_BUY_GORON_TUNIC: + case RG_BUY_ZORA_TUNIC: + case RG_BUY_HEART: + case RG_BUY_BOMBCHU_10: + case RG_BUY_BOMBCHU_20: + case RG_BUY_BOMBCHU_5: + case RG_BUY_DEKU_SEEDS_30: + case RG_SOLD_OUT: + case RG_BUY_BLUE_FIRE: + case RG_BUY_BOTTLE_BUG: + case RG_BUY_POE: + case RG_BUY_FAIRYS_SPIRIT: + case RG_BUY_ARROWS_10: + case RG_BUY_BOMBS_20: + case RG_BUY_BOMBS_30: + case RG_BUY_BOMBS_535: + case RG_BUY_RED_POTION_40: + case RG_BUY_RED_POTION_50: + return true; + default: + return false; + } +} + +bool Randomizer::CheckContainsVanillaItem(RandomizerCheck randoCheck) { + RandomizerGet randoGet = this->itemLocations[randoCheck]; + return IsItemVanilla(randoGet); } std::string Randomizer::GetAdultAltarText() const { @@ -1784,7 +1569,7 @@ u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return this->randoSettings[randoSettingKey]; } -GetItemID Randomizer::GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { +s16 Randomizer::GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { return GetItemFromGet(this->itemLocations[randomizerCheck], ogId); } @@ -2877,9 +2662,9 @@ void DrawRandoEditor(bool& open) { return; } -// Randomizer settings + // Randomizer settings // Logic Settings - const char* randoLogicRules[2] = { "Glitchless", "No logic"}; + const char* randoLogicRules[2] = { "Glitchless", "No logic" }; // Open Settings const char* randoForest[3] = { "Closed", "Closed Deku", "Open" }; @@ -2887,7 +2672,8 @@ void DrawRandoEditor(bool& open) { const char* randoDoorOfTime[3] = { "Closed", "Song only", "Open" }; const char* randoZorasFountain[3] = { "Closed", "Closed as child", "Open" }; const char* randoGerudoFortress[3] = { "Normal", "Fast", "Open" }; - const char* randoRainbowBridge[7] = { "Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens" }; + const char* randoRainbowBridge[7] = { "Vanilla", "Always open", "Stones", "Medallions", + "Dungeon rewards", "Dungeons", "Tokens" }; const char* randoGanonsTrial[2] = { "Off", "On" }; // World Settings @@ -2920,19 +2706,23 @@ void DrawRandoEditor(bool& open) { const char* randoShuffleAdultTrade[2] = { "Off", "On" }; // Shuffle Dungeon Items Settings - const char* randoShuffleMapsAndCompasses[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; - const char* randoShuffleSmallKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; + const char* randoShuffleMapsAndCompasses[6] = { "Start With", "Vanilla", "Own Dungeon", + "Any Dungeon", "Overworld", "Anywhere" }; + const char* randoShuffleSmallKeys[6] = { "Start With", "Vanilla", "Own Dungeon", + "Any Dungeon", "Overworld", "Anywhere" }; const char* randoShuffleGerudoFortressKeys[4] = { "Vanilla", "Any Dungeon", "Overworld", "Anywhere" }; - const char* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere" }; - const char* randoShuffleGanonsBossKey[6] = { "Vanilla", "Own dungeon", "Start with", "Any Dungeon", "Overworld", "Anywhere" }; + const char* randoShuffleBossKeys[6] = { "Start With", "Vanilla", "Own Dungeon", + "Any Dungeon", "Overworld", "Anywhere" }; + const char* randoShuffleGanonsBossKey[6] = { "Vanilla", "Own dungeon", "Start with", + "Any Dungeon", "Overworld", "Anywhere" }; // Timesaver Settings const char* randoSkipSongReplays[3] = { "Don't skip", "Skip (no SFX)", "Skip (Keep SFX)" }; // Misc Settings - const char* randoGossipStoneHints[4] = {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}; + const char* randoGossipStoneHints[4] = { "No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony" }; const char* randoHintClarity[3] = { "Obscure", "Ambiguous", "Clear" }; - const char* randoHintDistribution[4] = {"Useless", "Balanced", "Strong", "Very Strong"}; + const char* randoHintDistribution[4] = { "Useless", "Balanced", "Strong", "Very Strong" }; const char* randoDamageMultiplier[7] = { "x1", "x2", "x4", "x8", "x16", "OHKO", "x1/2" }; const char* randoStartingTime[2] = { "Day", "Night" }; const char* randoChestAnimations[2] = { "Always Fast", "Match contents" }; @@ -2942,7 +2732,7 @@ void DrawRandoEditor(bool& open) { // Item Pool Settings const char* randoItemPool[4] = { "Plentiful", "Balanced", "Scarce", "Minimal" }; - const char* randoIceTraps[5] = {"Off", "Normal", "Extra", "Mayhem", "Onslaught"}; + const char* randoIceTraps[5] = { "Off", "Normal", "Extra", "Mayhem", "Onslaught" }; // SFX Settings const char* randoSFXBackgroundMusic[3] = { "Normal", "No Music", "Random" }; @@ -3089,489 +2879,276 @@ void DrawRandoEditor(bool& open) { "Timer", "Zelda Gasp (Adult)" }; - ImGui::SetNextWindowSize(ImVec2(830, 600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Randomizer Editor", &open, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } + ImGui::SetNextWindowSize(ImVec2(830, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Randomizer Editor", &open, ImGuiWindowFlags_NoFocusOnAppearing)) { + ImGui::End(); + return; + } - bool disableEditingRandoSettings = CVar_GetS32("gRandoGenerating", 0) || CVar_GetS32("gOnFileSelectNameEntry", 0); - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, disableEditingRandoSettings); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, - ImGui::GetStyle().Alpha * (disableEditingRandoSettings ? 0.5f : 1.0f)); - SohImGui::EnhancementCheckbox("Enable Randomizer", "gRandomizer"); + bool disableEditingRandoSettings = CVar_GetS32("gRandoGenerating", 0) || CVar_GetS32("gOnFileSelectNameEntry", 0); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, disableEditingRandoSettings); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * (disableEditingRandoSettings ? 0.5f : 1.0f)); + SohImGui::EnhancementCheckbox("Enable Randomizer", "gRandomizer"); - if (CVar_GetS32("gRandomizer", 0) == 1) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - if (ImGui::Button("Generate Seed")) { - if (CVar_GetS32("gRandoGenerating", 0) == 0) { - randoThread = std::thread(&GenerateRandomizerImgui); - } + if (CVar_GetS32("gRandomizer", 0) == 1) { + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + if (ImGui::Button("Generate Seed")) { + if (CVar_GetS32("gRandoGenerating", 0) == 0) { + randoThread = std::thread(&GenerateRandomizerImgui); } - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - std::string spoilerfilepath = CVar_GetString("gSpoilerLog", ""); - ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str()); - - // RANDOTODO settings presets - // std::string presetfilepath = CVar_GetString("gLoadedPreset", ""); - // ImGui::Text("Settings File: %s", presetfilepath.c_str()); } - PaddedSeparator(); + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + std::string spoilerfilepath = CVar_GetString("gSpoilerLog", ""); + ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str()); - ImGuiWindow* window = ImGui::GetCurrentWindow(); - static ImVec2 cellPadding(8.0f, 8.0f); + // RANDOTODO settings presets + // std::string presetfilepath = CVar_GetString("gLoadedPreset", ""); + // ImGui::Text("Settings File: %s", presetfilepath.c_str()); + } + PaddedSeparator(); - if (CVar_GetS32("gRandomizer", 0) == 1 && ImGui::BeginTabBar("Randomizer Settings", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { - if (ImGui::BeginTabItem("Main Rules")) { - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - if (ImGui::BeginTable("tableRandoMainRules", 3, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("Open Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Shuffle Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Shuffle Dungeon Items", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::TableHeadersRow(); - ImGui::PopItemFlag(); - ImGui::TableNextRow(); + ImGuiWindow* window = ImGui::GetCurrentWindow(); + static ImVec2 cellPadding(8.0f, 8.0f); - // COLUMN 1 - OPEN SETTINGS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::PushItemWidth(-FLT_MIN); + if (CVar_GetS32("gRandomizer", 0) == 1 && + ImGui::BeginTabBar("Randomizer Settings", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { + if (ImGui::BeginTabItem("Main Rules")) { + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); + if (ImGui::BeginTable("tableRandoMainRules", 3, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("Open Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Shuffle Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Shuffle Dungeon Items", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::TableHeadersRow(); + ImGui::PopItemFlag(); + ImGui::TableNextRow(); - if (CVar_GetS32("gRandomizeAllOpenSettings", 0) != 1) { - // Forest - ImGui::Text(Settings::OpenForest.GetName().c_str()); - InsertHelpHoverText( - "Closed - Kokiri sword & shield are required to access " - "the Deku Tree, and completing the Deku Tree is required to " - "access the Hyrule Field exit.\n" - "\n" - "Closed Deku - Kokiri boy no longer blocks the path to Hyrule " - "Field but Mido still requires the Kokiri sword and Deku shield " - "to access the tree.\n" - "\n" - "Open - Mido no longer blocks the path to the Deku Tree. Kokiri " - "boy no longer blocks the path out of the forest."); - SohImGui::EnhancementCombobox("gRandomizeForest", randoForest, 3, 0); - PaddedSeparator(); - // Kakariko Gate - ImGui::Text(Settings::OpenKakariko.GetName().c_str()); - InsertHelpHoverText( - "Closed - The gate will remain closed until Zelda's letter " - "is shown to the guard.\n" - "\n" - "Open - The gate is always open. The happy mask shop " - "will open immediately after obtaining Zelda's letter." - ); - SohImGui::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 0); - PaddedSeparator(); + // COLUMN 1 - OPEN SETTINGS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::PushItemWidth(-FLT_MIN); - // Door of Time - ImGui::Text(Settings::OpenDoorOfTime.GetName().c_str()); - InsertHelpHoverText( - "Closed - The Ocarina of Time, the Song of Time and all " - "three spiritual stones are required to open the Door of Time.\n" - "\n" - "Song only - Play the Song of Time in front of the Door of " - "Time to open it.\n" - "\n" - "Open - The Door of Time is permanently open with no requirements." - ); - SohImGui::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0); - PaddedSeparator(); + if (CVar_GetS32("gRandomizeAllOpenSettings", 0) != 1) { + // Forest + ImGui::Text(Settings::OpenForest.GetName().c_str()); + InsertHelpHoverText("Closed - Kokiri sword & shield are required to access " + "the Deku Tree, and completing the Deku Tree is required to " + "access the Hyrule Field exit.\n" + "\n" + "Closed Deku - Kokiri boy no longer blocks the path to Hyrule " + "Field but Mido still requires the Kokiri sword and Deku shield " + "to access the tree.\n" + "\n" + "Open - Mido no longer blocks the path to the Deku Tree. Kokiri " + "boy no longer blocks the path out of the forest."); + SohImGui::EnhancementCombobox("gRandomizeForest", randoForest, 3, 0); + PaddedSeparator(); + // Kakariko Gate + ImGui::Text(Settings::OpenKakariko.GetName().c_str()); + InsertHelpHoverText("Closed - The gate will remain closed until Zelda's letter " + "is shown to the guard.\n" + "\n" + "Open - The gate is always open. The happy mask shop " + "will open immediately after obtaining Zelda's letter."); + SohImGui::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 0); + PaddedSeparator(); - // Zora's Fountain - ImGui::Text(Settings::ZorasFountain.GetName().c_str()); - InsertHelpHoverText( - "Closed - King Zora obstructs the way to Zora's Fountain. " - "Ruto's letter must be shown as child Link in order to move " - "him in both time periods.\n" - "\n" - "Closed as child - Ruto's Letter is only required to move King Zora " - "as child Link. Zora's Fountain starts open as adult.\n" - "\n" - "Open - King Zora has already mweeped out of the way in both " - "time periods. Ruto's Letter is removed from the item pool." - ); - SohImGui::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0); - PaddedSeparator(); + // Door of Time + ImGui::Text(Settings::OpenDoorOfTime.GetName().c_str()); + InsertHelpHoverText("Closed - The Ocarina of Time, the Song of Time and all " + "three spiritual stones are required to open the Door of Time.\n" + "\n" + "Song only - Play the Song of Time in front of the Door of " + "Time to open it.\n" + "\n" + "Open - The Door of Time is permanently open with no requirements."); + SohImGui::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0); + PaddedSeparator(); - // Gerudo Fortress - ImGui::Text(Settings::GerudoFortress.GetName().c_str()); - InsertHelpHoverText( - "Sets the amount of carpenters required to repair the bridge " - "in Gerudo Valley.\n" - "\n" - "Normal - All 4 carpenters are required to be saved.\n" - "\n" - "Fast - Only the bottom left carpenter requires rescuing.\n" - "\n" - "Open - The bridge is repaired from the start." - ); - SohImGui::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 0); - PaddedSeparator(); + // Zora's Fountain + ImGui::Text(Settings::ZorasFountain.GetName().c_str()); + InsertHelpHoverText("Closed - King Zora obstructs the way to Zora's Fountain. " + "Ruto's letter must be shown as child Link in order to move " + "him in both time periods.\n" + "\n" + "Closed as child - Ruto's Letter is only required to move King Zora " + "as child Link. Zora's Fountain starts open as adult.\n" + "\n" + "Open - King Zora has already mweeped out of the way in both " + "time periods. Ruto's Letter is removed from the item pool."); + SohImGui::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0); + PaddedSeparator(); - // Rainbow Bridge - ImGui::Text(Settings::Bridge.GetName().c_str()); - InsertHelpHoverText( - "Alters the requirements to open the bridge to Ganon's Castle.\n" - "\n" - "Vanilla - Obtain the Shadow Medallion, Spirit Medallion and Light Arrows.\n" - "\n" - "Always open - No requirements.\n" - "\n" - "Stones - Obtain the specified amount of spiritual stones.\n" - "\n" - "Medallions - Obtain the specified amount of medallions.\n" - "\n" - "Dungeon rewards - Obtain the specified total sum of spiritual " - "stones or medallions.\n" - "\n" - "Dungeons - Complete the specified amount of dungeons. Dungeons " - "are considered complete after stepping in to the blue warp after " - "the boss.\n" - "\n" - "Tokens - Obtain the specified amount of Skulltula tokens." - ); - SohImGui::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 0); + // Gerudo Fortress + ImGui::Text(Settings::GerudoFortress.GetName().c_str()); + InsertHelpHoverText("Sets the amount of carpenters required to repair the bridge " + "in Gerudo Valley.\n" + "\n" + "Normal - All 4 carpenters are required to be saved.\n" + "\n" + "Fast - Only the bottom left carpenter requires rescuing.\n" + "\n" + "Open - The bridge is repaired from the start."); + SohImGui::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 0); + PaddedSeparator(); + + // Rainbow Bridge + ImGui::Text(Settings::Bridge.GetName().c_str()); + InsertHelpHoverText("Alters the requirements to open the bridge to Ganon's Castle.\n" + "\n" + "Vanilla - Obtain the Shadow Medallion, Spirit Medallion and Light Arrows.\n" + "\n" + "Always open - No requirements.\n" + "\n" + "Stones - Obtain the specified amount of spiritual stones.\n" + "\n" + "Medallions - Obtain the specified amount of medallions.\n" + "\n" + "Dungeon rewards - Obtain the specified total sum of spiritual " + "stones or medallions.\n" + "\n" + "Dungeons - Complete the specified amount of dungeons. Dungeons " + "are considered complete after stepping in to the blue warp after " + "the boss.\n" + "\n" + "Tokens - Obtain the specified amount of Skulltula tokens."); + SohImGui::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 0); + ImGui::PopItemWidth(); + switch (CVar_GetS32("gRandomizeRainbowBridge", 0)) { + case 0: + break; + case 1: + break; + case 2: + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", + "gRandomizeStoneCount", 1, 3, "", 3, true); + break; + case 3: + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", + "gRandomizeMedallionCount", 1, 6, "", 6, true); + break; + case 4: + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", + "gRandomizeRewardCount", 1, 9, "", 9, true); + break; + case 5: + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + SohImGui::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", + "gRandomizeDungeonCount", 1, 8, "", 8, true); + break; + case 6: + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount", + "gRandomizeTokenCount", 1, 100, "", 100, true); + break; + } + PaddedSeparator(); + + // Random Ganon's Trials + /* + ImGui::Text("Random Ganon's Trials"); + InsertHelpHoverText("Sets a random number or required trials to enter\nGanon's Tower."); + SohImGui::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 2, 0); + if (CVar_GetS32("gRandomizeGanonTrial", 0) == 0) { ImGui::PopItemWidth(); - switch (CVar_GetS32("gRandomizeRainbowBridge", 0)) { - case 0: - break; - case 1: - break; - case 2: - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", - "gRandomizeStoneCount", 1, 3, "", 3, true); - break; - case 3: - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", - "gRandomizeMedallionCount", 1, 6, "", 6, true); - break; - case 4: - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", - "gRandomizeRewardCount", 1, 9, "", 9, true); - break; - case 5: - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", - "gRandomizeDungeonCount", 1, 8, "", 8, true); - break; - case 6: - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount", - "gRandomizeTokenCount", 1, 100, "", 100, true); - break; - } - PaddedSeparator(); - - // Random Ganon's Trials - /* - ImGui::Text("Random Ganon's Trials"); - InsertHelpHoverText("Sets a random number or required trials to enter\nGanon's Tower."); - SohImGui::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 2, 0); - if (CVar_GetS32("gRandomizeGanonTrial", 0) == 0) { - ImGui::PopItemWidth(); - SohImGui::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount", - "gRandomizeGanonTrialCount", 0, 6, "", 6); - InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower."); - RANDTODO: Switch back to slider when pre-completing some of Ganon's Trials is properly implemnted. - } - */ - SohImGui::EnhancementCheckbox("Skip Ganon's Trials", "gRandomizeGanonTrialCount"); - InsertHelpHoverText( - "Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower."); + SohImGui::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount", + "gRandomizeGanonTrialCount", 0, 6, "", 6); + InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower."); + RANDTODO: Switch back to slider when pre-completing some of Ganon's Trials is properly implemnted. } - - // COLUMN 2 - Shuffle Settings - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::PushItemWidth(-FLT_MIN); - if (CVar_GetS32("gRandomizeAllShuffleSettings", 0) != 1) { - - // Shuffle Songs - ImGui::Text(Settings::ShuffleSongs.GetName().c_str()); - InsertHelpHoverText( - "Song locations - Songs will only appear at locations that normally teach songs.\n" - "\n" - "Dungeon rewards - Songs appear after beating a major dungeon boss.\n" - "The 4 remaining songs are located at:\n" - " - Zelda's lullaby location\n" - " - Ice Cavern's Serenade of Water location\n" - " - Bottom of the Well Lens of Truth location\n" - " - Gerudo Training Ground's Ice Arrows location\n" - "\n" - "Anywhere - Songs can appear at any location." - ); - - SohImGui::EnhancementCombobox("gRandomizeShuffleSongs", randoShuffleSongs, 3, 0); - PaddedSeparator(); - - // Shuffle Tokens - ImGui::Text(Settings::Tokensanity.GetName().c_str()); - InsertHelpHoverText( - "Shuffles Golden Skulltula Tokens into the item pool. This means " - "Golden Skulltulas can contain other items as well.\n" - "\n" - "Off - GS tokens will not be shuffled.\n" - "\n" - "Dungeons - Only shuffle GS tokens that are within dungeons.\n" - "\n" - "Overworld - Only shuffle GS tokens that are outside of dungeons.\n" - "\n" - "All Tokens - Shuffle all 100 GS tokens." - ); - SohImGui::EnhancementCombobox("gRandomizeShuffleTokens", randoShuffleTokens, 4, 0); - PaddedSeparator(); - - SohImGui::EnhancementCheckbox("Nighttime GS expect Sun's Song", "gRandomizeGsExpectSunsSong"); - InsertHelpHoverText("All Golden Skulltulas that require nighttime to appear will only be " - "expected to be collected after getting Sun's Song."); - PaddedSeparator(); - - // Shuffle Cows - SohImGui::EnhancementCheckbox(Settings::ShuffleCows.GetName().c_str(), "gRandomizeShuffleCows"); - InsertHelpHoverText("Cows give a randomized item from the pool upon performing Epona's Song in front of them."); - PaddedSeparator(); - - // Shuffle Adult Trade Quest - SohImGui::EnhancementCheckbox(Settings::ShuffleAdultTradeQuest.GetName().c_str(), "gRandomizeShuffleAdultTrade"); - InsertHelpHoverText( - "Adds all of the adult trade quest items into the pool, each of which " - "can be traded for a unique reward.\n" - "\n" - "You will be able to choose which of your owned adult trade items is visible " - "in the inventory by selecting the item with A and using the control stick or " - "D-pad.\n" - "\n" - "If disabled, only the Claim Check will be found in the pool." - ); - PaddedSeparator(); - - if(CVar_GetS32("gRandomizeStartingKokiriSword", 0) == 0) { - // Shuffle Kokiri Sword - SohImGui::EnhancementCheckbox(Settings::ShuffleKokiriSword.GetName().c_str(), "gRandomizeShuffleKokiriSword"); - InsertHelpHoverText( - "Shuffles the Kokiri Sword into the item pool.\n" - "\n" - "This will require the use of sticks until the Kokiri Sword is found." - ); - PaddedSeparator(); - } - - if(CVar_GetS32("gRandomizeStartingOcarina", 0) == 0) { - // Shuffle Ocarinas - SohImGui::EnhancementCheckbox(Settings::ShuffleOcarinas.GetName().c_str(), "gRandomizeShuffleOcarinas"); - InsertHelpHoverText( - "Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n" - "\n" - "This will require finding an Ocarina before being able to play songs." - ); - PaddedSeparator(); - } - - // Shuffle Weird Egg - // Disabled when Skip Child Zelda is active - if (!disableEditingRandoSettings) { - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, CVar_GetS32("gRandomizeSkipChildZelda", 0)); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, - ImGui::GetStyle().Alpha * - (CVar_GetS32("gRandomizeSkipChildZelda", 0) ? 0.5f : 1.0f)); - } - SohImGui::EnhancementCheckbox(Settings::ShuffleWeirdEgg.GetName().c_str(), "gRandomizeShuffleWeirdEgg"); - if (!disableEditingRandoSettings) { - ImGui::PopStyleVar(); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && - CVar_GetS32("gRandomizeSkipChildZelda", 0)) { - ImGui::SetTooltip("%s", - "This option is disabled because \"Skip Child Zelda\" is enabled"); - } - ImGui::PopItemFlag(); - } - InsertHelpHoverText( - "Shuffles the Weird Egg from Malon in to the item pool. Enabling " - "\"Skip Child Zelda\" disables this feature.\n" - "\n" - "The Weird Egg is required to unlock several events:\n" - " - Zelda's Lullaby from Impa\n" - " - Saria's song in Sacred Forest Meadow\n" - " - Epona's song and chicken minigame at Lon Lon Ranch\n" - " - Zelda's letter for Kakariko gate (if set to closed)\n" - " - Happy Mask Shop sidequest\n" - ); - PaddedSeparator(); - - // Shuffle Gerudo Membership Card - SohImGui::EnhancementCheckbox(Settings::ShuffleGerudoToken.GetName().c_str(), "gRandomizeShuffleGerudoToken"); - InsertHelpHoverText( - "Shuffles the Gerudo Membership Card into the item pool.\n" - "\n" - "The Gerudo Card is required to enter the Gerudo Training Grounds, opening " - "the gate to Haunted Wasteland and the Horseback Archery minigame." - ); - PaddedSeparator(); - - // Shuffle Frog Song Rupees - SohImGui::EnhancementCheckbox(Settings::ShuffleFrogSongRupees.GetName().c_str(), "gRandomizeShuffleFrogSongRupees"); - InsertHelpHoverText( - "Shuffles 5 Purple Rupees into to the item pool, and allows\n" - "you to earn items by playing songs at the Frog Choir.\n" - "\n" - "This setting does not effect the item earned from playing\n" - "the Song of Storms and the frog song minigame." - ); - } - ImGui::PopItemWidth(); - - // COLUMN 3 - Shuffle Dungeon Items - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::PushItemWidth(-FLT_MIN); - - // Shuffle Dungeon Rewards - ImGui::Text(Settings::ShuffleRewards.GetName().c_str()); + */ + SohImGui::EnhancementCheckbox("Skip Ganon's Trials", "gRandomizeGanonTrialCount"); InsertHelpHoverText( - "Shuffles the location of spiritual stones and medallions.\n" - "\n" - "End of dungeons - Spiritual stones and medallions will be given as rewards " - "for beating major dungeons. Link will always start with one stone or medallion.\n" - "\n" - "Any dungeon - Spiritual stones and medallions can be found inside any dungeon.\n" - "\n" - "Overworld - Spiritual stones and medallions can only be found outside of dungeons.\n" - "\n" - "Anywhere - Spiritual stones and medallions can appear anywhere." - ); - SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0); - PaddedSeparator(); - - // Maps & Compasses - ImGui::Text(Settings::MapsAndCompasses.GetName().c_str()); - InsertHelpHoverText( - "Start with - You will start with Maps & Compasses from all dungeons.\n" - "\n" - "Vanilla - Maps & Compasses will appear in their vanilla locations.\n" - "\n" - "Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n" - "\n" - "Any dungeon - Maps & Compasses can only appear inside of any dungon.\n" - "\n" - "Overworld - Maps & Compasses can only appear outside of dungeons.\n" - "\n" - "Anywhere - Maps & Compasses can appear anywhere in the world." - ); - SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 2); - PaddedSeparator(); - - // Keysanity - ImGui::Text(Settings::Keysanity.GetName().c_str()); - InsertHelpHoverText( - "Start with - You will start with all Small Keys from all dungeons.\n" - "\n" - "Vanilla - Small Keys will appear in their vanilla locations.\n" - "\n" - "Own dungeon - Small Keys can only appear in their respective dungeon.\n" - "\n" - "Any dungeon - Small Keys can only appear inside of any dungon.\n" - "\n" - "Overworld - Small Keys can only appear outside of dungeons.\n" - "\n" - "Anywhere - Small Keys can appear anywhere in the world." - ); - SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 2); - PaddedSeparator(); - - // Gerudo Keys - ImGui::Text(Settings::GerudoKeys.GetName().c_str()); - InsertHelpHoverText( - "Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n" - "\n" - "Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n" - "\n" - "Overworld - Thieve's Hideout Keys can only appear outside of dungeons.\n" - "\n" - "Anywhere - Thieve's Hideout Keys can appear anywhere in the world." - ); - SohImGui::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); - PaddedSeparator(); - - // Boss Keysanity - ImGui::Text(Settings::BossKeysanity.GetName().c_str()); - InsertHelpHoverText( - "Start with - You will start with Boss keys from all dungeons.\n" - "\n" - "Vanilla - Boss Keys will appear in their vanilla locations.\n" - "\n" - "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" - "\n" - "Any dungeon - Boss Keys can only appear inside of any dungon.\n" - "\n" - "Overworld - Boss Keys can only appear outside of dungeons.\n" - "\n" - "Anywhere - Boss Keys can appear anywhere in the world." - ); - SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 2); - PaddedSeparator(); - - // Ganon's Boss Key - ImGui::Text(Settings::GanonsBossKey.GetName().c_str()); - InsertHelpHoverText( - "Vanilla - Ganon's Boss Key will appear in the vanilla location.\n" - "\n" - "Own dungeon - Ganon's Boss Key can appear anywhere inside Ganon's Castle.\n" - "\n" - "Start with - Places Ganon's Boss Key in your starting inventory." - "\n" - "Any dungeon - Ganon's Boss Key Key can only appear inside of any dungon.\n" - "\n" - "Overworld - Ganon's Boss Key Key can only appear outside of dungeons.\n" - "\n" - "Anywhere - Ganon's Boss Key Key can appear anywhere in the world." - ); - SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1); - - ImGui::PopItemWidth(); - ImGui::EndTable(); + "Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower."); } - ImGui::PopStyleVar(1); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Other")) { - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - if (ImGui::BeginTable("tableRandoOther", 3, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("Timesavers", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Hint Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Item Pool Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::TableHeadersRow(); - ImGui::PopItemFlag(); - ImGui::TableNextRow(); - - // COLUMN 1 - TIME SAVERS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; + // COLUMN 2 - Shuffle Settings + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::PushItemWidth(-FLT_MIN); + if (CVar_GetS32("gRandomizeAllShuffleSettings", 0) != 1) { - // Cuccos to return - SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", - "gRandomizeCuccosToReturn", 0, 7, "", 7, true); + // Shuffle Songs + ImGui::Text(Settings::ShuffleSongs.GetName().c_str()); InsertHelpHoverText( - "The amount of cuccos needed to claim the reward from Anju the cucco lady" - ); + "Song locations - Songs will only appear at locations that normally teach songs.\n" + "\n" + "Dungeon rewards - Songs appear after beating a major dungeon boss.\n" + "The 4 remaining songs are located at:\n" + " - Zelda's lullaby location\n" + " - Ice Cavern's Serenade of Water location\n" + " - Bottom of the Well Lens of Truth location\n" + " - Gerudo Training Ground's Ice Arrows location\n" + "\n" + "Anywhere - Songs can appear at any location."); + + SohImGui::EnhancementCombobox("gRandomizeShuffleSongs", randoShuffleSongs, 3, 0); PaddedSeparator(); - // Big Poe Target Count - SohImGui::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount", - "gRandomizeBigPoeTargetCount", 1, 10, "", 10, true); - InsertHelpHoverText( - "The Poe collector will give a reward for turning in this many Big Poes." - ); + // Shuffle Tokens + ImGui::Text(Settings::Tokensanity.GetName().c_str()); + InsertHelpHoverText("Shuffles Golden Skulltula Tokens into the item pool. This means " + "Golden Skulltulas can contain other items as well.\n" + "\n" + "Off - GS tokens will not be shuffled.\n" + "\n" + "Dungeons - Only shuffle GS tokens that are within dungeons.\n" + "\n" + "Overworld - Only shuffle GS tokens that are outside of dungeons.\n" + "\n" + "All Tokens - Shuffle all 100 GS tokens."); + SohImGui::EnhancementCombobox("gRandomizeShuffleTokens", randoShuffleTokens, 4, 0); PaddedSeparator(); - // Skip child stealth + SohImGui::EnhancementCheckbox("Nighttime GS expect Sun's Song", "gRandomizeGsExpectSunsSong"); + InsertHelpHoverText("All Golden Skulltulas that require nighttime to appear will only be " + "expected to be collected after getting Sun's Song."); + PaddedSeparator(); + + // Shuffle Cows + SohImGui::EnhancementCheckbox(Settings::ShuffleCows.GetName().c_str(), "gRandomizeShuffleCows"); + InsertHelpHoverText( + "Cows give a randomized item from the pool upon performing Epona's Song in front of them."); + PaddedSeparator(); + + // Shuffle Adult Trade Quest + SohImGui::EnhancementCheckbox(Settings::ShuffleAdultTradeQuest.GetName().c_str(), + "gRandomizeShuffleAdultTrade"); + InsertHelpHoverText("Adds all of the adult trade quest items into the pool, each of which " + "can be traded for a unique reward.\n" + "\n" + "You will be able to choose which of your owned adult trade items is visible " + "in the inventory by selecting the item with A and using the control stick or " + "D-pad.\n" + "\n" + "If disabled, only the Claim Check will be found in the pool."); + PaddedSeparator(); + + if (CVar_GetS32("gRandomizeStartingKokiriSword", 0) == 0) { + // Shuffle Kokiri Sword + SohImGui::EnhancementCheckbox(Settings::ShuffleKokiriSword.GetName().c_str(), + "gRandomizeShuffleKokiriSword"); + InsertHelpHoverText("Shuffles the Kokiri Sword into the item pool.\n" + "\n" + "This will require the use of sticks until the Kokiri Sword is found."); + PaddedSeparator(); + } + + if (CVar_GetS32("gRandomizeStartingOcarina", 0) == 0) { + // Shuffle Ocarinas + SohImGui::EnhancementCheckbox(Settings::ShuffleOcarinas.GetName().c_str(), + "gRandomizeShuffleOcarinas"); + InsertHelpHoverText( + "Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n" + "\n" + "This will require finding an Ocarina before being able to play songs."); + PaddedSeparator(); + } + + // Shuffle Weird Egg // Disabled when Skip Child Zelda is active if (!disableEditingRandoSettings) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, CVar_GetS32("gRandomizeSkipChildZelda", 0)); @@ -3579,8 +3156,8 @@ void DrawRandoEditor(bool& open) { ImGui::GetStyle().Alpha * (CVar_GetS32("gRandomizeSkipChildZelda", 0) ? 0.5f : 1.0f)); } - SohImGui::EnhancementCheckbox(Settings::SkipChildStealth.GetName().c_str(), - "gRandomizeSkipChildStealth"); + SohImGui::EnhancementCheckbox(Settings::ShuffleWeirdEgg.GetName().c_str(), + "gRandomizeShuffleWeirdEgg"); if (!disableEditingRandoSettings) { ImGui::PopStyleVar(); if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && @@ -3589,362 +3166,524 @@ void DrawRandoEditor(bool& open) { } ImGui::PopItemFlag(); } - InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); - PaddedSeparator(); - - // Skip child zelda - SohImGui::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda"); - InsertHelpHoverText( - "Start with Zelda's Letter in your inventory and skip the sequence up " - "until after meeting Zelda. Disables the ability to shuffle Weird Egg." - ); - PaddedSeparator(); - - // Skip Epona race - SohImGui::EnhancementCheckbox(Settings::SkipEponaRace.GetName().c_str(), "gRandomizeSkipEponaRace"); - InsertHelpHoverText( - "Epona can be summoned with Epona's Song without needing to race Ingo." - ); - PaddedSeparator(); - - // Skip tower escape - SohImGui::EnhancementCheckbox(Settings::SkipTowerEscape.GetName().c_str(), "gRandomizeSkipTowerEscape"); - InsertHelpHoverText( - "The tower escape sequence between Ganondorf and Ganon will be skipped." - ); - PaddedSeparator(); - - // Complete mask quest - SohImGui::EnhancementCheckbox(Settings::CompleteMaskQuest.GetName().c_str(), "gRandomizeCompleteMaskQuest"); - InsertHelpHoverText( - "Once the happy mask shop is opened, all masks will be available to be borrowed." - ); - PaddedSeparator(); - - // Enable Glitch-Useful Cutscenes - SohImGui::EnhancementCheckbox(Settings::EnableGlitchCutscenes.GetName().c_str(), "gRandomizeEnableGlitchCutscenes"); - InsertHelpHoverText( - "The cutscenes of the Poes in Forest Temple and Darunia in Fire Temple will not be skipped. " - "These cutscenes are only useful for glitched gameplay and can be safely skipped otherwise." - ); - - // COLUMN 2 - HINT SETTINGS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::PushItemWidth(-FLT_MIN); - - // Gossip Stone Hints - ImGui::Text(Settings::GossipStoneHints.GetName().c_str()); - InsertHelpHoverText( - "Allows Gossip Stones to provide hints on item locations. Hints mentioning " - "\"Way of the Hero\" indicate a location that holds an item required to beat " - "the seed.\n" - "\n" - "No hints - No hints will be given at all.\n" - "\n" - "Need Nothing - Hints are always available from Gossip Stones.\n" - "\n" - "Need Stone of Agony - Hints are only available after obtaining the Stone of Agony.\n" - "\n" - "Need Mask of Truth - Hints are only available whilst wearing the Mask of Truth.\n" - ); - - SohImGui::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1); - if (CVar_GetS32("gRandomizeGossipStoneHints", 1) != 0) { - // Hint Clarity - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - ImGui::Indent(); - ImGui::Text(Settings::ClearerHints.GetName().c_str()); - InsertHelpHoverText( - "Sets the difficulty of hints.\n" - "\n" - "Obscure - Hints are unique for each item, but the writing may be cryptic.\n" - "Ex: Kokiri Sword > a butter knife\n" - "\n" - "Ambiguous - Hints are clearly written, but may refer to more than one item.\n" - "Ex: Kokiri Sword > a sword\n" - "\n" - "Clear - Hints are clearly written and are unique for each item.\n" - "Ex: Kokiri Sword > the Kokiri Sword" - ); - SohImGui::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2); - - // Hint Distribution - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - ImGui::Text(Settings::HintDistribution.GetName().c_str()); - InsertHelpHoverText( - "Sets how many hints will be useful.\n" - "\n" - "Useless - Only junk hints.\n" - "\n" - "Balanced - Recommended hint spread.\n" - "\n" - "Strong - More useful hints.\n" - "\n" - "Very Strong - Many powerful hints." - ); - SohImGui::EnhancementCombobox("gRandomizeHintDistribution", randoHintDistribution, 4, 1); - ImGui::Unindent(); - } - ImGui::PopItemWidth(); - - // COLUMN 3 - ITEM POOL SETTINGS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::PushItemWidth(-FLT_MIN); - ImGui::Text(Settings::ItemPoolValue.GetName().c_str()); - InsertHelpHoverText( - "Sets how many major items appear in the item pool.\n" - "\n" - "Plentiful - Extra major items are added to the pool.\n" - "\n" - "Balanced - Original item pool.\n" - "\n" - "Scarce - Some excess items are removed, including health upgrades.\n" - "\n" - "Minimal - Most excess items are removed." - ); - SohImGui::EnhancementCombobox("gRandomizeItemPool", randoItemPool, 4, 1); - PaddedSeparator(); - - // Ice Traps - ImGui::Text(Settings::IceTrapValue.GetName().c_str()); - InsertHelpHoverText( - "Sets how many items are replaced by ice traps.\n" - "\n" - "Off - No ice traps.\n" - "\n" - "Normal - Only Ice Traps from the base item pool are shuffled in.\n" - "\n" - "Extra - Chance to replace added junk items with additional ice traps.\n" - "\n" - "Mayhem - All added junk items will be Ice Traps.\n" - "\n" - "Onslaught - All junk items will be replaced by Ice Traps, even those " - "in the base pool." - ); - SohImGui::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1); - ImGui::PopItemWidth(); - ImGui::EndTable(); - } - ImGui::PopStyleVar(1); - ImGui::EndTabItem(); - } - - static bool locationsTabOpen = false; - if (ImGui::BeginTabItem("Locations")) { - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - if (!locationsTabOpen) { - locationsTabOpen = true; - RandomizerCheckObjects::UpdateImGuiVisibility(); - // todo: this efficently when we build out cvar array support - std::stringstream excludedLocationStringStream(CVar_GetString("gRandomizeExcludedLocations", "")); - std::string excludedLocationString; - excludedLocations.clear(); - while(getline(excludedLocationStringStream, excludedLocationString, ',')) { - excludedLocations.insert((RandomizerCheck)std::stoi(excludedLocationString)); - } - } - - if (ImGui::BeginTable("tableRandoLocations", 2, - ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("Included", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Excluded", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::TableHeadersRow(); - ImGui::PopItemFlag(); - ImGui::TableNextRow(); - - // COLUMN 1 - INCLUDED LOCATIONS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - - static ImGuiTextFilter locationSearch; - locationSearch.Draw(); - - ImGui::BeginChild("ChildIncludedLocations", ImVec2(0, -8)); - for (auto areaIt : RandomizerCheckObjects::GetAllRCObjects()) { - bool hasItems = false; - for (auto locationIt : areaIt.second) { - if (locationIt.visibleInImgui && - !excludedLocations.count(locationIt.rc) && - locationSearch.PassFilter(locationIt.rcSpoilerName.c_str())) { - - hasItems = true; - break; - } - } - - if (hasItems) { - ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(areaIt.first).c_str())) { - for (auto locationIt : areaIt.second) { - if (locationIt.visibleInImgui && - !excludedLocations.count(locationIt.rc) && - locationSearch.PassFilter(locationIt.rcSpoilerName.c_str())) { - - if (ImGui::ArrowButton(std::to_string(locationIt.rc).c_str(), ImGuiDir_Right)) { - excludedLocations.insert(locationIt.rc); - // todo: this efficently when we build out cvar array support - std::string excludedLocationString = ""; - for (auto excludedLocationIt : excludedLocations) { - excludedLocationString += std::to_string(excludedLocationIt); - excludedLocationString += ","; - } - CVar_SetString("gRandomizeExcludedLocations", excludedLocationString.c_str()); - SohImGui::needs_save = true; - } - ImGui::SameLine(); - ImGui::Text(locationIt.rcShortName.c_str()); - } - } - ImGui::TreePop(); - } - } - } - ImGui::EndChild(); - - // COLUMN 2 - EXCLUDED LOCATIONS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - - ImGui::BeginChild("ChildExcludedLocations", ImVec2(0, -8)); - for (auto areaIt : RandomizerCheckObjects::GetAllRCObjects()) { - bool hasItems = false; - for (auto locationIt : areaIt.second) { - if (locationIt.visibleInImgui && excludedLocations.count(locationIt.rc)) { - hasItems = true; - break; - } - } - - if (hasItems) { - ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(areaIt.first).c_str())) { - for (auto locationIt : areaIt.second) { - auto elfound = excludedLocations.find(locationIt.rc); - if (locationIt.visibleInImgui && elfound != excludedLocations.end()) { - if (ImGui::ArrowButton(std::to_string(locationIt.rc).c_str(), ImGuiDir_Left)) { - excludedLocations.erase(elfound); - // todo: this efficently when we build out cvar array support - std::string excludedLocationString = ""; - for (auto excludedLocationIt : excludedLocations) { - excludedLocationString += std::to_string(excludedLocationIt); - excludedLocationString += ","; - } - CVar_SetString("gRandomizeExcludedLocations", excludedLocationString.c_str()); - SohImGui::needs_save = true; - } - ImGui::SameLine(); - ImGui::Text(locationIt.rcShortName.c_str()); - } - } - ImGui::TreePop(); - } - } - } - ImGui::EndChild(); - - ImGui::EndTable(); - } - ImGui::PopStyleVar(1); - ImGui::EndTabItem(); - } else { - locationsTabOpen = false; - } - - if (ImGui::BeginTabItem("Tricks/Glitches")) { - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - if (ImGui::BeginTable("tableRandoLogic", 1, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::PushItemWidth(170.0); - ImGui::Text("Logic Rules"); - InsertHelpHoverText("Glitchless - No glitches are required, but may require some minor tricks.\n" + InsertHelpHoverText("Shuffles the Weird Egg from Malon in to the item pool. Enabling " + "\"Skip Child Zelda\" disables this feature.\n" "\n" - "No logic - Item placement is completely random. MAY BE IMPOSSIBLE TO BEAT."); - SohImGui::EnhancementCombobox("gRandomizeLogicRules", randoLogicRules, 2, 0); - ImGui::PopItemWidth(); - ImGui::EndTable(); + "The Weird Egg is required to unlock several events:\n" + " - Zelda's Lullaby from Impa\n" + " - Saria's song in Sacred Forest Meadow\n" + " - Epona's song and chicken minigame at Lon Lon Ranch\n" + " - Zelda's letter for Kakariko gate (if set to closed)\n" + " - Happy Mask Shop sidequest\n"); + PaddedSeparator(); + + // Shuffle Gerudo Membership Card + SohImGui::EnhancementCheckbox(Settings::ShuffleGerudoToken.GetName().c_str(), + "gRandomizeShuffleGerudoToken"); + InsertHelpHoverText("Shuffles the Gerudo Membership Card into the item pool.\n" + "\n" + "The Gerudo Card is required to enter the Gerudo Training Grounds, opening " + "the gate to Haunted Wasteland and the Horseback Archery minigame."); + PaddedSeparator(); + + // Shuffle Frog Song Rupees + SohImGui::EnhancementCheckbox(Settings::ShuffleFrogSongRupees.GetName().c_str(), + "gRandomizeShuffleFrogSongRupees"); + InsertHelpHoverText("Shuffles 5 Purple Rupees into to the item pool, and allows\n" + "you to earn items by playing songs at the Frog Choir.\n" + "\n" + "This setting does not effect the item earned from playing\n" + "the Song of Storms and the frog song minigame."); } - if (ImGui::BeginTable("tableRandoTricksGlitches", 2, - ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("Enable Tricks", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Enable Glitches", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::TableHeadersRow(); - ImGui::PopItemFlag(); - ImGui::TableNextRow(); + ImGui::PopItemWidth(); - // COLUMN 1 - ENABLE TRICKS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::Text("Coming soon"); + // COLUMN 3 - Shuffle Dungeon Items + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::PushItemWidth(-FLT_MIN); - // COLUMN 2 - ENABLE GLITCHES - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::Text("Coming soon"); + // Shuffle Dungeon Rewards + ImGui::Text(Settings::ShuffleRewards.GetName().c_str()); + InsertHelpHoverText( + "Shuffles the location of spiritual stones and medallions.\n" + "\n" + "End of dungeons - Spiritual stones and medallions will be given as rewards " + "for beating major dungeons. Link will always start with one stone or medallion.\n" + "\n" + "Any dungeon - Spiritual stones and medallions can be found inside any dungeon.\n" + "\n" + "Overworld - Spiritual stones and medallions can only be found outside of dungeons.\n" + "\n" + "Anywhere - Spiritual stones and medallions can appear anywhere."); + SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0); + PaddedSeparator(); - ImGui::EndTable(); - } - ImGui::PopStyleVar(1); - ImGui::EndTabItem(); + // Maps & Compasses + ImGui::Text(Settings::MapsAndCompasses.GetName().c_str()); + InsertHelpHoverText("Start with - You will start with Maps & Compasses from all dungeons.\n" + "\n" + "Vanilla - Maps & Compasses will appear in their vanilla locations.\n" + "\n" + "Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n" + "\n" + "Any dungeon - Maps & Compasses can only appear inside of any dungon.\n" + "\n" + "Overworld - Maps & Compasses can only appear outside of dungeons.\n" + "\n" + "Anywhere - Maps & Compasses can appear anywhere in the world."); + SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 2); + PaddedSeparator(); + + // Keysanity + ImGui::Text(Settings::Keysanity.GetName().c_str()); + InsertHelpHoverText("Start with - You will start with all Small Keys from all dungeons.\n" + "\n" + "Vanilla - Small Keys will appear in their vanilla locations.\n" + "\n" + "Own dungeon - Small Keys can only appear in their respective dungeon.\n" + "\n" + "Any dungeon - Small Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Small Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Small Keys can appear anywhere in the world."); + SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 2); + PaddedSeparator(); + + // Gerudo Keys + ImGui::Text(Settings::GerudoKeys.GetName().c_str()); + InsertHelpHoverText("Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n" + "\n" + "Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Thieve's Hideout Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Thieve's Hideout Keys can appear anywhere in the world."); + SohImGui::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); + PaddedSeparator(); + + // Boss Keysanity + ImGui::Text(Settings::BossKeysanity.GetName().c_str()); + InsertHelpHoverText("Start with - You will start with Boss keys from all dungeons.\n" + "\n" + "Vanilla - Boss Keys will appear in their vanilla locations.\n" + "\n" + "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" + "\n" + "Any dungeon - Boss Keys can only appear inside of any dungon.\n" + "\n" + "Overworld - Boss Keys can only appear outside of dungeons.\n" + "\n" + "Anywhere - Boss Keys can appear anywhere in the world."); + SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 2); + PaddedSeparator(); + + // Ganon's Boss Key + ImGui::Text(Settings::GanonsBossKey.GetName().c_str()); + InsertHelpHoverText("Vanilla - Ganon's Boss Key will appear in the vanilla location.\n" + "\n" + "Own dungeon - Ganon's Boss Key can appear anywhere inside Ganon's Castle.\n" + "\n" + "Start with - Places Ganon's Boss Key in your starting inventory." + "\n" + "Any dungeon - Ganon's Boss Key Key can only appear inside of any dungon.\n" + "\n" + "Overworld - Ganon's Boss Key Key can only appear outside of dungeons.\n" + "\n" + "Anywhere - Ganon's Boss Key Key can appear anywhere in the world."); + SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1); + + ImGui::PopItemWidth(); + ImGui::EndTable(); } - - if (ImGui::BeginTabItem("Starting Inventory")) { - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - if (ImGui::BeginTable("tableRandoStartingInventory", 3, - ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { - ImGui::TableSetupColumn("Starting Equipment", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Starting Items", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::TableSetupColumn("Starting Songs", ImGuiTableColumnFlags_WidthStretch, 200.0f); - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::TableHeadersRow(); - ImGui::PopItemFlag(); - ImGui::TableNextRow(); - - // COLUMN 1 - STARTING EQUIPMENT - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - SohImGui::EnhancementCheckbox(Settings::StartingKokiriSword.GetName().c_str(), "gRandomizeStartingKokiriSword"); - PaddedSeparator(); - SohImGui::EnhancementCheckbox(Settings::StartingDekuShield.GetName().c_str(), "gRandomizeStartingDekuShield"); - - // COLUMN 2 - STARTING ITEMS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - SohImGui::EnhancementCheckbox(Settings::StartingOcarina.GetName().c_str(), "gRandomizeStartingOcarina"); - PaddedSeparator(); - SohImGui::EnhancementCheckbox(Settings::StartingConsumables.GetName().c_str(), "gRandomizeStartingConsumables"); - PaddedSeparator(); - SohImGui::EnhancementCheckbox("Full Wallets", "gRandomizeFullWallets"); - InsertHelpHoverText("Start with a full wallet. All wallet upgrades come filled with rupees."); - - // COLUMN 3 - STARTING SONGS - ImGui::TableNextColumn(); - window->DC.CurrLineTextBaseOffset = 0.0f; - ImGui::Text("Coming soon"); - - ImGui::EndTable(); - } - ImGui::PopStyleVar(1); - ImGui::EndTabItem(); - } - - ImGui::EndTabBar(); + ImGui::PopStyleVar(1); + ImGui::EndTabItem(); } - ImGui::PopItemFlag(); - ImGui::PopStyleVar(); - ImGui::End(); + + if (ImGui::BeginTabItem("Other")) { + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); + if (ImGui::BeginTable("tableRandoOther", 3, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("Timesavers", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Hint Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Item Pool Settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::TableHeadersRow(); + ImGui::PopItemFlag(); + ImGui::TableNextRow(); + + // COLUMN 1 - TIME SAVERS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + + // Cuccos to return + SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", + "gRandomizeCuccosToReturn", 0, 7, "", 7, true); + InsertHelpHoverText("The amount of cuccos needed to claim the reward from Anju the cucco lady"); + PaddedSeparator(); + + // Big Poe Target Count + SohImGui::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount", + "gRandomizeBigPoeTargetCount", 1, 10, "", 10, true); + InsertHelpHoverText("The Poe collector will give a reward for turning in this many Big Poes."); + PaddedSeparator(); + + // Skip child stealth + // Disabled when Skip Child Zelda is active + if (!disableEditingRandoSettings) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, CVar_GetS32("gRandomizeSkipChildZelda", 0)); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, + ImGui::GetStyle().Alpha * + (CVar_GetS32("gRandomizeSkipChildZelda", 0) ? 0.5f : 1.0f)); + } + SohImGui::EnhancementCheckbox(Settings::SkipChildStealth.GetName().c_str(), + "gRandomizeSkipChildStealth"); + if (!disableEditingRandoSettings) { + ImGui::PopStyleVar(); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + CVar_GetS32("gRandomizeSkipChildZelda", 0)) { + ImGui::SetTooltip("%s", "This option is disabled because \"Skip Child Zelda\" is enabled"); + } + ImGui::PopItemFlag(); + } + InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); + PaddedSeparator(); + + // Skip child zelda + SohImGui::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda"); + InsertHelpHoverText("Start with Zelda's Letter in your inventory and skip the sequence up " + "until after meeting Zelda. Disables the ability to shuffle Weird Egg."); + PaddedSeparator(); + + // Skip Epona race + SohImGui::EnhancementCheckbox(Settings::SkipEponaRace.GetName().c_str(), "gRandomizeSkipEponaRace"); + InsertHelpHoverText("Epona can be summoned with Epona's Song without needing to race Ingo."); + PaddedSeparator(); + + // Skip tower escape + SohImGui::EnhancementCheckbox(Settings::SkipTowerEscape.GetName().c_str(), "gRandomizeSkipTowerEscape"); + InsertHelpHoverText("The tower escape sequence between Ganondorf and Ganon will be skipped."); + PaddedSeparator(); + + // Complete mask quest + SohImGui::EnhancementCheckbox(Settings::CompleteMaskQuest.GetName().c_str(), + "gRandomizeCompleteMaskQuest"); + InsertHelpHoverText("Once the happy mask shop is opened, all masks will be available to be borrowed."); + PaddedSeparator(); + + // Enable Glitch-Useful Cutscenes + SohImGui::EnhancementCheckbox(Settings::EnableGlitchCutscenes.GetName().c_str(), + "gRandomizeEnableGlitchCutscenes"); + InsertHelpHoverText( + "The cutscenes of the Poes in Forest Temple and Darunia in Fire Temple will not be skipped. " + "These cutscenes are only useful for glitched gameplay and can be safely skipped otherwise."); + + // COLUMN 2 - HINT SETTINGS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::PushItemWidth(-FLT_MIN); + + // Gossip Stone Hints + ImGui::Text(Settings::GossipStoneHints.GetName().c_str()); + InsertHelpHoverText( + "Allows Gossip Stones to provide hints on item locations. Hints mentioning " + "\"Way of the Hero\" indicate a location that holds an item required to beat " + "the seed.\n" + "\n" + "No hints - No hints will be given at all.\n" + "\n" + "Need Nothing - Hints are always available from Gossip Stones.\n" + "\n" + "Need Stone of Agony - Hints are only available after obtaining the Stone of Agony.\n" + "\n" + "Need Mask of Truth - Hints are only available whilst wearing the Mask of Truth.\n"); + + SohImGui::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1); + if (CVar_GetS32("gRandomizeGossipStoneHints", 1) != 0) { + // Hint Clarity + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + ImGui::Indent(); + ImGui::Text(Settings::ClearerHints.GetName().c_str()); + InsertHelpHoverText("Sets the difficulty of hints.\n" + "\n" + "Obscure - Hints are unique for each item, but the writing may be cryptic.\n" + "Ex: Kokiri Sword > a butter knife\n" + "\n" + "Ambiguous - Hints are clearly written, but may refer to more than one item.\n" + "Ex: Kokiri Sword > a sword\n" + "\n" + "Clear - Hints are clearly written and are unique for each item.\n" + "Ex: Kokiri Sword > the Kokiri Sword"); + SohImGui::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2); + + // Hint Distribution + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + ImGui::Text(Settings::HintDistribution.GetName().c_str()); + InsertHelpHoverText("Sets how many hints will be useful.\n" + "\n" + "Useless - Only junk hints.\n" + "\n" + "Balanced - Recommended hint spread.\n" + "\n" + "Strong - More useful hints.\n" + "\n" + "Very Strong - Many powerful hints."); + SohImGui::EnhancementCombobox("gRandomizeHintDistribution", randoHintDistribution, 4, 1); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + // COLUMN 3 - ITEM POOL SETTINGS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::PushItemWidth(-FLT_MIN); + ImGui::Text(Settings::ItemPoolValue.GetName().c_str()); + InsertHelpHoverText("Sets how many major items appear in the item pool.\n" + "\n" + "Plentiful - Extra major items are added to the pool.\n" + "\n" + "Balanced - Original item pool.\n" + "\n" + "Scarce - Some excess items are removed, including health upgrades.\n" + "\n" + "Minimal - Most excess items are removed."); + SohImGui::EnhancementCombobox("gRandomizeItemPool", randoItemPool, 4, 1); + PaddedSeparator(); + + // Ice Traps + ImGui::Text(Settings::IceTrapValue.GetName().c_str()); + InsertHelpHoverText("Sets how many items are replaced by ice traps.\n" + "\n" + "Off - No ice traps.\n" + "\n" + "Normal - Only Ice Traps from the base item pool are shuffled in.\n" + "\n" + "Extra - Chance to replace added junk items with additional ice traps.\n" + "\n" + "Mayhem - All added junk items will be Ice Traps.\n" + "\n" + "Onslaught - All junk items will be replaced by Ice Traps, even those " + "in the base pool."); + SohImGui::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1); + ImGui::PopItemWidth(); + ImGui::EndTable(); + } + ImGui::PopStyleVar(1); + ImGui::EndTabItem(); + } + + static bool locationsTabOpen = false; + if (ImGui::BeginTabItem("Locations")) { + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); + if (!locationsTabOpen) { + locationsTabOpen = true; + RandomizerCheckObjects::UpdateImGuiVisibility(); + // todo: this efficently when we build out cvar array support + std::stringstream excludedLocationStringStream(CVar_GetString("gRandomizeExcludedLocations", "")); + std::string excludedLocationString; + excludedLocations.clear(); + while (getline(excludedLocationStringStream, excludedLocationString, ',')) { + excludedLocations.insert((RandomizerCheck)std::stoi(excludedLocationString)); + } + } + + if (ImGui::BeginTable("tableRandoLocations", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("Included", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Excluded", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::TableHeadersRow(); + ImGui::PopItemFlag(); + ImGui::TableNextRow(); + + // COLUMN 1 - INCLUDED LOCATIONS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + + static ImGuiTextFilter locationSearch; + locationSearch.Draw(); + + ImGui::BeginChild("ChildIncludedLocations", ImVec2(0, -8)); + for (auto areaIt : RandomizerCheckObjects::GetAllRCObjects()) { + bool hasItems = false; + for (auto locationIt : areaIt.second) { + if (locationIt.visibleInImgui && !excludedLocations.count(locationIt.rc) && + locationSearch.PassFilter(locationIt.rcSpoilerName.c_str())) { + + hasItems = true; + break; + } + } + + if (hasItems) { + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(areaIt.first).c_str())) { + for (auto locationIt : areaIt.second) { + if (locationIt.visibleInImgui && !excludedLocations.count(locationIt.rc) && + locationSearch.PassFilter(locationIt.rcSpoilerName.c_str())) { + + if (ImGui::ArrowButton(std::to_string(locationIt.rc).c_str(), ImGuiDir_Right)) { + excludedLocations.insert(locationIt.rc); + // todo: this efficently when we build out cvar array support + std::string excludedLocationString = ""; + for (auto excludedLocationIt : excludedLocations) { + excludedLocationString += std::to_string(excludedLocationIt); + excludedLocationString += ","; + } + CVar_SetString("gRandomizeExcludedLocations", excludedLocationString.c_str()); + SohImGui::needs_save = true; + } + ImGui::SameLine(); + ImGui::Text(locationIt.rcShortName.c_str()); + } + } + ImGui::TreePop(); + } + } + } + ImGui::EndChild(); + + // COLUMN 2 - EXCLUDED LOCATIONS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + + ImGui::BeginChild("ChildExcludedLocations", ImVec2(0, -8)); + for (auto areaIt : RandomizerCheckObjects::GetAllRCObjects()) { + bool hasItems = false; + for (auto locationIt : areaIt.second) { + if (locationIt.visibleInImgui && excludedLocations.count(locationIt.rc)) { + hasItems = true; + break; + } + } + + if (hasItems) { + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(areaIt.first).c_str())) { + for (auto locationIt : areaIt.second) { + auto elfound = excludedLocations.find(locationIt.rc); + if (locationIt.visibleInImgui && elfound != excludedLocations.end()) { + if (ImGui::ArrowButton(std::to_string(locationIt.rc).c_str(), ImGuiDir_Left)) { + excludedLocations.erase(elfound); + // todo: this efficently when we build out cvar array support + std::string excludedLocationString = ""; + for (auto excludedLocationIt : excludedLocations) { + excludedLocationString += std::to_string(excludedLocationIt); + excludedLocationString += ","; + } + CVar_SetString("gRandomizeExcludedLocations", excludedLocationString.c_str()); + SohImGui::needs_save = true; + } + ImGui::SameLine(); + ImGui::Text(locationIt.rcShortName.c_str()); + } + } + ImGui::TreePop(); + } + } + } + ImGui::EndChild(); + + ImGui::EndTable(); + } + ImGui::PopStyleVar(1); + ImGui::EndTabItem(); + } else { + locationsTabOpen = false; + } + + if (ImGui::BeginTabItem("Tricks/Glitches")) { + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); + if (ImGui::BeginTable("tableRandoLogic", 1, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::PushItemWidth(170.0); + ImGui::Text("Logic Rules"); + InsertHelpHoverText("Glitchless - No glitches are required, but may require some minor tricks.\n" + "\n" + "No logic - Item placement is completely random. MAY BE IMPOSSIBLE TO BEAT."); + SohImGui::EnhancementCombobox("gRandomizeLogicRules", randoLogicRules, 2, 0); + ImGui::PopItemWidth(); + ImGui::EndTable(); + } + if (ImGui::BeginTable("tableRandoTricksGlitches", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("Enable Tricks", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Enable Glitches", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::TableHeadersRow(); + ImGui::PopItemFlag(); + ImGui::TableNextRow(); + + // COLUMN 1 - ENABLE TRICKS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::Text("Coming soon"); + + // COLUMN 2 - ENABLE GLITCHES + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::Text("Coming soon"); + + ImGui::EndTable(); + } + ImGui::PopStyleVar(1); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Starting Inventory")) { + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); + if (ImGui::BeginTable("tableRandoStartingInventory", 3, + ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + ImGui::TableSetupColumn("Starting Equipment", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Starting Items", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::TableSetupColumn("Starting Songs", ImGuiTableColumnFlags_WidthStretch, 200.0f); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::TableHeadersRow(); + ImGui::PopItemFlag(); + ImGui::TableNextRow(); + + // COLUMN 1 - STARTING EQUIPMENT + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + SohImGui::EnhancementCheckbox(Settings::StartingKokiriSword.GetName().c_str(), + "gRandomizeStartingKokiriSword"); + PaddedSeparator(); + SohImGui::EnhancementCheckbox(Settings::StartingDekuShield.GetName().c_str(), + "gRandomizeStartingDekuShield"); + + // COLUMN 2 - STARTING ITEMS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + SohImGui::EnhancementCheckbox(Settings::StartingOcarina.GetName().c_str(), "gRandomizeStartingOcarina"); + PaddedSeparator(); + SohImGui::EnhancementCheckbox(Settings::StartingConsumables.GetName().c_str(), + "gRandomizeStartingConsumables"); + PaddedSeparator(); + SohImGui::EnhancementCheckbox("Full Wallets", "gRandomizeFullWallets"); + InsertHelpHoverText("Start with a full wallet. All wallet upgrades come filled with rupees."); + + // COLUMN 3 - STARTING SONGS + ImGui::TableNextColumn(); + window->DC.CurrLineTextBaseOffset = 0.0f; + ImGui::Text("Coming soon"); + + ImGui::EndTable(); + } + ImGui::PopStyleVar(1); + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); } + ImGui::PopItemFlag(); + ImGui::PopStyleVar(); + ImGui::End(); +} void CreateGetItemMessages(std::vector messageEntries) { CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::getItemMessageTableID); for (GetItemMessage messageEntry : messageEntries) { - if (messageEntry.giid == GI_ICE_TRAP) { + if (messageEntry.giid == RG_ICE_TRAP) { customMessageManager->CreateMessage(Randomizer::getItemMessageTableID, messageEntry.giid, { TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM, messageEntry.english, messageEntry.german, messageEntry.french }); @@ -3979,82 +3718,186 @@ void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). const std::vector getItemMessages = { - GIMESSAGE(GI_ICE_TRAP, ITEM_NONE, "\x08\x06\x30You are a %bFOWL%w!\x0E\x20", + GIMESSAGE(RG_ICE_TRAP, ITEM_NONE, "\x08\x06\x30You are a %bFOWL%w!\x0E\x20", "\x08\x06\x15 Du bist ein %bDUMMKOPF%w!\x0E\x20", "\x08\x06\x50%bIDIOT%w\x0E\x20"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", "Vous obtenez une %rBouteille avec&une Flamme Bleue%w! Utilisez-la&pour faire fondre la %rGlace&Rouge%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE, "You got a %rBig Poe in a Bottle%w!&Sell it to the Ghost Shop!", "Vous obtenez une %rBouteille avec&une Âme%w! Vendez-la au Marchand&d'Âme"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, "You got a %rBottle of Blue Potion%w!&Drink it to replenish your&%ghealth%w and %bmagic%w!", "Vous obtenez une %rBouteille avec&une Potion Bleue%w! Buvez-la pour&restaurer votre %rénergie vitale%w&ainsi que votre %gmagie%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_FISH, ITEM_FISH, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_FISH, ITEM_FISH, "You got a %rFish in a Bottle%w!&It looks fresh and delicious!&They say Jabu-Jabu loves them!", "Vous obtenez une %rBouteille avec&un Poisson%w! Il a l'air délicieux!&Il paraîtrait que %bJabu-Jabu %wen&serait friand!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_BUGS, ITEM_BUG, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_BUGS, ITEM_BUG, "You got a %rBug in a Bottle%w!&They love to burrow in&dirt holes!", "Vous obtenez une %rBouteille avec&des Insectes%w! Ils adorent creuser&dans la terre meuble!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_FAIRY, ITEM_FAIRY, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY, "You got a %rFairy in a Bottle%w!&Use it wisely!", "Vous obtenez une %rBouteille avec&une Fée%w! Faites-en bon usage!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, "You got a %rBottle of Red Potion%w!&Drink it to replenish your&%ghealth%w!", "Vous obtenez une %rBouteille avec&une Potion Rouge%w! Buvez-la pour&restaurer votre %rénergie vitale%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, "You got a %rBottle of Green Potion%w!&Drink it to replenish your&%bmagic%w!", "Vous obtenez une %rBouteille avec&une Potion Verte%w! Buvez-la pour&restaurer votre %gmagie%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTLE_WITH_POE, ITEM_POE, + GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_POE, ITEM_POE, "You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this...", "Vous obtenez une %rBouteille avec&un Esprit%w! Ça intéresserait&peut-être le vendeur d'Âme "), - GIMESSAGE_NO_GERMAN(GI_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"), - GIMESSAGE_NO_GERMAN(GI_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"), - GIMESSAGE_NO_GERMAN(GI_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"), - GIMESSAGE_NO_GERMAN(GI_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"), - GIMESSAGE_NO_GERMAN(GI_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"), - GIMESSAGE_NO_GERMAN(GI_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pBottom of the &Well %wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %Puits%w!"), - GIMESSAGE_NO_GERMAN(GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yGerudo Training &Grounds %wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), - GIMESSAGE_NO_GERMAN(GI_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %Château de Ganon%w!"), + GIMESSAGE_NO_GERMAN(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"), + GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"), + GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"), + GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"), + GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"), + GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"), + GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pBottom of the &Well %wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %Puits%w!"), + GIMESSAGE_NO_GERMAN(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yGerudo Training &Grounds %wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), + GIMESSAGE_NO_GERMAN(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %Château de Ganon%w!"), - GIMESSAGE_NO_GERMAN(GI_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %gForest Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%gTemple de la Forêt%w!"), - GIMESSAGE_NO_GERMAN(GI_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rFire Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%rTemple du Feu%w!"), - GIMESSAGE_NO_GERMAN(GI_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %bWater Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%bTemple de l'Eau%w!"), - GIMESSAGE_NO_GERMAN(GI_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %ySpirit Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%yTemple de l'Esprit%w!"), - GIMESSAGE_NO_GERMAN(GI_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %pShadow Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%pTemple de l'Ombre%w!"), - GIMESSAGE_NO_GERMAN(GI_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rGanon's Castle &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"), + GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %gForest Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%gTemple de la Forêt%w!"), + GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rFire Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%rTemple du Feu%w!"), + GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %bWater Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%bTemple de l'Eau%w!"), + GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %ySpirit Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%yTemple de l'Esprit%w!"), + GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %pShadow Temple &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%pTemple de l'Ombre%w!"), + GIMESSAGE_NO_GERMAN(RG_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rGanon's Castle &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"), - GIMESSAGE_NO_GERMAN(GI_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!", "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!"), - GIMESSAGE_NO_GERMAN(GI_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!", "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!"), - GIMESSAGE_NO_GERMAN(GI_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!", "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!"), - GIMESSAGE_NO_GERMAN(GI_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!"), - GIMESSAGE_NO_GERMAN(GI_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!"), - GIMESSAGE_NO_GERMAN(GI_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!"), - GIMESSAGE_NO_GERMAN(GI_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!"), - GIMESSAGE_NO_GERMAN(GI_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!", "Vous obtenez la %rCarte %wdu &%pPuits%w!"), - GIMESSAGE_NO_GERMAN(GI_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!", "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!"), + GIMESSAGE_NO_GERMAN(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!", "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!"), + GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!", "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!"), + GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!", "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!"), + GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!"), + GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!"), + GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!"), + GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!"), + GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!"), + GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!", "Vous obtenez la %rCarte %wdu &%pPuits%w!"), + GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!", "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!"), - GIMESSAGE_NO_GERMAN(GI_DEKU_TREE_COMPASS, ITEM_COMPASS, "You found the %gDeku Tree &%wCompass!", "Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"), - GIMESSAGE_NO_GERMAN(GI_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS, "You found the %rDodongo's Cavern &%wCompass!", "Vous obtenez la %rBoussole %wde la&%rCaverne Dodongo%w!"), - GIMESSAGE_NO_GERMAN(GI_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS, "You found the %bJabu Jabu's Belly &%wCompass!", "Vous obtenez la %rBoussole %wdu &%bVentre de Jabu-Jabu%w!"), - GIMESSAGE_NO_GERMAN(GI_FOREST_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %gForest Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%gTemple de la Forêt%w!"), - GIMESSAGE_NO_GERMAN(GI_FIRE_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %rFire Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%rTemple du Feu%w!"), - GIMESSAGE_NO_GERMAN(GI_WATER_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %bWater Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%bTemple de l'Eau%w!"), - GIMESSAGE_NO_GERMAN(GI_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %ySpirit Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%yTemple de l'Esprit%w!"), - GIMESSAGE_NO_GERMAN(GI_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %pShadow Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%pTemple de l'Ombre%w!"), - GIMESSAGE_NO_GERMAN(GI_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS, "You found the %pBottom of the &Well %wCompass!", "Vous obtenez la %rBoussole %wdu &%pPuits%w!"), - GIMESSAGE_NO_GERMAN(GI_ICE_CAVERN_COMPASS, ITEM_COMPASS, "You found the %cIce Cavern &%wCompass!", "Vous obtenez la %rBoussole %wde &la %cCaverne Polaire%w!"), + GIMESSAGE_NO_GERMAN(RG_DEKU_TREE_COMPASS, ITEM_COMPASS, "You found the %gDeku Tree &%wCompass!", "Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"), + GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS, "You found the %rDodongo's Cavern &%wCompass!", "Vous obtenez la %rBoussole %wde la&%rCaverne Dodongo%w!"), + GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS, "You found the %bJabu Jabu's Belly &%wCompass!", "Vous obtenez la %rBoussole %wdu &%bVentre de Jabu-Jabu%w!"), + GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %gForest Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%gTemple de la Forêt%w!"), + GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %rFire Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%rTemple du Feu%w!"), + GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %bWater Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%bTemple de l'Eau%w!"), + GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %ySpirit Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%yTemple de l'Esprit%w!"), + GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %pShadow Temple &%wCompass!", "Vous obtenez la %rBoussole %wdu &%pTemple de l'Ombre%w!"), + GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS, "You found the %pBottom of the &Well %wCompass!", "Vous obtenez la %rBoussole %wdu &%pPuits%w!"), + GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_COMPASS, ITEM_COMPASS, "You found the %cIce Cavern &%wCompass!", "Vous obtenez la %rBoussole %wde &la %cCaverne Polaire%w!"), }; CreateGetItemMessages(getItemMessages); CreateScrubMessages(); } +class ExtendedVanillaTableInvalidItemIdException: public std::exception { + private: + s16 itemID; + + public: + ExtendedVanillaTableInvalidItemIdException(s16 itemID): itemID(itemID) {} + std::string what() { + return itemID + " is not a valid ItemID for the extendedVanillaGetItemTable. If you are adding a new" + "item, try adding it to randoGetItemTable instead."; + } +}; + +void InitRandoItemTable() { + // These entries have ItemIDs from vanilla, but not GetItemIDs or entries in the old sGetItemTable + GetItemEntry extendedVanillaGetItemTable[] = { + GET_ITEM(ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_LIGHT_MEDALLION), + GET_ITEM(ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST, 0x3E, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_FOREST_MEDALLION), + GET_ITEM(ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_FIRE_MEDALLION), + GET_ITEM(ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER, 0x3D, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_WATER_MEDALLION), + GET_ITEM(ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW, 0x41, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SHADOW_MEDALLION), + GET_ITEM(ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT, 0x3F, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SPIRIT_MEDALLION), + + GET_ITEM(ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_KOKIRI_EMERALD), + GET_ITEM(ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_GORON_RUBY), + GET_ITEM(ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_ZORA_SAPPHIRE), + + GET_ITEM(ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_ZELDAS_LULLABY), + GET_ITEM(ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SUNS_SONG), + GET_ITEM(ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_EPONAS_SONG), + GET_ITEM(ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SONG_OF_STORMS), + GET_ITEM(ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SONG_OF_TIME), + GET_ITEM(ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SARIAS_SONG), + + GET_ITEM(ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_MINUET_OF_FOREST), + GET_ITEM(ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_BOLERO_OF_FIRE), + GET_ITEM(ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_SERENADE_OF_WATER), + GET_ITEM(ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_NOCTURNE_OF_SHADOW), + GET_ITEM(ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_REQUIEM_OF_SPIRIT), + GET_ITEM(ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG, MOD_NONE, RG_PRELUDE_OF_LIGHT), + }; + + // These do not have ItemIDs or GetItemIDs from vanilla, so I'm using their + // RandomizerGet enum values for both. + GetItemEntry randoGetItemTable[] = { + GET_ITEM(RG_ICE_TRAP, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_ICE_TRAP), + GET_ITEM(RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_MAGIC_SINGLE), + GET_ITEM(RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_MAGIC_DOUBLE), + GET_ITEM(RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_DOUBLE_DEFENSE), + GET_ITEM(RG_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_RED_POTION), + GET_ITEM(RG_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_GREEN_POTION), + GET_ITEM(RG_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_BLUE_POTION), + GET_ITEM(RG_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_FAIRY), + GET_ITEM(RG_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_FISH), + GET_ITEM(RG_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_BLUE_FIRE), + GET_ITEM(RG_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_BUGS), + GET_ITEM(RG_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_POE), + GET_ITEM(RG_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTLE_WITH_BIG_POE), + GET_ITEM(RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_GERUDO_FORTRESS_SMALL_KEY), + GET_ITEM(RG_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_FOREST_TEMPLE_SMALL_KEY), + GET_ITEM(RG_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_FIRE_TEMPLE_SMALL_KEY), + GET_ITEM(RG_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_WATER_TEMPLE_SMALL_KEY), + GET_ITEM(RG_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_SPIRIT_TEMPLE_SMALL_KEY), + GET_ITEM(RG_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_SHADOW_TEMPLE_SMALL_KEY), + GET_ITEM(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_BOTTOM_OF_THE_WELL_SMALL_KEY), + GET_ITEM(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY), + GET_ITEM(RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, MOD_RANDOMIZER, RG_GANONS_CASTLE_SMALL_KEY), + GET_ITEM(RG_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_FOREST_TEMPLE_BOSS_KEY), + GET_ITEM(RG_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_FIRE_TEMPLE_BOSS_KEY), + GET_ITEM(RG_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_WATER_TEMPLE_BOSS_KEY), + GET_ITEM(RG_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SPIRIT_TEMPLE_BOSS_KEY), + GET_ITEM(RG_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SHADOW_TEMPLE_BOSS_KEY), + GET_ITEM(RG_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY), + GET_ITEM(RG_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_DEKU_TREE_MAP), + GET_ITEM(RG_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_DODONGOS_CAVERN_MAP), + GET_ITEM(RG_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_JABU_JABUS_BELLY_MAP), + GET_ITEM(RG_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_FOREST_TEMPLE_MAP), + GET_ITEM(RG_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_FIRE_TEMPLE_MAP), + GET_ITEM(RG_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_WATER_TEMPLE_MAP), + GET_ITEM(RG_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SPIRIT_TEMPLE_MAP), + GET_ITEM(RG_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SHADOW_TEMPLE_MAP), + GET_ITEM(RG_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTOM_OF_THE_WELL_MAP), + GET_ITEM(RG_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_ICE_CAVERN_MAP), + GET_ITEM(RG_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_DEKU_TREE_COMPASS), + GET_ITEM(RG_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_DODONGOS_CAVERN_COMPASS), + GET_ITEM(RG_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_JABU_JABUS_BELLY_COMPASS), + GET_ITEM(RG_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_FOREST_TEMPLE_COMPASS), + GET_ITEM(RG_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_FIRE_TEMPLE_COMPASS), + GET_ITEM(RG_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_WATER_TEMPLE_COMPASS), + GET_ITEM(RG_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SPIRIT_TEMPLE_COMPASS), + GET_ITEM(RG_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SHADOW_TEMPLE_COMPASS), + GET_ITEM(RG_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTOM_OF_THE_WELL_COMPASS), + GET_ITEM(RG_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_ICE_CAVERN_COMPASS), + }; + ItemTableManager::Instance->AddItemTable(MOD_RANDOMIZER); + for (int i = 0; i < ARRAY_COUNT(extendedVanillaGetItemTable); i++) { + ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, extendedVanillaGetItemTable[i].getItemId, extendedVanillaGetItemTable[i]); + } + for (int i = 0; i < ARRAY_COUNT(randoGetItemTable); i++) { + ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, randoGetItemTable[i].itemId, randoGetItemTable[i]); + } +} + + void InitRando() { SohImGui::AddWindow("Randomizer", "Randomizer Settings", DrawRandoEditor); Randomizer::CreateCustomMessages(); + InitRandoItemTable(); } extern "C" { diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 1994cfdc4..15394fbcb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -16,11 +16,13 @@ class Randomizer { std::string ganonHintText; std::string ganonText; std::unordered_map randoSettings; - GetItemID GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId); - GetItemID GetItemFromActor(s16 actorId, s16 actorParams, s16 sceneNum, GetItemID ogItemId); + s16 GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId); + s16 GetItemFromActor(s16 actorId, s16 actorParams, s16 sceneNum, GetItemID ogItemId); void ParseRandomizerSettingsFile(const char* spoilerFileName); void ParseHintLocationsFile(const char* spoilerFileName); void ParseItemLocationsFile(const char* spoilerFileName, bool silent); + bool IsItemVanilla(RandomizerGet randoGet); + public: Randomizer(); @@ -38,14 +40,15 @@ class Randomizer { void LoadHintLocations(const char* spoilerFileName); void LoadItemLocations(const char* spoilerFileName, bool silent); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); - RandomizerCheck GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum); + RandomizerCheck GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams); std::string GetChildAltarText() const; std::string GetAdultAltarText() const; std::string GetGanonText() const; std::string GetGanonHintText() const; - GetItemID GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); - GetItemID GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); + s16 GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); + s16 GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); static void CreateCustomMessages(); + bool CheckContainsVanillaItem(RandomizerCheck randoCheck); }; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 742fd56db..21635278c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2,6 +2,11 @@ #include +// This should probably go in a less rando-specific location +// but the best location will probably be in the modding engine +// which doesn't exist yet. +typedef enum { MOD_NONE, MOD_RANDOMIZER } ModIndex; + typedef struct { char tex[512]; uint16_t width; @@ -810,6 +815,8 @@ typedef enum { RG_PROGRESSIVE_STICK_UPGRADE, RG_PROGRESSIVE_BOMBCHUS, RG_PROGRESSIVE_MAGIC_METER, + RG_MAGIC_SINGLE, // Added for refactor of GetItemEntries + RG_MAGIC_DOUBLE, // Added for refactor of GetItemEntries RG_PROGRESSIVE_OCARINA, RG_PROGRESSIVE_GORONSWORD, RG_EMPTY_BOTTLE, @@ -951,7 +958,8 @@ typedef enum { RG_BUY_RED_POTION_40, RG_BUY_RED_POTION_50, RG_TRIFORCE, - RG_HINT + RG_HINT, + RG_MAX } RandomizerGet; typedef enum { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 3611c97de..805e866da 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -57,10 +57,12 @@ #include #include #include +#include OTRGlobals* OTRGlobals::Instance; SaveManager* SaveManager::Instance; CustomMessageManager* CustomMessageManager::Instance; +ItemTableManager* ItemTableManager::Instance; OTRGlobals::OTRGlobals() { context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian"); @@ -158,6 +160,145 @@ extern "C" void OTRAudio_Exit() { audio.thread.join(); } +extern "C" void VanillaItemTable_Init() { + GetItemEntry getItemTable[] = { + GET_ITEM(ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBS_5), + GET_ITEM(ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, MOD_NONE, GI_NUTS_5), + GET_ITEM(ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBCHUS_10), + GET_ITEM(ITEM_BOW, OBJECT_GI_BOW, GID_BOW, 0x31, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOW), + GET_ITEM(ITEM_SLINGSHOT, OBJECT_GI_PACHINKO, GID_SLINGSHOT, 0x30, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SLINGSHOT), + GET_ITEM(ITEM_BOOMERANG, OBJECT_GI_BOOMERANG, GID_BOOMERANG, 0x35, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOOMERANG), + GET_ITEM(ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, MOD_NONE, GI_STICKS_1), + GET_ITEM(ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HOOKSHOT), + GET_ITEM(ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_LONGSHOT), + GET_ITEM(ITEM_LENS, OBJECT_GI_GLASSES, GID_LENS, 0x39, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_LENS), + GET_ITEM(ITEM_LETTER_ZELDA, OBJECT_GI_LETTER, GID_LETTER_ZELDA, 0x69, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_LETTER_ZELDA), + GET_ITEM(ITEM_OCARINA_TIME, OBJECT_GI_OCARINA, GID_OCARINA_TIME, 0x3A, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_OCARINA_OOT), + GET_ITEM(ITEM_HAMMER, OBJECT_GI_HAMMER, GID_HAMMER, 0x38, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HAMMER), + GET_ITEM(ITEM_COJIRO, OBJECT_GI_NIWATORI, GID_COJIRO, 0x02, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_COJIRO), + GET_ITEM(ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOTTLE), + GET_ITEM(ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_POTION_RED), + GET_ITEM(ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_POTION_GREEN), + GET_ITEM(ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_POTION_BLUE), + GET_ITEM(ITEM_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_FAIRY), + GET_ITEM(ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MILK_BOTTLE), + GET_ITEM(ITEM_LETTER_RUTO, OBJECT_GI_BOTTLE_LETTER, GID_LETTER_RUTO, 0x99, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_LETTER_RUTO), + GET_ITEM(ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_BEAN), + GET_ITEM(ITEM_MASK_SKULL, OBJECT_GI_SKJ_MASK, GID_MASK_SKULL, 0x10, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_SKULL), + GET_ITEM(ITEM_MASK_SPOOKY, OBJECT_GI_REDEAD_MASK, GID_MASK_SPOOKY, 0x11, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_SPOOKY), + GET_ITEM(ITEM_CHICKEN, OBJECT_GI_NIWATORI, GID_CHICKEN, 0x48, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_CHICKEN), + GET_ITEM(ITEM_MASK_KEATON, OBJECT_GI_KI_TAN_MASK, GID_MASK_KEATON, 0x12, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_KEATON), + GET_ITEM(ITEM_MASK_BUNNY, OBJECT_GI_RABIT_MASK, GID_MASK_BUNNY, 0x13, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_BUNNY), + GET_ITEM(ITEM_MASK_TRUTH, OBJECT_GI_TRUTH_MASK, GID_MASK_TRUTH, 0x17, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_TRUTH), + GET_ITEM(ITEM_POCKET_EGG, OBJECT_GI_EGG, GID_EGG, 0x01, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_POCKET_EGG), + GET_ITEM(ITEM_POCKET_CUCCO, OBJECT_GI_NIWATORI, GID_CHICKEN, 0x48, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_POCKET_CUCCO), + GET_ITEM(ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_ODD_MUSHROOM), + GET_ITEM(ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_ODD_POTION), + GET_ITEM(ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SAW), + GET_ITEM(ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SWORD_BROKEN), + GET_ITEM(ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_PRESCRIPTION), + GET_ITEM(ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_FROG), + GET_ITEM(ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_EYEDROPS), + GET_ITEM(ITEM_CLAIM_CHECK, OBJECT_GI_TICKETSTONE, GID_CLAIM_CHECK, 0x0A, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_CLAIM_CHECK), + GET_ITEM(ITEM_SWORD_KOKIRI, OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, 0xA4, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SWORD_KOKIRI), + GET_ITEM(ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x4B, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SWORD_KNIFE), + GET_ITEM(ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT, MOD_NONE, GI_SHIELD_DEKU), + GET_ITEM(ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT, MOD_NONE, GI_SHIELD_HYLIAN), + GET_ITEM(ITEM_SHIELD_MIRROR, OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, 0x4E, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SHIELD_MIRROR), + GET_ITEM(ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG, MOD_NONE, GI_TUNIC_GORON), + GET_ITEM(ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG, MOD_NONE, GI_TUNIC_ZORA), + GET_ITEM(ITEM_BOOTS_IRON, OBJECT_GI_BOOTS_2, GID_BOOTS_IRON, 0x53, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOOTS_IRON), + GET_ITEM(ITEM_BOOTS_HOVER, OBJECT_GI_HOVERBOOTS, GID_BOOTS_HOVER, 0x54, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOOTS_HOVER), + GET_ITEM(ITEM_QUIVER_40, OBJECT_GI_ARROWCASE, GID_QUIVER_40, 0x56, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_QUIVER_40), + GET_ITEM(ITEM_QUIVER_50, OBJECT_GI_ARROWCASE, GID_QUIVER_50, 0x57, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_QUIVER_50), + GET_ITEM(ITEM_BOMB_BAG_20, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, 0x58, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOMB_BAG_20), + GET_ITEM(ITEM_BOMB_BAG_30, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, 0x59, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOMB_BAG_30), + GET_ITEM(ITEM_BOMB_BAG_40, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, 0x5A, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BOMB_BAG_40), + GET_ITEM(ITEM_GAUNTLETS_SILVER, OBJECT_GI_GLOVES, GID_GAUNTLETS_SILVER, 0x5B, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_GAUNTLETS_SILVER), + GET_ITEM(ITEM_GAUNTLETS_GOLD, OBJECT_GI_GLOVES, GID_GAUNTLETS_GOLD, 0x5C, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_GAUNTLETS_GOLD), + GET_ITEM(ITEM_SCALE_SILVER, OBJECT_GI_SCALE, GID_SCALE_SILVER, 0xCD, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SCALE_SILVER), + GET_ITEM(ITEM_SCALE_GOLDEN, OBJECT_GI_SCALE, GID_SCALE_GOLDEN, 0xCE, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SCALE_GOLD), + GET_ITEM(ITEM_STONE_OF_AGONY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, 0x68, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_STONE_OF_AGONY), + GET_ITEM(ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_GERUDO_CARD), + GET_ITEM(ITEM_OCARINA_FAIRY, OBJECT_GI_OCARINA_0, GID_OCARINA_FAIRY, 0x4A, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_OCARINA_FAIRY), + GET_ITEM(ITEM_SEEDS, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, MOD_NONE, GI_SEEDS_5), + GET_ITEM(ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xC6, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HEART_CONTAINER), + GET_ITEM(ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xC2, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HEART_PIECE), + GET_ITEM(ITEM_KEY_BOSS, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_KEY_BOSS), + GET_ITEM(ITEM_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_COMPASS), + GET_ITEM(ITEM_DUNGEON_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MAP), + GET_ITEM(ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_KEY_SMALL), + GET_ITEM(ITEM_MAGIC_SMALL, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0x52, 0x6F, CHEST_ANIM_SHORT, MOD_NONE, GI_MAGIC_SMALL), + GET_ITEM(ITEM_MAGIC_LARGE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0x52, 0x6E, CHEST_ANIM_SHORT, MOD_NONE, GI_MAGIC_LARGE), + GET_ITEM(ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_WALLET_ADULT), + GET_ITEM(ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_WALLET_GIANT), + GET_ITEM(ITEM_WEIRD_EGG, OBJECT_GI_EGG, GID_EGG, 0x9A, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_WEIRD_EGG), + GET_ITEM(ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HEART), + GET_ITEM(ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT, MOD_NONE, GI_ARROWS_SMALL), + GET_ITEM(ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT, MOD_NONE, GI_ARROWS_MEDIUM), + GET_ITEM(ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT, MOD_NONE, GI_ARROWS_LARGE), + GET_ITEM(ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0x6F, 0x00, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_GREEN), + GET_ITEM(ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xCC, 0x01, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_BLUE), + GET_ITEM(ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF0, 0x02, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_RED), + GET_ITEM(ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xC6, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HEART_CONTAINER_2), + GET_ITEM(ITEM_MILK, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MILK), + GET_ITEM(ITEM_MASK_GORON, OBJECT_GI_GOLONMASK, GID_MASK_GORON, 0x14, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_GORON), + GET_ITEM(ITEM_MASK_ZORA, OBJECT_GI_ZORAMASK, GID_MASK_ZORA, 0x15, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_ZORA), + GET_ITEM(ITEM_MASK_GERUDO, OBJECT_GI_GERUDOMASK, GID_MASK_GERUDO, 0x16, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_MASK_GERUDO), + GET_ITEM(ITEM_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, 0x79, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BRACELET), + GET_ITEM(ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF1, 0x14, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_PURPLE), + GET_ITEM(ITEM_RUPEE_GOLD, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0xF2, 0x13, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_GOLD), + GET_ITEM(ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x0C, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_SWORD_BGS), + GET_ITEM(ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_ARROW_FIRE), + GET_ITEM(ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_ARROW_ICE), + GET_ITEM(ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_ARROW_LIGHT), + GET_ITEM(ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_SKULL_TOKEN), + GET_ITEM(ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_DINS_FIRE), + GET_ITEM(ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_FARORES_WIND), + GET_ITEM(ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_NAYRUS_LOVE), + GET_ITEM(ITEM_BULLET_BAG_30, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BULLET_BAG_30), + GET_ITEM(ITEM_BULLET_BAG_40, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BULLET_BAG_40), + GET_ITEM(ITEM_STICKS_5, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, MOD_NONE, GI_STICKS_5), + GET_ITEM(ITEM_STICKS_10, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT, MOD_NONE, GI_STICKS_10), + GET_ITEM(ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, MOD_NONE, GI_NUTS_5_2), + GET_ITEM(ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT, MOD_NONE, GI_NUTS_10), + GET_ITEM(ITEM_BOMB, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBS_1), + GET_ITEM(ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBS_10), + GET_ITEM(ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBS_20), + GET_ITEM(ITEM_BOMBS_30, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBS_30), + GET_ITEM(ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, MOD_NONE, GI_SEEDS_30), + GET_ITEM(ITEM_BOMBCHUS_5, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBCHUS_5), + GET_ITEM(ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_BOMBCHUS_20), + GET_ITEM(ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_FISH), + GET_ITEM(ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BUGS), + GET_ITEM(ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BLUE_FIRE), + GET_ITEM(ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_POE), + GET_ITEM(ITEM_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, 0xF9, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BIG_POE), + GET_ITEM(ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_DOOR_KEY), + GET_ITEM(ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0xF4, 0x00, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_GREEN_LOSE), + GET_ITEM(ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xF5, 0x01, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_BLUE_LOSE), + GET_ITEM(ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF6, 0x02, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_RED_LOSE), + GET_ITEM(ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF7, 0x14, CHEST_ANIM_SHORT, MOD_NONE, GI_RUPEE_PURPLE_LOSE), + GET_ITEM(ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xFA, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_HEART_PIECE_WIN), + GET_ITEM(ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_STICK_UPGRADE_20), + GET_ITEM(ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_STICK_UPGRADE_30), + GET_ITEM(ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_NUT_UPGRADE_30), + GET_ITEM(ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, MOD_NONE, GI_NUT_UPGRADE_40), + GET_ITEM(ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG_50, 0x6C, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BULLET_BAG_50), + GET_ITEM_NONE, + GET_ITEM_NONE, + }; + ItemTableManager::Instance->AddItemTable(MOD_NONE); + for (uint8_t i = 0; i < ARRAY_COUNT(getItemTable); i++) { + // The vanilla item table array started with ITEM_BOMBS_5, + // but the GetItemID enum started with GI_NONE. Then everywhere + // that table was accessed used `GetItemID - 1`. This allows the + // "first" item of the new map to start at 1, syncing it up with + // the GetItemID values and removing the need for the `- 1` + ItemTableManager::Instance->AddItemEntry(MOD_NONE, i+1, getItemTable[i]); + } +} + extern "C" void OTRExtScanner() { auto lst = *OTRGlobals::Instance->context->GetResourceManager()->ListFiles("*.*").get(); @@ -180,6 +321,7 @@ extern "C" void InitOTR() { OTRGlobals::Instance = new OTRGlobals(); SaveManager::Instance = new SaveManager(); CustomMessageManager::Instance = new CustomMessageManager(); + ItemTableManager::Instance = new ItemTableManager(); auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version"); if (!t->bHasLoadError) @@ -198,6 +340,7 @@ extern "C" void InitOTR() { Rando_Init(); InitItemTracker(); OTRExtScanner(); + VanillaItemTable_Init(); } extern "C" void DeinitOTR() { @@ -1401,14 +1544,6 @@ extern "C" void* getN64WeirdFrame(s32 i) { return &weirdFrameBytes[i + sizeof(n64WeirdFrames)]; } -extern "C" s16 Randomizer_GetItemModelFromId(s16 itemId) { - return OTRGlobals::Instance->gRandomizer->GetItemModelFromId(itemId); -} - -extern "C" s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId) { - return OTRGlobals::Instance->gRandomizer->GetItemIDFromGetItemID(getItemId); -} - extern "C" void Randomizer_LoadSettings(const char* spoilerFileName) { OTRGlobals::Instance->gRandomizer->LoadRandomizerSettings(spoilerFileName); } @@ -1468,24 +1603,54 @@ extern "C" CustomMessageEntry Randomizer_GetHintFromCheck(RandomizerCheck check) return hintText; } -extern "C" s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) { - return OTRGlobals::Instance->gRandomizer->GetRandomizedItemId(ogId, actorId, actorParams, sceneNum); +extern "C" GetItemEntry ItemTable_Retrieve(int16_t getItemID) { + GetItemEntry giEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_NONE, getItemID); + return giEntry; } -extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { - return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId); +extern "C" GetItemEntry ItemTable_RetrieveEntry(s16 tableID, s16 getItemID) { + return ItemTableManager::Instance->RetrieveItemEntry(tableID, getItemID); } -extern "C" bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor) { +extern "C" GetItemEntry Randomizer_GetRandomizedItem(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) { + s16 getItemModIndex; + if (OTRGlobals::Instance->gRandomizer->CheckContainsVanillaItem( + OTRGlobals::Instance->gRandomizer->GetCheckFromActor(sceneNum, actorId, actorParams))) { + getItemModIndex = MOD_NONE; + } else { + getItemModIndex = MOD_RANDOMIZER; + } + s16 itemID = OTRGlobals::Instance->gRandomizer->GetRandomizedItemId(ogId, actorId, actorParams, sceneNum); + return ItemTable_RetrieveEntry(getItemModIndex, itemID); +} + +extern "C" GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { + s16 getItemModIndex; + if (OTRGlobals::Instance->gRandomizer->CheckContainsVanillaItem(randomizerCheck)) { + getItemModIndex = MOD_NONE; + } else { + getItemModIndex = MOD_RANDOMIZER; + } + s16 itemID = OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId); + return ItemTable_RetrieveEntry(getItemModIndex, itemID); +} + +extern "C" u32 Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor) { return gSaveContext.n64ddFlag && (actor->parent != NULL) && - Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP; + Randomizer_GetItemFromKnownCheck(randomizerCheck, ogId).getItemId == RG_ICE_TRAP; } -extern "C" bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId) { - return gSaveContext.n64ddFlag && Randomizer_GetItemIdFromKnownCheck(randomizerCheck, ogId) == GI_ICE_TRAP; +extern "C" u32 Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId) { + return gSaveContext.n64ddFlag && Randomizer_GetItemFromKnownCheck(randomizerCheck, ogId).getItemId == RG_ICE_TRAP; } -extern "C" CustomMessageEntry Randomizer_GetCustomGetItemMessage(GetItemID giid, char* buffer, const int maxBufferSize) { +extern "C" CustomMessageEntry Randomizer_GetCustomGetItemMessage(Player* player) { + s16 giid; + if (player->getItemEntry.objectId != OBJECT_INVALID) { + giid = player->getItemEntry.getItemId; + } else { + giid = player->getItemId; + } const CustomMessageEntry getItemText = CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, giid); return getItemText; } @@ -1500,7 +1665,7 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) { messageEntry = - Randomizer_GetCustomGetItemMessage((GetItemID)GET_PLAYER(globalCtx)->getItemId, buffer, maxBufferSize); + Randomizer_GetCustomGetItemMessage(GET_PLAYER(globalCtx)); } else if (textId == TEXT_RANDOMIZER_GOSSIP_STONE_HINTS && Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) != 0 && (Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 1 || (Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 2 && diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index ae8f799b9..069707cd9 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -5,6 +5,7 @@ #include "GlobalCtx2.h" #include "SaveManager.h" +#include #ifdef __cplusplus #include "Enhancements/savestates.h" @@ -20,6 +21,7 @@ public: std::shared_ptr context; std::shared_ptr gSaveStateMgr; std::shared_ptr gRandomizer; + uint16_t getItemModIndex; OTRGlobals(); ~OTRGlobals(); @@ -30,6 +32,7 @@ private: #endif #ifndef __cplusplus +void VanillaItemTable_Init(); void OTRAudio_Init(); void InitAudio(); void Graph_StartFrame(); @@ -95,13 +98,13 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum); void Randomizer_LoadHintLocations(const char* spoilerFileName); void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent); -s16 Randomizer_GetItemModelFromId(s16 itemId); -s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId); -s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); -s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); +GetItemEntry Randomizer_GetRandomizedItem(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); +GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor); bool Randomizer_ItemIsIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId); int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx); +GetItemEntry ItemTable_Retrieve(int16_t getItemID); +GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID); #endif #endif diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index 9921d3050..8e7b21003 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -60,6 +60,7 @@ void OTRGameplay_InitScene(GlobalContext* globalCtx, s32 spawn) { globalCtx->cUpElfMsgs = nullptr; globalCtx->setupPathList = nullptr; globalCtx->numSetupActors = 0; + OTRGlobals::Instance->getItemModIndex = MOD_NONE; Object_InitBank(globalCtx, &globalCtx->objectCtx); LightContext_Init(globalCtx, &globalCtx->lightCtx); TransitionActor_InitContext(&globalCtx->state, &globalCtx->transiActorCtx); diff --git a/soh/src/code/code_800EC960.c b/soh/src/code/code_800EC960.c index 9255049a6..f5f1b980e 100644 --- a/soh/src/code/code_800EC960.c +++ b/soh/src/code/code_800EC960.c @@ -1246,7 +1246,7 @@ void Audio_StepFreqLerp(FreqLerp* lerp); void func_800F56A8(void); void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId); s32 Audio_SetGanonDistVol(u8 targetVol); -void Audio_PlayFanfare_Rando(ItemID getItemId); +void Audio_PlayFanfare_Rando(GetItemEntry getItem); // Right stick as virtual C buttons #define RSTICK_UP 0x100000 @@ -3957,42 +3957,51 @@ void Audio_ResetSfxChannelState(void) { // Function to play "get-item" fanfares according to the type of item obtained (used in rando) // Longer fanfares for medallions/stones/songs are behind the Cvar -void Audio_PlayFanfare_Rando(ItemID getItemId) { +void Audio_PlayFanfare_Rando(GetItemEntry getItem) { s32 temp1; + s16 getItemId = getItem.getItemId; + s16 itemId = getItem.itemId; - if (((getItemId >= GI_RUPEE_GREEN) && (getItemId <= GI_RUPEE_RED)) || - ((getItemId >= GI_RUPEE_PURPLE) && (getItemId <= GI_RUPEE_GOLD)) || - ((getItemId >= GI_RUPEE_GREEN_LOSE) && (getItemId <= GI_RUPEE_PURPLE_LOSE)) || (getItemId == GI_HEART)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - } else { - if ((getItemId == GI_HEART_CONTAINER_2) || (getItemId == GI_HEART_CONTAINER) || - ((getItemId == GI_HEART_PIECE) && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) { - temp1 = NA_BGM_HEART_GET | 0x900; + if (getItem.modIndex == MOD_NONE) { + if (((itemId >= ITEM_RUPEE_GREEN) && (itemId <= ITEM_RUPEE_GOLD)) || (itemId == ITEM_HEART)) { + Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } else { - temp1 = (getItemId == GI_HEART_PIECE) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900; - } - // If we get a skulltula token or the "WINNER" heart, play "get small item" - if (getItemId == GI_SKULL_TOKEN || getItemId == GI_HEART_PIECE_WIN) { - temp1 = NA_BGM_SMALL_ITEM_GET | 0x900; - } - // But if the "WINNER" heart is the 4th heart piece collected, play "get heart container" - if (getItemId == GI_HEART_PIECE_WIN && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000)) { - temp1 = NA_BGM_HEART_GET | 0x900; - } - // If the setting is toggled on and we get special quest items (longer fanfares): - if (CVar_GetS32("gRandoQuestItemFanfares", 0) != 0) { - // If we get a medallion, play the "get a medallion" fanfare - if ((getItemId >= GI_MEDALLION_LIGHT) && (getItemId <= GI_MEDALLION_SPIRIT)) { - temp1 = NA_BGM_MEDALLION_GET | 0x900; + if (itemId == ITEM_HEART_CONTAINER || + ((itemId == ITEM_HEART_PIECE_2) && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) { + temp1 = NA_BGM_HEART_GET | 0x900; + } else { + temp1 = (itemId == ITEM_HEART_PIECE_2) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900; } - // If it's a Spiritual Stone, play the "get a spiritual stone" fanfare - if ((getItemId >= GI_STONE_KOKIRI) && (getItemId <= GI_STONE_ZORA)) { - temp1 = NA_BGM_SPIRITUAL_STONE | 0x900; + // If we get a skulltula token or the "WINNER" heart, play "get small item" + // Also make sure "WINNER" heart is not the 4th heart piece. + if (itemId == ITEM_SKULL_TOKEN || (getItemId == GI_HEART_PIECE_WIN && itemId == ITEM_HEART_PIECE_2 && + (gSaveContext.inventory.questItems & 0xF0000000) != 0x40000000)) { + temp1 = NA_BGM_SMALL_ITEM_GET | 0x900; } - // If the item we're getting is a song, play the "learned a song" fanfare - if ((getItemId >= GI_ZELDAS_LULLABY) && (getItemId <= GI_PRELUDE_OF_LIGHT)) { - temp1 = NA_BGM_OCA_FAIRY_GET | 0x900; + // If the setting is toggled on and we get special quest items (longer fanfares): + if (CVar_GetS32("gRandoQuestItemFanfares", 0) != 0) { + // If we get a medallion, play the "get a medallion" fanfare + if ((itemId >= ITEM_MEDALLION_FOREST) && (itemId <= ITEM_MEDALLION_LIGHT)) { + temp1 = NA_BGM_MEDALLION_GET | 0x900; + } + // If it's a Spiritual Stone, play the "get a spiritual stone" fanfare + if ((itemId >= ITEM_KOKIRI_EMERALD) && (itemId <= ITEM_ZORA_SAPPHIRE)) { + temp1 = NA_BGM_SPIRITUAL_STONE | 0x900; + } + // If the item we're getting is a song, play the "learned a song" fanfare + if ((itemId >= ITEM_SONG_MINUET) && (itemId <= ITEM_SONG_STORMS)) { + temp1 = NA_BGM_OCA_FAIRY_GET | 0x900; + } } + Audio_PlayFanfare(temp1); + } + } else if (getItem.modIndex == MOD_RANDOMIZER) { + if ((itemId >= RG_BOTTLE_WITH_RED_POTION && itemId <= RG_BOTTLE_WITH_BIG_POE) || + (itemId >= RG_DEKU_TREE_MAP && itemId <= RG_GANONS_CASTLE_SMALL_KEY)) { + temp1 = NA_BGM_ITEM_GET | 0x900; + } else { + // Just in case nothing else matches. + temp1 = NA_BGM_ITEM_GET | 0x900; } Audio_PlayFanfare(temp1); } diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 63624999a..055db0e9f 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -1955,14 +1955,25 @@ u32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx) { } } -s32 GiveItemWithoutActor(GlobalContext* globalCtx, s32 getItemId) { +/** + * Uses the given `GetItemEntry` to prepare the player to receive an item via the animation + * where Link holds an item over his head. This function does not require an actor for giving + * the player an item, instead setting the player as their own interactRangeActor and getItemDirection. + * + * \param globalCtx the Global Context + * \param getItemEntry the GetItemEntry for the item you want the player to receive. + * \return true if the player can receive an item, false if not. + */ +s32 GiveItemEntryWithoutActor(GlobalContext* globalCtx, GetItemEntry getItemEntry) { Player* player = GET_PLAYER(globalCtx); if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { - if (((player->heldActor != NULL) && (getItemId > GI_NONE) && (getItemId < GI_MAX)) || + if (((player->heldActor != NULL) && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX)) || + (gSaveContext.n64ddFlag && (getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))) || (!(player->stateFlags1 & 0x20000800))) { - if ((getItemId != GI_NONE)) { - player->getItemId = getItemId; + if ((getItemEntry.getItemId != GI_NONE)) { + player->getItemEntry = getItemEntry; + player->getItemId = getItemEntry.getItemId; player->interactRangeActor = &player->actor; player->getItemDirection = player->actor.shape.rot.y; // Player state 26 = Player is frozen @@ -1977,12 +1988,69 @@ s32 GiveItemWithoutActor(GlobalContext* globalCtx, s32 getItemId) { return false; } +/** + * Uses the given `GetItemEntry` to prepare the player to receive an item via the animation + * where Link holds an item over his head. This uses data from the actor link is receiving + * the item from to set the player's interactRangeActor and getItemDirection. It also checks + * a range from which Link must be from said actor in order to receive the item. + * + * \param actor the actor link is receiving an item from. Will usually be a chest but can also + * be an npc. + * \param globalCtx the Global Context + * \param getItemEntry the GetItemEntry for the item you want the player to receive. + * \param xzRange the distance on the x and z axes that the player can be from the target + * actor to receive the item. + * \param yRange the distance on the y axis that the player can be from the target actor + * to receive the item. + * \return true if the player can receive an item, false if not. + */ +s32 GiveItemEntryFromActor(Actor* actor, GlobalContext* globalCtx, GetItemEntry getItemEntry, f32 xzRange, f32 yRange) { + Player* player = GET_PLAYER(globalCtx); + + if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { + if ((((player->heldActor != NULL) || (actor == player->targetActor)) && + ((!gSaveContext.n64ddFlag && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) || + (gSaveContext.n64ddFlag && ((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) || + (!(player->stateFlags1 & 0x20000800))) { + if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) { + s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y; + s32 absYawDiff = ABS(yawDiff); + + if ((getItemEntry.getItemId != GI_NONE) || (player->getItemDirection < absYawDiff)) { + player->getItemEntry = getItemEntry; + player->getItemId = getItemEntry.getItemId; + player->interactRangeActor = actor; + player->getItemDirection = absYawDiff; + return true; + } + } + } + } + + return false; +} + +/** + * Uses the given `GetItemEntry` to prepare the player to receive an item via the animation + * where Link holds an item over his head. This is a wrapper function around `GiveItemEntryFromActor` + * that supplies a fixed xzRange of 50.0f and a fixed yRange of 10.0f. + * + * \param actor the target actor that link is receiving an item from. + * \param globalCtx the Global Context + * \param getItemEntry the GetItemEntry for the item you want the player to receive. + */ +void GiveItemEntryFromActorWithFixedRange(Actor* actor, GlobalContext* globalCtx, GetItemEntry getItemEntry) { + GiveItemEntryFromActor(actor, globalCtx, getItemEntry, 50.0f, 10.0f); +} + +// TODO: Rename to GiveItemIdFromActor or similar +// If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActor s32 func_8002F434(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzRange, f32 yRange) { Player* player = GET_PLAYER(globalCtx); if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { - if ((((player->heldActor != NULL) || (actor == player->targetActor)) && (getItemId > GI_NONE) && - (getItemId < GI_MAX)) || + if ((((player->heldActor != NULL) || (actor == player->targetActor)) && + ((!gSaveContext.n64ddFlag && ((getItemId > GI_NONE) && (getItemId < GI_MAX))) || (gSaveContext.n64ddFlag && ((getItemId > RG_NONE) && (getItemId < RG_MAX))))) || (!(player->stateFlags1 & 0x20000800))) { if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) { s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y; @@ -2001,6 +2069,8 @@ s32 func_8002F434(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzR return false; } +// TODO: Rename to GiveItemIdFromActorWithFixedRange or similar +// If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActorWithFixedRange void func_8002F554(Actor* actor, GlobalContext* globalCtx, s32 getItemId) { func_8002F434(actor, globalCtx, getItemId, 50.0f, 10.0f); } @@ -5997,7 +6067,7 @@ s32 func_80038290(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar return true; } -s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) { +GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, GlobalContext* globalCtx) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { // RANDOTODO update this logic when we implement keysanity // because 3drando replaces the keys not the rupees @@ -6008,27 +6078,27 @@ s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) switch(room) { case 1: if(!Flags_GetCollectible(globalCtx, 0x1B)) { - return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN); + return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN); } break; case 2: if(!Flags_GetCollectible(globalCtx, 0x1C)) { - return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN); + return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN); } break; case 3: if(!Flags_GetCollectible(globalCtx, 0x1D)) { - return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE); + return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE); } break; case 4: if(!Flags_GetCollectible(globalCtx, 0x1E)) { - return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE); + return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE); } break; case 5: if(!Flags_GetCollectible(globalCtx, 0x1F)) { - return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED); + return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED); } break; } @@ -6036,17 +6106,17 @@ s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) } if(ogDrawId == GID_HEART_PIECE) { - return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE); + return Randomizer_GetItemFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE); } - return GI_NONE; + return (GetItemEntry)GET_ITEM_NONE; } s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) { - s32 randoGetItemId = GetChestGameRandoGetItemId(room, ogDrawId, globalCtx); + GetItemEntry randoGetItem = GetChestGameRandoGetItem(room, ogDrawId, globalCtx); - if(randoGetItemId != GI_NONE) { - return Randomizer_GetItemModelFromId(randoGetItemId); + if (randoGetItem.itemId != RG_NONE) { + return randoGetItem.gid; } return ogDrawId; diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 24d069706..a50c74e87 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -335,6 +335,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { f32 yOffset = 980.0f; f32 shadowScale = 6.0f; s32 getItemId = GI_NONE; + GetItemEntry getItem = (GetItemEntry)GET_ITEM_NONE; s16 spawnParam8000 = this->actor.params & 0x8000; s32 pad1; @@ -508,9 +509,15 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { break; } - if ((gSaveContext.n64ddFlag || getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) { - getItemId = Randomizer_GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); - func_8002F554(&this->actor, globalCtx, getItemId); + if (!Actor_HasParent(&this->actor, globalCtx)) { + if (!gSaveContext.n64ddFlag) { + if (getItemId != GI_NONE) { + func_8002F554(&this->actor, globalCtx, getItemId); + } + } else { + getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem); + } } EnItem00_SetupAction(this, func_8001E5C8); @@ -666,10 +673,15 @@ void func_8001E304(EnItem00* this, GlobalContext* globalCtx) { void func_8001E5C8(EnItem00* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (this->getItemId != GI_NONE) { if (!Actor_HasParent(&this->actor, globalCtx)) { - func_8002F434(&this->actor, globalCtx, this->getItemId, 50.0f, 80.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, this->getItemId, 50.0f, 80.0f); + } else { + GetItemEntry getItemEntry = + Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 50.0f, 80.0f); + } this->unk_15A++; } else { this->getItemId = GI_NONE; @@ -703,6 +715,7 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { s16* params; Actor* dynaActor; s32 getItemId = GI_NONE; + GetItemEntry getItem = (GetItemEntry)GET_ITEM_NONE; s16 sp3A = 0; s16 i; u32* temp; @@ -883,10 +896,13 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { params = &this->actor.params; if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) { - if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + if (!gSaveContext.n64ddFlag) { + func_8002F554(&this->actor, globalCtx, getItemId); + } else { + getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + getItemId = getItem.getItemId; + GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem); } - func_8002F554(&this->actor, globalCtx, getItemId); } switch (*params) { @@ -1214,38 +1230,56 @@ void EnItem00_Draw(Actor* thisx, GlobalContext* globalCtx) { } } -void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, s16 getItemId) { +void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetItemEntry giEntry) { s16 color_slot; - switch (getItemId) { - case GI_MINUET_OF_FOREST: - case GI_SINGLE_MAGIC: - case GI_DOUBLE_MAGIC: - color_slot = 0; + switch (giEntry.modIndex) { + case MOD_NONE: + switch (giEntry.itemId) { + case ITEM_SONG_MINUET: + color_slot = 0; + break; + case ITEM_SONG_BOLERO: + color_slot = 1; + break; + case ITEM_SONG_SERENADE: + color_slot = 2; + break; + case ITEM_SONG_REQUIEM: + color_slot = 3; + break; + case ITEM_SONG_NOCTURNE: + color_slot = 4; + break; + case ITEM_SONG_PRELUDE: + color_slot = 5; + break; + case ITEM_STICK_UPGRADE_20: + case ITEM_STICK_UPGRADE_30: + color_slot = 6; + break; + case ITEM_NUT_UPGRADE_30: + case ITEM_NUT_UPGRADE_40: + color_slot = 7; + break; + default: + return; + } break; - case GI_BOLERO_OF_FIRE: - case GI_DOUBLE_DEFENSE: - color_slot = 1; - break; - case GI_SERENADE_OF_WATER: - color_slot = 2; - break; - case GI_REQUIEM_OF_SPIRIT: - color_slot = 3; - break; - case GI_NOCTURNE_OF_SHADOW: - color_slot = 4; - break; - case GI_PRELUDE_OF_LIGHT: - color_slot = 5; - break; - case GI_STICK_UPGRADE_20: - case GI_STICK_UPGRADE_30: - color_slot = 6; - break; - case GI_NUT_UPGRADE_30: - case GI_NUT_UPGRADE_40: - color_slot = 7; + case MOD_RANDOMIZER: + switch (giEntry.itemId) { + case RG_MAGIC_SINGLE: + case RG_MAGIC_DOUBLE: + color_slot = 0; + break; + case RG_DOUBLE_DEFENSE: + color_slot = 1; + break; + default: + return; + } break; + default: + return; } s16* colors[9][3] = { @@ -1323,12 +1357,10 @@ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { f32 mtxScale = 16.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - s32 randoGetItemId = Randomizer_GetRandomizedItemId(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } - GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); + GetItemEntry randoGetItemEntry = + Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry); + GetItem_Draw(globalCtx, randoGetItemEntry.gid); } else { s32 texIndex = this->actor.params - 3; @@ -1384,12 +1416,10 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { f32 mtxScale = 16.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - s32 randoGetItemId = Randomizer_GetRandomizedItemId(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum); - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } - GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); + GetItemEntry randoGetItemEntry = + Randomizer_GetRandomizedItem(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum); + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry); + GetItem_Draw(globalCtx, randoGetItemEntry.gid); } else { s32 pad; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 100c5102a..215fa3f1b 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1591,70 +1591,6 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { osSyncPrintf("item_get_setting=%d pt=%d z=%x\n", item, slot, gSaveContext.inventory.items[slot]); osSyncPrintf(VT_RST); - if (item == ITEM_SINGLE_MAGIC) { - gSaveContext.magicAcquired = true; - gSaveContext.unk_13F6 = 0x30; - Magic_Fill(globalCtx); - return ITEM_NONE; - } else if (item == ITEM_DOUBLE_MAGIC) { - if (!gSaveContext.magicAcquired) { - gSaveContext.magicAcquired = true; - } - gSaveContext.doubleMagic = true; - gSaveContext.unk_13F6 = 0x60; - gSaveContext.magicLevel = 0; - Magic_Fill(globalCtx); - return ITEM_NONE; - } - - if (item == ITEM_DOUBLE_DEFENSE) { - gSaveContext.doubleDefense = true; - gSaveContext.inventory.defenseHearts = 20; - gSaveContext.healthAccumulator = 0x140; - return ITEM_NONE; - } - - if (item >= ITEM_BOTTLE_WITH_RED_POTION && - item <= ITEM_BOTTLE_WITH_BIG_POE) { - temp = SLOT(ITEM_BOTTLE); - for (i = 0; i < 4; i++) { - if (gSaveContext.inventory.items[temp + i] == ITEM_NONE) { - switch (item) { - case ITEM_BOTTLE_WITH_RED_POTION: - item = ITEM_POTION_RED; - break; - case ITEM_BOTTLE_WITH_GREEN_POTION: - item = ITEM_POTION_GREEN; - break; - case ITEM_BOTTLE_WITH_BLUE_POTION: - item = ITEM_POTION_BLUE; - break; - case ITEM_BOTTLE_WITH_FAIRY: - item = ITEM_FAIRY; - break; - case ITEM_BOTTLE_WITH_FISH: - item = ITEM_FISH; - break; - case ITEM_BOTTLE_WITH_BLUE_FIRE: - item = ITEM_BLUE_FIRE; - break; - case ITEM_BOTTLE_WITH_BUGS: - item = ITEM_BUG; - break; - case ITEM_BOTTLE_WITH_POE: - item = ITEM_POE; - break; - case ITEM_BOTTLE_WITH_BIG_POE: - item = ITEM_BIG_POE; - break; - } - - gSaveContext.inventory.items[temp + i] = item; - return ITEM_NONE; - } - } - } - if ((item >= ITEM_MEDALLION_FOREST) && (item <= ITEM_MEDALLION_LIGHT)) { gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST]; @@ -1758,100 +1694,6 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex]++; return ITEM_NONE; } - } else if ( - (item >= ITEM_GERUDO_FORTRESS_SMALL_KEY && item <= ITEM_GANONS_CASTLE_SMALL_KEY) || - (item >= ITEM_FOREST_TEMPLE_BOSS_KEY && item <= ITEM_GANONS_CASTLE_BOSS_KEY) || - (item >= ITEM_DEKU_TREE_MAP && item <= ITEM_ICE_CAVERN_MAP) || - (item >= ITEM_DEKU_TREE_COMPASS && item <= ITEM_ICE_CAVERN_COMPASS) - ) { - int mapIndex = gSaveContext.mapIndex; - switch (item) { - case ITEM_DEKU_TREE_MAP: - case ITEM_DEKU_TREE_COMPASS: - mapIndex = SCENE_YDAN; - break; - case ITEM_DODONGOS_CAVERN_MAP: - case ITEM_DODONGOS_CAVERN_COMPASS: - mapIndex = SCENE_DDAN; - break; - case ITEM_JABU_JABUS_BELLY_MAP: - case ITEM_JABU_JABUS_BELLY_COMPASS: - mapIndex = SCENE_BDAN; - break; - case ITEM_FOREST_TEMPLE_MAP: - case ITEM_FOREST_TEMPLE_COMPASS: - case ITEM_FOREST_TEMPLE_SMALL_KEY: - case ITEM_FOREST_TEMPLE_BOSS_KEY: - mapIndex = SCENE_BMORI1; - break; - case ITEM_FIRE_TEMPLE_MAP: - case ITEM_FIRE_TEMPLE_COMPASS: - case ITEM_FIRE_TEMPLE_SMALL_KEY: - case ITEM_FIRE_TEMPLE_BOSS_KEY: - mapIndex = SCENE_HIDAN; - break; - case ITEM_WATER_TEMPLE_MAP: - case ITEM_WATER_TEMPLE_COMPASS: - case ITEM_WATER_TEMPLE_SMALL_KEY: - case ITEM_WATER_TEMPLE_BOSS_KEY: - mapIndex = SCENE_MIZUSIN; - break; - case ITEM_SPIRIT_TEMPLE_MAP: - case ITEM_SPIRIT_TEMPLE_COMPASS: - case ITEM_SPIRIT_TEMPLE_SMALL_KEY: - case ITEM_SPIRIT_TEMPLE_BOSS_KEY: - mapIndex = SCENE_JYASINZOU; - break; - case ITEM_SHADOW_TEMPLE_MAP: - case ITEM_SHADOW_TEMPLE_COMPASS: - case ITEM_SHADOW_TEMPLE_SMALL_KEY: - case ITEM_SHADOW_TEMPLE_BOSS_KEY: - mapIndex = SCENE_HAKADAN; - break; - case ITEM_BOTTOM_OF_THE_WELL_MAP: - case ITEM_BOTTOM_OF_THE_WELL_COMPASS: - case ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY: - mapIndex = SCENE_HAKADANCH; - break; - case ITEM_ICE_CAVERN_MAP: - case ITEM_ICE_CAVERN_COMPASS: - mapIndex = SCENE_ICE_DOUKUTO; - break; - case ITEM_GANONS_CASTLE_BOSS_KEY: - mapIndex = SCENE_GANON; - break; - case ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - mapIndex = SCENE_MEN; - break; - case ITEM_GERUDO_FORTRESS_SMALL_KEY: - mapIndex = SCENE_GERUDOWAY; - break; - case ITEM_GANONS_CASTLE_SMALL_KEY: - mapIndex = SCENE_GANONTIKA; - break; - } - - if ((item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY)) { - if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[mapIndex] = 1; - return ITEM_NONE; - } else { - gSaveContext.inventory.dungeonKeys[mapIndex]++; - return ITEM_NONE; - } - } else { - int bitmask; - if ((item >= ITEM_DEKU_TREE_MAP) && (item <= ITEM_ICE_CAVERN_MAP)) { - bitmask = gBitFlags[2]; - } else if ((item >= ITEM_DEKU_TREE_COMPASS) && (item <= ITEM_ICE_CAVERN_COMPASS)) { - bitmask = gBitFlags[1]; - } else { - bitmask = gBitFlags[0]; - } - - gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; - return ITEM_NONE; - } } else if ((item == ITEM_QUIVER_30) || (item == ITEM_BOW)) { if (CUR_UPG_VALUE(UPG_QUIVER) == 0) { Inventory_ChangeUpgrade(UPG_QUIVER, 1); @@ -2313,6 +2155,176 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return temp; } +u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) { + uint16_t item = giEntry.itemId; + uint16_t temp; + uint16_t i; + uint16_t slot; + + slot = SLOT(item); + if (item == RG_MAGIC_SINGLE) { + gSaveContext.magicAcquired = true; + gSaveContext.unk_13F6 = 0x30; + Magic_Fill(globalCtx); + return RG_NONE; + } else if (item == RG_MAGIC_DOUBLE) { + if (!gSaveContext.magicAcquired) { + gSaveContext.magicAcquired = true; + } + gSaveContext.doubleMagic = true; + gSaveContext.unk_13F6 = 0x60; + gSaveContext.magicLevel = 0; + Magic_Fill(globalCtx); + return RG_NONE; + } + + if (item == RG_DOUBLE_DEFENSE) { + gSaveContext.doubleDefense = true; + gSaveContext.inventory.defenseHearts = 20; + gSaveContext.healthAccumulator = 0x140; + return RG_NONE; + } + + if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) { + temp = SLOT(ITEM_BOTTLE); + for (i = 0; i < 4; i++) { + if (gSaveContext.inventory.items[temp + i] == ITEM_NONE) { + switch (item) { + case RG_BOTTLE_WITH_RED_POTION: + item = ITEM_POTION_RED; + break; + case RG_BOTTLE_WITH_GREEN_POTION: + item = ITEM_POTION_GREEN; + break; + case RG_BOTTLE_WITH_BLUE_POTION: + item = ITEM_POTION_BLUE; + break; + case RG_BOTTLE_WITH_FAIRY: + item = ITEM_FAIRY; + break; + case RG_BOTTLE_WITH_FISH: + item = ITEM_FISH; + break; + case RG_BOTTLE_WITH_BLUE_FIRE: + item = ITEM_BLUE_FIRE; + break; + case RG_BOTTLE_WITH_BUGS: + item = ITEM_BUG; + break; + case RG_BOTTLE_WITH_POE: + item = ITEM_POE; + break; + case RG_BOTTLE_WITH_BIG_POE: + item = ITEM_BIG_POE; + break; + } + + gSaveContext.inventory.items[temp + i] = item; + return ITEM_NONE; + } + } + } else if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || + (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || + (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || + (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) { + int mapIndex = gSaveContext.mapIndex; + switch (item) { + case RG_DEKU_TREE_MAP: + case RG_DEKU_TREE_COMPASS: + mapIndex = SCENE_YDAN; + break; + case RG_DODONGOS_CAVERN_MAP: + case RG_DODONGOS_CAVERN_COMPASS: + mapIndex = SCENE_DDAN; + break; + case RG_JABU_JABUS_BELLY_MAP: + case RG_JABU_JABUS_BELLY_COMPASS: + mapIndex = SCENE_BDAN; + break; + case RG_FOREST_TEMPLE_MAP: + case RG_FOREST_TEMPLE_COMPASS: + case RG_FOREST_TEMPLE_SMALL_KEY: + case RG_FOREST_TEMPLE_BOSS_KEY: + mapIndex = SCENE_BMORI1; + break; + case RG_FIRE_TEMPLE_MAP: + case RG_FIRE_TEMPLE_COMPASS: + case RG_FIRE_TEMPLE_SMALL_KEY: + case RG_FIRE_TEMPLE_BOSS_KEY: + mapIndex = SCENE_HIDAN; + break; + case RG_WATER_TEMPLE_MAP: + case RG_WATER_TEMPLE_COMPASS: + case RG_WATER_TEMPLE_SMALL_KEY: + case RG_WATER_TEMPLE_BOSS_KEY: + mapIndex = SCENE_MIZUSIN; + break; + case RG_SPIRIT_TEMPLE_MAP: + case RG_SPIRIT_TEMPLE_COMPASS: + case RG_SPIRIT_TEMPLE_SMALL_KEY: + case RG_SPIRIT_TEMPLE_BOSS_KEY: + mapIndex = SCENE_JYASINZOU; + break; + case RG_SHADOW_TEMPLE_MAP: + case RG_SHADOW_TEMPLE_COMPASS: + case RG_SHADOW_TEMPLE_SMALL_KEY: + case RG_SHADOW_TEMPLE_BOSS_KEY: + mapIndex = SCENE_HAKADAN; + break; + case RG_BOTTOM_OF_THE_WELL_MAP: + case RG_BOTTOM_OF_THE_WELL_COMPASS: + case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: + mapIndex = SCENE_HAKADANCH; + break; + case RG_ICE_CAVERN_MAP: + case RG_ICE_CAVERN_COMPASS: + mapIndex = SCENE_ICE_DOUKUTO; + break; + case RG_GANONS_CASTLE_BOSS_KEY: + mapIndex = SCENE_GANON; + break; + case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + mapIndex = SCENE_MEN; + break; + case RG_GERUDO_FORTRESS_SMALL_KEY: + mapIndex = SCENE_GERUDOWAY; + break; + case RG_GANONS_CASTLE_SMALL_KEY: + mapIndex = SCENE_GANONTIKA; + break; + } + + if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) { + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + return RG_NONE; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + return RG_NONE; + } + } else { + int bitmask; + if ((item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP)) { + bitmask = gBitFlags[2]; + } else if ((item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) { + bitmask = gBitFlags[1]; + } else { + bitmask = gBitFlags[0]; + } + + gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; + return RG_NONE; + } + } + + temp = gSaveContext.inventory.items[slot]; + osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp); + INV_CONTENT(item) = item; + + return temp; +} + + u8 Item_CheckObtainability(u8 item) { s16 i; s16 slot = SLOT(item); @@ -2365,11 +2377,11 @@ u8 Item_CheckObtainability(u8 item) { } else { return ITEM_NONE; } - } else if ( - (item >= ITEM_GERUDO_FORTRESS_SMALL_KEY) && (item <= ITEM_GANONS_CASTLE_SMALL_KEY) || - (item >= ITEM_FOREST_TEMPLE_BOSS_KEY) && (item <= ITEM_GANONS_CASTLE_BOSS_KEY) || - (item >= ITEM_DEKU_TREE_MAP) && (item <= ITEM_ICE_CAVERN_MAP) || - (item >= ITEM_DEKU_TREE_COMPASS) && (item <= ITEM_ICE_CAVERN_COMPASS) + } else if ( gSaveContext.n64ddFlag && + ((item >= RG_GERUDO_FORTRESS_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY) || + (item >= RG_FOREST_TEMPLE_BOSS_KEY) && (item <= RG_GANONS_CASTLE_BOSS_KEY) || + (item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP) || + (item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) ) { return ITEM_NONE; } else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index e3cf2f8e9..eec0ce208 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -201,8 +201,8 @@ void GivePlayerRandoRewardSongOfTime(GlobalContext* globalCtx, RandomizerCheck c if (gSaveContext.entranceIndex == 0x050F && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && !Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME); - GiveItemWithoutActor(globalCtx, getItemId); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); + GiveItemEntryWithoutActor(globalCtx, getItemEntry); player->pendingFlag.flagID = 0x1F; player->pendingFlag.flagType = FLAG_SCENE_TREASURE; } @@ -216,8 +216,8 @@ void GivePlayerRandoRewardNocturne(GlobalContext* globalCtx, RandomizerCheck che gSaveContext.entranceIndex == 0x0195) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && !Flags_GetEventChkInf(0xAA)) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_NOCTURNE_OF_SHADOW); - GiveItemWithoutActor(globalCtx, getItemId); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_NOCTURNE_OF_SHADOW); + GiveItemEntryWithoutActor(globalCtx, getItemEntry); Flags_SetEventChkInf(0xAA); } } @@ -228,8 +228,8 @@ void GivePlayerRandoRewardRequiem(GlobalContext* globalCtx, RandomizerCheck chec if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { if ((gSaveContext.entranceIndex == 0x01E1) && !Flags_GetEventChkInf(0xAC) && player != NULL && !Player_InBlockingCsMode(globalCtx, player)) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME); - GiveItemWithoutActor(globalCtx, getItemId); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); + GiveItemEntryWithoutActor(globalCtx, getItemEntry); Flags_SetEventChkInf(0xAC); } } @@ -242,21 +242,22 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TOKINOMA) && !Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && globalCtx->sceneLoadFlag == 0) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ARROW_LIGHT); - GiveItemWithoutActor(globalCtx, getItemId); - player->pendingFlag.flagID = 0x1E; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; + GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(check, GI_ARROW_LIGHT); + if (player->pendingFlag.flagType == FLAG_NONE && GiveItemEntryWithoutActor(globalCtx, getItem)) { + player->pendingFlag.flagID = 0x1E; + player->pendingFlag.flagType = FLAG_SCENE_TREASURE; + } } } void GivePlayerRandoRewardSariaGift(GlobalContext* globalCtx, RandomizerCheck check) { Player* player = GET_PLAYER(globalCtx); if (gSaveContext.entranceIndex == 0x05E0) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); - if ((!Flags_GetEventChkInf(0xC1) || (player->getItemId == getItemId && getItemId != GI_ICE_TRAP)) && + if ((!Flags_GetEventChkInf(0xC1) || (player->getItemId == getItemEntry.getItemId && getItemEntry.getItemId != GI_ICE_TRAP)) && player != NULL && !Player_InBlockingCsMode(globalCtx, player)) { - GiveItemWithoutActor(globalCtx, getItemId); + GiveItemEntryWithoutActor(globalCtx, getItemEntry); Flags_SetEventChkInf(0xC1); } } diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 5e6677ff2..8d23e42eb 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -2,6 +2,7 @@ #include "vt.h" #include +#include #define NUM_DUNGEONS 8 #define NUM_TRIALS 6 @@ -307,11 +308,11 @@ void GiveLinkDekuNutUpgrade(GetItemID giid) { } void GiveLinkMagic(GetItemID giid) { - if (giid == GI_SINGLE_MAGIC) { + if (giid == RG_MAGIC_SINGLE) { gSaveContext.magicLevel = 1; gSaveContext.magicAcquired = true; gSaveContext.doubleMagic = false; - } else if (giid == GI_DOUBLE_MAGIC) { + } else if (giid == RG_MAGIC_DOUBLE) { gSaveContext.magicLevel = 2; gSaveContext.magicAcquired = true; gSaveContext.doubleMagic = true; @@ -327,40 +328,40 @@ void GiveLinkSong(GetItemID getItemId) { uint32_t bitMask; switch (getItemId) { - case GI_ZELDAS_LULLABY: + case RG_ZELDAS_LULLABY: bitMask = 1 << QUEST_SONG_LULLABY; break; - case GI_SUNS_SONG: + case RG_SUNS_SONG: bitMask = 1 << QUEST_SONG_SUN; break; - case GI_EPONAS_SONG: + case RG_EPONAS_SONG: bitMask = 1 << QUEST_SONG_EPONA; break; - case GI_SONG_OF_STORMS: + case RG_SONG_OF_STORMS: bitMask = 1 << QUEST_SONG_STORMS; break; - case GI_SONG_OF_TIME: + case RG_SONG_OF_TIME: bitMask = 1 << QUEST_SONG_TIME; break; - case GI_SARIAS_SONG: + case RG_SARIAS_SONG: bitMask = 1 << QUEST_SONG_SARIA; break; - case GI_MINUET_OF_FOREST: + case RG_MINUET_OF_FOREST: bitMask = 1 << QUEST_SONG_MINUET; break; - case GI_BOLERO_OF_FIRE: + case RG_BOLERO_OF_FIRE: bitMask = 1 << QUEST_SONG_BOLERO; break; - case GI_SERENADE_OF_WATER: + case RG_SERENADE_OF_WATER: bitMask = 1 << QUEST_SONG_SERENADE; break; - case GI_NOCTURNE_OF_SHADOW: + case RG_NOCTURNE_OF_SHADOW: bitMask = 1 << QUEST_SONG_NOCTURNE; break; - case GI_REQUIEM_OF_SPIRIT: + case RG_REQUIEM_OF_SPIRIT: bitMask = 1 << QUEST_SONG_REQUIEM; break; - case GI_PRELUDE_OF_LIGHT: + case RG_PRELUDE_OF_LIGHT: bitMask = 1 << QUEST_SONG_PRELUDE; break; } @@ -368,43 +369,43 @@ void GiveLinkSong(GetItemID getItemId) { gSaveContext.inventory.questItems |= bitMask; } -void GiveLinkDungeonReward(GetItemID getItemId) { +void GiveLinkDungeonReward(uint16_t getItemId) { s16 item; u8 medallion = 0; switch (getItemId) { - case GI_MEDALLION_FOREST: + case RG_FOREST_MEDALLION: item = ITEM_MEDALLION_FOREST; medallion = 1; break; - case GI_MEDALLION_FIRE: + case RG_FIRE_MEDALLION: item = ITEM_MEDALLION_FIRE; medallion = 1; break; - case GI_MEDALLION_WATER: + case RG_WATER_MEDALLION: item = ITEM_MEDALLION_WATER; medallion = 1; break; - case GI_MEDALLION_SHADOW: + case RG_SHADOW_MEDALLION: item = ITEM_MEDALLION_SHADOW; medallion = 1; break; - case GI_MEDALLION_SPIRIT: + case RG_SPIRIT_MEDALLION: item = ITEM_MEDALLION_SPIRIT; medallion = 1; break; - case GI_MEDALLION_LIGHT: + case RG_LIGHT_MEDALLION: item = ITEM_MEDALLION_LIGHT; medallion = 1; break; - case GI_STONE_KOKIRI: + case RG_KOKIRI_EMERALD: item = ITEM_KOKIRI_EMERALD; break; - case GI_STONE_GORON: + case RG_GORON_RUBY: item = ITEM_GORON_RUBY; break; - case GI_STONE_ZORA: + case RG_ZORA_SAPPHIRE: item = ITEM_ZORA_SAPPHIRE; break; } @@ -420,72 +421,72 @@ void GiveLinkDungeonItem(GetItemID getItemId) { int mapIndex; switch (getItemId) { - case GI_DEKU_TREE_MAP: - case GI_DEKU_TREE_COMPASS: + case RG_DEKU_TREE_MAP: + case RG_DEKU_TREE_COMPASS: mapIndex = SCENE_YDAN; break; - case GI_DODONGOS_CAVERN_MAP: - case GI_DODONGOS_CAVERN_COMPASS: + case RG_DODONGOS_CAVERN_MAP: + case RG_DODONGOS_CAVERN_COMPASS: mapIndex = SCENE_DDAN; break; - case GI_JABU_JABUS_BELLY_MAP: - case GI_JABU_JABUS_BELLY_COMPASS: + case RG_JABU_JABUS_BELLY_MAP: + case RG_JABU_JABUS_BELLY_COMPASS: mapIndex = SCENE_BDAN; break; - case GI_FOREST_TEMPLE_MAP: - case GI_FOREST_TEMPLE_COMPASS: - case GI_FOREST_TEMPLE_SMALL_KEY: - case GI_FOREST_TEMPLE_BOSS_KEY: + case RG_FOREST_TEMPLE_MAP: + case RG_FOREST_TEMPLE_COMPASS: + case RG_FOREST_TEMPLE_SMALL_KEY: + case RG_FOREST_TEMPLE_BOSS_KEY: mapIndex = SCENE_BMORI1; break; - case GI_FIRE_TEMPLE_MAP: - case GI_FIRE_TEMPLE_COMPASS: - case GI_FIRE_TEMPLE_SMALL_KEY: - case GI_FIRE_TEMPLE_BOSS_KEY: + case RG_FIRE_TEMPLE_MAP: + case RG_FIRE_TEMPLE_COMPASS: + case RG_FIRE_TEMPLE_SMALL_KEY: + case RG_FIRE_TEMPLE_BOSS_KEY: mapIndex = SCENE_HIDAN; break; - case GI_WATER_TEMPLE_MAP: - case GI_WATER_TEMPLE_COMPASS: - case GI_WATER_TEMPLE_SMALL_KEY: - case GI_WATER_TEMPLE_BOSS_KEY: + case RG_WATER_TEMPLE_MAP: + case RG_WATER_TEMPLE_COMPASS: + case RG_WATER_TEMPLE_SMALL_KEY: + case RG_WATER_TEMPLE_BOSS_KEY: mapIndex = SCENE_MIZUSIN; break; - case GI_SPIRIT_TEMPLE_MAP: - case GI_SPIRIT_TEMPLE_COMPASS: - case GI_SPIRIT_TEMPLE_SMALL_KEY: - case GI_SPIRIT_TEMPLE_BOSS_KEY: + case RG_SPIRIT_TEMPLE_MAP: + case RG_SPIRIT_TEMPLE_COMPASS: + case RG_SPIRIT_TEMPLE_SMALL_KEY: + case RG_SPIRIT_TEMPLE_BOSS_KEY: mapIndex = SCENE_JYASINZOU; break; - case GI_SHADOW_TEMPLE_MAP: - case GI_SHADOW_TEMPLE_COMPASS: - case GI_SHADOW_TEMPLE_SMALL_KEY: - case GI_SHADOW_TEMPLE_BOSS_KEY: + case RG_SHADOW_TEMPLE_MAP: + case RG_SHADOW_TEMPLE_COMPASS: + case RG_SHADOW_TEMPLE_SMALL_KEY: + case RG_SHADOW_TEMPLE_BOSS_KEY: mapIndex = SCENE_HAKADAN; break; - case GI_BOTTOM_OF_THE_WELL_MAP: - case GI_BOTTOM_OF_THE_WELL_COMPASS: - case GI_BOTTOM_OF_THE_WELL_SMALL_KEY: + case RG_BOTTOM_OF_THE_WELL_MAP: + case RG_BOTTOM_OF_THE_WELL_COMPASS: + case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: mapIndex = SCENE_HAKADANCH; break; - case GI_ICE_CAVERN_MAP: - case GI_ICE_CAVERN_COMPASS: + case RG_ICE_CAVERN_MAP: + case RG_ICE_CAVERN_COMPASS: mapIndex = SCENE_ICE_DOUKUTO; break; - case GI_GANONS_CASTLE_BOSS_KEY: + case RG_GANONS_CASTLE_BOSS_KEY: mapIndex = SCENE_GANON; break; - case GI_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: mapIndex = SCENE_MEN; break; - case GI_GERUDO_FORTRESS_SMALL_KEY: + case RG_GERUDO_FORTRESS_SMALL_KEY: mapIndex = SCENE_GERUDOWAY; break; - case GI_GANONS_CASTLE_SMALL_KEY: + case RG_GANONS_CASTLE_SMALL_KEY: mapIndex = SCENE_GANONTIKA; break; } - if ((getItemId >= GI_GERUDO_FORTRESS_SMALL_KEY) && (getItemId <= GI_GANONS_CASTLE_SMALL_KEY)) { + if ((getItemId >= RG_GERUDO_FORTRESS_SMALL_KEY) && (getItemId <= RG_GANONS_CASTLE_SMALL_KEY)) { if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { gSaveContext.inventory.dungeonKeys[mapIndex] = 1; } else { @@ -493,9 +494,9 @@ void GiveLinkDungeonItem(GetItemID getItemId) { } } else { int bitmask; - if ((getItemId >= GI_DEKU_TREE_MAP) && (getItemId <= GI_ICE_CAVERN_MAP)) { + if ((getItemId >= RG_DEKU_TREE_MAP) && (getItemId <= RG_ICE_CAVERN_MAP)) { bitmask = gBitFlags[2]; - } else if ((getItemId >= GI_DEKU_TREE_COMPASS) && (getItemId <= GI_ICE_CAVERN_COMPASS)) { + } else if ((getItemId >= RG_DEKU_TREE_COMPASS) && (getItemId <= RG_ICE_CAVERN_COMPASS)) { bitmask = gBitFlags[1]; } else { bitmask = gBitFlags[0]; @@ -506,9 +507,9 @@ void GiveLinkDungeonItem(GetItemID getItemId) { } void GiveLinksPocketMedallion() { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE); - GiveLinkDungeonReward(getItemId); + GiveLinkDungeonReward(getItemEntry.getItemId); } /** @@ -795,102 +796,73 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { } if(Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { - s32 giid = Randomizer_GetItemIdFromKnownCheck(RC_SONG_FROM_IMPA, GI_ZELDAS_LULLABY); - - if(giid >= GI_ZELDAS_LULLABY && giid <= GI_PRELUDE_OF_LIGHT) { - GiveLinkSong(giid); - } else if (giid == GI_RUPEE_GREEN || - giid == GI_RUPEE_BLUE || - giid == GI_RUPEE_RED || - giid == GI_RUPEE_PURPLE || - giid == GI_RUPEE_GOLD) { - GiveLinkRupeesByGetItemId(giid); - } else if (giid == GI_BOMBCHUS_10 || - giid == GI_BOMBCHUS_5 || - giid == GI_BOMBCHUS_20) { - GiveLinkBombchus(giid); - } else if (giid == GI_STICKS_1 || - giid == GI_STICKS_5 || - giid == GI_STICKS_10) { - GiveLinkDekuSticksByGetItemId(giid); - } else if (giid == GI_NUTS_5 || - giid == GI_NUTS_10) { - GiveLinkDekuNutsByGetItemId(giid); - } else if (giid == GI_BEAN) { - GiveLinkBeans(); - } else if (giid >= GI_MEDALLION_LIGHT && giid <= GI_STONE_ZORA) { - GiveLinkDungeonReward(giid); - } else if (giid == GI_SWORD_KOKIRI) { - GiveLinkKokiriSword(); - } else if (giid == GI_SWORD_BGS) { - GiveLinkBiggoronSword(); - } else if (giid == GI_SWORD_KNIFE) { - GiveLinkGiantsKnife(); - } else if (giid == GI_SHIELD_DEKU) { - GiveLinkDekuShield(); - } else if (giid == GI_SHIELD_HYLIAN) { - GiveLinkHylianShield(); - } else if (giid == GI_SHIELD_MIRROR) { - GiveLinkMirrorShield(); - } else if (giid == GI_TUNIC_GORON) { - GiveLinkGoronTunic(); - } else if (giid == GI_TUNIC_ZORA) { - GiveLinkZoraTunic(); - } else if (giid == GI_BOOTS_IRON) { - GiveLinkIronBoots(); - } else if (giid == GI_BOOTS_HOVER) { - GiveLinkHoverBoots(); - } else if (giid == GI_SLINGSHOT || - giid == GI_BULLET_BAG_40 || - giid == GI_BULLET_BAG_50) { - GiveLinkBulletBagUpgrade(giid); - } else if (giid == GI_BOW || - giid == GI_QUIVER_40 || - giid == GI_QUIVER_50) { - GiveLinkQuiverUpgrade(giid); - } else if (giid == GI_BOMB_BAG_20 || - giid == GI_BOMB_BAG_30 || - giid == GI_BOMB_BAG_40) { - GiveLinkBombBagUpgrade(giid); - } else if (giid == GI_BRACELET || - giid == GI_GAUNTLETS_SILVER || - giid == GI_GAUNTLETS_GOLD) { - GiveLinkStrengthUpgrade(giid); - } else if (giid == GI_SCALE_SILVER || - giid == GI_SCALE_GOLD) { - GiveLinkScaleUpgrade(giid); - } else if (giid == GI_WALLET_ADULT || - giid == GI_WALLET_GIANT) { - GiveLinkWalletUpgrade(giid); - } else if (giid == GI_STONE_OF_AGONY) { - GiveLinkStoneOfAgony(); - } else if (giid == GI_GERUDO_CARD) { - GiveLinkGerudoCard(); - } else if (giid == GI_HEART_PIECE) { - GiveLinkPieceOfHeart(); - } else if (giid == GI_HEART_CONTAINER) { - GiveLinkHeartContainer(); - } else if (giid == GI_STICK_UPGRADE_20 || - giid == GI_STICK_UPGRADE_30) { - GiveLinkDekuStickUpgrade(giid); - } else if (giid == GI_NUT_UPGRADE_30 || - giid == GI_NUT_UPGRADE_40) { - GiveLinkDekuNutUpgrade(giid); - } else if (giid == GI_SINGLE_MAGIC || - giid == GI_DOUBLE_MAGIC) { - GiveLinkMagic(giid); - } else if (giid == GI_DOUBLE_DEFENSE) { - GiveLinkDoubleDefense(); - } else if ( - (giid >= GI_GERUDO_FORTRESS_SMALL_KEY && giid <= GI_GANONS_CASTLE_SMALL_KEY) || - (giid >= GI_FOREST_TEMPLE_BOSS_KEY && giid <= GI_GANONS_CASTLE_BOSS_KEY) || - (giid >= GI_DEKU_TREE_MAP && giid <= GI_ICE_CAVERN_MAP) || - (giid >= GI_DEKU_TREE_COMPASS && giid <= GI_ICE_CAVERN_COMPASS) - ) { - GiveLinkDungeonItem(giid); - } else { - s32 iid = Randomizer_GetItemIDFromGetItemID(giid); - if (iid != -1) INV_CONTENT(iid) = iid; + GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(RC_SONG_FROM_IMPA, RG_ZELDAS_LULLABY); + s32 giid = getItem.getItemId; + + if (getItem.modIndex == MOD_NONE) { + if(getItem.itemId >= ITEM_KOKIRI_EMERALD && getItem.itemId <= ITEM_MEDALLION_LIGHT) { + GiveLinkDungeonReward(getItem.getItemId); + } else if (giid == GI_RUPEE_GREEN || giid == GI_RUPEE_BLUE || giid == GI_RUPEE_RED || + giid == GI_RUPEE_PURPLE || giid == GI_RUPEE_GOLD) { + GiveLinkRupeesByGetItemId(giid); + } else if (giid == GI_BOMBCHUS_10 || giid == GI_BOMBCHUS_5 || giid == GI_BOMBCHUS_20) { + GiveLinkBombchus(giid); + } else if (giid == GI_STICKS_1 || giid == GI_STICKS_5 || giid == GI_STICKS_10) { + GiveLinkDekuSticksByGetItemId(giid); + } else if (giid == GI_NUTS_5 || giid == GI_NUTS_10) { + GiveLinkDekuNutsByGetItemId(giid); + } else if (giid == GI_BEAN) { + GiveLinkBeans(); + } else if (giid == GI_SWORD_KOKIRI) { + GiveLinkKokiriSword(); + } else if (giid == GI_SWORD_BGS) { + GiveLinkBiggoronSword(); + } else if (giid == GI_SWORD_KNIFE) { + GiveLinkGiantsKnife(); + } else if (giid == GI_SHIELD_DEKU) { + GiveLinkDekuShield(); + } else if (giid == GI_SHIELD_HYLIAN) { + GiveLinkHylianShield(); + } else if (giid == GI_SHIELD_MIRROR) { + GiveLinkMirrorShield(); + } else if (giid == GI_TUNIC_GORON) { + GiveLinkGoronTunic(); + } else if (giid == GI_TUNIC_ZORA) { + GiveLinkZoraTunic(); + } else if (giid == GI_BOOTS_IRON) { + GiveLinkIronBoots(); + } else if (giid == GI_BOOTS_HOVER) { + GiveLinkHoverBoots(); + } else if (giid == GI_SLINGSHOT || giid == GI_BULLET_BAG_40 || giid == GI_BULLET_BAG_50) { + GiveLinkBulletBagUpgrade(giid); + } else if (giid == GI_BOW || giid == GI_QUIVER_40 || giid == GI_QUIVER_50) { + GiveLinkQuiverUpgrade(giid); + } else if (giid == GI_BOMB_BAG_20 || giid == GI_BOMB_BAG_30 || giid == GI_BOMB_BAG_40) { + GiveLinkBombBagUpgrade(giid); + } else if (giid == GI_BRACELET || giid == GI_GAUNTLETS_SILVER || giid == GI_GAUNTLETS_GOLD) { + GiveLinkStrengthUpgrade(giid); + } else if (giid == GI_SCALE_SILVER || giid == GI_SCALE_GOLD) { + GiveLinkScaleUpgrade(giid); + } else if (giid == GI_WALLET_ADULT || giid == GI_WALLET_GIANT) { + GiveLinkWalletUpgrade(giid); + } else if (giid == GI_STONE_OF_AGONY) { + GiveLinkStoneOfAgony(); + } else if (giid == GI_GERUDO_CARD) { + GiveLinkGerudoCard(); + } else if (giid == GI_HEART_PIECE) { + GiveLinkPieceOfHeart(); + } else if (giid == GI_HEART_CONTAINER) { + GiveLinkHeartContainer(); + } else if (giid == GI_STICK_UPGRADE_20 || giid == GI_STICK_UPGRADE_30) { + GiveLinkDekuStickUpgrade(giid); + } else if (giid == GI_NUT_UPGRADE_30 || giid == GI_NUT_UPGRADE_40) { + GiveLinkDekuNutUpgrade(giid); + } else { + s32 iid = getItem.itemId; + if (iid != -1) INV_CONTENT(iid) = iid; + } + } else if (getItem.modIndex == MOD_RANDOMIZER) { + Randomizer_Item_Give(NULL, getItem); } // malon/talon back at ranch diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 0f1713ba8..e04755a34 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -70,14 +70,14 @@ const ActorInit Bg_Dy_Yoseizo_InitVars = { void GivePlayerRandoRewardGreatFairy(BgDyYoseizo* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - GetItemID getItemId = Randomizer_GetRandomizedItemId(GI_NONE, this->actor.id, this->fountainType + 1, globalCtx->sceneNum); + GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(GI_NONE, this->actor.id, this->fountainType + 1, globalCtx->sceneNum); if (this->actor.parent == GET_PLAYER(globalCtx) && !Flags_GetTreasure(globalCtx, this->fountainType + 1) && !Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { Flags_SetTreasure(globalCtx, this->fountainType + 1); Actor_Kill(&this->actor); } else if (!Flags_GetTreasure(globalCtx, this->fountainType + 1)) { - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c index 5e2921729..8d81b41c4 100644 --- a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -2087,8 +2087,8 @@ void DemoEffect_DrawGetItem(Actor* thisx, GlobalContext* globalCtx) { return; } if (gSaveContext.n64ddFlag && globalCtx->sceneNum == SCENE_BDAN) { - GetItemID getItemID = Randomizer_GetItemIdFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); - this->getItem.drawId = Randomizer_GetItemModelFromId(getItemID); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); + this->getItem.drawId = getItemEntry.gid; } func_8002EBCC(thisx, globalCtx, 0); func_8002ED80(thisx, globalCtx, 0); diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index cd49f7558..93007f547 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -899,13 +899,13 @@ void func_80986BF8(DemoIm* this, GlobalContext* globalCtx) { } void GivePlayerRandoRewardImpa(Actor* impa, GlobalContext* globalCtx, RandomizerCheck check) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); if (impa->parent != NULL && impa->parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { Flags_SetTreasure(globalCtx, 0x1F); } else if (!Flags_GetTreasure(globalCtx, 0x1F) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { - func_8002F434(impa, globalCtx, getItemId, 75.0f, 50.0f); + GiveItemEntryFromActor(impa, globalCtx, getItemEntry, 75.0f, 50.0f); } else if (!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { gSaveContext.eventChkInf[5] |= 0x200; globalCtx->sceneLoadFlag = 0x14; diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 291208752..5130f1ca8 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -462,13 +462,13 @@ s32 DoorWarp1_PlayerInRange(DoorWarp1* this, GlobalContext* globalCtx) { } void GivePlayerRandoReward(DoorWarp1* this, Player* player, GlobalContext* globalCtx, u8 ruto, u8 adult) { - GetItemID getItemId = Randomizer_GetRandomizedItemId(GI_NONE, this->actor.id, this->actor.params, globalCtx->sceneNum); + GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(GI_NONE, this->actor.id, this->actor.params, globalCtx->sceneNum); if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { Flags_SetTreasure(globalCtx, 0x1F); } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } else if (!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { if (adult) { OnePointCutscene_Init(globalCtx, 0x25E8, 999, &this->actor, MAIN_CAM); diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index b5c7d8a4a..5debc658e 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -126,11 +126,11 @@ void func_809B0558(EnAni* this, GlobalContext* globalCtx) { } gSaveContext.itemGetInf[1] |= 0x20; } else { - if (gSaveContext.n64ddFlag) { - s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 200.0f); } } } @@ -140,11 +140,11 @@ void func_809B05F0(EnAni* this, GlobalContext* globalCtx) { EnAni_SetupAction(this, func_809B0558); } - if (gSaveContext.n64ddFlag) { - s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 200.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index ee9ce1329..321f76810 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -177,6 +177,7 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) { func_8002DF54(globalCtx, NULL, 7); this->getItemId = sGetItemIds[this->prizeIndex]; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; if ((this->getItemId == GI_BOMB_BAG_30) && (CUR_CAPACITY(UPG_BOMB_BAG) == 30)) { this->getItemId = GI_BOMB_BAG_40; @@ -185,22 +186,27 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { switch (this->prizeIndex) { case EXITEM_BOMB_BAG_BOWLING: - this->getItemId = - Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); + this->getItemId = this->getItemEntry.getItemId; break; case EXITEM_HEART_PIECE_BOWLING: - this->getItemId = - Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); + this->getItemId = this->getItemEntry.getItemId; break; case EXITEM_BOMBCHUS_BOWLING: - this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); + this->getItemId = this->getItemEntry.getItemId; break; } } player->stateFlags1 &= ~0x20000000; this->actor.parent = NULL; - func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 2000.0f, 1000.0f); + } player->stateFlags1 |= 0x20000000; this->actionFunc = EnBomBowlPit_WaitTillPrizeGiven; } @@ -209,7 +215,11 @@ void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, GlobalContext* globalCt if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = EnBomBowlPit_Reset; } else { - func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 2000.0f, 1000.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h index af5d8d3e1..fd7c03be4 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h @@ -33,6 +33,7 @@ typedef struct EnBomBowlPit { /* 0x01D4 */ Vec3f unk_1D4; // camera eye (maxsteps) /* 0x01E0 */ EnExItem* exItem; /* 0x01E4 */ char unk_1E4[0x3520]; + /* */ GetItemEntry getItemEntry; } EnBomBowlPit; // size = 0x3704 #endif diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 533ba593a..3e78982a3 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -70,6 +70,7 @@ static InitChainEntry sInitChain[] = { }; static UNK_TYPE sUnused; +GetItemEntry sItem; void EnBox_SetupAction(EnBox* this, EnBoxActionFunc actionFunc) { this->actionFunc = actionFunc; @@ -445,40 +446,47 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) { func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos); if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f && Player_IsFacingActor(&this->dyna.actor, 0x3000, globalCtx)) { - int32_t item = Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum); + sItem = Randomizer_GetRandomizedItem(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum); + GetItemEntry blueRupee = ItemTable_RetrieveEntry(MOD_NONE, GI_RUPEE_BLUE); // RANDOTODO treasure chest game rando if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) { if((this->dyna.actor.params & 0xF) < 2) { if(Flags_GetCollectible(globalCtx, 0x1B)) { - item = GI_RUPEE_BLUE; + sItem = blueRupee; } } if((this->dyna.actor.params & 0xF) >= 2 && (this->dyna.actor.params & 0xF) < 4) { if(Flags_GetCollectible(globalCtx, 0x1C)) { - item = GI_RUPEE_BLUE; + sItem = blueRupee; } } if((this->dyna.actor.params & 0xF) >= 4 && (this->dyna.actor.params & 0xF) < 6) { if(Flags_GetCollectible(globalCtx, 0x1D)) { - item = GI_RUPEE_BLUE; + sItem = blueRupee; } } if((this->dyna.actor.params & 0xF) >= 6 && (this->dyna.actor.params & 0xF) < 8) { if(Flags_GetCollectible(globalCtx, 0x1E)) { - item = GI_RUPEE_BLUE; + sItem = blueRupee; } } if((this->dyna.actor.params & 0xF) >= 8 && (this->dyna.actor.params & 0xF) < 10) { if(Flags_GetCollectible(globalCtx, 0x1F)) { - item = GI_RUPEE_BLUE; + sItem = blueRupee; } } } } - - func_8002F554(&this->dyna.actor, globalCtx, 0 - item); + // Chests need to have a negative getItemId in order to not immediately give their item + // when approaching. + if (gSaveContext.n64ddFlag) { + sItem.getItemId = 0 - sItem.getItemId; + GiveItemEntryFromActorWithFixedRange(&this->dyna.actor, globalCtx, sItem); + } else { + func_8002F554(&this->dyna.actor, globalCtx, -(this->dyna.actor.params >> 5 & 0x7F)); + } } if (Flags_GetTreasure(globalCtx, this->dyna.actor.params & 0x1F)) { EnBox_SetupAction(this, EnBox_Open); @@ -590,9 +598,7 @@ void EnBox_Update(Actor* thisx, GlobalContext* globalCtx) { } if (((!gSaveContext.n64ddFlag && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) || - (gSaveContext.n64ddFlag && Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, - this->dyna.actor.id, this->dyna.actor.params, - globalCtx->sceneNum) == GI_ICE_TRAP)) && + (gSaveContext.n64ddFlag && ABS(sItem.getItemId) == RG_ICE_TRAP)) && this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) EnBox_SpawnIceSmoke(this, globalCtx); } diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 8e30bea28..3a687f41d 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -343,8 +343,8 @@ bool EnCow_HasBeenMilked(EnCow* this, GlobalContext* globalCtx) { void EnCow_GivePlayerRandomizedItem(EnCow* this, GlobalContext* globalCtx) { if (!EnCow_HasBeenMilked(this, globalCtx)) { CowInfo cowInfo = EnCow_GetInfo(this, globalCtx); - GetItemID itemId = Randomizer_GetItemIdFromKnownCheck(cowInfo.randomizerCheck, GI_MILK); - func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(cowInfo.randomizerCheck, GI_MILK); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 10000.0f, 100.0f); } else { // once we've gotten the rando reward from the cow, // return them to the their default action function diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index 9f43a5f54..1f0d47d7a 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -453,7 +453,12 @@ void func_809EEA00(EnDivingGame* this, GlobalContext* globalCtx) { if ((this->unk_292 == Message_GetState(&globalCtx->msgCtx) && Message_ShouldAdvance(globalCtx))) { Message_CloseTextbox(globalCtx); this->actor.parent = NULL; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_SCALE_SILVER, 90.0f, 10.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 90.0f, 10.0f); + } this->actionFunc = func_809EEA90; } } @@ -463,7 +468,12 @@ void func_809EEA90(EnDivingGame* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = func_809EEAF8; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_SCALE_SILVER, 90.0f, 10.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 90.0f, 10.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index a89d583ae..d3a924356 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -371,7 +371,8 @@ void EnDns_Talk(EnDns* this, GlobalContext* globalCtx) { void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) { if (this->actor.params == 0x9) { if (gSaveContext.n64ddFlag) { - func_8002F434(&this->actor, globalCtx, Randomizer_GetRandomizedItemId(GI_STICK_UPGRADE_30, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f); + GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(GI_STICK_UPGRADE_30, this->actor.id, this->actor.params, globalCtx->sceneNum); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 130.0f, 100.0f); } else if (CUR_UPG_VALUE(UPG_STICKS) < 2) { func_8002F434(&this->actor, globalCtx, GI_STICK_UPGRADE_20, 130.0f, 100.0f); } else { @@ -379,14 +380,20 @@ void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) { } } else if (this->actor.params == 0xA) { if (gSaveContext.n64ddFlag) { - func_8002F434(&this->actor, globalCtx, Randomizer_GetRandomizedItemId(GI_NUT_UPGRADE_40, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f); + GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(GI_NUT_UPGRADE_40, this->actor.id, this->actor.params, globalCtx->sceneNum); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 130.0f, 100.0f); } else if (CUR_UPG_VALUE(UPG_NUTS) < 2) { func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_30, 130.0f, 100.0f); } else { func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_40, 130.0f, 100.0f); } } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetRandomizedItemId(this->dnsItemEntry->getItemId, this->actor.id, this->actor.params, globalCtx->sceneNum) : this->dnsItemEntry->getItemId, 130.0f, 100.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, this->dnsItemEntry->getItemId, 130.0f, 100.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(this->dnsItemEntry->getItemId, this->actor.id, this->actor.params, globalCtx->sceneNum); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 130.0f, 100.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c index 6d3a4accd..c50e1ec77 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c @@ -139,13 +139,15 @@ void EnDntDemo_Judge(EnDntDemo* this, GlobalContext* globalCtx) { switch (Player_GetMask(globalCtx)) { case PLAYER_MASK_SKULL: if (!Flags_GetTreasure(globalCtx, 0x1F)) { - GiveItemWithoutActor(globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30)); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30); + GiveItemEntryWithoutActor(globalCtx, getItemEntry); Flags_SetTreasure(globalCtx, 0x1F); } break; case PLAYER_MASK_TRUTH: if (!Flags_GetTreasure(globalCtx, 0x1E)) { - GiveItemWithoutActor(globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40)); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40); + GiveItemEntryWithoutActor(globalCtx, getItemEntry); Flags_SetTreasure(globalCtx, 0x1E); } break; diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index 97e58b30a..331677c6d 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -94,8 +94,10 @@ void EnDs_GiveOddPotion(EnDs* this, GlobalContext* globalCtx) { } else { u32 itemId = GI_ODD_POTION; if (gSaveContext.n64ddFlag) { - itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 10000.0f, 50.0f); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_ODD_MUSHROOM); + return; } func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f); } @@ -107,8 +109,10 @@ void EnDs_TalkAfterBrewOddPotion(EnDs* this, GlobalContext* globalCtx) { this->actionFunc = EnDs_GiveOddPotion; u32 itemId = GI_ODD_POTION; if (gSaveContext.n64ddFlag) { - itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_ODD_MUSHROOM, GI_ODD_POTION); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 10000.0f, 50.0f); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_ODD_MUSHROOM); + return; } func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f); } diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index e7f9b51aa..b1953bc74 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -548,7 +548,12 @@ void func_809FEC70(EnDu* this, GlobalContext* globalCtx) { EnDu_SetupAction(this, func_809FECE4); } else { f32 xzRange = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET) : GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 29632ebc3..0cbc370af 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -138,8 +138,8 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) { case EXITEM_BOMB_BAG_BOWLING: this->unk_17C = func_8002EBCC; if (gSaveContext.n64ddFlag) { - this->giDrawId = Randomizer_GetItemModelFromId( - Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20)); + this->giDrawId = + Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20).gid; } else { this->giDrawId = GID_BOMB_BAG_30; } @@ -173,8 +173,7 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) { case EXITEM_BOMBCHUS_BOWLING: this->unk_17C = func_8002EBCC; if (gSaveContext.n64ddFlag) { - this->giDrawId = Randomizer_GetItemModelFromId( - Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10)); + this->giDrawId = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10).gid; } else { this->giDrawId = GID_BOMBCHU; } @@ -397,6 +396,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, GlobalContext* globalCtx) { this->actor.world.pos.z += (tmpf3 / tmpf4) * 5.0f; } } else { + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; this->actor.draw = NULL; @@ -404,7 +404,8 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, GlobalContext* globalCtx) { this->actor.parent = NULL; if (gSaveContext.n64ddFlag) { GET_PLAYER(globalCtx)->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11); - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); + getItemId = getItemEntry.getItemId; } else { if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) { getItemId = GI_BULLET_BAG_40; @@ -412,24 +413,28 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, GlobalContext* globalCtx) { getItemId = GI_BULLET_BAG_50; } } - func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); + + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 2000.0f, 1000.0f); + } this->actionFunc = EnExItem_TargetPrizeGive; } } void EnExItem_TargetPrizeGive(EnExItem* this, GlobalContext* globalCtx) { - s32 getItemId; - if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = EnExItem_TargetPrizeFinish; } else { - if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); + if (!gSaveContext.n64ddFlag) { + s32 getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40; + func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); } else { - getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40; + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 2000.0f, 1000.0f); } - func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); } } @@ -506,24 +511,19 @@ void EnExItem_DrawItems(EnExItem* this, GlobalContext* globalCtx) { if (this) {} func_8002ED80(&this->actor, globalCtx, 0); if (gSaveContext.n64ddFlag) { - s32 randoGetItemId; + GetItemEntry randoGetItem; switch (this->type) { case EXITEM_BOMB_BAG_BOWLING: case EXITEM_BOMB_BAG_COUNTER: - randoGetItemId = Randomizer_GetItemIdFromKnownCheck( - RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); + randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); break; case EXITEM_BOMBCHUS_BOWLING: case EXITEM_BOMBCHUS_COUNTER: - randoGetItemId = Randomizer_GetItemIdFromKnownCheck( - RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); + randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); break; } - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); } GetItem_Draw(globalCtx, this->giDrawId); @@ -533,13 +533,10 @@ void EnExItem_DrawHeartPiece(EnExItem* this, GlobalContext* globalCtx) { func_8002ED80(&this->actor, globalCtx, 0); if (gSaveContext.n64ddFlag) { - s32 randoGetItemId = Randomizer_GetItemIdFromKnownCheck( - RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } - GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); + GetItemEntry randoGetItem = + Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); + GetItem_Draw(globalCtx, randoGetItem.gid); } else { GetItem_Draw(globalCtx, GID_HEART_PIECE); } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index 6b39c671f..251edce48 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -602,6 +602,7 @@ void EnFr_Idle(EnFr* this, GlobalContext* globalCtx) { player->actor.world.pos.z = this->actor.world.pos.z; // z = -1220.0f player->currentYaw = player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y; this->reward = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = EnFr_Activate; } else if (EnFr_IsAboveAndWithin30DistXZ(player, this)) { player->unk_6A8 = &this->actor; @@ -837,6 +838,7 @@ s32 EnFr_IsFrogSongComplete(EnFr* this, GlobalContext* globalCtx) { void EnFr_OcarinaMistake(EnFr* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->reward = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; func_80078884(NA_SE_SY_OCARINA_ERROR); Audio_OcaSetInstrument(0); sEnFrPointers.flags = 12; @@ -945,13 +947,15 @@ void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) { songIndex = this->songIndex; this->actionFunc = EnFr_Deactivate; this->reward = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; if ((songIndex >= FROG_ZL) && (songIndex <= FROG_SOT)) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; if (!gSaveContext.n64ddFlag) { this->reward = GI_RUPEE_PURPLE; } else { - this->reward = Randomizer_GetItemIdFromKnownCheck(EnFr_RandomizerCheckFromSongIndex(songIndex), GI_RUPEE_PURPLE); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(EnFr_RandomizerCheckFromSongIndex(songIndex), GI_RUPEE_PURPLE); + this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_BLUE; @@ -962,7 +966,8 @@ void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { this->reward = GI_HEART_PIECE; } else { - this->reward = Randomizer_GetItemIdFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE); + this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_BLUE; @@ -973,7 +978,8 @@ void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { this->reward = GI_HEART_PIECE; } else { - this->reward = Randomizer_GetItemIdFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE); + this->reward = this->getItemEntry.getItemId; } } else { this->reward = GI_RUPEE_PURPLE; @@ -1024,7 +1030,11 @@ void EnFr_Deactivate(EnFr* this, GlobalContext* globalCtx) { this->actionFunc = EnFr_Idle; } else { this->actionFunc = EnFr_GiveReward; - func_8002F434(&this->actor, globalCtx, this->reward, 30.0f, 100.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->reward, 30.0f, 100.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 30.0f, 100.0f); + } } } @@ -1033,12 +1043,16 @@ void EnFr_GiveReward(EnFr* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnFr_SetIdle; } else { - func_8002F434(&this->actor, globalCtx, this->reward, 30.0f, 100.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->reward, 30.0f, 100.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 30.0f, 100.0f); + } } } void EnFr_SetIdle(EnFr* this, GlobalContext* globalCtx) { - if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx) || (gSaveContext.n64ddFlag && this->reward == GI_ICE_TRAP)) { + if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx) || (gSaveContext.n64ddFlag && this->reward == RG_ICE_TRAP)) { this->actionFunc = EnFr_Idle; } } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h index 154aefc17..972c32e49 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.h @@ -73,6 +73,7 @@ typedef struct EnFr { /* 0x03AA */ s16 xyAngleButterfly; // Butterfly Travels along random angles in the x-y plane /* 0x03AC */ Vec3f posButterfly; // Position/Coordinates of the Butterfly /* 0x03B8 */ Vec3f posButterflyLight; // Used in Lights_PointNoGlowSetInfo() + /* */ GetItemEntry getItemEntry; } EnFr; // size = 0x03C4 typedef struct { diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 24676a577..28aa94c0e 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -154,8 +154,8 @@ void GivePlayerRandoRewardSongOfStorms(EnFu* windmillGuy, GlobalContext* globalC Flags_SetTreasure(globalCtx, 0x1F); windmillGuy->actionFunc = func_80A1DBD4; } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_STORMS); - func_8002F434(&windmillGuy->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_STORMS); + GiveItemEntryFromActor(&windmillGuy->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c index 31fe04e90..f2b6c8638 100644 --- a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c +++ b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c @@ -353,7 +353,12 @@ void func_80A2FA50(EnGb* this, GlobalContext* globalCtx) { void func_80A2FB40(EnGb* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(globalCtx)) { - func_8002F434(&this->dyna.actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE) : GI_BOTTLE, 100.0f, 10.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->dyna.actor, globalCtx, GI_BOTTLE, 100.0f, 10.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE); + GiveItemEntryFromActor(&this->dyna.actor, globalCtx, getItemEntry, 100.0f, 10.0f); + } this->actionFunc = func_80A2FBB0; } } @@ -363,7 +368,12 @@ void func_80A2FBB0(EnGb* this, GlobalContext* globalCtx) { this->dyna.actor.parent = NULL; this->actionFunc = func_80A2FC0C; } else { - func_8002F434(&this->dyna.actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE) : GI_BOTTLE, 100.0f, 10.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->dyna.actor, globalCtx, GI_BOTTLE, 100.0f, 10.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE); + GiveItemEntryFromActor(&this->dyna.actor, globalCtx, getItemEntry, 100.0f, 10.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index d34fb977b..407c43100 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -502,6 +502,7 @@ void EnGe1_SetupWait_Archery(EnGe1* this, GlobalContext* globalCtx) { } void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, GlobalContext* globalCtx) { + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; if (Actor_HasParent(&this->actor, globalCtx)) { @@ -533,21 +534,28 @@ void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, GlobalContext* globalCtx) { break; } } else { - getItemId = Randomizer_GetItemIdFromKnownCheck( - RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); + getItemId = getItemEntry.getItemId; } } else { if (!gSaveContext.n64ddFlag) { getItemId = GI_HEART_PIECE; } else { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); + getItemId = getItemEntry.getItemId; } } - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); + + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } void EnGe1_BeginGiveItem_Archery(EnGe1* this, GlobalContext* globalCtx) { + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { @@ -567,18 +575,23 @@ void EnGe1_BeginGiveItem_Archery(EnGe1* this, GlobalContext* globalCtx) { break; } } else { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_GF_HBA_1500_POINTS, - CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); + getItemId = getItemEntry.getItemId; } } else { if (!gSaveContext.n64ddFlag) { getItemId = GI_HEART_PIECE; } else { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); + getItemId = getItemEntry.getItemId; } } - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } void EnGe1_TalkWinPrize_Archery(EnGe1* this, GlobalContext* globalCtx) { diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 5310fc65e..9fc4ce295 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -457,7 +457,12 @@ void EnGe2_WaitTillCardGiven(EnGe2* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnGe2_SetActionAfterTalk; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_GERUDO_CARD, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } @@ -466,7 +471,12 @@ void EnGe2_GiveCard(EnGe2* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->actor.flags &= ~ACTOR_FLAG_16; this->actionFunc = EnGe2_WaitTillCardGiven; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_GERUDO_CARD, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index 556e7c203..261ce49ec 100644 --- a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -142,7 +142,12 @@ void EnGe3_WaitTillCardGiven(EnGe3* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnGe3_Wait; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_GERUDO_CARD, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } @@ -151,7 +156,12 @@ void EnGe3_GiveCard(EnGe3* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->actor.flags &= ~ACTOR_FLAG_16; this->actionFunc = EnGe3_WaitTillCardGiven; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_GERUDO_CARD, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index c51090221..389b1b145 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -947,6 +947,7 @@ void func_80A40B1C(EnGo* this, GlobalContext* globalCtx) { void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) { f32 xzDist; f32 yDist; + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; if (Actor_HasParent(&this->actor, globalCtx)) { @@ -957,21 +958,30 @@ void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) { this->unk_20C = 0; if ((this->actor.params & 0xF0) == 0x90) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { - getItemId = gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS) : GI_SWORD_BGS; + if (!gSaveContext.n64ddFlag) { + getItemId = GI_SWORD_BGS; + } else { + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS); + getItemId = getItemEntry.getItemId; + } this->unk_20C = 1; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { - getItemId = GI_CLAIM_CHECK; if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); + getItemId = getItemEntry.getItemId; Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_EYEDROPS); + } else { + getItemId = GI_CLAIM_CHECK; } } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) { - getItemId = GI_PRESCRIPTION; if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_SWORD_BROKEN); + getItemId = getItemEntry.getItemId; + } else { + getItemId = GI_PRESCRIPTION; } } } @@ -982,7 +992,11 @@ void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) { yDist = fabsf(this->actor.yDistToPlayer) + 1.0f; xzDist = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, globalCtx, getItemId, xzDist, yDist); + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, xzDist, yDist); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, xzDist, yDist); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 97a6fd3a8..175335a0d 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -287,6 +287,13 @@ void EnGo2_GetItem(EnGo2* this, GlobalContext* globalCtx, s32 getItemId) { fabsf(this->actor.yDistToPlayer) + 1.0f); } +void EnGo2_GetItemEntry(EnGo2* this, GlobalContext* globalCtx, GetItemEntry getItemEntry) { + this->getItemId = getItemEntry.getItemId; + this->getItemEntry = getItemEntry; + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, this->actor.xzDistToPlayer + 1.0f, + fabsf(this->actor.yDistToPlayer) + 1.0f); +} + s32 EnGo2_GetDialogState(EnGo2* this, GlobalContext* globalCtx) { s16 dialogState = Message_GetState(&globalCtx->msgCtx); @@ -335,8 +342,6 @@ u16 EnGo2_GetTextIdGoronCityRollingBig(GlobalContext* globalCtx, EnGo2* this) { } s16 EnGo2_GetStateGoronCityRollingBig(GlobalContext* globalCtx, EnGo2* this) { - s32 bombBagUpgrade; - switch (Message_GetState(&globalCtx->msgCtx)) { case TEXT_STATE_CLOSING: return 2; @@ -345,11 +350,10 @@ s16 EnGo2_GetStateGoronCityRollingBig(GlobalContext* globalCtx, EnGo2* this) { if (this->actor.textId == 0x3012) { this->actionFunc = EnGo2_SetupGetItem; if(!gSaveContext.n64ddFlag) { - bombBagUpgrade = CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30; + EnGo2_GetItem(this, globalCtx, CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30); } else { - bombBagUpgrade = Randomizer_GetItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40); + EnGo2_GetItemEntry(this, globalCtx, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40)); } - EnGo2_GetItem(this, globalCtx, bombBagUpgrade); Message_CloseTextbox(globalCtx); gSaveContext.infTable[17] |= 0x4000; return 2; @@ -543,7 +547,7 @@ s16 EnGo2_GetStateGoronCityLink(GlobalContext* globalCtx, EnGo2* this) { } gSaveContext.infTable[16] |= 0x200; - EnGo2_GetItem(this, globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); + EnGo2_GetItemEntry(this, globalCtx, Randomizer_GetItemFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); this->actionFunc = EnGo2_SetupGetItem; Flags_SetTreasure(globalCtx, 0x1F); return 2; @@ -622,7 +626,7 @@ s16 EnGo2_GetStateGoronDmtBiggoron(GlobalContext* globalCtx, EnGo2* this) { return 0; } - EnGo2_GetItem(this, globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS)); + EnGo2_GetItemEntry(this, globalCtx, Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS)); Flags_SetTreasure(globalCtx, 0x1F); } else { EnGo2_GetItem(this, globalCtx, GI_SWORD_BGS); @@ -653,12 +657,14 @@ s16 EnGo2_GetStateGoronDmtBiggoron(GlobalContext* globalCtx, EnGo2* this) { if (Message_ShouldAdvance(globalCtx)) { if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) { if (globalCtx->msgCtx.choiceIndex == 0) { - u32 getItemId = GI_PRESCRIPTION; if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_BROKEN_SWORD, GI_PRESCRIPTION); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_SWORD_BROKEN); + EnGo2_GetItemEntry(this, globalCtx, getItemEntry); + } else { + u32 getItemId = GI_PRESCRIPTION; + EnGo2_GetItem(this, globalCtx, getItemId); } - EnGo2_GetItem(this, globalCtx, getItemId); this->actionFunc = EnGo2_SetupGetItem; return 2; } @@ -1575,6 +1581,7 @@ void EnGo2_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_216 = this->actor.shape.rot.z; this->unk_26E = 1; this->path = Path_GetByIndex(globalCtx, (this->actor.params & 0x3E0) >> 5, 0x1F); + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; switch (this->actor.params & 0x1F) { case GORON_CITY_ENTRANCE: case GORON_CITY_ISLAND: @@ -1814,8 +1821,11 @@ void EnGo2_SetupGetItem(EnGo2* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnGo2_SetGetItem; } else { - func_8002F434(&this->actor, globalCtx, this->getItemId, this->actor.xzDistToPlayer + 1.0f, - fabsf(this->actor.yDistToPlayer) + 1.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->getItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + } } } @@ -1887,12 +1897,14 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, GlobalContext* globalCtx) { this->unk_26E = 2; this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = this->skelAnime.endFrame; - u32 getItemId = GI_CLAIM_CHECK; if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_DMT_TRADE_EYEDROPS, GI_CLAIM_CHECK); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_EYEDROPS); + EnGo2_GetItemEntry(this, globalCtx, getItemEntry); + } else { + u32 getItemId = GI_CLAIM_CHECK; + EnGo2_GetItem(this, globalCtx, getItemId); } - EnGo2_GetItem(this, globalCtx, getItemId); this->actionFunc = EnGo2_SetupGetItem; this->goronState = 0; } diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h index d31eb7678..1618005f9 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.h @@ -104,6 +104,7 @@ typedef struct EnGo2 { /* 0x0598 */ char unk_598[0x02]; /* 0x059A */ s16 camId; /* 0x059C */ s16 unk_59C; + /* */ GetItemEntry getItemEntry; } EnGo2; // size = 0x05A0 #endif diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index b3c008a50..743550697 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -177,12 +177,14 @@ void func_80A6E740(EnHs* this, GlobalContext* globalCtx) { this->actor.parent = NULL; func_80A6E3A0(this, func_80A6E630); } else { - s32 itemId = GI_ODD_MUSHROOM; if (gSaveContext.n64ddFlag) { - itemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_COJIRO); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 10000.0f, 50.0f); + } else { + s32 itemId = GI_ODD_MUSHROOM; + func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f); } - func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f); } this->unk_2A8 |= 1; @@ -193,12 +195,14 @@ void func_80A6E7BC(EnHs* this, GlobalContext* globalCtx) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_80A6E3A0(this, func_80A6E740); - s32 itemId = GI_ODD_MUSHROOM; if (gSaveContext.n64ddFlag) { - itemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_COJIRO, GI_ODD_MUSHROOM); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_COJIRO); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 10000.0f, 50.0f); + } else { + s32 itemId = GI_ODD_MUSHROOM; + func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f); } - func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 50.0f); break; case 1: Message_ContinueTextbox(globalCtx, 0x10B4); diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index af4eb8ef4..5c2340ce7 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -659,7 +659,18 @@ s16 func_80A70058(GlobalContext* globalCtx, Actor* thisx) { gSaveContext.dogParams = 0; break; case 0x709F: - func_80A6F7CC(this, globalCtx, (gSaveContext.infTable[25] & 2) ? GI_RUPEE_BLUE : gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_MARKET_LOST_DOG, GI_HEART_PIECE) : GI_HEART_PIECE); + if (gSaveContext.infTable[25] & 2) { // Already brought the lost dog back + func_80A6F7CC(this, globalCtx, GI_RUPEE_BLUE); + } else { + if (!gSaveContext.n64ddFlag) { + func_80A6F7CC(this, globalCtx, GI_HEART_PIECE); + } else { + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_LOST_DOG, GI_HEART_PIECE); + // The follownig line and last arguments of GiveItemEntryFromActor are copied from func_80A6F7CC + this->unkGetItemId = this->getItemEntry.getItemId; + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + } + } this->actionFunc = func_80A714C4; break; } @@ -883,6 +894,7 @@ void EnHy_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_Kill(&this->actor); } + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = EnHy_InitImpl; } @@ -1050,8 +1062,11 @@ void func_80A714C4(EnHy* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = func_80A71530; } else { - func_8002F434(&this->actor, globalCtx, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, - fabsf(this->actor.yDistToPlayer) + 1.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->unkGetItemId, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, this->actor.xzDistToPlayer + 1.0f, fabsf(this->actor.yDistToPlayer) + 1.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h index f7e66544d..253d8df7d 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.h @@ -59,6 +59,7 @@ typedef struct EnHy { /* 0x0270 */ Vec3s jointTable[16]; /* 0x02D0 */ Vec3s morphTable[16]; /* 0x0330 */ u16 unk_330; + /* */ GetItemEntry getItemEntry; } EnHy; // size = 0x0334 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 2763be734..ff1502e4b 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -1230,12 +1230,14 @@ void func_80A99504(EnKo* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = func_80A99560; } else { - s32 itemId = GI_SAW; if (gSaveContext.n64ddFlag) { - itemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TRADE_ODD_POTION, GI_SAW); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_TRADE_ODD_POTION, GI_SAW); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_ODD_POTION); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 120.0f, 10.0f); + } else { + s32 itemId = GI_SAW; + func_8002F434(&this->actor, globalCtx, itemId, 120.0f, 10.0f); } - func_8002F434(&this->actor, globalCtx, itemId, 120.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 25bc987ab..da73fd634 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -454,6 +454,7 @@ void EnKz_Wait(EnKz* this, GlobalContext* globalCtx) { } void EnKz_SetupGetItem(EnKz* this, GlobalContext* globalCtx) { + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; s32 getItemId; f32 xzRange; f32 yRange; @@ -465,18 +466,24 @@ void EnKz_SetupGetItem(EnKz* this, GlobalContext* globalCtx) { } else { if (gSaveContext.n64ddFlag) { if (this->isTrading) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG); + getItemId = getItemEntry.getItemId; Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_PRESCRIPTION); Flags_SetTreasure(globalCtx, 0x1F); } else { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA); + getItemId = getItemEntry.getItemId; } } else { getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; } yRange = fabsf(this->actor.yDistToPlayer) + 1.0f; xzRange = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, globalCtx, getItemId, xzRange, yRange); + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, xzRange, yRange); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, xzRange, yRange); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index b0ff90eac..88c5b0724 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -338,11 +338,11 @@ void func_80AA0EA0(EnMa1* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = func_80AA0EFC; } else { - if (gSaveContext.n64ddFlag) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_HC_MALON_EGG, GI_WEIRD_EGG); - func_8002F434(&this->actor, globalCtx, getItemId, 120.0f, 10.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_WEIRD_EGG, 120.0f, 10.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, GI_WEIRD_EGG); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 120.0f, 10.0f); } } } @@ -357,7 +357,7 @@ void func_80AA0EFC(EnMa1* this, GlobalContext* globalCtx) { } void GivePlayerRandoRewardMalon(EnMa1* malon, GlobalContext* globalCtx, RandomizerCheck check) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_EPONAS_SONG); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_EPONAS_SONG); // Prevents flag from getting set if we weren't able to get the item (i.e. Player is holding shield // when closing the textbox). if (malon->actor.parent != NULL && malon->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && @@ -367,7 +367,7 @@ void GivePlayerRandoRewardMalon(EnMa1* malon, GlobalContext* globalCtx, Randomiz // (confirmed via breakpoints in a vanilla save). malon->actionFunc = func_80AA0D88; } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { - func_8002F434(&malon->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GiveItemEntryFromActor(&malon->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } // make malon sing again after giving the item. malon->unk_1E8.unk_00 = 0; diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index dd853ac06..db22509e6 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -99,24 +99,28 @@ void func_80AACA94(EnMk* this, GlobalContext* globalCtx) { gSaveContext.eventInf[1] &= ~1; } } else { - s32 getItemID = GI_EYEDROPS; if (gSaveContext.n64ddFlag) { - getItemID = Randomizer_GetItemIdFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_FROG); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } else { + s32 getItemID = GI_EYEDROPS; + func_8002F434(&this->actor, globalCtx, getItemID, 10000.0f, 50.0f); } - func_8002F434(&this->actor, globalCtx, getItemID, 10000.0f, 50.0f); } } void func_80AACB14(EnMk* this, GlobalContext* globalCtx) { if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actionFunc = func_80AACA94; - s32 getItemID = GI_EYEDROPS; if (gSaveContext.n64ddFlag) { - getItemID = Randomizer_GetItemIdFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_TRADE_FROG, GI_EYEDROPS); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_FROG); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } else { + s32 getItemID = GI_EYEDROPS; + func_8002F434(&this->actor, globalCtx, getItemID, 10000.0f, 50.0f); } - func_8002F434(&this->actor, globalCtx, getItemID, 10000.0f, 50.0f); } } @@ -211,14 +215,24 @@ void func_80AACFA0(EnMk* this, GlobalContext* globalCtx) { gSaveContext.itemGetInf[1] |= 1; } else { // not sure when/how/if this is getting called - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE) : GI_HEART_PIECE, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } void func_80AAD014(EnMk* this, GlobalContext* globalCtx) { if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actionFunc = func_80AACFA0; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE) : GI_HEART_PIECE, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } this->flags |= 1; diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 23584cc19..eeaff6c33 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -89,6 +89,7 @@ void EnNiwLady_Init(Actor* thisx, GlobalContext* globalCtx) { osSyncPrintf("\n\n"); this->actionFunc = func_80AB9F24; thisx->uncullZoneForward = 600.0f; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; } void EnNiwLady_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -305,12 +306,12 @@ void func_80ABA654(EnNiwLady* this, GlobalContext* globalCtx) { if (!(gSaveContext.itemGetInf[0] & 0x1000)) { this->actor.parent = NULL; - if (gSaveContext.n64ddFlag) { - s32 itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_CHILD, GI_BOTTLE); - func_8002F434(&this->actor, globalCtx, itemId, 100.0f, 50.0f); - } else { + if (!gSaveContext.n64ddFlag) { this->getItemId = GI_BOTTLE; func_8002F434(&this->actor, globalCtx, GI_BOTTLE, 100.0f, 50.0f); + } else { + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_CHILD, GI_BOTTLE); + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 100.0f, 50.0f); } this->actionFunc = func_80ABAC00; @@ -395,11 +396,12 @@ void func_80ABA9B8(EnNiwLady* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->actor.parent = NULL; - if (gSaveContext.n64ddFlag) { - s32 itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); - func_8002F434(&this->actor, globalCtx, itemId, 200.0f, 100.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_POCKET_EGG, 200.0f, 100.0f); + } else { + // TODO: get-item-rework Adult trade sequence + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 200.0f, 100.0f); } this->actionFunc = func_80ABAC00; @@ -457,14 +459,19 @@ void func_80ABAC00(EnNiwLady* this, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { if (getItemId == GI_POCKET_EGG) { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); + // TODO: get-item-rework Adult trade sequence + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 200.0f, 100.0f); } else { - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_TRADE_POCKET_CUCCO, GI_COJIRO); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_TRADE_POCKET_CUCCO, GI_COJIRO); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_POCKET_CUCCO); + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 200.0f, 100.0f); } } } - func_8002F434(&this->actor, globalCtx, getItemId, 200.0f, 100.0f); + if (this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, 200.0f, 100.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h index 57ba86f2d..5fe9684f4 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h @@ -40,6 +40,7 @@ typedef struct EnNiwLady { /* 0x0284 */ s32 getItemId; /* 0x0288 */ struct_80034A14_arg1 unk_288; /* 0x02B0 */ ColliderCylinder collider; + /* 0x02FC */ GetItemEntry getItemEntry; } EnNiwLady; // size = 0x02FC #endif diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 56bd79e7b..978d61da7 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -324,8 +324,8 @@ void func_80ABF708(EnOkarinaTag* this, GlobalContext* globalCtx) { void GivePlayerRandoRewardSunSong(EnOkarinaTag* song, GlobalContext* globalCtx, RandomizerCheck check) { Flags_SetTreasure(globalCtx, 0x1F); - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_LETTER_ZELDA); - func_8002F434(&song->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, GI_LETTER_ZELDA); + GiveItemEntryFromActor(&song->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } void func_80ABF7CC(EnOkarinaTag* this, GlobalContext* globalCtx) { diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index c6dd38acc..6d9c160a8 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -618,14 +618,12 @@ void func_80AF67D0(EnSa* this, GlobalContext* globalCtx) { } void GivePlayerRandoRewardSaria(EnSa* saria, GlobalContext* globalCtx, RandomizerCheck check) { - GetItemID getItemId = - Randomizer_GetItemIdFromKnownCheck(check, GI_SARIAS_SONG); - + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SARIAS_SONG); if (saria->actor.parent != NULL && saria->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { Flags_SetTreasure(globalCtx, 0x1F); } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { - func_8002F434(&saria->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GiveItemEntryFromActor(&saria->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c index 73a29bf0b..a9c3cb258 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -17,10 +17,12 @@ s32 func_80AFB748(EnSi* this, GlobalContext* globalCtx); void func_80AFB768(EnSi* this, GlobalContext* globalCtx); void func_80AFB89C(EnSi* this, GlobalContext* globalCtx); void func_80AFB950(EnSi* this, GlobalContext* globalCtx); +void Randomizer_GrantSkullReward(EnSi* this, GlobalContext* globalCtx); s32 textId = 0xB4; s32 giveItemId = ITEM_SKULL_TOKEN; s32 getItemId; +GetItemEntry getItem; static ColliderCylinderInit sCylinderInit = { { @@ -98,30 +100,21 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx) { if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetRandomizedItemId(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum); - if (getItemId == GI_ICE_TRAP) { - player->getItemId = GI_ICE_TRAP; - player->pendingIceTrap = true; - textId = 0xF8; - } else { - textId = sGetItemTable[getItemId - 1].textId; - giveItemId = sGetItemTable[getItemId - 1].itemId; - Item_Give(globalCtx, giveItemId); - } - player->getItemId = getItemId; + Randomizer_GrantSkullReward(this, globalCtx); } else { Item_Give(globalCtx, giveItemId); } - if ((CVar_GetS32("gSkulltulaFreeze", 0) != 1 || giveItemId != ITEM_SKULL_TOKEN) && getItemId != GI_ICE_TRAP) { + if ((CVar_GetS32("gSkulltulaFreeze", 0) != 1 || giveItemId != ITEM_SKULL_TOKEN) && getItemId != RG_ICE_TRAP) { player->actor.freezeTimer = 20; } Message_StartTextbox(globalCtx, textId, NULL); - if (gSaveContext.n64ddFlag) { - Audio_PlayFanfare_Rando(getItemId); + if (gSaveContext.n64ddFlag && getItemId != RG_ICE_TRAP) { + Audio_PlayFanfare_Rando(getItem); } else { Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); } + player->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = func_80AFB950; } else { Collider_UpdateCylinder(&this->actor, &this->collider); @@ -134,33 +127,23 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx) { void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Math_SmoothStepToF(&this->actor.scale.x, 0.25f, 0.4f, 1.0f, 0.0f); Actor_SetScale(&this->actor, this->actor.scale.x); this->actor.shape.rot.y += 0x400; if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_13)) { if (gSaveContext.n64ddFlag) { - getItemId = Randomizer_GetRandomizedItemId(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum); - if (getItemId == GI_ICE_TRAP) { - player->getItemId = GI_ICE_TRAP; - player->pendingIceTrap = true; - textId = 0xF8; - } else { - textId = sGetItemTable[getItemId - 1].textId; - giveItemId = sGetItemTable[getItemId - 1].itemId; - Item_Give(globalCtx, giveItemId); - } - player->getItemId = getItemId; + Randomizer_GrantSkullReward(this, globalCtx); } else { Item_Give(globalCtx, giveItemId); } Message_StartTextbox(globalCtx, textId, NULL); - if (gSaveContext.n64ddFlag) { - Audio_PlayFanfare_Rando(getItemId); + if (gSaveContext.n64ddFlag && getItemId != RG_ICE_TRAP) { + Audio_PlayFanfare_Rando(getItem); } else { Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET); } + player->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->actionFunc = func_80AFB950; } } @@ -169,7 +152,7 @@ void func_80AFB950(EnSi* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING && - ((CVar_GetS32("gSkulltulaFreeze", 0) != 1 || giveItemId != ITEM_SKULL_TOKEN) && getItemId != GI_ICE_TRAP)) { + ((CVar_GetS32("gSkulltulaFreeze", 0) != 1 || giveItemId != ITEM_SKULL_TOKEN) && getItemId != RG_ICE_TRAP)) { player->actor.freezeTimer = 10; } else { SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF); @@ -195,16 +178,35 @@ void EnSi_Draw(Actor* thisx, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { GetItem_Draw(globalCtx, GID_SKULL_TOKEN_2); } else { - getItemId = Randomizer_GetRandomizedItemId(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum); - if (getItemId >= GI_MINUET_OF_FOREST && getItemId <= GI_DOUBLE_DEFENSE) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, getItemId); - } - if (getItemId != ITEM_SKULL_TOKEN) { + getItem = Randomizer_GetRandomizedItem(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum); + EnItem00_CustomItemsParticles(&this->actor, globalCtx, getItem); + if (getItem.itemId != ITEM_SKULL_TOKEN) { f32 mtxScale = 1.5f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); } - GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(getItemId)); + GetItem_Draw(globalCtx, getItem.gid); } } } + +void Randomizer_GrantSkullReward(EnSi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + getItem = Randomizer_GetRandomizedItem(GI_SKULL_TOKEN, this->actor.id, this->actor.params, globalCtx->sceneNum); + getItemId = getItem.getItemId; + if (getItemId == RG_ICE_TRAP) { + player->pendingIceTrap = true; + textId = 0xF8; + } else { + textId = getItem.textId; + giveItemId = getItem.itemId; + if (getItem.modIndex == MOD_NONE) { + Item_Give(globalCtx, giveItemId); + } else if (getItem.modIndex == MOD_RANDOMIZER) { + Randomizer_Item_Give(globalCtx, getItem); + } + } + // player->getItemId = getItemId; + player->getItemEntry = getItem; +} diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index 8929e6362..cded4c801 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -1035,8 +1035,12 @@ void EnSkj_SariaSongTalk(EnSkj* this, GlobalContext* globalCtx) { EnSkj_SetupWaitInRange(this); } else { func_80AFFE24(this); - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE) : GI_HEART_PIECE, EnSkj_GetItemXzRange(this), - EnSkj_GetItemYRange(this)); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + } } } } @@ -1050,7 +1054,12 @@ void func_80AFFE44(EnSkj* this, GlobalContext* globalCtx) { this->actor.parent = NULL; EnSkj_SetupPostSariasSong(this); } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE) : GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + } } } @@ -1527,11 +1536,12 @@ void EnSkj_WonOcarinaMiniGame(EnSkj* this, GlobalContext* globalCtx) { void EnSkj_WaitToGiveReward(EnSkj* this, GlobalContext* globalCtx) { if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) { - func_8002F434(&this->actor, globalCtx, - gSaveContext.n64ddFlag && gSaveContext.ocarinaGameRoundNum != 3 - ? Randomizer_GetItemIdFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE) - : sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], - 26.0f, 26.0f); + if (gSaveContext.n64ddFlag && gSaveContext.ocarinaGameRoundNum != 3) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 26.0f, 26.0f); + } else { + func_8002F434(&this->actor, globalCtx, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); + } this->actionFunc = EnSkj_GiveOcarinaGameReward; } @@ -1542,11 +1552,12 @@ void EnSkj_GiveOcarinaGameReward(EnSkj* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnSkj_FinishOcarinaGameRound; } else { - func_8002F434(&this->actor, globalCtx, - gSaveContext.n64ddFlag && gSaveContext.ocarinaGameRoundNum != 3 - ? Randomizer_GetItemIdFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE) - : sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], - 26.0f, 26.0f); + if (gSaveContext.n64ddFlag && gSaveContext.ocarinaGameRoundNum != 3) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 26.0f, 26.0f); + } else { + func_8002F434(&this->actor, globalCtx, sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index b01c6b8c4..bfaf4188f 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -239,27 +239,29 @@ void EnSth_ParentRewardObtainedWait(EnSth* this, GlobalContext* globalCtx) { void EnSth_GivePlayerItem(EnSth* this, GlobalContext* globalCtx) { u16 getItemId = sGetItemIds[this->actor.params]; + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; if (gSaveContext.n64ddFlag) { switch (getItemId) { case GI_RUPEE_GOLD: break; case GI_WALLET_ADULT: - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_10_GOLD_SKULLTULA_REWARD, GI_WALLET_ADULT); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_10_GOLD_SKULLTULA_REWARD, GI_WALLET_ADULT); break; case GI_STONE_OF_AGONY: - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_20_GOLD_SKULLTULA_REWARD, GI_STONE_OF_AGONY); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_20_GOLD_SKULLTULA_REWARD, GI_STONE_OF_AGONY); break; case GI_WALLET_GIANT: - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_30_GOLD_SKULLTULA_REWARD, GI_WALLET_GIANT); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_30_GOLD_SKULLTULA_REWARD, GI_WALLET_GIANT); break; case GI_BOMBCHUS_10: - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_40_GOLD_SKULLTULA_REWARD, GI_BOMBCHUS_10); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_40_GOLD_SKULLTULA_REWARD, GI_BOMBCHUS_10); break; case GI_HEART_PIECE: - getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_50_GOLD_SKULLTULA_REWARD, GI_HEART_PIECE); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_50_GOLD_SKULLTULA_REWARD, GI_HEART_PIECE); break; } + getItemId = getItemEntry.getItemId; } else { switch (this->actor.params) { case 1: @@ -277,7 +279,11 @@ void EnSth_GivePlayerItem(EnSth* this, GlobalContext* globalCtx) { } } - func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } void EnSth_GiveReward(EnSth* this, GlobalContext* globalCtx) { diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index 7b57bea89..a6ddb5844 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -169,6 +169,7 @@ void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx) { this->blinkFunc = EnSyatekiMan_BlinkWait; this->actor.colChkInfo.cylRadius = 100; this->actionFunc = EnSyatekiMan_Start; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; } void EnSyatekiMan_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -336,7 +337,8 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx) { this->actor.parent = NULL; if (!LINK_IS_ADULT) { if(gSaveContext.n64ddFlag && !Flags_GetTreasure(globalCtx, 0x1E)) { - this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_MARKET_SHOOTING_GALLERY_REWARD, GI_BULLET_BAG_50); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_SHOOTING_GALLERY_REWARD, GI_BULLET_BAG_50); + this->getItemId = this->getItemEntry.getItemId; Flags_SetTreasure(globalCtx, 0x1E); } else if (!gSaveContext.n64ddFlag && !(gSaveContext.itemGetInf[0] & 0x2000)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Pachinko ☆☆☆☆☆ %d\n" VT_RST, @@ -351,7 +353,8 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx) { } } else { if(gSaveContext.n64ddFlag && !Flags_GetTreasure(globalCtx, 0x1F)) { - this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_SHOOTING_GALLERY_REWARD, GI_QUIVER_50); + this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_SHOOTING_GALLERY_REWARD, GI_QUIVER_50); + this->getItemId = this->getItemEntry.getItemId; Flags_SetTreasure(globalCtx, 0x1F); } else if (!gSaveContext.n64ddFlag && !(gSaveContext.itemGetInf[0] & 0x4000)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Bow ☆☆☆☆☆ %d\n" VT_RST, @@ -371,7 +374,11 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx) { this->getItemId = GI_RUPEE_PURPLE; } } - func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 2000.0f, 1000.0f); + } this->actionFunc = EnSyatekiMan_GivePrize; break; case SYATEKI_RESULT_ALMOST: @@ -400,7 +407,11 @@ void EnSyatekiMan_GivePrize(EnSyatekiMan* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = EnSyatekiMan_FinishPrize; } else { - func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + if (!gSaveContext.n64ddFlag || this->getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, this->getItemEntry, 2000.0f, 1000.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h index d82cdf9c7..9caa7c88f 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h @@ -28,6 +28,7 @@ typedef struct EnSyatekiMan { /* 0x0220 */ Actor* tempGallery; /* 0x0224 */ EnSyatekiManOtherFunc blinkFunc; // Seems to be part of a blink system with unk_20C and unk_20E, but it's unused. /* 0x0228 */ s16 csCam; + /* */ GetItemEntry getItemEntry; } EnSyatekiMan; // size = 0x022C #endif diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index 85e47a7e7..b7b964272 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -876,7 +876,12 @@ void func_80B15E80(EnTa* this, GlobalContext* globalCtx) { } else if (this->unk_2E0 & 2) { func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 50.0f); } else { - func_8002F434(&this->actor, globalCtx, GI_MILK_BOTTLE, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_MILK_BOTTLE, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } this->unk_2E0 |= 1; } @@ -886,7 +891,12 @@ void func_80B15F54(EnTa* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->unk_2E0 &= ~0x2; func_80B13AA0(this, func_80B15E80, func_80B16938); - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE) : GI_MILK_BOTTLE, 10000.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_MILK_BOTTLE, 10000.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 10000.0f, 50.0f); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index c6ca4cad7..af994bbf3 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -314,12 +314,14 @@ void func_80B20768(EnToryo* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->unk_1E4 = 5; } else { - s32 itemId = GI_SWORD_BROKEN; if (gSaveContext.n64ddFlag) { - itemId = Randomizer_GetItemIdFromKnownCheck(RC_GV_TRADE_SAW, GI_SWORD_BROKEN); + GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GV_TRADE_SAW, GI_SWORD_BROKEN); Randomizer_ConsumeAdultTradeItem(globalCtx, ITEM_SAW); + GiveItemEntryFromActor(&this->actor, globalCtx, itemEntry, 100.0f, 10.0f); + } else { + s32 itemId = GI_SWORD_BROKEN; + func_8002F434(&this->actor, globalCtx, itemId, 100.0f, 10.0f); } - func_8002F434(&this->actor, globalCtx, itemId, 100.0f, 10.0f); } return; } diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index d9f96e177..30ab5d06e 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -289,18 +289,18 @@ void func_80B3CA38(EnXc* this, GlobalContext* globalCtx) { void GivePlayerRandoRewardSheikSong(EnXc* sheik, GlobalContext* globalCtx, RandomizerCheck check, int sheikType, GetItemID ogSongId) { Player* player = GET_PLAYER(globalCtx); - if (sheik->actor.parent != NULL && sheik->actor.parent->id == player->actor.id && - !(gSaveContext.eventChkInf[5] & sheikType)) { - gSaveContext.eventChkInf[5] |= sheikType; - } else if (!(gSaveContext.eventChkInf[5] & sheikType)) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, ogSongId); + if (!(gSaveContext.eventChkInf[5] & sheikType)) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, ogSongId); if (check == RC_SHEIK_AT_TEMPLE && !Flags_GetTreasure(globalCtx, 0x1F)) { - if (func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f)) { + if (GiveItemEntryFromActor(&sheik->actor, globalCtx, getItemEntry, 10000.0f, 100.0f)) { player->pendingFlag.flagID = 0x1F; player->pendingFlag.flagType = FLAG_SCENE_TREASURE; } } else if (check != RC_SHEIK_AT_TEMPLE) { - func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f); + if (GiveItemEntryFromActor(&sheik->actor, globalCtx, getItemEntry, 10000.0f, 100.0f)) { + player->pendingFlag.flagID = (0x5 << 4) | (sheikType & 0xF) >> 1; + player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; + } } } } @@ -318,7 +318,7 @@ s32 EnXc_MinuetCS(EnXc* this, GlobalContext* globalCtx) { gSaveContext.eventChkInf[5] |= 1; Item_Give(globalCtx, ITEM_SONG_MINUET); } else { - GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_IN_FOREST, 1, GI_MINUET_OF_FOREST); + GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_IN_FOREST, 1, RG_MINUET_OF_FOREST); return false; } return true; @@ -354,7 +354,7 @@ s32 EnXc_BoleroCS(EnXc* this, GlobalContext* globalCtx) { gSaveContext.eventChkInf[5] |= 2; Item_Give(globalCtx, ITEM_SONG_BOLERO); } else { - GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_IN_CRATER, 2, GI_BOLERO_OF_FIRE); + GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_IN_CRATER, 2, RG_BOLERO_OF_FIRE); return false; } return true; @@ -395,7 +395,7 @@ s32 EnXc_SerenadeCS(EnXc* this, GlobalContext* globalCtx) { gSaveContext.eventChkInf[5] |= 4; // Learned Serenade of Water Flag Item_Give(globalCtx, ITEM_SONG_SERENADE); } else { - GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_IN_ICE_CAVERN, 4, GI_SERENADE_OF_WATER); + GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_IN_ICE_CAVERN, 4, RG_SERENADE_OF_WATER); return false; } osSyncPrintf("ブーツを取った!!!!!!!!!!!!!!!!!!\n"); @@ -2206,7 +2206,7 @@ void EnXc_InitTempleOfTime(EnXc* this, GlobalContext* globalCtx) { gSaveContext.cutsceneTrigger = 1; this->action = SHEIK_ACTION_30; } else { - GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_AT_TEMPLE, 0x20, GI_PRELUDE_OF_LIGHT); + GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_AT_TEMPLE, 0x20, RG_PRELUDE_OF_LIGHT); } } else if (!(gSaveContext.eventChkInf[5] & 0x20)) { func_80B3C9EC(this); @@ -2348,7 +2348,7 @@ void EnXc_Update(Actor* thisx, GlobalContext* globalCtx) { if (this->actor.params == SHEIK_TYPE_9) { if (gSaveContext.n64ddFlag && LINK_IS_ADULT) { if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && !(gSaveContext.eventChkInf[5] & 0x20)) { - GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_AT_TEMPLE, 0x20, GI_PRELUDE_OF_LIGHT); + GivePlayerRandoRewardSheikSong(this, globalCtx, RC_SHEIK_AT_TEMPLE, 0x20, RG_PRELUDE_OF_LIGHT); } } } diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index d4250fca2..96bf18aef 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -233,8 +233,8 @@ void GivePlayerRandoRewardZeldaChild(EnZl4* zelda, GlobalContext* globalCtx, Ran Flags_SetTreasure(globalCtx, 0x1E); } else if (!Flags_GetTreasure(globalCtx, 0x1E) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA) && Actor_TextboxIsClosing(&zelda->actor, globalCtx) && (globalCtx->msgCtx.textId == 0x703C || globalCtx->msgCtx.textId == 0x703D)) { - GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_LETTER_ZELDA); - func_8002F434(&zelda->actor, globalCtx, getItemId, 10000.0f, 100.0f); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, GI_LETTER_ZELDA); + GiveItemEntryFromActor(&zelda->actor, globalCtx, getItemEntry, 10000.0f, 100.0f); } else if (Flags_GetTreasure(globalCtx, 0x1E) && !Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { gSaveContext.unk_13EE = 0x32; gSaveContext.eventChkInf[4] |= 1; diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index b562dad30..1336a0dcd 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -5000,6 +5000,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE)) && Message_ShouldAdvance(globalCtx)) { s32 getItemId; + GetItemEntry getItemEntry = (GetItemEntry)GET_ITEM_NONE; Message_CloseTextbox(globalCtx); @@ -5054,9 +5055,12 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { if (D_80B7E078 >= Fishing_GetMinimumRequiredScore()) { HIGH_SCORE(HS_FISHING) |= 0x400; sSinkingLureLocation = (u8)Rand_ZeroFloat(3.999f) + 1; - getItemId = gSaveContext.n64ddFlag ? - Randomizer_GetItemIdFromKnownCheck(RC_LH_CHILD_FISHING, GI_HEART_PIECE) : - GI_HEART_PIECE; + if (!gSaveContext.n64ddFlag) { + getItemId = GI_HEART_PIECE; + } else { + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_CHILD_FISHING, GI_HEART_PIECE); + getItemId = getItemEntry.getItemId; + } } } } else { @@ -5064,9 +5068,12 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { if (D_80B7E078 >= Fishing_GetMinimumRequiredScore()) { HIGH_SCORE(HS_FISHING) |= 0x800; sSinkingLureLocation = (u8)Rand_ZeroFloat(3.999f) + 1; - getItemId = gSaveContext.n64ddFlag ? - Randomizer_GetItemIdFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD) : - GI_SCALE_GOLD; + if (!gSaveContext.n64ddFlag) { + getItemId = GI_SCALE_GOLD; + } else { + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD); + getItemId = getItemEntry.getItemId; + } } } } @@ -5076,7 +5083,11 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { } this->actor.parent = NULL; - func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); + if (!gSaveContext.n64ddFlag || getItemEntry.getItemId == GI_NONE) { + func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); + } else { + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 2000.0f, 1000.0f); + } this->unk_15C = 23; } break; @@ -5140,9 +5151,8 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_SCALE_GOLD, 2000.0f, 1000.0f); } else { - func_8002F434(&this->actor, globalCtx, - Randomizer_GetItemIdFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD), 2000.0f, - 1000.0f); + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 2000.0f, 1000.0f); } } break; diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index e32ab216f..304c3053d 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -59,11 +59,11 @@ void ItemBHeart_Update(Actor* thisx, GlobalContext* globalCtx) { Flags_SetCollectible(globalCtx, 0x1F); Actor_Kill(&this->actor); } else { - if (gSaveContext.n64ddFlag) { - s32 getItemId = Randomizer_GetRandomizedItemId(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum); - func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 40.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_HEART_CONTAINER_2, 30.0f, 40.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetRandomizedItem(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 30.0f, 40.0f); } } } @@ -99,8 +99,8 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) { } if (gSaveContext.n64ddFlag) { - GetItem_Draw(globalCtx, - Randomizer_GetItemModelFromId(Randomizer_GetRandomizedItemId(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum))); + GetItem_Draw(globalCtx, Randomizer_GetRandomizedItem(GI_HEART_CONTAINER_2, + this->actor.id,this->actor.params, globalCtx->sceneNum).gid); } else { if (flag) { func_80093D84(globalCtx->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index 7b422d140..eb6efef7b 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -21,6 +21,7 @@ void ItemEtcetera_SpawnSparkles(ItemEtcetera* this, GlobalContext* globalCtx); void ItemEtcetera_MoveFireArrowDown(ItemEtcetera* this, GlobalContext* globalCtx); void func_80B85B28(ItemEtcetera* this, GlobalContext* globalCtx); void ItemEtcetera_UpdateFireArrow(ItemEtcetera* this, GlobalContext* globalCtx); +GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, GlobalContext* globalCtx); const ActorInit Item_Etcetera_InitVars = { ACTOR_ITEM_ETCETERA, @@ -132,11 +133,11 @@ void func_80B85824(ItemEtcetera* this, GlobalContext* globalCtx) { } Actor_Kill(&this->actor); } else { - if (gSaveContext.n64ddFlag) { - s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); - func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 50.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, this->getItemId, 30.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 30.0f, 50.0f); } } } @@ -155,11 +156,11 @@ void func_80B858B4(ItemEtcetera* this, GlobalContext* globalCtx) { } else { if (0) {} // Necessary to match - if (gSaveContext.n64ddFlag) { - s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); - func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 50.0f); - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, this->getItemId, 30.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 30.0f, 50.0f); } if ((globalCtx->gameplayFrames & 0xD) == 0) { @@ -229,13 +230,10 @@ void ItemEtcetera_DrawThroughLens(Actor* thisx, GlobalContext* globalCtx) { func_8002ED80(&this->actor, globalCtx, 0); if(gSaveContext.n64ddFlag && globalCtx->sceneNum == 16) { - s32 randoGetItemId = GetChestGameRandoGetItemId(this->actor.room, this->giDrawId, globalCtx); - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } - if (randoGetItemId != GI_NONE) { - GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); + GetItemEntry randoGetItem = GetChestGameRandoGetItem(this->actor.room, this->giDrawId, globalCtx); + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); + if (randoGetItem.itemId != ITEM_NONE) { + GetItem_Draw(globalCtx, randoGetItem.gid); return; } } @@ -249,20 +247,17 @@ void ItemEtcetera_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 type = this->actor.params & 0xFF; if (gSaveContext.n64ddFlag) { - s32 randoGetItemId = GI_NONE; + GetItemEntry randoGetItem = (GetItemEntry)GET_ITEM_NONE; if (type == ITEM_ETC_ARROW_FIRE) { - randoGetItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); + randoGetItem = Randomizer_GetItemFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); } else if (type == ITEM_ETC_LETTER) { - randoGetItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); + randoGetItem = Randomizer_GetItemFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); } - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); - if (randoGetItemId != GI_NONE) { - this->giDrawId = Randomizer_GetItemModelFromId(randoGetItemId); + if (randoGetItem.itemId != RG_NONE) { + this->giDrawId = randoGetItem.gid; } } diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index f58b0927a..a8db425da 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -190,11 +190,12 @@ void ItemOcarina_WaitInWater(ItemOcarina* this, GlobalContext* globalCtx) { this->actionFunc = ItemOcarina_StartSoTCutscene; this->actor.draw = NULL; } else { - func_8002F434(&this->actor, globalCtx, - gSaveContext.n64ddFlag - ? Randomizer_GetItemIdFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT) - : GI_OCARINA_OOT, - 30.0f, 50.0f); + if (!gSaveContext.n64ddFlag) { + func_8002F434(&this->actor, globalCtx, GI_OCARINA_OOT, 30.0f, 50.0f); + } else { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); + GiveItemEntryFromActor(&this->actor, globalCtx, getItemEntry, 30.0f, 50.0f); + } if ((globalCtx->gameplayFrames & 13) == 0) { EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, 0.0f, 10.0f, 0.13f); @@ -215,12 +216,9 @@ void ItemOcarina_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8002ED80(thisx, globalCtx, 0); if (gSaveContext.n64ddFlag) { - s32 randoGetItemId = Randomizer_GetItemIdFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); - if ((randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) || - (randoGetItemId >= GI_STICK_UPGRADE_20 && randoGetItemId <= GI_NUT_UPGRADE_40)) { - EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); - } - GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); + GetItemEntry randoGetItem = Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); + EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); + GetItem_Draw(globalCtx, randoGetItem.gid); return; } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index aed098e5c..195da7945 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -21,15 +21,7 @@ #include "objects/object_link_child/object_link_child.h" #include "textures/icon_item_24_static/icon_item_24_static.h" #include - -#define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim) \ - { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId } - -#define CHEST_ANIM_SHORT 0 -#define CHEST_ANIM_LONG 1 - -#define GET_ITEM_NONE \ - { ITEM_NONE, 0, 0, 0, OBJECT_INVALID } +#include typedef enum { /* 0x00 */ KNOB_ANIM_ADULT_L, @@ -490,215 +482,6 @@ static u16 D_8085361C[] = { NA_SE_VO_LI_FALL_L, }; -GetItemEntry sGetItemTable[] = { - GET_ITEM(ITEM_BOMBS_5, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOW, OBJECT_GI_BOW, GID_BOW, 0x31, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SLINGSHOT, OBJECT_GI_PACHINKO, GID_SLINGSHOT, 0x30, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOOMERANG, OBJECT_GI_BOOMERANG, GID_BOOMERANG, 0x35, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_STICK, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_LENS, OBJECT_GI_GLASSES, GID_LENS, 0x39, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_LETTER_ZELDA, OBJECT_GI_LETTER, GID_LETTER_ZELDA, 0x69, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_OCARINA_TIME, OBJECT_GI_OCARINA, GID_OCARINA_TIME, 0x3A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_HAMMER, OBJECT_GI_HAMMER, GID_HAMMER, 0x38, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_COJIRO, OBJECT_GI_NIWATORI, GID_COJIRO, 0x02, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_POTION_GREEN, OBJECT_GI_LIQUID, GID_POTION_GREEN, 0x44, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_POTION_BLUE, OBJECT_GI_LIQUID, GID_POTION_BLUE, 0x45, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x46, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_LETTER_RUTO, OBJECT_GI_BOTTLE_LETTER, GID_LETTER_RUTO, 0x99, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_MASK_SKULL, OBJECT_GI_SKJ_MASK, GID_MASK_SKULL, 0x10, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_SPOOKY, OBJECT_GI_REDEAD_MASK, GID_MASK_SPOOKY, 0x11, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_CHICKEN, OBJECT_GI_NIWATORI, GID_CHICKEN, 0x48, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_KEATON, OBJECT_GI_KI_TAN_MASK, GID_MASK_KEATON, 0x12, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_BUNNY, OBJECT_GI_RABIT_MASK, GID_MASK_BUNNY, 0x13, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_TRUTH, OBJECT_GI_TRUTH_MASK, GID_MASK_TRUTH, 0x17, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_POCKET_EGG, OBJECT_GI_EGG, GID_EGG, 0x01, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_POCKET_CUCCO, OBJECT_GI_NIWATORI, GID_CHICKEN, 0x48, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_CLAIM_CHECK, OBJECT_GI_TICKETSTONE, GID_CLAIM_CHECK, 0x0A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SWORD_KOKIRI, OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, 0xA4, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x4B, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHIELD_DEKU, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, 0x4C, 0xA0, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SHIELD_HYLIAN, OBJECT_GI_SHIELD_2, GID_SHIELD_HYLIAN, 0x4D, 0xA0, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SHIELD_MIRROR, OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, 0x4E, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_TUNIC_GORON, OBJECT_GI_CLOTHES, GID_TUNIC_GORON, 0x50, 0xA0, CHEST_ANIM_LONG), - GET_ITEM(ITEM_TUNIC_ZORA, OBJECT_GI_CLOTHES, GID_TUNIC_ZORA, 0x51, 0xA0, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOOTS_IRON, OBJECT_GI_BOOTS_2, GID_BOOTS_IRON, 0x53, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOOTS_HOVER, OBJECT_GI_HOVERBOOTS, GID_BOOTS_HOVER, 0x54, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_QUIVER_40, OBJECT_GI_ARROWCASE, GID_QUIVER_40, 0x56, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_QUIVER_50, OBJECT_GI_ARROWCASE, GID_QUIVER_50, 0x57, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOMB_BAG_20, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, 0x58, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOMB_BAG_30, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, 0x59, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOMB_BAG_40, OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, 0x5A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GAUNTLETS_SILVER, OBJECT_GI_GLOVES, GID_GAUNTLETS_SILVER, 0x5B, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GAUNTLETS_GOLD, OBJECT_GI_GLOVES, GID_GAUNTLETS_GOLD, 0x5C, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SCALE_SILVER, OBJECT_GI_SCALE, GID_SCALE_SILVER, 0xCD, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SCALE_GOLDEN, OBJECT_GI_SCALE, GID_SCALE_GOLDEN, 0xCE, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_STONE_OF_AGONY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, 0x68, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_OCARINA_FAIRY, OBJECT_GI_OCARINA_0, GID_OCARINA_FAIRY, 0x4A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SEEDS, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xC6, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xC2, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_KEY_BOSS, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, 0xC7, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, 0x67, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DUNGEON_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, 0x66, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0x60, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_MAGIC_SMALL, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0x52, 0x6F, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_MAGIC_LARGE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0x52, 0x6E, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WEIRD_EGG, OBJECT_GI_EGG, GID_EGG, 0x9A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_HEART, OBJECT_GI_HEART, GID_HEART, 0x55, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ARROWS_SMALL, OBJECT_GI_ARROW, GID_ARROWS_SMALL, 0xE6, 0x48, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_ARROWS_MEDIUM, OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, 0xE6, 0x49, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_ARROWS_LARGE, OBJECT_GI_ARROW, GID_ARROWS_LARGE, 0xE6, 0x4A, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0x6F, 0x00, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xCC, 0x01, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF0, 0x02, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_HEART_CONTAINER, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xC6, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MILK, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_GORON, OBJECT_GI_GOLONMASK, GID_MASK_GORON, 0x14, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_ZORA, OBJECT_GI_ZORAMASK, GID_MASK_ZORA, 0x15, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MASK_GERUDO, OBJECT_GI_GERUDOMASK, GID_MASK_GERUDO, 0x16, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, 0x79, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF1, 0x14, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_GOLD, OBJECT_GI_RUPY, GID_RUPEE_GOLD, 0xF2, 0x13, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SWORD_BGS, OBJECT_GI_LONGSWORD, GID_SWORD_BGS, 0x0C, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BULLET_BAG_30, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BULLET_BAG_40, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG, 0x07, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_STICKS_5, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_STICKS_10, OBJECT_GI_STICK, GID_STICK, 0x37, 0x0D, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_NUTS_5, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_NUTS_10, OBJECT_GI_NUTS, GID_NUTS, 0x34, 0x0C, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMB, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMBS_10, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMBS_20, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMBS_30, OBJECT_GI_BOMB_1, GID_BOMB, 0x32, 0x59, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMBCHUS_5, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_FISH, OBJECT_GI_FISH, GID_FISH, 0x47, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, 0xF9, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_GREEN, OBJECT_GI_RUPY, GID_RUPEE_GREEN, 0xF4, 0x00, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_BLUE, OBJECT_GI_RUPY, GID_RUPEE_BLUE, 0xF5, 0x01, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_RED, OBJECT_GI_RUPY, GID_RUPEE_RED, 0xF6, 0x02, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_RUPEE_PURPLE, OBJECT_GI_RUPY, GID_RUPEE_PURPLE, 0xF7, 0x14, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_HEART_PIECE_2, OBJECT_GI_HEARTS, GID_HEART_PIECE, 0xFA, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG_50, 0x6C, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x3C, 0x80, CHEST_ANIM_SHORT), // Ice Traps - GET_ITEM_NONE, - - GET_ITEM(ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MEDALLION_FOREST, OBJECT_GI_MEDAL, GID_MEDALLION_FOREST, 0x3E, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MEDALLION_FIRE, OBJECT_GI_MEDAL, GID_MEDALLION_FIRE, 0x3C, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MEDALLION_WATER, OBJECT_GI_MEDAL, GID_MEDALLION_WATER, 0x3D, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MEDALLION_SHADOW, OBJECT_GI_MEDAL, GID_MEDALLION_SHADOW, 0x41, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_MEDALLION_SPIRIT, OBJECT_GI_MEDAL, GID_MEDALLION_SPIRIT, 0x3F, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_KOKIRI_EMERALD, OBJECT_GI_JEWEL, GID_KOKIRI_EMERALD, 0x80, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GORON_RUBY, OBJECT_GI_JEWEL, GID_GORON_RUBY, 0x81, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ZORA_SAPPHIRE, OBJECT_GI_JEWEL, GID_ZORA_SAPPHIRE, 0x82, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_SONG_LULLABY, OBJECT_GI_MELODY, GID_SONG_ZELDA, 0xD4, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_SUN, OBJECT_GI_MELODY, GID_SONG_SUN, 0xD3, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_EPONA, OBJECT_GI_MELODY, GID_SONG_EPONA, 0xD2, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_STORMS, OBJECT_GI_MELODY, GID_SONG_STORM, 0xD6, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_TIME, OBJECT_GI_MELODY, GID_SONG_TIME, 0xD5, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_SARIA, OBJECT_GI_MELODY, GID_SONG_SARIA, 0xD1, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_SONG_MINUET, OBJECT_GI_MELODY, GID_SONG_MINUET, 0x73, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_BOLERO, OBJECT_GI_MELODY, GID_SONG_BOLERO, 0x74, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_SERENADE, OBJECT_GI_MELODY, GID_SONG_SERENADE, 0x75, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_NOCTURNE, OBJECT_GI_MELODY, GID_SONG_NOCTURNE, 0x77, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_REQUIEM, OBJECT_GI_MELODY, GID_SONG_REQUIEM, 0x76, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_SINGLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DOUBLE_MAGIC, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_BOTTLE_WITH_RED_POTION, OBJECT_GI_LIQUID, GID_POTION_RED, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_GREEN_POTION, OBJECT_GI_LIQUID, GID_POTION_GREEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BLUE_POTION, OBJECT_GI_LIQUID, GID_POTION_BLUE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_FAIRY, OBJECT_GI_BOTTLE, GID_BOTTLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_FISH, OBJECT_GI_FISH, GID_FISH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BUGS, OBJECT_GI_INSECT, GID_BUG, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_POE, OBJECT_GI_GHOST, GID_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTLE_WITH_BIG_POE, OBJECT_GI_GHOST, GID_BIG_POE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_FOREST_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_FIRE_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_WATER_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SPIRIT_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_SHADOW_TEMPLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - GET_ITEM(ITEM_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT), - - GET_ITEM(ITEM_FOREST_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FIRE_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WATER_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SPIRIT_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHADOW_TEMPLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_GANONS_CASTLE_BOSS_KEY, OBJECT_GI_BOSSKEY, GID_KEY_BOSS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - - GET_ITEM(ITEM_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_JABU_JABUS_BELLY_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FOREST_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_FIRE_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_WATER_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SPIRIT_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG), - - GET_ITEM_NONE, - GET_ITEM_NONE, -}; - static LinkAnimationHeader* D_80853914[PLAYER_ANIMGROUP_MAX][PLAYER_ANIMTYPE_MAX] = { /* PLAYER_ANIMGROUP_0 */ { &gPlayerAnim_003240, &gPlayerAnim_003238, &gPlayerAnim_003238, &gPlayerAnim_002BE0, &gPlayerAnim_003240, @@ -1625,9 +1408,14 @@ s32 func_808332E4(Player* this) { } void func_808332F4(Player* this, GlobalContext* globalCtx) { - GetItemEntry* giEntry = &sGetItemTable[this->getItemId - 1]; + GetItemEntry giEntry; + if (this->getItemEntry.objectId == OBJECT_INVALID) { + giEntry = ItemTable_Retrieve(this->getItemId); + } else { + giEntry = this->getItemEntry; + } - this->unk_862 = ABS(giEntry->gi); + this->unk_862 = ABS(giEntry.gi); } static LinkAnimationHeader* func_80833338(Player* this) { @@ -1814,6 +1602,7 @@ void func_808337D4(GlobalContext* globalCtx, Player* this) { this->interactRangeActor = spawnedActor; this->heldActor = spawnedActor; this->getItemId = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->unk_3BC.y = spawnedActor->shape.rot.y - this->actor.shape.rot.y; this->stateFlags1 |= PLAYER_STATE1_11; } @@ -4739,11 +4528,12 @@ void func_8083A434(GlobalContext* globalCtx, Player* this) { if (this->getItemId == GI_HEART_CONTAINER_2) { this->unk_850 = 20; } - else if (this->getItemId >= 0) { + else if (this->getItemId >= 0 || (this->getItemEntry.objectId != OBJECT_INVALID && this->getItemEntry.getItemId >= 0)) { this->unk_850 = 1; } else { this->getItemId = -this->getItemId; + this->getItemEntry.getItemId = -this->getItemEntry.getItemId; } } @@ -5034,7 +4824,7 @@ static LinkAnimationHeader* D_80854548[] = { s32 func_8083B040(Player* this, GlobalContext* globalCtx) { s32 sp2C; s32 sp28; - GetItemEntry* giEntry; + GetItemEntry giEntry; Actor* targetActor; if ((this->unk_6AD != 0) && @@ -5071,8 +4861,12 @@ s32 func_8083B040(Player* this, GlobalContext* globalCtx) { func_80835DE4(globalCtx, this, func_8084F104, 0); if (sp2C >= 0) { - giEntry = &sGetItemTable[D_80854528[sp2C] - 1]; - func_8083AE40(this, giEntry->objectId); + if (this->getItemEntry.objectId == OBJECT_INVALID) { + giEntry = ItemTable_Retrieve(D_80854528[sp2C]); + } else { + giEntry = this->getItemEntry; + } + func_8083AE40(this, giEntry.objectId); } this->stateFlags1 |= PLAYER_STATE1_6 | PLAYER_STATE1_28 | PLAYER_STATE1_29; @@ -6270,7 +6064,7 @@ void func_8083E4C4(GlobalContext* globalCtx, Player* this, GetItemEntry* giEntry Item_Give(globalCtx, giEntry->itemId); } - func_80078884((this->getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM); + func_80078884((this->getItemId < 0 || this->getItemEntry.getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM); } // Sets a flag according to which type of flag is specified in player->pendingFlag.flagType @@ -6292,6 +6086,9 @@ void Player_SetPendingFlag(Player* this, GlobalContext* globalCtx) { case FLAG_COW_MILKED: gSaveContext.cowsMilked[this->pendingFlag.flagID] = 1; break; + case FLAG_EVENT_CHECK_INF: + Flags_SetEventChkInf(this->pendingFlag.flagID); + break; case FLAG_NONE: default: break; @@ -6310,16 +6107,20 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) { this->getItemId = iREG(68); } - if (this->getItemId < GI_MAX) { - GetItemEntry* giEntry = &sGetItemTable[this->getItemId - 1]; - + GetItemEntry giEntry; + if (this->getItemEntry.objectId == OBJECT_INVALID) { + giEntry = ItemTable_Retrieve(this->getItemId); + } else { + giEntry = this->getItemEntry; + } + if (giEntry.collectable) { if ((interactedActor != &this->actor) && !iREG(67)) { interactedActor->parent = &this->actor; } iREG(67) = false; - if (gSaveContext.n64ddFlag && this->getItemId == GI_ICE_TRAP) { + if (gSaveContext.n64ddFlag && giEntry.getItemId == RG_ICE_TRAP) { this->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11); this->actor.colChkInfo.damage = 0; func_80837C0C(globalCtx, this, 3, 0.0f, 0.0f, 0, 20); @@ -6327,24 +6128,25 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) { return 1; } - s32 drop = giEntry->objectId; + s32 drop = giEntry.objectId; if (gSaveContext.n64ddFlag || (globalCtx->sceneNum == SCENE_BOWLING) || !(CVar_GetS32("gFastDrops", 0) && ((drop == OBJECT_GI_BOMB_1) || (drop == OBJECT_GI_NUTS) || (drop == OBJECT_GI_STICK) || (drop == OBJECT_GI_SEED) || (drop == OBJECT_GI_MAGICPOT) || (drop == OBJECT_GI_ARROW))) && - (Item_CheckObtainability(giEntry->itemId) == ITEM_NONE)) { + (Item_CheckObtainability(giEntry.itemId) == ITEM_NONE)) { if (gSaveContext.n64ddFlag && ((interactedActor->id == ACTOR_EN_ITEM00 && (interactedActor->params != 6 && interactedActor->params != 17)) || (interactedActor->id == ACTOR_EN_KAREBABA || interactedActor->id == ACTOR_EN_DEKUBABA))) { - func_8083E4C4(globalCtx, this, giEntry); + func_8083E4C4(globalCtx, this, &giEntry); this->getItemId = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; return 0; } func_808323B4(globalCtx, this); - func_8083AE40(this, giEntry->objectId); + func_8083AE40(this, giEntry.objectId); if (!(this->stateFlags2 & PLAYER_STATE2_10) || (this->currentBoots == PLAYER_BOOTS_IRON)) { func_80836898(globalCtx, this, func_8083A434); @@ -6357,29 +6159,35 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) { return 1; } - func_8083E4C4(globalCtx, this, giEntry); + func_8083E4C4(globalCtx, this, &giEntry); this->getItemId = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; } } else if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) && !(this->stateFlags1 & PLAYER_STATE1_11) && !(this->stateFlags2 & PLAYER_STATE2_10)) { - if (this->getItemId != GI_NONE) { - GetItemEntry* giEntry = &sGetItemTable[-this->getItemId - 1]; + if (this->getItemId != GI_NONE || this->getItemEntry.objectId != OBJECT_INVALID) { + GetItemEntry giEntry; + if (this->getItemEntry.objectId == OBJECT_INVALID) { + giEntry = ItemTable_Retrieve(-this->getItemId); + } else { + giEntry = this->getItemEntry; + } EnBox* chest = (EnBox*)interactedActor; if (CVar_GetS32("gFastChests", 0) != 0) { - giEntry->gi = -1 * abs(giEntry->gi); + giEntry.gi = -1 * abs(giEntry.gi); } - if (giEntry->itemId != ITEM_NONE) { - if (((Item_CheckObtainability(giEntry->itemId) == ITEM_NONE) && (giEntry->field & 0x40)) || - ((Item_CheckObtainability(giEntry->itemId) != ITEM_NONE) && (giEntry->field & 0x20))) { + if (giEntry.itemId != ITEM_NONE) { + if (((Item_CheckObtainability(giEntry.itemId) == ITEM_NONE) && (giEntry.field & 0x40)) || + ((Item_CheckObtainability(giEntry.itemId) != ITEM_NONE) && (giEntry.field & 0x20))) { this->getItemId = -GI_RUPEE_BLUE; - giEntry = &sGetItemTable[GI_RUPEE_BLUE - 1]; + giEntry = ItemTable_Retrieve(GI_RUPEE_BLUE); } } func_80836898(globalCtx, this, func_8083A434); this->stateFlags1 |= PLAYER_STATE1_10 | PLAYER_STATE1_11 | PLAYER_STATE1_29; - func_8083AE40(this, giEntry->objectId); + func_8083AE40(this, giEntry.objectId); this->actor.world.pos.x = chest->dyna.actor.world.pos.x - (Math_SinS(chest->dyna.actor.shape.rot.y) * 29.4343f); this->actor.world.pos.z = @@ -6387,8 +6195,8 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) { this->currentYaw = this->actor.shape.rot.y = chest->dyna.actor.shape.rot.y; func_80832224(this); - if ((giEntry->itemId != ITEM_NONE) && (giEntry->gi >= 0) && - (Item_CheckObtainability(giEntry->itemId) == ITEM_NONE)) { + if ((giEntry.itemId != ITEM_NONE) && (giEntry.gi >= 0) && + (Item_CheckObtainability(giEntry.itemId) == ITEM_NONE)) { func_808322D0(globalCtx, this, this->ageProperties->unk_98); func_80832F54(globalCtx, this, 0x28F); chest->unk_1F4 = 1; @@ -6786,6 +6594,7 @@ s32 func_8083F7BC(Player* this, GlobalContext* globalCtx) { this->stateFlags1 |= PLAYER_STATE1_11; this->interactRangeActor = &wallPolyActor->actor; this->getItemId = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; this->currentYaw = this->actor.wallYaw + 0x8000; func_80832224(this); @@ -9878,14 +9687,12 @@ void func_808473D4(GlobalContext* globalCtx, Player* this) { else if ((!(this->stateFlags1 & PLAYER_STATE1_11) || (heldActor == NULL)) && (interactRangeActor != NULL) && ((!sp1C && (this->getItemId == GI_NONE)) || - ((this->getItemId < 0) && !(this->stateFlags1 & PLAYER_STATE1_27)))) { - if (this->getItemId < 0) { + ((this->getItemId < 0 || this->getItemEntry.getItemId < 0) && !(this->stateFlags1 & PLAYER_STATE1_27)))) { + if (this->getItemId < 0 || this->getItemEntry.getItemId < 0) { doAction = DO_ACTION_OPEN; - } - else if ((interactRangeActor->id == ACTOR_BG_TOKI_SWD) && LINK_IS_ADULT) { + } else if ((interactRangeActor->id == ACTOR_BG_TOKI_SWD) && LINK_IS_ADULT) { doAction = DO_ACTION_DROP; - } - else { + } else { doAction = DO_ACTION_GRAB; } } @@ -9937,7 +9744,7 @@ void func_808473D4(GlobalContext* globalCtx, Player* this) { } } else if (!(this->stateFlags1 & PLAYER_STATE1_27) && func_8083A0D4(this) && - (this->getItemId < GI_MAX)) { + ((!gSaveContext.n64ddFlag && this->getItemId < GI_MAX) || (gSaveContext.n64ddFlag && this->getItemEntry.getItemId < RG_MAX))) { doAction = DO_ACTION_GRAB; } else if (this->stateFlags2 & PLAYER_STATE2_11) { @@ -11083,7 +10890,8 @@ void Player_UpdateCommon(Player* this, GlobalContext* globalCtx, Input* input) { Collider_ResetQuadAT(globalCtx, &this->shieldQuad.base); if (this->pendingIceTrap) { - GiveItemWithoutActor(globalCtx, GI_ICE_TRAP); + this->getItemEntry = ItemTable_RetrieveEntry(MOD_RANDOMIZER, RG_ICE_TRAP); + GiveItemEntryWithoutActor(globalCtx, this->getItemEntry); } } @@ -12728,6 +12536,7 @@ void func_8084DF6C(GlobalContext* globalCtx, Player* this) { this->unk_862 = 0; this->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11); this->getItemId = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; func_8005B1A4(Gameplay_GetCamera(globalCtx, 0)); } @@ -12739,16 +12548,20 @@ void func_8084DFAC(GlobalContext* globalCtx, Player* this) { } s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) { - GetItemEntry* giEntry; + GetItemEntry giEntry; s32 temp1; s32 temp2; - if (this->getItemId == GI_NONE) { + if (this->getItemId == GI_NONE && this->getItemEntry.objectId == OBJECT_INVALID) { return 1; } if (this->unk_84F == 0) { - giEntry = &sGetItemTable[this->getItemId - 1]; + if (this->getItemEntry.objectId == OBJECT_INVALID) { + giEntry = ItemTable_Retrieve(this->getItemId); + } else { + giEntry = this->getItemEntry; + } this->unk_84F = 1; // make sure we get the BGS instead of giant's knife @@ -12757,34 +12570,47 @@ s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) { gSaveContext.swordHealth = 8; } - Message_StartTextbox(globalCtx, giEntry->textId, &this->actor); - Item_Give(globalCtx, giEntry->itemId); - + Message_StartTextbox(globalCtx, giEntry.textId, &this->actor); + if (giEntry.modIndex == MOD_NONE) { + Item_Give(globalCtx, giEntry.itemId); + } else { + Randomizer_Item_Give(globalCtx, giEntry); + } Player_SetPendingFlag(this, globalCtx); - // In rando the fanfares are handled by a function in code_800EC960.c - if (gSaveContext.n64ddFlag) { - Audio_PlayFanfare_Rando(this->getItemId); - } - else if (((this->getItemId >= GI_RUPEE_GREEN) && (this->getItemId <= GI_RUPEE_RED)) || - ((this->getItemId >= GI_RUPEE_PURPLE) && (this->getItemId <= GI_RUPEE_GOLD)) || - ((this->getItemId >= GI_RUPEE_GREEN_LOSE) && (this->getItemId <= GI_RUPEE_PURPLE_LOSE)) || - (this->getItemId == GI_HEART)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - } - else { - if ((this->getItemId == GI_HEART_CONTAINER_2) || (this->getItemId == GI_HEART_CONTAINER) || - ((this->getItemId == GI_HEART_PIECE) && - ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) { - temp1 = NA_BGM_HEART_GET | 0x900; + // Use this if we do have a getItemEntry + if (giEntry.modIndex == MOD_NONE) { + if (gSaveContext.n64ddFlag) { + Audio_PlayFanfare_Rando(giEntry); + } else if (((giEntry.itemId >= ITEM_RUPEE_GREEN) && (giEntry.itemId <= ITEM_RUPEE_RED)) || + ((giEntry.itemId >= ITEM_RUPEE_PURPLE) && (giEntry.itemId <= ITEM_RUPEE_GOLD)) || + (giEntry.itemId == ITEM_HEART)) { + Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else { + if ((giEntry.itemId == ITEM_HEART_CONTAINER) || + ((giEntry.itemId == ITEM_HEART_PIECE) && + ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) { + temp1 = NA_BGM_HEART_GET | 0x900; + } else { + temp1 = temp2 = + (giEntry.itemId == ITEM_HEART_PIECE) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900; + } + Audio_PlayFanfare(temp1); } - else { - temp1 = temp2 = (this->getItemId == GI_HEART_PIECE) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900; + } else if (giEntry.modIndex == MOD_RANDOMIZER) { + if (gSaveContext.n64ddFlag) { + Audio_PlayFanfare_Rando(giEntry); + } else if (giEntry.itemId == RG_DOUBLE_DEFENSE || giEntry.itemId == RG_MAGIC_SINGLE || + giEntry.itemId == RG_MAGIC_DOUBLE) { + Audio_PlayFanfare(NA_BGM_HEART_GET | 0x900); + } else { + Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900); } - Audio_PlayFanfare(temp1); + } else { + // Just in case something weird happens with modIndex. + Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900); } - } - else { + } else { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) { if (this->getItemId == GI_GAUNTLETS_SILVER && !gSaveContext.n64ddFlag) { globalCtx->nextEntranceIndex = 0x0123; @@ -12795,6 +12621,7 @@ s32 func_8084DFF4(GlobalContext* globalCtx, Player* this) { func_80852FFC(globalCtx, NULL, 8); } this->getItemId = GI_NONE; + this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; } } @@ -12959,15 +12786,16 @@ void func_8084E6D4(Player* this, GlobalContext* globalCtx) { else { func_80832DBC(this); - if (this->getItemId == GI_ICE_TRAP) { + if ((this->getItemId == GI_ICE_TRAP && !gSaveContext.n64ddFlag) || + (gSaveContext.n64ddFlag && (this->getItemId == RG_ICE_TRAP || this->getItemEntry.getItemId == RG_ICE_TRAP))) { this->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11); - if (this->getItemId != GI_ICE_TRAP) { + if ((this->getItemId != GI_ICE_TRAP && !gSaveContext.n64ddFlag) || + (gSaveContext.n64ddFlag && (this->getItemId != RG_ICE_TRAP || this->getItemEntry.getItemId != RG_ICE_TRAP))) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, this->actor.world.pos.y + 100.0f, this->actor.world.pos.z, 0, 0, 0, 0); func_8083C0E8(this, globalCtx); - } - else { + } else { this->actor.colChkInfo.damage = 0; func_80837C0C(globalCtx, this, 3, 0.0f, 0.0f, 0, 20); } @@ -13356,14 +13184,14 @@ void func_8084F104(Player* this, GlobalContext* globalCtx) { func_80853148(globalCtx, targetActor); } else { - GetItemEntry* giEntry = &sGetItemTable[D_80854528[this->exchangeItemId - 1] - 1]; + GetItemEntry giEntry = ItemTable_Retrieve(D_80854528[this->exchangeItemId - 1]); if (this->itemActionParam >= PLAYER_AP_LETTER_ZELDA) { - if (giEntry->gi >= 0) { - this->unk_862 = giEntry->gi; + if (giEntry.gi >= 0) { + this->unk_862 = giEntry.gi; } else { - this->unk_862 = -giEntry->gi; + this->unk_862 = -giEntry.gi; } }