Rando: Master Sword Shuffle (#2981)

* The mother of all commits

* Removed `GI_SWORD_MASTER`;
"Master Sword" Items now actually give MS

* Removed dupe MS entries in item pool;
updated GIMESSAGE (should stop crashing on non-Windows);
re-added MS in item list

* Give Adult Link a freebie with shuffle MS on;
cihld -> adult no longer gives MS;
ToT Master Sword now gives correct item

* add master sword GI draw func based on ToT MS object

* Force `MasterSword` logic var to only update upon getting MS

* Dorf funny line now activates with LA and MS in inv

* Apply suggestions

* Updated RAND_INF;
Check Tracker changes;
Gave RAND_INF and ice trap logic to ToT MS check;
Fixed swordless behavior for HBA/fishing

* ToT MS Check now works in check tracker;
Visual bug where box hovers over non-existent MS gone;
Fixed RAND_INF check with ToT MS pedestal;
Ganon no longer gives free MS

* adult equips no longer reset in MS shuffle

* Apply (most) locacc review suggestions

Co-authored-by: inspectredc <78732756+inspectredc@users.noreply.github.com>

* Reorganized swordless check for interface to fit edge cases;
getting master sword no longer highlights box

* Edge case for BGS but no bow

* Fix implicit declaration error for GI hooks (#9)

* Adjusted `CanAdultAttack/Damage`; applied logic suggestions

* Fixed build errors (hopefully)

* Cleanup merge

* get shit working again

* Tidied up remaining uses of DD flag as rando indicator

* make master sword invisible and fix ms flag (#10)

* Add text to sheik if go mode is obtained but barrier is still up

* overhaul swordless behavior in `func_80083108`

* reworked ToT MS Check to have an actual GI

* suggestions

* Apply suggestions

* Better swordless handling with temp B (#11)

* better swordless handling with temp B

* prevent auto save in fishing pond

* prevent auto save during bombchu bowling

* enum fix

---------

Co-authored-by: Adam Bird <archez39@me.com>
Co-authored-by: inspectredc <78732756+inspectredc@users.noreply.github.com>
Co-authored-by: RaelCappra <rael.cappra@gmail.com>
Co-authored-by: Adam Bird <Archez@users.noreply.github.com>
This commit is contained in:
Ralphie Morell
2023-10-21 21:51:37 -04:00
committed by GitHub
parent e6445e0ce3
commit 2eaed8d81e
57 changed files with 558 additions and 310 deletions
@@ -122,7 +122,9 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) {
if (!LINK_IS_ADULT || (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && !IS_RANDO) || IS_RANDO) {
if (Actor_HasParent(&this->actor, play)) {
if (!LINK_IS_ADULT) {
Item_Give(play, ITEM_SWORD_MASTER);
if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) {
Item_Give(play, ITEM_SWORD_MASTER);
}
play->csCtx.segment = D_808BB2F0;
} else {
play->csCtx.segment = D_808BB7A0;
@@ -184,6 +186,11 @@ void BgTokiSwd_Draw(Actor* thisx, PlayState* play2) {
BgTokiSwd* this = (BgTokiSwd*)thisx;
s32 pad[3];
// Do not draw the Master Sword in the pedestal if the player has not found it yet
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) {
return;
}
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
@@ -153,6 +153,8 @@ void func_808FD27C(PlayState* play, Vec3f* position, Vec3f* velocity, f32 scale)
}
}
static u8 hasFoundMasterSword;
void BossGanon2_Init(Actor* thisx, PlayState* play) {
BossGanon2* this = (BossGanon2*)thisx;
s32 pad;
@@ -175,6 +177,11 @@ void BossGanon2_Init(Actor* thisx, PlayState* play) {
func_808FD5C4(this, play);
this->actor.naviEnemyId = 0x3E;
this->actor.gravity = 0.0f;
hasFoundMasterSword = 1;
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) {
hasFoundMasterSword = 0;
}
}
void BossGanon2_Destroy(Actor* thisx, PlayState* play) {
@@ -2895,6 +2902,11 @@ void func_80905DA8(BossGanon2* this, PlayState* play) {
effect->velocity.y += effect->accel.y;
effect->velocity.z += effect->accel.z;
if (effect->type == 1) {
// Prevent invisible master sword from making spark effect/sound when landing in the ground
// and prevent the player from picking it up if the player has not found the master sword
if (IS_RANDO && !hasFoundMasterSword) {
continue;
}
if (effect->unk_2E == 0) {
effect->unk_38.z += 1.0f;
effect->unk_38.y = (2.0f * M_PI) / 5.0f;
@@ -2955,6 +2967,11 @@ void func_809060E8(PlayState* play) {
for (i = 0; i < 1; i++) {
if (effect->type == 1) {
// Do not draw the master sword in the ground if the player has not found it yet
if (IS_RANDO && !hasFoundMasterSword) {
continue;
}
FrameInterpolation_RecordOpenChild("Ganon 809060E8 0", i);
Vec3f spA0;
@@ -5125,16 +5125,6 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) {
if (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) {
this->unk_15C = 0;
Player* player = GET_PLAYER(play);
if (gSaveContext.temporaryWeapon) {
player->currentSwordItemId = ITEM_NONE;
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_NONE);
gSaveContext.temporaryWeapon = false;
}
if (D_80B7A68C != 0) {
D_80B7A688 = 1;
D_80B7A68C = 0;
@@ -14946,6 +14946,16 @@ void func_80852648(PlayState* play, Player* this, CsCmdActorAction* arg2) {
this->heldItemId = ITEM_NONE;
this->modelGroup = this->nextModelGroup = Player_ActionToModelGroup(this, PLAYER_IA_NONE);
this->leftHandDLists = gPlayerLeftHandOpenDLs;
// If MS sword is shuffled and not in the players inventory, then we need to unequip the current sword
// and set swordless flag to mimic Link having his weapon knocked out of his hand in the Ganon fight
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_SWORD, 1)) {
Inventory_ChangeEquipment(EQUIP_SWORD, 0);
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
Flags_SetInfTable(INFTABLE_SWORDLESS);
return;
}
Inventory_ChangeEquipment(EQUIP_SWORD, 2);
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
Inventory_DeleteEquipment(play, 0);
@@ -15135,17 +15145,6 @@ s32 Player_IsDroppingFish(PlayState* play) {
s32 Player_StartFishing(PlayState* play) {
Player* this = GET_PLAYER(play);
if (gSaveContext.linkAge == 1) {
if (!CHECK_OWNED_EQUIP(EQUIP_SWORD, 0)) {
gSaveContext.temporaryWeapon = true;
}
if (this->heldItemId == ITEM_NONE) {
this->currentSwordItemId = ITEM_SWORD_KOKIRI;
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI;
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_KOKIRI);
}
}
func_80832564(play, this);
func_80835F44(play, this, ITEM_FISHING_POLE);
return 1;
@@ -4378,6 +4378,9 @@ void KaleidoScope_Update(PlayState* play)
gSaveContext.buttonStatus[buttonIndex] = sButtonStatusSave[buttonIndex];
}
// Used to clear swordless temp B after unpause so minigame/epona handling restarts
Interface_RandoRestoreSwordless();
interfaceCtx->unk_1FA = interfaceCtx->unk_1FC = 0;
osSyncPrintf(VT_FGCOL(YELLOW));
osSyncPrintf("i=%d LAST_TIME_TYPE=%d\n", i, gSaveContext.unk_13EE);