Skip to content

Commit

Permalink
Add "Bosses only" option for Enemy Souls
Browse files Browse the repository at this point in the history
  • Loading branch information
HylianFreddy committed May 23, 2024
1 parent 3d8e9ae commit a51c23e
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 73 deletions.
25 changes: 14 additions & 11 deletions code/src/actor.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,23 +324,26 @@ void HyperActors_UpdateAgain(Actor* thisx) {
hyperActors_ExtraUpdate = 0;
}

s32 Actor_IsBoss(Actor* actor) {
return (actor->id == 0x28) || // Gohma
(actor->id == 0x27 || actor->id == 0x30) || // King Dodongo + Fire Breath
(actor->id == 0xBA && actor->params == -1) || // Barinade
(actor->id == 0x52 || actor->id == 0x67 || actor->id == 0x6D) || // Phantom Ganon + Horse + Lightning
(actor->id == 0x96 || actor->id == 0xA2 || actor->id == 0xAD) || // Volvagia + Rock Attack
(actor->id == 0xC4) || // Morpha
(actor->id == 0xE9 && actor->params == -1) || // Bongo Bongo
(actor->id == 0xDC) || // Twinrova
(actor->id == 0xE8) || // Ganondorf
(actor->id == 0x17A); // Ganon
}

void HyperActors_Main(Actor* thisx, GlobalContext* globalCtx) {
if (!IsInGame() || thisx->update == NULL || (PLAYER != NULL && Player_InBlockingCsMode(globalCtx, PLAYER))) {
return;
}

if (gSettingsContext.hyperBosses == ON) {
if ((thisx->id == 0x28) || // Gohma
(thisx->id == 0x27 || thisx->id == 0x30) || // King Dodongo + Fire Breath
(thisx->id == 0xBA && thisx->params == -1) || // Barinade
(thisx->id == 0x52 || thisx->id == 0x67 || thisx->id == 0x6D) || // Phantom Ganon + Horse + Lightning
(thisx->id == 0x96 || thisx->id == 0xA2 || thisx->id == 0xAD) || // Volvagia + Rock Attack
(thisx->id == 0xC4) || // Morpha
(thisx->id == 0xE9 && thisx->params == -1) || // Bongo Bongo
(thisx->id == 0xDC) || // Twinrova
(thisx->id == 0xE8) || // Ganondorf
(thisx->id == 0x17A)) { // Ganon

if (Actor_IsBoss(thisx)) {
// Special case to update in order for Barinade and Bongo Bongo
if (thisx->id == 0xBA || thisx->id == 0xE9) {
for (Actor* actor = gGlobalContext->actorCtx.actorList[ACTORTYPE_BOSS].first; actor != NULL;
Expand Down
1 change: 1 addition & 0 deletions code/src/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
void Actor_Init();
void ActorSetup_Extra();
s32 Actor_CollisionATvsAC(Collider* at, Collider* ac);
s32 Actor_IsBoss(Actor* actor);

#endif //_ACTOR_H_
2 changes: 1 addition & 1 deletion code/src/actors/shabom.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "enemy_souls.h"

u16 Shabom_CheckEnemySoul(void) {
return gSettingsContext.shuffleEnemySouls == OFF || EnemySouls_GetSoulFlag(SOUL_SHABOM);
return gSettingsContext.shuffleEnemySouls != SHUFFLEENEMYSOULS_ALL || EnemySouls_GetSoulFlag(SOUL_SHABOM);
}

// This is currently useless because soulless enemies are invisible
Expand Down
4 changes: 3 additions & 1 deletion code/src/enemy_souls.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "savefile.h"
#include "settings.h"
#include "armos.h"
#include "actor.h"

// clang-format off
static EnemySoulId EnemySouls_GetSoulId(s16 actorId) {
Expand Down Expand Up @@ -96,7 +97,8 @@ void EnemySouls_SetSoulFlag(EnemySoulId soulId) {
}

u8 EnemySouls_CheckSoulForActor(Actor* actor) {
if ((gSettingsContext.shuffleEnemySouls == OFF) ||
if ((gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_OFF) ||
(gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_BOSSES && !Actor_IsBoss(actor)) ||
(actor->id == 0x054 && ((EnAm*)actor)->textureBlend == 0 /* Armos, statue or asleep */)) {
return TRUE;
}
Expand Down
5 changes: 3 additions & 2 deletions code/src/enemy_souls.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ typedef enum EnemySoulId {
typedef struct SoulMenuInfo {
EnemySoulId soulId;
const char* name;
const char* altName;
} SoulMenuInfo;

extern SoulMenuInfo SoulMenuNames[SOUL_MAX];
Expand Down Expand Up @@ -107,8 +108,8 @@ SoulMenuInfo SoulMenuNames[SOUL_MAX] = {
{ SOUL_WALLMASTER, "Wallmaster, Floormaster" },
{ SOUL_WOLFOS, "Wolfos (all)" },
// Bosses
{ SOUL_GOHMA, "Gohma, Gohma Larva" },
{ SOUL_DODONGO, "Dodongo (all)" },
{ SOUL_GOHMA, "Gohma, Gohma Larva", "Queen Gohma" },
{ SOUL_DODONGO, "Dodongo (all)", "King Dodongo" },
{ SOUL_BARINADE, "Barinade" },
{ SOUL_PHANTOM_GANON, "Phantom Ganon" },
{ SOUL_VOLVAGIA, "Volvagia" },
Expand Down
22 changes: 17 additions & 5 deletions code/src/gfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static void Gfx_DrawButtonPrompts(void) {
Draw_DrawIcon(offsetX, promptY, COLOR_BUTTON_A, ICON_BUTTON_A);
offsetX += buttonSpacing;
Draw_DrawString(offsetX, textY, COLOR_TITLE, "Toggle Legend");
} else if (curMenuIdx == PAGE_ENEMYSOULS) {
} else if (curMenuIdx == PAGE_ENEMYSOULS && gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_ALL) {
Draw_DrawIcon(offsetX, promptY, COLOR_WHITE, ICON_BUTTON_DPAD);
offsetX += buttonSpacing;
nextStr = "Scroll";
Expand Down Expand Up @@ -536,17 +536,29 @@ static void Gfx_DrawDungeonItems(void) {
static void Gfx_DrawEnemySouls(void) {
Draw_DrawString(10, 16, COLOR_TITLE, "Enemy Souls Obtained");

u8 startIndex = soulsScroll <= 0 ? 0 : 32;
u8 endIndex = soulsScroll <= 0 ? 32 : ARRAY_SIZE(SoulMenuNames);
const s32 bossesOnly = gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_BOSSES;
u8 startIndex, endIndex;

if (bossesOnly) {
startIndex = ARRAY_SIZE(SoulMenuNames) - 9;
endIndex = ARRAY_SIZE(SoulMenuNames);
} else if (soulsScroll == 0) {
startIndex = 0;
endIndex = 32;
} else {
startIndex = 32;
endIndex = ARRAY_SIZE(SoulMenuNames);
}

for (u8 i = startIndex; i < endIndex; i++) {
u16 posX = 10 + (((i % 32) / 16) * (SPACING_X * 25));
u16 posY = 30 + (SPACING_Y * (i % 16));
u16 posY = 30 + (SPACING_Y * ((i - (bossesOnly ? startIndex : 0)) % 16));
SoulMenuInfo info = SoulMenuNames[i];
const char* name = (bossesOnly && info.altName != NULL) ? info.altName : info.name;

Draw_DrawRect(posX, posY, 9, 9, COLOR_WHITE);
Draw_DrawRect(posX + 1, posY + 1, 7, 7, EnemySouls_GetSoulFlag(info.soulId) ? COLOR_GREEN : COLOR_BLACK);
Draw_DrawString(posX + SPACING_X * 2, posY, COLOR_WHITE, info.name);
Draw_DrawString(posX + SPACING_X * 2, posY, COLOR_WHITE, name);
}
}

Expand Down
6 changes: 6 additions & 0 deletions code/src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ typedef enum {
SHUFFLECHESTMINIGAME_PACK,
} ShuffleChestMinigameSetting;

typedef enum {
SHUFFLEENEMYSOULS_OFF,
SHUFFLEENEMYSOULS_ALL,
SHUFFLEENEMYSOULS_BOSSES,
} ShuffleEnemySoulsSetting;

typedef enum {
MAPSANDCOMPASSES_START_WITH,
MAPSANDCOMPASSES_VANILLA,
Expand Down
11 changes: 10 additions & 1 deletion source/item_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ const std::array<ItemKey, 47> enemySouls = {
SOUL_ITEM_BARINADE, SOUL_ITEM_PHANTOM_GANON, SOUL_ITEM_VOLVAGIA, SOUL_ITEM_MORPHA, SOUL_ITEM_BONGO_BONGO,
SOUL_ITEM_TWINROVA, SOUL_ITEM_GANON,
};
const std::array<ItemKey, 9> bossSouls = {
SOUL_ITEM_GOHMA, SOUL_ITEM_DODONGO, SOUL_ITEM_BARINADE, SOUL_ITEM_PHANTOM_GANON, SOUL_ITEM_VOLVAGIA,
SOUL_ITEM_MORPHA, SOUL_ITEM_BONGO_BONGO, SOUL_ITEM_TWINROVA, SOUL_ITEM_GANON,
};
const std::array<ItemKey, 5> ocarinaNoteButtons = {
OCA_BUTTON_ITEM_L, OCA_BUTTON_ITEM_R, OCA_BUTTON_ITEM_X, OCA_BUTTON_ITEM_Y, OCA_BUTTON_ITEM_A,
};
Expand Down Expand Up @@ -1030,11 +1034,16 @@ void GenerateItemPool() {
IceTrapModels.push_back(GI_SWORD_BGS);
}

if (ShuffleEnemySouls) {
if (ShuffleEnemySouls.Is(SHUFFLEENEMYSOULS_ALL)) {
AddItemsToPool(ItemPool, enemySouls);
if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) {
AddItemsToPool(PendingJunkPool, enemySouls);
}
} else if (ShuffleEnemySouls.Is(SHUFFLEENEMYSOULS_BOSSES)) {
AddItemsToPool(ItemPool, bossSouls);
if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) {
AddItemsToPool(PendingJunkPool, bossSouls);
}
}

if (ShuffleOcarinaButtons) {
Expand Down
25 changes: 13 additions & 12 deletions source/location_access/locacc_dodongos_cavern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,19 @@ void AreaTable_Init_DodongosCavern() {
{
// Exits
Entrance(DODONGOS_CAVERN_LOBBY, { [] { return true; } }),
Entrance(DODONGOS_CAVERN_SE_ROOM, { [] {
return Here(DODONGOS_CAVERN_SE_CORRIDOR, [] {
return CanBlastOrSmash ||
(SoulDodongo && (CanAdultAttack || CanChildAttack ||
(CanTakeDamage && CanShield)));
});
},
/*Glitched*/
[] {
return Here(DODONGOS_CAVERN_SE_CORRIDOR,
[] { return (GlitchBlueFireWall && BlueFire); });
} }),
Entrance(DODONGOS_CAVERN_SE_ROOM,
{ [] {
return Here(DODONGOS_CAVERN_SE_CORRIDOR, [] {
return CanBlastOrSmash ||
((SoulDodongo || ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL)) &&
(CanAdultAttack || CanChildAttack || (CanTakeDamage && CanShield)));
});
},
/*Glitched*/
[] {
return Here(DODONGOS_CAVERN_SE_CORRIDOR,
[] { return (GlitchBlueFireWall && BlueFire); });
} }),
Entrance(DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, { [] { return true; } }),
});

Expand Down
76 changes: 38 additions & 38 deletions source/logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1215,44 +1215,44 @@ void LogicReset() {
DoubleDefense = false;
TriforcePieces = 0;

SoulPoe = ShuffleEnemySouls.Is(OFF);
SoulOctorok = ShuffleEnemySouls.Is(OFF);
SoulKeese = ShuffleEnemySouls.Is(OFF);
SoulTektite = ShuffleEnemySouls.Is(OFF);
SoulLeever = ShuffleEnemySouls.Is(OFF);
SoulPeahat = ShuffleEnemySouls.Is(OFF);
SoulLizalfosDinolfos = ShuffleEnemySouls.Is(OFF);
SoulShabom = ShuffleEnemySouls.Is(OFF);
SoulBiriBari = ShuffleEnemySouls.Is(OFF);
SoulTailpasaran = ShuffleEnemySouls.Is(OFF);
SoulSkulltula = ShuffleEnemySouls.Is(OFF);
SoulTorchSlug = ShuffleEnemySouls.Is(OFF);
SoulStinger = ShuffleEnemySouls.Is(OFF);
SoulMoblin = ShuffleEnemySouls.Is(OFF);
SoulArmos = ShuffleEnemySouls.Is(OFF);
SoulDekuBaba = ShuffleEnemySouls.Is(OFF);
SoulBubble = ShuffleEnemySouls.Is(OFF);
SoulFlyingTrap = ShuffleEnemySouls.Is(OFF);
SoulBeamos = ShuffleEnemySouls.Is(OFF);
SoulWallmaster = ShuffleEnemySouls.Is(OFF);
SoulRedeadGibdo = ShuffleEnemySouls.Is(OFF);
SoulShellBlade = ShuffleEnemySouls.Is(OFF);
SoulLikeLike = ShuffleEnemySouls.Is(OFF);
SoulParasiticTentacle = ShuffleEnemySouls.Is(OFF);
SoulAnubis = ShuffleEnemySouls.Is(OFF);
SoulSpike = ShuffleEnemySouls.Is(OFF);
SoulSkullKid = ShuffleEnemySouls.Is(OFF);
SoulFreezard = ShuffleEnemySouls.Is(OFF);
SoulDekuScrub = ShuffleEnemySouls.Is(OFF);
SoulWolfos = ShuffleEnemySouls.Is(OFF);
SoulStalchild = ShuffleEnemySouls.Is(OFF);
SoulGuay = ShuffleEnemySouls.Is(OFF);
SoulDoorMimic = ShuffleEnemySouls.Is(OFF);
SoulStalfos = ShuffleEnemySouls.Is(OFF);
SoulDarkLink = ShuffleEnemySouls.Is(OFF);
SoulFlareDancer = ShuffleEnemySouls.Is(OFF);
SoulDeadHand = ShuffleEnemySouls.Is(OFF);
SoulGerudo = ShuffleEnemySouls.Is(OFF);
SoulPoe = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulOctorok = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulKeese = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulTektite = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulLeever = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulPeahat = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulLizalfosDinolfos = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulShabom = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulBiriBari = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulTailpasaran = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulSkulltula = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulTorchSlug = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulStinger = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulMoblin = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulArmos = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulDekuBaba = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulBubble = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulFlyingTrap = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulBeamos = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulWallmaster = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulRedeadGibdo = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulShellBlade = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulLikeLike = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulParasiticTentacle = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulAnubis = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulSpike = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulSkullKid = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulFreezard = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulDekuScrub = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulWolfos = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulStalchild = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulGuay = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulDoorMimic = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulStalfos = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulDarkLink = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulFlareDancer = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulDeadHand = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulGerudo = ShuffleEnemySouls.IsNot(SHUFFLEENEMYSOULS_ALL);
SoulGohma = ShuffleEnemySouls.Is(OFF);
SoulDodongo = ShuffleEnemySouls.Is(OFF);
SoulBarinade = ShuffleEnemySouls.Is(OFF);
Expand Down
5 changes: 3 additions & 2 deletions source/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ Option ShuffleMerchants = Option::U8 ("Shuffle Merchants", {"Off", "
Option ShuffleAdultTradeQuest = Option::Bool("Shuffle Adult Trade", {"Off", "On"}, {adultTradeDesc});
Option ShuffleChestMinigame = Option::U8 ("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}, {chestMinigameDesc});
Option ShuffleFrogSongRupees = Option::Bool("Shuffle Frog Rupees", {"Off", "On"}, {frogSongRupeesDesc});
Option ShuffleEnemySouls = Option::U8 ("Shuffle Enemy Souls", {"Off", "On"}, {enemySoulDesc});
Option ShuffleEnemySouls = Option::U8 ("Shuffle Enemy Souls", {"Off", "All enemies", "Bosses only"}, {enemySoulDesc});
Option ShuffleOcarinaButtons = Option::Bool("Shuffle Ocarina Buttons",{"Off", "On"}, {ocarinaButtonsDesc});
std::vector<Option *> shuffleOptions = {
&RandomizeShuffle,
Expand Down Expand Up @@ -3288,7 +3288,8 @@ bool ValidateSettings() {
}

// Check that there are no MQ dungeons with Enemy Souls
if (ShuffleEnemySouls && Logic.IsNot(LOGIC_NONE) && Logic.IsNot(LOGIC_VANILLA) && MQDungeonCount.IsNot(0)) {
if (ShuffleEnemySouls.Is(SHUFFLEENEMYSOULS_ALL) && Logic.IsNot(LOGIC_NONE) && Logic.IsNot(LOGIC_VANILLA) &&
MQDungeonCount.IsNot(0)) {
if (ShuffleEnemySouls.IsHidden()) {
ShuffleEnemySouls.SetSelectedIndex(OFF);
} else {
Expand Down

0 comments on commit a51c23e

Please sign in to comment.