mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-23 16:48:52 -05:00
Refactor Hint Creation and add support for hint Copies and fixed number of hints. (#3205)
* Initial implementation of no-duplicates of special hints * stupid fixes * Impa's song will no longer be hinted when you skip child zelda * fix building * Fix Loading spoiler logs causing corrupt hints, remove disabled warp song shuffle text from spoiler logs * Remove Sheik and Saria hints from the spoiler log when are not enabled * Prevent Magic hinted by Saria and Light Arrows hinted by Sheik from being hinted elsewhere unless they are locked by that item. * Prevent the Final Frogs gossip stone hint from spawning when the special final frogs hint is enabled. * Fix building after rebasing in deduplication * redelete keys.hpp * Remove Sheik and Saria hints from the spoiler log when are not enabled * Prevent the Final Frogs gossip stone hint from spawning when the special final frogs hint is enabled. * First part of copies implementation * Refactor hint system (broken) * fix building * fix obvious errors * fix fixed hints doubling after failing to place a hint * Fix bugs with hint distrabution * Split PlaceRandomHint and fix hint bugs * Merge special hint functions, move special hint text to the HintTable, expand LightArrow hint category into OtherHint category. * Fix remaining hint distribution errors * Forgot to stage dampe diary update * Restore building after conflict resolution * fix SetAllInRegionAsHinted
This commit is contained in:
parent
15ebcd30fb
commit
051314e8b1
@ -1098,20 +1098,13 @@ int Fill() {
|
|||||||
printf("Done");
|
printf("Done");
|
||||||
ctx->CreateItemOverrides();
|
ctx->CreateItemOverrides();
|
||||||
CreateEntranceOverrides();
|
CreateEntranceOverrides();
|
||||||
//Always execute ganon hint generation for the funny line
|
|
||||||
CreateGanonAndSheikText();
|
//funny ganon line
|
||||||
CreateAltarText();
|
Text ganonText = RandomElement(GetHintCategory(HintCategory::GanonLine)).GetText();
|
||||||
CreateDampesDiaryText();
|
CreateMessageFromTextObject(0x70CB, 0, 2, 3, AddColorsAndFormat(ganonText));
|
||||||
CreateGregRupeeHint();
|
SetGanonText(ganonText);
|
||||||
CreateSariaText();
|
|
||||||
if (GossipStoneHints.IsNot(HINTS_NO_HINTS)) {
|
|
||||||
printf("\x1b[10;10HCreating Hints...");
|
|
||||||
CreateAllHints();
|
CreateAllHints();
|
||||||
printf("Done");
|
|
||||||
}
|
|
||||||
if (ShuffleMerchants.Is(SHUFFLEMERCHANTS_HINTS)) {
|
|
||||||
CreateMerchantsHints();
|
|
||||||
}
|
|
||||||
CreateWarpSongTexts();
|
CreateWarpSongTexts();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ void ClearProgress();
|
|||||||
void VanillaFill();
|
void VanillaFill();
|
||||||
int Fill();
|
int Fill();
|
||||||
|
|
||||||
|
std::vector<RandomizerCheck> GetEmptyLocations(std::vector<RandomizerCheck> allowedLocations);
|
||||||
|
|
||||||
std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<RandomizerCheck>& allowedLocations,
|
std::vector<RandomizerCheck> GetAccessibleLocations(const std::vector<RandomizerCheck>& allowedLocations,
|
||||||
SearchMode mode = SearchMode::ReachabilitySearch, std::string ignore = "",
|
SearchMode mode = SearchMode::ReachabilitySearch, std::string ignore = "",
|
||||||
bool checkPoeCollectorAccess = false,
|
bool checkPoeCollectorAccess = false,
|
||||||
|
@ -472,7 +472,7 @@ void HintTable_Init() {
|
|||||||
Text{ "a #cow behind webs# in a grotto gifts", /*french*/ "la #vache derrière les toiles# d'une grotte donne",
|
Text{ "a #cow behind webs# in a grotto gifts", /*french*/ "la #vache derrière les toiles# d'une grotte donne",
|
||||||
/*spanish*/ "una #vaca tras la telaraña# de una cueva brinda" });
|
/*spanish*/ "una #vaca tras la telaraña# de una cueva brinda" });
|
||||||
|
|
||||||
hintTable[RHT_ZR_FROGS_OCARINA_GAME] = HintText::Always(
|
hintTable[RHT_ZR_FROGS_OCARINA_GAME] = HintText::Sometimes(
|
||||||
{
|
{
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{ "an #amphibian feast# yields", /*french*/ "un #festin d'amphibiens# donne",
|
Text{ "an #amphibian feast# yields", /*french*/ "un #festin d'amphibiens# donne",
|
||||||
@ -2949,7 +2949,7 @@ void HintTable_Init() {
|
|||||||
| LIGHT ARROW LOCATION TEXT|
|
| LIGHT ARROW LOCATION TEXT|
|
||||||
---------------------------*/
|
---------------------------*/
|
||||||
|
|
||||||
hintTable[RHT_LIGHT_ARROW_LOCATION_HINT] = HintText::LightArrow({
|
hintTable[RHT_LIGHT_ARROW_LOCATION_HINT] = HintText::OtherHint({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{
|
Text{
|
||||||
"Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from ",
|
"Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from ",
|
||||||
@ -2959,7 +2959,7 @@ void HintTable_Init() {
|
|||||||
"Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de " },
|
"Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de " },
|
||||||
});
|
});
|
||||||
|
|
||||||
hintTable[RHT_SHEIK_LIGHT_ARROW_HINT] = HintText::LightArrow({
|
hintTable[RHT_SHEIK_LIGHT_ARROW_HINT] = HintText::OtherHint({
|
||||||
// obscure text
|
// obscure text
|
||||||
Text{
|
Text{
|
||||||
"I overheard Ganondorf say that he misplaced the %yLight Arrows%w in&%r",
|
"I overheard Ganondorf say that he misplaced the %yLight Arrows%w in&%r",
|
||||||
@ -2974,6 +2974,70 @@ void HintTable_Init() {
|
|||||||
Text{ "your pocket", /*french*/ "tes poches", /*spanish*/ "tu bolsillo" },
|
Text{ "your pocket", /*french*/ "tes poches", /*spanish*/ "tu bolsillo" },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*--------------------------
|
||||||
|
| OTHER HINT TEXT |
|
||||||
|
---------------------------*/
|
||||||
|
|
||||||
|
hintTable[RHT_DAMPE_DIARY01] = HintText::OtherHint({
|
||||||
|
// obscure text
|
||||||
|
Text{
|
||||||
|
"Whoever reads this, please enter %r",
|
||||||
|
/*french*/
|
||||||
|
"Toi qui lit ce journal, rends-toi dans %r",
|
||||||
|
/*german?*/
|
||||||
|
"Wer immer dies liest, der möge folgenden Ort aufsuchen: %r"},
|
||||||
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_DAMPE_DIARY02] = HintText::OtherHint({
|
||||||
|
// obscure text
|
||||||
|
Text{
|
||||||
|
"%w. I will let you have my stretching, shrinking keepsake.^I'm waiting for you.&--Dampé",
|
||||||
|
/*french*/
|
||||||
|
"%w. Et peut-être auras-tu droit à mon précieux %rtrésor%w.^Je t'attends...&--Igor",
|
||||||
|
/*german?*/
|
||||||
|
"%w. Ihm gebe ich meinen langen, kurzen Schatz.^Ich warte!&Boris"},
|
||||||
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_GREG_HINT01] = HintText::OtherHint({
|
||||||
|
// obscure text
|
||||||
|
Text{
|
||||||
|
"By the way, if you're interested, I saw the shiniest %gGreen Rupee%w somewhere in%g ",
|
||||||
|
/*french*/
|
||||||
|
"Au fait, si ça t'intéresse, j'ai aperçu le plus éclatant des %gRubis Verts%w quelque part à %g",
|
||||||
|
/*spanish*/
|
||||||
|
""},
|
||||||
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_GREG_HINT02] = HintText::OtherHint({
|
||||||
|
// obscure text
|
||||||
|
Text{
|
||||||
|
"%w.^It's said to have %rmysterious powers%w...^But then, it could just be another regular rupee.&Oh well.",
|
||||||
|
/*french*/
|
||||||
|
"%w. On dit qu'il possède des pouvoirs mystérieux... Mais bon, ça pourrait juste être un autre rubis ordinaire.",
|
||||||
|
/*spanish*/
|
||||||
|
""},
|
||||||
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_SARIA_TEXT01] = HintText::OtherHint({
|
||||||
|
// obscure text
|
||||||
|
Text{
|
||||||
|
"Did you feel the %gsurge of magic%w recently? A mysterious bird told me it came from %g",
|
||||||
|
/*french*/
|
||||||
|
"As-tu récemment ressenti une vague de %gpuissance magique%w? Un mystérieux hibou m'a dit qu'elle provenait du %g",
|
||||||
|
/*spanish*/
|
||||||
|
""},
|
||||||
|
});
|
||||||
|
|
||||||
|
hintTable[RHT_SARIA_TEXT02] = HintText::OtherHint({
|
||||||
|
// obscure text
|
||||||
|
Text{
|
||||||
|
"%w.^You should check that place out, @!$C",
|
||||||
|
/*french*/
|
||||||
|
"%w. Tu devrais aller y jeter un coup d'oeil, @!$C",
|
||||||
|
/*spanish*/
|
||||||
|
"%w.$C"},
|
||||||
|
});
|
||||||
|
|
||||||
/*--------------------------
|
/*--------------------------
|
||||||
| GANON LINE TEXT |
|
| GANON LINE TEXT |
|
||||||
---------------------------*/
|
---------------------------*/
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
struct HintDistributionSetting {
|
struct HintDistributionSetting {
|
||||||
HintType type;
|
HintType type;
|
||||||
uint8_t order;
|
|
||||||
size_t weight;
|
size_t weight;
|
||||||
uint8_t fixed;
|
uint8_t fixed;
|
||||||
uint8_t copies;
|
uint8_t copies;
|
||||||
@ -42,7 +41,7 @@ enum class HintCategory {
|
|||||||
LACS,
|
LACS,
|
||||||
Altar,
|
Altar,
|
||||||
Validation,
|
Validation,
|
||||||
LightArrow,
|
OtherHint,
|
||||||
GanonLine,
|
GanonLine,
|
||||||
MerchantsDialogs,
|
MerchantsDialogs,
|
||||||
};
|
};
|
||||||
@ -112,9 +111,9 @@ public:
|
|||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Validation};
|
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Validation};
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto LightArrow(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
static auto OtherHint(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LightArrow};
|
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::OtherHint};
|
||||||
} //RANDOTODO Concert to generic special hints?
|
}
|
||||||
|
|
||||||
static auto GanonLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
static auto GanonLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
|
||||||
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine};
|
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine};
|
||||||
@ -197,22 +196,17 @@ using ConditionalAlwaysHint = std::pair<RandomizerCheck, std::function<bool()>>;
|
|||||||
|
|
||||||
//10 dungeons as GTG and GC are excluded
|
//10 dungeons as GTG and GC are excluded
|
||||||
extern std::array<DungeonInfo, 10> dungeonInfoData;
|
extern std::array<DungeonInfo, 10> dungeonInfoData;
|
||||||
|
|
||||||
extern std::array<ConditionalAlwaysHint, 10> conditionalAlwaysHints;
|
extern std::array<ConditionalAlwaysHint, 10> conditionalAlwaysHints;
|
||||||
|
|
||||||
extern RandomizerHintTextKey GetHintRegionHintKey(const RandomizerRegion area);
|
extern RandomizerHintTextKey GetHintRegionHintKey(const RandomizerRegion area);
|
||||||
extern void CreateAllHints();
|
extern void CreateAllHints();
|
||||||
extern void CreateMerchantsHints();
|
|
||||||
extern void CreateWarpSongTexts();
|
extern void CreateWarpSongTexts();
|
||||||
extern void CreateDampesDiaryText();
|
|
||||||
extern void CreateGregRupeeHint();
|
|
||||||
extern void CreateSariaText();
|
|
||||||
extern void CreateGanonAndSheikText();
|
|
||||||
extern void CreateAltarText();
|
|
||||||
|
|
||||||
Text& GetChildAltarText();
|
Text& GetChildAltarText();
|
||||||
Text& GetAdultAltarText();
|
Text& GetAdultAltarText();
|
||||||
Text& GetGanonText();
|
Text& GetGanonText();
|
||||||
|
void SetGanonText(Text text);
|
||||||
Text& GetGanonHintText();
|
Text& GetGanonHintText();
|
||||||
Text& GetDampeHintText();
|
Text& GetDampeHintText();
|
||||||
Text& GetGregHintText();
|
Text& GetGregHintText();
|
||||||
@ -226,6 +220,7 @@ Text& GetWarpRequiemText();
|
|||||||
Text& GetWarpNocturneText();
|
Text& GetWarpNocturneText();
|
||||||
Text& GetWarpPreludeText();
|
Text& GetWarpPreludeText();
|
||||||
|
|
||||||
std::string GetDampeHintLoc();
|
|
||||||
std::string GetLightArrowHintLoc();
|
std::string GetLightArrowHintLoc();
|
||||||
|
std::string GetDampeHintLoc();
|
||||||
|
std::string GetGregHintLoc();
|
||||||
std::string GetSariaHintLoc();
|
std::string GetSariaHintLoc();
|
||||||
|
@ -37,7 +37,7 @@ using json = nlohmann::ordered_json;
|
|||||||
json jsonData;
|
json jsonData;
|
||||||
std::map<RandomizerHintTextKey, Rando::ItemLocation*> hintedLocations;
|
std::map<RandomizerHintTextKey, Rando::ItemLocation*> hintedLocations;
|
||||||
|
|
||||||
extern std::unordered_map<HintType, std::string> hintTypeNames;
|
extern std::array<std::string, HINT_TYPE_MAX> hintTypeNames;
|
||||||
extern std::array<std::string, 17> hintCategoryNames;
|
extern std::array<std::string, 17> hintCategoryNames;
|
||||||
extern Area* GetHintRegion(uint32_t);
|
extern Area* GetHintRegion(uint32_t);
|
||||||
|
|
||||||
@ -775,7 +775,7 @@ static void WriteHints(int language) {
|
|||||||
}
|
}
|
||||||
if (Settings::GregHintText){
|
if (Settings::GregHintText){
|
||||||
jsonData["gregText"] = gregText;
|
jsonData["gregText"] = gregText;
|
||||||
jsonData["gregLoc"] = Rando::StaticData::GetLocation(GetItemLocation(RG_GREG_RUPEE)->GetRandomizerCheck())->GetName();
|
jsonData["gregLoc"] = GetGregHintLoc();
|
||||||
}
|
}
|
||||||
if (Settings::SariaHintText){
|
if (Settings::SariaHintText){
|
||||||
jsonData["sariaText"] = sariaText;
|
jsonData["sariaText"] = sariaText;
|
||||||
@ -804,16 +804,16 @@ static void WriteHints(int language) {
|
|||||||
|
|
||||||
std::string textStr = AutoFormatHintTextString(unformattedHintTextString);
|
std::string textStr = AutoFormatHintTextString(unformattedHintTextString);
|
||||||
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["hint"] = textStr;
|
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["hint"] = textStr;
|
||||||
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["type"] = hintTypeNames.find(hintType)->second;
|
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["type"] = hintTypeNames[(int)hintType];
|
||||||
if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_NAMED_ITEM || hintType == HINT_TYPE_WOTH) {
|
if ((hintType >= HINT_TYPE_ALWAYS && hintType < HINT_TYPE_JUNK) || hintType == HINT_TYPE_WOTH) {
|
||||||
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["item"] = hintedLocation->GetPlacedItemName().GetEnglish();
|
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["item"] = hintedLocation->GetPlacedItemName().GetEnglish();
|
||||||
if (hintType != HINT_TYPE_NAMED_ITEM || hintType == HINT_TYPE_WOTH) {
|
if (hintType != HINT_TYPE_NAMED_ITEM) {
|
||||||
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["location"] =
|
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["location"] =
|
||||||
Rando::StaticData::GetLocation(hintedLocation->GetRandomizerCheck())->GetName();
|
Rando::StaticData::GetLocation(hintedLocation->GetRandomizerCheck())->GetName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hintType != HINT_TYPE_TRIAL && hintType != HINT_TYPE_JUNK) {
|
if (hintType != HINT_TYPE_TRIAL && hintType != HINT_TYPE_JUNK) {
|
||||||
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["area"] = hint->GetHintedRegion();
|
jsonData["hints"][Rando::StaticData::GetLocation(key)->GetName()]["area"] = hint->GetHintedRegion(); //RANDOTODO find elegent way to capitalise this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ extern "C" uint32_t ResourceMgr_IsGameMasterQuest();
|
|||||||
extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
|
extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
|
||||||
|
|
||||||
extern std::map<RandomizerCheckArea, std::string> rcAreaNames;
|
extern std::map<RandomizerCheckArea, std::string> rcAreaNames;
|
||||||
extern std::unordered_map<HintType, std::string> hintTypeNames;
|
extern std::array<std::string, HINT_TYPE_MAX> hintTypeNames;
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
@ -139,6 +139,18 @@ Randomizer::Randomizer() {
|
|||||||
item.GetName().french,
|
item.GetName().french,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
for (auto area : rcAreaNames) {
|
||||||
|
SpoilerfileAreaNameToEnum[area.second] = area.first;
|
||||||
|
}
|
||||||
|
SpoilerfileAreaNameToEnum["Inside Ganon's Castle"] = RCAREA_GANONS_CASTLE;
|
||||||
|
SpoilerfileAreaNameToEnum["the Lost Woods"] = RCAREA_LOST_WOODS;
|
||||||
|
SpoilerfileAreaNameToEnum["the Market"] = RCAREA_MARKET;
|
||||||
|
SpoilerfileAreaNameToEnum["the Graveyard"] = RCAREA_GRAVEYARD;
|
||||||
|
SpoilerfileAreaNameToEnum["Haunted Wasteland"] = RCAREA_WASTELAND;
|
||||||
|
SpoilerfileAreaNameToEnum["outside Ganon's Castle"] = RCAREA_HYRULE_CASTLE;
|
||||||
|
for (int c = 0; c < hintTypeNames.size(); c++) {
|
||||||
|
SpoilerfileHintTypeNameToEnum[hintTypeNames[c]] = (HintType)c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite* Randomizer::GetSeedTexture(uint8_t index) {
|
Sprite* Randomizer::GetSeedTexture(uint8_t index) {
|
||||||
|
@ -31,23 +31,23 @@ typedef enum {
|
|||||||
} RandomizerCheckStatus;
|
} RandomizerCheckStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
HINT_TYPE_STATIC,
|
||||||
HINT_TYPE_TRIAL,
|
HINT_TYPE_TRIAL,
|
||||||
HINT_TYPE_ALWAYS,
|
|
||||||
HINT_TYPE_WOTH, // Way of the Hero
|
HINT_TYPE_WOTH, // Way of the Hero
|
||||||
HINT_TYPE_BARREN,
|
HINT_TYPE_BARREN,
|
||||||
HINT_TYPE_ENTRANCE,
|
HINT_TYPE_ENTRANCE,
|
||||||
|
HINT_TYPE_ALWAYS,
|
||||||
HINT_TYPE_SOMETIMES,
|
HINT_TYPE_SOMETIMES,
|
||||||
HINT_TYPE_RANDOM,
|
|
||||||
HINT_TYPE_ITEM,
|
|
||||||
HINT_TYPE_SONG,
|
HINT_TYPE_SONG,
|
||||||
HINT_TYPE_OVERWORLD,
|
HINT_TYPE_OVERWORLD,
|
||||||
HINT_TYPE_DUNGEON,
|
HINT_TYPE_DUNGEON,
|
||||||
HINT_TYPE_JUNK,
|
|
||||||
HINT_TYPE_NAMED_ITEM,
|
HINT_TYPE_NAMED_ITEM,
|
||||||
HINT_TYPE_STATIC, // For special hints, like Light Arrows or Hookshot Hints
|
HINT_TYPE_RANDOM,
|
||||||
|
HINT_TYPE_JUNK,
|
||||||
HINT_TYPE_MAX
|
HINT_TYPE_MAX
|
||||||
} HintType;
|
} HintType;
|
||||||
|
|
||||||
|
|
||||||
// Check types based on main settings
|
// Check types based on main settings
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RCTYPE_STANDARD, // Base set of rando checks
|
RCTYPE_STANDARD, // Base set of rando checks
|
||||||
@ -3182,6 +3182,13 @@ typedef enum {
|
|||||||
RHT_SHEIK_LIGHT_ARROW_HINT,
|
RHT_SHEIK_LIGHT_ARROW_HINT,
|
||||||
// Your Pocket
|
// Your Pocket
|
||||||
RHT_YOUR_POCKET,
|
RHT_YOUR_POCKET,
|
||||||
|
// Other Hints
|
||||||
|
RHT_DAMPE_DIARY01,
|
||||||
|
RHT_DAMPE_DIARY02,
|
||||||
|
RHT_GREG_HINT01,
|
||||||
|
RHT_GREG_HINT02,
|
||||||
|
RHT_SARIA_TEXT01,
|
||||||
|
RHT_SARIA_TEXT02,
|
||||||
// Ganon Line
|
// Ganon Line
|
||||||
RHT_GANON_LINE01,
|
RHT_GANON_LINE01,
|
||||||
RHT_GANON_LINE02,
|
RHT_GANON_LINE02,
|
||||||
|
Loading…
Reference in New Issue
Block a user