From 669f76d2f448a9cca17a92c063f89ac6a811b9d1 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Sat, 27 Aug 2022 22:49:13 -0700 Subject: [PATCH 01/34] Implement Enhanced Magic Arrows Currently as a rando-only enhancement until it can be accounted for in logic --- .../actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 51 ++++++++++- .../actors/ovl_Bg_Breakwall/z_bg_breakwall.h | 1 + .../ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c | 65 ++++++++++++-- .../actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c | 6 +- .../ovl_Obj_Lightswitch/z_obj_lightswitch.c | 86 +++++++++++++++++-- 5 files changed, 197 insertions(+), 12 deletions(-) diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 4951fb9a9..2c29e1725 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -59,6 +59,27 @@ static ColliderQuadInit sQuadInit = { { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; +// This quad only used for "Blue Fire Arrows" enhancement +static ColliderQuadInit sIceArrowQuadInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xFFCFFFFF, 0x00, 0x00 }, + TOUCH_NONE, + BUMP_ON, + OCELEM_NONE, + }, + { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, +}; + static BombableWallInfo sBombableWallInfo[] = { { &object_bwall_Col_000118, object_bwall_DL_000040, 0 }, { &object_bwall_Col_000118, object_bwall_DL_000040, 0 }, @@ -73,6 +94,8 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), }; +bool enhancedIceArrow = false; + void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) { this->actionFunc = actionFunc; } @@ -82,6 +105,8 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; + enhancedIceArrow = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, DPM_UNK); this->bombableWallDList = sBombableWallInfo[wallType].dList; @@ -100,6 +125,11 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f); Collider_InitQuad(globalCtx, &this->collider); Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit); + // If "Blue Fire Arrows" are enabled, set up this collider for them + if (enhancedIceArrow) { + Collider_InitQuad(globalCtx, &this->colliderIceArrow); + Collider_SetQuad(globalCtx, &this->colliderIceArrow, &this->dyna.actor, &sIceArrowQuadInit); + } } else { this->dyna.actor.world.pos.y -= 40.0f; } @@ -227,7 +257,22 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, GlobalContext* globalCtx) { * despawn itself. */ void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) { - if (this->collider.base.acFlags & 2) { + bool blueFireArrowCheck = false; + // If "Blue Fire Arrows" enabled, check this collider for a hit + if (enhancedIceArrow) { + if (this->colliderIceArrow.base.acFlags & AC_HIT) { + this->colliderIceArrow.base.acFlags &= ~AC_HIT; + if ((this->colliderIceArrow.base.ac != NULL) && (this->colliderIceArrow.base.ac->id == ACTOR_EN_ARROW)) { + + if (this->colliderIceArrow.base.ac->child != NULL && + this->colliderIceArrow.base.ac->child->id == ACTOR_ARROW_ICE) { + blueFireArrowCheck = true; + } + } + } + } + + if (this->collider.base.acFlags & 2 || blueFireArrowCheck) { Vec3f effectPos; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; @@ -313,6 +358,10 @@ void BgBreakwall_Draw(Actor* thisx, GlobalContext* globalCtx) { Collider_SetQuadVertices(&this->collider, &colQuad[0], &colQuad[1], &colQuad[2], &colQuad[3]); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (enhancedIceArrow) { + Collider_SetQuadVertices(&this->colliderIceArrow, &colQuad[0], &colQuad[1], &colQuad[2], &colQuad[3]); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderIceArrow.base); + } } CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h index 43fd4ee93..7d2606195 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h @@ -14,6 +14,7 @@ typedef struct BgBreakwall { /* 0x0168 */ s8 colType; /* 0x0169 */ s8 bankIndex; /* 0x016C */ ColliderQuad collider; + ColliderQuad colliderIceArrow; // Blue Fire Arrows /* 0x01EC */ BgBreakwallActionFunc actionFunc; } BgBreakwall; // size = 0x01F0 diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c index 70a1ea1a6..709f8e1ba 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c @@ -14,6 +14,8 @@ void func_808911BC(BgIceShelter* this); void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx); void func_808911D4(BgIceShelter* this, GlobalContext* globalCtx); +void CheckIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, GlobalContext* globalCtx); + const ActorInit Bg_Ice_Shelter_InitVars = { ACTOR_BG_ICE_SHELTER, ACTORCAT_BG, @@ -32,7 +34,7 @@ static f32 sScales[] = { 0.1f, 0.06f, 0.1f, 0.1f, 0.25f }; static Color_RGBA8 sDustPrimColor = { 250, 250, 250, 255 }; static Color_RGBA8 sDustEnvColor = { 180, 180, 180, 255 }; -static ColliderCylinderInit D_8089170C = { +static ColliderCylinderInit sCylinder1Init = { { COLTYPE_NONE, AT_NONE, @@ -52,7 +54,7 @@ static ColliderCylinderInit D_8089170C = { { 0, 0, 0, { 0, 0, 0 } }, }; -static ColliderCylinderInit D_80891738 = { +static ColliderCylinderInit sCylinder2Init = { { COLTYPE_HARD, AT_NONE, @@ -72,14 +74,44 @@ static ColliderCylinderInit D_80891738 = { { 0, 0, 0, { 0, 0, 0 } }, }; +// This cylinder only used for "Blue Fire Arrows" enhancement +static ColliderCylinderInit sIceArrowCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_OTHER | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xFFCFFFFF, 0x00, 0x00 }, + TOUCH_NONE, + BUMP_ON, + OCELEM_ON, + }, + { 0, 0, 0, { 0, 0, 0 } }, +}; + +bool enhancedIceArrow = false; + void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) { static s16 cylinderRadii[] = { 47, 33, 44, 41, 100 }; static s16 cylinderHeights[] = { 80, 54, 90, 60, 200 }; s32 pad; s32 type = (this->dyna.actor.params >> 8) & 7; + enhancedIceArrow = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); + Collider_InitCylinder(globalCtx, &this->cylinder1); - Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &D_8089170C); + // If "Blue Fire Arrows" is enabled, set up a collider on the red ice that responds to them + if (enhancedIceArrow) { + Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &sIceArrowCylinderInit); + } else { + Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &sCylinder1Init); + } Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder1); this->cylinder1.dim.radius = cylinderRadii[type]; @@ -87,7 +119,7 @@ void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) { if (type == 0 || type == 1 || type == 4) { Collider_InitCylinder(globalCtx, &this->cylinder2); - Collider_SetCylinder(globalCtx, &this->cylinder2, &this->dyna.actor, &D_80891738); + Collider_SetCylinder(globalCtx, &this->cylinder2, &this->dyna.actor, &sCylinder2Init); Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder2); this->cylinder2.dim.radius = cylinderRadii[type]; this->cylinder2.dim.height = cylinderHeights[type]; @@ -292,7 +324,12 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) { this->dyna.actor.parent->freezeTimer = 10000; } } - + // If we have "Blue Fire Arrows" enabled, check both cylinders for a hit + if (enhancedIceArrow) { + CheckIceArrowHit(this, this->cylinder1, type, globalCtx); + CheckIceArrowHit(this, this->cylinder2, type, globalCtx); + } + // Default blue fire check if (this->cylinder1.base.acFlags & AC_HIT) { this->cylinder1.base.acFlags &= ~AC_HIT; @@ -320,6 +357,24 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) { CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->cylinder1.base); } +// Check for an Ice Arrow hit (for "Blue Fire Arrows" enhancement). Copied from default blue fire check +void CheckIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, GlobalContext* globalCtx) { + if (cylinder.base.acFlags & AC_HIT) { + cylinder.base.acFlags &= ~AC_HIT; + if ((cylinder.base.ac != NULL) && (cylinder.base.ac->id == ACTOR_EN_ARROW)) { + if (cylinder.base.ac->child != NULL && cylinder.base.ac->child->id == ACTOR_ARROW_ICE) { + if (type == 4) { + if (this->dyna.actor.parent != NULL) { + this->dyna.actor.parent->freezeTimer = 50; + } + } + func_808911BC(this); + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_ICE_MELT); + } + } + } +} + void func_808911BC(BgIceShelter* this) { this->actionFunc = func_808911D4; this->alpha = 255; diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c index 57c7ac413..9476a02a2 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c @@ -96,7 +96,11 @@ void BgJyaLift_DelayMove(BgJyaLift* this, GlobalContext* globalCtx) { if (Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F) || (this->moveDelay > 0)) { this->moveDelay++; if (this->moveDelay >= 20) { - OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM); + // Skip this cutscene if using Enhanced Arrows, since activating the switch while + // not standing on the platform will cause the cutscene to show the unloaded room + if (!(gSaveContext.n64ddFlag && CVar_GetS32("gEnhancedMagicArrows", 0) != 0)) { + OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM); + } BgJyaLift_SetupMove(this); } } diff --git a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 459f20218..3335aa340 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -73,6 +73,36 @@ static ColliderJntSphInit sColliderJntSphInit = { 1, sColliderJntSphElementInit, }; +// Collider info used for "Enhanced Arrows" +static ColliderJntSphElementInit sColliderLightArrowElementInit[] = { + { + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00202000, 0x00, 0x00 }, + TOUCH_NONE, + BUMP_ON, + OCELEM_ON, + }, + { 0, { { 0, 0, 0 }, 19 }, 100 }, + }, +}; +// Sphere collider used for "Enhanced Arrows" +static ColliderJntSphInit sColliderLightArrowInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_JNTSPH, + }, + 1, + sColliderLightArrowElementInit, +}; + +bool activatedByLightArrow = false; +bool enhancedLightArrow = false; static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE }; @@ -91,9 +121,15 @@ static InitChainEntry sInitChain[] = { void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) { s32 pad; + enhancedLightArrow = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); Collider_InitJntSph(globalCtx, &this->collider); - Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems); + // If "Enhanced Arrows" is enabled, set up the collider to allow Light Arrow hits + if (enhancedLightArrow) { + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderLightArrowInit, this->colliderItems); + } else { + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems); + } Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y), this->actor.world.pos.z, &this->actor.shape.rot); @@ -211,6 +247,23 @@ void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx2) { GlobalContext* globalCtx = globalCtx2; ObjLightswitch* this = (ObjLightswitch*)thisx; + // Unset the switch flag on room exit to prevent the rock in the wall from + // vanishing on its own after activating the sun switch by Light Arrow + if (activatedByLightArrow && enhancedLightArrow) { + switch (this->actor.params >> 4 & 3) { + case OBJLIGHTSWITCH_TYPE_STAY_ON: + case OBJLIGHTSWITCH_TYPE_2: + case OBJLIGHTSWITCH_TYPE_1: + if (this->actor.room != 25) { // Don't unset the flag for the chain platform + Flags_UnsetSwitch(globalCtx, this->actor.params >> 8 & 0x3F); + } + activatedByLightArrow = false; + break; + case OBJLIGHTSWITCH_TYPE_BURN: + break; + } + } + Collider_DestroyJntSph(globalCtx, &this->collider); } @@ -221,8 +274,11 @@ void ObjLightswitch_SetupOff(ObjLightswitch* this) { this->color[1] = 125 << 6; this->color[2] = 255 << 6; this->alpha = 255 << 6; + if (enhancedLightArrow) { + activatedByLightArrow = false; + } } - +// A Sun Switch that is currently turned off void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) { switch (this->actor.params >> 4 & 3) { case OBJLIGHTSWITCH_TYPE_STAY_ON: @@ -230,6 +286,13 @@ void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { ObjLightswitch_SetupTurnOn(this); ObjLightswitch_SetSwitchFlag(this, globalCtx); + // Remember if we've been activated by a Light Arrow, so we can + // prevent the switch from immediately turning back off + if (enhancedLightArrow) { + if (this->collider.base.ac != NULL && this->collider.base.ac->id == ACTOR_EN_ARROW) { + activatedByLightArrow = true; + } + } } break; case OBJLIGHTSWITCH_TYPE_1: @@ -289,13 +352,18 @@ void ObjLightswitch_SetupOn(ObjLightswitch* this) { this->flameRingRotSpeed = -0xAA; this->timer = 0; } - +// A Sun Switch that is currently turned on void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) { switch (this->actor.params >> 4 & 3) { case OBJLIGHTSWITCH_TYPE_STAY_ON: if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) { ObjLightswitch_SetupTurnOff(this); } + if (enhancedLightArrow && (this->collider.base.acFlags & AC_HIT)) { + if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) { + activatedByLightArrow = false; + } + } break; case OBJLIGHTSWITCH_TYPE_1: if (this->collider.base.acFlags & AC_HIT && !(this->prevFrameACflags & AC_HIT)) { @@ -304,10 +372,18 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) { } break; case OBJLIGHTSWITCH_TYPE_2: + if (enhancedLightArrow && (this->collider.base.acFlags & AC_HIT)) { + if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) { + activatedByLightArrow = false; + } + } if (!(this->collider.base.acFlags & AC_HIT)) { if (this->timer >= 7) { - ObjLightswitch_SetupTurnOff(this); - ObjLightswitch_ClearSwitchFlag(this, globalCtx); + // If we aren't using Enhanced Light Arrows, let the switch turn off normally + if (!activatedByLightArrow) { + ObjLightswitch_SetupTurnOff(this); + ObjLightswitch_ClearSwitchFlag(this, globalCtx); + } } else { this->timer++; } From d510d8cde04345e4b0a52ab0d1b2f41b7ee51c3d Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Sun, 28 Aug 2022 09:45:00 -0700 Subject: [PATCH 02/34] Comment clarity --- soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 6 +++--- soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h | 2 +- .../actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 2c29e1725..6d816404c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -257,7 +257,7 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, GlobalContext* globalCtx) { * despawn itself. */ void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) { - bool blueFireArrowCheck = false; + bool blueFireArrowHit = false; // If "Blue Fire Arrows" enabled, check this collider for a hit if (enhancedIceArrow) { if (this->colliderIceArrow.base.acFlags & AC_HIT) { @@ -266,13 +266,13 @@ void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) { if (this->colliderIceArrow.base.ac->child != NULL && this->colliderIceArrow.base.ac->child->id == ACTOR_ARROW_ICE) { - blueFireArrowCheck = true; + blueFireArrowHit = true; } } } } - if (this->collider.base.acFlags & 2 || blueFireArrowCheck) { + if (this->collider.base.acFlags & 2 || blueFireArrowHit) { Vec3f effectPos; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h index 7d2606195..09089469e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h @@ -14,7 +14,7 @@ typedef struct BgBreakwall { /* 0x0168 */ s8 colType; /* 0x0169 */ s8 bankIndex; /* 0x016C */ ColliderQuad collider; - ColliderQuad colliderIceArrow; // Blue Fire Arrows + ColliderQuad colliderIceArrow; // For "Blue Fire Arrows" enhancement /* 0x01EC */ BgBreakwallActionFunc actionFunc; } BgBreakwall; // size = 0x01F0 diff --git a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 3335aa340..65c39a54e 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -249,12 +249,15 @@ void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx2) { // Unset the switch flag on room exit to prevent the rock in the wall from // vanishing on its own after activating the sun switch by Light Arrow + // Also prevents the cobra mirror from rotating to face the sun on its own + // Makes sun switches temporary when activated by Light Arrows (will turn off on room exit) if (activatedByLightArrow && enhancedLightArrow) { switch (this->actor.params >> 4 & 3) { case OBJLIGHTSWITCH_TYPE_STAY_ON: case OBJLIGHTSWITCH_TYPE_2: case OBJLIGHTSWITCH_TYPE_1: - if (this->actor.room != 25) { // Don't unset the flag for the chain platform + // Except for this one, because we want the chain platform to stay down for good + if (this->actor.room != 25) { Flags_UnsetSwitch(globalCtx, this->actor.params >> 8 & 0x3F); } activatedByLightArrow = false; @@ -359,6 +362,7 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) { if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) { ObjLightswitch_SetupTurnOff(this); } + // If hit by sunlight after already being turned on, then behave as if originally activated by sunlight if (enhancedLightArrow && (this->collider.base.acFlags & AC_HIT)) { if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) { activatedByLightArrow = false; @@ -372,6 +376,7 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) { } break; case OBJLIGHTSWITCH_TYPE_2: + // If hit by sunlight after already being turned on, then behave as if originally activated by sunlight if (enhancedLightArrow && (this->collider.base.acFlags & AC_HIT)) { if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) { activatedByLightArrow = false; From dc44dc9ef640c5524f397da47a64e2587e04d6b5 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Sun, 28 Aug 2022 10:15:39 -0700 Subject: [PATCH 03/34] Add rando enhancement checkbox --- libultraship/libultraship/ImGuiImpl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index d430bc769..7e78b1718 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -2017,6 +2017,11 @@ namespace SohImGui { "Play unique fanfares when obtaining quest items " "(medallions/stones/songs). Note that these fanfares are longer than usual." ); + PaddedEnhancementCheckbox("Enhanced Magic Arrows", "gEnhancedMagicArrows", true, false); + Tooltip( + "Allows Ice Arrows to melt red ice and allows Light Arrows " + "to activate Sun Switches." + ); ImGui::EndMenu(); } From 12ae59d133a88ea713d3cce9563a9e30f231fa03 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Sun, 28 Aug 2022 10:39:53 -0700 Subject: [PATCH 04/34] Change bool name To make jenkins happy (I hope) --- .../overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 6d816404c..eec0c067b 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -94,7 +94,7 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), }; -bool enhancedIceArrow = false; +bool enhancedIceArrowDC = false; void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) { this->actionFunc = actionFunc; @@ -105,7 +105,7 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; - enhancedIceArrow = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); + enhancedIceArrowDC = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, DPM_UNK); @@ -126,7 +126,7 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { Collider_InitQuad(globalCtx, &this->collider); Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit); // If "Blue Fire Arrows" are enabled, set up this collider for them - if (enhancedIceArrow) { + if (enhancedIceArrowDC) { Collider_InitQuad(globalCtx, &this->colliderIceArrow); Collider_SetQuad(globalCtx, &this->colliderIceArrow, &this->dyna.actor, &sIceArrowQuadInit); } @@ -259,7 +259,7 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, GlobalContext* globalCtx) { void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) { bool blueFireArrowHit = false; // If "Blue Fire Arrows" enabled, check this collider for a hit - if (enhancedIceArrow) { + if (enhancedIceArrowDC) { if (this->colliderIceArrow.base.acFlags & AC_HIT) { this->colliderIceArrow.base.acFlags &= ~AC_HIT; if ((this->colliderIceArrow.base.ac != NULL) && (this->colliderIceArrow.base.ac->id == ACTOR_EN_ARROW)) { @@ -358,7 +358,7 @@ void BgBreakwall_Draw(Actor* thisx, GlobalContext* globalCtx) { Collider_SetQuadVertices(&this->collider, &colQuad[0], &colQuad[1], &colQuad[2], &colQuad[3]); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (enhancedIceArrow) { + if (enhancedIceArrowDC) { Collider_SetQuadVertices(&this->colliderIceArrow, &colQuad[0], &colQuad[1], &colQuad[2], &colQuad[3]); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderIceArrow.base); } From 8e2f035278734cd71a993de5149623af50532d24 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Tue, 30 Aug 2022 11:06:42 -0700 Subject: [PATCH 05/34] Split into two enhancements "Blue Fire Arrows" and "Sunlight Arrows" --- libultraship/libultraship/ImGuiImpl.cpp | 9 +++++--- .../actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 10 ++++----- .../ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c | 8 +++---- .../actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c | 2 +- .../ovl_Obj_Lightswitch/z_obj_lightswitch.c | 22 +++++++++---------- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 7e78b1718..c43b5337e 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -2017,10 +2017,13 @@ namespace SohImGui { "Play unique fanfares when obtaining quest items " "(medallions/stones/songs). Note that these fanfares are longer than usual." ); - PaddedEnhancementCheckbox("Enhanced Magic Arrows", "gEnhancedMagicArrows", true, false); + PaddedEnhancementCheckbox("Blue Fire Arrows", "gBlueFireArrows", true, false); Tooltip( - "Allows Ice Arrows to melt red ice and allows Light Arrows " - "to activate Sun Switches." + "Allows Ice Arrows to melt red ice and break mud walls" + ); + PaddedEnhancementCheckbox("Sunlight Arrows", "gSunLightArrows", true, false); + Tooltip( + "Allows Light Arrows to activate Sun Switches" ); ImGui::EndMenu(); } diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index eec0c067b..bead453d1 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -94,7 +94,7 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), }; -bool enhancedIceArrowDC = false; +bool blueFireArrowsDC = false; void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) { this->actionFunc = actionFunc; @@ -105,7 +105,7 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF; - enhancedIceArrowDC = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); + blueFireArrowsDC = (gSaveContext.n64ddFlag && (CVar_GetS32("gBlueFireArrows", 0) != 0)); Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, DPM_UNK); @@ -126,7 +126,7 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { Collider_InitQuad(globalCtx, &this->collider); Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit); // If "Blue Fire Arrows" are enabled, set up this collider for them - if (enhancedIceArrowDC) { + if (blueFireArrowsDC) { Collider_InitQuad(globalCtx, &this->colliderIceArrow); Collider_SetQuad(globalCtx, &this->colliderIceArrow, &this->dyna.actor, &sIceArrowQuadInit); } @@ -259,7 +259,7 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, GlobalContext* globalCtx) { void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) { bool blueFireArrowHit = false; // If "Blue Fire Arrows" enabled, check this collider for a hit - if (enhancedIceArrowDC) { + if (blueFireArrowsDC) { if (this->colliderIceArrow.base.acFlags & AC_HIT) { this->colliderIceArrow.base.acFlags &= ~AC_HIT; if ((this->colliderIceArrow.base.ac != NULL) && (this->colliderIceArrow.base.ac->id == ACTOR_EN_ARROW)) { @@ -358,7 +358,7 @@ void BgBreakwall_Draw(Actor* thisx, GlobalContext* globalCtx) { Collider_SetQuadVertices(&this->collider, &colQuad[0], &colQuad[1], &colQuad[2], &colQuad[3]); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (enhancedIceArrowDC) { + if (blueFireArrowsDC) { Collider_SetQuadVertices(&this->colliderIceArrow, &colQuad[0], &colQuad[1], &colQuad[2], &colQuad[3]); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderIceArrow.base); } diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c index 709f8e1ba..52200ac3e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c @@ -95,7 +95,7 @@ static ColliderCylinderInit sIceArrowCylinderInit = { { 0, 0, 0, { 0, 0, 0 } }, }; -bool enhancedIceArrow = false; +bool blueFireArrows = false; void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) { static s16 cylinderRadii[] = { 47, 33, 44, 41, 100 }; @@ -103,11 +103,11 @@ void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) { s32 pad; s32 type = (this->dyna.actor.params >> 8) & 7; - enhancedIceArrow = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); + blueFireArrows = (gSaveContext.n64ddFlag && (CVar_GetS32("gBlueFireArrows", 0) != 0)); Collider_InitCylinder(globalCtx, &this->cylinder1); // If "Blue Fire Arrows" is enabled, set up a collider on the red ice that responds to them - if (enhancedIceArrow) { + if (blueFireArrows) { Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &sIceArrowCylinderInit); } else { Collider_SetCylinder(globalCtx, &this->cylinder1, &this->dyna.actor, &sCylinder1Init); @@ -325,7 +325,7 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) { } } // If we have "Blue Fire Arrows" enabled, check both cylinders for a hit - if (enhancedIceArrow) { + if (blueFireArrows) { CheckIceArrowHit(this, this->cylinder1, type, globalCtx); CheckIceArrowHit(this, this->cylinder2, type, globalCtx); } diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c index 9476a02a2..c7db6751e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c @@ -98,7 +98,7 @@ void BgJyaLift_DelayMove(BgJyaLift* this, GlobalContext* globalCtx) { if (this->moveDelay >= 20) { // Skip this cutscene if using Enhanced Arrows, since activating the switch while // not standing on the platform will cause the cutscene to show the unloaded room - if (!(gSaveContext.n64ddFlag && CVar_GetS32("gEnhancedMagicArrows", 0) != 0)) { + if (!(gSaveContext.n64ddFlag && CVar_GetS32("gSunLightArrows", 0) != 0)) { OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM); } BgJyaLift_SetupMove(this); diff --git a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 65c39a54e..4791f186d 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -73,7 +73,7 @@ static ColliderJntSphInit sColliderJntSphInit = { 1, sColliderJntSphElementInit, }; -// Collider info used for "Enhanced Arrows" +// Collider info used for "Sunlight Arrows" static ColliderJntSphElementInit sColliderLightArrowElementInit[] = { { { @@ -87,7 +87,7 @@ static ColliderJntSphElementInit sColliderLightArrowElementInit[] = { { 0, { { 0, 0, 0 }, 19 }, 100 }, }, }; -// Sphere collider used for "Enhanced Arrows" +// Sphere collider used for "Sunlight Arrows" static ColliderJntSphInit sColliderLightArrowInit = { { COLTYPE_NONE, @@ -102,7 +102,7 @@ static ColliderJntSphInit sColliderLightArrowInit = { }; bool activatedByLightArrow = false; -bool enhancedLightArrow = false; +bool sunLightArrows = false; static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE }; @@ -121,11 +121,11 @@ static InitChainEntry sInitChain[] = { void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) { s32 pad; - enhancedLightArrow = (gSaveContext.n64ddFlag && (CVar_GetS32("gEnhancedMagicArrows", 0) != 0)); + sunLightArrows = (gSaveContext.n64ddFlag && (CVar_GetS32("gSunLightArrows", 0) != 0)); Collider_InitJntSph(globalCtx, &this->collider); - // If "Enhanced Arrows" is enabled, set up the collider to allow Light Arrow hits - if (enhancedLightArrow) { + // If "Sunlight Arrows" is enabled, set up the collider to allow Light Arrow hits + if (sunLightArrows) { Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderLightArrowInit, this->colliderItems); } else { Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems); @@ -251,7 +251,7 @@ void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx2) { // vanishing on its own after activating the sun switch by Light Arrow // Also prevents the cobra mirror from rotating to face the sun on its own // Makes sun switches temporary when activated by Light Arrows (will turn off on room exit) - if (activatedByLightArrow && enhancedLightArrow) { + if (activatedByLightArrow && sunLightArrows) { switch (this->actor.params >> 4 & 3) { case OBJLIGHTSWITCH_TYPE_STAY_ON: case OBJLIGHTSWITCH_TYPE_2: @@ -277,7 +277,7 @@ void ObjLightswitch_SetupOff(ObjLightswitch* this) { this->color[1] = 125 << 6; this->color[2] = 255 << 6; this->alpha = 255 << 6; - if (enhancedLightArrow) { + if (sunLightArrows) { activatedByLightArrow = false; } } @@ -291,7 +291,7 @@ void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) { ObjLightswitch_SetSwitchFlag(this, globalCtx); // Remember if we've been activated by a Light Arrow, so we can // prevent the switch from immediately turning back off - if (enhancedLightArrow) { + if (sunLightArrows) { if (this->collider.base.ac != NULL && this->collider.base.ac->id == ACTOR_EN_ARROW) { activatedByLightArrow = true; } @@ -363,7 +363,7 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) { ObjLightswitch_SetupTurnOff(this); } // If hit by sunlight after already being turned on, then behave as if originally activated by sunlight - if (enhancedLightArrow && (this->collider.base.acFlags & AC_HIT)) { + if (sunLightArrows && (this->collider.base.acFlags & AC_HIT)) { if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) { activatedByLightArrow = false; } @@ -377,7 +377,7 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) { break; case OBJLIGHTSWITCH_TYPE_2: // If hit by sunlight after already being turned on, then behave as if originally activated by sunlight - if (enhancedLightArrow && (this->collider.base.acFlags & AC_HIT)) { + if (sunLightArrows && (this->collider.base.acFlags & AC_HIT)) { if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) { activatedByLightArrow = false; } From 0a2bbabbed7eae91c2bbd36d1e648c1c06280629 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Wed, 31 Aug 2022 21:13:09 -0700 Subject: [PATCH 06/34] First pass on logic --- .../3drando/location_access/locacc_ganons_castle.cpp | 2 +- .../3drando/location_access/locacc_spirit_temple.cpp | 4 ++-- soh/soh/Enhancements/randomizer/3drando/logic.cpp | 2 +- .../randomizer/3drando/setting_descriptions.cpp | 10 ++++++++++ .../randomizer/3drando/setting_descriptions.hpp | 3 +++ soh/soh/Enhancements/randomizer/3drando/settings.cpp | 8 ++++++++ soh/soh/Enhancements/randomizer/3drando/settings.hpp | 4 ++++ soh/soh/Enhancements/randomizer/randomizer.cpp | 6 ++++++ soh/soh/Enhancements/randomizer/randomizerTypes.h | 4 +++- 9 files changed, 38 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp index 383b72b9f..264fd1959 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ganons_castle.cpp @@ -87,7 +87,7 @@ void AreaTable_Init_GanonsCastle() { areaTable[GANONS_CASTLE_SPIRIT_TRIAL] = Area("Ganon's Castle Spirit Trial", "Ganon's Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&NutPot, {[]{return NutPot || ((LogicSpiritTrialHookshot || CanUse(HOOKSHOT)) && HasBombchus && Bow && MirrorShield && IsAdult);}}), - EventAccess(&SpiritTrialClear, {[]{return CanUse(LIGHT_ARROWS) && MirrorShield && HasBombchus && (LogicSpiritTrialHookshot || CanUse(HOOKSHOT));}}), + EventAccess(&SpiritTrialClear, {[]{return CanUse(LIGHT_ARROWS) && (MirrorShield || SunlightArrows) && HasBombchus && (LogicSpiritTrialHookshot || CanUse(HOOKSHOT));}}), }, { //Locations LocationAccess(GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, {[]{return LogicSpiritTrialHookshot || CanUse(HOOKSHOT);}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp index 4bfd7c269..687efdde2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp @@ -114,7 +114,7 @@ void AreaTable_Init_SpiritTemple() { areaTable[SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Central Locked Door", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, {[]{return MirrorShield && HasExplosives;}}), + LocationAccess(SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, {[]{return (MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS))) && HasExplosives;}}), LocationAccess(SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, {[]{return (LogicLensSpirit || CanUse(LENS_OF_TRUTH)) && HasExplosives;}}), LocationAccess(SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, {[]{return (LogicLensSpirit || CanUse(LENS_OF_TRUTH)) && HasExplosives;}}), }, { @@ -128,7 +128,7 @@ void AreaTable_Init_SpiritTemple() { }, { //Locations LocationAccess(SPIRIT_TEMPLE_BOSS_KEY_CHEST, {[]{return CanPlay(ZeldasLullaby) && ((CanTakeDamage && LogicFlamingChests) || (Bow && Hookshot));}}), - LocationAccess(SPIRIT_TEMPLE_TOPMOST_CHEST, {[]{return MirrorShield;}}), + LocationAccess(SPIRIT_TEMPLE_TOPMOST_CHEST, {[]{return MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS));}}), LocationAccess(SPIRIT_TEMPLE_TWINROVA_HEART, {[]{return MirrorShield && HasExplosives && Hookshot && BossKeySpiritTemple;}}), LocationAccess(TWINROVA, {[]{return MirrorShield && HasExplosives && Hookshot && BossKeySpiritTemple;}}), }, {}); diff --git a/soh/soh/Enhancements/randomizer/3drando/logic.cpp b/soh/soh/Enhancements/randomizer/3drando/logic.cpp index f85e4ed2a..c66f2bf82 100644 --- a/soh/soh/Enhancements/randomizer/3drando/logic.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/logic.cpp @@ -702,7 +702,7 @@ namespace Logic { Nuts = DekuNutDrop || Nuts; Sticks = DekuStickDrop || Sticks; Bugs = HasBottle && BugsAccess; - BlueFire = HasBottle && BlueFireAccess; + BlueFire = (HasBottle && BlueFireAccess) || (BlueFireArrows && CanUse(ICE_ARROWS)); Fish = HasBottle && FishAccess; Fairy = HasBottle && FairyAccess; diff --git a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp index 328b862bd..aa0c4637b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.cpp @@ -896,6 +896,16 @@ string_view gkDurabilityRandomSafe = "Each Giant's Knife will get a random du "between 10 and 50, with an average of 30."; // // /*------------------------------ // +| BLUE FIRE ARROWS | // +------------------------------*/ // +string_view blueFireArrowsDesc = "Ice Arrows gain the ability to melt red ice\n" // + "and break the mud walls in Dodongo's Cavern."; // +/*------------------------------ // +| SUNLIGHT ARROWS | // +------------------------------*/ // +string_view sunlightArrowsDesc = "Light Arrows gain the ability to activate sun\n" // + "switches."; // +/*------------------------------ // | MULTIPLAYER | // ------------------------------*/ // string_view mp_EnabledDesc = "Enables multiplayer.\n" // diff --git a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp index cea8f419d..224563d5e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/setting_descriptions.hpp @@ -284,6 +284,9 @@ extern string_view gkDurabilityVanilla; extern string_view gkDurabilityRandomRisk; extern string_view gkDurabilityRandomSafe; +extern string_view blueFireArrowsDesc; +extern string_view sunlightArrowsDesc; + extern string_view mp_EnabledDesc; extern string_view mp_SharedProgressDesc; extern string_view mp_SyncIdDesc; diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index cb91e5334..a5f16c228 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -304,6 +304,8 @@ namespace Settings { Option IngameSpoilers = Option::Bool("Ingame Spoilers", {"Hide", "Show"}, {ingameSpoilersHideDesc, ingameSpoilersShowDesc }); Option MenuOpeningButton = Option::U8 ("Open Info Menu with", {"Select","Start","D-Pad Up","D-Pad Down","D-Pad Right","D-Pad Left",}, {menuButtonDesc}); Option RandomTrapDmg = Option::U8 ("Random Trap Damage", {"Off", "Basic", "Advanced"}, {randomTrapDmgDesc, basicTrapDmgDesc, advancedTrapDmgDesc}, OptionCategory::Setting, 1); // Basic + Option BlueFireArrows = Option::Bool("Blue Fire Arrows", {"No", "Yes"}, {blueFireArrowsDesc}); + Option SunlightArrows = Option::Bool("Sunlight Arrows", {"No", "Yes"}, {sunlightArrowsDesc}); bool HasNightStart = false; std::vector