Implement Mask Hints

This commit is contained in:
Pepper0ni 2024-05-15 21:51:16 +01:00
parent baf7691fbd
commit 64227e46b3
10 changed files with 34 additions and 10 deletions

View File

@ -74,6 +74,7 @@ typedef enum {
TEXT_SARIAS_SONG_IMPRISON_GANONDORF = 0x016C,
TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D,
TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x01B3, // 0x1yy for Navi msg range
TEXT_MASK_SHOP_SIGN = 0x0207,
TEXT_FROGS_UNDERWATER = 0x022E,
TEXT_GF_HBA_SIGN = 0x031A,
TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x0346, // 0x3yy for cuttable sign range

View File

@ -2861,6 +2861,10 @@ void StaticData::HintTable_Init() {
/*french*/ "Yeaaarrgh! Je suis maudit!^Détruit encore #[[d]] Araignées de la Malédiction# et j'aurai quelque chose à te donner! #([[1]])#",
{QM_YELLOW, QM_GREEN}));
hintTextTable[RHT_MASK_SHOP_HINT] = HintText(CustomMessage("Some young scrubs in the #Deku Theatre# love seeing Masks!^"
"They'll give you #[[1]]# if you show them the #Skull Mask#, and #[[2]]# if you show them the #Mask of Truth#!",
{QM_GREEN, QM_GREEN, QM_RED, QM_GREEN, QM_RED}));
/*--------------------------
| GANON LINE TEXT |
---------------------------*/

View File

@ -277,7 +277,7 @@ std::vector<std::pair<RandomizerCheck, std::function<bool()>>> conditionalAlways
}), // Remember, the option's value being 3 means 4 are required
std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, []() {
auto ctx = Rando::Context::GetInstance();
return !ctx->GetOption(RSK_COMPLETE_MASK_QUEST);
return !ctx->GetOption(RSK_MASK_SHOP_HINT) && !ctx->GetOption(RSK_COMPLETE_MASK_QUEST);
}),
std::make_pair(RC_SONG_FROM_OCARINA_OF_TIME, []() { return StonesRequiredBySettings() < 2; }),
std::make_pair(RC_HF_OCARINA_OF_TIME_ITEM, []() { return StonesRequiredBySettings() < 2; }),

View File

