diff --git a/CMakeLists.txt b/CMakeLists.txt index 669604f8a..e24d01fe2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) project(Ship LANGUAGES C CXX - VERSION 5.0.1) -set(PROJECT_BUILD_NAME "FLYNN BRAVO" CACHE STRING "") + VERSION 5.0.2) +set(PROJECT_BUILD_NAME "FLYNN CHARLIE" CACHE STRING "") set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) diff --git a/scripts/linux/appimage/soh.sh b/scripts/linux/appimage/soh.sh index e05bba983..384311d4c 100644 --- a/scripts/linux/appimage/soh.sh +++ b/scripts/linux/appimage/soh.sh @@ -64,22 +64,26 @@ while [[ (! -e "$SHIP_HOME"/oot.otr) || (! -e "$SHIP_HOME"/oot-mq.otr) ]]; do echo -e "\n$romfile - $ROMHASH rom hash does not match\n" continue;; esac - cp -r "$ASSETDIR"/assets/game "$ASSETDIR"/Extract/assets - if [ -n "$ZENITY" ]; then - (echo "# 25%"; echo "25"; sleep 2; echo "# 50%"; echo "50"; sleep 3; echo "# 75%"; echo "75"; sleep 2; echo "# 100%"; echo "100"; sleep 3) | - zenity --progress --title="OTR Generating..." --timeout=10 --percentage=0 --icon-name=soh --window-icon=soh.png --height=80 --width=400 & - else - echo "Processing..." + if [[ ! -e "$SHIP_HOME"/"$OTRNAME" ]]; then + cp -r "$ASSETDIR"/assets/game "$ASSETDIR"/Extract/assets + if [ -n "$ZENITY" ]; then + (echo "# 25%"; echo "25"; sleep 2; echo "# 50%"; echo "50"; sleep 3; echo "# 75%"; echo "75"; sleep 2; echo "# 100%"; echo "100"; sleep 3) | + zenity --progress --title="OTR Generating..." --timeout=10 --percentage=0 --icon-name=soh --window-icon=soh.png --height=80 --width=400 & + else + echo "Processing..." + fi + assets/extractor/ZAPD.out ed -eh -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 --otrfile "${OTRNAME}" > /dev/null 2>&1 + cp "$ASSETDIR"/"$OTRNAME" "$SHIP_HOME" fi - assets/extractor/ZAPD.out ed -eh -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 --otrfile "${OTRNAME}" > /dev/null 2>&1 - cp "$ASSETDIR"/"$OTRNAME" "$SHIP_HOME" else - if [ -n "$ZENITY" ]; then - zenity --error --timeout=5 --text="Place ROM in $SHIP_HOME" --title="Missing ROM file" --width=500 --width=200 - else - echo -e "\nPlace ROM in this folder\n" - fi - exit + if [[ (! -e "$SHIP_HOME"/oot.otr) && (! -e "$SHIP_HOME"/oot-mq.otr) ]]; then + if [ -n "$ZENITY" ]; then + zenity --error --timeout=5 --text="Place ROM in $SHIP_HOME" --title="Missing ROM file" --width=500 --width=200 + else + echo -e "\nPlace ROM in this folder\n" + fi + exit + fi fi done if [[ (! -e "$SHIP_HOME"/oot.otr) && (! -e "$SHIP_HOME"/oot-mq.otr) ]]; then diff --git a/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml b/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml index 79cba2ab3..27c36a5f2 100644 --- a/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml +++ b/soh/assets/xml/GC_MQ_D/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml index 79cba2ab3..27c36a5f2 100644 --- a/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml index 79cba2ab3..27c36a5f2 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml @@ -68,7 +68,7 @@ - + diff --git a/soh/include/functions.h b/soh/include/functions.h index 49bb9a628..b077c59a3 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -394,7 +394,7 @@ void Flags_UnsetTempClear(PlayState* play, s32 flag); s32 Flags_GetCollectible(PlayState* play, s32 flag); void Flags_SetCollectible(PlayState* play, s32 flag); void TitleCard_InitBossName(PlayState* play, TitleCardContext* titleCtx, void* texture, s16 x, s16 y, u8 width, - u8 height, s16 hastranslation); + u8 height, s16 hasTranslation); void TitleCard_InitPlaceName(PlayState* play, TitleCardContext* titleCtx, void* texture, s32 x, s32 y, s32 width, s32 height, s32 delay); s32 func_8002D53C(PlayState* play, TitleCardContext* titleCtx); diff --git a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp index e76878fc0..2f5b1a3ac 100644 --- a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp +++ b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp @@ -458,7 +458,7 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(std::string effectId, uin if (dryRun == 0) CMD_EXECUTE(fmt::format("defense_modifier {}", value)); return EffectResult::Success; } else if (effectId == EFFECT_DAMAGE) { - if ((gSaveContext.healthCapacity - 0x10) <= 0) { + if ((gSaveContext.health - (16 * value)) <= 0) { return EffectResult::Failure; } @@ -482,6 +482,14 @@ bool CrowdControl::SpawnEnemy(std::string effectId) { if (effectId == EFFECT_SPAWN_WALLMASTER) { enemyId = 17; } else if (effectId == EFFECT_SPAWN_ARWING) { + // Don't allow Arwings in certain areas because they cause issues. + // Locations: King dodongo room, Morpha room, Twinrova room, Ganondorf room, Fishing pond, Ganon's room + // TODO: Swap this to disabling the option in CC options menu instead. + if (gPlayState->sceneNum == SCENE_DDAN_BOSS || gPlayState->sceneNum == SCENE_MIZUSIN_BS || + gPlayState->sceneNum == SCENE_JYASINBOSS || gPlayState->sceneNum == SCENE_GANON_BOSS || + gPlayState->sceneNum == SCENE_TURIBORI || gPlayState->sceneNum == SCENE_GANON_DEMO) { + return 0; + } enemyId = 315; enemyParams = 1; posYOffset = 100; diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index d6cfa515b..8111d3fb5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -974,7 +974,7 @@ void HintTable_Init() { hintTable[KOKIRI_FOREST] = HintText::Exclude({ // obscure text - Text{ "Kokiri Forest", /*french*/ "la forêt Kokiri", /*spanish*/ "el Bosque Kokiri" }, + Text{ "Kokiri Forest", /*french*/ "la Forêt Kokiri", /*spanish*/ "el Bosque Kokiri" }, }); hintTable[THE_LOST_WOODS] = HintText::Exclude({ @@ -1004,7 +1004,7 @@ void HintTable_Init() { hintTable[GERUDO_FORTRESS] = HintText::Exclude({ // obscure text - Text{ "Gerudo's Fortress", /*french*/ "la Repaire des Voleurs", /*spanish*/ "la Fortaleza Gerudo" }, + Text{ "Gerudo's Fortress", /*french*/ "le Repaire des Voleurs", /*spanish*/ "la Fortaleza Gerudo" }, }); hintTable[HAUNTED_WASTELAND] = HintText::Exclude({ @@ -1102,22 +1102,22 @@ void HintTable_Init() { hintTable[KF_MIDOS_HOUSE] = HintText::Region({ // obscure text - Text{ "Mido's house", /*french*/ "la #Cabane du Grand Mido#", /*spanish*/ "la casa de Mido" }, + Text{ "Mido's house", /*french*/ "la Cabane du Grand Mido", /*spanish*/ "la casa de Mido" }, }); hintTable[KF_SARIAS_HOUSE] = HintText::Region({ // obscure text - Text{ "Saria's House", /*french*/ "la #Cabane de Saria#", /*spanish*/ "la casa de Saria" }, + Text{ "Saria's House", /*french*/ "la Cabane de Saria", /*spanish*/ "la casa de Saria" }, }); hintTable[KF_HOUSE_OF_TWINS] = HintText::Region({ // obscure text - Text{ "the #House of Twins#", /*french*/ "la #Cabane des Jumelles#", /*spanish*/ "la casa de las gemelas" }, + Text{ "the #House of Twins#", /*french*/ "la Cabane des Jumelles", /*spanish*/ "la casa de las gemelas" }, }); hintTable[KF_KNOW_IT_ALL_HOUSE] = HintText::Region({ // obscure text - Text{ "Know-It-All Brothers' House", /*french*/ "la #Cabane des frères Je-Sais-Tout#", + Text{ "Know-It-All Brothers' House", /*french*/ "la Cabane des frères Je-Sais-Tout", /*spanish*/ "la casa de los hermanos Sabelotodo" }, }); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index cc4a0ada7..5d31acd96 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4234,7 +4234,7 @@ CustomMessageEntry Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u std::vector> mapGetItemHints = { { " It's ordinary.", " It's masterful!" }, - { " It's ordinary.", " It's masterful!" }, // TODO: German Translation (when map items are also translated) + { "&Sieht aus wie immer.", " &Man kann darauf die Worte&%r\"Master Quest\"%w entziffern..." }, { "&Elle vous semble %rordinaire%w.", "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus." }, }; @@ -4531,150 +4531,232 @@ 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_NO_GERMAN( - RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", + GIMESSAGE(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, + "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", + "Du erhältst eine %rFlasche mit&blauem Feuer%w! Nutze es um&%rRotes Eis%w zu schmelzen!", "Vous obtenez une %rBouteille avec&une Flamme Bleue%w! Utilisez-la&pour faire fondre la %rGlace&Rouge%w!"), - 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(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( - RG_BOTTLE_WITH_FISH, ITEM_FISH, + GIMESSAGE(RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE, + "You got a %rBig Poe in a Bottle%w!&Sell it to the Ghost Shop!", + "Du hast einen %rNachtschwärmer%w&in einer Flasche gefangen!&Gehe zum %rGespenstermarkt%w&und verkaufe ihn!", + "Vous obtenez une %rBouteille avec&une Âme%w! Vendez-la au Marchand&d'Âme"), + GIMESSAGE(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!", + "Du erhältst ein %rBlaues Elexier%w!&Nutze es, um deine %rMagie- und&Energieleiste%w komplett&aufzufüllen!", + "Vous obtenez une %rBouteille avec&une Potion Bleue%w! Buvez-la pour&restaurer votre %rénergie vitale%w&ainsi que votre %gmagie%w!"), + GIMESSAGE(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( - RG_BOTTLE_WITH_BUGS, ITEM_BUG, "You got a %rBug in a Bottle%w!&They love to burrow in&dirt holes!", + "Du hast jetzt einen %rFisch in&einer Flasche%w! Er sieht richtig&frisch aus! Man sagt,&Lord Jabu-Jabu liebt Fische!", + "Vous obtenez une %rBouteille avec&un Poisson%w! Il a l'air délicieux!&Il paraîtrait que %bJabu-Jabu %wen&serait friand!"), + GIMESSAGE(RG_BOTTLE_WITH_BUGS, ITEM_BUG, + "You got a %rBug in a Bottle%w!&They love to burrow in&dirt holes!", + "Du hast jetzt %rKäfer in einer&Flasche&%w!&Sie graben gerne&in Erdlöchern.", "Vous obtenez une %rBouteille avec&des Insectes%w! Ils adorent creuser&dans la terre meuble!"), - 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( - RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, + GIMESSAGE(RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY, + "You got a %rFairy in a Bottle%w!&Use it wisely!", + "Du hast jetzt eine %rFee in einer&Flasche%w! Nutze sie weise!", + "Vous obtenez une %rBouteille avec&une Fée%w! Faites-en bon usage!"), + GIMESSAGE(RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, "You got a %rBottle of Red Potion%w!&Drink it to replenish your&%ghealth%w!", + "Du erhältst ein %rRotes Elexier%w!&Nutze es, um deine %rEnergieleiste&%weinmalig komplett aufzufüllen!", "Vous obtenez une %rBouteille avec&une Potion Rouge%w! Buvez-la pour&restaurer votre %rénergie vitale%w!"), - GIMESSAGE_NO_GERMAN( - RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, + GIMESSAGE(RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, "You got a %rBottle of Green Potion%w!&Drink it to replenish your&%bmagic%w!", + "Du erhältst ein %rGrünes Elexier%w!&Nutze es, um deine %bMagieleiste&%weinmalig komplett aufzufüllen!", "Vous obtenez une %rBouteille avec&une Potion Verte%w! Buvez-la pour&restaurer votre %gmagie%w!"), - GIMESSAGE_NO_GERMAN( - RG_BOTTLE_WITH_POE, ITEM_POE, + GIMESSAGE(RG_BOTTLE_WITH_POE, ITEM_POE, "You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this...", + "Du hast jetzt ein %rIrrlicht in einer&Flasche%w! Der %rGespenstermarkt%w&interessiert sich für vielleicht&dafür...", "Vous obtenez une %rBouteille avec&un Esprit%w! Ça intéresserait&peut-être le vendeur d'Âme "), - 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 %pPuits%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 %rChâteau de Ganon%w!"), + GIMESSAGE(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %yThieves Hideout &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für das %yDiebesversteck%w!", + "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %gForest Temple &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für den %gWaldtempel%w!", + "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %rFire Temple &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für den %rFeuertempel%w!", + "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %bWater Temple &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für den %bWassertempel%w!", + "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %ySpirit Temple &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für den %yGeistertempel%w!", + "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %pShadow Temple &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für den %pSchattentempel%w!", + "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %pBottom of the &Well %wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für den %pGrund des Brunnens%w!", + "Vous obtenez une %rPetite Clé %w&du %pPuits%w!"), + GIMESSAGE(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %yGerudo Training &Grounds %wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für die %yGerudo&Trainingsarena%w!", + "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), + GIMESSAGE(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, + "You found a %rGanon's Castle &%wSmall Key!", + "Du erhältst einen %rKleinen&Schlüssel%w für die %rGanons Schloß%w!", + "Vous obtenez une %rPetite Clé %w&du %rChâteau de Ganon%w!"), - GIMESSAGE_NO_GERMAN(RG_GERUDO_FORTRESS_KEY_RING, ITEM_KEY_SMALL, - "You found a %yThieves Hideout &%wKeyring!", - "Vous obtenez un trousseau de&clés du %yRepaire des Voleurs%w!"), - GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %gForest Temple &%wKeyring!", - "Vous obtenez un trousseau de&clés du %gTemple de la Forêt%w!"), - GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %rFire Temple &%wKeyring!", - "Vous obtenez un trousseau de&clés du %rTemple du Feu%w!"), - GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %bWater Temple &%wKeyring!", - "Vous obtenez un trousseau de&clés du %bTemple de l'Eau%w!"), - GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %ySpirit Temple &%wKeyring!", - "Vous obtenez un trousseau de&clés du %yTemple de l'Esprit%w!"), - GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %pShadow Temple &%wKeyring!", - "Vous obtenez un trousseau de&clés du %pTemple de l'Ombre%w!"), - GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_KEY_RING, ITEM_KEY_SMALL, - "You found a %pBottom of the &Well %wKeyring!", - "Vous obtenez un trousseau de&clés du %pPuits%w!"), - GIMESSAGE_NO_GERMAN(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, ITEM_KEY_SMALL, - "You found a %yGerudo Training &Grounds %wKeyring!", - "Vous obtenez un trousseau de&clés du %yGymnase Gerudo%w!"), - GIMESSAGE_NO_GERMAN(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %rGanon's Castle &%wKeyring!", - "Vous obtenez un trousseau de&clés du %rChâteau de Ganon%w!"), + GIMESSAGE(RG_GERUDO_FORTRESS_KEY_RING, ITEM_KEY_SMALL, + "You found a %yThieves Hideout &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für das %yDiebesversteck%w!", + "Vous obtenez un trousseau de&clés du %yRepaire des Voleurs%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_KEY_RING, ITEM_KEY_SMALL, + "You found a %gForest Temple &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %gWaldtempel%w!", + "Vous obtenez un trousseau de&clés du %gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_KEY_RING, ITEM_KEY_SMALL, + "You found a %rFire Temple &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %rFeuertempel%w!", + "Vous obtenez un trousseau de&clés du %rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_KEY_RING, ITEM_KEY_SMALL, + "You found a %bWater Temple &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %bWassertempel%w!", + "Vous obtenez un trousseau de&clés du %bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_KEY_RING, ITEM_KEY_SMALL, + "You found a %ySpirit Temple &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %yGeistertempel%w!", + "Vous obtenez un trousseau de&clés du %yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_KEY_RING, ITEM_KEY_SMALL, + "You found a %pShadow Temple &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %pSchattentempel%w!", + "Vous obtenez un trousseau de&clés du %pTemple de l'Ombre%w!"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_KEY_RING, ITEM_KEY_SMALL, + "You found a %pBottom of the &Well %wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %pGrund des Brunnens%w!", + "Vous obtenez un trousseau de&clés du %pPuits%w!"), + GIMESSAGE(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, ITEM_KEY_SMALL, + "You found a %yGerudo Training &Grounds %wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für die %yGerudo Trainingsarena%w!", + "Vous obtenez un trousseau de&clés du %yGymnase Gerudo%w!"), + GIMESSAGE(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL, + "You found a %rGanon's Castle &%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für %rGanons Schloß%w!", + "Vous obtenez un trousseau de&clés du %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(RG_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, + "You found the %gForest Temple &%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %gWaldtempel%w!", + "Vous obtenez la %rClé d'or %wdu&%gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, + "You found the %rFire Temple &%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %rFeuertempel%w!", + "Vous obtenez la %rClé d'or %wdu&%rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, + "You found the %bWater Temple &%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %bWassertempel%w!", + "Vous obtenez la %rClé d'or %wdu&%bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, + "You found the %ySpirit Temple &%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %yGeistertempel%w!", + "Vous obtenez la %rClé d'or %wdu&%yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, + "You found the %pShadow Temple &%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %pSchattentempel%w!", + "Vous obtenez la %rClé d'or %wdu&%pTemple de l'Ombre%w!"), + GIMESSAGE(RG_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, + "You found the %rGanon's Castle &%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für %rGanons Schloß%w!", + "Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"), - GIMESSAGE_NO_GERMAN(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wdu &%pPuits%w!{{typeHint}}"), - GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!{{typeHint}}", - "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!{{typeHint}}"), + GIMESSAGE(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, + "You found the %gDeku Tree &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%gDeku-Baum%w!{{typeHint}}", + "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!{{typeHint}}"), + GIMESSAGE(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, + "You found the %rDodongo's Cavern &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für&%rDodongos Höhle%w!{{typeHint}}", + "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!{{typeHint}}"), + GIMESSAGE(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, + "You found the %bJabu Jabu's Belly &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für&%bJabu-Jabus Bauch%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!{{typeHint}}"), + GIMESSAGE(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, + "You found the %gForest Temple &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%gWaldtempel%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!{{typeHint}}"), + GIMESSAGE(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, + "You found the %rFire Temple &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%rFeuertempel%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!{{typeHint}}"), + GIMESSAGE(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, + "You found the %bWater Temple &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%bWassertempel%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!{{typeHint}}"), + GIMESSAGE(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, + "You found the %ySpirit Temple &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%yGeistertempel%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!{{typeHint}}"), + GIMESSAGE(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, + "You found the %pShadow Temple &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%pSchattentempel%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!{{typeHint}}"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, + "You found the %pBottom of the &Well %wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für den&%pGrund des Brunnens%w!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%pPuits%w!{{typeHint}}"), + GIMESSAGE(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, + "You found the %cIce Cavern &%wMap!{{typeHint}}", + "Du erhältst die %rKarte%w für die&%cEishöhle%w!{{typeHint}}", + "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!{{typeHint}}"), + + GIMESSAGE(RG_DEKU_TREE_COMPASS, ITEM_COMPASS, + "You found the %gDeku Tree &%wCompass!", + "Du erhältst den %rKompaß%w für den&%gDeku-Baum%w!", + "Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"), + GIMESSAGE(RG_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS, + "You found the %rDodongo's Cavern &%wCompass!", + "Du erhältst den %rKompaß%w für&%rDodongos Höhle%w!", + "Vous obtenez la %rBoussole %wde la&%rCaverne Dodongo%w!"), + GIMESSAGE(RG_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS, + "You found the %bJabu Jabu's Belly &%wCompass!", + "Du erhältst den %rKompaß%w für den&%bJabu-Jabus Bauch%w!", + "Vous obtenez la %rBoussole %wdu &%bVentre de Jabu-Jabu%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_COMPASS, ITEM_COMPASS, + "You found the %gForest Temple &%wCompass!", + "Du erhältst den %rKompaß%w für den&%gWaldtempel%w!", + "Vous obtenez la %rBoussole %wdu &%gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_COMPASS, ITEM_COMPASS, + "You found the %rFire Temple &%wCompass!", + "Du erhältst den %rKompaß%w für den&%rFeuertempel%w!", + "Vous obtenez la %rBoussole %wdu &%rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_COMPASS, ITEM_COMPASS, + "You found the %bWater Temple &%wCompass!", + "Du erhältst den %rKompaß%w für den&%bWassertempel%w!", + "Vous obtenez la %rBoussole %wdu &%bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS, + "You found the %ySpirit Temple &%wCompass!", + "Du erhältst den %rKompaß%w für den&%yGeistertempel%w!", + "Vous obtenez la %rBoussole %wdu &%yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS, + "You found the %pShadow Temple &%wCompass!", + "Du erhältst den %rKompaß%w für den&%pSchattentempel%w!", + "Vous obtenez la %rBoussole %wdu &%pTemple de l'Ombre%w!"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS, + "You found the %pBottom of the &Well %wCompass!", + "Du erhältst den %rKompaß%w für den&%pGrund des Brunnens%w!", + "Vous obtenez la %rBoussole %wdu &%pPuits%w!"), + GIMESSAGE(RG_ICE_CAVERN_COMPASS, ITEM_COMPASS, + "You found the %cIce Cavern &%wCompass!", + "Du erhältst den %rKompaß%w für die&%cEishöhle%w!", + "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!"), GIMESSAGE(RG_MAGIC_BEAN_PACK, ITEM_BEAN, - "You got a %rPack of Magic Beans%w!&Find a suitable spot for a garden&and plant them. Then, wait for&something fun to happen!", - "Du hast eine %rPackung&Magic Beans%w! Finde&einen geeigneten Platz fur einen&Garten und pflanze sie. Dann^warte auf etwas Lustiges passiert!", - "Vous obtenez un %rPaquet de&Haricots Magiques%w! Trouvez&un endroit approprié pour un&jardin et plantez-les.^Attendez ensuite que quelque&chose d'amusant se produise!"), - GIMESSAGE_NO_GERMAN(RG_TYCOON_WALLET, ITEM_WALLET_GIANT, - "You got a %rTycoon's Wallet%w!&It's gigantic! Now you can carry&up to %y999 rupees%w!", - "Vous obtenez la %rBourse de Magnat%w!&Elle peut contenir jusqu'à %y999 rubis%w!&C'est gigantesque!") + "You got a %rPack of Magic Beans%w!&Find a suitable spot for a garden&and plant them. Then, wait for&something fun to happen!", + "Du erhältst eine %rPackung&Wundererbsen%w! Suche nach einer&Stelle um sie einzupflanzen.&Warte ab, was passiert!", + "Vous obtenez un %rPaquet de&Haricots Magiques%w! Trouvez&un endroit approprié pour un&jardin et plantez-les.^Attendez ensuite que quelque&chose d'amusant se produise!"), + GIMESSAGE(RG_TYCOON_WALLET, ITEM_WALLET_GIANT, + "You got a %rTycoon's Wallet%w!&It's gigantic! Now you can carry&up to %y999 rupees%w!", + "Du erhältst die %rGoldene&Geldbörse%w! Die größte aller&Geldbörsen! Jetzt kannst Du bis&zu %y999 Rubine%w mit dir führen!", + "Vous obtenez la %rBourse de Magnat%w!&Elle peut contenir jusqu'à %y999 rubis%w!&C'est gigantesque!") }; CreateGetItemMessages(getItemMessages); CreateRupeeMessages(); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index f08d25be7..c36852f62 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -469,7 +469,7 @@ std::map rcObjects = { RC_OBJECT(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCVORMQ_VANILLA, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8705, GI_SKULL_TOKEN, "GS Lobby Basement Lower", "Jabu Jabus Belly GS Lobby Basement Lower"), RC_OBJECT(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCVORMQ_VANILLA, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8706, GI_SKULL_TOKEN, "GS Lobby Basement Upper", "Jabu Jabus Belly GS Lobby Basement Upper"), RC_OBJECT(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCVORMQ_VANILLA, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8708, GI_SKULL_TOKEN, "GS Near Boss", "Jabu Jabus Belly GS Near Boss"), - RC_OBJECT(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8712, GI_SKULL_TOKEN, "GS Water Switch Room", "Jabu Jabus Belly GS Water Switch Room"), + RC_OBJECT(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCVORMQ_VANILLA, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8712, GI_SKULL_TOKEN, "GS Water Switch Room", "Jabu Jabus Belly GS Water Switch Room"), RC_OBJECT(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8708, GI_SKULL_TOKEN, "MQ GS Tail Parasan Room", "Jabu Jabus Belly MQ GS Tail Parasan Room"), RC_OBJECT(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8712, GI_SKULL_TOKEN, "MQ GS Invisible Enemies Room", "Jabu Jabus Belly MQ GS Invisible Enemies Room"), RC_OBJECT(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCVORMQ_MQ, RCTYPE_SKULL_TOKEN, RCAREA_JABU_JABUS_BELLY, ACTOR_EN_SI, SCENE_BDAN, 8705, GI_SKULL_TOKEN, "MQ GS Boomerang Chest Room", "Jabu Jabus Belly MQ GS Boomerang Chest Room"), diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 2e609ef26..61dff30b6 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -924,7 +924,7 @@ namespace GameMenuBar { UIWidgets::Tooltip("Holding down B skips text"); UIWidgets::PaddedEnhancementCheckbox("Free Camera", "gFreeCamera", true, false); UIWidgets::Tooltip("Enables camera control\nNote: You must remap C buttons off of the right stick in the controller config menu, and map the camera stick to the right stick."); - + #ifdef __SWITCH__ UIWidgets::Spacer(0); int slot = CVar_GetS32("gSwitchPerfMode", (int)Ship::SwitchProfiles::STOCK); @@ -1232,7 +1232,7 @@ namespace GameMenuBar { #ifdef ENABLE_CROWD_CONTROL UIWidgets::EnhancementCheckbox("Crowd Control", "gCrowdControl"); - UIWidgets::Tooltip("Requires a full SoH restart to take effect!\n\nEnables CrowdControl. Will attempt to connect to the local Crowd Control server."); + UIWidgets::Tooltip("Will attempt to connect to the Crowd Control server. Check out crowdcontrol.live for more information."); if (CVar_GetS32("gCrowdControl", 0)) { CrowdControl::Instance->Enable(); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 527397b3a..017fd1591 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -709,19 +709,29 @@ extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) return result; } -extern "C" void ResourceMgr_LoadFile(const char* resName) { - OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName); -} - -std::shared_ptr ResourceMgr_LoadResource(const char* path) { +std::string GetName(const char* path) { std::string Path = path; - if (ResourceMgr_IsGameMasterQuest()) { + if (IsGameMasterQuest()) { size_t pos = 0; if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) { Path.replace(pos, 7, "/mq/"); } } - return OTRGlobals::Instance->context->GetResourceManager()->LoadResource(Path.c_str()); + return Path; +} + +extern "C" const char* ResourceMgr_GetName(const char* path) { + auto s = new std::string(GetName(path)); + const char* name = s->c_str(); + return name; +} + +extern "C" void ResourceMgr_LoadFile(const char* resName) { + OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName); +} + +std::shared_ptr ResourceMgr_LoadResource(const char* path) { + return OTRGlobals::Instance->context->GetResourceManager()->LoadResource(ResourceMgr_GetName(path)); } extern "C" char* ResourceMgr_LoadFileRaw(const char* resName) { @@ -796,14 +806,7 @@ extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) { else if (res->ResType == Ship::ResourceType::Array) return (char*)(std::static_pointer_cast(res))->vertices.data(); else { - std::string Path = filePath; - if (ResourceMgr_IsGameMasterQuest()) { - size_t pos = 0; - if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) { - Path.replace(pos, 7, "/mq/"); - } - } - return ResourceMgr_LoadTexByName(Path.c_str()); + return ResourceMgr_LoadTexByName(ResourceMgr_GetName(filePath)); } } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 549332785..4e1a848ab 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -35,6 +35,7 @@ private: }; uint32_t IsGameMasterQuest(); +std::string GetName(const char* path); #endif #ifndef __cplusplus @@ -57,6 +58,7 @@ uint32_t ResourceMgr_GetNumGameVersions(); uint32_t ResourceMgr_GetGameVersion(int index); void ResourceMgr_CacheDirectory(const char* resName); char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); +const char* ResourceMgr_GetName(const char* path); void ResourceMgr_LoadFile(const char* resName); char* ResourceMgr_LoadFileFromDisk(const char* filePath); char* ResourceMgr_LoadJPEG(char* data, int dataSize); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 1d4e59f07..537d185bd 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2704,7 +2704,7 @@ u8 Item_CheckObtainability(u8 item) { } void PerformAutosave(PlayState* play, u8 item) { - if (CVar_GetS32("gAutosave", 0)) { + if (CVar_GetS32("gAutosave", 0) && (play->sceneNum != SCENE_KENJYANOMA)) { if (CVar_GetS32("gAutosaveAllItems", 0)) { Play_PerformSave(play); } else if (CVar_GetS32("gAutosaveMajorItems", 1)) { @@ -2745,6 +2745,13 @@ void PerformAutosave(PlayState* play, u8 item) { if (play->sceneNum == SCENE_GANON_DEMO) { break; } + case ITEM_BOMBCHU: + case ITEM_BOMBCHUS_5: + case ITEM_BOMBCHUS_20: + if (!CVar_GetS32("gBombchuDrops", 0)) { + Play_PerformSave(play); + } + break; default: Play_PerformSave(play); break; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index b08f9cee4..dab5411b9 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -870,7 +870,7 @@ void Play_Update(PlayState* play) { // Don't autosave in grottos or cutscenes // Also don't save when you first load a file if (CVar_GetS32("gAutosave", 0) && (gSaveContext.cutsceneIndex == 0) && (play->gameplayFrames > 60) && - (play->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (play->sceneNum != SCENE_KAKUSIANA)) { + (play->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (play->sceneNum != SCENE_KAKUSIANA) && (play->sceneNum != SCENE_KENJYANOMA)) { Play_PerformSave(play); } } diff --git a/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c b/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c index 0bbbe58c5..b1774251b 100644 --- a/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c +++ b/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c @@ -257,6 +257,10 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { sp60.x = this->unk_1F4.x - (this->unk_1E8.x - this->unk_1F4.x); sp60.y = this->unk_1F4.y - (this->unk_1E8.y - this->unk_1F4.y); sp60.z = this->unk_1F4.z - (this->unk_1E8.z - this->unk_1F4.z); + u16 buttonsToCheck = BTN_A | BTN_B | BTN_R | BTN_CUP | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN; + if (CVar_GetS32("gDpadEquips", 0) != 0) { + buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT; + } if (BgCheck_EntityLineTest1(&play->colCtx, &sp60, &this->unk_1E8, &sp78, &poly, true, true, true, true, &bgId) && !func_8002F9EC(play, &this->actor, poly, bgId, &sp78)) { @@ -281,8 +285,7 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_REFLECT, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); } - } else if (CHECK_BTN_ANY(play->state.input[0].press.button, - (BTN_A | BTN_B | BTN_R | BTN_CUP | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN))) { + } else if (CHECK_BTN_ANY(play->state.input[0].press.button, (buttonsToCheck))) { this->timer = 0; } } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index b85ec62c1..7e08cbb0f 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -1082,7 +1082,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { if (!(gSaveContext.eventChkInf[7] & 0x100)) { TitleCard_InitBossName(play, &play->actorCtx.titleCtx, - SEGMENTED_TO_VIRTUAL(gGanondorfTitleCardTex), 160, 180, 128, 40, false); + SEGMENTED_TO_VIRTUAL(gGanondorfTitleCardTex), 160, 180, 128, 40, true); } gSaveContext.eventChkInf[7] |= 0x100; @@ -1197,8 +1197,8 @@ void BossGanon_SetupTowerCutscene(BossGanon* this, PlayState* play) { void BossGanon_ShatterWindows(u8 windowShatterState) { s16 i; - u8* tex1 = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(ganon_boss_sceneTex_006C18)); - u8* tex2 = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(ganon_boss_sceneTex_007418)); + u8* tex1 = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(ResourceMgr_GetName(ganon_boss_sceneTex_006C18))); + u8* tex2 = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(ResourceMgr_GetName(ganon_boss_sceneTex_007418))); u8* templateTex = ResourceMgr_LoadTexByName(SEGMENTED_TO_VIRTUAL(gGanondorfWindowShatterTemplateTex)); for (i = 0; i < 2048; i++) { @@ -3820,8 +3820,8 @@ void BossGanon_Draw(Actor* thisx, PlayState* play) { // Invalidate textures if they have changed if (this->windowShatterState != GDF_WINDOW_SHATTER_OFF) { - gSPInvalidateTexCache(POLY_OPA_DISP++, ganon_boss_sceneTex_006C18); - gSPInvalidateTexCache(POLY_OPA_DISP++, ganon_boss_sceneTex_007418); + gSPInvalidateTexCache(POLY_OPA_DISP++, ResourceMgr_GetName(ganon_boss_sceneTex_006C18)); + gSPInvalidateTexCache(POLY_OPA_DISP++, ResourceMgr_GetName(ganon_boss_sceneTex_007418)); } Gfx_SetupDL_25Opa(play->state.gfxCtx); 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 c7ea77f38..599055594 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 @@ -843,6 +843,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (gSaveContext.n64ddFlag) { play->nextEntranceIndex = 0x60C; gSaveContext.nextCutsceneIndex = 0; + // Set "raised lake hylia water" since we aren't warping to the cutscene + gSaveContext.eventChkInf[6] |= 0x200; } else { Item_Give(play, ITEM_MEDALLION_WATER); play->nextEntranceIndex = 0x6B; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 7d6661696..fa0545977 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -1980,7 +1980,7 @@ void KaleidoScope_DrawInfoPanel(PlayState* play) { } else {//baguettes PosX = 98; } - s16 PosY = 200; //General Pos of C button icon + s16 PosY = 200 - pauseCtx->infoPanelOffsetY; //General Pos of C button icon s16 icon_w = 46; // Original texture size s16 icon_h = 16; s32 icon_x_offset;