insert witty commit message here

This commit is contained in:
Ralphie Morell 2023-10-18 01:30:49 -04:00
parent 8357c2aa1b
commit 582771ab48
25 changed files with 413 additions and 19 deletions

View File

@ -1015,6 +1015,54 @@ void RegisterRandomizerSheikSpawn() {
});
}
//Boss souls require an additional item (represented by a RAND_INF) to spawn a boss in a particular lair
void RegisterBossSouls() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* actor) {
if (!gPlayState) return;
if (!IS_RANDO || !(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS))) return;
RandomizerInf rand_inf = RAND_INF_MAX;
Actor* actual = (Actor*)actor;
switch (gPlayState->sceneNum){
case SCENE_DEKU_TREE_BOSS:
rand_inf = RAND_INF_GOHMA_SOUL;
break;
case SCENE_DODONGOS_CAVERN_BOSS:
rand_inf = RAND_INF_KING_DODONGO_SOUL;
break;
case SCENE_JABU_JABU_BOSS:
rand_inf = RAND_INF_BARINADE_SOUL;
break;
case SCENE_FOREST_TEMPLE_BOSS:
rand_inf = RAND_INF_PHANTOM_GANON_SOUL;
break;
case SCENE_FIRE_TEMPLE_BOSS:
rand_inf = RAND_INF_VOLVAGIA_SOUL;
break;
case SCENE_WATER_TEMPLE_BOSS:
rand_inf = RAND_INF_MORPHA_SOUL;
break;
case SCENE_SHADOW_TEMPLE_BOSS:
rand_inf = RAND_INF_BONGO_BONGO_SOUL;
break;
case SCENE_SPIRIT_TEMPLE_BOSS:
rand_inf = RAND_INF_TWINROVA_SOUL;
break;
case SCENE_GANONDORF_BOSS:
rand_inf = RAND_INF_GANON_SOUL;
break;
case SCENE_GANON_BOSS:
rand_inf = RAND_INF_GANON_SOUL;
break;
default: break;
}
if (!Flags_GetRandomizerInf(rand_inf) && actual->category == ACTORCAT_BOSS) {
Actor_Delete(&gPlayState->actorCtx, actual, gPlayState);
}
});
}
void InitMods() {
RegisterTTS();
RegisterInfiniteMoney();
@ -1041,5 +1089,6 @@ void InitMods() {
RegisterEnemyDefeatCounts();
RegisterAltTrapTypes();
RegisterRandomizerSheikSpawn();
RegisterBossSouls();
NameTag_RegisterHooks();
}

View File

@ -716,7 +716,8 @@ static void RandomizeDungeonRewards() {
}
for (size_t i = 0; i < dungeonRewardLocations.size(); i++) {
const auto index = Location(dungeonRewardLocations[i])->GetPlacedItem().GetItemID() - baseOffset;
const auto itemID = Location(dungeonRewardLocations[i])->GetPlacedItem().GetItemID();
const auto index = itemID - baseOffset;
rDungeonRewardOverrides[i] = index;
//set the player's dungeon reward on file creation instead of pushing it to them at the start.

View File

@ -1939,6 +1939,107 @@ void HintTable_Init_Item() {
Text{"a Piece of the Triforce", /*french*/"un fragment de la Triforce", /*spanish*/"un fragmento de la Trifuerza"}
);
hintTable[GOHMA_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"a regal soul", "", ""},
Text("some spider essence", "", ""),
}, {
//ambiguous text
Text("something webbed", "", "")
}, {
//clear text
Text("the soul of Gohma", "", "")}
);
hintTable[KING_DODONGO_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"a royal soul", "", ""},
Text("some reptile essence", "", ""),
}, {
//ambiguous text
Text("something spectral", "", "")
}, {
//clear text
Text("the soul of King Dodongo", "", "")
});
hintTable[BARINADE_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"an infectuous soul", "", ""},
Text("some parasitic essence", "", ""),
}, {
//ambiguous text
Text("something fishy", "", "")
}, {
//clear text
Text("the soul of Barinade", "", "")
});
hintTable[PHANTOM_GANON_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"a duplicate soul", "", ""},
Text("some illusionary essence", "", ""),
}, {
//ambiguous text
Text("something spectral", "", "")
}, {
//clear text
Text("the soul of Phantom Ganon", "", "")
});
hintTable[VOLVAGIA_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"a draconic soul", "", ""},
Text("some magmatic essence", "", ""),
}, {
//ambiguous text
Text("something hot", "", "")
}, {
//clear text
Text("the soul of Volvagia", "", "")
});
hintTable[MORPHA_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"an aquatic soul", "", ""},
Text("some liquid essence", "", ""),
}, {
//ambiguous text
Text("something wet", "", "")
}, {
//clear text
Text("the soul of Barinade", "", "")
});
hintTable[BONGO_BONGO_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"a shadowy soul", "", ""},
Text("some handy essence", "", ""),
}, {
//ambiguous text
Text("something dark", "", "")
}, {
//clear text
Text("the soul of Bongo Bongo", "", "")
});
hintTable[TWINROVA_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"old souls", "", ""},
Text("twin essences", "", ""),
}, {
//ambiguous text
Text("something spiritual", "", "")
}, {
//clear text
Text("the soul of Twinrova", "", "")
});
hintTable[GANON_BOSS_SOUL] = HintText::Item({
//obscure text
Text{"an evil soul", "", ""},
Text("some powerful essence", "", ""),
}, {
//ambiguous text
Text("something strong", "", "")
}, {
//clear text
Text("the soul of Ganon", "", "")
});
hintTable[EPONA] = HintText::Item({
//obscure text
Text{"a horse", /*french*/"un fidèle destrier", /*spanish*/"una yegua"},

View File

@ -246,6 +246,17 @@ void ItemTable_Init() { // RandomizerGet
itemTable[TRIFORCE] = Item(RG_TRIFORCE, Text{"Triforce", "Triforce", "Trifuerza"}, ITEMTYPE_EVENT, GI_RUPEE_RED_LOSE, false, &noVariable, NONE);
itemTable[HINT] = Item(RG_HINT, Text{"Hint", "Indice", "Pista"}, ITEMTYPE_EVENT, GI_RUPEE_BLUE_LOSE, false, &noVariable, NONE);
//Boss Souls
itemTable[GOHMA_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Gohma's Soul", "Ame de Gohma", "Alma de Gohma"}, ITEMTYPE_ITEM, 0xE1, true, &CanSummonGohma, NONE);
itemTable[KING_DODONGO_BOSS_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{"King Dodongo's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE2, true, &CanSummonKingDodongo, NONE);
itemTable[BARINADE_BOSS_SOUL] = Item(RG_BARINADE_SOUL, Text{"Barinade's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE3, true, &CanSummonBarinade, NONE);
itemTable[PHANTOM_GANON_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Phantom Ganon's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE4, true, &CanSummonPhantomGanon, NONE);
itemTable[VOLVAGIA_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Volvagia's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE5, true, &CanSummonVolvagia, NONE);
itemTable[MORPHA_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Morpha's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE6, true, &CanSummonMorpha, NONE);
itemTable[BONGO_BONGO_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Bongo Bongo's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE7, true, &CanSummonBongoBongo, NONE);
itemTable[TWINROVA_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Twinrova's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE8, true, &CanSummonTwinrova, NONE);
itemTable[GANON_BOSS_SOUL] = Item(RG_GOHMA_SOUL, Text{"Ganon's Soul", "Ame de ", "Alma de "}, ITEMTYPE_ITEM, 0xE9, true, &CanSummonGanon, NONE);
// itemTable[HOOKSHOT] = Item(RG_HOOKSHOT, Text{"Hookshot", "Grappin", "Gancho"}, ITEMTYPE_ITEM, 0x80, true, &ProgressiveHookshot, HOOKSHOT);
// itemTable[LONGSHOT] = Item(RG_LONGSHOT, Text{"Longshot", "Super-Grappin", "Supergancho"}, ITEMTYPE_ITEM, 0x80, true, &ProgressiveHookshot, LONGSHOT);
// itemTable[FAIRY_OCARINA] = Item(RG_FAIRY_OCARINA, Text{"Fairy Ocarina", "Ocarina des fées", "Ocarina de las Hadas"}, ITEMTYPE_ITEM, 0x8B, true, &ProgressiveOcarina, FAIRY_OCARINA);

View File

@ -816,6 +816,19 @@ void GenerateItemPool() {
PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, false, true);
}
if (ShuffleBossSouls.IsNot(BOSSSOULS_OFF)) {
AddItemToMainPool(GOHMA_BOSS_SOUL);
AddItemToMainPool(KING_DODONGO_BOSS_SOUL);
AddItemToMainPool(BARINADE_BOSS_SOUL);
AddItemToMainPool(PHANTOM_GANON_BOSS_SOUL);
AddItemToMainPool(VOLVAGIA_BOSS_SOUL);
AddItemToMainPool(BONGO_BONGO_BOSS_SOUL);
AddItemToMainPool(TWINROVA_BOSS_SOUL);
if (ShuffleBossSouls.Is(BOSSSOULS_ON_PLUS_GANON)) {
AddItemToMainPool(GANON_BOSS_SOUL);
}
}
if (BombchusInLogic) {
AddItemToMainPool(PROGRESSIVE_BOMBCHUS, 5);
} else {

View File

@ -203,6 +203,17 @@ typedef enum {
TRIFORCE,
TRIFORCE_PIECE,
TRIFORCE_COMPLETED,
GOHMA_BOSS_SOUL,
KING_DODONGO_BOSS_SOUL,
BARINADE_BOSS_SOUL,
PHANTOM_GANON_BOSS_SOUL,
VOLVAGIA_BOSS_SOUL,
MORPHA_BOSS_SOUL,
BONGO_BONGO_BOSS_SOUL,
TWINROVA_BOSS_SOUL,
GANON_BOSS_SOUL,
EPONA,
HINT,

View File

@ -253,9 +253,9 @@ void AreaTable_Init_DekuTree() {
{
// Events
EventAccess(&DekuTreeClear, { [] {
return DekuTreeClear ||
return DekuTreeClear || (CanSummonGohma &&
(CanJumpslash && (Nuts || CanUse(SLINGSHOT) || CanUse(BOW) ||
HookshotOrBoomerang));
HookshotOrBoomerang)));
}}),
},
{

View File

@ -290,10 +290,10 @@ void AreaTable_Init_DodongosCavern() {
// Events
EventAccess(&DodongosCavernClear,
{ [] {
return DodongosCavernClear ||
return DodongosCavernClear || (CanSummonKingDodongo &&
(Here(DODONGOS_CAVERN_BOSS_ROOM,
[] { return HasExplosives || (CanUse(MEGATON_HAMMER) && LogicDCHammerFloor); }) &&
(Bombs || GoronBracelet) && CanJumpslash); /*todo add chu kill to tricks*/
(Bombs || GoronBracelet) && CanJumpslash)); /*todo add chu kill to tricks*/
}}),
},
{

View File

@ -407,7 +407,7 @@ void AreaTable_Init_FireTemple() {
{
// Events
EventAccess(&FireTempleClear,
{ [] { return FireTempleClear || (FireTimer >= 64 && CanUse(MEGATON_HAMMER)); }}),
{ [] { return FireTempleClear || (CanSummonVolvagia && (FireTimer >= 64 && CanUse(MEGATON_HAMMER))); }}),
},
{
// Locations

View File

@ -421,8 +421,8 @@ void AreaTable_Init_ForestTemple() {
{
// Events
EventAccess(&ForestTempleClear, { [] {
return ForestTempleClear || ((CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) &&
(CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT)));
return ForestTempleClear || (CanSummonPhantomGanon && ((CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) &&
(CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT))));
} }),
},
{

View File

@ -235,7 +235,7 @@ void AreaTable_Init_JabuJabusBelly() {
{
// Events //todo: add pot kill trick
EventAccess(&JabuJabusBellyClear,
{ [] { return JabuJabusBellyClear || (CanUse(BOOMERANG) && CanJumpslash); } }),
{ [] { return JabuJabusBellyClear || (CanSummonBarinade && (CanUse(BOOMERANG) && CanJumpslash)); } }),
},
{
// Locations

View File

@ -194,10 +194,10 @@ void AreaTable_Init_ShadowTemple() {
{
// Events
EventAccess(&ShadowTempleClear, { [] {
return ShadowTempleClear ||
return ShadowTempleClear || (CanSummonBongoBongo &&
((CanUse(LENS_OF_TRUTH) || LogicLensBongo) &&
(CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) &&
(CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT) || LogicShadowBongo));
(CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT) || LogicShadowBongo)));
} }),
},
{

View File

@ -259,8 +259,8 @@ void AreaTable_Init_SpiritTemple() {
{
// Events
EventAccess(&SpiritTempleClear, { [] {
return SpiritTempleClear || (CanUse(MIRROR_SHIELD) &&
(CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)));
return SpiritTempleClear || (CanSummonTwinrova && (CanUse(MIRROR_SHIELD) &&
(CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))));
} }),
},
{

View File

@ -318,14 +318,14 @@ void AreaTable_Init_WaterTemple() {
{
// Events
EventAccess(&WaterTempleClear, { [] {
return WaterTempleClear ||
(CanUse(HOOKSHOT) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)));
return WaterTempleClear || (CanSummonMorpha &&
(CanUse(HOOKSHOT) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))));
} }),
},
{
// Locations
LocationAccess(WATER_TEMPLE_MORPHA_HEART, { [] { return WaterTempleClear; } }),
LocationAccess(MORPHA, { [] { return WaterTempleClear; } }),
LocationAccess(MORPHA, { [] { return CanSummonMorpha && WaterTempleClear; } }),
},
{
// Exits

View File

@ -314,6 +314,16 @@ namespace Logic {
uint8_t Age = 0;
bool CanCompleteTriforce = false;
bool CanSummonGohma = false;
bool CanSummonKingDodongo = false;
bool CanSummonBarinade = false;
bool CanSummonPhantomGanon = false;
bool CanSummonVolvagia = false;
bool CanSummonMorpha = false;
bool CanSummonBongoBongo = false;
bool CanSummonTwinrova = false;
bool CanSummonGanon = false;
//Events
bool ShowedMidoSwordAndShield = false;
bool CarpenterRescue = false;
@ -464,6 +474,22 @@ namespace Logic {
(age == HasProjectileAge::Either && (Slingshot || Boomerang || Hookshot || Bow));
}
bool HasBossSoul(uint32_t itemName) {
if (ShuffleBossSouls.Is(BOSSSOULS_OFF)) {
return true;
}
return (itemName == GOHMA_BOSS_SOUL && CanSummonGohma) ||
(itemName == KING_DODONGO_BOSS_SOUL && CanSummonKingDodongo) ||
(itemName == BARINADE_BOSS_SOUL && CanSummonBarinade) ||
(itemName == PHANTOM_GANON_BOSS_SOUL && CanSummonPhantomGanon) ||
(itemName == VOLVAGIA_BOSS_SOUL && CanSummonVolvagia) ||
(itemName == MORPHA_BOSS_SOUL && CanSummonMorpha) ||
(itemName == BONGO_BONGO_BOSS_SOUL && CanSummonBongoBongo) ||
(itemName == TWINROVA_BOSS_SOUL && CanSummonTwinrova) ||
(ShuffleBossSouls.Is(BOSSSOULS_ON_PLUS_GANON) && (itemName == GANON_BOSS_SOUL && CanSummonGanon));
}
uint8_t GetDifficultyValueFromString(Option& glitchOption) {
return 0;
}
@ -625,6 +651,16 @@ namespace Logic {
(LACSCondition == LACSCONDITION_DUNGEONS && DungeonCount + (Greg && GregInLogic ? 1 : 0) >= LACSDungeonCount.Value<uint8_t>()) ||
(LACSCondition == LACSCONDITION_TOKENS && GoldSkulltulaTokens >= LACSTokenCount.Value<uint8_t>());
CanCompleteTriforce = TriforcePieces >= TriforceHuntRequired.Value<uint8_t>();
CanSummonGohma = HasBossSoul(GOHMA_BOSS_SOUL);
CanSummonKingDodongo = HasBossSoul(KING_DODONGO_BOSS_SOUL);
CanSummonBarinade = HasBossSoul(BARINADE_BOSS_SOUL);
CanSummonPhantomGanon = HasBossSoul(PHANTOM_GANON_BOSS_SOUL);
CanSummonVolvagia = HasBossSoul(VOLVAGIA_BOSS_SOUL);
CanSummonMorpha = HasBossSoul(MORPHA_BOSS_SOUL);
CanSummonBongoBongo = HasBossSoul(BONGO_BONGO_BOSS_SOUL);
CanSummonTwinrova = HasBossSoul(TWINROVA_BOSS_SOUL);
CanSummonGanon = HasBossSoul(GANON_BOSS_SOUL);
}
bool SmallKeys(Key dungeon, uint8_t requiredAmount) {
@ -880,6 +916,17 @@ namespace Logic {
//Triforce Pieces
TriforcePieces = 0;
//Boss Souls
CanSummonGohma = false;
CanSummonKingDodongo = false;
CanSummonBarinade = false;
CanSummonPhantomGanon = false;
CanSummonVolvagia = false;
CanSummonMorpha = false;
CanSummonBongoBongo = false;
CanSummonTwinrova = false;
CanSummonGanon = false;
//Drops and Bottle Contents Access
DekuNutDrop = false;
NutPot = false;

View File

@ -303,6 +303,16 @@ extern bool LinksCow;
extern uint8_t Age;
extern bool CanCompleteTriforce;
extern bool CanSummonGohma;
extern bool CanSummonKingDodongo;
extern bool CanSummonBarinade;
extern bool CanSummonPhantomGanon;
extern bool CanSummonVolvagia;
extern bool CanSummonMorpha;
extern bool CanSummonBongoBongo;
extern bool CanSummonTwinrova;
extern bool CanSummonGanon;
// Events
extern bool ShowedMidoSwordAndShield;
extern bool CarpenterRescue;

View File

@ -196,6 +196,7 @@ namespace Settings {
Option ShuffleAdultTradeQuest = Option::Bool("Shuffle Adult Trade", {"Off", "On"});
Option ShuffleChestMinigame = Option::U8 ("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"});
Option Shuffle100GSReward = Option::Bool("Shuffle 100 GS Reward", {"Off", "On"});
Option ShuffleBossSouls = Option::U8 ("Shuffle Boss Souls", {"Off", "On", "On + Ganon"});
std::vector<Option *> shuffleOptions = {
&RandomizeShuffle,
&ShuffleRewards,
@ -217,6 +218,7 @@ namespace Settings {
&ShuffleAdultTradeQuest,
&ShuffleChestMinigame,
&Shuffle100GSReward,
&ShuffleBossSouls,
};
//Shuffle Dungeon Items
@ -2276,6 +2278,7 @@ namespace Settings {
ShopsanityPricesAffordable.SetSelectedIndex(cvarSettings[RSK_SHOPSANITY_PRICES_AFFORDABLE]);
Scrubsanity.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_SCRUBS]);
ShuffleCows.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_COWS]);
ShuffleBossSouls.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_BOSS_SOULS]);
ShuffleKokiriSword.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD]);
ShuffleOcarinas.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_OCARINA]);

View File

@ -199,6 +199,12 @@ typedef enum {
SHUFFLECHESTMINIGAME_PACK,
} ShuffleChestMinigameSetting;
typedef enum {
BOSSSOULS_OFF,
BOSSSOULS_ON,
BOSSSOULS_ON_PLUS_GANON,
} ShuffleBossSoulsSetting;
typedef enum {
MAPSANDCOMPASSES_START_WITH,
MAPSANDCOMPASSES_VANILLA,
@ -421,6 +427,7 @@ typedef struct {
uint8_t shuffleAdultTradeQuest;
uint8_t shuffleChestMinigame;
uint8_t shuffle100GsReward;
uint8_t shuffleBossSouls;
uint8_t mapsAndCompasses;
uint8_t keysanity;
@ -811,6 +818,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
extern Option ShuffleAdultTradeQuest;
extern Option ShuffleChestMinigame;
extern Option Shuffle100GSReward;
extern Option ShuffleBossSouls;
extern Option MapsAndCompasses;
extern Option Keysanity;

View File

@ -13,7 +13,7 @@ using namespace Settings;
std::vector<ItemAndPrice> NonShopItems = {};
static std::array<std::vector<Text>, 0xE0> trickNameTable; // Table of trick names for ice traps
static std::array<std::vector<Text>, 0xF0> trickNameTable; // Table of trick names for ice traps
bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet
//Set vanilla shop item locations before potentially shuffling
@ -702,6 +702,42 @@ void InitTrickNames() {
Text{"Piece of Cheese", "Morceau de Fromage", "Piece of Cheese"},
Text{"Triforce Shard", "Éclat de Triforce", "Triforce Shard"},
Text{"Shiny Rock", "Caiiloux Brillant", "Shiny Rock"}};
trickNameTable[0xE1] = {
Text{"Spider Sense", "", ""},
Text{"Deku Spirit", "", ""},
Text("Ghost of Ghoma", "", "")};
trickNameTable[0xE2] = {
Text{"Lizard Soul", "", ""},
Text{"Regal Remains", "", ""},
Text{"Dodongo's Core", "", ""}};
trickNameTable[0xE3] = {
Text{"Parasitic Poltergeist", "", ""},
Text{"Jabu Insides", "", ""},
Text{"Barinade Bacteria", "", ""}};
trickNameTable[0xE4] = {
Text{"Bigger Poe", "", ""},
Text{"Sacred Forest Pine Tree", "", ""},
Text{"Ganon's Phantom", "", ""}};
trickNameTable[0xE5] = {
Text{"Dragon Roast", "", ""},
Text{"Hot n' Ready", "", ""},
Text{"Volvagia's Vitality", "", ""}};
trickNameTable[0xE6] = {
Text{"Dihydrogen Monoxide", "", ""},
Text{"Morpha Molecules", "", ""},
Text{"Wet Stuff", "", ""}};
trickNameTable[0xE7] = {
Text{"Shadow Soul", "", ""},
Text{"Dark Essence", "", ""},
Text{"Bongo Bongo's Bongo", "", ""}};
trickNameTable[0xE8] = {
Text{"Sandy Ashes", "", ""},
Text{"Spiritual Spirit", "", ""},
Text{"Twin Rovers", "", ""}};
trickNameTable[0xE9] = {
Text{"Pure Evil", "", ""},
Text{"Ganon's Ghost", "", ""},
Text{"Pork", "", ""}};
/*
//Names for individual upgrades, in case progressive names are replaced

View File

@ -10,6 +10,7 @@
#include "objects/object_gi_key/object_gi_key.h"
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
#include "objects/object_gi_hearts/object_gi_hearts.h"
#include "objects/object_gi_sutaru/object_gi_sutaru.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "soh_assets.h"
@ -256,3 +257,29 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
CLOSE_DISPS(play->state.gfxCtx);
}
// TODO get custom model for boss souls
// extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry getItemEntry) {
// OPEN_DISPS(play->state.gfxCtx);
// Gfx_SetupDL_25Opa(play->state.gfxCtx);
// gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
// G_MTX_MODELVIEW | G_MTX_LOAD);
// gDPSetGrayscaleColor(POLY_OPA_DISP++, 255, 0, 0, 255);
// gSPGrayscale(POLY_OPA_DISP++, true);
// gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSkulltulaTokenDL);
// Gfx_SetupDL_25Xlu(play->state.gfxCtx);
// gSPSegment(POLY_XLU_DISP++, 8, Gfx_TwoTexScroll(
// play->state.gfxCtx, 0, 0 * (play->state.frames * 0),
// 1 * -(play->state.frames * 5), 32, 32, 1, 0 * (play->state.frames * 0),
// 0 * (play->state.frames * 0), 32, 64
// ));
// gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
// G_MTX_MODELVIEW | G_MTX_LOAD);
// gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSkulltulaTokenFlameDL);
// CLOSE_DISPS(play->state.gfxCtx);
// }

View File

@ -257,6 +257,7 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn
{ "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES },
{ "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS },
{ "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD },
{ "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS },
{ "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD },
{ "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD },
{ "Start with Fairy Ocarina", RSK_STARTING_OCARINA },
@ -942,6 +943,14 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
gSaveContext.randoSettings[index].value = RO_AMMO_DROPS_OFF;
}
break;
case RSK_SHUFFLE_BOSS_SOULS:
if (it.value() == "Off") {
gSaveContext.randoSettings[index].value = RO_BOSS_SOULS_OFF;
} else if (it.value() == "On") {
gSaveContext.randoSettings[index].value = RO_BOSS_SOULS_ON;
} else if (it.value() == "On + Ganon") {
gSaveContext.randoSettings[index].value = RO_BOSS_SOULS_ON_PLUS_GANON;
}
case RSK_STARTING_OCARINA:
if(it.value() == "Off") {
gSaveContext.randoSettings[index].value = RO_STARTING_OCARINA_OFF;
@ -2900,6 +2909,7 @@ void GenerateRandomizerImgui(std::string seed = "") {
cvarSettings[RSK_SHUFFLE_MAGIC_BEANS] = CVarGetInteger("gRandomizeShuffleBeans", 0);
cvarSettings[RSK_SHUFFLE_MERCHANTS] = CVarGetInteger("gRandomizeShuffleMerchants", RO_SHUFFLE_MERCHANTS_OFF);
cvarSettings[RSK_SHUFFLE_100_GS_REWARD] = CVarGetInteger("gRandomizeShuffle100GSReward", RO_GENERIC_OFF);
cvarSettings[RSK_SHUFFLE_BOSS_SOULS] = CVarGetInteger("gRandomizeShuffleBossSouls", RO_BOSS_SOULS_OFF);
cvarSettings[RSK_ENABLE_BOMBCHU_DROPS] = CVarGetInteger("gRandomizeEnableBombchuDrops", 0);
cvarSettings[RSK_BOMBCHUS_IN_LOGIC] = CVarGetInteger("gRandomizeBombchusInLogic", 0);
cvarSettings[RSK_SKIP_CHILD_ZELDA] = CVarGetInteger("gRandomizeSkipChildZelda", 0);
@ -3124,6 +3134,7 @@ void RandomizerSettingsWindow::DrawElement() {
static const char* randoTokensanity[4] = { "Off", "Dungeons", "Overworld", "All Tokens" };
static const char* randoShuffleScrubs[4] = { "Off", "Affordable", "Expensive", "Random Prices" };
static const char* randoShuffleMerchants[3] = { "Off", "On (no hints)", "On (with hints)" };
static const char* randoShuffleBossSouls[3] = { "Off", "On", "On + Ganon"};
// Shuffle Dungeon Items Settings
static const char* randoShuffleMapsAndCompasses[6] = { "Start With", "Vanilla", "Own Dungeon",
@ -4012,6 +4023,15 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::PaddedSeparator();
// Shuffle Boss Souls
// Forces players to find a boss's soul before defeating them in their lair.
ImGui::Text("%s", Settings::ShuffleBossSouls.GetName().c_str());
UIWidgets::InsertHelpHoverText("Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its respective soul."
"\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul.");
UIWidgets::EnhancementCombobox("gRandomizeShuffleBossSouls", randoShuffleBossSouls, RO_BOSS_SOULS_OFF);
UIWidgets::PaddedSeparator();
ImGui::PopItemWidth();
ImGui::EndChild();
@ -5866,7 +5886,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) {
void Randomizer::CreateCustomMessages() {
// RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED
// with GIMESSAGE(getItemID, itemID, english, german, french).
const std::array<GetItemMessage, 56> getItemMessages = {{
const std::array<GetItemMessage, 65> getItemMessages = {{
GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON,
"You found %gGreg%w!",
"%gGreg%w! Du hast ihn wirklich gefunden!",
@ -6096,7 +6116,18 @@ void Randomizer::CreateCustomMessages() {
GIMESSAGE(RG_TYCOON_WALLET, ITEM_WALLET_GIANT,
"You got a %rTycoon's Wallet%w!&It's gigantic! Now you can carry&up to %y999 rupees%w!",
"Du erhältst die %rGoldene&Geldbörse%w! Die größte aller&Geldbörsen! Jetzt kannst Du bis&zu %y999 Rubine%w mit dir führen!",
"Vous obtenez la %rBourse de Magnat%w!&Elle peut contenir jusqu'à %y999 rubis%w!&C'est gigantesque!")
"Vous obtenez la %rBourse de Magnat%w!&Elle peut contenir jusqu'à %y999 rubis%w!&C'est gigantesque!"),
GIMESSAGE_UNTRANSLATED(RG_GOHMA_SOUL, ITEM_BIG_POE, "You found the soul for %gGohma%w!"),
GIMESSAGE_UNTRANSLATED(RG_KING_DODONGO_SOUL, ITEM_BIG_POE, "You found the soul for %rKing Dodongo%w!"),
GIMESSAGE_UNTRANSLATED(RG_BARINADE_SOUL, ITEM_BIG_POE, "You found the soul for %bBarindade%w!"),
GIMESSAGE_UNTRANSLATED(RG_PHANTOM_GANON_SOUL, ITEM_BIG_POE, "You found the soul for %gPhantom Ganon%w!"),
GIMESSAGE_UNTRANSLATED(RG_VOLVAGIA_SOUL, ITEM_BIG_POE, "You found the soul for %rVolvagia%w!"),
GIMESSAGE_UNTRANSLATED(RG_MORPHA_SOUL, ITEM_BIG_POE, "You found the soul for %bMorpha%w!"),
GIMESSAGE_UNTRANSLATED(RG_BONGO_BONGO_SOUL, ITEM_BIG_POE, "You found the soul for %pBongo Bongo%w!"),
GIMESSAGE_UNTRANSLATED(RG_TWINROVA_SOUL, ITEM_BIG_POE, "You found the soul for %yTwinrova%w!"),
GIMESSAGE_UNTRANSLATED(RG_GANON_SOUL, ITEM_BIG_POE, "You found the soul for %cGanon%w!"),
}};
CreateGetItemMessages(&getItemMessages);
CreateRupeeMessages();
@ -6212,6 +6243,15 @@ void InitRandoItemTable() {
GET_ITEM(RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, RG_TYCOON_WALLET),
GET_ITEM(RG_PROGRESSIVE_BOMBCHUS, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_PROGRESSIVE_BOMBCHUS),
GET_ITEM(RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_TRIFORCE_PIECE),
GET_ITEM(RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_GOHMA_SOUL),
GET_ITEM(RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_KING_DODONGO_SOUL),
GET_ITEM(RG_BARINADE_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_BARINADE_SOUL),
GET_ITEM(RG_PHANTOM_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_PHANTOM_GANON_SOUL),
GET_ITEM(RG_VOLVAGIA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_VOLVAGIA_SOUL),
GET_ITEM(RG_MORPHA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_MORPHA_SOUL),
GET_ITEM(RG_BONGO_BONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_BONGO_BONGO_SOUL),
GET_ITEM(RG_TWINROVA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_TWINROVA_SOUL),
GET_ITEM(RG_GANON_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_GANON_SOUL),
};
ItemTableManager::Instance->AddItemTable(MOD_RANDOMIZER);
for (int i = 0; i < ARRAY_COUNT(extendedVanillaGetItemTable); i++) {

View File

@ -1314,6 +1314,15 @@ typedef enum {
RG_BUY_RED_POTION_50,
RG_TRIFORCE,
RG_TRIFORCE_PIECE,
RG_GOHMA_SOUL,
RG_KING_DODONGO_SOUL,
RG_BARINADE_SOUL,
RG_PHANTOM_GANON_SOUL,
RG_VOLVAGIA_SOUL,
RG_MORPHA_SOUL,
RG_BONGO_BONGO_SOUL,
RG_TWINROVA_SOUL,
RG_GANON_SOUL,
RG_HINT,
RG_TYCOON_WALLET,
RG_MAX
@ -1468,6 +1477,7 @@ typedef enum {
RSK_TRIFORCE_HUNT,
RSK_TRIFORCE_HUNT_PIECES_TOTAL,
RSK_TRIFORCE_HUNT_PIECES_REQUIRED,
RSK_SHUFFLE_BOSS_SOULS,
RSK_MAX
} RandomizerSettingKey;
@ -1592,6 +1602,12 @@ typedef enum {
RO_AMMO_DROPS_OFF,
} RandoOptionAmmoDrops;
typedef enum {
RO_BOSS_SOULS_OFF,
RO_BOSS_SOULS_ON,
RO_BOSS_SOULS_ON_PLUS_GANON,
} RandoOptionBossSouls;
//Any Dungeon Item (start with, vanilla, own dungeon, any dungeon,
//overworld, anywhere)
typedef enum {

View File

@ -159,6 +159,16 @@ typedef enum {
RAND_INF_10_BIG_POES,
RAND_INF_GOHMA_SOUL,
RAND_INF_KING_DODONGO_SOUL,
RAND_INF_BARINADE_SOUL,
RAND_INF_PHANTOM_GANON_SOUL,
RAND_INF_VOLVAGIA_SOUL,
RAND_INF_MORPHA_SOUL,
RAND_INF_BONGO_BONGO_SOUL,
RAND_INF_TWINROVA_SOUL,
RAND_INF_GANON_SOUL,
// If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16)
RAND_INF_MAX,

View File

@ -2543,6 +2543,13 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
return Return_Item_Entry(giEntry, RG_NONE);
}
if (item >= RG_GOHMA_SOUL && item <= RG_GANON_SOUL) {
u8 index = item - RG_GOHMA_SOUL;
Flags_SetRandomizerInf(RAND_INF_GOHMA_SOUL + index);
return Return_Item_Entry(giEntry, RG_NONE);
}
if (item == RG_PROGRESSIVE_BOMBCHUS) {
if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) {
INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU;

View File

@ -652,6 +652,9 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
this->actor.colChkInfo.damageTable = sDamageTable;
sPhase2Timer = 0xFFFF;
if (Flags_GetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE)) {
if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_SOULS) && !Flags_GetRandomizerInf(RAND_INF_BARINADE_SOUL)) {
sCsState = BOSSVA_BATTLE;
} else {
sCsState = INTRO_CALL_BARI;
sDoorState = 100;
func_8002DF54(play, &this->actor, 1);
@ -682,6 +685,7 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
}
sCameraAtMaxVel = sCameraEyeMaxVel = sZeroVec;
}
} else {
sCsState = INTRO_START;