mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-05-31 17:41:30 -04:00
Compare commits
28 Commits
9.2.3
...
develop-ackbar
| Author | SHA1 | Date | |
|---|---|---|---|
| b8a3998c51 | |||
| 31cbeb929b | |||
| d09cd4ffcd | |||
| a57cdc6f77 | |||
| 5bccc8a340 | |||
| dc4b27d65a | |||
| 0dcd52e5c7 | |||
| e5ad4e6f11 | |||
| e3ee258a92 | |||
| b728e671bf | |||
| 37db034815 | |||
| 5b4d8edf51 | |||
| 1a46d2ec96 | |||
| ea76550fc7 | |||
| ccfa31a245 | |||
| 806398a65b | |||
| 3221d8a988 | |||
| 69681e608f | |||
| 719bb87eda | |||
| bf37645d72 | |||
| 3b65eaa4ef | |||
| 3be7eff02c | |||
| 39dcc0a73c | |||
| 256ab01630 | |||
| 072838613a | |||
| 9c321862ca | |||
| 412b60a02f | |||
| 1876435e98 |
@@ -4,7 +4,7 @@
|
||||
"gRandoSettings": {
|
||||
"BigPoeTargetCount": 1,
|
||||
"BlueFireArrows": 1,
|
||||
"BombchuBag": 1,
|
||||
"BombchuBag": 2,
|
||||
"BossKeysanity": 5,
|
||||
"ClosedForest": 2,
|
||||
"CuccosToReturn": 1,
|
||||
@@ -21,11 +21,13 @@
|
||||
"LacsRewardCount": 10,
|
||||
"LacsRewardOptions": 1,
|
||||
"LockOverworldDoors": 1,
|
||||
"MedallionLockedTrials": 1,
|
||||
"MixBosses": 1,
|
||||
"MixDungeons": 1,
|
||||
"MixGrottos": 1,
|
||||
"MixInteriors": 1,
|
||||
"MixOverworld": 1,
|
||||
"MixThievesHideout": 1,
|
||||
"MixedEntrances": 1,
|
||||
"RainbowBridge": 7,
|
||||
"ScrubsPrices": 2,
|
||||
@@ -35,12 +37,16 @@
|
||||
"Shuffle100GSReward": 1,
|
||||
"ShuffleAdultTrade": 1,
|
||||
"ShuffleBeanFairies": 1,
|
||||
"ShuffleBeanSouls": 1,
|
||||
"ShuffleBeehives": 1,
|
||||
"ShuffleBossEntrances": 2,
|
||||
"ShuffleBossSouls": 2,
|
||||
"ShuffleBushes": 1,
|
||||
"ShuffleChildWallet": 1,
|
||||
"ShuffleClimb": 1,
|
||||
"ShuffleCows": 1,
|
||||
"ShuffleCrates": 3,
|
||||
"ShuffleCrawl": 1,
|
||||
"ShuffleDekuNutBag": 1,
|
||||
"ShuffleDekuStickBag": 1,
|
||||
"ShuffleDungeonsEntrances": 2,
|
||||
@@ -50,7 +56,9 @@
|
||||
"ShuffleFreestanding": 3,
|
||||
"ShuffleFrogSongRupees": 1,
|
||||
"ShuffleGanonBossKey": 9,
|
||||
"ShuffleGanonTowerEntrance": 1,
|
||||
"ShuffleGerudoToken": 1,
|
||||
"ShuffleGrab": 1,
|
||||
"ShuffleGrass": 3,
|
||||
"ShuffleGrottosEntrances": 1,
|
||||
"ShuffleInteriorsEntrances": 2,
|
||||
@@ -59,18 +67,21 @@
|
||||
"ShuffleMerchants": 3,
|
||||
"ShuffleOcarinaButtons": 1,
|
||||
"ShuffleOcarinas": 1,
|
||||
"ShuffleOpenChest": 1,
|
||||
"ShuffleOverworldEntrances": 1,
|
||||
"ShuffleOverworldSpawns": 1,
|
||||
"ShuffleOwlDrops": 1,
|
||||
"ShufflePots": 3,
|
||||
"ShuffleScrubs": 2,
|
||||
"ShuffleSongs": 2,
|
||||
"ShuffleSpeak": 1,
|
||||
"ShuffleStoneFairies": 1,
|
||||
"ShuffleSwim": 1,
|
||||
"ShuffleThievesHideoutEntrances": 1,
|
||||
"ShuffleTrees": 1,
|
||||
"ShuffleTokens": 3,
|
||||
"ShuffleWarpSongs": 1,
|
||||
"ShuffleWeirdEgg": 1,
|
||||
"SkipEponaRace": 1,
|
||||
"StartingAge": 2,
|
||||
"StartingHearts": 0,
|
||||
"StartingMapsCompasses": 5,
|
||||
|
||||
@@ -43,11 +43,11 @@ static bool HasArrowType(PlayerItemAction itemAction) {
|
||||
case PLAYER_IA_BOW:
|
||||
return true;
|
||||
case PLAYER_IA_BOW_FIRE:
|
||||
return INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_ARROW_FIRE;
|
||||
return INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_ARROW_FIRE && gSaveContext.magic >= sMagicArrowCosts[0];
|
||||
case PLAYER_IA_BOW_ICE:
|
||||
return INV_CONTENT(ITEM_ARROW_ICE) == ITEM_ARROW_ICE;
|
||||
return INV_CONTENT(ITEM_ARROW_ICE) == ITEM_ARROW_ICE && gSaveContext.magic >= sMagicArrowCosts[1];
|
||||
case PLAYER_IA_BOW_LIGHT:
|
||||
return INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT;
|
||||
return INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && gSaveContext.magic >= sMagicArrowCosts[2];
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <variables.h>
|
||||
|
||||
f32 Fishing_GetMinimumRequiredScore();
|
||||
}
|
||||
|
||||
void BuildFishingMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (gSaveContext.minigameScore == 0) {
|
||||
gSaveContext.minigameScore = Fishing_GetMinimumRequiredScore();
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterFishingMessages() {
|
||||
COND_ID_HOOK(OnOpenText, 0x40AE, CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0), BuildFishingMessage);
|
||||
COND_ID_HOOK(OnOpenText, 0x4080, CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0), BuildFishingMessage);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterFishingMessages, { CVAR_ENHANCEMENT("CustomizeFishing") });
|
||||
@@ -6,11 +6,11 @@ extern "C" {
|
||||
|
||||
void BuildSkulltulaMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
CustomMessage msg =
|
||||
CustomMessage("You got a %rGold Skulltula Token%w!&You've collected %r[[gsCount]]%w tokens&in total!",
|
||||
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r[[gsCount]]&%wGoldene "
|
||||
"Skulltula-Symbole&gesammelt!",
|
||||
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r[[gsCount]]%w symboles en "
|
||||
"tout!",
|
||||
CustomMessage("You got a %rGold Skulltula Token%w!&You've collected %r[[d]]%w |token|tokens|&in total!",
|
||||
"Ein %rGoldenes Skulltula-Symbol%w!&Du hast nun insgesamt %r[[d]]&%w|Goldenes "
|
||||
"Skulltula-Symbol|Goldene Skulltula-Symbole|&gesammelt!",
|
||||
"Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r[[d]]%w |symbole|symboles| "
|
||||
"en tout!",
|
||||
TEXTBOX_TYPE_BLUE);
|
||||
// The freeze text cannot be manually dismissed and must be auto-dismissed.
|
||||
// This is fine and even wanted when skull tokens are not shuffled, but when
|
||||
@@ -25,7 +25,7 @@ void BuildSkulltulaMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
msg = msg + "\x0E\x3C";
|
||||
}
|
||||
int16_t gsCount = gSaveContext.inventory.gsTokens;
|
||||
msg.Replace("[[gsCount]]", std::to_string(gsCount));
|
||||
msg.InsertNumber(gsCount);
|
||||
msg.AutoFormat(ITEM_SKULL_TOKEN);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
|
||||
@@ -36,7 +36,7 @@ void RegisterAdditionalReticles() {
|
||||
bool shouldRegister = CVAR_BOW_RETICLE_VALUE || CVAR_BOOMERANG_RETICLE_VALUE;
|
||||
|
||||
COND_VB_SHOULD(VB_DRAW_ADDITIONAL_RETICLES, shouldRegister, {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
Player* player = va_arg(args, Player*);
|
||||
Actor* heldActor = player->heldActor;
|
||||
if (CVAR_BOW_RETICLE_VALUE &&
|
||||
((player->heldItemAction >= PLAYER_IA_BOW && player->heldItemAction <= PLAYER_IA_BOW_LIGHT) ||
|
||||
|
||||
@@ -86,8 +86,7 @@ void RegisterShouldPlayBlueWarp() {
|
||||
* should also account for the difference between your first and following visits to the blue warp.
|
||||
*/
|
||||
REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, {
|
||||
// Do nothing when in a boss rush
|
||||
if (IS_BOSS_RUSH) {
|
||||
if (IS_BOSS_RUSH || gSaveContext.gameMode == GAMEMODE_END_CREDITS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ extern std::shared_ptr<SohMenu> mSohMenu;
|
||||
#define SEQ_COUNT_INSTRUMENT 6
|
||||
#define SEQ_COUNT_SFX 57
|
||||
#define SEQ_COUNT_VOICE 108
|
||||
#define SEQ_COUNT_ENDING 5
|
||||
|
||||
size_t AuthenticCountBySequenceType(SeqType type) {
|
||||
switch (type) {
|
||||
@@ -74,6 +75,8 @@ size_t AuthenticCountBySequenceType(SeqType type) {
|
||||
return SEQ_COUNT_INSTRUMENT;
|
||||
case SEQ_VOICE:
|
||||
return SEQ_COUNT_VOICE;
|
||||
case SEQ_ENDING:
|
||||
return SEQ_COUNT_ENDING;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -806,7 +809,8 @@ void AudioEditor::DrawElement() {
|
||||
}
|
||||
|
||||
std::vector<SeqType> allTypes = {
|
||||
SEQ_BGM_WORLD, SEQ_BGM_EVENT, SEQ_BGM_BATTLE, SEQ_OCARINA, SEQ_FANFARE, SEQ_INSTRUMENT, SEQ_SFX, SEQ_VOICE,
|
||||
SEQ_BGM_WORLD, SEQ_BGM_EVENT, SEQ_BGM_BATTLE, SEQ_OCARINA, SEQ_FANFARE,
|
||||
SEQ_INSTRUMENT, SEQ_SFX, SEQ_VOICE, SEQ_ENDING,
|
||||
};
|
||||
|
||||
void AudioEditor_RandomizeAll() {
|
||||
|
||||
@@ -2707,6 +2707,7 @@ void RegisterCosmeticHooks() {
|
||||
[](s16 sceneNum) { CosmeticsEditor_AutoRandomizeAll(); });
|
||||
|
||||
COND_HOOK(OnGameFrameUpdate, true, CosmeticsUpdateTick);
|
||||
COND_HOOK(OnAssetAltChange, true, []() { ApplyOrResetCustomGfxPatches(true); });
|
||||
}
|
||||
|
||||
void RegisterCosmeticWidgets() {
|
||||
|
||||
@@ -121,6 +121,8 @@ static bool IsDummyPlayer(const Player* player) {
|
||||
return player != nullptr && player->actor.update == DummyPlayer_Update;
|
||||
}
|
||||
|
||||
static bool sPrevAltAssetsEnabled = false;
|
||||
|
||||
void PatchOrUnpatch(const char* resource, const char* gfx, const char* dlist1, const char* dlist2, const char* dlist3,
|
||||
const char* alternateDL) {
|
||||
if (resource == NULL || gfx == NULL || dlist1 == NULL || dlist2 == NULL) {
|
||||
@@ -128,6 +130,7 @@ void PatchOrUnpatch(const char* resource, const char* gfx, const char* dlist1, c
|
||||
}
|
||||
|
||||
const bool altAssetsRuntime = ResourceMgr_IsAltAssetsEnabled();
|
||||
const bool altAssetsChanged = (altAssetsRuntime != sPrevAltAssetsEnabled);
|
||||
|
||||
if (!altAssetsRuntime) {
|
||||
// Alt assets are off; ensure any prior patches using these names are reverted.
|
||||
@@ -136,11 +139,16 @@ void PatchOrUnpatch(const char* resource, const char* gfx, const char* dlist1, c
|
||||
if (dlist3 != NULL) {
|
||||
ResourceMgr_UnpatchGfxByName(resource, dlist3);
|
||||
}
|
||||
// Drop any cached version of the resource so it reloads clean (unpatched) next use.
|
||||
ResourceMgr_UnloadResource(resource);
|
||||
if (altAssetsChanged) {
|
||||
ResourceMgr_UnloadResource(resource);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (altAssetsChanged) {
|
||||
ResourceMgr_UnloadResource(resource);
|
||||
}
|
||||
|
||||
if (!ResourceGetIsCustomByName(gfx)) {
|
||||
return;
|
||||
}
|
||||
@@ -510,4 +518,6 @@ void UpdatePatchCustomEquipmentDlists() {
|
||||
}
|
||||
|
||||
ApplyCommonEquipmentPatches();
|
||||
|
||||
sPrevAltAssetsEnabled = ResourceMgr_IsAltAssetsEnabled();
|
||||
}
|
||||
|
||||
@@ -540,10 +540,11 @@ typedef enum {
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// (this->heldItemAction == PLAYER_IA_HOOKSHOT) ||
|
||||
// (this->heldItemAction == PLAYER_IA_LONGSHOT)
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
// - '*Player'
|
||||
VB_DRAW_ADDITIONAL_RETICLES,
|
||||
|
||||
// #### `result`
|
||||
|
||||
@@ -1318,6 +1318,14 @@ void StaticData::HintTable_Init_Exclude_Dungeon() {
|
||||
/*german*/ "Man erzählt sich, daß sich bewacht von einem #Ring der Flammen#, im Geistertempel #[[1]]# |befände|befänden|.",
|
||||
/*french*/ "Selon moi, protégé par un #cercle de flammes# dans le Temple de l'Esprit se trouve #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun past rolling boulders in Spirit Temple# reveals #[[1]]#.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in the spotlight by statues# reveals #[[1]]#.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_CRATE_SPIRIT_TEMPLE] = HintText(CustomMessage("They say that a #crate in Spirit Temple# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Kiste im Geistertempel# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #caisse dans le Temple de l'Esprit# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
@@ -2128,7 +2128,7 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
|
||||
/*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN }));
|
||||
|
||||
hintTextTable[RHT_BUSH_HYRULE_FIELD] =
|
||||
HintText(CustomMessage("They say that a #bush in Hyrle Field# contains #[[1]]#.",
|
||||
HintText(CustomMessage("They say that a #bush in Hyrule Field# contains #[[1]]#.",
|
||||
/*german*/ "",
|
||||
/*french*/ "Selon moi, un #buisson dans la Plaine d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN }));
|
||||
hintTextTable[RHT_BUSH_ZORAS_FOUNTAIN] =
|
||||
|
||||
@@ -126,6 +126,7 @@ void GenerateStartingInventory() {
|
||||
AddItemToInventory(RG_NOCTURNE_OF_SHADOW, ctx->GetOption(RSK_STARTING_NOCTURNE_OF_SHADOW) ? 1 : 0);
|
||||
AddItemToInventory(RG_PRELUDE_OF_LIGHT, ctx->GetOption(RSK_STARTING_PRELUDE_OF_LIGHT) ? 1 : 0);
|
||||
AddItemToInventory(RG_KOKIRI_SWORD, ctx->GetOption(RSK_STARTING_KOKIRI_SWORD) ? 1 : 0);
|
||||
AddItemToInventory(RG_MAGIC_BEAN_PACK, ctx->GetOption(RSK_STARTING_BEANS) ? 1 : 0);
|
||||
// if (ProgressiveGoronSword) {
|
||||
// AddItemToInventory(RG_PROGRESSIVE_GORONSWORD, StartingBiggoronSword.Value<uint8_t>());
|
||||
// } else {
|
||||
|
||||
@@ -13,7 +13,7 @@ extern PlayState* gPlayState;
|
||||
|
||||
void BuildHintStoneMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if ((RAND_GET_OPTION(RSK_GOSSIP_STONE_HINTS).Is(RO_GOSSIP_STONES_NEED_TRUTH) &&
|
||||
Player_GetMask(gPlayState) == PLAYER_MASK_TRUTH) ||
|
||||
Player_GetMask(gPlayState) != PLAYER_MASK_TRUTH) ||
|
||||
(RAND_GET_OPTION(RSK_GOSSIP_STONE_HINTS).Is(RO_GOSSIP_STONES_NEED_STONE) &&
|
||||
CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY) == 0)) {
|
||||
return;
|
||||
|
||||
@@ -110,6 +110,8 @@ void BuildCarpetGuyMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
BuildMerchantMessage(msg, RC_WASTELAND_BOMBCHU_SALESMAN,
|
||||
!RAND_GET_OPTION(RSK_MERCHANT_TEXT_HINT) ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
msg.AutoFormat();
|
||||
msg.LoadIntoFont();
|
||||
|
||||
@@ -140,7 +140,7 @@ void BuildSkulltulaPeopleMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
"et j'aurai quelque chose à te donner! [[color]]([[1]])%w");
|
||||
msg.InsertNumber(count);
|
||||
msg.Replace("[[color]]", item.GetColor());
|
||||
msg.InsertNames({ item.GetHint().GetHintMessage().GetForCurrentLanguage() });
|
||||
msg.InsertNames({ item.GetHint().GetHintMessage() });
|
||||
msg.AutoFormat();
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
@@ -158,7 +158,7 @@ void Build100SkullsHintMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
Rando::Item& item =
|
||||
Rando::StaticData::RetrieveItem(RAND_GET_ITEM_LOC(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedRandomizerGet());
|
||||
msg.Replace("[[color]]", item.GetColor());
|
||||
msg.InsertNames({ item.GetHint().GetHintMessage().GetForCurrentLanguage() });
|
||||
msg.InsertNames({ item.GetHint().GetHintMessage() });
|
||||
msg.AutoFormat();
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
@@ -178,78 +178,43 @@ void BuildGregHintMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
}
|
||||
}
|
||||
|
||||
void BuildMysteriousWarpMessage() {
|
||||
CustomMessage msg = CustomMessage(
|
||||
"Warp to&%ra mysterious place?%w&" + CustomMessage::TWO_WAY_CHOICE() + "%gOK&No%w",
|
||||
"Zu&%reinem mysteriösen Ort%w?&" + CustomMessage::TWO_WAY_CHOICE() + "%gOK&No%w",
|
||||
"Se téléporter vers&%run endroit mystérieux%w?&" + CustomMessage::TWO_WAY_CHOICE() + "%rOK!&Non%w");
|
||||
msg.LoadIntoFont();
|
||||
static void BuildWarpMessage(RandomizerHint rh, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
CustomMessage msg = CustomMessage(
|
||||
"Warp to&%ra mysterious place?%w&" + CustomMessage::TWO_WAY_CHOICE() + "%gOK&No%w",
|
||||
"Zu&%reinem mysteriösen Ort%w?&" + CustomMessage::TWO_WAY_CHOICE() + "%gOK&No%w",
|
||||
"Se téléporter vers&%run endroit mystérieux%w?&" + CustomMessage::TWO_WAY_CHOICE() + "%rOK!&Non%w");
|
||||
msg.AutoFormat();
|
||||
msg.LoadIntoFont();
|
||||
} else {
|
||||
CustomMessage msg = RAND_GET_HINT(rh)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
}
|
||||
*loadFromMessageTable = false;
|
||||
}
|
||||
|
||||
void BuildMinuetWarpMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
BuildMysteriousWarpMessage();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
}
|
||||
CustomMessage msg = RAND_GET_HINT(RH_MINUET_WARP_LOC)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
BuildWarpMessage(RH_MINUET_WARP_LOC, loadFromMessageTable);
|
||||
}
|
||||
|
||||
void BuildBoleroWarpMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
BuildMysteriousWarpMessage();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
}
|
||||
CustomMessage msg = RAND_GET_HINT(RH_BOLERO_WARP_LOC)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
BuildWarpMessage(RH_BOLERO_WARP_LOC, loadFromMessageTable);
|
||||
}
|
||||
|
||||
void BuildSerenadeWarpMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
BuildMysteriousWarpMessage();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
}
|
||||
CustomMessage msg = RAND_GET_HINT(RH_SERENADE_WARP_LOC)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
BuildWarpMessage(RH_SERENADE_WARP_LOC, loadFromMessageTable);
|
||||
}
|
||||
|
||||
void BuildRequiemWarpMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
BuildMysteriousWarpMessage();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
}
|
||||
CustomMessage msg = RAND_GET_HINT(RH_REQUIEM_WARP_LOC)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
BuildWarpMessage(RH_REQUIEM_WARP_LOC, loadFromMessageTable);
|
||||
}
|
||||
|
||||
void BuildNocturneWarpMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
BuildMysteriousWarpMessage();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
}
|
||||
CustomMessage msg = RAND_GET_HINT(RH_NOCTURNE_WARP_LOC)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
BuildWarpMessage(RH_NOCTURNE_WARP_LOC, loadFromMessageTable);
|
||||
}
|
||||
|
||||
void BuildPreludeWarpMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
if (!RAND_GET_OPTION(RSK_WARP_SONG_HINTS)) {
|
||||
BuildMysteriousWarpMessage();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
}
|
||||
CustomMessage msg = RAND_GET_HINT(RH_PRELUDE_WARP_LOC)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
msg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
BuildWarpMessage(RH_PRELUDE_WARP_LOC, loadFromMessageTable);
|
||||
}
|
||||
|
||||
void BuildFrogsHintMessage(uint16_t* textId, bool* loadFromMessageTable) {
|
||||
@@ -419,15 +384,17 @@ void RegisterStaticHints() {
|
||||
COND_ID_HOOK(OnOpenText, TEXT_CHEST_GAME_REAL_GAMBLER, RAND_GET_OPTION(RSK_GREG_HINT), BuildGregHintMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_CHEST_GAME_THANKS_A_LOT, RAND_GET_OPTION(RSK_GREG_HINT), BuildGregHintMessage);
|
||||
// Warp
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_MINUET_OF_FOREST, RAND_GET_OPTION(RSK_WARP_SONG_HINTS), BuildMinuetWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_BOLERO_OF_FIRE, RAND_GET_OPTION(RSK_WARP_SONG_HINTS), BuildBoleroWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_SERENADE_OF_WATER, RAND_GET_OPTION(RSK_WARP_SONG_HINTS),
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_MINUET_OF_FOREST, RAND_GET_OPTION(RSK_SHUFFLE_WARP_SONGS),
|
||||
BuildMinuetWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_BOLERO_OF_FIRE, RAND_GET_OPTION(RSK_SHUFFLE_WARP_SONGS), BuildBoleroWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_SERENADE_OF_WATER, RAND_GET_OPTION(RSK_SHUFFLE_WARP_SONGS),
|
||||
BuildSerenadeWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_REQUIEM_OF_SPIRIT, RAND_GET_OPTION(RSK_WARP_SONG_HINTS),
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_REQUIEM_OF_SPIRIT, RAND_GET_OPTION(RSK_SHUFFLE_WARP_SONGS),
|
||||
BuildRequiemWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_NOCTURNE_OF_SHADOW, RAND_GET_OPTION(RSK_WARP_SONG_HINTS),
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_NOCTURNE_OF_SHADOW, RAND_GET_OPTION(RSK_SHUFFLE_WARP_SONGS),
|
||||
BuildNocturneWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_PRELUDE_OF_LIGHT, RAND_GET_OPTION(RSK_WARP_SONG_HINTS), BuildPreludeWarpMessage);
|
||||
COND_ID_HOOK(OnOpenText, TEXT_WARP_PRELUDE_OF_LIGHT, RAND_GET_OPTION(RSK_SHUFFLE_WARP_SONGS),
|
||||
BuildPreludeWarpMessage);
|
||||
// Frogs
|
||||
COND_ID_HOOK(OnOpenText, TEXT_FROGS_UNDERWATER, RAND_GET_OPTION(RSK_FROGS_HINT), BuildFrogsHintMessage);
|
||||
// Loach
|
||||
|
||||
@@ -2616,7 +2616,16 @@ void RandomizerOnPlayerUpdateHandler() {
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawn->second.yaw;
|
||||
}
|
||||
|
||||
Play_TriggerVoidOut(gPlayState);
|
||||
if (gPlayState->sceneNum == SCENE_GROTTOS) {
|
||||
// RESPAWN_MODE_DOWN isn't refreshed on grotto entry, reload grotto instead
|
||||
gPlayState->nextEntranceIndex = gSaveContext.entranceIndex;
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
gPlayState->transitionType = TRANS_TYPE_FADE_BLACK;
|
||||
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK;
|
||||
gSaveContext.respawnFlag = 0;
|
||||
} else {
|
||||
Play_TriggerVoidOut(gPlayState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2629,8 +2638,14 @@ void RandomizerOnPlayerUpdateHandler() {
|
||||
}
|
||||
|
||||
if (!GameInteractor::IsGameplayPaused() && RAND_GET_OPTION(RSK_TRIFORCE_HUNT).IsNot(RO_TRIFORCE_HUNT_OFF)) {
|
||||
// Warp to credits
|
||||
if (GameInteractor::State::TriforceHuntCreditsWarpActive) {
|
||||
// Warp to credits once item queue has drained to avoid losing queued items
|
||||
if (GameInteractor::State::TriforceHuntCreditsWarpActive && randomizerQueuedChecks.empty() &&
|
||||
randomizerQueuedCheck == RC_UNKNOWN_CHECK) {
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] =
|
||||
static_cast<u32>(GAMEPLAYSTAT_TOTAL_TIME);
|
||||
gSaveContext.ship.stats.gameComplete = 1;
|
||||
Play_PerformSave(gPlayState);
|
||||
Notification::Emit({ .message = "Game autosaved" });
|
||||
gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0;
|
||||
gSaveContext.nextCutsceneIndex = 0xFFF2;
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <memory>
|
||||
|
||||
#include "3drando/text.hpp"
|
||||
|
||||
@@ -64,7 +64,7 @@ bool Rando::Location::IsOverworld() const {
|
||||
}
|
||||
|
||||
bool Rando::Location::IsShop() const {
|
||||
return scene >= SCENE_BAZAAR && scene <= SCENE_BOMBCHU_SHOP;
|
||||
return (scene >= SCENE_BAZAAR && scene <= SCENE_BOMBCHU_SHOP) || scene == SCENE_TEST01;
|
||||
}
|
||||
|
||||
bool Rando::Location::IsVanillaCompletion() const {
|
||||
|
||||
@@ -134,7 +134,6 @@ void RegionTable_Init_SpiritTemple() {
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanHitSwitch(ED_BOMB_THROW) && logic->HasItem(RG_OPEN_CHEST);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->TakeDamage() ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW);}, false,
|
||||
RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())),
|
||||
}, {
|
||||
//Exits
|
||||
ENTRANCE(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, true),
|
||||
|
||||
@@ -64,7 +64,7 @@ void RegionTable_Init_DeathMountainTrail() {
|
||||
//Exits
|
||||
ENTRANCE(RR_DEATH_MOUNTAIN_ROCKFALL, true),
|
||||
ENTRANCE(RR_DMC_UPPER_ENTRY, true),
|
||||
ENTRANCE(RR_DMT_OWL_FLIGHT, logic->IsChild && (logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))),
|
||||
ENTRANCE(RR_DMT_OWL_FLIGHT, logic->IsChild && (logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_KOKIRI) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))),
|
||||
ENTRANCE(RR_DMT_GREAT_FAIRY_FOUNTAIN, AnyAgeTime([]{return logic->BlastOrSmash();})),
|
||||
});
|
||||
|
||||
|
||||
@@ -83,11 +83,11 @@ void RegionTable_Init_LakeHylia() {
|
||||
//Exits
|
||||
ENTRANCE(RR_HF_TO_LAKE_HYLIA, true),
|
||||
ENTRANCE(RR_LH_FROM_SHORTCUT, true),
|
||||
ENTRANCE(RR_LH_OWL_FLIGHT, logic->IsChild && (logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))),
|
||||
ENTRANCE(RR_LH_OWL_FLIGHT, logic->IsChild && (logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_KOKIRI) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))),
|
||||
ENTRANCE(RR_LH_FISHING_ISLAND, ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->ReachScarecrow() || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)))),
|
||||
ENTRANCE(RR_LH_LAB, logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY)),
|
||||
ENTRANCE(RR_LH_FROM_WATER_TEMPLE, true),
|
||||
ENTRANCE(RR_LH_GROTTO, logic->HasItem(RG_POWER_BRACELET) && (logic->IsAdult || logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))),
|
||||
ENTRANCE(RR_LH_GROTTO, logic->HasItem(RG_POWER_BRACELET) && (logic->IsAdult || logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_KOKIRI) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))),
|
||||
});
|
||||
|
||||
areaTable[RR_LH_FROM_SHORTCUT] = Region("LH From Shortcut", SCENE_LAKE_HYLIA, TIME_DOESNT_PASS, {RA_LAKE_HYLIA}, {}, {}, {
|
||||
|
||||
@@ -3589,49 +3589,28 @@ static std::unordered_map<RandomizerGet, GameplayStatTimestamp> randomizerGetToS
|
||||
// Gameplay stat tracking: Update time the item was acquired
|
||||
// (special cases for rando items)
|
||||
void Randomizer_GameplayStats_SetTimestamp(uint16_t item) {
|
||||
|
||||
u32 time = static_cast<u32>(GAMEPLAYSTAT_TOTAL_TIME);
|
||||
|
||||
// Have items in Link's pocket shown as being obtained at 0.1 seconds
|
||||
if (time == 0) {
|
||||
time = 1;
|
||||
}
|
||||
|
||||
// Use ITEM_KEY_BOSS to timestamp Ganon's boss key
|
||||
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_KEY_BOSS] = time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (randomizerGetToStatsTimeStamp.contains((RandomizerGet)item)) {
|
||||
gSaveContext.ship.stats.itemTimestamp[randomizerGetToStatsTimeStamp[(RandomizerGet)item]] = time;
|
||||
return;
|
||||
}
|
||||
|
||||
// Count any bottled item as a bottle
|
||||
if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) {
|
||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] == 0) {
|
||||
if (gSaveContext.ship.stats.itemTimestamp[item] == 0) {
|
||||
if (item == RG_GANONS_CASTLE_BOSS_KEY) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_KEY_BOSS] = time;
|
||||
} else if (item == RG_MASTER_SWORD) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_SWORD_MASTER] = time;
|
||||
} else if (randomizerGetToStatsTimeStamp.contains((RandomizerGet)item)) {
|
||||
gSaveContext.ship.stats.itemTimestamp[randomizerGetToStatsTimeStamp[(RandomizerGet)item]] = time;
|
||||
} else if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_BOTTLE] = time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Count any bombchu pack as bombchus
|
||||
if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHU_BAG) {
|
||||
if (gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = 0) {
|
||||
} else if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHU_BAG) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_BOMBCHU] = time;
|
||||
} else if (item == RG_MAGIC_SINGLE) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
|
||||
} else if (item == RG_DOUBLE_DEFENSE) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == RG_MAGIC_SINGLE) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_SINGLE_MAGIC] = time;
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == RG_DOUBLE_DEFENSE) {
|
||||
gSaveContext.ship.stats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3902,13 +3881,7 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
|
||||
|
||||
if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) ==
|
||||
RO_TRIFORCE_HUNT_WIN) {
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] =
|
||||
static_cast<u32>(GAMEPLAYSTAT_TOTAL_TIME);
|
||||
gSaveContext.ship.stats.gameComplete = 1;
|
||||
Play_PerformSave(play);
|
||||
Notification::Emit({
|
||||
.message = "Game autosaved",
|
||||
});
|
||||
// Save and warp are deferred until item queue drains
|
||||
GameInteractor_SetTriforceHuntCreditsWarpActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1565,7 +1565,8 @@ bool IsCheckShuffled(RandomizerCheck rc) {
|
||||
(loc->GetRCType() != RCTYPE_SCRUB || showScrubs ||
|
||||
(showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized
|
||||
rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) &&
|
||||
(loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) &&
|
||||
((loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) ||
|
||||
(rc == RC_ZR_MAGIC_BEAN_SALESMAN && showBeans)) &&
|
||||
(loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) &&
|
||||
(loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) &&
|
||||
(loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) &&
|
||||
@@ -1603,8 +1604,7 @@ bool IsCheckShuffled(RandomizerCheck rc) {
|
||||
rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off
|
||||
) &&
|
||||
(rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && (rc != RC_TOT_MASTER_SWORD || showMasterSword) &&
|
||||
(rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) &&
|
||||
(rc != RC_HC_MALON_EGG || showWeirdEgg) &&
|
||||
(rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && (rc != RC_HC_MALON_EGG || showWeirdEgg) &&
|
||||
(loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) &&
|
||||
((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) &&
|
||||
(loc->GetRCType() != RCTYPE_FOUNTAIN_FAIRY || showFountainFairies) &&
|
||||
|
||||
@@ -700,17 +700,18 @@ void Entrance_OverrideSpawnScene(s32 sceneNum, s32 spawn) {
|
||||
modifiedLinkActorEntry.rot = gPlayState->linkActorEntry->rot;
|
||||
modifiedLinkActorEntry.params = gPlayState->linkActorEntry->params;
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON) {
|
||||
// Move Ganon's Castle exit spawn to be on the small ledge near the castle and not over the void
|
||||
// to prevent Link from falling if the bridge isn't spawned
|
||||
if (sceneNum == SCENE_OUTSIDE_GANONS_CASTLE && spawn == 1) {
|
||||
modifiedLinkActorEntry.pos.x = 0xFEA8;
|
||||
modifiedLinkActorEntry.pos.y = 0x065C;
|
||||
modifiedLinkActorEntry.pos.z = 0x0290;
|
||||
modifiedLinkActorEntry.rot.y = 0x0700;
|
||||
modifiedLinkActorEntry.params = 0x0DFF; // stationary spawn
|
||||
gPlayState->linkActorEntry = &modifiedLinkActorEntry;
|
||||
}
|
||||
// Move Ganon's Castle exit spawn to be on the small ledge near the castle and not over the void
|
||||
// to prevent Link from falling if the bridge isn't spawned
|
||||
if (sceneNum == SCENE_OUTSIDE_GANONS_CASTLE && spawn == 1 &&
|
||||
(Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) == RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON ||
|
||||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF ||
|
||||
Randomizer_GetSettingValue(RSK_SHUFFLE_GANONS_TOWER_ENTRANCE))) {
|
||||
modifiedLinkActorEntry.pos.x = 0xFEA8;
|
||||
modifiedLinkActorEntry.pos.y = 0x065C;
|
||||
modifiedLinkActorEntry.pos.z = 0x0290;
|
||||
modifiedLinkActorEntry.rot.y = 0x0700;
|
||||
modifiedLinkActorEntry.params = 0x0DFF; // stationary spawn
|
||||
gPlayState->linkActorEntry = &modifiedLinkActorEntry;
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) {
|
||||
|
||||
@@ -24,7 +24,6 @@ extern "C" {
|
||||
#include "src/overlays/actors/ovl_En_Jj/z_en_jj.h"
|
||||
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
|
||||
@@ -1241,41 +1240,41 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) {
|
||||
case FLAG_EVENT_CHECK_INF:
|
||||
switch (flag) {
|
||||
case EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FAIRY_OCARINA).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_FAIRY_OCARINA);
|
||||
break;
|
||||
case EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_KOKIRI_EMERALD);
|
||||
break;
|
||||
case EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_GORON_RUBY).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_GORON_RUBY);
|
||||
break;
|
||||
case EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZORA_SAPPHIRE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_ZORA_SAPPHIRE);
|
||||
break;
|
||||
case EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FOREST_MEDALLION).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_FOREST_MEDALLION);
|
||||
break;
|
||||
case EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FIRE_MEDALLION).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_FIRE_MEDALLION);
|
||||
break;
|
||||
case EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_WATER_MEDALLION).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_WATER_MEDALLION);
|
||||
break;
|
||||
case EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_ARROWS).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_LIGHT_ARROWS);
|
||||
break;
|
||||
case EVENTCHKINF_TIME_TRAVELED_TO_ADULT:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_MEDALLION).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_LIGHT_MEDALLION);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FLAG_RANDOMIZER_INF:
|
||||
switch (flag) {
|
||||
case RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SHADOW_MEDALLION).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SHADOW_MEDALLION);
|
||||
break;
|
||||
case RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SPIRIT_MEDALLION).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SPIRIT_MEDALLION);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1287,22 +1286,22 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) {
|
||||
case FLAG_RANDOMIZER_INF:
|
||||
switch (flag) {
|
||||
case RAND_INF_ZF_GREAT_FAIRY_REWARD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FARORES_WIND).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_FARORES_WIND);
|
||||
break;
|
||||
case RAND_INF_HC_GREAT_FAIRY_REWARD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DINS_FIRE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_DINS_FIRE);
|
||||
break;
|
||||
case RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NAYRUS_LOVE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_NAYRUS_LOVE);
|
||||
break;
|
||||
case RAND_INF_DMT_GREAT_FAIRY_REWARD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_SINGLE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_MAGIC_SINGLE);
|
||||
break;
|
||||
case RAND_INF_DMC_GREAT_FAIRY_REWARD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_DOUBLE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_MAGIC_DOUBLE);
|
||||
break;
|
||||
case RAND_INF_OGC_GREAT_FAIRY_REWARD:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DOUBLE_DEFENSE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_DOUBLE_DEFENSE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1328,47 +1327,44 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) {
|
||||
case FLAG_EVENT_CHECK_INF:
|
||||
switch (flag) {
|
||||
case EVENTCHKINF_LEARNED_ZELDAS_LULLABY:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZELDAS_LULLABY).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_ZELDAS_LULLABY);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_MINUET_OF_FOREST:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MINUET_OF_FOREST).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_MINUET_OF_FOREST);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_BOLERO_OF_FIRE:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_BOLERO_OF_FIRE).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_BOLERO_OF_FIRE);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_SERENADE_OF_WATER:
|
||||
vanillaQueuedItemEntry =
|
||||
Rando::StaticData::RetrieveItem(RG_SERENADE_OF_WATER).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SERENADE_OF_WATER);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT:
|
||||
vanillaQueuedItemEntry =
|
||||
Rando::StaticData::RetrieveItem(RG_REQUIEM_OF_SPIRIT).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_REQUIEM_OF_SPIRIT);
|
||||
break;
|
||||
case EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL:
|
||||
vanillaQueuedItemEntry =
|
||||
Rando::StaticData::RetrieveItem(RG_NOCTURNE_OF_SHADOW).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_NOCTURNE_OF_SHADOW);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_PRELUDE_OF_LIGHT).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_PRELUDE_OF_LIGHT);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_SARIAS_SONG:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SARIAS_SONG).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SARIAS_SONG);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_SONG_OF_TIME:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_TIME).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SONG_OF_TIME);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_SONG_OF_STORMS:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SONG_OF_STORMS);
|
||||
break;
|
||||
case EVENTCHKINF_LEARNED_SUNS_SONG:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SUNS_SONG).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_SUNS_SONG);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FLAG_RANDOMIZER_INF:
|
||||
switch (flag) {
|
||||
case RAND_INF_LEARNED_EPONA_SONG:
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_EPONAS_SONG).GetGIEntry_Copy();
|
||||
TimeSaverQueueItem(RG_EPONAS_SONG);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1415,12 +1411,10 @@ static void TimeSaverRegisterHooks() {
|
||||
TimeSaverOnSceneInitHandler);
|
||||
COND_HOOK(OnVanillaBehavior, true, TimeSaverOnVanillaBehaviorHandler);
|
||||
COND_HOOK(OnActorInit, true, TimeSaverOnActorInitHandler);
|
||||
COND_HOOK(OnSceneInit, true, [](int16_t sceneNum) { successChimeCooldown = 0; });
|
||||
|
||||
// item queue for use outside rando, rando has its own queue
|
||||
COND_HOOK(OnLoadGame, !IS_RANDO, [](int32_t fileNum) {
|
||||
vanillaQueuedItemEntry = GET_ITEM_NONE;
|
||||
successChimeCooldown = 0;
|
||||
});
|
||||
COND_HOOK(OnLoadGame, !IS_RANDO, [](int32_t fileNum) { vanillaQueuedItemEntry = GET_ITEM_NONE; });
|
||||
COND_HOOK(OnItemReceive, !IS_RANDO, TimeSaverOnItemReceiveHandler);
|
||||
COND_HOOK(OnPlayerUpdate, !IS_RANDO, TimeSaverOnPlayerUpdateHandler);
|
||||
COND_HOOK(OnFlagSet,
|
||||
|
||||
@@ -2536,6 +2536,7 @@ bool SoH_HandleConfigDrop(char* filePath) {
|
||||
->ClearBindings();
|
||||
|
||||
Rando::Settings::GetInstance()->UpdateAllOptions();
|
||||
SohGui::MarkRandomizerMenusDirty();
|
||||
gui->SaveConsoleVariablesNextFrame();
|
||||
ShipInit::Init("*");
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ static std::map<int32_t, const char*> languages = {
|
||||
};
|
||||
void UpdateMenuTricks();
|
||||
void UpdateMenuLocations();
|
||||
void MarkRandomizerMenusDirty();
|
||||
|
||||
class SohMenu : public Ship::Menu {
|
||||
public:
|
||||
|
||||
@@ -181,6 +181,11 @@ void DrawLocationsMenu(WidgetInfo& info) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void MarkRandomizerMenusDirty() {
|
||||
locationsDirty = true;
|
||||
tricksDirty = true;
|
||||
}
|
||||
|
||||
void UpdateMenuLocations() {
|
||||
RandomizerCheckObjects::UpdateImGuiVisibility();
|
||||
// todo: this efficiently when we build out cvar array support
|
||||
|
||||
@@ -2032,8 +2032,10 @@ s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry) {
|
||||
PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_JUMPING | PLAYER_STATE1_FREEFALL | PLAYER_STATE1_FIRST_PERSON |
|
||||
PLAYER_STATE1_CLIMBING_LADDER)) &&
|
||||
Player_GetExplosiveHeld(player) < 0) {
|
||||
if (((player->heldActor != NULL) && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX)) ||
|
||||
(IS_RANDO && (getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))) ||
|
||||
if (((player->heldActor != NULL && (getItemEntry.modIndex == MOD_NONE && getItemEntry.getItemId > GI_NONE &&
|
||||
getItemEntry.getItemId < GI_MAX)) ||
|
||||
(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId > RG_NONE &&
|
||||
getItemEntry.getItemId < RG_MAX)) ||
|
||||
(!(player->stateFlags1 & (PLAYER_STATE1_CARRYING_ACTOR | PLAYER_STATE1_IN_CUTSCENE)))) {
|
||||
if ((getItemEntry.getItemId != GI_NONE)) {
|
||||
player->getItemEntry = getItemEntry;
|
||||
@@ -2073,8 +2075,10 @@ s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEn
|
||||
PLAYER_STATE1_CLIMBING_LADDER)) &&
|
||||
Player_GetExplosiveHeld(player) < 0) {
|
||||
if ((((player->heldActor != NULL) || (actor == player->talkActor)) &&
|
||||
((!IS_RANDO && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) ||
|
||||
(IS_RANDO && ((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) ||
|
||||
((getItemEntry.getItemId == MOD_NONE &&
|
||||
((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) ||
|
||||
(getItemEntry.getItemId == MOD_RANDOMIZER &&
|
||||
((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) ||
|
||||
(!(player->stateFlags1 & (PLAYER_STATE1_CARRYING_ACTOR | PLAYER_STATE1_IN_CUTSCENE)))) {
|
||||
if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) {
|
||||
s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y;
|
||||
@@ -2118,8 +2122,7 @@ s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange
|
||||
PLAYER_STATE1_CLIMBING_LADDER)) &&
|
||||
Player_GetExplosiveHeld(player) < 0) {
|
||||
if ((((player->heldActor != NULL) || (actor == player->talkActor)) &&
|
||||
((!IS_RANDO && ((getItemId > GI_NONE) && (getItemId < GI_MAX))) ||
|
||||
(IS_RANDO && ((getItemId > RG_NONE) && (getItemId < RG_MAX))))) ||
|
||||
((getItemId > GI_NONE) && (getItemId < GI_MAX))) ||
|
||||
(!(player->stateFlags1 & (PLAYER_STATE1_CARRYING_ACTOR | PLAYER_STATE1_IN_CUTSCENE)))) {
|
||||
if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) {
|
||||
s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y;
|
||||
|
||||
+16
-11
@@ -3,7 +3,6 @@
|
||||
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
|
||||
#include "objects/object_link_boy/object_link_boy.h"
|
||||
#include "objects/object_link_child/object_link_child.h"
|
||||
#include "objects/object_triforce_spot/object_triforce_spot.h"
|
||||
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
|
||||
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
@@ -1317,12 +1316,14 @@ s32 Player_OverrideLimbDrawGameplayCommon(PlayState* play, s32 limbIndex, Gfx**
|
||||
if (limbIndex == PLAYER_LIMB_HEAD) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("Link.HeadScale.Changed"), 0)) {
|
||||
f32 scale = CVarGetFloat(CVAR_COSMETIC("Link.HeadScale.Value"), 1.0f);
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
if (scale > 1.2f) {
|
||||
Matrix_Translate(-((LINK_IS_ADULT ? 320.0f : 200.0f) * scale), 0.0f, 0.0f, MTXMODE_APPLY);
|
||||
} else if (scale < 1.0f) {
|
||||
Matrix_Translate((LINK_IS_ADULT ? 3600.0f : 2900.0f) * ABS(scale - 1.0f), 0.0f, 0.0f,
|
||||
MTXMODE_APPLY);
|
||||
if (scale != 1.0f) {
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
if (scale > 1.2f) {
|
||||
Matrix_Translate(-((LINK_IS_ADULT ? 320.0f : 200.0f) * scale), 0.0f, 0.0f, MTXMODE_APPLY);
|
||||
} else if (scale < 1.0f) {
|
||||
Matrix_Translate((LINK_IS_ADULT ? 3600.0f : 2900.0f) * ABS(scale - 1.0f), 0.0f, 0.0f,
|
||||
MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
rot->x += this->headLimbRot.z;
|
||||
@@ -1331,8 +1332,10 @@ s32 Player_OverrideLimbDrawGameplayCommon(PlayState* play, s32 limbIndex, Gfx**
|
||||
} else if (limbIndex == PLAYER_LIMB_L_HAND) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("Link.SwordScale.Changed"), 0)) {
|
||||
f32 scale = CVarGetFloat(CVAR_COSMETIC("Link.SwordScale.Value"), 1.0f);
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
Matrix_Translate(-((LINK_IS_ADULT ? 320.0f : 200.0f) * scale), 0.0f, 0.0f, MTXMODE_APPLY);
|
||||
if (scale != 1.0f) {
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
Matrix_Translate(-((LINK_IS_ADULT ? 320.0f : 200.0f) * (scale - 1.0f)), 0.0f, 0.0f, MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
} else if (limbIndex == PLAYER_LIMB_UPPER) {
|
||||
if (this->upperLimbYawSecondary != 0) {
|
||||
@@ -1906,8 +1909,10 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList, Ve
|
||||
}
|
||||
|
||||
if (this->actor.scale.y >= 0.0f) {
|
||||
if (GameInteractor_Should(VB_DRAW_ADDITIONAL_RETICLES, (this->heldItemAction == PLAYER_IA_HOOKSHOT) ||
|
||||
(this->heldItemAction == PLAYER_IA_LONGSHOT))) {
|
||||
if (GameInteractor_Should(VB_DRAW_ADDITIONAL_RETICLES,
|
||||
(this->heldItemAction == PLAYER_IA_HOOKSHOT) ||
|
||||
(this->heldItemAction == PLAYER_IA_LONGSHOT),
|
||||
this)) {
|
||||
Matrix_MultVec3f(&D_80126184, &this->unk_3C8);
|
||||
|
||||
if (heldActor != NULL) {
|
||||
|
||||
@@ -1183,7 +1183,7 @@ void func_80A99048(EnKo* this, PlayState* play) {
|
||||
if (ENKO_TYPE == ENKO_TYPE_CHILD_5) {
|
||||
this->collider.base.ocFlags1 |= 0x40;
|
||||
}
|
||||
if (GameInteractor_Should(VB_KOKIRI_GET_FOREST_QUEST_STATE2, false, this)) {
|
||||
if (GameInteractor_Should(VB_KOKIRI_GET_FOREST_QUEST_STATE2, true, this)) {
|
||||
this->forestQuestState = EnKo_GetForestQuestState2(this);
|
||||
}
|
||||
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, sOsAnimeLookup[ENKO_TYPE][this->forestQuestState]);
|
||||
|
||||
@@ -432,6 +432,8 @@ static FishingEffect sFishingEffects[FISHING_EFFECT_COUNT];
|
||||
static Vec3f sStreamSoundProjectedPos;
|
||||
static s16 sFishOnHandParams;
|
||||
|
||||
f32 Fishing_GetMinimumRequiredScore();
|
||||
|
||||
u8 AllHyruleLoaches() {
|
||||
return CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("AllHyruleLoaches"), 0);
|
||||
@@ -904,12 +906,16 @@ void Fishing_Init(Actor* thisx, PlayState* play2) {
|
||||
if (sLinkAge == LINK_AGE_CHILD) {
|
||||
if ((HIGH_SCORE(HS_FISHING) & HS_FISH_LENGTH_CHILD) != 0) {
|
||||
sFishingRecordLength = HIGH_SCORE(HS_FISHING) & HS_FISH_LENGTH_CHILD;
|
||||
} else if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0)) {
|
||||
sFishingRecordLength = Fishing_GetMinimumRequiredScore();
|
||||
} else {
|
||||
sFishingRecordLength = 40.0f; // 6 lbs
|
||||
}
|
||||
} else {
|
||||
if ((HIGH_SCORE(HS_FISHING) & HS_FISH_LENGTH_ADULT) != 0) {
|
||||
sFishingRecordLength = (HIGH_SCORE(HS_FISHING) & HS_FISH_LENGTH_ADULT) >> 0x18;
|
||||
} else if (CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0)) {
|
||||
sFishingRecordLength = Fishing_GetMinimumRequiredScore();
|
||||
} else {
|
||||
sFishingRecordLength = 45.0f; // 7 lbs
|
||||
}
|
||||
|
||||
@@ -7339,8 +7339,9 @@ s32 Player_ActionHandler_2(Player* this, PlayState* play) {
|
||||
// getting bombchus need to show the cutscene) and whenever the player doesn't have the item yet. In
|
||||
// rando, we're overruling this because we need to keep showing the cutscene because those items can be
|
||||
// randomized and thus it's important to keep showing the cutscene.
|
||||
uint8_t showItemCutscene = play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY ||
|
||||
Item_CheckObtainability(giEntry.itemId) == ITEM_NONE || IS_RANDO;
|
||||
uint8_t showItemCutscene = play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY || IS_RANDO ||
|
||||
giEntry.modIndex == MOD_RANDOMIZER ||
|
||||
Item_CheckObtainability(giEntry.itemId) == ITEM_NONE;
|
||||
|
||||
// Only skip cutscenes for drops when they're items/consumables from bushes/rocks/enemies.
|
||||
uint8_t isDropToSkip =
|
||||
@@ -7359,8 +7360,8 @@ s32 Player_ActionHandler_2(Player* this, PlayState* play) {
|
||||
// the player already has because those items could be a randomized item coming from scrubs,
|
||||
// freestanding PoH's and keys. So we need to once again overrule this specifically for items coming
|
||||
// from bushes/rocks/enemies when the player has already picked that item up.
|
||||
uint8_t skipItemCutsceneRando =
|
||||
IS_RANDO && Item_CheckObtainability(giEntry.itemId) != ITEM_NONE && isDropToSkip;
|
||||
uint8_t skipItemCutsceneRando = IS_RANDO && giEntry.modIndex == MOD_NONE &&
|
||||
Item_CheckObtainability(giEntry.itemId) != ITEM_NONE && isDropToSkip;
|
||||
|
||||
// Show cutscene when picking up a item.
|
||||
if (showItemCutscene && !skipItemCutscene && !skipItemCutsceneRando) {
|
||||
|
||||
Reference in New Issue
Block a user