Mask improvements (#3431)

* Add gKeepMasks

* Add gSaveMasksToFile

* Add gKeepMasksOnDeath & gKeepBunnyHoodThroughTime

* Fix mask bleedthrough

* Update cvar names

* Change bunny hood enhancements to all mask ones

* Consolidate multiple enhancements into PersistentMasks

* Move keeping masks thru loading zones to PersistentMasks

* I forgot

* Update z_player.c

* Update z64save.h

Merge commit excluded this removal for some reason.

---------

Co-authored-by: Malkierian <malkierian@gmail.com>
Co-authored-by: Malkierian <malkierian@live.com>
This commit is contained in:
Pepe20129 2024-10-11 01:16:41 +02:00 committed by GitHub
parent 62713bb551
commit 70a2141351
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 72 additions and 61 deletions

View File

@ -280,6 +280,7 @@ typedef struct {
/* */ u8 pendingIceTrapCount; /* */ u8 pendingIceTrapCount;
/* */ SohStats sohStats; /* */ SohStats sohStats;
/* */ FaroresWindData backupFW; /* */ FaroresWindData backupFW;
/* */ u8 maskMemory;
// #endregion // #endregion
// #region SOH [Randomizer] // #region SOH [Randomizer]
// Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer

View File

@ -83,7 +83,7 @@ const std::vector<const char*> enhancementsCvars = {
CVAR_ENHANCEMENT("NoForcedNavi"), CVAR_ENHANCEMENT("NoForcedNavi"),
CVAR_ENHANCEMENT("SkulltulaFreeze"), CVAR_ENHANCEMENT("SkulltulaFreeze"),
CVAR_ENHANCEMENT("MMBunnyHood"), CVAR_ENHANCEMENT("MMBunnyHood"),
CVAR_ENHANCEMENT("AdultBunnyHood"), CVAR_ENHANCEMENT("AdultMasks"),
CVAR_ENHANCEMENT("FastChests"), CVAR_ENHANCEMENT("FastChests"),
CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"),
CVAR_ENHANCEMENT("FastDrops"), CVAR_ENHANCEMENT("FastDrops"),
@ -698,7 +698,7 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
// MM Bunny Hood // MM Bunny Hood
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP),
// Adult Bunny Hood // Adult Bunny Hood
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
// Fast Chests // Fast Chests
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1),
// Fast Drops // Fast Drops
@ -825,7 +825,7 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
// MM Bunny Hood // MM Bunny Hood
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP),
// Adult Bunny Hood // Adult Bunny Hood
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
// Fast Chests // Fast Chests
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1),
// Fast Drops // Fast Drops
@ -931,7 +931,7 @@ const std::vector<PresetEntry> spockRacePresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1),
@ -1003,7 +1003,7 @@ const std::vector<PresetEntry> spockRacePresetEntries = {
}; };
const std::vector<PresetEntry> spockRaceNoLogicPresetEntries = { const std::vector<PresetEntry> spockRaceNoLogicPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1),
PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1), PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1),
@ -1099,7 +1099,7 @@ const std::vector<PresetEntry> s6PresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN),
@ -1133,7 +1133,7 @@ const std::vector<PresetEntry> hellModePresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE),

View File

@ -858,6 +858,7 @@ void SaveManager::InitFileNormal() {
gSaveContext.pendingSaleMod = MOD_NONE; gSaveContext.pendingSaleMod = MOD_NONE;
gSaveContext.isBossRushPaused = 0; gSaveContext.isBossRushPaused = 0;
gSaveContext.pendingIceTrapCount = 0; gSaveContext.pendingIceTrapCount = 0;
gSaveContext.maskMemory = PLAYER_MASK_NONE;
// Init with normal quest unless only an MQ rom is provided // Init with normal quest unless only an MQ rom is provided
gSaveContext.questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER; gSaveContext.questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
@ -2178,6 +2179,7 @@ void SaveManager::LoadBaseVersion4() {
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.backupFW.tempCollectFlags); SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.backupFW.tempCollectFlags);
}); });
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams); SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
SaveManager::Instance->LoadData("maskMemory", gSaveContext.maskMemory);
} }
void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSave) { void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSave) {
@ -2347,6 +2349,7 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
SaveManager::Instance->SaveData("tempCollectFlags", saveContext->backupFW.tempCollectFlags); SaveManager::Instance->SaveData("tempCollectFlags", saveContext->backupFW.tempCollectFlags);
}); });
SaveManager::Instance->SaveData("dogParams", saveContext->dogParams); SaveManager::Instance->SaveData("dogParams", saveContext->dogParams);
SaveManager::Instance->SaveData("maskMemory", saveContext->maskMemory);
} }
// Load a string into a char array based on size and ensuring it is null terminated when overflowed // Load a string into a char array based on size and ensuring it is null terminated when overflowed

