Skip to content

Commit

Permalink
House of Skulltula and Dampé's diary hints (#690)
Browse files Browse the repository at this point in the history
* Implement progressive hookshot hint

- Dampe's Diary will now reveal the region of one of the two available progressive hookshots
- Add Dampe Hint toggle to Misc Hints list

* Localisation

Added localisation

* Fix issues with dampé's diary hint and add overload for Text::Replace function

* Skulltula Hints (missing some translations)

* Use new Replace overload for Merchants hints

* Add missing translations

---------

Co-authored-by: Huevos <[email protected]>
  • Loading branch information
HylianFreddy and VeryTwistedSpoon committed Aug 20, 2023
1 parent d9f0ad2 commit c5eb90f
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 54 deletions.
3 changes: 3 additions & 0 deletions code/src/actor.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include "deku_scrubs.h"
#include "bean_plant.h"
#include "sheik.h"
#include "skulltula_people.h"

#define OBJECT_GI_KEY 170
#define OBJECT_GI_BOSSKEY 185
Expand Down Expand Up @@ -201,6 +202,8 @@ void Actor_Init() {

gActorOverlayTable[0x185].initInfo->update = EnWonderTalk2_rUpdate;

gActorOverlayTable[0x188].initInfo->update = EnSsh_rUpdate;

gActorOverlayTable[0x18A].initInfo->update = OceffWipe_rUpdate;
gActorOverlayTable[0x18B].initInfo->update = OceffStorm_rUpdate;

Expand Down
11 changes: 11 additions & 0 deletions code/src/actors/skulltula_people.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "settings.h"

#define EnSsh_Update_addr 0x1DF0A4
#define EnSsh_Update ((ActorFunc)EnSsh_Update_addr)

void EnSsh_rUpdate(Actor* thisx, GlobalContext* globalCtx) {
EnSsh_Update(thisx, globalCtx);
if (gSettingsContext.skulltulaHints && thisx->textId == 0x22) {
thisx->textId = 0x9400 + thisx->params - 1;
}
}
8 changes: 8 additions & 0 deletions code/src/actors/skulltula_people.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _SKULLTULA_PEOPLE_H_
#define _SKULLTULA_PEOPLE_H_

#include "z3D/z3D.h"

void EnSsh_rUpdate(Actor* thisx, GlobalContext* globalCtx);

#endif
2 changes: 2 additions & 0 deletions code/src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ typedef struct {
u8 totAltarHints;
u8 ganonHints;
u8 sheikHints;
u8 dampeHint;
u8 skulltulaHints;
u8 compassesShowReward;
u8 compassesShowWotH;
u8 mapsShowDungeonMode;
Expand Down
5 changes: 5 additions & 0 deletions source/descriptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,11 @@ string_view ganonHintsDesc = "Talking to Ganondorf in his boss room w
"\n" //
"When trials are on, Sheik will appear to relay\n" //
"these hints in Ganon's Castle."; //
string_view dampeHintDesc = "Reading Dampe's diary will reveal the location\n" //
"of a single progressive hookshot."; //
string_view skulltulaHintDesc = "Talking to a cursed House of Skulltula resident\n"//
"will tell you the reward they will give you for\n"//
"removing their curse."; //
/*------------------------------ //
| MAP AND COMPASS GIVES INFO | //
------------------------------*/ //
Expand Down
2 changes: 2 additions & 0 deletions source/descriptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ extern string_view bonusGossipHintsDesc;
extern string_view miscHintsDesc;
extern string_view totAltarHintsDesc;
extern string_view ganonHintsDesc;
extern string_view dampeHintDesc;
extern string_view skulltulaHintDesc;

extern string_view compassesShowRewardsDesc;
extern string_view compassesShowWotHDesc;
Expand Down
95 changes: 52 additions & 43 deletions source/hint_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2295,58 +2295,41 @@ void HintTable_Init() {
| MERCHANTS' ITEMS |
---------------------------*/

hintTable[MEDIGORON_DIALOG_FIRST] = HintText::MerchantsDialogs({
hintTable[MEDIGORON_DIALOG] = HintText::MerchantsDialogs({
// obscure text
Text{"How about buying ",
/*french*/"Veux-tu acheter ",
/*spanish*/"¿Me compras ",
/*italian*/"Che ne dici? Vuoi comprrrarrre ",
/*german*/"Möchtest du "},
});

hintTable[MEDIGORON_DIALOG_SECOND] = HintText::MerchantsDialogs({
// obscure text
Text{" for #200 Rupees#?&"+TWO_WAY_CHOICE()+"#Buy&Don't buy#",
/*french*/" pour #200 rubis#?&"+TWO_WAY_CHOICE()+"#Acheter&Ne pas acheter#",
/*spanish*/" por #200 rupias#?&"+TWO_WAY_CHOICE()+"#Comprar&No comprar#",
/*italian*/" per #200 rupie#?&"+TWO_WAY_CHOICE()+"#Sì&No#",
/*german*/" für #200 Rubine# kaufen?&"+TWO_WAY_CHOICE()+"#Klar!&Nie im Leben!#"},
Text{"How about buying %s for #200 Rupees#?&"+TWO_WAY_CHOICE()+"#Buy&Don't buy#",
/*french*/"Veux-tu acheter %s pour #200 rubis#?&"+TWO_WAY_CHOICE()+"#Acheter&Ne pas acheter#",
/*spanish*/"¿Me compras %s por #200 rupias#?&"+TWO_WAY_CHOICE()+"#Comprar&No comprar#",
/*italian*/"Che ne dici? Vuoi comprrrarrre %s per #200 rupie#?&"+TWO_WAY_CHOICE()+"#Sì&No#",
/*german*/"Möchtest du %s für #200 Rubine# kaufen?&"+TWO_WAY_CHOICE()+"#Klar!&Nie im Leben!#"},
});

hintTable[CARPET_SALESMAN_DIALOG_FIRST] = HintText::MerchantsDialogs({
// obscure text
Text{"Welcome!^I am selling stuff, strange and rare, from&all over the world to everybody. Today's&special is...^",
/*french*/"Bienvenue!^Je vends des objets rares et merveilleux du&monde entier. En spécial aujourd'hui...^",
/*spanish*/"¡Acércate!^Vendo productos extraños y difíciles de&encontrar... De todo el mundo a todo el&mundo. La oferta de hoy es...^¡",
/*italian*/"Benvenuto!^Vendo merce strana e introvabile che&proviene da ogni parte del mondo.&Oggi il pezzo forte è...^",
/*german*/"Willkommen!^Ich verkaufe hier seltsame,&seltene Sachen aus der ganzen Welt.^Mein heutiges Angebot...&"},
Text{"Welcome!^I am selling stuff, strange and rare, from&all over the world to everybody. Today's&special is...^"
"%s! Terrifying! I won't tell you what it is until I see the money...^How about #200 Rupees#?&&"+TWO_WAY_CHOICE()+"#Buy&Don't buy#",
/*french*/"Bienvenue!^Je vends des objets rares et merveilleux du&monde entier. En spécial aujourd'hui...^"
"%s! Un concentré de puissance! Mais montre tes rubis avant que je te dise ce que c'est...^Disons #200 rubis#?&&"+TWO_WAY_CHOICE()+"#Acheter&Ne pas acheter#",
/*spanish*/"¡Acércate!^Vendo productos extraños y difíciles de&encontrar... De todo el mundo a todo el&mundo. La oferta de hoy es...^"
"¡%s! ¡Terrorífico! No te revelaré su nombre hasta que vea el dinero...^#200 rupias#, ¿qué te parece?&&"+TWO_WAY_CHOICE()+"#Comprar&No comprar#",
/*italian*/"Benvenuto!^Vendo merce strana e introvabile che&proviene da ogni parte del mondo.&Oggi il pezzo forte è...^"
"%s! Non ti dico di che si tratta finché non vedo la grana.^Hai #200 rupie#?&&"+TWO_WAY_CHOICE()+"#Tieni!&Veramente no...#",
/*german*/"Willkommen!^Ich verkaufe hier seltsame,&seltene Sachen aus der ganzen Welt.^Mein heutiges Angebot...&"
"%s!&Furchterregend oder? Ich erzähle Euch mehr, wenn ich Geld sehe...^Wie wär's mit #200 Rubinen#?&&"+TWO_WAY_CHOICE()+"#Aber sicher!&Ich bin weg!#"},
});

hintTable[CARPET_SALESMAN_DIALOG_SECOND] = HintText::MerchantsDialogs({
// obscure text
Text{"! Terrifying! I won't tell you what it is until I see the money...^How about #200 Rupees#?&&"+TWO_WAY_CHOICE()+"#Buy&Don't buy#",
/*french*/"! Un concentré de puissance! Mais montre tes rubis avant que je te dise ce que c'est...^Disons #200 rubis#?&&"+TWO_WAY_CHOICE()+"#Acheter&Ne pas acheter#",
/*spanish*/"! ¡Terrorífico! No te revelaré su nombre hasta que vea el dinero...^#200 rupias#, ¿qué te parece?&&"+TWO_WAY_CHOICE()+"#Comprar&No comprar#",
/*italian*/"! Non ti dico di che si tratta finché non vedo la grana.^Hai #200 rupie#?&&"+TWO_WAY_CHOICE()+"#Tieni!&Veramente no...#",
/*german*/"!&Furchterregend oder? Ich erzähle Euch mehr, wenn ich Geld sehe...^Wie wär's mit #200 Rubinen#?&&"+TWO_WAY_CHOICE()+"#Aber sicher!&Ich bin weg!#"},
});

hintTable[CARPET_SALESMAN_DIALOG_THIRD] = HintText::MerchantsDialogs({
// obscure text
Text{"Thank you very much!^What I'm selling is... #",
/*french*/"Merci beaucoup!^Cet objet extraordinaire est... #",
/*spanish*/"¡Muchas gracias!^Lo que vendo es... #¡",
/*italian*/"Grazie!^Hai appena comprato... #",
/*german*/"Vielen herzlichen Dank!&#"},
});

hintTable[CARPET_SALESMAN_DIALOG_FOURTH] = HintText::MerchantsDialogs({
// obscure text
Text{"!#^The mark that will lead you to the #Spirit&Temple# is the #flag on the "+IF_NOT_MQ()+"left"+MQ_ELSE()+"right"+MQ_END()+"# outside the shop. Be seeing you!",
/*french*/"!#^La marque qui te mènera au #Temple de l'esprit# est le #drapeau "+IF_NOT_MQ()+"gauche"+MQ_ELSE()+"droite"+MQ_END()+"# en sortant d'ici. À la prochaine!",
/*spanish*/"!#^La marca que te guiará al #Templo del&Espíritu# es la #bandera que está a la&"+IF_NOT_MQ()+"izquierda"+MQ_ELSE()+"derecha"+MQ_END()+"# al salir de aquí. ¡Nos vemos!",
/*italian*/"!#^La direzione per il #Santuario dello Spirito# è indicata dalla #bandiera sulla "+IF_NOT_MQ()+"sinistra"+MQ_ELSE()+"destra"+MQ_END()+"# del negozio. A presto!",
/*german*/"#! Toll oder?^Das Zeichen, welches Euch zum&#Geistertempel# führt, ist die #Flagge&zur "+IF_NOT_MQ()+"Linken"+MQ_ELSE()+"Rechten"+MQ_END()+"# außerhalb des Ladens.^Schaut mal wieder vorbei!"},
Text{"Thank you very much!^What I'm selling is... "
"#%s!#^The mark that will lead you to the #Spirit&Temple# is the #flag on the "+IF_NOT_MQ()+"left"+MQ_ELSE()+"right"+MQ_END()+"# outside the shop. Be seeing you!",
/*french*/"Merci beaucoup!^Cet objet extraordinaire est... "
"#%s!#^La marque qui te mènera au #Temple de l'esprit# est le #drapeau "+IF_NOT_MQ()+"gauche"+MQ_ELSE()+"droite"+MQ_END()+"# en sortant d'ici. À la prochaine!",
/*spanish*/"¡Muchas gracias!^Lo que vendo es... "
"¡#%s!#^La marca que te guiará al #Templo del&Espíritu# es la #bandera que está a la&"+IF_NOT_MQ()+"izquierda"+MQ_ELSE()+"derecha"+MQ_END()+"# al salir de aquí. ¡Nos vemos!",
/*italian*/"Grazie!^Hai appena comprato... "
"#%s!#^La direzione per il #Santuario dello Spirito# è indicata dalla #bandiera sulla "+IF_NOT_MQ()+"sinistra"+MQ_ELSE()+"destra"+MQ_END()+"# del negozio. A presto!",
/*german*/"Vielen herzlichen Dank!&"
"#%s#! Toll oder?^Das Zeichen, welches Euch zum&#Geistertempel# führt, ist die #Flagge&zur "+IF_NOT_MQ()+"Linken"+MQ_ELSE()+"Rechten"+MQ_END()+"# außerhalb des Ladens.^Schaut mal wieder vorbei!"},
});

hintTable[GRANNY_DIALOG] = HintText::MerchantsDialogs({
Expand All @@ -2357,6 +2340,32 @@ void HintTable_Init() {
/*italian*/"! Che ne dici di #100 rupie#?&"+TWO_WAY_CHOICE()+"#Aggiudicato!&Non mi serve...#",
/*german*/"! Sagen wir #100 Rubine#!&"+TWO_WAY_CHOICE()+"#Gerne!&Auf keinen Fall!#"},
});

/*----------------------------------
| DAMPÉ DIARY TEXT |
-----------------------------------*/

hintTable[DAMPE_DIARY_HINT] = HintText::DampeHint({
// obscure text
Text{"Whoever reads this, please enter #%s#. I will let you have my stretching, shrinking #keepsake#.^I'm waiting for you.&--Dampé",
/*french*/"Toi, le petit curieux qui lit ce journal, viens dans #%s#. Et peut-être auras-tu droit à mon précieux #trésor#.^Je t'attends...&--Igor",
/*spanish*/"A quien lea estas palabras: Entra en #%s# y mi fantástico #tesoro# será para ti.^Te espero.&- Dampé",
/*italian*/"Chiunque legga questo, visiti #%s#. Gli darò il mio #tesoro# BOING BOING.^Firmato: Danpei",
/*german*/"Wer immer dies liest, der möge #%s# betreten. Ihm gebe ich meinen langen, kurzen #Schatz#^Ich warte! Boris"},
});

/*----------------------------------
| HOUSE OF SKULLTULA HINTS |
-----------------------------------*/

hintTable[HOUSE_OF_SKULLTULA_HINT] = HintText::SkulltulaHints({
// obscure text
Text{"Yeaaarrgh! I'm cursed!! Please save me by destroying #%d Spiders of the Curse# and I will give you #%s#.",
/*french*/"Beuaaaaark! Je suis maudit! Je t'en supplie, aide-moi en vainquant #%d araignées d'or# et je te donnerai #%s#.",
/*spanish*/"¡Grrrrrr! ¡Estoy maldito! Por favor, sálvame destruyendo #%d Arañas de la Maldición# y yo te daría #%s#.",
/*italian*/"Ahhhhhhhh! Questa maledizione è davvero terribile! Ti prego, salvami distruggendo #%d Aracnule d'oro# e ti darò #%s#.",
/*german*/"Aarrrgh! Ich bin verflucht!^Bitte rette mich, indem du #%d Skulltulas# zerstörst und ich werde dir dafür #%s# geben!"},
});
}
// clang-format on
s32 StonesRequiredBySettings() {
Expand Down
48 changes: 42 additions & 6 deletions source/hints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,36 @@ static void CreateGanonText() {
}
}

static void CreateDampeHint() {
auto hookshotLocation = FilterFromPool(
allLocations, [](const LocationKey loc) { return Location(loc)->GetPlacedItemKey() == PROGRESSIVE_HOOKSHOT; });

auto hookLocHint = hookshotLocation.empty()
? Hint(YOUR_POCKET)
: GetHintRegion(Location(hookshotLocation[0])->GetParentRegionKey())->GetHint();

auto dampeText = Hint(DAMPE_DIARY_HINT).GetText();
dampeText.Replace("%s", hookLocHint.GetText());
CreateMessageFromTextObject(0x5003, 0, 2, 3, AddColorsAndFormat(dampeText, { QM_PINK, QM_RED }));
}

static void CreateSkulltulaHints() {
// Create a message for each cursed man that gives a reward.
for (int i = 0; i < 5; i++) {
ItemLocation* location = Location(KAK_10_GOLD_SKULLTULA_REWARD + i);
Text rewardItemText = location->GetPlacedItem().GetHint().GetTextCopy();
rewardItemText.Replace("$", "");

Text hintText = Hint(HOUSE_OF_SKULLTULA_HINT).GetTextCopy();
hintText.Replace("%d", std::to_string((i + 1) * 10));
hintText.Replace("%s", rewardItemText);

CreateMessageFromTextObject(0x9400 + i, 0, 2, 3, AddColorsAndFormat(hintText, { QM_RED, QM_GREEN }));

location->SetAsHinted();
}
}

// Find the location which has the given itemKey and create the generic altar text for the reward
static Text BuildDungeonRewardText(ItemID itemID, const ItemKey itemKey) {
std::vector<LocationKey> itemKeyLocations = FilterFromPool(
Expand Down Expand Up @@ -813,6 +843,9 @@ void CreateMiscHints() {
if (GanonHints) {
CreateGanonText();
}
if (DampeHint) {
CreateDampeHint();
}
if (ToTAltarHints) {
CreateAltarText(rewardHints);
}
Expand All @@ -821,6 +854,9 @@ void CreateMiscHints() {
if (ShuffleMerchants.IsNot(SHUFFLEMERCHANTS_OFF)) {
CreateMerchantsHints();
}
if (SkulltulaHints) {
CreateSkulltulaHints();
}
}

void CreateMerchantsHints() {
Expand All @@ -842,13 +878,13 @@ void CreateMerchantsHints() {

Text grannyCapitalItemText = grannyItemText.Capitalize();

Text medigoronText =
Hint(MEDIGORON_DIALOG_FIRST).GetText() + medigoronItemText + Hint(MEDIGORON_DIALOG_SECOND).GetText();
Text medigoronText = Hint(MEDIGORON_DIALOG).GetText();
medigoronText.Replace("%s", medigoronItemText);
Text grannyText = grannyCapitalItemText + Hint(GRANNY_DIALOG).GetText();
Text carpetSalesmanTextOne = Hint(CARPET_SALESMAN_DIALOG_FIRST).GetText() + carpetSalesmanItemText +
Hint(CARPET_SALESMAN_DIALOG_SECOND).GetText();
Text carpetSalesmanTextTwo = Hint(CARPET_SALESMAN_DIALOG_THIRD).GetText() + carpetSalesmanItemClearText +
Hint(CARPET_SALESMAN_DIALOG_FOURTH).GetText();
Text carpetSalesmanTextOne = Hint(CARPET_SALESMAN_DIALOG_FIRST).GetText();
carpetSalesmanTextOne.Replace("%s", carpetSalesmanItemText);
Text carpetSalesmanTextTwo = Hint(CARPET_SALESMAN_DIALOG_SECOND).GetText();
carpetSalesmanTextTwo.Replace("%s", carpetSalesmanItemClearText);

CreateMessageFromTextObject(0x9120, 0, 2, 3, AddColorsAndFormat(medigoronText, { QM_RED, QM_GREEN }));
CreateMessageFromTextObject(0x9121, 0, 2, 3, AddColorsAndFormat(grannyText, { QM_RED, QM_GREEN }));
Expand Down
14 changes: 14 additions & 0 deletions source/hints.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ enum class HintCategory {
MasterSword,
GanonLine,
SheikLine,
DampeHint,
MerchantsDialogs,
SkulltulaHints,
};

class HintText {
Expand Down Expand Up @@ -156,6 +158,12 @@ class HintText {
HintCategory::MasterSword };
}

static auto DampeHint(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {},
Text&& clearText = {}) {
return HintText{ std::move(obscureText), std::move(ambiguousText), std::move(clearText),
HintCategory::DampeHint };
}

static auto GanonLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {},
Text&& clearText = {}) {
return HintText{ std::move(obscureText), std::move(ambiguousText), std::move(clearText),
Expand All @@ -174,6 +182,12 @@ class HintText {
HintCategory::MerchantsDialogs };
}

static auto SkulltulaHints(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {},
Text&& clearText = {}) {
return HintText{ std::move(obscureText), std::move(ambiguousText), std::move(clearText),
HintCategory::SkulltulaHints };
}

Text& GetObscure() {
return RandomElement(obscureText);
}
Expand Down
9 changes: 5 additions & 4 deletions source/keys.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1727,13 +1727,14 @@ typedef enum {
SHEIK_LINE02,
SHEIK_LINE03,

MEDIGORON_DIALOG_FIRST,
MEDIGORON_DIALOG_SECOND,
MEDIGORON_DIALOG,
CARPET_SALESMAN_DIALOG_FIRST,
CARPET_SALESMAN_DIALOG_SECOND,
CARPET_SALESMAN_DIALOG_THIRD,
CARPET_SALESMAN_DIALOG_FOURTH,
GRANNY_DIALOG,

DAMPE_DIARY_HINT,

HOUSE_OF_SKULLTULA_HINT,

KEY_ENUM_MAX,
} Key;
Loading

0 comments on commit c5eb90f

Please sign in to comment.