mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-02-16 23:30:15 -05:00
Enhanced Magic Arrows (non-rando) (#1376)
* Add magic arrow enhancements, non-rando Changes to red ice actor, sun switch actor, and mudwall actor to adjust their collision * Update tooltip * Simplify mudwall collision check * Restore checkboxes in menu Accidentally lost these during merge * Update tooltip * Add line break in tooltip * Clarify var names and comments Also preserve chain platform cutscene in spirit based on Link's position * Remove !=0 from cvar check * Missed a couple * Clean up chain platform cutscene check
This commit is contained in:
parent
9686a7ca4c
commit
a9f3aedf8e
@ -237,6 +237,10 @@ namespace GameMenuBar {
|
|||||||
CVar_SetS32("gInjectSkulltulaCount", 0);
|
CVar_SetS32("gInjectSkulltulaCount", 0);
|
||||||
// Pull grave during the day
|
// Pull grave during the day
|
||||||
CVar_SetS32("gDayGravePull", 0);
|
CVar_SetS32("gDayGravePull", 0);
|
||||||
|
// Blue Fire Arrows
|
||||||
|
CVar_SetS32("gBlueFireArrows", 0);
|
||||||
|
// Sunlight Arrows
|
||||||
|
CVar_SetS32("gSunlightArrows", 0);
|
||||||
|
|
||||||
// Rotate link (0 to 2)
|
// Rotate link (0 to 2)
|
||||||
CVar_SetS32("gPauseLiveLinkRotation", 0);
|
CVar_SetS32("gPauseLiveLinkRotation", 0);
|
||||||
@ -880,6 +884,10 @@ namespace GameMenuBar {
|
|||||||
UIWidgets::Tooltip("Injects Golden Skulltula total count in pickup messages");
|
UIWidgets::Tooltip("Injects Golden Skulltula total count in pickup messages");
|
||||||
UIWidgets::PaddedEnhancementCheckbox("Pull grave during the day", "gDayGravePull", true, false);
|
UIWidgets::PaddedEnhancementCheckbox("Pull grave during the day", "gDayGravePull", true, false);
|
||||||
UIWidgets::Tooltip("Allows graves to be pulled when child during the day");
|
UIWidgets::Tooltip("Allows graves to be pulled when child during the day");
|
||||||
|
UIWidgets::PaddedEnhancementCheckbox("Blue Fire Arrows", "gBlueFireArrows", true, false);
|
||||||
|
UIWidgets::Tooltip("Allows Ice Arrows to melt red ice.\nMay require a room reload if toggled during gameplay.");
|
||||||
|
UIWidgets::PaddedEnhancementCheckbox("Sunlight Arrows", "gSunlightArrows", true, false);
|
||||||
|
UIWidgets::Tooltip("Allows Light Arrows to activate sun switches.\nMay require a room reload if toggled during gameplay.");
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 } } },
|
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Replacement quad used for "Blue Fire Arrows" enhancement
|
||||||
|
static ColliderQuadInit sIceArrowQuadInit = {
|
||||||
|
{
|
||||||
|
COLTYPE_NONE,
|
||||||
|
AT_NONE,
|
||||||
|
AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER,
|
||||||
|
OC1_NONE,
|
||||||
|
OC2_TYPE_2,
|
||||||
|
COLSHAPE_QUAD,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ELEMTYPE_UNK0,
|
||||||
|
{ 0x00000048, 0x00, 0x00 },
|
||||||
|
{ 0x00001048, 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[] = {
|
static BombableWallInfo sBombableWallInfo[] = {
|
||||||
{ &object_bwall_Col_000118, object_bwall_DL_000040, 0 },
|
{ &object_bwall_Col_000118, object_bwall_DL_000040, 0 },
|
||||||
{ &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),
|
ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool blueFireArrowsEnabledOnMudwallLoad = false;
|
||||||
|
|
||||||
void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) {
|
void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) {
|
||||||
this->actionFunc = actionFunc;
|
this->actionFunc = actionFunc;
|
||||||
}
|
}
|
||||||
@ -82,6 +105,9 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
s32 pad;
|
s32 pad;
|
||||||
s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF;
|
s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF;
|
||||||
|
|
||||||
|
// Initialize this with the mud wall, so it can't be affected by toggling while the actor is loaded
|
||||||
|
blueFireArrowsEnabledOnMudwallLoad = (CVar_GetS32("gBlueFireArrows", 0));
|
||||||
|
|
||||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||||
DynaPolyActor_Init(&this->dyna, DPM_UNK);
|
DynaPolyActor_Init(&this->dyna, DPM_UNK);
|
||||||
this->bombableWallDList = sBombableWallInfo[wallType].dList;
|
this->bombableWallDList = sBombableWallInfo[wallType].dList;
|
||||||
@ -98,8 +124,15 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f);
|
ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f);
|
||||||
|
|
||||||
|
// If "Blue Fire Arrows" are enabled, set up this collider for them
|
||||||
|
if (blueFireArrowsEnabledOnMudwallLoad) {
|
||||||
|
Collider_InitQuad(globalCtx, &this->collider);
|
||||||
|
Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sIceArrowQuadInit);
|
||||||
|
} else {
|
||||||
Collider_InitQuad(globalCtx, &this->collider);
|
Collider_InitQuad(globalCtx, &this->collider);
|
||||||
Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit);
|
Collider_SetQuad(globalCtx, &this->collider, &this->dyna.actor, &sQuadInit);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this->dyna.actor.world.pos.y -= 40.0f;
|
this->dyna.actor.world.pos.y -= 40.0f;
|
||||||
}
|
}
|
||||||
@ -227,7 +260,21 @@ void BgBreakwall_WaitForObject(BgBreakwall* this, GlobalContext* globalCtx) {
|
|||||||
* despawn itself.
|
* despawn itself.
|
||||||
*/
|
*/
|
||||||
void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) {
|
void BgBreakwall_Wait(BgBreakwall* this, GlobalContext* globalCtx) {
|
||||||
if (this->collider.base.acFlags & 2) {
|
bool blueFireArrowHit = false;
|
||||||
|
// If "Blue Fire Arrows" enabled, check this collider for a hit
|
||||||
|
if (blueFireArrowsEnabledOnMudwallLoad) {
|
||||||
|
if (this->collider.base.acFlags & AC_HIT) {
|
||||||
|
if ((this->collider.base.ac != NULL) && (this->collider.base.ac->id == ACTOR_EN_ARROW)) {
|
||||||
|
|
||||||
|
if (this->collider.base.ac->child != NULL &&
|
||||||
|
this->collider.base.ac->child->id == ACTOR_ARROW_ICE) {
|
||||||
|
blueFireArrowHit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->collider.base.acFlags & 2 || blueFireArrowHit) {
|
||||||
Vec3f effectPos;
|
Vec3f effectPos;
|
||||||
s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF;
|
s32 wallType = ((this->dyna.actor.params >> 13) & 3) & 0xFF;
|
||||||
|
|
||||||
|
@ -14,6 +14,9 @@ void func_808911BC(BgIceShelter* this);
|
|||||||
void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx);
|
void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx);
|
||||||
void func_808911D4(BgIceShelter* this, GlobalContext* globalCtx);
|
void func_808911D4(BgIceShelter* this, GlobalContext* globalCtx);
|
||||||
|
|
||||||
|
// For "Blue Fire Arrows" enhancement
|
||||||
|
void MeltOnIceArrowHit(BgIceShelter* this, ColliderCylinder cylinder, s16 type, GlobalContext* globalCtx);
|
||||||
|
|
||||||
const ActorInit Bg_Ice_Shelter_InitVars = {
|
const ActorInit Bg_Ice_Shelter_InitVars = {
|
||||||
ACTOR_BG_ICE_SHELTER,
|
ACTOR_BG_ICE_SHELTER,
|
||||||
ACTORCAT_BG,
|
ACTORCAT_BG,
|
||||||
@ -32,7 +35,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 sDustPrimColor = { 250, 250, 250, 255 };
|
||||||
static Color_RGBA8 sDustEnvColor = { 180, 180, 180, 255 };
|
static Color_RGBA8 sDustEnvColor = { 180, 180, 180, 255 };
|
||||||
|
|
||||||
static ColliderCylinderInit D_8089170C = {
|
static ColliderCylinderInit sCylinder1Init = {
|
||||||
{
|
{
|
||||||
COLTYPE_NONE,
|
COLTYPE_NONE,
|
||||||
AT_NONE,
|
AT_NONE,
|
||||||
@ -52,7 +55,7 @@ static ColliderCylinderInit D_8089170C = {
|
|||||||
{ 0, 0, 0, { 0, 0, 0 } },
|
{ 0, 0, 0, { 0, 0, 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ColliderCylinderInit D_80891738 = {
|
static ColliderCylinderInit sCylinder2Init = {
|
||||||
{
|
{
|
||||||
COLTYPE_HARD,
|
COLTYPE_HARD,
|
||||||
AT_NONE,
|
AT_NONE,
|
||||||
@ -72,14 +75,45 @@ static ColliderCylinderInit D_80891738 = {
|
|||||||
{ 0, 0, 0, { 0, 0, 0 } },
|
{ 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 blueFireArrowsEnabledOnRedIceLoad = false;
|
||||||
|
|
||||||
void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) {
|
void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) {
|
||||||
static s16 cylinderRadii[] = { 47, 33, 44, 41, 100 };
|
static s16 cylinderRadii[] = { 47, 33, 44, 41, 100 };
|
||||||
static s16 cylinderHeights[] = { 80, 54, 90, 60, 200 };
|
static s16 cylinderHeights[] = { 80, 54, 90, 60, 200 };
|
||||||
s32 pad;
|
s32 pad;
|
||||||
s32 type = (this->dyna.actor.params >> 8) & 7;
|
s32 type = (this->dyna.actor.params >> 8) & 7;
|
||||||
|
|
||||||
|
// Initialize this with the red ice, so it can't be affected by toggling while the actor is loaded
|
||||||
|
blueFireArrowsEnabledOnRedIceLoad = (CVar_GetS32("gBlueFireArrows", 0));
|
||||||
|
|
||||||
Collider_InitCylinder(globalCtx, &this->cylinder1);
|
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 (blueFireArrowsEnabledOnRedIceLoad) {
|
||||||
|
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);
|
Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder1);
|
||||||
|
|
||||||
this->cylinder1.dim.radius = cylinderRadii[type];
|
this->cylinder1.dim.radius = cylinderRadii[type];
|
||||||
@ -87,7 +121,7 @@ void func_80890740(BgIceShelter* this, GlobalContext* globalCtx) {
|
|||||||
|
|
||||||
if (type == 0 || type == 1 || type == 4) {
|
if (type == 0 || type == 1 || type == 4) {
|
||||||
Collider_InitCylinder(globalCtx, &this->cylinder2);
|
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);
|
Collider_UpdateCylinder(&this->dyna.actor, &this->cylinder2);
|
||||||
this->cylinder2.dim.radius = cylinderRadii[type];
|
this->cylinder2.dim.radius = cylinderRadii[type];
|
||||||
this->cylinder2.dim.height = cylinderHeights[type];
|
this->cylinder2.dim.height = cylinderHeights[type];
|
||||||
@ -292,7 +326,12 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) {
|
|||||||
this->dyna.actor.parent->freezeTimer = 10000;
|
this->dyna.actor.parent->freezeTimer = 10000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If we have "Blue Fire Arrows" enabled, check both cylinders for a hit
|
||||||
|
if (blueFireArrowsEnabledOnRedIceLoad) {
|
||||||
|
MeltOnIceArrowHit(this, this->cylinder1, type, globalCtx);
|
||||||
|
MeltOnIceArrowHit(this, this->cylinder2, type, globalCtx);
|
||||||
|
}
|
||||||
|
// Default blue fire check
|
||||||
if (this->cylinder1.base.acFlags & AC_HIT) {
|
if (this->cylinder1.base.acFlags & AC_HIT) {
|
||||||
this->cylinder1.base.acFlags &= ~AC_HIT;
|
this->cylinder1.base.acFlags &= ~AC_HIT;
|
||||||
|
|
||||||
@ -320,6 +359,24 @@ void func_8089107C(BgIceShelter* this, GlobalContext* globalCtx) {
|
|||||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->cylinder1.base);
|
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->cylinder1.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For "Blue Fire Arrows" enhancement: If hit by an Ice Arrow, melt the red ice (copied from the default blue fire function above).
|
||||||
|
void MeltOnIceArrowHit(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) {
|
void func_808911BC(BgIceShelter* this) {
|
||||||
this->actionFunc = func_808911D4;
|
this->actionFunc = func_808911D4;
|
||||||
this->alpha = 255;
|
this->alpha = 255;
|
||||||
|
@ -96,7 +96,15 @@ void BgJyaLift_DelayMove(BgJyaLift* this, GlobalContext* globalCtx) {
|
|||||||
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F) || (this->moveDelay > 0)) {
|
if (Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x3F) || (this->moveDelay > 0)) {
|
||||||
this->moveDelay++;
|
this->moveDelay++;
|
||||||
if (this->moveDelay >= 20) {
|
if (this->moveDelay >= 20) {
|
||||||
|
// The cutscene of the platform lowering will show the central room in an unloaded state if
|
||||||
|
// Link is not standing on the platform as it lowers. Therefore check for the Sunlight arrows
|
||||||
|
// enhancement and if it's enabled, check that Link is on the platform. Otherwise skip it.
|
||||||
|
if (!CVar_GetS32("gSunlightArrows", 0) || (GET_PLAYER(globalCtx)->actor.world.pos.x > -19.0f &&
|
||||||
|
GET_PLAYER(globalCtx)->actor.world.pos.x < 139.0f &&
|
||||||
|
GET_PLAYER(globalCtx)->actor.world.pos.z > -1172.0f &&
|
||||||
|
GET_PLAYER(globalCtx)->actor.world.pos.z < -1009.0f)) {
|
||||||
OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM);
|
OnePointCutscene_Init(globalCtx, 3430, -99, &this->dyna.actor, MAIN_CAM);
|
||||||
|
}
|
||||||
BgJyaLift_SetupMove(this);
|
BgJyaLift_SetupMove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,36 @@ static ColliderJntSphInit sColliderJntSphInit = {
|
|||||||
1,
|
1,
|
||||||
sColliderJntSphElementInit,
|
sColliderJntSphElementInit,
|
||||||
};
|
};
|
||||||
|
// Collider info used for "Sunlight 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 "Sunlight 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 sunSwitchActivatedByLightArrow = false;
|
||||||
|
bool sunLightArrowsEnabledOnSunSwitchLoad = false;
|
||||||
|
|
||||||
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE };
|
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE };
|
||||||
|
|
||||||
@ -92,8 +122,16 @@ static InitChainEntry sInitChain[] = {
|
|||||||
void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) {
|
void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||||
s32 pad;
|
s32 pad;
|
||||||
|
|
||||||
|
// Initialize this with the sun switch, so it can't be affected by toggling while the actor is loaded
|
||||||
|
sunLightArrowsEnabledOnSunSwitchLoad = (CVar_GetS32("gSunlightArrows", 0));
|
||||||
|
|
||||||
Collider_InitJntSph(globalCtx, &this->collider);
|
Collider_InitJntSph(globalCtx, &this->collider);
|
||||||
|
// If "Sunlight Arrows" is enabled, set up the collider to allow Light Arrow hits
|
||||||
|
if (sunLightArrowsEnabledOnSunSwitchLoad) {
|
||||||
|
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderLightArrowInit, this->colliderItems);
|
||||||
|
} else {
|
||||||
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems);
|
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems);
|
||||||
|
}
|
||||||
Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x,
|
Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x,
|
||||||
this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y),
|
this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y),
|
||||||
this->actor.world.pos.z, &this->actor.shape.rot);
|
this->actor.world.pos.z, &this->actor.shape.rot);
|
||||||
@ -211,6 +249,26 @@ void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
|
|||||||
GlobalContext* globalCtx = globalCtx2;
|
GlobalContext* globalCtx = globalCtx2;
|
||||||
ObjLightswitch* this = (ObjLightswitch*)thisx;
|
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
|
||||||
|
// 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 (sunSwitchActivatedByLightArrow) {
|
||||||
|
switch (this->actor.params >> 4 & 3) {
|
||||||
|
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
||||||
|
case OBJLIGHTSWITCH_TYPE_2:
|
||||||
|
case OBJLIGHTSWITCH_TYPE_1:
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
sunSwitchActivatedByLightArrow = false;
|
||||||
|
break;
|
||||||
|
case OBJLIGHTSWITCH_TYPE_BURN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Collider_DestroyJntSph(globalCtx, &this->collider);
|
Collider_DestroyJntSph(globalCtx, &this->collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +279,11 @@ void ObjLightswitch_SetupOff(ObjLightswitch* this) {
|
|||||||
this->color[1] = 125 << 6;
|
this->color[1] = 125 << 6;
|
||||||
this->color[2] = 255 << 6;
|
this->color[2] = 255 << 6;
|
||||||
this->alpha = 255 << 6;
|
this->alpha = 255 << 6;
|
||||||
|
if (sunLightArrowsEnabledOnSunSwitchLoad) {
|
||||||
|
sunSwitchActivatedByLightArrow = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// A Sun Switch that is currently turned off
|
||||||
void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) {
|
void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||||
switch (this->actor.params >> 4 & 3) {
|
switch (this->actor.params >> 4 & 3) {
|
||||||
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
||||||
@ -230,6 +291,13 @@ void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) {
|
|||||||
if (this->collider.base.acFlags & AC_HIT) {
|
if (this->collider.base.acFlags & AC_HIT) {
|
||||||
ObjLightswitch_SetupTurnOn(this);
|
ObjLightswitch_SetupTurnOn(this);
|
||||||
ObjLightswitch_SetSwitchFlag(this, 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 (sunLightArrowsEnabledOnSunSwitchLoad) {
|
||||||
|
if (this->collider.base.ac != NULL && this->collider.base.ac->id == ACTOR_EN_ARROW) {
|
||||||
|
sunSwitchActivatedByLightArrow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJLIGHTSWITCH_TYPE_1:
|
case OBJLIGHTSWITCH_TYPE_1:
|
||||||
@ -289,13 +357,19 @@ void ObjLightswitch_SetupOn(ObjLightswitch* this) {
|
|||||||
this->flameRingRotSpeed = -0xAA;
|
this->flameRingRotSpeed = -0xAA;
|
||||||
this->timer = 0;
|
this->timer = 0;
|
||||||
}
|
}
|
||||||
|
// A Sun Switch that is currently turned on
|
||||||
void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) {
|
void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) {
|
||||||
switch (this->actor.params >> 4 & 3) {
|
switch (this->actor.params >> 4 & 3) {
|
||||||
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
case OBJLIGHTSWITCH_TYPE_STAY_ON:
|
||||||
if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) {
|
if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) {
|
||||||
ObjLightswitch_SetupTurnOff(this);
|
ObjLightswitch_SetupTurnOff(this);
|
||||||
}
|
}
|
||||||
|
// If hit by sunlight after already being turned on, then behave as if originally activated by sunlight
|
||||||
|
if (sunLightArrowsEnabledOnSunSwitchLoad && (this->collider.base.acFlags & AC_HIT)) {
|
||||||
|
if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) {
|
||||||
|
sunSwitchActivatedByLightArrow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OBJLIGHTSWITCH_TYPE_1:
|
case OBJLIGHTSWITCH_TYPE_1:
|
||||||
if (this->collider.base.acFlags & AC_HIT && !(this->prevFrameACflags & AC_HIT)) {
|
if (this->collider.base.acFlags & AC_HIT && !(this->prevFrameACflags & AC_HIT)) {
|
||||||
@ -304,10 +378,19 @@ void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJLIGHTSWITCH_TYPE_2:
|
case OBJLIGHTSWITCH_TYPE_2:
|
||||||
|
// If hit by sunlight after already being turned on, then behave as if originally activated by sunlight
|
||||||
|
if (sunLightArrowsEnabledOnSunSwitchLoad && (this->collider.base.acFlags & AC_HIT)) {
|
||||||
|
if (this->collider.base.ac != NULL && this->collider.base.ac->id != ACTOR_EN_ARROW) {
|
||||||
|
sunSwitchActivatedByLightArrow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!(this->collider.base.acFlags & AC_HIT)) {
|
if (!(this->collider.base.acFlags & AC_HIT)) {
|
||||||
if (this->timer >= 7) {
|
if (this->timer >= 7) {
|
||||||
|
// If we aren't using Enhanced Light Arrows, let the switch turn off normally
|
||||||
|
if (!sunSwitchActivatedByLightArrow) {
|
||||||
ObjLightswitch_SetupTurnOff(this);
|
ObjLightswitch_SetupTurnOff(this);
|
||||||
ObjLightswitch_ClearSwitchFlag(this, globalCtx);
|
ObjLightswitch_ClearSwitchFlag(this, globalCtx);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this->timer++;
|
this->timer++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user