View File

@ -778,8 +778,17 @@ void DrawEnhancementsMenu() {
"Wearing the Bunny Hood grants a speed increase like in Majora's Mask. The longer jump option is not accounted for in randomizer logic.\n\n" "Wearing the Bunny Hood grants a speed increase like in Majora's Mask. The longer jump option is not accounted for in randomizer logic.\n\n"
"Also disables NPC's reactions to wearing the Bunny Hood." "Also disables NPC's reactions to wearing the Bunny Hood."
); );
UIWidgets::PaddedEnhancementCheckbox("Bunny Hood Equippable as Adult", CVAR_ENHANCEMENT("AdultBunnyHood"), true, false, (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) == BUNNY_HOOD_VANILLA), "Only available with increased bunny hood speed", UIWidgets::CheckboxGraphics::Cross, false); UIWidgets::PaddedEnhancementCheckbox("Masks Equippable as Adult", CVAR_ENHANCEMENT("AdultMasks"), true, false);
UIWidgets::Tooltip("Allows the bunny hood to be equipped normally from the pause menu as adult."); UIWidgets::Tooltip("Allows masks to be equipped normally from the pause menu as adult.");
UIWidgets::PaddedEnhancementCheckbox("Persistent masks", CVAR_ENHANCEMENT("PersistentMasks"), true, false);
UIWidgets::Tooltip(
"Stops masks from automatically unequipping on certain situations:\n"
"- When entering a new scene\n"
"- When not in any C button or the D-Pad\n"
"- When saving and quitting\n"
"- When dying\n"
"- When traveling thru time (if \"Masks Equippable as Adult\" is activated)"
);
UIWidgets::PaddedEnhancementCheckbox("Mask Select in Inventory", CVAR_ENHANCEMENT("MaskSelect"), true, false); UIWidgets::PaddedEnhancementCheckbox("Mask Select in Inventory", CVAR_ENHANCEMENT("MaskSelect"), true, false);
UIWidgets::Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks"); UIWidgets::Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks");
UIWidgets::PaddedEnhancementCheckbox("Nuts explode bombs", CVAR_ENHANCEMENT("NutsExplodeBombs"), true, false); UIWidgets::PaddedEnhancementCheckbox("Nuts explode bombs", CVAR_ENHANCEMENT("NutsExplodeBombs"), true, false);

View File

@ -539,14 +539,19 @@ void Play_Init(GameState* thisx) {
(s32)(zAllocAligned + zAllocSize) - (s32)(zAllocAligned - zAlloc)); (s32)(zAllocAligned + zAllocSize) - (s32)(zAllocAligned - zAlloc));
Fault_AddClient(&D_801614B8, ZeldaArena_Display, NULL, NULL); Fault_AddClient(&D_801614B8, ZeldaArena_Display, NULL, NULL);
// In order to keep bunny hood equipped on first load, we need to pre-set the age reqs for the item and slot // In order to keep masks equipped on first load, we need to pre-set the age reqs for the item and slot
if ((CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA && CVarGetInteger(CVAR_ENHANCEMENT("AdultBunnyHood"), 0)) || CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)) { if (CVarGetInteger(CVAR_ENHANCEMENT("AdultMasks"), 0) || CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)) {
gItemAgeReqs[ITEM_MASK_BUNNY] = AGE_REQ_NONE; for (int i = ITEM_MASK_KEATON; i <= ITEM_MASK_TRUTH; i += 1) {
if(INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_MASK_BUNNY) gItemAgeReqs[i] = AGE_REQ_NONE;
}
if (INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_KEATON && INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_TRUTH) {
gSlotAgeReqs[SLOT_TRADE_CHILD] = AGE_REQ_NONE; gSlotAgeReqs[SLOT_TRADE_CHILD] = AGE_REQ_NONE;
} }
else { } else {
gItemAgeReqs[ITEM_MASK_BUNNY] = gSlotAgeReqs[SLOT_TRADE_CHILD] = AGE_REQ_CHILD; for (int i = ITEM_MASK_KEATON; i <= ITEM_MASK_TRUTH; i += 1) {
gItemAgeReqs[i] = AGE_REQ_CHILD;
}
gSlotAgeReqs[SLOT_TRADE_CHILD] = AGE_REQ_CHILD;
} }
func_800304DC(play, &play->actorCtx, play->linkActorEntry); func_800304DC(play, &play->actorCtx, play->linkActorEntry);

View File

