Win condition tooltip + altar hint + draw full triforce for anywhere wincon (#7341)

This commit is contained in:
A Green Spoon
2026-10-07 21:35:22 -04:00
committed by GitHub
parent 41702557d0
commit c724b412b9
8 changed files with 77 additions and 18 deletions
+32 -6
View File
@@ -1159,6 +1159,38 @@
"rewards on slider does not change."
]
},
"wincon": {
"name": "Win Condition",
"description": [
"Defeat Ganon - Defeat Ganon to complete the game.\n",
"\n",
"Anywhere - Collect the Triforce to complete the game. It can appear anywhere in the world.\n",
"\n",
"Trigger - These settings put the completing the game on a trigger, ",
"playing the credits when the requirements are met:\n",
"- Stones: Obtain the specified amount of Spiritual Stones.\n",
"- Medallions: Obtain the specified amount of medallions.\n",
"- Dungeon rewards: Obtain the specified total sum of Spiritual Stones or medallions.\n",
"- Dungeons: Complete the specified amount of dungeons. Dungeons are considered complete after stepping into ",
"the blue warp after the boss.\n",
"- Tokens: Obtain the specified amount of Skulltula tokens.\n",
"- Triforce Pieces: Obtain the specified number of Triforce Pieces."
]
},
"wincon_options": {
"name": "Win Condition Options",
"description": [
"Standard Rewards - Greg does not change logic, Greg does not help obtain Ganon's Soul, max ",
"number of rewards on slider does not change.\n",
"\n",
"Greg as Reward - Greg does change logic (can be part of expected path for obtaining ",
"Ganon's Soul), Greg helps obtain Ganon's Soul, max number of rewards on slider increases by 1 to ",
"account for Greg.\n",
"\n",
"Greg as Wildcard - Greg does not change logic, Greg helps obtain Ganon's Soul, max number of ",
"rewards on slider does not change."
]
},
"big_poe_count": {
"name": "Big Poe Target Count",
"description": "The Poe collector will give a reward for turning in this many Big Poes."
@@ -1549,12 +1581,6 @@
"ganons_soul_triforce_count": {
"name": "Ganon's Soul Triforce Piece Count"
},
"wincon": {
"name": "Win Condition"
},
"wincon_options": {
"name": "Win Condition Reward Options"
},
"wincon_medallion_count": {
"name": "Win Condition Medallion Count"
},
+3 -2
View File
@@ -594,8 +594,9 @@ typedef enum {
/* 0x7A */ GID_SONG_TIME,
/* 0x7B */ GID_SONG_STORM,
/* 0x7C */ GID_TRIFORCE_PIECE,
/* 0x7D */ GID_FISHING_POLE,
/* 0x7E */ GID_MAXIMUM
/* 0x7D */ GID_TRIFORCE,
/* 0x7E */ GID_FISHING_POLE,
/* 0x7F */ GID_MAXIMUM
} GetItemDrawID;
@@ -2152,6 +2152,11 @@ void StaticData::HintTable_Init() {
| WINCON HINT TEXT |
---------------------------*/
hintTextTable[RHT_WINCON_DEFEAT_GANON_HINT] = HintText(CustomMessage("$wAnd the #Triforce# will be granted once #the evil one# is defeated.^",
/*german*/ "$wUnd das #Triforce# wird gewährt, sobald #der Böse# besiegt wurde.^",
/*french*/ "$wAussi, la #Triforce# sera accordée une fois que #le Malin# aura été vaincu.^",
{QM_YELLOW, QM_PINK}));
hintTextTable[RHT_WINCON_ANYWHERE_HINT] = HintText(CustomMessage("$wAnd the #Triforce# will be hidden somewhere&#in Hyrule#.^",
/*german*/ "$wUnd das #Triforce# wird irgendwo #in Hyrule# zu finden sein.^",
/*french*/ "$wAussi, la #Triforce# se trouve quelque part #dans Hyrule#.^",
+4
View File
@@ -357,6 +357,10 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
if (rando->GetRandoSettingValue(RSK_GANONS_SOUL) == RO_GANONS_SOUL_TRIFORCE_PIECES) {
fullTriforce = fullTriforce || (rando->GetRandoSettingValue(RSK_GANONS_SOUL_TRIFORCE_COUNT) == current);
}
if (getItemEntry.getItemId == RG_TRIFORCE) {
fullTriforce = true;
triforcePieceScale = 0.035f;
}
Matrix_Scale(triforcePieceScale, triforcePieceScale, triforcePieceScale, MTXMODE_APPLY);
+3 -1
View File
@@ -650,7 +650,9 @@ CustomMessage Hint::GetWinconText() {
auto ctx = Rando::Context::GetInstance();
CustomMessage winconMessage;
if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_ANYWHERE)) {
if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_DEFEAT_GANON)) {
return StaticData::hintTextTable[RHT_WINCON_DEFEAT_GANON_HINT].GetHintMessage();
} else if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_ANYWHERE)) {
return StaticData::hintTextTable[RHT_WINCON_ANYWHERE_HINT].GetHintMessage();
} else if (ctx->GetOption(RSK_WINCON).Is(RO_WINCON_STONES)) {
winconMessage = StaticData::hintTextTable[RHT_WINCON_STONES_HINT].GetHintMessage();
@@ -472,7 +472,7 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "Sac de Noix Mojo", "Deku-Nuß-Tasche" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "un ", "eine "}).CustomIcon(gItemIconDekuNutTex);
itemTable[RG_DEKU_NUT_BAG].SetCustomDrawFunc(Randomizer_DrawNutBag);
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_ITEM, RG_TRIFORCE, true, LOGIC_NONE, RHT_NONE, RG_TRIFORCE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "die "}).CustomIcon(gTriforcePieceTex);;
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_ITEM, RG_TRIFORCE, true, LOGIC_NONE, RHT_NONE, RG_TRIFORCE, OBJECT_GI_BOMB_2, GID_TRIFORCE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "die "}).CustomIcon(gTriforcePieceTex);;
itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_LESSER);
// Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen)
itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE, {"the ", "le ", "den "});
@@ -1258,6 +1258,7 @@ RANDO_ENUM_ITEM(RHT_GANONS_SOUL_DUNGEONS_HINT)
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_TOKENS_HINT)
RANDO_ENUM_ITEM(RHT_GANONS_SOUL_TRIFORCE_PIECES_HINT)
// Wincon
RANDO_ENUM_ITEM(RHT_WINCON_DEFEAT_GANON_HINT)
RANDO_ENUM_ITEM(RHT_WINCON_ANYWHERE_HINT)
RANDO_ENUM_ITEM(RHT_WINCON_STONES_HINT)
RANDO_ENUM_ITEM(RHT_WINCON_MEDALLIONS_HINT)
+28 -8
View File
@@ -114,6 +114,7 @@ void GetItem_DrawJewelGoron(PlayState* play, s16 drawId);
void GetItem_DrawJewelZora(PlayState* play, s16 drawId);
void GetItem_DrawGenericMusicNote(PlayState* play, s16 drawId);
void GetItem_DrawTriforcePiece(PlayState* play, s16 drawId);
void GetItem_DrawTriforce(PlayState* play, s16 drawId);
void GetItem_DrawFishingPole(PlayState* play, s16 drawId);
typedef struct {
@@ -384,14 +385,15 @@ DrawItemTableEntry sDrawItemTable[] = {
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Generic
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Zelda's Lullaby
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Epona's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Saria's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Sun's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Song of time
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Song of storms
{ GetItem_DrawTriforcePiece, { gTriforcePiece0DL } }, // Triforce Piece
{ GetItem_DrawFishingPole, { gGiFishingPoleDL } }, // Fishing Pole
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Zelda's Lullaby
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Epona's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Saria's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Sun's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Song of time
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, // Song of storms
{ GetItem_DrawTriforcePiece, { gTriforcePiece0DL } }, // Triforce Piece
{ GetItem_DrawTriforce, { gTriforcePieceCompletedDL } }, // Triforce
{ GetItem_DrawFishingPole, { gGiFishingPoleDL } }, // Fishing Pole
};
/**
@@ -1027,6 +1029,24 @@ void GetItem_DrawTriforcePiece(PlayState* play, s16 drawId) {
CLOSE_DISPS(play->state.gfxCtx);
}
void GetItem_DrawTriforce(PlayState* play, s16 drawId) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Matrix_Scale(0.035f, 0.035f, 0.035f, MTXMODE_APPLY);
uint8_t index = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected % 3;
Gfx* triforceDL = (Gfx*)gTriforcePieceCompletedDL;
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, triforceDL);
CLOSE_DISPS(play->state.gfxCtx);
}
void GetItem_DrawFishingPole(PlayState* play, s16 drawId) {
Vec3f pos;
OPEN_DISPS(play->state.gfxCtx);