mirror of https://github.com/zeldaret/mm.git
En_Bb (Blue Bubble) OK and documented. object_bb documented (#713)
* EnBb_Init OK * EnBb_Destroy OK * func_808C20D4 OK * func_808C2238 OK * func_808C1FF4 OK * func_808C1E94 OK * func_808C2344 OK * func_808C23EC OK * EnBb_Update OK * func_808C2E34 OK * func_808C254C OK * func_808C272C OK * func_808C2B94 OK * func_808C2A00 OK * func_808C1F00 OK * func_808C1F74 OK * func_808C25E0 OK * func_808C28CC OK * func_808C2B1C OK * func_808C2BD0 OK * func_808C2C38 OK * func_808C2CB4 OK * func_808C2CF0 OK * func_808C2D78 OK * EnBb_Draw OK * func_808C32EC OK * func_808C3324 OK * Migrate data to C * Use generated reloc * Object symbols and misc cleanup * Name struct vars that are used with Actor_DrawDamageEffects * Name most things in the object * Name attackRange * Good enough names for limbs for now * Might as well name the limb draw stuff for now * Name flame width/height * Enum for damage effects * Name some more stuff from OoT * Name a lot more stuff * First pass names on all functions * Name jinxTimer on gSaveContext * Name sLimbIndexToLimbPos * First pass name to the rest of the limb draw system * More cleanup * Last cleanup before PR * Incorporate Actor_DrawDamageEffect stuff * Respond to hensldm's review
This commit is contained in:
parent
7d4aaef0cd
commit
acd84bda77
|
@ -1,37 +1,47 @@
|
|||
<Root>
|
||||
<!-- Assets for red and blue Bubbles -->
|
||||
<File Name="object_bb" Segment="6">
|
||||
<Animation Name="object_bb_Anim_000184" Offset="0x184" />
|
||||
<Animation Name="object_bb_Anim_0002AC" Offset="0x2AC" />
|
||||
<Animation Name="object_bb_Anim_000444" Offset="0x444" />
|
||||
<DList Name="object_bb_DL_000C20" Offset="0xC20" />
|
||||
<DList Name="object_bb_DL_000CB0" Offset="0xCB0" />
|
||||
<DList Name="object_bb_DL_000D40" Offset="0xD40" />
|
||||
<DList Name="object_bb_DL_000E08" Offset="0xE08" />
|
||||
<DList Name="object_bb_DL_001100" Offset="0x1100" />
|
||||
<DList Name="object_bb_DL_001190" Offset="0x1190" />
|
||||
<Texture Name="object_bb_Tex_001220" OutName="tex_001220" Format="rgba16" Width="16" Height="16" Offset="0x1220" />
|
||||
<Texture Name="object_bb_Tex_001420" OutName="tex_001420" Format="rgba16" Width="8" Height="8" Offset="0x1420" />
|
||||
<Texture Name="object_bb_Tex_0014A0" OutName="tex_0014A0" Format="rgba16" Width="4" Height="4" Offset="0x14A0" />
|
||||
<Texture Name="object_bb_Tex_0014C0" OutName="tex_0014C0" Format="rgba16" Width="8" Height="8" Offset="0x14C0" />
|
||||
<Texture Name="object_bb_Tex_001540" OutName="tex_001540" Format="rgba16" Width="8" Height="8" Offset="0x1540" />
|
||||
<Texture Name="object_bb_Tex_0015C0" OutName="tex_0015C0" Format="rgba16" Width="8" Height="8" Offset="0x15C0" />
|
||||
<Texture Name="object_bb_Tex_001640" OutName="tex_001640" Format="rgba16" Width="16" Height="8" Offset="0x1640" />
|
||||
<Texture Name="object_bb_Tex_001740" OutName="tex_001740" Format="rgba16" Width="16" Height="16" Offset="0x1740" />
|
||||
<Limb Name="object_bb_Standardlimb_001940" Type="Standard" EnumName="OBJECT_BB_LIMB_01" Offset="0x1940" />
|
||||
<Limb Name="object_bb_Standardlimb_00194C" Type="Standard" EnumName="OBJECT_BB_LIMB_02" Offset="0x194C" />
|
||||
<Limb Name="object_bb_Standardlimb_001958" Type="Standard" EnumName="OBJECT_BB_LIMB_03" Offset="0x1958" />
|
||||
<Limb Name="object_bb_Standardlimb_001964" Type="Standard" EnumName="OBJECT_BB_LIMB_04" Offset="0x1964" />
|
||||
<Limb Name="object_bb_Standardlimb_001970" Type="Standard" EnumName="OBJECT_BB_LIMB_05" Offset="0x1970" />
|
||||
<Limb Name="object_bb_Standardlimb_00197C" Type="Standard" EnumName="OBJECT_BB_LIMB_06" Offset="0x197C" />
|
||||
<Limb Name="object_bb_Standardlimb_001988" Type="Standard" EnumName="OBJECT_BB_LIMB_07" Offset="0x1988" />
|
||||
<Limb Name="object_bb_Standardlimb_001994" Type="Standard" EnumName="OBJECT_BB_LIMB_08" Offset="0x1994" />
|
||||
<Limb Name="object_bb_Standardlimb_0019A0" Type="Standard" EnumName="OBJECT_BB_LIMB_09" Offset="0x19A0" />
|
||||
<Limb Name="object_bb_Standardlimb_0019AC" Type="Standard" EnumName="OBJECT_BB_LIMB_0A" Offset="0x19AC" />
|
||||
<Limb Name="object_bb_Standardlimb_0019B8" Type="Standard" EnumName="OBJECT_BB_LIMB_0B" Offset="0x19B8" />
|
||||
<Limb Name="object_bb_Standardlimb_0019C4" Type="Standard" EnumName="OBJECT_BB_LIMB_0C" Offset="0x19C4" />
|
||||
<Limb Name="object_bb_Standardlimb_0019D0" Type="Standard" EnumName="OBJECT_BB_LIMB_0D" Offset="0x19D0" />
|
||||
<Limb Name="object_bb_Standardlimb_0019DC" Type="Standard" EnumName="OBJECT_BB_LIMB_0E" Offset="0x19DC" />
|
||||
<Limb Name="object_bb_Standardlimb_0019E8" Type="Standard" EnumName="OBJECT_BB_LIMB_0F" Offset="0x19E8" />
|
||||
<Skeleton Name="object_bb_Skel_001A30" Type="Normal" LimbType="Standard" LimbNone="OBJECT_BB_LIMB_NONE" LimbMax="OBJECT_BB_LIMB_MAX" EnumName="object_bb_Limbs" Offset="0x1A30" />
|
||||
<!-- 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="gBubbleFlyingAnim" Offset="0x444" /> <!-- Original name is "bb_fly" -->
|
||||
|
||||
<!-- Bubble Limb DisplayLimbs -->
|
||||
<DList Name="gBubbleLeftWingWebbingDL" Offset="0xC20" />
|
||||
<DList Name="gBubbleLeftWingBoneDL" Offset="0xCB0" />
|
||||
<DList Name="gBubbleJawDL" Offset="0xD40" />
|
||||
<DList Name="gBubbleCraniumDL" Offset="0xE08" />
|
||||
<DList Name="gBubbleRightWingBoneDL" Offset="0x1100" />
|
||||
<DList Name="gBubbleRightWingWebbingDL" Offset="0x1190" />
|
||||
|
||||
<!-- Bubble Textures -->
|
||||
<Texture Name="gBubbleEyeSocketBottomTex" OutName="eye_socket_bottom" Format="rgba16" Width="16" Height="16" Offset="0x1220" />
|
||||
<Texture Name="gBubbleNostrilTex" OutName="nostril" Format="rgba16" Width="8" Height="8" Offset="0x1420" />
|
||||
<Texture Name="gBubbleEyeSocketTopAndJawTex" OutName="eye_socket_top_and_jaw" Format="rgba16" Width="4" Height="4" Offset="0x14A0" />
|
||||
<Texture Name="gBubbleCraniumTopTex" OutName="cranium_top" Format="rgba16" Width="8" Height="8" Offset="0x14C0" />
|
||||
<Texture Name="gBubbleCraniumSidesAndBackTex" OutName="cranium_sides_and_back" Format="rgba16" Width="8" Height="8" Offset="0x1540" />
|
||||
<Texture Name="gBubbleEyeGlowTex" OutName="eye_glow" Format="rgba16" Width="8" Height="8" Offset="0x15C0" />
|
||||
<Texture Name="gBubbleWingBoneTex" OutName="wing_bone" Format="rgba16" Width="16" Height="8" Offset="0x1640" />
|
||||
<Texture Name="gBubbleWingWebbingTex" OutName="wing_webbing" Format="rgba16" Width="16" Height="16" Offset="0x1740" />
|
||||
|
||||
<!-- Bubble Limbs -->
|
||||
<Limb Name="gBubbleRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_ROOT" Offset="0x1940" />
|
||||
<Limb Name="gBubbleCraniumRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_CRANIUM_ROOT" Offset="0x194C" />
|
||||
<Limb Name="gBubbleJawRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_JAW_ROOT" Offset="0x1958" />
|
||||
<Limb Name="gBubbleJawLimb" Type="Standard" EnumName="BUBBLE_LIMB_JAW" Offset="0x1964" />
|
||||
<Limb Name="gBubbleLeftWingRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_LEFT_WING_ROOT" Offset="0x1970" />
|
||||
<Limb Name="gBubbleLeftWingWrapperLimb" Type="Standard" EnumName="BUBBLE_LIMB_LEFT_WING_WRAPPER" Offset="0x197C" />
|
||||
<Limb Name="gBubbleLeftWingWebbingRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_LEFT_WING_WEBBING_ROOT" Offset="0x1988" />
|
||||
<Limb Name="gBubbleLeftWingWebbingLimb" Type="Standard" EnumName="BUBBLE_LIMB_LEFT_WING_WEBBING" Offset="0x1994" />
|
||||
<Limb Name="gBubbleLeftWingBoneLimb" Type="Standard" EnumName="BUBBLE_LIMB_LEFT_WING_BONE" Offset="0x19A0" />
|
||||
<Limb Name="gBubbleRightWingRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_RIGHT_WING_ROOT" Offset="0x19AC" />
|
||||
<Limb Name="gBubbleRightWingWrapperLimb" Type="Standard" EnumName="BUBBLE_LIMB_RIGHT_WING_WRAPPER" Offset="0x19B8" />
|
||||
<Limb Name="gBubbleRightWingWebbingRootLimb" Type="Standard" EnumName="BUBBLE_LIMB_RIGHT_WING_WEBBING_ROOT" Offset="0x19C4" />
|
||||
<Limb Name="gBubbleRightWingWebbingLimb" Type="Standard" EnumName="BUBBLE_LIMB_RIGHT_WING_WEBBING" Offset="0x19D0" />
|
||||
<Limb Name="gBubbleRightWingBoneLimb" Type="Standard" EnumName="BUBBLE_LIMB_RIGHT_WING_BONE" Offset="0x19DC" />
|
||||
<Limb Name="gBubbleCraniumLimb" Type="Standard" EnumName="BUBBLE_LIMB_CRANIUM" Offset="0x19E8" />
|
||||
|
||||
<!-- Bubble Skeleton -->
|
||||
<Skeleton Name="gBubbleSkel" Type="Normal" LimbType="Standard" LimbNone="BUBBLE_LIMB_NONE" LimbMax="BUBBLE_LIMB_MAX" EnumName="BubbleLimbs" Offset="0x1A30" />
|
||||
</File>
|
||||
</Root>
|
||||
|
|
|
@ -134,7 +134,7 @@ typedef struct {
|
|||
/* 0x100C */ u8 eventInf[8];
|
||||
/* 0x1014 */ u8 unk_1014; // "stone_set_flag"
|
||||
/* 0x1015 */ u8 unk_1015;
|
||||
/* 0x1016 */ u16 unk_1016;
|
||||
/* 0x1016 */ u16 jinxTimer;
|
||||
/* 0x1018 */ s16 rupeeAccumulator; // "lupy_udct"
|
||||
/* 0x101A */ u8 unk_101A[6]; // "bottle_status", one entry for each bottle
|
||||
/* 0x1020 */ OSTime unk_1020[6]; // "bottle_ostime", one entry for each bottle
|
||||
|
|
3
spec
3
spec
|
@ -1080,8 +1080,7 @@ beginseg
|
|||
name "ovl_En_Bb"
|
||||
compress
|
||||
include "build/src/overlays/actors/ovl_En_Bb/z_en_bb.o"
|
||||
include "build/data/ovl_En_Bb/ovl_En_Bb.data.o"
|
||||
include "build/data/ovl_En_Bb/ovl_En_Bb.reloc.o"
|
||||
include "build/src/overlays/actors/ovl_En_Bb/ovl_En_Bb_reloc.o"
|
||||
endseg
|
||||
|
||||
beginseg
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include "z_en_bb.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200)
|
||||
|
||||
|
@ -15,15 +16,25 @@ void EnBb_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void EnBb_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnBb_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
void func_808C23EC(EnBb* this, GlobalContext* globalCtx);
|
||||
void func_808C25E0(EnBb* this, GlobalContext* globalCtx);
|
||||
void func_808C28CC(EnBb* this, GlobalContext* globalCtx);
|
||||
void func_808C2B1C(EnBb* this, GlobalContext* globalCtx);
|
||||
void func_808C2BD0(EnBb* this, GlobalContext* globalCtx);
|
||||
void func_808C2CB4(EnBb* this, GlobalContext* globalCtx);
|
||||
void func_808C2D78(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_SetupFlyIdle(EnBb* this);
|
||||
void EnBb_FlyIdle(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_SetupAttack(EnBb* this);
|
||||
void EnBb_Attack(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_Down(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_Dead(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_Damage(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_Frozen(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_SetupWaitForRevive(EnBb* this);
|
||||
void EnBb_WaitForRevive(EnBb* this, GlobalContext* globalCtx);
|
||||
void EnBb_SetupRevive(EnBb* this);
|
||||
void EnBb_Revive(EnBb* this, GlobalContext* globalCtx);
|
||||
|
||||
typedef enum {
|
||||
/* -1 */ BB_BODY_PART_DRAW_STATUS_BROKEN = -1,
|
||||
/* 0 */ BB_BODY_PART_DRAW_STATUS_ALIVE,
|
||||
/* 1 */ BB_BODY_PART_DRAW_STATUS_DEAD,
|
||||
} EnBbBodyPartDrawStatus;
|
||||
|
||||
#if 0
|
||||
const ActorInit En_Bb_InitVars = {
|
||||
ACTOR_EN_BB,
|
||||
ACTORCAT_ENEMY,
|
||||
|
@ -36,118 +47,667 @@ const ActorInit En_Bb_InitVars = {
|
|||
(ActorFunc)EnBb_Draw,
|
||||
};
|
||||
|
||||
// static ColliderSphereInit sSphereInit = {
|
||||
static ColliderSphereInit D_808C37A0 = {
|
||||
{ COLTYPE_HIT3, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, },
|
||||
{ ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, },
|
||||
static ColliderSphereInit sSphereInit = {
|
||||
{
|
||||
COLTYPE_HIT3,
|
||||
AT_NONE | AT_TYPE_ENEMY,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_ON | OC1_TYPE_ALL,
|
||||
OC2_TYPE_1,
|
||||
COLSHAPE_SPHERE,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xF7CFFFFF, 0x00, 0x08 },
|
||||
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_NORMAL,
|
||||
BUMP_ON | BUMP_HOOKABLE,
|
||||
OCELEM_ON,
|
||||
},
|
||||
{ 0, { { 0, 0, 0 }, 20 }, 100 },
|
||||
};
|
||||
|
||||
// static DamageTable sDamageTable = {
|
||||
static DamageTable D_808C37CC = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, 0x1),
|
||||
/* Deku Stick */ DMG_ENTRY(1, 0x0),
|
||||
/* Horse trample */ DMG_ENTRY(1, 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_BB_DMGEFF_NONE,
|
||||
/* 0x1 */ EN_BB_DMGEFF_STUN,
|
||||
/* 0x3 */ EN_BB_DMGEFF_ICE_ARROW = 0x3,
|
||||
/* 0x4 */ EN_BB_DMGEFF_LIGHT_ARROW,
|
||||
/* 0x5 */ EN_BB_DMGEFF_ZORA_MAGIC,
|
||||
/* 0xE */ EN_BB_DMGEFF_HOOKSHOT = 0xE,
|
||||
} EnBbDamageEffect;
|
||||
|
||||
static DamageTable sDamageTable = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, EN_BB_DMGEFF_STUN),
|
||||
/* Deku Stick */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Horse trample */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Explosives */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Zora boomerang */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Normal arrow */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* Hookshot */ DMG_ENTRY(0, EN_BB_DMGEFF_HOOKSHOT),
|
||||
/* Goron punch */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Sword */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Goron pound */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Fire arrow */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Ice arrow */ DMG_ENTRY(2, EN_BB_DMGEFF_ICE_ARROW),
|
||||
/* Light arrow */ DMG_ENTRY(2, EN_BB_DMGEFF_LIGHT_ARROW),
|
||||
/* Goron spikes */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Deku spin */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Deku bubble */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Deku launch */ DMG_ENTRY(2, EN_BB_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_BB_DMGEFF_STUN),
|
||||
/* Zora barrier */ DMG_ENTRY(0, EN_BB_DMGEFF_ZORA_MAGIC),
|
||||
/* Normal shield */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* Light ray */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* Thrown object */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Zora punch */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Spin attack */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
/* Sword beam */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* Normal Roll */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* Unblockable */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE),
|
||||
/* Powder Keg */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE),
|
||||
};
|
||||
|
||||
// sColChkInfoInit
|
||||
static CollisionCheckInfoInit D_808C37EC = { 2, 20, 40, 50 };
|
||||
static CollisionCheckInfoInit sColChkInfoInit = { 2, 20, 40, 50 };
|
||||
|
||||
// static InitChainEntry sInitChain[] = {
|
||||
static InitChainEntry D_808C37F4[] = {
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_S8(hintId, 28, 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 ColliderSphereInit D_808C37A0;
|
||||
extern DamageTable D_808C37CC;
|
||||
extern CollisionCheckInfoInit D_808C37EC;
|
||||
extern InitChainEntry D_808C37F4[];
|
||||
/**
|
||||
* 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 EnBb_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBb* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Init.s")
|
||||
Actor_ProcessInitChain(&this->actor, sInitChain);
|
||||
SkelAnime_Init(globalCtx, &this->skelAnime, &gBubbleSkel, &gBubbleFlyingAnim, this->jointTable, this->morphTable,
|
||||
BUBBLE_LIMB_MAX);
|
||||
Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit);
|
||||
ActorShape_Init(&this->actor.shape, 1500.0f, ActorShadow_DrawCircle, 35.0f);
|
||||
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Destroy.s")
|
||||
this->flameScaleY = 0.8f;
|
||||
this->flameScaleX = 1.0f;
|
||||
this->actor.world.pos.y += 50.0f;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1E94.s")
|
||||
if (EN_BB_ATTACK_RANGE(&this->actor) == 0xFF) {
|
||||
this->attackRange = 200.0f;
|
||||
} else {
|
||||
this->attackRange = EN_BB_ATTACK_RANGE(&this->actor) * 4.0f;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1F00.s")
|
||||
EnBb_SetupFlyIdle(this);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1F74.s")
|
||||
void EnBb_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBb* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1FF4.s")
|
||||
Collider_DestroySphere(globalCtx, &this->collider);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C20D4.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 EnBb_CheckForWall(EnBb* this) {
|
||||
s16 yawDiff;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2238.s")
|
||||
if (this->actor.bgCheckFlags & 8) {
|
||||
yawDiff = this->actor.shape.rot.y - this->actor.wallYaw;
|
||||
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_Bb/func_808C2344.s")
|
||||
this->targetYRotation = this->actor.shape.rot.y;
|
||||
this->actor.bgCheckFlags &= ~8;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C23EC.s")
|
||||
void EnBb_Freeze(EnBb* 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_Bb/func_808C254C.s")
|
||||
void EnBb_Thaw(EnBb* 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_Bb/func_808C25E0.s")
|
||||
/**
|
||||
* Updates certain variables that relate to flying like the Bubble's
|
||||
* Y-position, bob phase, and flame scale.
|
||||
*/
|
||||
void EnBb_UpdateStateForFlying(EnBb* this) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
if (this->actor.floorHeight > BGCHECK_Y_MIN) {
|
||||
Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + this->flyHeightMod, 0.5f);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C272C.s")
|
||||
this->actor.world.pos.y += Math_CosS(this->bobPhase);
|
||||
this->bobPhase += 0x826;
|
||||
Math_StepToF(&this->flameScaleY, 0.8f, 0.1f);
|
||||
Math_StepToF(&this->flameScaleX, 1.0f, 0.1f);
|
||||
EnBb_CheckForWall(this);
|
||||
Math_StepToF(&this->actor.speedXZ, this->maxSpeed, 0.5f);
|
||||
Math_ApproachS(&this->actor.shape.rot.y, this->targetYRotation, 5, 0x3E8);
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C28CC.s")
|
||||
void EnBb_SetupFlyIdle(EnBb* this) {
|
||||
if (this->actionFunc != EnBb_FlyIdle) {
|
||||
Animation_PlayLoop(&this->skelAnime, &gBubbleFlyingAnim);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2A00.s")
|
||||
if (this->actionFunc == EnBb_Attack) {
|
||||
this->attackWaitTimer = 40;
|
||||
} else {
|
||||
this->attackWaitTimer = 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2B1C.s")
|
||||
this->timer = (s32)Rand_ZeroFloat(20.0f) + 40;
|
||||
this->actor.gravity = 0.0f;
|
||||
this->actor.velocity.y = 0.0f;
|
||||
this->flyHeightMod = (Math_CosS(this->bobPhase) * 10.0f) + 30.0f;
|
||||
this->targetYRotation = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2B94.s")
|
||||
if ((this->actor.xzDistToPlayer < (this->attackRange + 120.0f)) ||
|
||||
(Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 300.0f)) {
|
||||
this->targetYRotation += (s16)(Rand_Next() >> 0x11);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2BD0.s")
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->maxSpeed = Rand_ZeroFloat(1.5f) + 1.0f;
|
||||
this->actionFunc = EnBb_FlyIdle;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2C38.s")
|
||||
/**
|
||||
* Makes the Bubble fly in circles around its home.
|
||||
*/
|
||||
void EnBb_FlyIdle(EnBb* this, GlobalContext* globalCtx) {
|
||||
EnBb_UpdateStateForFlying(this);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2CB4.s")
|
||||
if (Animation_OnFrame(&this->skelAnime, 5.0f)) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING);
|
||||
} else if ((Animation_OnFrame(&this->skelAnime, 0.0f)) && (Rand_ZeroOne() < 0.1f)) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_LAUGH);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2CF0.s")
|
||||
DECR(this->attackWaitTimer);
|
||||
this->timer--;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2D78.s")
|
||||
if ((this->attackWaitTimer == 0) && (this->actor.xzDistToPlayer < this->attackRange) &&
|
||||
(Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) {
|
||||
EnBb_SetupAttack(this);
|
||||
} else if (this->timer == 0) {
|
||||
EnBb_SetupFlyIdle(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2E34.s")
|
||||
void EnBb_SetupAttack(EnBb* this) {
|
||||
Animation_PlayLoop(&this->skelAnime, &gBubbleAttackAnim);
|
||||
this->timer = (s32)Rand_ZeroFloat(20.0f) + 60;
|
||||
this->flyHeightMod = (Math_CosS(this->bobPhase) * 10.0f) + 30.0f;
|
||||
this->targetYRotation = this->actor.yawTowardsPlayer;
|
||||
this->maxSpeed = Rand_ZeroFloat(1.5f) + 4.0f;
|
||||
this->actionFunc = EnBb_Attack;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Update.s")
|
||||
/**
|
||||
* Makes the Bubble actively move towards the player.
|
||||
*/
|
||||
void EnBb_Attack(EnBb* this, GlobalContext* globalCtx) {
|
||||
this->targetYRotation = this->actor.yawTowardsPlayer;
|
||||
EnBb_UpdateStateForFlying(this);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C32EC.s")
|
||||
if ((Animation_OnFrame(&this->skelAnime, 0.0f)) || (Animation_OnFrame(&this->skelAnime, 5.0f))) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_MOUTH);
|
||||
} else if ((Animation_OnFrame(&this->skelAnime, 2.0f)) || (Animation_OnFrame(&this->skelAnime, 7.0f))) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING);
|
||||
} else if ((Animation_OnFrame(&this->skelAnime, 0.0f)) && (Rand_ZeroOne() < 0.1f)) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_LAUGH);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C3324.s")
|
||||
this->timer--;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Draw.s")
|
||||
if (((this->attackRange + 120.0f) < this->actor.xzDistToPlayer) || (this->timer == 0) ||
|
||||
(Player_GetMask(globalCtx) == PLAYER_MASK_STONE) ||
|
||||
(Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 400.0f)) {
|
||||
EnBb_SetupFlyIdle(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EnBb_SetupDown(EnBb* this) {
|
||||
Animation_PlayLoop(&this->skelAnime, &gBubbleFlyingAnim);
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->timer = 140;
|
||||
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 = EnBb_Down;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the Bubble hop along the ground.
|
||||
*/
|
||||
void EnBb_Down(EnBb* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
EnBb_CheckForWall(this);
|
||||
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK);
|
||||
if (this->timer == 0) {
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_UP);
|
||||
EnBb_SetupFlyIdle(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 EnBb_SetupDead(EnBb* this, GlobalContext* globalCtx) {
|
||||
Vec3f* bodyPartVelocity;
|
||||
Vec3f posDiff;
|
||||
f32 magnitude;
|
||||
s32 i;
|
||||
|
||||
func_800BE568(&this->actor, &this->collider);
|
||||
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 = BB_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->actor.flags |= ACTOR_FLAG_10;
|
||||
this->actor.flags &= ~ACTOR_FLAG_1;
|
||||
this->actionFunc = EnBb_Dead;
|
||||
}
|
||||
|
||||
void EnBb_Dead(EnBb* 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);
|
||||
}
|
||||
|
||||
EnBb_SetupWaitForRevive(this);
|
||||
} 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 EnBb_SetupDamage(EnBb* this) {
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DAMAGE);
|
||||
func_800BE568(&this->actor, &this->collider);
|
||||
|
||||
if (this->actor.colChkInfo.damageEffect == EN_BB_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_BB_DMGEFF_STUN) {
|
||||
Actor_SetColorFilter(&this->actor, 0, 255, 0, 20);
|
||||
this->actor.speedXZ = 0.0f;
|
||||
} else if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_HOOKSHOT) {
|
||||
this->actor.speedXZ = 0.0f;
|
||||
} else {
|
||||
Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20);
|
||||
this->actor.speedXZ = 7.0f;
|
||||
}
|
||||
|
||||
this->actor.gravity = -1.0f;
|
||||
this->actionFunc = EnBb_Damage;
|
||||
}
|
||||
|
||||
void EnBb_Damage(EnBb* 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)) {
|
||||
EnBb_SetupDown(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EnBb_SetupFrozen(EnBb* 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 = EnBb_Frozen;
|
||||
}
|
||||
|
||||
void EnBb_Frozen(EnBb* this, GlobalContext* globalCtx) {
|
||||
DECR(this->timer);
|
||||
|
||||
if (this->timer == 0) {
|
||||
EnBb_Thaw(this, globalCtx);
|
||||
if (this->actor.colChkInfo.health == 0) {
|
||||
EnBb_SetupDead(this, globalCtx);
|
||||
} else {
|
||||
EnBb_SetupDown(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBb_SetupWaitForRevive(EnBb* this) {
|
||||
this->actor.draw = NULL;
|
||||
this->bodyPartDrawStatus = BB_BODY_PART_DRAW_STATUS_ALIVE;
|
||||
this->drawDmgEffAlpha = 0.0f;
|
||||
Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos);
|
||||
this->actor.shape.rot.x = 0;
|
||||
this->actor.world.pos.y += 50.0f;
|
||||
this->timer = 200;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actor.velocity.y = 0.0f;
|
||||
this->actor.gravity = 0.0f;
|
||||
this->actionFunc = EnBb_WaitForRevive;
|
||||
}
|
||||
|
||||
void EnBb_WaitForRevive(EnBb* this, GlobalContext* globalCtx) {
|
||||
this->timer--;
|
||||
if (this->timer == 0) {
|
||||
EnBb_SetupRevive(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EnBb_SetupRevive(EnBb* this) {
|
||||
Animation_PlayLoop(&this->skelAnime, &gBubbleAttackAnim);
|
||||
this->actor.draw = EnBb_Draw;
|
||||
this->actor.scale.x = 0.0f;
|
||||
this->actor.scale.y = 0.015f;
|
||||
this->actor.scale.z = 0.0f;
|
||||
this->flameScaleX = 1.0f;
|
||||
this->flameScaleY = 0.8f;
|
||||
this->actor.colChkInfo.health = sColChkInfoInit.health;
|
||||
this->actionFunc = EnBb_Revive;
|
||||
}
|
||||
|
||||
void EnBb_Revive(EnBb* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
this->actor.shape.rot.y += 0x1F00;
|
||||
|
||||
if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f)) {
|
||||
this->actor.flags &= ~ACTOR_FLAG_10;
|
||||
this->actor.flags |= ACTOR_FLAG_1;
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
EnBb_SetupFlyIdle(this);
|
||||
}
|
||||
|
||||
this->actor.scale.z = this->actor.scale.x;
|
||||
this->actor.scale.y = ((0.01f - this->actor.scale.x) * 0.5f) + 0.01f;
|
||||
}
|
||||
|
||||
void EnBb_UpdateDamage(EnBb* 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.info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) {
|
||||
Actor_SetDropFlag(&this->actor, &this->collider.info);
|
||||
this->flameScaleY = 0.0f;
|
||||
this->flameScaleX = 0.0f;
|
||||
EnBb_Thaw(this, globalCtx);
|
||||
|
||||
if (Actor_ApplyDamage(&this->actor) == 0) {
|
||||
Enemy_StartFinishingBlow(globalCtx, &this->actor);
|
||||
}
|
||||
|
||||
if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_ICE_ARROW) {
|
||||
EnBb_Freeze(this);
|
||||
if (this->actor.colChkInfo.health == 0) {
|
||||
this->timer = 3;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
}
|
||||
|
||||
EnBb_SetupFrozen(this);
|
||||
} else if (this->actor.colChkInfo.health == 0) {
|
||||
EnBb_SetupDead(this, globalCtx);
|
||||
} else {
|
||||
EnBb_SetupDamage(this);
|
||||
}
|
||||
|
||||
if (this->actor.colChkInfo.damageEffect == EN_BB_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.info.bumper.hitPos.x,
|
||||
this->collider.info.bumper.hitPos.y, this->collider.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);
|
||||
if (this->actionFunc != EnBb_Down) {
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000;
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
EnBb_SetupDown(this);
|
||||
}
|
||||
} else if (this->collider.base.atFlags & AT_HIT) {
|
||||
this->collider.base.atFlags &= ~AT_HIT;
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000;
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_BITE);
|
||||
|
||||
if (this->flameScaleX > 0.0f) {
|
||||
gSaveContext.jinxTimer = 1200;
|
||||
}
|
||||
|
||||
if (this->actionFunc == EnBb_Attack) {
|
||||
EnBb_SetupFlyIdle(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBb_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBb* this = THIS;
|
||||
|
||||
EnBb_UpdateDamage(this, globalCtx);
|
||||
this->actionFunc(this, globalCtx);
|
||||
if ((this->actionFunc != EnBb_Dead) && (this->actionFunc != EnBb_WaitForRevive)) {
|
||||
Actor_MoveWithGravity(&this->actor);
|
||||
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 25.0f, 40.0f, 7);
|
||||
|
||||
this->collider.dim.worldSphere.center.x = this->actor.world.pos.x;
|
||||
this->collider.dim.worldSphere.center.y = this->actor.world.pos.y + 15.0f;
|
||||
this->collider.dim.worldSphere.center.z = this->actor.world.pos.z;
|
||||
this->collider.dim.worldSphere.radius = this->flameScaleX * 30.0f;
|
||||
this->collider.dim.worldSphere.radius = CLAMP_MIN(this->collider.dim.worldSphere.radius, 20);
|
||||
|
||||
Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->collider.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 EnBb_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
|
||||
EnBb* this = THIS;
|
||||
|
||||
if (this->bodyPartDrawStatus == BB_BODY_PART_DRAW_STATUS_BROKEN) {
|
||||
this->limbDList = *dList;
|
||||
*dList = NULL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EnBb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
|
||||
s32 pad;
|
||||
EnBb* this = THIS;
|
||||
MtxF* currentMatrixState;
|
||||
|
||||
if (this->bodyPartDrawStatus == BB_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 > BB_BODY_PART_DRAW_STATUS_ALIVE) {
|
||||
if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) {
|
||||
Matrix_GetStateTranslation(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]);
|
||||
}
|
||||
|
||||
if (limbIndex == BUBBLE_LIMB_CRANIUM) {
|
||||
this->bodyPartDrawStatus = BB_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 EnBb_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnBb* this = THIS;
|
||||
MtxF* currentMatrixState;
|
||||
Gfx* gfx;
|
||||
|
||||
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, EnBb_OverrideLimbDraw,
|
||||
EnBb_PostLimbDraw, &this->actor);
|
||||
|
||||
if (this->flameScaleX > 0.0f) {
|
||||
currentMatrixState = Matrix_GetCurrentState();
|
||||
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);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, 255);
|
||||
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, 0);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08,
|
||||
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0,
|
||||
(globalCtx->gameplayFrames * -20) & 0x1FF, 32, 128));
|
||||
currentMatrixState->mf[3][1] -= 47.0f * this->flameScaleY;
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL);
|
||||
}
|
||||
|
||||
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,39 @@
|
|||
#define Z_EN_BB_H
|
||||
|
||||
#include "global.h"
|
||||
#include "objects/object_bb/object_bb.h"
|
||||
|
||||
#define EN_BB_ATTACK_RANGE(thisx) (((thisx)->params >> 8) & 0xFF)
|
||||
|
||||
struct EnBb;
|
||||
|
||||
typedef void (*EnBbActionFunc)(struct EnBb*, GlobalContext*);
|
||||
|
||||
typedef struct EnBb {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x0144 */ char unk_144[0x104];
|
||||
/* 0x0248 */ EnBbActionFunc actionFunc;
|
||||
/* 0x024C */ char unk_24C[0x100];
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ SkelAnime skelAnime;
|
||||
/* 0x188 */ Vec3s jointTable[BUBBLE_LIMB_MAX];
|
||||
/* 0x1E8 */ Vec3s morphTable[BUBBLE_LIMB_MAX];
|
||||
/* 0x248 */ EnBbActionFunc actionFunc;
|
||||
/* 0x24C */ s8 bodyPartDrawStatus;
|
||||
/* 0x24D */ u8 drawDmgEffType;
|
||||
/* 0x24E */ UNK_TYPE1 unk_24E[0x2];
|
||||
/* 0x250 */ s16 timer;
|
||||
/* 0x252 */ s16 attackWaitTimer; // Cannot start attacking the player if this is non-zero
|
||||
/* 0x254 */ s16 targetYRotation;
|
||||
/* 0x256 */ s16 bobPhase;
|
||||
/* 0x258 */ f32 maxSpeed;
|
||||
/* 0x25C */ f32 flyHeightMod;
|
||||
/* 0x260 */ f32 attackRange;
|
||||
/* 0x264 */ f32 flameScaleX;
|
||||
/* 0x268 */ f32 flameScaleY;
|
||||
/* 0x26C */ f32 drawDmgEffAlpha;
|
||||
/* 0x270 */ f32 drawDmgEffScale;
|
||||
/* 0x274 */ f32 drawDmgEffFrozenSteamScale;
|
||||
/* 0x278 */ Vec3f bodyPartsPos[5];
|
||||
/* 0x2B4 */ Vec3f bodyPartsVelocity[5];
|
||||
/* 0x2F0 */ Gfx* limbDList;
|
||||
/* 0x2F4 */ ColliderSphere collider;
|
||||
} EnBb; // size = 0x34C
|
||||
|
||||
extern const ActorInit En_Bb_InitVars;
|
||||
|
|
|
@ -363,7 +363,7 @@ void EnElf_Init(Actor* thisx, GlobalContext* globalCtx2) {
|
|||
|
||||
case 1:
|
||||
colorConfig = -1;
|
||||
gSaveContext.unk_1016 = 0;
|
||||
gSaveContext.jinxTimer = 0;
|
||||
EnElf_SetupAction(this, func_8088E0F0);
|
||||
this->unk_254 = Math_Vec3f_DistXZ(&thisx->world.pos, &player->actor.world.pos);
|
||||
this->unk_248 = player->actor.shape.rot.y;
|
||||
|
@ -677,7 +677,7 @@ void func_8088DD34(EnElf* this, GlobalContext* globalCtx) {
|
|||
if (this->fairyFlags & 0x200) {
|
||||
Parameter_AddMagic(globalCtx, ((void)0, gSaveContext.unk_3F30) + (gSaveContext.doubleMagic * 0x30) + 0x30);
|
||||
}
|
||||
gSaveContext.unk_1016 = 0;
|
||||
gSaveContext.jinxTimer = 0;
|
||||
this->unk_254 = 50.0f;
|
||||
this->unk_248 = refActor->actor.shape.rot.y;
|
||||
this->unk_24C = -0x1000;
|
||||
|
|
|
@ -493,6 +493,7 @@ animdict = {
|
|||
"player->unk_38C": "player->mountSide",
|
||||
"player->unk_394": "player->csMode",
|
||||
"globalCtx->actorCtx.actorList[": "globalCtx->actorCtx.actorLists[",
|
||||
"gSaveContext.unk_1016": "gSaveContext.jinxTimer",
|
||||
"gSaveContext.unk_3F58": "gSaveContext.sunsSongState",
|
||||
"globalCtx->msgCtx.unk1202A": "globalCtx->msgCtx.ocarinaMode",
|
||||
"globalCtx->msgCtx.unk1202C": "globalCtx->msgCtx.ocarinaAction",
|
||||
|
|
|
@ -6113,30 +6113,30 @@
|
|||
0x808C1918:("ArmsHook_Draw",),
|
||||
0x808C1D40:("EnBb_Init",),
|
||||
0x808C1E68:("EnBb_Destroy",),
|
||||
0x808C1E94:("func_808C1E94",),
|
||||
0x808C1F00:("func_808C1F00",),
|
||||
0x808C1F74:("func_808C1F74",),
|
||||
0x808C1FF4:("func_808C1FF4",),
|
||||
0x808C20D4:("func_808C20D4",),
|
||||
0x808C2238:("func_808C2238",),
|
||||
0x808C2344:("func_808C2344",),
|
||||
0x808C23EC:("func_808C23EC",),
|
||||
0x808C254C:("func_808C254C",),
|
||||
0x808C25E0:("func_808C25E0",),
|
||||
0x808C272C:("func_808C272C",),
|
||||
0x808C28CC:("func_808C28CC",),
|
||||
0x808C2A00:("func_808C2A00",),
|
||||
0x808C2B1C:("func_808C2B1C",),
|
||||
0x808C2B94:("func_808C2B94",),
|
||||
0x808C2BD0:("func_808C2BD0",),
|
||||
0x808C2C38:("func_808C2C38",),
|
||||
0x808C2CB4:("func_808C2CB4",),
|
||||
0x808C2CF0:("func_808C2CF0",),
|
||||
0x808C2D78:("func_808C2D78",),
|
||||
0x808C2E34:("func_808C2E34",),
|
||||
0x808C1E94:("EnBb_CheckForWall",),
|
||||
0x808C1F00:("EnBb_Freeze",),
|
||||
0x808C1F74:("EnBb_Thaw",),
|
||||
0x808C1FF4:("EnBb_UpdateStateForFlying",),
|
||||
0x808C20D4:("EnBb_SetupFlyIdle",),
|
||||
0x808C2238:("EnBb_FlyIdle",),
|
||||
0x808C2344:("EnBb_SetupAttack",),
|
||||
0x808C23EC:("EnBb_Attack",),
|
||||
0x808C254C:("EnBb_SetupDown",),
|
||||
0x808C25E0:("EnBb_Down",),
|
||||
0x808C272C:("EnBb_SetupDead",),
|
||||
0x808C28CC:("EnBb_Dead",),
|
||||
0x808C2A00:("EnBb_SetupDamage",),
|
||||
0x808C2B1C:("EnBb_Damage",),
|
||||
0x808C2B94:("EnBb_SetupFrozen",),
|
||||
0x808C2BD0:("EnBb_Frozen",),
|
||||
0x808C2C38:("EnBb_SetupWaitForRevive",),
|
||||
0x808C2CB4:("EnBb_WaitForRevive",),
|
||||
0x808C2CF0:("EnBb_SetupRevive",),
|
||||
0x808C2D78:("EnBb_Revive",),
|
||||
0x808C2E34:("EnBb_UpdateDamage",),
|
||||
0x808C30A0:("EnBb_Update",),
|
||||
0x808C32EC:("func_808C32EC",),
|
||||
0x808C3324:("func_808C3324",),
|
||||
0x808C32EC:("EnBb_OverrideLimbDraw",),
|
||||
0x808C3324:("EnBb_PostLimbDraw",),
|
||||
0x808C351C:("EnBb_Draw",),
|
||||
0x808C3A50:("BgKeikokuSpr_Init",),
|
||||
0x808C3A78:("BgKeikokuSpr_Destroy",),
|
||||
|
|
|
@ -1075,12 +1075,6 @@ D_0600D530 = 0x0600D530;
|
|||
D_060000A0 = 0x060000A0;
|
||||
D_060000C8 = 0x060000C8;
|
||||
|
||||
// ovl_En_Bb
|
||||
|
||||
D_06000184 = 0x06000184;
|
||||
D_06000444 = 0x06000444;
|
||||
D_06001A30 = 0x06001A30;
|
||||
|
||||
// ovl_En_Bbfall
|
||||
|
||||
D_06000184 = 0x06000184;
|
||||
|
|
Loading…
Reference in New Issue