@ -140,6 +140,10 @@ void Sram_OpenSave() {
break; break;
} }
if (!CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
gSaveContext.maskMemory = PLAYER_MASK_NONE;
}
osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex); osSyncPrintf("scene_no = %d\n", gSaveContext.entranceIndex);
osSyncPrintf(VT_RST); osSyncPrintf(VT_RST);

View File

@ -1089,7 +1089,6 @@ static s8 sItemActions[] = {
PLAYER_IA_SWORD_BIGGORON, // ITEM_SWORD_BIGGORON PLAYER_IA_SWORD_BIGGORON, // ITEM_SWORD_BIGGORON
}; };
static u8 sMaskMemory;
u8 gWalkSpeedToggle1; u8 gWalkSpeedToggle1;
u8 gWalkSpeedToggle2; u8 gWalkSpeedToggle2;
@ -2251,37 +2250,20 @@ void Player_ProcessItemButtons(Player* this, PlayState* play) {
s32 item; s32 item;
s32 i; s32 i;
if (this->currentMask != PLAYER_MASK_NONE) { if (this->currentMask != PLAYER_MASK_NONE && !CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA) { maskItemAction = this->currentMask - 1 + PLAYER_IA_MASK_KEATON;
s32 maskItem = this->currentMask - PLAYER_MASK_KEATON + ITEM_MASK_KEATON;
bool hasOnDpad = false;
if (CVarGetInteger(CVAR_SETTING("DpadEquips"), 0) != 0) {
for (int buttonIndex = 4; buttonIndex < 8; buttonIndex++) {
hasOnDpad |= gSaveContext.equips.buttonItems[buttonIndex] == maskItem;
}
}
if (gSaveContext.equips.buttonItems[0] != maskItem && gSaveContext.equips.buttonItems[1] != maskItem && bool hasOnDpad = false;
gSaveContext.equips.buttonItems[2] != maskItem && gSaveContext.equips.buttonItems[3] != maskItem && if (CVarGetInteger(CVAR_SETTING("DpadEquips"), 0) != 0) {
!hasOnDpad) { for (int buttonIndex = 0; buttonIndex < 4; buttonIndex++) {
this->currentMask = sMaskMemory = PLAYER_MASK_NONE; hasOnDpad |= Player_ItemIsItemAction(DPAD_ITEM(buttonIndex), maskItemAction);
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
}
} else {
maskItemAction = this->currentMask - 1 + PLAYER_IA_MASK_KEATON;
bool hasOnDpad = false;
if (CVarGetInteger(CVAR_SETTING("DpadEquips"), 0) != 0) {
for (int buttonIndex = 0; buttonIndex < 4; buttonIndex++) {
hasOnDpad |= Player_ItemIsItemAction(DPAD_ITEM(buttonIndex), maskItemAction);
}
}
if (!Player_ItemIsItemAction(C_BTN_ITEM(0), maskItemAction) &&
!Player_ItemIsItemAction(C_BTN_ITEM(1), maskItemAction) &&
!Player_ItemIsItemAction(C_BTN_ITEM(2), maskItemAction) && !hasOnDpad) {
this->currentMask = PLAYER_MASK_NONE;
} }
} }
if (!Player_ItemIsItemAction(C_BTN_ITEM(0), maskItemAction) &&
!Player_ItemIsItemAction(C_BTN_ITEM(1), maskItemAction) &&
!Player_ItemIsItemAction(C_BTN_ITEM(2), maskItemAction) && !hasOnDpad) {
this->currentMask = PLAYER_MASK_NONE;
}
} }
if (!(this->stateFlags1 & (PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE)) && !func_8008F128(this)) { if (!(this->stateFlags1 & (PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE)) && !func_8008F128(this)) {
@ -3221,7 +3203,8 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) {
this->currentMask = itemAction - PLAYER_IA_MASK_KEATON + 1; this->currentMask = itemAction - PLAYER_IA_MASK_KEATON + 1;
} }
sMaskMemory = this->currentMask; gSaveContext.maskMemory = this->currentMask;
func_808328EC(this, NA_SE_PL_CHANGE_ARMS); func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
} else if (((itemAction >= PLAYER_IA_OCARINA_FAIRY) && (itemAction <= PLAYER_IA_OCARINA_OF_TIME)) || } else if (((itemAction >= PLAYER_IA_OCARINA_FAIRY) && (itemAction <= PLAYER_IA_OCARINA_OF_TIME)) ||
(itemAction >= PLAYER_IA_BOTTLE_FISH)) { (itemAction >= PLAYER_IA_BOTTLE_FISH)) {
@ -5069,7 +5052,9 @@ void func_8083A0F4(PlayState* play, Player* this) {
this->interactRangeActor->parent = &this->actor; this->interactRangeActor->parent = &this->actor;
Player_SetupAction(play, this, Player_Action_8084F608, 0); Player_SetupAction(play, this, Player_Action_8084F608, 0);
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
sMaskMemory = PLAYER_MASK_NONE; if (!CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0) || !CVarGetInteger(CVAR_ENHANCEMENT("AdultMasks"), 0)) {
gSaveContext.maskMemory = PLAYER_MASK_NONE;
}
} else { } else {
LinkAnimationHeader* anim; LinkAnimationHeader* anim;
@ -8940,7 +8925,9 @@ void func_80843AE8(PlayState* play, Player* this) {
OnePointCutscene_Init(play, 9908, 125, &this->actor, MAIN_CAM); OnePointCutscene_Init(play, 9908, 125, &this->actor, MAIN_CAM);
} else if (play->gameOverCtx.state == GAMEOVER_DEATH_WAIT_GROUND) { } else if (play->gameOverCtx.state == GAMEOVER_DEATH_WAIT_GROUND) {
play->gameOverCtx.state = GAMEOVER_DEATH_DELAY_MENU; play->gameOverCtx.state = GAMEOVER_DEATH_DELAY_MENU;
sMaskMemory = PLAYER_MASK_NONE; if (!CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
gSaveContext.maskMemory = PLAYER_MASK_NONE;
}
} }
} }
@ -10191,11 +10178,12 @@ void Player_Init(Actor* thisx, PlayState* play2) {
Player_UseItem(play, this, ITEM_NONE); Player_UseItem(play, this, ITEM_NONE);
Player_SetEquipmentData(play, this); Player_SetEquipmentData(play, this);
this->prevBoots = this->currentBoots; this->prevBoots = this->currentBoots;
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA) { //keep masks thru loading zones
if (CVarGetInteger(CVAR_ENHANCEMENT("PersistentMasks"), 0)) {
if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_SOLD_OUT) { if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_SOLD_OUT) {
sMaskMemory = PLAYER_MASK_NONE; gSaveContext.maskMemory = PLAYER_MASK_NONE;
} }
this->currentMask = sMaskMemory; this->currentMask = gSaveContext.maskMemory;
} }
Player_InitCommon(this, play, gPlayerSkelHeaders[((void)0, gSaveContext.linkAge)]); Player_InitCommon(this, play, gPlayerSkelHeaders[((void)0, gSaveContext.linkAge)]);
this->giObjectSegment = (void*)(((uintptr_t)ZELDA_ARENA_MALLOC_DEBUG(0x3008) + 8) & ~0xF); this->giObjectSegment = (void*)(((uintptr_t)ZELDA_ARENA_MALLOC_DEBUG(0x3008) + 8) & ~0xF);

