diff --git a/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp b/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp index b48dfd1e79..68284a4838 100644 --- a/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp +++ b/soh/soh/Enhancements/ExtraModes/RandomizedEnemySizes.cpp @@ -7,7 +7,10 @@ extern "C" { #include "functions.h" #include "src/overlays/actors/ovl_En_Fz/z_en_fz.h" #include "src/overlays/actors/ovl_En_Crow/z_en_crow.h" +#include "src/overlays/actors/ovl_En_Firefly/z_en_firefly.h" extern void EnCrow_TurnAway(EnCrow*, PlayState*); +extern void EnFirefly_SetupFlyAway(EnFirefly*); +extern void EnFirefly_Fall(EnFirefly*, PlayState*); } static constexpr int32_t CVAR_RANDO_ENEMY_SIZE_DEFAULT = 0; @@ -18,6 +21,15 @@ static constexpr int32_t CVAR_ENEMY_SCALE_HEALTH_DEFAULT = 0; #define CVAR_ENEMY_SCALE_HEALTH_NAME CVAR_ENHANCEMENT("EnemySizeScalesHealth") #define CVAR_ENEMY_SCALE_HEALTH_VALUE CVarGetInteger(CVAR_ENEMY_SCALE_HEALTH_NAME, CVAR_ENEMY_SCALE_HEALTH_DEFAULT) +// If scale > normal, start downscaling already during death fall +void EnemyRandoSize_KeeseFallScale(void* ptr) { + EnFirefly* enFirefly = (EnFirefly*)ptr; + if (enFirefly->actionFunc == EnFirefly_Fall && enFirefly->actor.scale.x > 0.005f) { + Math_StepToF(&enFirefly->actor.scale.x, 0.005f, 0.00034f); + enFirefly->actor.scale.y = enFirefly->actor.scale.z = enFirefly->actor.scale.x; + } +} + static void RandomizedEnemySizes(void* refActor) { // Randomized Enemy Sizes Actor* actor = static_cast(refActor); @@ -63,6 +75,7 @@ static void RandomizedEnemySizes(void* refActor) { static void RegisterRandomizedEnemySizes() { COND_HOOK(OnActorInit, CVAR_RANDO_ENEMY_SIZE_VALUE, RandomizedEnemySizes); + COND_ID_HOOK(OnActorUpdate, ACTOR_EN_FIREFLY, CVAR_RANDO_ENEMY_SIZE_VALUE, EnemyRandoSize_KeeseFallScale); // Guays try to die on any damage, but EnCrow_Update doesn't let them reach ground if health != 0 // Makeshift "damaged but not dead" action setup @@ -92,6 +105,25 @@ static void RegisterRandomizedEnemySizes() { *scale = 2.0f; } }); + + // Keese try to fall/die on any damage which behaves oddly if health is above normal 1 + // Makeshift "damaged but not dead" action setup + COND_VB_SHOULD(VB_KEESE_SETUP_FALL, CVAR_RANDO_ENEMY_SIZE_VALUE && CVAR_ENEMY_SCALE_HEALTH_VALUE, { + EnFirefly* enFirefly = va_arg(args, EnFirefly*); + + if (*should && enFirefly->actor.colChkInfo.health != 0) { + *should = false; + Audio_PlayActorSound2(&enFirefly->actor, NA_SE_EN_FFLY_DEAD); + Actor_SetColorFilter(&enFirefly->actor, 0x4000, 0xFF, 0, 40); + EnFirefly_SetupFlyAway(enFirefly); + } + }); + + // Ensure Keese just die on Ice Arrows + COND_VB_SHOULD(VB_KEESE_SETUP_FROZENFALL, CVAR_RANDO_ENEMY_SIZE_VALUE && CVAR_ENEMY_SCALE_HEALTH_VALUE, { + EnFirefly* enFirefly = va_arg(args, EnFirefly*); + enFirefly->actor.colChkInfo.health = 0; + }); } static void RegisterFreezardHealthScale() { diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 761033a54f..cd0fc22551 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -1624,6 +1624,22 @@ typedef enum { // - `*EnFirefly` VB_KEESE_FORCE_FLY_AWAY, + // #### `result` + // ```c + // varies + // ``` + // #### `args` + // - `*EnFirefly` + VB_KEESE_SETUP_FALL, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnFirefly` + VB_KEESE_SETUP_FROZENFALL, + // #### `result` // ```c // Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) diff --git a/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index f1d894c623..5b1ad6bda3 100644 --- a/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -648,9 +648,9 @@ void EnFirefly_UpdateDamage(EnFirefly* this, PlayState* play) { } } } else if (damageEffect == 3) { // Ice Arrows or Ice Magic - if (this->actor.params == KEESE_ICE_FLY) { + if (GameInteractor_Should(VB_KEESE_SETUP_FALL, this->actor.params == KEESE_ICE_FLY, this)) { EnFirefly_SetupFall(this); - } else { + } else if (GameInteractor_Should(VB_KEESE_SETUP_FROZENFALL, true, this)) { EnFirefly_SetupFrozenFall(this, play); } } else if (damageEffect == 1) { // Deku Nuts @@ -661,7 +661,9 @@ void EnFirefly_UpdateDamage(EnFirefly* this, PlayState* play) { if ((damageEffect == 0xF) && (this->actor.params == KEESE_ICE_FLY)) { EnFirefly_Combust(this, play); } - EnFirefly_SetupFall(this); + if (GameInteractor_Should(VB_KEESE_SETUP_FALL, true, this)) { + EnFirefly_SetupFall(this); + } } } }