Browse Source

Merge branch 'develop-flynn' into flynn-to-dev

pull/2107/head
briaguya 2 months ago
parent
commit
4f109178ff
  1. 4
      CMakeLists.txt
  2. 32
      scripts/linux/appimage/soh.sh
  3. 2
      soh/assets/xml/GC_MQ_D/objects/object_ganon.xml
  4. 2
      soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml
  5. 2
      soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml
  6. 2
      soh/include/functions.h
  7. 10
      soh/soh/Enhancements/crowd-control/CrowdControl.cpp
  8. 12
      soh/soh/Enhancements/randomizer/3drando/hint_list.cpp
  9. 350
      soh/soh/Enhancements/randomizer/randomizer.cpp
  10. 2
      soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp
  11. 4
      soh/soh/GameMenuBar.cpp
  12. 33
      soh/soh/OTRGlobals.cpp
  13. 2
      soh/soh/OTRGlobals.h
  14. 9
      soh/src/code/z_parameter.c
  15. 2
      soh/src/code/z_play.c
  16. 7
      soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c
  17. 10
      soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
  18. 2
      soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
  19. 2
      soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c

4
CMakeLists.txt

@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") @@ -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)

32
scripts/linux/appimage/soh.sh

@ -64,22 +64,26 @@ while [[ (! -e "$SHIP_HOME"/oot.otr) || (! -e "$SHIP_HOME"/oot-mq.otr) ]]; do @@ -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

2
soh/assets/xml/GC_MQ_D/objects/object_ganon.xml

@ -68,7 +68,7 @@ @@ -68,7 +68,7 @@
<DList Name="gGanondorfRightHandOpenDL" Offset="0xC9E8"/>
<!-- Ganondorf Title Card Texture -->
<Texture Name="gGanondorfTitleCardTex" OutName="ganondorf_title_card" Format="i8" Width="128" Height="40" Offset="0xCF00"/>
<Texture Name="gGanondorfTitleCardTex" OutName="ganondorf_title_card" Format="i8" Width="128" Height="120" Offset="0xCF00"/>
<!-- Ganondorf Animation -->
<Animation Name="gGanondorfEndingFloatAnim" Offset="0x11348"/> <!-- Original name is "ONOLEE" (lit. "Curse you!" from his in-game dialogue) -->

2
soh/assets/xml/GC_NMQ_D/objects/object_ganon.xml

@ -68,7 +68,7 @@ @@ -68,7 +68,7 @@
<DList Name="gGanondorfRightHandOpenDL" Offset="0xC9E8"/>
<!-- Ganondorf Title Card Texture -->
<Texture Name="gGanondorfTitleCardTex" OutName="ganondorf_title_card" Format="i8" Width="128" Height="40" Offset="0xCF00"/>
<Texture Name="gGanondorfTitleCardTex" OutName="ganondorf_title_card" Format="i8" Width="128" Height="120" Offset="0xCF00"/>
<!-- Ganondorf Animation -->
<Animation Name="gGanondorfEndingFloatAnim" Offset="0x11348"/> <!-- Original name is "ONOLEE" (lit. "Curse you!" from his in-game dialogue) -->

2
soh/assets/xml/GC_NMQ_PAL_F/objects/object_ganon.xml

@ -68,7 +68,7 @@ @@ -68,7 +68,7 @@
<DList Name="gGanondorfRightHandOpenDL" Offset="0xC9E8"/>
<!-- Ganondorf Title Card Texture -->
<Texture Name="gGanondorfTitleCardTex" OutName="ganondorf_title_card" Format="i8" Width="128" Height="40" Offset="0xCF00"/>
<Texture Name="gGanondorfTitleCardTex" OutName="ganondorf_title_card" Format="i8" Width="128" Height="120" Offset="0xCF00"/>
<!-- Ganondorf Animation -->
<Animation Name="gGanondorfEndingFloatAnim" Offset="0x11348"/> <!-- Original name is "ONOLEE" (lit. "Curse you!" from his in-game dialogue) -->

2
soh/include/functions.h

@ -394,7 +394,7 @@ void Flags_UnsetTempClear(PlayState* play, s32 flag); @@ -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);

10
soh/soh/Enhancements/crowd-control/CrowdControl.cpp

@ -458,7 +458,7 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(std::string effectId, uin @@ -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) { @@ -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;

12
soh/soh/Enhancements/randomizer/3drando/hint_list.cpp

@ -974,7 +974,7 @@ void HintTable_Init() { @@ -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() { @@ -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() { @@ -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" },
});

350
soh/soh/Enhancements/randomizer/randomizer.cpp

@ -4234,7 +4234,7 @@ CustomMessageEntry Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u @@ -4234,7 +4234,7 @@ CustomMessageEntry Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u
std::vector<std::vector<const char*>> 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() { @@ -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<GetItemMessage> 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_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_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(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_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_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(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(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(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(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();

2
soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp

@ -469,7 +469,7 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { @@ -469,7 +469,7 @@ std::map<RandomizerCheck, RandomizerCheckObject> 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"),

4
soh/soh/GameMenuBar.cpp

@ -924,7 +924,7 @@ namespace GameMenuBar { @@ -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 { @@ -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();

33
soh/soh/OTRGlobals.cpp

@ -709,19 +709,29 @@ extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) @@ -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<Ship::Resource> 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<Ship::Resource> 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) { @@ -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<Ship::Array>(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));
}
}

2
soh/soh/OTRGlobals.h

@ -35,6 +35,7 @@ private: @@ -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(); @@ -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);

9
soh/src/code/z_parameter.c

@ -2704,7 +2704,7 @@ u8 Item_CheckObtainability(u8 item) { @@ -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) { @@ -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;

2
soh/src/code/z_play.c

@ -870,7 +870,7 @@ void Play_Update(PlayState* play) { @@ -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);
}
}

7
soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c

@ -257,6 +257,10 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { @@ -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) { @@ -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;
}
}

10
soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c

@ -1082,7 +1082,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { @@ -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) { @@ -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) { @@ -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);

2
soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c

@ -843,6 +843,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { @@ -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;

2
soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c

@ -1980,7 +1980,7 @@ void KaleidoScope_DrawInfoPanel(PlayState* play) { @@ -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;

Loading…
Cancel
Save