@ -191,9 +191,11 @@ void AreaTable_Init_CastleTown() {
areaTable[RR_MARKET_MASK_SHOP] = Area("Market Mask Shop", "Market Mask Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->SkullMask, {[]{return logic->SkullMask || (logic->ZeldasLetter && (randoCtx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}}),
EventAccess(&logic->SkullMask, {[]{return logic->SkullMask || (logic->ZeldasLetter && (randoCtx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link'd pocket
EventAccess(&logic->MaskOfTruth, {[]{return logic->MaskOfTruth || (logic->SkullMask && (randoCtx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && AreaTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->HasAllStones)));}}),
}, {}, {
}, {
LocationAccess(RC_MASK_SHOP_HINT, {[]{return true;}}),
}, {
//Exits
Entrance(RR_THE_MARKET, {[]{return true;}}),
});

View File

@ -558,7 +558,8 @@ std::vector<RandomizerCheck> Rando::StaticData::staticHintLocations = {
RC_SARIA_SONG_HINT,
RC_ALTAR_HINT_CHILD,
RC_ALTAR_HINT_ADULT,
RC_FISHING_POLE_HINT
RC_FISHING_POLE_HINT,
RC_MASK_SHOP_HINT,
};
std::vector<RandomizerCheck> Rando::StaticData::pondFishLocations = {
@ -1564,6 +1565,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Child Altar Hint");
locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Adult Altar Hint");
locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_LAKE_HYLIA, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint");
locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, RCTYPE_GOSSIP_STONE, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint");
locationTable[RC_TRIFORCE_COMPLETED] = Location::Reward(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP);
// clang-format on

View File

@ -532,6 +532,7 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_KAK_40_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 40 tokens will tell you the reward";
mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 50 tokens will tell you the reward";
mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 100 tokens will tell you the reward";
mOptionDescriptions[RSK_MASK_SHOP_HINT] = "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre.";
mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees.";
mOptionDescriptions[RSK_BOMBCHUS_IN_LOGIC] =

View File

@ -1489,6 +1489,7 @@ typedef enum {
RC_ALTAR_HINT_CHILD,
RC_ALTAR_HINT_ADULT,
RC_FISHING_POLE_HINT,
RC_MASK_SHOP_HINT,
RC_DMC_UPPER_GROTTO_FISH,
RC_DMT_STORMS_GROTTO_FISH,
RC_HF_SOUTHEAST_GROTTO_FISH,
@ -2086,6 +2087,7 @@ typedef enum {
RH_KAK_40_SKULLS_HINT,
RH_KAK_50_SKULLS_HINT,
RH_KAK_100_SKULLS_HINT,
RH_MASK_SHOP_HINT,
RH_MAX,
} RandomizerHint;
@ -3447,6 +3449,7 @@ typedef enum {
RHT_BIGGORON_HINT,
RHT_FROGS_HINT,
RHT_SKULLS_HINT,
RHT_MASK_SHOP_HINT,
// Ganon Line
RHT_GANON_JOKE01,
RHT_GANON_JOKE02,
@ -3607,6 +3610,7 @@ typedef enum {
RSK_KAK_40_SKULLS_HINT,
RSK_KAK_50_SKULLS_HINT,
RSK_KAK_100_SKULLS_HINT,
RSK_MASK_SHOP_HINT,
RSK_BIGGORON_HINT,
RSK_BIG_POES_HINT,
RSK_CHICKENS_HINT,

View File

@ -176,7 +176,8 @@ void Settings::CreateOptions() {
mOptions[RSK_KAK_30_SKULLS_HINT] = Option::Bool("30 GS Hint", CVAR_RANDOMIZER_SETTING("30GSHint"), mOptionDescriptions[RSK_KAK_30_SKULLS_HINT], IMFLAG_NONE);
mOptions[RSK_KAK_40_SKULLS_HINT] = Option::Bool("40 GS Hint", CVAR_RANDOMIZER_SETTING("40GSHint"), mOptionDescriptions[RSK_KAK_40_SKULLS_HINT], IMFLAG_NONE);
mOptions[RSK_KAK_50_SKULLS_HINT] = Option::Bool("50 GS Hint", CVAR_RANDOMIZER_SETTING("50GSHint"), mOptionDescriptions[RSK_KAK_50_SKULLS_HINT], IMFLAG_NONE);
mOptions[RSK_KAK_100_SKULLS_HINT] = Option::Bool("100 GS Hint", CVAR_RANDOMIZER_SETTING("100GSHint"), mOptionDescriptions[RSK_KAK_100_SKULLS_HINT]);
mOptions[RSK_KAK_100_SKULLS_HINT] = Option::Bool("100 GS Hint", CVAR_RANDOMIZER_SETTING("100GSHint"), mOptionDescriptions[RSK_KAK_100_SKULLS_HINT], IMFLAG_NONE);
mOptions[RSK_MASK_SHOP_HINT] = Option::Bool("Mask Shop Hint", CVAR_RANDOMIZER_SETTING("MaksShopHint"), mOptionDescriptions[RSK_MASK_SHOP_HINT]);
// TODO: Compasses show rewards/woth, maps show dungeon mode
mOptions[RSK_BLUE_FIRE_ARROWS] = Option::Bool("Blue Fire Arrows", CVAR_RANDOMIZER_SETTING("BlueFireArrows"), mOptionDescriptions[RSK_BLUE_FIRE_ARROWS]);
mOptions[RSK_SUNLIGHT_ARROWS] = Option::Bool("Sunlight Arrows", CVAR_RANDOMIZER_SETTING("SunlightArrows"), mOptionDescriptions[RSK_SUNLIGHT_ARROWS]);
@ -745,7 +746,8 @@ void Settings::CreateOptions() {
&mOptions[RSK_KAK_30_SKULLS_HINT],
&mOptions[RSK_KAK_40_SKULLS_HINT],
&mOptions[RSK_KAK_50_SKULLS_HINT],
&mOptions[RSK_KAK_100_SKULLS_HINT]
&mOptions[RSK_KAK_100_SKULLS_HINT],
&mOptions[RSK_MASK_SHOP_HINT]
}, false, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones.");
mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = OptionGroup::SubGroup("Item Pool & Hints", std::initializer_list<OptionGroup*>{
&mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI],
@ -974,6 +976,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_KAK_40_SKULLS_HINT],
&mOptions[RSK_KAK_50_SKULLS_HINT],
&mOptions[RSK_KAK_100_SKULLS_HINT],
&mOptions[RSK_MASK_SHOP_HINT],
&mOptions[RSK_SCRUB_TEXT_HINT],
&mOptions[RSK_FISHING_POLE_HINT],
// TODO: Compasses show Reward/WOTH, Maps show Dungeon Mode, Starting Time
@ -1185,7 +1188,8 @@ void Settings::CreateOptions() {
{ "Miscellaneous Settings:30 GS Hint", RSK_KAK_30_SKULLS_HINT },
{ "Miscellaneous Settings:40 GS Hint", RSK_KAK_40_SKULLS_HINT },
{ "Miscellaneous Settings:50 GS Hint", RSK_KAK_50_SKULLS_HINT },
{ "Miscellaneous Settings:50 GS Hint", RSK_KAK_100_SKULLS_HINT },
{ "Miscellaneous Settings:100 GS Hint", RSK_KAK_100_SKULLS_HINT },
{ "Miscellaneous Settings:Mask Shop Hint", RSK_MASK_SHOP_HINT },
{ "Miscellaneous Settings:Biggoron's Hint", RSK_BIGGORON_HINT },
{ "Miscellaneous Settings:Big Poes Hint", RSK_BIG_POES_HINT },
{ "Miscellaneous Settings:Warp Song Hints", RSK_WARP_SONG_HINTS },
@ -2294,6 +2298,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
case RSK_KAK_40_SKULLS_HINT:
case RSK_KAK_50_SKULLS_HINT:
case RSK_KAK_100_SKULLS_HINT:
case RSK_MASK_SHOP_HINT:
case RSK_BIGGORON_HINT:
case RSK_BIG_POES_HINT:
case RSK_CHICKENS_HINT:

View File

@ -93,7 +93,8 @@ std::unordered_map<uint32_t, CustomMessage> StaticData::hintNames = {
{RH_KAK_30_SKULLS_HINT, CustomMessage("30 Skulls Hint")},
{RH_KAK_40_SKULLS_HINT, CustomMessage("40 Skulls Hint")},
{RH_KAK_50_SKULLS_HINT, CustomMessage("50 Skulls Hint")},
{RH_KAK_100_SKULLS_HINT, CustomMessage("100 Skulls Hint")}
{RH_KAK_100_SKULLS_HINT, CustomMessage("100 Skulls Hint")},
{RH_MASK_SHOP_HINT, CustomMessage("Mask Shop Hint")},
};
std::unordered_map<RandomizerCheck, RandomizerHint> StaticData::gossipStoneCheckToHint {
@ -203,7 +204,7 @@ std::unordered_map<RandomizerHint, StaticHintInfo> StaticData::staticHintInfoMap
{RH_CARPET_SALESMAN, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_CARPET_SALESMAN_DIALOG_HINTED}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_WASTELAND_BOMBCHU_SALESMAN})},
{RH_BEAN_SALESMAN, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_BEAN_SALESMAN_HINT}, RSK_SHUFFLE_MAGIC_BEANS, true, {RC_ZR_MAGIC_BEAN_SALESMAN})},
{RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})},
{RH_MALON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_MALON_HINT_TURNING_EVIL, RHT_MALON_HINT_HOW_IS_EPONA, RHT_MALON_HINT_OBSTICLE_COURSE, RHT_MALON_HINT_INGO_TEMPTED},RSK_MALON_HINT, true, {RC_KF_LINKS_HOUSE_COW})},
{RH_MALON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_MALON_HINT_TURNING_EVIL, RHT_MALON_HINT_HOW_IS_EPONA, RHT_MALON_HINT_OBSTICLE_COURSE, RHT_MALON_HINT_INGO_TEMPTED}, RSK_MALON_HINT, true, {RC_KF_LINKS_HOUSE_COW})},
{RH_BIG_POES_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_BIG_POES_HINT}, RSK_BIG_POES_HINT, true, {RC_MARKET_10_BIG_POES})},
{RH_CHICKENS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_CHICKENS_HINT}, RSK_CHICKENS_HINT, true, {RC_KAK_ANJU_AS_CHILD})},
{RH_BIGGORON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_BIGGORON_HINT}, RSK_BIGGORON_HINT, true, {RC_DMT_TRADE_CLAIM_CHECK})},
@ -213,7 +214,8 @@ std::unordered_map<RandomizerHint, StaticHintInfo> StaticData::staticHintInfoMap
{RH_KAK_30_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_30_SKULLS_HINT, true, {RC_KAK_30_GOLD_SKULLTULA_REWARD}, {}, {}, false, 30)},
{RH_KAK_40_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_40_SKULLS_HINT, true, {RC_KAK_40_GOLD_SKULLTULA_REWARD}, {}, {}, false, 40)},
{RH_KAK_50_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_50_SKULLS_HINT, true, {RC_KAK_50_GOLD_SKULLTULA_REWARD}, {}, {}, false, 50)},
{RH_KAK_100_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_100_SKULLS_HINT, true, {RC_KAK_100_GOLD_SKULLTULA_REWARD}, {}, {}, false, 100)}
{RH_KAK_100_SKULLS_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_SKULLS_HINT}, RSK_KAK_100_SKULLS_HINT, true, {RC_KAK_100_GOLD_SKULLTULA_REWARD}, {}, {}, false, 100)},
{RH_MASK_SHOP_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_MASK_SHOP_HINT}, RSK_MASK_SHOP_HINT, true, {RC_DEKU_THEATER_SKULL_MASK, RC_DEKU_THEATER_MASK_OF_TRUTH}, {}, {RC_MASK_SHOP_HINT})}
};
std::unordered_map<std::string, uint32_t> StaticData::PopulateTranslationMap(std::unordered_map<uint32_t, CustomMessage> input){

View File

@ -2754,6 +2754,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
else if (textId == TEXT_HBA_ALREADY_HAVE_1000 && ctx->GetOption(RSK_HBA_HINT)) {
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3);
}
else if (textId == TEXT_MASK_SHOP_SIGN && ctx->GetOption(RSK_MASK_SHOP_HINT)) {
messageEntry = ctx->GetHint(RH_MASK_SHOP_HINT)->GetHintMessage(MF_AUTO_FORMAT);
}
}
if (textId == TEXT_GS_NO_FREEZE || textId == TEXT_GS_FREEZE) {
if (CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0) != 0) {