mirror of https://github.com/zeldaret/mm.git
En_Bbfall (Red Bubble) OK and documented (#780)
* EnBbfall_Init OK * EnBbfall_Destroy, func_808BF5E0, and func_808BF734 OK * func_808BF578 and func_808BF7A0 OK * func_808BF4B4, func_808BF830, and func_808BF894 OK * func_808BF438, func_808BF514, func_808BF8DC OK * func_808BFA18 and func_808BFA3C OK * EnBbfall_Draw OK, thanks Tharo, Anon, and Maide! * LimbDraw functions OK * All functions OK, thanks Anon for the loop in Update! * Migrate data to C * Use generated reloc and object symbols * Port over a ton of documentation from EnBb * Use ARRAY_COUNT for all loops * Do a ton more documentation * Name unused animation in object_bb * Copy "floorType" variable name from OoT * Use enum values for collider type * Respond to reviews * Add comment explaining EnBbfall_IsTouchingLava
This commit is contained in:
parent
c7753f43b0
commit
232b901ccf
|
|
@ -3,7 +3,7 @@
|
|||
<File Name="object_bb" Segment="6">
|
||||
<!-- Bubble Animations -->
|
||||
<Animation Name="gBubbleAttackAnim" Offset="0x184" /> <!-- Original name is "bb_atack" -->
|
||||
<Animation Name="object_bb_Anim_0002AC" Offset="0x2AC" /> <!-- Original name might be "bb_damage". Maybe unused? -->
|
||||
<Animation Name="gBubblePainAnim" Offset="0x2AC" /> <!-- Original name might be "bb_damage". Unused. -->
|
||||
<Animation Name="gBubbleFlyingAnim" Offset="0x444" /> <!-- Original name is "bb_fly" -->
|
||||
|
||||
<!-- Bubble Limb DisplayLimbs -->
|
||||
|
|
|
|||
3
spec
3
spec
|
|
@ -1057,8 +1057,7 @@ beginseg
|
|||
name "ovl_En_Bbfall"
|
||||
compress
|
||||
include "build/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.o"
|
||||
include "build/data/ovl_En_Bbfall/ovl_En_Bbfall.data.o"
|
||||
include "build/data/ovl_En_Bbfall/ovl_En_Bbfall.reloc.o"
|
||||
include "build/src/overlays/actors/ovl_En_Bbfall/ovl_En_Bbfall_reloc.o"
|
||||
endseg
|
||||
|
||||
beginseg
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ void EnBb_UpdateDamage(EnBb* this, GlobalContext* globalCtx) {
|
|||
this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
|
||||
this->collider.base.atFlags &= ~AT_ON;
|
||||
if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) ||
|
||||
(!(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) {
|
||||
!(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) {
|
||||
Actor_SetDropFlag(&this->actor, &this->collider.info);
|
||||
this->flameScaleY = 0.0f;
|
||||
this->flameScaleX = 0.0f;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include "z_en_bbfall.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_200)
|
||||
|
||||
|
|
@ -15,16 +16,25 @@ void EnBbfall_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void EnBbfall_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnBbfall_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
void func_808BF734(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808BF830(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808BF8DC(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808BFA3C(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808BFB4C(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808BFE58(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808C00A0(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void func_808C0178(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_SetupWaitForPlayer(EnBbfall* this);
|
||||
void EnBbfall_WaitForPlayer(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_SetupEmerge(EnBbfall* this);
|
||||
void EnBbfall_Emerge(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_SetupFly(EnBbfall* this);
|
||||
void EnBbfall_Fly(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_SetupSinkIntoLava(EnBbfall* this);
|
||||
void EnBbfall_SinkIntoLava(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_Down(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_Dead(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_Damage(EnBbfall* this, GlobalContext* globalCtx);
|
||||
void EnBbfall_Frozen(EnBbfall* this, GlobalContext* globalCtx);
|
||||
|
||||
typedef enum {
|
||||
/* -1 */ BBFALL_BODY_PART_DRAW_STATUS_BROKEN = -1,
|
||||
/* 0 */ BBFALL_BODY_PART_DRAW_STATUS_ALIVE,
|
||||
/* 1 */ BBFALL_BODY_PART_DRAW_STATUS_DEAD,
|
||||
} EnBbfallBodyPartDrawStatus;
|
||||
|
||||
#if 0
|
||||
const ActorInit En_Bbfall_InitVars = {
|
||||
ACTOR_EN_BBFALL,
|
||||
ACTORCAT_ENEMY,
|
||||
|
|
@ -37,140 +47,720 @@ const ActorInit En_Bbfall_InitVars = {
|
|||
(ActorFunc)EnBbfall_Draw,
|
||||
};
|
||||
|
||||
// static ColliderJntSphElementInit sJntSphElementsInit[3] = {
|
||||
static ColliderJntSphElementInit D_808C0D30[3] = {
|
||||
static ColliderJntSphElementInit sJntSphElementsInit[3] = {
|
||||
{
|
||||
{ ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x01, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, },
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xF7CFFFFF, 0x01, 0x08 },
|
||||
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_HARD,
|
||||
BUMP_ON | BUMP_HOOKABLE,
|
||||
OCELEM_ON,
|
||||
},
|
||||
{ 0, { { 0, 0, 0 }, 20 }, 100 },
|
||||
},
|
||||
{
|
||||
{ ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x01, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_NONE, OCELEM_NONE, },
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xF7CFFFFF, 0x01, 0x08 },
|
||||
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_HARD,
|
||||
BUMP_NONE,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ 0, { { 0, 0, 0 }, 20 }, 100 },
|
||||
},
|
||||
{
|
||||
{ ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x01, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_NONE, OCELEM_NONE, },
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xF7CFFFFF, 0x01, 0x08 },
|
||||
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_HARD,
|
||||
BUMP_NONE,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ 0, { { 0, 0, 0 }, 20 }, 100 },
|
||||
},
|
||||
};
|
||||
|
||||
// static ColliderJntSphInit sJntSphInit = {
|
||||
static ColliderJntSphInit D_808C0D9C = {
|
||||
{ COLTYPE_HIT3, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, },
|
||||
3, D_808C0D30, // sJntSphElementsInit,
|
||||
static ColliderJntSphInit sJntSphInit = {
|
||||
{
|
||||
COLTYPE_HIT3,
|
||||
AT_NONE | AT_TYPE_ENEMY,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_ON | OC1_TYPE_ALL,
|
||||
OC2_TYPE_1,
|
||||
COLSHAPE_JNTSPH,
|
||||
},
|
||||
ARRAY_COUNT(sJntSphElementsInit),
|
||||
sJntSphElementsInit,
|
||||
};
|
||||
|
||||
// static DamageTable sDamageTable = {
|
||||
static DamageTable D_808C0DAC = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, 0x1),
|
||||
/* Deku Stick */ DMG_ENTRY(1, 0x0),
|
||||
/* Horse trample */ DMG_ENTRY(0, 0x0),
|
||||
/* Explosives */ DMG_ENTRY(1, 0x0),
|
||||
/* Zora boomerang */ DMG_ENTRY(1, 0x0),
|
||||
/* Normal arrow */ DMG_ENTRY(1, 0x0),
|
||||
/* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0),
|
||||
/* Hookshot */ DMG_ENTRY(0, 0xE),
|
||||
/* Goron punch */ DMG_ENTRY(1, 0x0),
|
||||
/* Sword */ DMG_ENTRY(1, 0x0),
|
||||
/* Goron pound */ DMG_ENTRY(1, 0x0),
|
||||
/* Fire arrow */ DMG_ENTRY(1, 0x0),
|
||||
/* Ice arrow */ DMG_ENTRY(2, 0x3),
|
||||
/* Light arrow */ DMG_ENTRY(2, 0x4),
|
||||
/* Goron spikes */ DMG_ENTRY(1, 0x0),
|
||||
/* Deku spin */ DMG_ENTRY(1, 0x0),
|
||||
/* Deku bubble */ DMG_ENTRY(1, 0x0),
|
||||
/* Deku launch */ DMG_ENTRY(2, 0x0),
|
||||
/* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1),
|
||||
/* Zora barrier */ DMG_ENTRY(0, 0x5),
|
||||
/* Normal shield */ DMG_ENTRY(0, 0x0),
|
||||
/* Light ray */ DMG_ENTRY(0, 0x0),
|
||||
/* Thrown object */ DMG_ENTRY(1, 0x0),
|
||||
/* Zora punch */ DMG_ENTRY(1, 0x0),
|
||||
/* Spin attack */ DMG_ENTRY(1, 0x0),
|
||||
/* Sword beam */ DMG_ENTRY(0, 0x0),
|
||||
/* Normal Roll */ DMG_ENTRY(0, 0x0),
|
||||
/* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0),
|
||||
/* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0),
|
||||
/* Unblockable */ DMG_ENTRY(0, 0x0),
|
||||
/* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0),
|
||||
/* Powder Keg */ DMG_ENTRY(1, 0x0),
|
||||
typedef enum {
|
||||
/* 0x0 */ EN_BBFALL_DMGEFF_NONE,
|
||||
/* 0x1 */ EN_BBFALL_DMGEFF_STUN,
|
||||
/* 0x3 */ EN_BBFALL_DMGEFF_ICE_ARROW = 0x3,
|
||||
/* 0x4 */ EN_BBFALL_DMGEFF_LIGHT_ARROW,
|
||||
/* 0x5 */ EN_BBFALL_DMGEFF_ZORA_MAGIC,
|
||||
/* 0xE */ EN_BBFALL_DMGEFF_HOOKSHOT = 0xE,
|
||||
} EnBbfallDamageEffect;
|
||||
|
||||
static DamageTable sDamageTable = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_STUN),
|
||||
/* Deku Stick */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Horse trample */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Explosives */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Zora boomerang */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Normal arrow */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Hookshot */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_HOOKSHOT),
|
||||
/* Goron punch */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Sword */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Goron pound */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Fire arrow */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Ice arrow */ DMG_ENTRY(2, EN_BBFALL_DMGEFF_ICE_ARROW),
|
||||
/* Light arrow */ DMG_ENTRY(2, EN_BBFALL_DMGEFF_LIGHT_ARROW),
|
||||
/* Goron spikes */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Deku spin */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Deku bubble */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Deku launch */ DMG_ENTRY(2, EN_BBFALL_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_STUN),
|
||||
/* Zora barrier */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_ZORA_MAGIC),
|
||||
/* Normal shield */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Light ray */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Thrown object */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Zora punch */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Spin attack */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Sword beam */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Normal Roll */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Unblockable */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE),
|
||||
/* Powder Keg */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE),
|
||||
};
|
||||
|
||||
// sColChkInfoInit
|
||||
static CollisionCheckInfoInit D_808C0DCC = { 2, 20, 40, 50 };
|
||||
static CollisionCheckInfoInit sColChkInfoInit = { 2, 20, 40, 50 };
|
||||
|
||||
// static InitChainEntry sInitChain[] = {
|
||||
static InitChainEntry D_808C0DD4[] = {
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_S8(hintId, 36, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(targetArrowOffset, 10, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#endif
|
||||
/**
|
||||
* This maps a given limb based on its limbIndex to its appropriate index
|
||||
* in the bodyPartsPos/Velocity arrays. An index of -1 indicates that the
|
||||
* limb is not part of the bodyParts arrays.
|
||||
*/
|
||||
static s8 sLimbIndexToBodyPartsIndex[] = {
|
||||
-1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, -1, 2, -1, 3,
|
||||
};
|
||||
|
||||
extern ColliderJntSphElementInit D_808C0D30[3];
|
||||
extern ColliderJntSphInit D_808C0D9C;
|
||||
extern DamageTable D_808C0DAC;
|
||||
extern CollisionCheckInfoInit D_808C0DCC;
|
||||
extern InitChainEntry D_808C0DD4[];
|
||||
/**
|
||||
* The last element of the bodyParts arrays is a duplicate of the cranium
|
||||
* limb, which is then offset by a certain amount. There is no display list
|
||||
* associated with this, so it is only used for effects.
|
||||
*/
|
||||
static Vec3f sDuplicateCraniumBodyPartOffset = { 1000.0f, -700.0f, 0.0f };
|
||||
|
||||
extern UNK_TYPE D_06000184;
|
||||
extern UNK_TYPE D_06000444;
|
||||
void EnBbfall_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBbfall* this = THIS;
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Init.s")
|
||||
Actor_ProcessInitChain(&this->actor, sInitChain);
|
||||
SkelAnime_Init(globalCtx, &this->skelAnime, &gBubbleSkel, &gBubbleFlyingAnim, this->jointTable, this->morphTable,
|
||||
BUBBLE_LIMB_MAX);
|
||||
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
|
||||
Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
|
||||
ActorShape_Init(&this->actor.shape, 1500.0f, ActorShadow_DrawCircle, 35.0f);
|
||||
this->timer = 0;
|
||||
EnBbfall_SetupWaitForPlayer(this);
|
||||
Actor_SetFocus(&this->actor, 0.0f);
|
||||
for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) {
|
||||
this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Destroy.s")
|
||||
void EnBbfall_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBbfall* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF344.s")
|
||||
Collider_DestroyJntSph(globalCtx, &this->collider);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF3B8.s")
|
||||
void EnBbfall_Freeze(EnBbfall* this) {
|
||||
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX;
|
||||
this->drawDmgEffScale = 0.4f;
|
||||
this->drawDmgEffFrozenSteamScale = 0.6f;
|
||||
this->timer = 80;
|
||||
this->drawDmgEffAlpha = 1.0f;
|
||||
this->actor.flags &= ~ACTOR_FLAG_200;
|
||||
Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF438.s")
|
||||
void EnBbfall_Thaw(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
|
||||
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE;
|
||||
this->drawDmgEffAlpha = 0.0f;
|
||||
Actor_SpawnIceEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), 2, 0.2f,
|
||||
0.15f);
|
||||
this->actor.flags |= ACTOR_FLAG_200;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF4B4.s")
|
||||
/**
|
||||
* Returns true if the Bubble is touching a floor that it should "sink into" (i.e., if it's touching lava).
|
||||
*/
|
||||
s32 EnBbfall_IsTouchingLava(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
if (!SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId)) {
|
||||
u32 floorType = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF514.s")
|
||||
if ((floorType == 2) || (floorType == 3) || (floorType == 9)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF578.s")
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF5AC.s")
|
||||
void EnBbfall_PlaySfx(EnBbfall* this) {
|
||||
if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_MOUTH);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF5E0.s")
|
||||
func_800B9010(&this->actor, NA_SE_EN_BUBLEFALL_FIRE - SFX_FLAG);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF734.s")
|
||||
/**
|
||||
* Checks to see if the Bubble is touching a wall. If it is, and if the
|
||||
* Bubble is facing directly "into" the wall, then rotate it away from
|
||||
* the wall.
|
||||
*/
|
||||
void EnBbfall_CheckForWall(EnBbfall* this) {
|
||||
s16 yawDiff;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF7A0.s")
|
||||
if (this->actor.bgCheckFlags & 8) {
|
||||
yawDiff = this->actor.shape.rot.y - this->actor.wallYaw;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF830.s")
|
||||
if (ABS_ALT(yawDiff) > 0x4000) {
|
||||
this->actor.shape.rot.y = ((this->actor.wallYaw * 2) - this->actor.shape.rot.y) - 0x8000;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF894.s")
|
||||
this->actor.bgCheckFlags &= ~8;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF8DC.s")
|
||||
void EnBbfall_EnableColliders(EnBbfall* this) {
|
||||
this->collider.elements[0].info.toucher.effect = ELEMTYPE_UNK1; // Fire
|
||||
this->collider.elements[1].info.toucherFlags |= TOUCH_ON;
|
||||
this->collider.elements[2].info.toucherFlags |= TOUCH_ON;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFA18.s")
|
||||
void EnBbfall_DisableColliders(EnBbfall* this) {
|
||||
this->collider.elements[0].info.toucher.effect = ELEMTYPE_UNK0; // Nothing
|
||||
this->collider.elements[1].info.toucherFlags &= ~TOUCH_ON;
|
||||
this->collider.elements[2].info.toucherFlags &= ~TOUCH_ON;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFA3C.s")
|
||||
void EnBbfall_SetupWaitForPlayer(EnBbfall* this) {
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFAB4.s")
|
||||
Animation_PlayLoop(&this->skelAnime, &gBubbleAttackAnim);
|
||||
this->collider.base.atFlags &= ~AT_ON;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->collider.base.ocFlags1 &= ~OC1_ON;
|
||||
this->flameScaleY = 0.8f;
|
||||
this->flameScaleX = 1.0f;
|
||||
this->flameOpacity = 255;
|
||||
this->actor.colChkInfo.health = sColChkInfoInit.health;
|
||||
this->actor.colorFilterTimer = 0;
|
||||
this->isBgCheckCollisionEnabled = false;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actor.gravity = 0.0f;
|
||||
this->actor.velocity.y = 0.0f;
|
||||
Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos);
|
||||
this->actor.world.pos.y -= 90.0f;
|
||||
for (i = 0; i < ARRAY_COUNT(this->flamePos); i++) {
|
||||
Math_Vec3f_Copy(&this->flamePos[i], &this->actor.world.pos);
|
||||
this->flamePos[i].y -= 47.0f;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFB4C.s")
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
this->actor.flags &= ~ACTOR_FLAG_1;
|
||||
this->actionFunc = EnBbfall_WaitForPlayer;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFCCC.s")
|
||||
void EnBbfall_WaitForPlayer(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
} else if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && (this->actor.xyzDistToPlayerSq <= SQ(250.0f))) {
|
||||
EnBbfall_SetupEmerge(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFE58.s")
|
||||
void EnBbfall_SetupEmerge(EnBbfall* this) {
|
||||
this->actor.gravity = -1.0f;
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->collider.base.ocFlags1 |= OC1_ON;
|
||||
this->actor.velocity.y = 17.0f;
|
||||
EnBbfall_EnableColliders(this);
|
||||
this->actor.flags |= ACTOR_FLAG_1;
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLEFALL_APPEAR);
|
||||
this->actionFunc = EnBbfall_Emerge;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFF8C.s")
|
||||
void EnBbfall_Emerge(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
if (this->actor.home.pos.y < this->actor.world.pos.y) {
|
||||
EnBbfall_SetupFly(this);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C00A0.s")
|
||||
EnBbfall_PlaySfx(this);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C013C.s")
|
||||
void EnBbfall_SetupFly(EnBbfall* this) {
|
||||
this->flameOpacity = 255;
|
||||
this->isBgCheckCollisionEnabled = true;
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
this->actor.speedXZ = 5.0f;
|
||||
this->actor.gravity = -1.0f;
|
||||
this->actionFunc = EnBbfall_Fly;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C0178.s")
|
||||
void EnBbfall_Fly(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Math_StepToF(&this->flameScaleY, 0.8f, 0.1f);
|
||||
Math_StepToF(&this->flameScaleX, 1.0f, 0.1f);
|
||||
EnBbfall_CheckForWall(this);
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
if (EnBbfall_IsTouchingLava(this, globalCtx)) {
|
||||
EnBbfall_SetupSinkIntoLava(this);
|
||||
} else {
|
||||
// Bounce upwards off the ground
|
||||
this->actor.velocity.y *= -1.2f;
|
||||
this->actor.velocity.y = CLAMP(this->actor.velocity.y, 8.0f, 12.0f);
|
||||
this->actor.shape.rot.y += (s16)randPlusMinusPoint5Scaled(73728.0f);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C01E0.s")
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Update.s")
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
EnBbfall_PlaySfx(this);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C07D4.s")
|
||||
void EnBbfall_SetupSinkIntoLava(EnBbfall* this) {
|
||||
this->isBgCheckCollisionEnabled = false;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->actionFunc = EnBbfall_SinkIntoLava;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C080C.s")
|
||||
void EnBbfall_SinkIntoLava(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
if (this->actor.world.pos.y < (this->actor.floorHeight - 90.0f)) {
|
||||
this->timer = 10;
|
||||
EnBbfall_SetupWaitForPlayer(this);
|
||||
} else {
|
||||
EnBbfall_PlaySfx(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Draw.s")
|
||||
void EnBbfall_SetupDown(EnBbfall* this) {
|
||||
Animation_PlayLoop(&this->skelAnime, &gBubbleFlyingAnim);
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->timer = 200;
|
||||
this->flameOpacity = 0;
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->actor.speedXZ = 2.0f;
|
||||
this->flameScaleY = 0.0f;
|
||||
this->flameScaleX = 0.0f;
|
||||
this->actor.gravity = -2.0f;
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DOWN);
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
this->actionFunc = EnBbfall_Down;
|
||||
}
|
||||
|
||||
void EnBbfall_Down(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
EnBbfall_CheckForWall(this);
|
||||
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
if (EnBbfall_IsTouchingLava(this, globalCtx)) {
|
||||
EnBbfall_SetupSinkIntoLava(this);
|
||||
return;
|
||||
}
|
||||
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK);
|
||||
if (this->timer == 0) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_UP);
|
||||
EnBbfall_EnableColliders(this);
|
||||
this->actor.velocity.y = 8.0f;
|
||||
EnBbfall_SetupFly(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->actor.velocity.y < -14.0f) {
|
||||
this->actor.velocity.y *= -0.7f;
|
||||
} else {
|
||||
this->actor.velocity.y = 10.0f;
|
||||
}
|
||||
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0);
|
||||
Math_ScaledStepToS(&this->actor.shape.rot.y, BINANG_ADD(this->actor.yawTowardsPlayer, 0x8000), 0xBB8);
|
||||
}
|
||||
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
if (Animation_OnFrame(&this->skelAnime, 5.0f)) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING);
|
||||
}
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
}
|
||||
}
|
||||
|
||||
void EnBbfall_SetupDead(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
Vec3f* bodyPartVelocity;
|
||||
Vec3f posDiff;
|
||||
f32 magnitude;
|
||||
s32 i;
|
||||
|
||||
func_800BE5CC(&this->actor, &this->collider, 0);
|
||||
this->timer = 15;
|
||||
this->actor.shape.rot.x += 0x4E20;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_BUBLE_DEAD);
|
||||
Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x70);
|
||||
this->actor.velocity.y = 0.0f;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->bodyPartDrawStatus = BBFALL_BODY_PART_DRAW_STATUS_DEAD;
|
||||
this->actor.gravity = -1.5f;
|
||||
|
||||
bodyPartVelocity = &this->bodyPartsVelocity[0];
|
||||
for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++, bodyPartVelocity++) {
|
||||
Math_Vec3f_Diff(&this->bodyPartsPos[i], &this->actor.world.pos, &posDiff);
|
||||
magnitude = Math3D_Vec3fMagnitude(&posDiff);
|
||||
if (magnitude > 1.0f) {
|
||||
magnitude = 2.5f / magnitude;
|
||||
}
|
||||
|
||||
bodyPartVelocity->x = posDiff.x * magnitude;
|
||||
bodyPartVelocity->z = posDiff.z * magnitude;
|
||||
bodyPartVelocity->y = Rand_ZeroFloat(3.5f) + 10.0f;
|
||||
}
|
||||
|
||||
this->actionFunc = EnBbfall_Dead;
|
||||
}
|
||||
|
||||
void EnBbfall_Dead(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
s32 i;
|
||||
|
||||
this->timer--;
|
||||
Math_SmoothStepToS(&this->actor.world.rot.z, 0x4000, 4, 0x1000, 0x400);
|
||||
|
||||
if (this->timer == 0) {
|
||||
for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) {
|
||||
func_800B3030(globalCtx, &this->bodyPartsPos[i], &gZeroVec3f, &gZeroVec3f, 40, 7, 2);
|
||||
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->bodyPartsPos[i], 11, NA_SE_EN_EXTINCT);
|
||||
}
|
||||
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) {
|
||||
Math_Vec3f_Sum(&this->bodyPartsPos[i], &this->bodyPartsVelocity[i], &this->bodyPartsPos[i]);
|
||||
this->bodyPartsVelocity[i].y += this->actor.gravity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBbfall_SetupDamage(EnBbfall* this) {
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DAMAGE);
|
||||
func_800BE5CC(&this->actor, &this->collider, 0);
|
||||
|
||||
if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_ZORA_MAGIC) {
|
||||
Actor_SetColorFilter(&this->actor, 0, 255, 0, 40);
|
||||
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE;
|
||||
this->drawDmgEffAlpha = 2.0f;
|
||||
this->drawDmgEffScale = 0.4f;
|
||||
} else if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_STUN) {
|
||||
Actor_SetColorFilter(&this->actor, 0, 255, 0, 20);
|
||||
this->actor.speedXZ = 0.0f;
|
||||
} else if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_HOOKSHOT) {
|
||||
this->actor.speedXZ = 0.0f;
|
||||
} else {
|
||||
Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20);
|
||||
this->actor.speedXZ = 7.0f;
|
||||
}
|
||||
|
||||
this->actionFunc = EnBbfall_Damage;
|
||||
}
|
||||
|
||||
void EnBbfall_Damage(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f);
|
||||
if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ < 0.1f)) {
|
||||
if (EnBbfall_IsTouchingLava(this, globalCtx)) {
|
||||
EnBbfall_SetupSinkIntoLava(this);
|
||||
} else {
|
||||
EnBbfall_SetupDown(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBbfall_SetupFrozen(EnBbfall* this) {
|
||||
this->actor.speedXZ = 0.0f;
|
||||
if (this->actor.velocity.y > 0.0f) {
|
||||
this->actor.velocity.y = 0.0f;
|
||||
}
|
||||
|
||||
this->actor.gravity = -2.0f;
|
||||
this->actionFunc = EnBbfall_Frozen;
|
||||
}
|
||||
|
||||
void EnBbfall_Frozen(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
DECR(this->timer);
|
||||
|
||||
if (this->timer == 0) {
|
||||
EnBbfall_Thaw(this, globalCtx);
|
||||
if (this->actor.colChkInfo.health == 0) {
|
||||
EnBbfall_SetupDead(this, globalCtx);
|
||||
} else {
|
||||
EnBbfall_SetupDown(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBbfall_UpdateDamage(EnBbfall* this, GlobalContext* globalCtx) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
this->collider.base.acFlags &= ~AC_HIT;
|
||||
this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
|
||||
this->collider.base.atFlags &= ~AT_ON;
|
||||
if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) ||
|
||||
!(this->collider.elements[0].info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) {
|
||||
Actor_SetDropFlagJntSph(&this->actor, &this->collider);
|
||||
this->flameOpacity = 0;
|
||||
this->flameScaleY = 0.0f;
|
||||
this->flameScaleX = 0.0f;
|
||||
EnBbfall_DisableColliders(this);
|
||||
EnBbfall_Thaw(this, globalCtx);
|
||||
|
||||
if (Actor_ApplyDamage(&this->actor) == 0) {
|
||||
Enemy_StartFinishingBlow(globalCtx, &this->actor);
|
||||
}
|
||||
|
||||
if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_ICE_ARROW) {
|
||||
EnBbfall_Freeze(this);
|
||||
if (this->actor.colChkInfo.health == 0) {
|
||||
this->timer = 3;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
}
|
||||
|
||||
EnBbfall_SetupFrozen(this);
|
||||
} else if (this->actor.colChkInfo.health == 0) {
|
||||
EnBbfall_SetupDead(this, globalCtx);
|
||||
} else {
|
||||
EnBbfall_SetupDamage(this);
|
||||
}
|
||||
|
||||
if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_LIGHT_ARROW) {
|
||||
this->drawDmgEffAlpha = 4.0f;
|
||||
this->drawDmgEffScale = 0.4f;
|
||||
this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS;
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG,
|
||||
this->collider.elements[0].info.bumper.hitPos.x,
|
||||
this->collider.elements[0].info.bumper.hitPos.y,
|
||||
this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_SMALL_LIGHT_RAYS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->collider.base.atFlags & AT_BOUNCED) {
|
||||
this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
|
||||
EnBbfall_DisableColliders(this);
|
||||
if (this->actionFunc != EnBbfall_Down) {
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000;
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
EnBbfall_SetupDown(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBbfall_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBbfall* this = THIS;
|
||||
Sphere16* sphere;
|
||||
Vec3f diff;
|
||||
s32 i;
|
||||
f32 scale;
|
||||
s32 pad[2];
|
||||
|
||||
EnBbfall_UpdateDamage(this, globalCtx);
|
||||
this->actionFunc(this, globalCtx);
|
||||
if (this->actionFunc != EnBbfall_Dead) {
|
||||
Actor_MoveWithGravity(&this->actor);
|
||||
if (this->isBgCheckCollisionEnabled) {
|
||||
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 25.0f, 20.0f, 7);
|
||||
}
|
||||
|
||||
for (i = ARRAY_COUNT(this->flamePos) - 1; i >= 2; i--) {
|
||||
Math_Vec3f_Diff(&this->flamePos[i - 2], &this->flamePos[i - 1], &diff);
|
||||
Math_Vec3f_Scale(&diff, (i - 1) * 0.1f);
|
||||
Math_Vec3f_Copy(&this->flamePos[i], &this->flamePos[i - 1]);
|
||||
Math_Vec3f_Sum(&this->flamePos[i], &diff, &this->flamePos[i]);
|
||||
}
|
||||
|
||||
Math_Vec3f_Copy(&this->flamePos[1], &this->flamePos[0]);
|
||||
Math_Vec3f_Copy(&this->flamePos[0], &this->actor.world.pos);
|
||||
this->flamePos[0].y += 15.0f;
|
||||
this->flamePos[0].y -= 47.0f * this->flameScaleY;
|
||||
|
||||
for (i = 0, scale = this->flameScaleX; i < ARRAY_COUNT(this->colliderElements); i++, scale *= 0.7569f) {
|
||||
sphere = &this->collider.elements[i].dim.worldSphere;
|
||||
sphere->radius = 30.0f * scale;
|
||||
sphere->center.x = this->flamePos[2 * i].x;
|
||||
sphere->center.y = this->flamePos[2 * i].y + (47.0f * scale);
|
||||
sphere->center.z = this->flamePos[2 * i].z;
|
||||
}
|
||||
|
||||
this->collider.elements[0].dim.worldSphere.radius =
|
||||
CLAMP_MIN(this->collider.elements[0].dim.worldSphere.radius, 20);
|
||||
|
||||
Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->collider.elements->dim.worldSphere.center);
|
||||
|
||||
if (this->collider.base.atFlags & AT_ON) {
|
||||
this->actor.flags |= ACTOR_FLAG_1000000;
|
||||
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
}
|
||||
|
||||
if (this->collider.base.acFlags & AC_ON) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
}
|
||||
|
||||
if (this->collider.base.ocFlags1 & OC1_ON) {
|
||||
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
}
|
||||
|
||||
if (this->drawDmgEffAlpha > 0.0f) {
|
||||
if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) {
|
||||
Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f);
|
||||
this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.2f;
|
||||
this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.4f);
|
||||
} else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.4f, 0.01f)) {
|
||||
func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 EnBbfall_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
Actor* thisx) {
|
||||
EnBbfall* this = THIS;
|
||||
|
||||
if (this->bodyPartDrawStatus == BBFALL_BODY_PART_DRAW_STATUS_BROKEN) {
|
||||
this->limbDList = *dList;
|
||||
*dList = NULL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EnBbfall_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
|
||||
s32 pad;
|
||||
EnBbfall* this = THIS;
|
||||
MtxF* currentMatrixState;
|
||||
|
||||
if (this->bodyPartDrawStatus == BBFALL_BODY_PART_DRAW_STATUS_ALIVE) {
|
||||
if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) {
|
||||
if (sLimbIndexToBodyPartsIndex[limbIndex] == 0) {
|
||||
Matrix_GetStateTranslationAndScaledX(1000.0f, &this->bodyPartsPos[0]);
|
||||
} else if (sLimbIndexToBodyPartsIndex[limbIndex] == 3) {
|
||||
Matrix_GetStateTranslationAndScaledX(-1000.0f, &this->bodyPartsPos[3]);
|
||||
Matrix_MultiplyVector3fByState(&sDuplicateCraniumBodyPartOffset, &this->bodyPartsPos[4]);
|
||||
} else {
|
||||
Matrix_GetStateTranslation(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]);
|
||||
}
|
||||
}
|
||||
} else if (this->bodyPartDrawStatus > BBFALL_BODY_PART_DRAW_STATUS_ALIVE) {
|
||||
if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) {
|
||||
Matrix_GetStateTranslation(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]);
|
||||
}
|
||||
|
||||
if (limbIndex == BUBBLE_LIMB_CRANIUM) {
|
||||
this->bodyPartDrawStatus = BBFALL_BODY_PART_DRAW_STATUS_BROKEN;
|
||||
}
|
||||
} else {
|
||||
if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) {
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
|
||||
currentMatrixState = Matrix_GetCurrentState();
|
||||
currentMatrixState->mf[3][0] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].x;
|
||||
currentMatrixState->mf[3][1] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].y;
|
||||
currentMatrixState->mf[3][2] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].z;
|
||||
Matrix_InsertZRotation_s(thisx->world.rot.z, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, this->limbDList);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBbfall_Draw(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
GlobalContext* globalCtx = globalCtx2;
|
||||
EnBbfall* this = THIS;
|
||||
MtxF* currentMatrixState;
|
||||
Gfx* gfx;
|
||||
s32 opacity;
|
||||
Vec3f* pos;
|
||||
s32 i;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
|
||||
gfx = POLY_OPA_DISP;
|
||||
gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]);
|
||||
POLY_OPA_DISP = &gfx[1];
|
||||
SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnBbfall_OverrideLimbDraw,
|
||||
EnBbfall_PostLimbDraw, &this->actor);
|
||||
|
||||
if (this->flameOpacity > 0) {
|
||||
func_8012C2DC(globalCtx->state.gfxCtx);
|
||||
Matrix_RotateY(
|
||||
((Camera_GetCamDirYaw(globalCtx->cameraPtrs[globalCtx->activeCamera]) - this->actor.shape.rot.y) + 0x8000),
|
||||
MTXMODE_APPLY);
|
||||
Matrix_Scale(this->flameScaleX, this->flameScaleY, 1.0f, MTXMODE_APPLY);
|
||||
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
|
||||
currentMatrixState = Matrix_GetCurrentState();
|
||||
|
||||
opacity = this->flameOpacity;
|
||||
pos = &this->flamePos[0];
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(this->flamePos); i++, pos++) {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08,
|
||||
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
|
||||
((globalCtx->gameplayFrames + (i * 10)) * (-20 + i * 2)) & 0x1FF, 32, 128));
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, opacity);
|
||||
currentMatrixState->mf[3][0] = pos->x;
|
||||
currentMatrixState->mf[3][1] = pos->y;
|
||||
currentMatrixState->mf[3][2] = pos->z;
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL);
|
||||
|
||||
opacity -= 35;
|
||||
if (opacity < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
Matrix_Scale(0.87f, 0.87f, 1.0f, MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
|
||||
Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos),
|
||||
this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha,
|
||||
this->drawDmgEffType);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,35 @@
|
|||
#define Z_EN_BBFALL_H
|
||||
|
||||
#include "global.h"
|
||||
#include "objects/object_bb/object_bb.h"
|
||||
|
||||
struct EnBbfall;
|
||||
|
||||
typedef void (*EnBbfallActionFunc)(struct EnBbfall*, GlobalContext*);
|
||||
|
||||
typedef struct EnBbfall {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x0144 */ char unk_144[0x104];
|
||||
/* 0x0248 */ EnBbfallActionFunc actionFunc;
|
||||
/* 0x024C */ char unk_24C[0x218];
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ SkelAnime skelAnime;
|
||||
/* 0x188 */ Vec3s jointTable[BUBBLE_LIMB_MAX];
|
||||
/* 0x1E8 */ Vec3s morphTable[BUBBLE_LIMB_MAX];
|
||||
/* 0x248 */ EnBbfallActionFunc actionFunc;
|
||||
/* 0x24C */ u8 flameOpacity;
|
||||
/* 0x24D */ u8 isBgCheckCollisionEnabled;
|
||||
/* 0x24E */ s8 bodyPartDrawStatus;
|
||||
/* 0x24F */ u8 drawDmgEffType;
|
||||
/* 0x250 */ s16 timer;
|
||||
/* 0x254 */ f32 flameScaleY;
|
||||
/* 0x258 */ f32 flameScaleX;
|
||||
/* 0x25C */ f32 drawDmgEffAlpha;
|
||||
/* 0x260 */ f32 drawDmgEffScale;
|
||||
/* 0x264 */ f32 drawDmgEffFrozenSteamScale;
|
||||
/* 0x268 */ Vec3f flamePos[6];
|
||||
/* 0x2B0 */ Vec3f bodyPartsPos[5];
|
||||
/* 0x2EC */ Vec3f bodyPartsVelocity[5];
|
||||
/* 0x328 */ Gfx* limbDList;
|
||||
/* 0x32C */ UNK_TYPE1 unk_32C[0x58];
|
||||
/* 0x384 */ ColliderJntSph collider;
|
||||
/* 0x3A4 */ ColliderJntSphElement colliderElements[3];
|
||||
} EnBbfall; // size = 0x464
|
||||
|
||||
extern const ActorInit En_Bbfall_InitVars;
|
||||
|
|
|
|||
|
|
@ -6071,33 +6071,33 @@
|
|||
0x808BEE38:("EnDekunuts_Draw",),
|
||||
0x808BF220:("EnBbfall_Init",),
|
||||
0x808BF318:("EnBbfall_Destroy",),
|
||||
0x808BF344:("func_808BF344",),
|
||||
0x808BF3B8:("func_808BF3B8",),
|
||||
0x808BF438:("func_808BF438",),
|
||||
0x808BF4B4:("func_808BF4B4",),
|
||||
0x808BF514:("func_808BF514",),
|
||||
0x808BF578:("func_808BF578",),
|
||||
0x808BF5AC:("func_808BF5AC",),
|
||||
0x808BF5E0:("func_808BF5E0",),
|
||||
0x808BF734:("func_808BF734",),
|
||||
0x808BF7A0:("func_808BF7A0",),
|
||||
0x808BF830:("func_808BF830",),
|
||||
0x808BF894:("func_808BF894",),
|
||||
0x808BF8DC:("func_808BF8DC",),
|
||||
0x808BFA18:("func_808BFA18",),
|
||||
0x808BFA3C:("func_808BFA3C",),
|
||||
0x808BFAB4:("func_808BFAB4",),
|
||||
0x808BFB4C:("func_808BFB4C",),
|
||||
0x808BFCCC:("func_808BFCCC",),
|
||||
0x808BFE58:("func_808BFE58",),
|
||||
0x808BFF8C:("func_808BFF8C",),
|
||||
0x808C00A0:("func_808C00A0",),
|
||||
0x808C013C:("func_808C013C",),
|
||||
0x808C0178:("func_808C0178",),
|
||||
0x808C01E0:("func_808C01E0",),
|
||||
0x808BF344:("EnBbfall_Freeze",),
|
||||
0x808BF3B8:("EnBbfall_Thaw",),
|
||||
0x808BF438:("EnBbfall_IsTouchingLava",),
|
||||
0x808BF4B4:("EnBbfall_PlaySfx",),
|
||||
0x808BF514:("EnBbfall_CheckForWall",),
|
||||
0x808BF578:("EnBbfall_EnableColliders",),
|
||||
0x808BF5AC:("EnBbfall_DisableColliders",),
|
||||
0x808BF5E0:("EnBbfall_SetupWaitForPlayer",),
|
||||
0x808BF734:("EnBbfall_WaitForPlayer",),
|
||||
0x808BF7A0:("EnBbfall_SetupEmerge",),
|
||||
0x808BF830:("EnBbfall_Emerge",),
|
||||
0x808BF894:("EnBbfall_SetupFly",),
|
||||
0x808BF8DC:("EnBbfall_Fly",),
|
||||
0x808BFA18:("EnBbfall_SetupSinkIntoLava",),
|
||||
0x808BFA3C:("EnBbfall_SinkIntoLava",),
|
||||
0x808BFAB4:("EnBbfall_SetupDown",),
|
||||
0x808BFB4C:("EnBbfall_Down",),
|
||||
0x808BFCCC:("EnBbfall_SetupDead",),
|
||||
0x808BFE58:("EnBbfall_Dead",),
|
||||
0x808BFF8C:("EnBbfall_SetupDamage",),
|
||||
0x808C00A0:("EnBbfall_Damage",),
|
||||
0x808C013C:("EnBbfall_SetupFrozen",),
|
||||
0x808C0178:("EnBbfall_Frozen",),
|
||||
0x808C01E0:("EnBbfall_UpdateDamage",),
|
||||
0x808C03EC:("EnBbfall_Update",),
|
||||
0x808C07D4:("func_808C07D4",),
|
||||
0x808C080C:("func_808C080C",),
|
||||
0x808C07D4:("EnBbfall_OverrideLimbDraw",),
|
||||
0x808C080C:("EnBbfall_PostLimbDraw",),
|
||||
0x808C0A04:("EnBbfall_Draw",),
|
||||
0x808C1030:("ArmsHook_SetupAction",),
|
||||
0x808C103C:("ArmsHook_Init",),
|
||||
|
|
|
|||
|
|
@ -1016,12 +1016,6 @@ D_0600D530 = 0x0600D530;
|
|||
D_060000A0 = 0x060000A0;
|
||||
D_060000C8 = 0x060000C8;
|
||||
|
||||
// ovl_En_Bbfall
|
||||
|
||||
D_06000184 = 0x06000184;
|
||||
D_06000444 = 0x06000444;
|
||||
D_06001A30 = 0x06001A30;
|
||||
|
||||
// ovl_En_Bee
|
||||
|
||||
D_0600005C = 0x0600005C;
|
||||
|
|
|
|||
Loading…
Reference in New Issue