mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-25 17:48:50 -05:00
Merge branch 'rando-next' into rando-settings-menu-even-moar-changes
This commit is contained in:
commit
1c59995feb
@ -260,5 +260,6 @@ extern GraphicsContext* __gfxCtx;
|
||||
|
||||
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
|
||||
|
||||
#define NUM_TRIALS 6
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,8 @@ typedef enum {
|
||||
TEXT_BLUE_RUPEE = 0xCC,
|
||||
TEXT_RED_RUPEE = 0xF0,
|
||||
TEXT_PURPLE_RUPEE = 0xF1,
|
||||
TEXT_HUGE_RUPEE = 0xF2
|
||||
TEXT_HUGE_RUPEE = 0xF2,
|
||||
TEXT_BEAN_SALESMAN = 0x405E
|
||||
} TextIDs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -2517,18 +2517,16 @@ namespace Settings {
|
||||
BridgeRewardCount.SetSelectedIndex(cvarSettings[RSK_RAINBOW_BRIDGE_REWARD_COUNT]);
|
||||
BridgeDungeonCount.SetSelectedIndex(cvarSettings[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT]);
|
||||
BridgeTokenCount.SetSelectedIndex(cvarSettings[RSK_RAINBOW_BRIDGE_TOKEN_COUNT]);
|
||||
RandomGanonsTrials.SetSelectedIndex(cvarSettings[RSK_RANDOM_TRIALS]);
|
||||
// RANDTODO: Switch this back once Ganon's Trials Count is properly implemented.
|
||||
//GanonsTrialsCount.SetSelectedIndex(cvarSettings[RSK_TRIAL_COUNT]);
|
||||
switch (cvarSettings[RSK_TRIAL_COUNT]) {
|
||||
case 0:
|
||||
GanonsTrialsCount.SetSelectedIndex(6);
|
||||
break;
|
||||
case 1:
|
||||
GanonsTrialsCount.SetSelectedIndex(0);
|
||||
break;
|
||||
if (cvarSettings[RSK_RANDOM_TRIALS] == 2) {
|
||||
RandomGanonsTrials.SetSelectedIndex(1);
|
||||
} else {
|
||||
RandomGanonsTrials.SetSelectedIndex(0);
|
||||
}
|
||||
if (cvarSettings[RSK_RANDOM_TRIALS] == 0) {
|
||||
GanonsTrialsCount.SetSelectedIndex(0);
|
||||
} else {
|
||||
GanonsTrialsCount.SetSelectedIndex(cvarSettings[RSK_TRIAL_COUNT]);
|
||||
}
|
||||
|
||||
ShuffleRewards.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_DUNGEON_REWARDS]);
|
||||
ShuffleSongs.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_SONGS]);
|
||||
Tokensanity.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_TOKENS]);
|
||||
@ -2552,6 +2550,7 @@ namespace Settings {
|
||||
ShuffleFrogSongRupees.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_FROG_SONG_RUPEES]);
|
||||
|
||||
ShuffleAdultTradeQuest.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_ADULT_TRADE]);
|
||||
ShuffleMagicBeans.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_MAGIC_BEANS]);
|
||||
|
||||
// the checkbox works because 0 is "Off" and 1 is "Fairy Ocarina"
|
||||
StartingOcarina.SetSelectedIndex(cvarSettings[RSK_STARTING_OCARINA]);
|
||||
|
@ -501,25 +501,23 @@ static void WriteMasterQuestDungeons(tinyxml2::XMLDocument& spoilerLog) {
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the required trails to the spoiler log, if there are any.
|
||||
static void WriteRequiredTrials(tinyxml2::XMLDocument& spoilerLog) {
|
||||
auto parentNode = spoilerLog.NewElement("required-trials");
|
||||
|
||||
for (const auto* trial : Trial::trialList) {
|
||||
if (trial->IsSkipped()) {
|
||||
continue;
|
||||
// Writes the required trials to the spoiler log, if there are any.
|
||||
static void WriteRequiredTrials() {
|
||||
for (const auto& trial : Trial::trialList) {
|
||||
if (trial->IsRequired()) {
|
||||
std::string trialName;
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
trialName = trial->GetName().GetFrench();
|
||||
break;
|
||||
case LANGUAGE_ENG:
|
||||
default:
|
||||
trialName = trial->GetName().GetEnglish();
|
||||
break;
|
||||
}
|
||||
jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName));
|
||||
}
|
||||
}
|
||||
|
||||
auto node = parentNode->InsertNewChildElement("trial");
|
||||
// PURPLE TODO: LOCALIZATION
|
||||
std::string name = trial->GetName().GetEnglish();
|
||||
name[0] = toupper(name[0]); // Capitalize T in "The"
|
||||
node->SetAttribute("name", name.c_str());
|
||||
}
|
||||
|
||||
if (!parentNode->NoChildren()) {
|
||||
spoilerLog.RootElement()->InsertEndChild(parentNode);
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the intended playthrough to the spoiler log, separated into spheres.
|
||||
@ -723,7 +721,7 @@ const char* SpoilerLog_Write(int language) {
|
||||
// WriteEnabledGlitches(spoilerLog);
|
||||
//}
|
||||
//WriteMasterQuestDungeons(spoilerLog);
|
||||
//WriteRequiredTrials(spoilerLog);
|
||||
WriteRequiredTrials();
|
||||
WritePlaythrough();
|
||||
//WriteWayOfTheHeroLocation(spoilerLog);
|
||||
|
||||
@ -773,7 +771,7 @@ bool PlacementLog_Write() {
|
||||
WriteEnabledTricks(placementLog);
|
||||
WriteEnabledGlitches(placementLog);
|
||||
WriteMasterQuestDungeons(placementLog);
|
||||
WriteRequiredTrials(placementLog);
|
||||
//WriteRequiredTrials(placementLog);
|
||||
|
||||
placementtxt = "\n" + placementtxt;
|
||||
|
||||
|
@ -7,12 +7,12 @@ TrialInfo::TrialInfo(Text name_)
|
||||
|
||||
TrialInfo::~TrialInfo() = default;
|
||||
|
||||
TrialInfo ForestTrial = TrialInfo(Text{"the Forest Trial", /*french*/"l'épreuve de la forêt", /*spanish*/"la prueba del bosque"});
|
||||
TrialInfo FireTrial = TrialInfo(Text{"the Fire Trial", /*french*/"l'épreuve du feu", /*spanish*/"la prueba del fuego"});
|
||||
TrialInfo WaterTrial = TrialInfo(Text{"the Water Trial", /*french*/"l'épreuve de l'eau", /*spanish*/"la prueba del agua"});
|
||||
TrialInfo SpiritTrial = TrialInfo(Text{"the Spirit Trial", /*french*/"l'épreuve de l'esprit", /*spanish*/"la prueba del espíritu"});
|
||||
TrialInfo ShadowTrial = TrialInfo(Text{"the Shadow Trial", /*french*/"l'épreuve de l'ombre", /*spanish*/"la prueba de las sombras"});
|
||||
TrialInfo LightTrial = TrialInfo(Text{"the Light Trial", /*french*/"l'épreuve de la lumière", /*spanish*/"la prueba de la luz"});
|
||||
TrialInfo ForestTrial = TrialInfo(Text{"the Forest Trial", /*french*/"l'épreuve de la Forêt", /*spanish*/"la prueba del bosque"});
|
||||
TrialInfo FireTrial = TrialInfo(Text{"the Fire Trial", /*french*/"l'épreuve du Feu", /*spanish*/"la prueba del fuego"});
|
||||
TrialInfo WaterTrial = TrialInfo(Text{"the Water Trial", /*french*/"l'épreuve de l'Eau", /*spanish*/"la prueba del agua"});
|
||||
TrialInfo SpiritTrial = TrialInfo(Text{"the Spirit Trial", /*french*/"l'épreuve de l'Esprit", /*spanish*/"la prueba del espíritu"});
|
||||
TrialInfo ShadowTrial = TrialInfo(Text{"the Shadow Trial", /*french*/"l'épreuve de l'Ombre", /*spanish*/"la prueba de las sombras"});
|
||||
TrialInfo LightTrial = TrialInfo(Text{"the Light Trial", /*french*/"l'épreuve de la Lumière", /*spanish*/"la prueba de la luz"});
|
||||
|
||||
const TrialArray trialList = {
|
||||
&ForestTrial,
|
||||
|
@ -32,7 +32,7 @@ u8 generated;
|
||||
|
||||
const std::string Randomizer::getItemMessageTableID = "Randomizer";
|
||||
const std::string Randomizer::hintMessageTableID = "RandomizerHints";
|
||||
const std::string Randomizer::scrubMessageTableID = "RandomizerScrubs";
|
||||
const std::string Randomizer::merchantMessageTableID = "RandomizerMerchants";
|
||||
const std::string Randomizer::rupeeMessageTableID = "RandomizerRupees";
|
||||
const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
|
||||
|
||||
@ -107,6 +107,21 @@ Randomizer::~Randomizer() {
|
||||
this->randomizerMerchantPrices.clear();
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, RandomizerInf> spoilerFileTrialToEnum = {
|
||||
{ "the Forest Trial", RAND_INF_TRIALS_DONE_FOREST_TRIAL },
|
||||
{ "l'épreuve de la Forêt", RAND_INF_TRIALS_DONE_FOREST_TRIAL },
|
||||
{ "the Fire Trial", RAND_INF_TRIALS_DONE_FIRE_TRIAL },
|
||||
{ "l'épreuve du Feu", RAND_INF_TRIALS_DONE_FIRE_TRIAL },
|
||||
{ "the Water Trial", RAND_INF_TRIALS_DONE_WATER_TRIAL },
|
||||
{ "l'épreuve de l'Eau", RAND_INF_TRIALS_DONE_WATER_TRIAL },
|
||||
{ "the Spirit Trial", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL },
|
||||
{ "l'épreuve de l'Esprit", RAND_INF_TRIALS_DONE_SPIRIT_TRIAL },
|
||||
{ "the Shadow Trial", RAND_INF_TRIALS_DONE_SHADOW_TRIAL },
|
||||
{ "l'épreuve de l'Ombre", RAND_INF_TRIALS_DONE_SHADOW_TRIAL },
|
||||
{ "the Light Trial", RAND_INF_TRIALS_DONE_LIGHT_TRIAL },
|
||||
{ "l'épreuve de la Lumière", RAND_INF_TRIALS_DONE_LIGHT_TRIAL }
|
||||
};
|
||||
|
||||
std::unordered_map<s16, s16> getItemIdToItemId = {
|
||||
{ GI_BOW, ITEM_BOW },
|
||||
{ GI_ARROW_FIRE, ITEM_ARROW_FIRE },
|
||||
@ -551,6 +566,7 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn
|
||||
{ "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS },
|
||||
{ "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS },
|
||||
{ "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE },
|
||||
{ "Shuffle Settings:Shuffle Magic Beans", RSK_SHUFFLE_MAGIC_BEANS},
|
||||
{ "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD },
|
||||
{ "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD },
|
||||
{ "Start with Fairy Ocarina", RSK_STARTING_OCARINA },
|
||||
@ -672,6 +688,12 @@ void Randomizer::LoadItemLocations(const char* spoilerFileName, bool silent) {
|
||||
itemLocations[RC_UNKNOWN_CHECK] = RG_NONE;
|
||||
}
|
||||
|
||||
void Randomizer::LoadRequiredTrials(const char* spoilerFileName) {
|
||||
if (strcmp(spoilerFileName, "") != 0) {
|
||||
ParseRequiredTrialsFile(spoilerFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
|
||||
std::ifstream spoilerFileStream(sanitize(spoilerFileName));
|
||||
if (!spoilerFileStream)
|
||||
@ -788,6 +810,7 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
|
||||
case RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD:
|
||||
case RSK_SHUFFLE_COWS:
|
||||
case RSK_SHUFFLE_ADULT_TRADE:
|
||||
case RSK_SHUFFLE_MAGIC_BEANS:
|
||||
case RSK_RANDOM_TRIALS:
|
||||
case RSK_STARTING_DEKU_SHIELD:
|
||||
case RSK_STARTING_KOKIRI_SWORD:
|
||||
@ -1089,6 +1112,25 @@ void Randomizer::ParseHintLocationsFile(const char* spoilerFileName) {
|
||||
}
|
||||
}
|
||||
|
||||
void Randomizer::ParseRequiredTrialsFile(const char* spoilerFileName) {
|
||||
std::ifstream spoilerFileStream(sanitize(spoilerFileName));
|
||||
if (!spoilerFileStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
json spoilerFileJson;
|
||||
spoilerFileStream >> spoilerFileJson;
|
||||
json trialsJson = spoilerFileJson["requiredTrials"];
|
||||
|
||||
for (auto it = trialsJson.begin(); it != trialsJson.end(); it++) {
|
||||
this->trialsRequired[spoilerFileTrialToEnum[it.value()]] = true;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent) {
|
||||
std::ifstream spoilerFileStream(sanitize(spoilerFileName));
|
||||
if (!spoilerFileStream)
|
||||
@ -1139,6 +1181,10 @@ void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent
|
||||
}
|
||||
}
|
||||
|
||||
bool Randomizer::IsTrialRequired(RandomizerInf trial) {
|
||||
return this->trialsRequired.contains(trial);
|
||||
}
|
||||
|
||||
s16 Randomizer::GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) {
|
||||
s16 itemId = GetItemFromActor(actorId, actorParams, sceneNum, ogId);
|
||||
return itemId;
|
||||
@ -1211,8 +1257,6 @@ s16 Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) {
|
||||
|
||||
case RG_MAGIC_BEAN:
|
||||
return GI_BEAN;
|
||||
case RG_MAGIC_BEAN_PACK:
|
||||
return GI_BEAN; //todo make it 10 of them
|
||||
|
||||
case RG_WEIRD_EGG:
|
||||
return GI_WEIRD_EGG;
|
||||
@ -2900,6 +2944,7 @@ void GenerateRandomizerImgui() {
|
||||
cvarSettings[RSK_SHUFFLE_SCRUBS] = CVar_GetS32("gRandomizeShuffleScrubs", 0);
|
||||
cvarSettings[RSK_SHUFFLE_COWS] = CVar_GetS32("gRandomizeShuffleCows", 0);
|
||||
cvarSettings[RSK_SHUFFLE_ADULT_TRADE] = CVar_GetS32("gRandomizeShuffleAdultTrade", 0);
|
||||
cvarSettings[RSK_SHUFFLE_MAGIC_BEANS] = CVar_GetS32("gRandomizeShuffleBeans", 0);
|
||||
cvarSettings[RSK_SKIP_CHILD_ZELDA] = CVar_GetS32("gRandomizeSkipChildZelda", 0);
|
||||
|
||||
// if we skip child zelda, we start with zelda's letter, and malon starts
|
||||
@ -2980,7 +3025,7 @@ void DrawRandoEditor(bool& open) {
|
||||
const char* randoGerudoFortress[3] = { "Normal", "Fast", "Open" };
|
||||
const char* randoRainbowBridge[7] = { "Vanilla", "Always open", "Stones", "Medallions",
|
||||
"Dungeon rewards", "Dungeons", "Tokens" };
|
||||
const char* randoGanonsTrial[2] = { "Off", "On" };
|
||||
const char* randoGanonsTrial[3] = { "Skip", "Set Number", "Random Number" };
|
||||
|
||||
// World Settings
|
||||
const char* randoStartingAge[3] = { "Child", "Adult", "Random" };
|
||||
@ -3383,23 +3428,20 @@ void DrawRandoEditor(bool& open) {
|
||||
PaddedSeparator();
|
||||
|
||||
// Random Ganon's Trials
|
||||
/*
|
||||
ImGui::Text("Random Ganon's Trials");
|
||||
InsertHelpHoverText("Sets a random number or required trials to enter\nGanon's Tower.");
|
||||
SohImGui::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 2, 0);
|
||||
if (CVar_GetS32("gRandomizeGanonTrial", 0) == 0) {
|
||||
ImGui::PopItemWidth();
|
||||
SohImGui::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount",
|
||||
"gRandomizeGanonTrialCount", 0, 6, "", 6);
|
||||
InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower.");
|
||||
RANDTODO: Switch back to slider when pre-completing some of Ganon's Trials is properly implemnted.
|
||||
}
|
||||
*/
|
||||
|
||||
SohImGui::EnhancementCheckbox("Skip Ganon's Trials", "gRandomizeGanonTrialCount");
|
||||
ImGui::Text("Ganon's Trials");
|
||||
InsertHelpHoverText(
|
||||
"Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower."
|
||||
"Sets the number of Ganon's Trials required to dispel the barrier\n\n"
|
||||
"Skip - No Trials are required and the barrier is already dispelled.\n\n"
|
||||
"Set Number - Select a number of trials that will be required from the"
|
||||
"slider below. Which specific trials you need to complete will be random.\n\n"
|
||||
"Random Number - A Random number and set of trials will be required."
|
||||
);
|
||||
SohImGui::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 3, 0);
|
||||
if (CVar_GetS32("gRandomizeGanonTrial", 0) == 1) {
|
||||
SohImGui::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount",
|
||||
"gRandomizeGanonTrialCount", 1, 6, "", 6);
|
||||
InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower.");
|
||||
}
|
||||
|
||||
PaddedSeparator();
|
||||
|
||||
@ -4182,10 +4224,10 @@ void CreateGetItemMessages(std::vector<GetItemMessage> messageEntries) {
|
||||
|
||||
// Currently these are generated at runtime, one for each price between 0-95. We're soon going to migrate this
|
||||
// to being generated at save load, with only messages specific to each scrub.
|
||||
void CreateScrubMessages() {
|
||||
void CreateMerchantMessages() {
|
||||
CustomMessageManager* customMessageManager = CustomMessageManager::Instance;
|
||||
customMessageManager->AddCustomMessageTable(Randomizer::scrubMessageTableID);
|
||||
customMessageManager->CreateMessage(Randomizer::scrubMessageTableID, 0,
|
||||
customMessageManager->AddCustomMessageTable(Randomizer::merchantMessageTableID);
|
||||
customMessageManager->CreateMessage(Randomizer::merchantMessageTableID, 0,
|
||||
{ TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM,
|
||||
"\x12\x38\x82\All right! You win! In return for&sparing me, I will give you a&%gmysterious item%w!&Please, take it!\x07\x10\xA3",
|
||||
"\x12\x38\x82\In Ordnung! Du gewinnst! Im Austausch&dafür, dass du mich verschont hast,&werde ich dir einen %gmysteriösen&Gegenstand%w geben! Bitte nimm ihn!\x07\x10\xA3",
|
||||
@ -4193,7 +4235,7 @@ void CreateScrubMessages() {
|
||||
});
|
||||
|
||||
for (u32 price = 5; price <= 95; price += 5) {
|
||||
customMessageManager->CreateMessage(Randomizer::scrubMessageTableID, price,
|
||||
customMessageManager->CreateMessage(Randomizer::merchantMessageTableID, price,
|
||||
{ TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM,
|
||||
"\x12\x38\x82\All right! You win! In return for&sparing me, I will sell you a&%gmysterious item%w!&%r" +
|
||||
std::to_string(price) + " Rupees%w it is!\x07\x10\xA3",
|
||||
@ -4204,6 +4246,18 @@ void CreateScrubMessages() {
|
||||
std::to_string(price) + " Rubis%w!\x07\x10\xA3"
|
||||
});
|
||||
}
|
||||
customMessageManager->CreateMessage(
|
||||
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN,
|
||||
{
|
||||
TEXTBOX_TYPE_BLACK,
|
||||
TEXTBOX_POS_BOTTOM,
|
||||
"I tried to be a %rmagic bean%w salesman,&but it turns out my marketing skills&weren't worth "
|
||||
"beans!^Anyway, want to buy my&%gmysterious item%w for 60 Rupees?\x1B&%gYes&No%w",
|
||||
"Möchten Sie einen geheimnisvollen&Gegenstand für 60 Rubine?\x1B&%gJa&Nein%w",
|
||||
"J'ai essayé d'être un vendeur de&%rharicots magiques%w, mais j'étais&mauvais au niveau du marketing et&ça "
|
||||
"me courait sur le haricot...^Enfin bref, ça te dirait de m'acheter un&"
|
||||
"%gobjet mystérieux%w pour 60 Rubis?\x1B&%gOui&Non%w",
|
||||
});
|
||||
}
|
||||
|
||||
void CreateRupeeMessages() {
|
||||
@ -4348,75 +4402,122 @@ void Randomizer::CreateCustomMessages() {
|
||||
const std::vector<GetItemMessage> getItemMessages = {
|
||||
GIMESSAGE(RG_ICE_TRAP, ITEM_NONE, "\x08\x06\x30You are a %bFOWL%w!\x0E\x20",
|
||||
"\x08\x06\x15 Du bist ein %bDUMMKOPF%w!\x0E\x20", "\x08\x06\x50%bIDIOT%w\x0E\x20"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE,
|
||||
"You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!",
|
||||
"Vous obtenez une %rBouteille avec&une Flamme Bleue%w! Utilisez-la&pour faire fondre la %rGlace&Rouge%w!"),
|
||||
GIMESSAGE_NO_GERMAN(
|
||||
RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!",
|
||||
"Vous obtenez une %rBouteille avec&une Flamme Bleue%w! Utilisez-la&pour faire fondre la %rGlace&Rouge%w!"),
|
||||
GIMESSAGE_NO_GERMAN(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"),
|
||||
"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,
|
||||
"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!",
|
||||
"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,
|
||||
"You got a %rBottle of Red Potion%w!&Drink it to replenish your&%ghealth%w!",
|
||||
"Vous obtenez une %rBouteille avec&une Potion Rouge%w! Buvez-la pour&restaurer votre %rénergie vitale%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN,
|
||||
"You got a %rBottle of Green Potion%w!&Drink it to replenish your&%bmagic%w!",
|
||||
"Vous obtenez une %rBouteille avec&une Potion Verte%w! Buvez-la pour&restaurer votre %gmagie%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTLE_WITH_POE, ITEM_POE,
|
||||
"You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this...",
|
||||
"Vous obtenez une %rBouteille avec&un Esprit%w! Ça intéresserait&peut-être le vendeur d'Âme "),
|
||||
"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,
|
||||
"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!",
|
||||
"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,
|
||||
"You got a %rBottle of Red Potion%w!&Drink it to replenish your&%ghealth%w!",
|
||||
"Vous obtenez une %rBouteille avec&une Potion Rouge%w! Buvez-la pour&restaurer votre %rénergie vitale%w!"),
|
||||
GIMESSAGE_NO_GERMAN(
|
||||
RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN,
|
||||
"You got a %rBottle of Green Potion%w!&Drink it to replenish your&%bmagic%w!",
|
||||
"Vous obtenez une %rBouteille avec&une Potion Verte%w! Buvez-la pour&restaurer votre %gmagie%w!"),
|
||||
GIMESSAGE_NO_GERMAN(
|
||||
RG_BOTTLE_WITH_POE, ITEM_POE,
|
||||
"You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this...",
|
||||
"Vous obtenez une %rBouteille avec&un Esprit%w! Ça intéresserait&peut-être le vendeur d'Âme "),
|
||||
|
||||
GIMESSAGE_NO_GERMAN(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pBottom of the &Well %wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %Puits%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yGerudo Training &Grounds %wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!", "Vous obtenez une %rPetite Clé %w&du %Château de Ganon%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL,
|
||||
"You found a %pBottom of the &Well %wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %Puits%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL,
|
||||
"You found a %yGerudo Training &Grounds %wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!",
|
||||
"Vous obtenez une %rPetite Clé %w&du %Château de Ganon%w!"),
|
||||
|
||||
GIMESSAGE_NO_GERMAN(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!", "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!", "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!", "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!", "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!", "Vous obtenez la %rCarte %wdu &%pPuits%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!", "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!"),
|
||||
GIMESSAGE_NO_GERMAN(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_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_NO_GERMAN(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!",
|
||||
"Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!",
|
||||
"Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!",
|
||||
"Vous obtenez la %rCarte %wdu &%pPuits%w!"),
|
||||
GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!",
|
||||
"Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!"),
|
||||
|
||||
GIMESSAGE_NO_GERMAN(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 avez un %rPack de&haricots magiques%w ! Trouvez&un endroit convenable pour un&jardin et plantez-les.^Ensuite, attendez quelque&chose d'amusant doit arriver !")
|
||||
};
|
||||
CreateGetItemMessages(getItemMessages);
|
||||
CreateScrubMessages();
|
||||
CreateMerchantMessages();
|
||||
CreateRupeeMessages();
|
||||
CreateNaviRandoMessages();
|
||||
}
|
||||
@ -4513,6 +4614,7 @@ void InitRandoItemTable() {
|
||||
GET_ITEM(RG_SHADOW_TEMPLE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_SHADOW_TEMPLE_COMPASS),
|
||||
GET_ITEM(RG_BOTTOM_OF_THE_WELL_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_BOTTOM_OF_THE_WELL_COMPASS),
|
||||
GET_ITEM(RG_ICE_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_ICE_CAVERN_COMPASS),
|
||||
GET_ITEM(RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, MOD_RANDOMIZER, RG_MAGIC_BEAN_PACK)
|
||||
};
|
||||
ItemTableManager::Instance->AddItemTable(MOD_RANDOMIZER);
|
||||
for (int i = 0; i < ARRAY_COUNT(extendedVanillaGetItemTable); i++) {
|
||||
|
@ -14,6 +14,7 @@ class Randomizer {
|
||||
private:
|
||||
std::unordered_map<RandomizerCheck, RandomizerGet> itemLocations;
|
||||
std::unordered_map<RandomizerCheck, std::string> hintLocations;
|
||||
std::unordered_map<RandomizerInf, bool> trialsRequired;
|
||||
std::string childAltarText;
|
||||
std::string adultAltarText;
|
||||
std::string ganonHintText;
|
||||
@ -24,6 +25,7 @@ class Randomizer {
|
||||
s16 GetItemFromActor(s16 actorId, s16 actorParams, s16 sceneNum, GetItemID ogItemId);
|
||||
void ParseRandomizerSettingsFile(const char* spoilerFileName);
|
||||
void ParseHintLocationsFile(const char* spoilerFileName);
|
||||
void ParseRequiredTrialsFile(const char* spoilerFileName);
|
||||
void ParseItemLocationsFile(const char* spoilerFileName, bool silent);
|
||||
bool IsItemVanilla(RandomizerGet randoGet);
|
||||
|
||||
@ -34,7 +36,7 @@ class Randomizer {
|
||||
|
||||
static const std::string getItemMessageTableID;
|
||||
static const std::string hintMessageTableID;
|
||||
static const std::string scrubMessageTableID;
|
||||
static const std::string merchantMessageTableID;
|
||||
static const std::string rupeeMessageTableID;
|
||||
static const std::string NaviRandoMessageTableID;
|
||||
|
||||
@ -44,7 +46,9 @@ class Randomizer {
|
||||
bool SpoilerFileExists(const char* spoilerFileName);
|
||||
void LoadRandomizerSettings(const char* spoilerFileName);
|
||||
void LoadHintLocations(const char* spoilerFileName);
|
||||
void LoadItemLocations(const char* spoilerFileName, bool silent);
|
||||
void LoadRequiredTrials(const char* spoilerFileName);
|
||||
void LoadItemLocations(const char* spoilerFileName,bool silent);
|
||||
bool IsTrialRequired(RandomizerInf trial);
|
||||
u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey);
|
||||
RandomizerCheck GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams);
|
||||
std::string GetChildAltarText() const;
|
||||
|
@ -1016,7 +1016,8 @@ typedef enum {
|
||||
RSK_COMPLETE_MASK_QUEST,
|
||||
RSK_ENABLE_GLITCH_CUTSCENES,
|
||||
RSK_SKULLS_SUNS_SONG,
|
||||
RSK_SHUFFLE_ADULT_TRADE
|
||||
RSK_SHUFFLE_ADULT_TRADE,
|
||||
RSK_SHUFFLE_MAGIC_BEANS
|
||||
} RandomizerSettingKey;
|
||||
|
||||
typedef struct ScrubIdentity {
|
||||
|
@ -1562,10 +1562,18 @@ extern "C" void Randomizer_LoadHintLocations(const char* spoilerFileName) {
|
||||
OTRGlobals::Instance->gRandomizer->LoadHintLocations(spoilerFileName);
|
||||
}
|
||||
|
||||
extern "C" void Randomizer_LoadRequiredTrials(const char* spoilerFileName) {
|
||||
OTRGlobals::Instance->gRandomizer->LoadRequiredTrials(spoilerFileName);
|
||||
}
|
||||
|
||||
extern "C" void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent) {
|
||||
OTRGlobals::Instance->gRandomizer->LoadItemLocations(spoilerFileName, silent);
|
||||
}
|
||||
|
||||
extern "C" bool Randomizer_IsTrialRequired(RandomizerInf trial) {
|
||||
return OTRGlobals::Instance->gRandomizer->IsTrialRequired(trial);
|
||||
}
|
||||
|
||||
extern "C" bool SpoilerFileExists(const char* spoilerFileName) {
|
||||
return OTRGlobals::Instance->gRandomizer->SpoilerFileExists(spoilerFileName);
|
||||
}
|
||||
@ -1583,7 +1591,7 @@ extern "C" ScrubIdentity Randomizer_IdentifyScrub(s32 sceneNum, s32 actorParams,
|
||||
}
|
||||
|
||||
extern "C" CustomMessageEntry Randomizer_GetScrubMessage(s16 itemPrice) {
|
||||
return CustomMessageManager::Instance->RetrieveMessage(Randomizer::scrubMessageTableID, itemPrice);
|
||||
return CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, itemPrice);
|
||||
}
|
||||
|
||||
extern "C" CustomMessageEntry Randomizer_GetNaviMessage() {
|
||||
@ -1721,6 +1729,8 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) {
|
||||
// In rando, replace Navi's general overworld hints with rando-related gameplay tips
|
||||
} else if (CVar_GetS32("gRandoRelevantNavi", 1) && textId >= 0x0140 && textId <= 0x015F) {
|
||||
messageEntry = Randomizer_GetNaviMessage();
|
||||
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS) && textId == TEXT_BEAN_SALESMAN) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN);
|
||||
}
|
||||
}
|
||||
if (textId == TEXT_GS_NO_FREEZE || textId == TEXT_GS_FREEZE) {
|
||||
|
@ -98,7 +98,9 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
|
||||
RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum);
|
||||
ScrubIdentity Randomizer_IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData);
|
||||
void Randomizer_LoadHintLocations(const char* spoilerFileName);
|
||||
void Randomizer_LoadRequiredTrials(const char* spoilerFileName);
|
||||
void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent);
|
||||
bool Randomizer_IsTrialRequired(RandomizerInf trial);
|
||||
GetItemEntry Randomizer_GetRandomizedItem(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
|
||||
GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
|
||||
bool Randomizer_ObtainedFreestandingIceTrap(RandomizerCheck randomizerCheck, GetItemID ogId, Actor* actor);
|
||||
|
@ -1290,6 +1290,7 @@ void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetI
|
||||
switch (giEntry.itemId) {
|
||||
case RG_MAGIC_SINGLE:
|
||||
case RG_MAGIC_DOUBLE:
|
||||
case RG_MAGIC_BEAN_PACK:
|
||||
color_slot = 0;
|
||||
break;
|
||||
case RG_DOUBLE_DEFENSE:
|
||||
|
@ -2181,6 +2181,14 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
|
||||
return RG_NONE;
|
||||
}
|
||||
|
||||
if (item == RG_MAGIC_BEAN_PACK) {
|
||||
if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) {
|
||||
INV_CONTENT(ITEM_BEAN) = ITEM_BEAN;
|
||||
AMMO(ITEM_BEAN) = 10;
|
||||
}
|
||||
return RG_NONE;
|
||||
}
|
||||
|
||||
if (item == RG_DOUBLE_DEFENSE) {
|
||||
gSaveContext.doubleDefense = true;
|
||||
gSaveContext.inventory.defenseHearts = 20;
|
||||
@ -2227,9 +2235,9 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
|
||||
}
|
||||
}
|
||||
} else if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) ||
|
||||
(item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) ||
|
||||
(item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) ||
|
||||
(item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) {
|
||||
(item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) ||
|
||||
(item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) ||
|
||||
(item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) {
|
||||
int mapIndex = gSaveContext.mapIndex;
|
||||
switch (item) {
|
||||
case RG_DEKU_TREE_MAP:
|
||||
@ -2327,7 +2335,6 @@ u16 Randomizer_Item_Give(GlobalContext* globalCtx, GetItemEntry giEntry) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
u8 Item_CheckObtainability(u8 item) {
|
||||
s16 i;
|
||||
s16 slot = SLOT(item);
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include <string.h>
|
||||
#include <soh/Enhancements/randomizer/randomizerTypes.h>
|
||||
#include <soh/Enhancements/randomizer/randomizer_inf.h>
|
||||
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
|
||||
|
||||
#define NUM_DUNGEONS 8
|
||||
#define NUM_TRIALS 6
|
||||
#define NUM_COWS 10
|
||||
#define NUM_SCRUBS 35
|
||||
|
||||
@ -309,6 +309,11 @@ void GiveLinkDekuNutUpgrade(GetItemID giid) {
|
||||
}
|
||||
}
|
||||
|
||||
void GiveLinkSkullToken() {
|
||||
gSaveContext.inventory.questItems |= gBitFlags[QUEST_SKULL_TOKEN];
|
||||
gSaveContext.inventory.gsTokens++;
|
||||
}
|
||||
|
||||
void GiveLinkMagic(GetItemID giid) {
|
||||
if (giid == RG_MAGIC_SINGLE) {
|
||||
gSaveContext.magicLevel = 1;
|
||||
@ -508,6 +513,53 @@ void GiveLinkDungeonItem(GetItemID getItemId) {
|
||||
}
|
||||
}
|
||||
|
||||
void GiveLinkAdultTradeItem(GetItemID giid) {
|
||||
ItemID item;
|
||||
switch (giid) {
|
||||
case GI_POCKET_EGG:
|
||||
item = ITEM_POCKET_EGG;
|
||||
break;
|
||||
case GI_POCKET_CUCCO:
|
||||
item = ITEM_POCKET_CUCCO;
|
||||
break;
|
||||
case GI_COJIRO:
|
||||
item = ITEM_COJIRO;
|
||||
break;
|
||||
case GI_ODD_MUSHROOM:
|
||||
item = ITEM_ODD_MUSHROOM;
|
||||
break;
|
||||
case GI_ODD_POTION:
|
||||
item = ITEM_ODD_POTION;
|
||||
break;
|
||||
case GI_SAW:
|
||||
item = ITEM_SAW;
|
||||
break;
|
||||
case GI_SWORD_BROKEN:
|
||||
item = ITEM_SWORD_BROKEN;
|
||||
break;
|
||||
case GI_PRESCRIPTION:
|
||||
item = ITEM_PRESCRIPTION;
|
||||
break;
|
||||
case GI_FROG:
|
||||
item = ITEM_FROG;
|
||||
break;
|
||||
case GI_EYEDROPS:
|
||||
item = ITEM_EYEDROPS;
|
||||
break;
|
||||
case GI_CLAIM_CHECK:
|
||||
item = ITEM_CLAIM_CHECK;
|
||||
break;
|
||||
}
|
||||
if ((item == ITEM_SAW) && CVar_GetS32("gDekuNutUpgradeFix", 0) == 0) {
|
||||
gSaveContext.itemGetInf[1] |= 0x8000;
|
||||
}
|
||||
|
||||
if (item >= ITEM_POCKET_EGG) {
|
||||
gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(item);
|
||||
}
|
||||
INV_CONTENT(ITEM_TRADE_ADULT) = item;
|
||||
}
|
||||
|
||||
void GiveLinksPocketMedallion() {
|
||||
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
|
||||
|
||||
@ -709,6 +761,15 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
gSaveContext.randomizerInf[i] = 0;
|
||||
}
|
||||
|
||||
// Set all trials to cleared if trial count is random or anything other than 6
|
||||
if (Randomizer_GetSettingValue(RSK_RANDOM_TRIALS) || (Randomizer_GetSettingValue(RSK_TRIAL_COUNT) != 6)) {
|
||||
for (u16 i = RAND_INF_TRIALS_DONE_LIGHT_TRIAL; i <= RAND_INF_TRIALS_DONE_SHADOW_TRIAL; i++) {
|
||||
if (!Randomizer_IsTrialRequired(i)) {
|
||||
Flags_SetRandomizerInf(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set Cutscene flags to skip them
|
||||
gSaveContext.eventChkInf[0xC] |= 0x10; // returned to tot with medallions
|
||||
gSaveContext.eventChkInf[0xC] |= 0x20; //sheik at tot pedestal
|
||||
@ -735,6 +796,11 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
gSaveContext.eventChkInf[3] |= 0x800;
|
||||
gSaveContext.eventChkInf[12] |= 1;
|
||||
|
||||
// shuffle adult trade quest
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
gSaveContext.adultTradeItems = 0;
|
||||
}
|
||||
|
||||
// Give Link's pocket item
|
||||
GiveLinksPocketMedallion();
|
||||
|
||||
@ -849,6 +915,10 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
GiveLinkDekuStickUpgrade(giid);
|
||||
} else if (giid == GI_NUT_UPGRADE_30 || giid == GI_NUT_UPGRADE_40) {
|
||||
GiveLinkDekuNutUpgrade(giid);
|
||||
} else if (giid == GI_SKULL_TOKEN) {
|
||||
GiveLinkSkullToken();
|
||||
} else if (giid >= GI_POCKET_EGG && giid <= GI_CLAIM_CHECK || giid == GI_COJIRO) {
|
||||
GiveLinkAdultTradeItem(giid);
|
||||
} else {
|
||||
s32 iid = getItem.itemId;
|
||||
if (iid != -1) INV_CONTENT(iid) = iid;
|
||||
@ -965,11 +1035,6 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle adult trade quest
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
gSaveContext.adultTradeItems = 0;
|
||||
}
|
||||
|
||||
// complete mask quest
|
||||
if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) {
|
||||
gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask
|
||||
|
@ -64,12 +64,33 @@ static u8 sEnergyColors[] = {
|
||||
/* Forest prim */ 255, 255, 170, /* env */ 0, 200, 0,
|
||||
};
|
||||
|
||||
// Translates from the barrier's actor params to their corresponding randInf flags.
|
||||
RandomizerInf trialParamToRandInf(u16 params) {
|
||||
switch (params) {
|
||||
case KEKKAI_LIGHT:
|
||||
return RAND_INF_TRIALS_DONE_LIGHT_TRIAL;
|
||||
case KEKKAI_FOREST:
|
||||
return RAND_INF_TRIALS_DONE_FOREST_TRIAL;
|
||||
case KEKKAI_FIRE:
|
||||
return RAND_INF_TRIALS_DONE_FIRE_TRIAL;
|
||||
case KEKKAI_WATER:
|
||||
return RAND_INF_TRIALS_DONE_WATER_TRIAL;
|
||||
case KEKKAI_SPIRIT:
|
||||
return RAND_INF_TRIALS_DONE_SPIRIT_TRIAL;
|
||||
case KEKKAI_SHADOW:
|
||||
return RAND_INF_TRIALS_DONE_SHADOW_TRIAL;
|
||||
}
|
||||
}
|
||||
|
||||
s32 DemoKekkai_CheckEventFlag(s32 params) {
|
||||
static s32 eventFlags[] = { 0xC3, 0xBC, 0xBF, 0xBE, 0xBD, 0xAD, 0xBB };
|
||||
|
||||
if ((params < KEKKAI_TOWER) || (params > KEKKAI_FOREST)) {
|
||||
return true;
|
||||
}
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
return Flags_GetRandomizerInf(trialParamToRandInf(params));
|
||||
}
|
||||
return Flags_GetEventChkInf(eventFlags[params]);
|
||||
}
|
||||
|
||||
@ -128,8 +149,7 @@ void DemoKekkai_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
this->collider2.dim.yShift = 300;
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
int trialsToComplete = Randomizer_GetSettingValue(RSK_TRIAL_COUNT);
|
||||
if (trialsToComplete <= TrialsDoneCount()) {
|
||||
if (TrialsDoneCount() == NUM_TRIALS) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
@ -141,6 +161,10 @@ void DemoKekkai_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
case KEKKAI_SHADOW:
|
||||
case KEKKAI_SPIRIT:
|
||||
case KEKKAI_FOREST:
|
||||
if (gSaveContext.n64ddFlag && Flags_GetRandomizerInf(trialParamToRandInf(thisx->params))) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
this->energyAlpha = 1.0f;
|
||||
this->orbScale = 1.0f;
|
||||
Actor_SetScale(thisx, 0.1f);
|
||||
@ -247,27 +271,10 @@ void DemoKekkai_TrialBarrierDispel(Actor* thisx, GlobalContext* globalCtx) {
|
||||
DemoKekkai* this = (DemoKekkai*)thisx;
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
switch (thisx->params) {
|
||||
case KEKKAI_WATER:
|
||||
Flags_SetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL);
|
||||
break;
|
||||
case KEKKAI_LIGHT:
|
||||
Flags_SetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL);
|
||||
break;
|
||||
case KEKKAI_FIRE:
|
||||
Flags_SetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL);
|
||||
break;
|
||||
case KEKKAI_SHADOW:
|
||||
Flags_SetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL);
|
||||
break;
|
||||
case KEKKAI_SPIRIT:
|
||||
Flags_SetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL);
|
||||
break;
|
||||
case KEKKAI_FOREST:
|
||||
Flags_SetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL);
|
||||
break;
|
||||
}
|
||||
Flags_SetEventChkInf(eventFlags[thisx->params]);
|
||||
Flags_SetRandomizerInf(trialParamToRandInf(thisx->params));
|
||||
// May or may not be needed. Not sure if needed for anything
|
||||
// that randoInf isn't already covering. Leaving it for safety.
|
||||
Flags_SetEventChkInf(eventFlags[thisx->params]);
|
||||
}
|
||||
|
||||
if (globalCtx->csCtx.frames == csFrames[this->actor.params]) {
|
||||
|
@ -90,7 +90,16 @@ static void* sEyeTextures[] = {
|
||||
gMalonChildEyeClosedTex,
|
||||
};
|
||||
|
||||
bool Randomizer_ObtainedMalonHCReward() {
|
||||
return Flags_GetEventChkInf(0x12);
|
||||
}
|
||||
|
||||
u16 EnMa1_GetText(GlobalContext* globalCtx, Actor* thisx) {
|
||||
// Special case for Malon Hyrule Castle Text. Placing it here at the beginning
|
||||
// has the added benefit of circumventing mask text if wearing bunny hood.
|
||||
if (gSaveContext.n64ddFlag && globalCtx->sceneNum == SCENE_SPOT15) {
|
||||
return Randomizer_ObtainedMalonHCReward() ? 0x2044 : 0x2043;
|
||||
}
|
||||
u16 faceReaction = Text_GetFaceReaction(globalCtx, 0x17);
|
||||
|
||||
if (faceReaction != 0) {
|
||||
@ -191,25 +200,34 @@ s32 func_80AA08C4(EnMa1* this, GlobalContext* globalCtx) {
|
||||
if (!LINK_IS_CHILD) {
|
||||
return 0;
|
||||
}
|
||||
// Causes Malon to appear in the market if you haven't met her yet.
|
||||
if (((globalCtx->sceneNum == SCENE_MARKET_NIGHT) || (globalCtx->sceneNum == SCENE_MARKET_DAY)) &&
|
||||
!(gSaveContext.eventChkInf[1] & 0x10) && !(gSaveContext.infTable[8] & 0x800)) {
|
||||
return 1;
|
||||
}
|
||||
if ((globalCtx->sceneNum == SCENE_SPOT15) && !(gSaveContext.eventChkInf[1] & 0x10)) {
|
||||
if (gSaveContext.infTable[8] & 0x800) {
|
||||
return 1;
|
||||
} else {
|
||||
gSaveContext.infTable[8] |= 0x800;
|
||||
return 0;
|
||||
if ((globalCtx->sceneNum == SCENE_SPOT15) && // if we're at hyrule castle
|
||||
(!(gSaveContext.eventChkInf[1] & 0x10) || // and talon hasn't left
|
||||
(gSaveContext.n64ddFlag &&
|
||||
!Randomizer_ObtainedMalonHCReward()))) { // or we're rando'd and haven't gotten malon's HC check
|
||||
if (gSaveContext.infTable[8] & 0x800) { // if we've met malon
|
||||
return 1; // make her appear at the castle
|
||||
} else { // if we haven't met malon
|
||||
gSaveContext.infTable[8] |= 0x800; // set the flag for meeting malon
|
||||
return 0; // don't make her appear at the castle
|
||||
}
|
||||
}
|
||||
// Malon asleep in her bed if Talon has left Hyrule Castle and it is nighttime.
|
||||
if ((globalCtx->sceneNum == SCENE_SOUKO) && IS_NIGHT && (gSaveContext.eventChkInf[1] & 0x10)) {
|
||||
return 1;
|
||||
}
|
||||
// Don't spawn Malon if none of the above are true and we are not in Lon Lon Ranch.
|
||||
if (globalCtx->sceneNum != SCENE_SPOT20) {
|
||||
return 0;
|
||||
}
|
||||
if ((this->actor.shape.rot.z == 3) && IS_DAY && (gSaveContext.eventChkInf[1] & 0x10)) {
|
||||
// If we've gotten this far, we're in Lon Lon Ranch. Spawn Malon if it is daytime, Talon has left Hyrule Castle, and
|
||||
// either we are not randomized, or we are and we have received Malon's item at Hyrule Castle.
|
||||
if ((this->actor.shape.rot.z == 3) && IS_DAY && (gSaveContext.eventChkInf[1] & 0x10) &&
|
||||
((gSaveContext.n64ddFlag && Randomizer_ObtainedMalonHCReward()) || !gSaveContext.n64ddFlag)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -290,10 +308,16 @@ void EnMa1_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
this->actor.targetMode = 6;
|
||||
this->unk_1E8.unk_00 = 0;
|
||||
|
||||
if (!(gSaveContext.eventChkInf[1] & 0x10) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !gSaveContext.n64ddFlag) ||
|
||||
// To avoid missing a check, we want Malon to have the actionFunc for singing, but not reacting to Ocarina, if any of
|
||||
// the following are true.
|
||||
// 1. Talon has not left Hyrule Castle.
|
||||
// 2. We are Randomized and have not obtained Malon's Weird Egg Check.
|
||||
// 3. We are not Randomized and have obtained Epona's Song
|
||||
if (!(gSaveContext.eventChkInf[1] & 0x10) || (gSaveContext.n64ddFlag && !Randomizer_ObtainedMalonHCReward()) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !gSaveContext.n64ddFlag) ||
|
||||
(gSaveContext.n64ddFlag && Flags_GetTreasure(globalCtx, 0x1F))) {
|
||||
this->actionFunc = func_80AA0D88;
|
||||
EnMa1_ChangeAnim(this, ENMA1_ANIM_2);
|
||||
// If none of the above conditions were true, set Malon up to teach Epona's Song.
|
||||
} else {
|
||||
if (gSaveContext.n64ddFlag) { // Skip straight to "let's sing it together" textbox in the ranch
|
||||
gSaveContext.eventChkInf[1] |= 0x40;
|
||||
@ -322,9 +346,16 @@ void func_80AA0D88(EnMa1* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((globalCtx->sceneNum == SCENE_SPOT15) && (gSaveContext.eventChkInf[1] & 0x10)) {
|
||||
// We want to Kill Malon's Actor outside of randomizer when Talon is freed. In Randomizer we don't kill Malon's
|
||||
// Actor here, otherwise if we wake up Talon first and then get her check she will spontaneously
|
||||
// disappear.
|
||||
if ((globalCtx->sceneNum == SCENE_SPOT15) && (!gSaveContext.n64ddFlag && gSaveContext.eventChkInf[1] & 0x10)) {
|
||||
Actor_Kill(&this->actor);
|
||||
} else if (!(gSaveContext.eventChkInf[1] & 0x10) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !gSaveContext.n64ddFlag)) {
|
||||
// We want Malon to give the Weird Egg Check (see function below) in the following situations:
|
||||
// 1. Talon as not left Hyrule Castle (Vanilla) OR
|
||||
// 2. We haven't obtained Malon's Weird Egg Check (Randomizer only) OR
|
||||
// 3. We have Epona's Song? (Vanilla only, not sure why it's here but I didn't write that one)
|
||||
} else if ((!(gSaveContext.eventChkInf[1] & 0x10) || (gSaveContext.n64ddFlag && !Randomizer_ObtainedMalonHCReward())) || (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && !gSaveContext.n64ddFlag)) {
|
||||
if (this->unk_1E8.unk_00 == 2) {
|
||||
this->actionFunc = func_80AA0EA0;
|
||||
globalCtx->msgCtx.stateTimer = 4;
|
||||
|
@ -125,11 +125,19 @@ void EnMs_Talk(EnMs* this, GlobalContext* globalCtx) {
|
||||
} else if (Message_ShouldAdvance(globalCtx)) {
|
||||
switch (globalCtx->msgCtx.choiceIndex) {
|
||||
case 0: // yes
|
||||
if (gSaveContext.rupees < sPrices[BEANS_BOUGHT]) {
|
||||
if (gSaveContext.rupees <
|
||||
((gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS))
|
||||
? 60
|
||||
: sPrices[BEANS_BOUGHT])) {
|
||||
Message_ContinueTextbox(globalCtx, 0x4069); // not enough rupees text
|
||||
return;
|
||||
}
|
||||
func_8002F434(&this->actor, globalCtx, GI_BEAN, 90.0f, 10.0f);
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) {
|
||||
GiveItemEntryFromActor(&this->actor, globalCtx,
|
||||
Randomizer_GetItemFromKnownCheck(RC_ZR_MAGIC_BEAN_SALESMAN, GI_BEAN), 90.0f, 10.0f);
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_BEAN, 90.0f, 10.0f);
|
||||
}
|
||||
this->actionFunc = EnMs_Sell;
|
||||
return;
|
||||
case 1: // no
|
||||
@ -142,11 +150,18 @@ void EnMs_Talk(EnMs* this, GlobalContext* globalCtx) {
|
||||
|
||||
void EnMs_Sell(EnMs* this, GlobalContext* globalCtx) {
|
||||
if (Actor_HasParent(&this->actor, globalCtx)) {
|
||||
Rupees_ChangeBy(-sPrices[BEANS_BOUGHT]);
|
||||
Rupees_ChangeBy((gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) ? -60 : -sPrices[BEANS_BOUGHT]);
|
||||
this->actor.parent = NULL;
|
||||
this->actionFunc = EnMs_TalkAfterPurchase;
|
||||
this->actionFunc =
|
||||
(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) ? EnMs_Wait : EnMs_TalkAfterPurchase;
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_BEAN, 90.0f, 10.0f);
|
||||
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS)) {
|
||||
GiveItemEntryFromActor(&this->actor, globalCtx,
|
||||
Randomizer_GetItemFromKnownCheck(RC_ZR_MAGIC_BEAN_SALESMAN, GI_BEAN), 90.0f, 10.0f);
|
||||
BEANS_BOUGHT = 10;
|
||||
} else {
|
||||
func_8002F434(&this->actor, globalCtx, GI_BEAN, 90.0f, 10.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +135,27 @@ void ObjectKankyo_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
this->effects[5].size = 0.0f;
|
||||
}
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FOREST_TRIAL)) {
|
||||
this->effects[0].size = 0.0f;
|
||||
}
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_WATER_TRIAL)) {
|
||||
this->effects[1].size = 0.0f;
|
||||
}
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SHADOW_TRIAL)) {
|
||||
this->effects[2].size = 0.0f;
|
||||
}
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_FIRE_TRIAL)) {
|
||||
this->effects[3].size = 0.0f;
|
||||
}
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_LIGHT_TRIAL)) {
|
||||
this->effects[4].size = 0.0f;
|
||||
}
|
||||
if (Flags_GetRandomizerInf(RAND_INF_TRIALS_DONE_SPIRIT_TRIAL)) {
|
||||
this->effects[5].size = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSaveContext.cutsceneTrigger != 0) {
|
||||
if (gSaveContext.entranceIndex == 0x0538) {
|
||||
this->effects[0].size = 0.1f;
|
||||
|
@ -433,6 +433,7 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
|
||||
const char* fileLoc = CVar_GetString("gSpoilerLog", "");
|
||||
Randomizer_LoadSettings(fileLoc);
|
||||
Randomizer_LoadHintLocations(fileLoc);
|
||||
Randomizer_LoadRequiredTrials(fileLoc);
|
||||
Randomizer_LoadItemLocations(fileLoc, silent);
|
||||
fileSelectSpoilerFileLoaded = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user