View File

@ -342,24 +342,25 @@ void KaleidoScope_HandleItemCycles(PlayState* play) {
); );
//the slot age requirement for the child trade slot has to be updated //the slot age requirement for the child trade slot has to be updated
//in case it currently holds the bunny hood //in case it currently holds a mask
//to allow adult link to wear it if the setting is enabled //to allow adult link to wear it if the setting is enabled
gSlotAgeReqs[SLOT_TRADE_CHILD] = gSlotAgeReqs[SLOT_TRADE_CHILD] =
( (
((CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA) && CVarGetInteger(CVAR_ENHANCEMENT("AdultBunnyHood"), 0)) || CVarGetInteger(CVAR_ENHANCEMENT("AdultMasks"), 0) ||
CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0) CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)
) && ) &&
INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_MASK_BUNNY INV_CONTENT(ITEM_TRADE_CHILD) >= ITEM_MASK_KEATON &&
? AGE_REQ_NONE INV_CONTENT(ITEM_TRADE_CHILD) <= ITEM_MASK_TRUTH
: AGE_REQ_CHILD;
//also update the age requirement for the bunny hood itself
gItemAgeReqs[ITEM_MASK_BUNNY] =
((CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA) && CVarGetInteger(CVAR_ENHANCEMENT("AdultBunnyHood"), 0)) ||
CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)
? AGE_REQ_NONE ? AGE_REQ_NONE
: AGE_REQ_CHILD; : AGE_REQ_CHILD;
//also update the age requirements for the masks itself
for (int i = ITEM_MASK_KEATON; i <= ITEM_MASK_TRUTH; i += 1) {
gItemAgeReqs[i] = CVarGetInteger(CVAR_ENHANCEMENT("AdultMasks"), 0) || CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)
? AGE_REQ_NONE
: AGE_REQ_CHILD;
}
//handle the adult trade select //handle the adult trade select
KaleidoScope_HandleItemCycleExtras( KaleidoScope_HandleItemCycleExtras(
play, play,