mirror of
https://github.com/zeldaret/mm.git
synced 2026-08-18 05:08:48 -04:00
En_Minislime OK and Documented (#231)
* Get Minislime code from Bigslime Branch * format * PR Feedback, add Damage Effects Enum, add +1 use of Room Coordinates Macro
This commit is contained in:
+2
-2
@@ -757,9 +757,9 @@ void Actor_FreeOverlay(ActorOverlay* entry) {
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_actor//Actor_LoadOverlay.asm")
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_actor//Actor_SpawnWithParentAndCutscene.asm")
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_actor//Actor_SpawnAsChildAndCutscene.asm")
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_actor//Actor_SpawnWithParent.asm")
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_actor//Actor_SpawnAsChild.asm")
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/code/z_actor//Actor_SpawnTransitionActors.asm")
|
||||
|
||||
|
||||
@@ -2,12 +2,127 @@
|
||||
#define Z_EN_BIGSLIME_H
|
||||
|
||||
#include <global.h>
|
||||
#include "overlays/actors/ovl_En_Minislime/z_en_minislime.h"
|
||||
#include "overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h"
|
||||
|
||||
struct EnBigslime;
|
||||
|
||||
typedef void (*EnBigslimeActionFunc)(struct EnBigslime*, GlobalContext*);
|
||||
|
||||
#define BIGSLIME_NUM_VTX 162 // Number of vertices
|
||||
#define BIGSLIME_NUM_FACES 320 // Number of triangles
|
||||
#define BIGSLIME_NUM_RING_FACES 12 // Number of rings composed of faces
|
||||
#define BIGSLIME_NUM_RING_VTX (1 + BIGSLIME_NUM_RING_FACES) // Number of rings composed of vertices
|
||||
#define BIGSLIME_RADIUS_S 1000 // Radius of reference sphere int
|
||||
#define BIGSLIME_RADIUS_F 1000.0f // Radius of reference sphere float
|
||||
#define BIGSLIME_NUM_ICE_SHARD (BIGSLIME_NUM_VTX + 10*MINISLIME_NUM_SPAWN)
|
||||
|
||||
#define GBT_ROOM_5_CENTER_X 1338.0f
|
||||
#define GBT_ROOM_5_CENTER_Y -390.0f
|
||||
#define GBT_ROOM_5_CENTER_Z -2492.0f
|
||||
#define GBT_ROOM_5_MIN_X (GBT_ROOM_5_CENTER_X - 480.0f)
|
||||
#define GBT_ROOM_5_MAX_X (GBT_ROOM_5_CENTER_X + 480.0f)
|
||||
#define GBT_ROOM_5_MIN_Y (GBT_ROOM_5_CENTER_Y - 300.0f)
|
||||
#define GBT_ROOM_5_MAX_Y (GBT_ROOM_5_CENTER_Y + 300.0f)
|
||||
#define GBT_ROOM_5_MIN_Z (GBT_ROOM_5_CENTER_Z - 480.0f)
|
||||
#define GBT_ROOM_5_MAX_Z (GBT_ROOM_5_CENTER_Z + 480.0f)
|
||||
|
||||
/*
|
||||
* Triangle face
|
||||
* Based on "Tri" struct from gbi.h, but without the flag
|
||||
*/
|
||||
typedef struct {
|
||||
/* 0x0 */ u8 v[3]; // vertex index
|
||||
} EnBigslimeTri; // size = 0x3
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ s32 v; // vertex index
|
||||
/* 0x4 */ f32 scaleVtx; // fraction of distance from center to vtx (range 0-1)
|
||||
} EnBigslimeBubbles; // size = 0x8
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Vec3f pos;
|
||||
/* 0x0C */ Vec3f vel;
|
||||
/* 0x18 */ s16 isActive;
|
||||
/* 0x1A */ Vec3s rotation;
|
||||
/* 0x20 */ f32 scale;
|
||||
} EnBigslimeIceShardEffect; // size = 0x24
|
||||
|
||||
typedef struct EnBigslime {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x0144 */ char unk_0144[0x34F0];
|
||||
/* 0x0144 */ SkelAnime skelAnime;
|
||||
/* 0x0188 */ EnBigslimeActionFunc actionFunc;
|
||||
/* 0x018C */ EnBigslimeActionFunc actionFuncStored;
|
||||
/* 0x0190 */ Vec3s jointTable[GEKKO_LIMB_MAX];
|
||||
/* 0x0220 */ Vec3s morphTable[GEKKO_LIMB_MAX];
|
||||
/* 0x02B0 */ u8 minislimeState;
|
||||
/* 0x02B1 */ u8 dynamicVtxState; // Toggles between two states of dynamic Vtx
|
||||
/* 0x02B2 */ u8 isAnimUpdate;
|
||||
/* 0x02B3 */ union {
|
||||
u8 formBigslimeTimer; // Bigslime will start forming when timer reaches 0
|
||||
u8 minislimeCounter;
|
||||
u8 numGekkoMeleeAttacks; // The Gekko will melee-attack link at 1-3 times at each position while engulfed in bigslime
|
||||
};
|
||||
/* 0x02B4 */ u8 iceShardAlpha;
|
||||
/* 0x02B5 */ u8 gekkoDrawEffect;
|
||||
/* 0x02B6 */ s16 gekkoYaw;
|
||||
/* 0x02B8 */ s16 cutscene;
|
||||
/* 0x02BA */ union { // multi-use timer
|
||||
s16 idleTimer;
|
||||
s16 noticeTimer;
|
||||
s16 callTimer;
|
||||
s16 jumpTimer;
|
||||
s16 damageSpinTimer;
|
||||
s16 scaleFactor; // Used between individual gekko melee-attacks while engulfed in bigslime
|
||||
s16 windupPunchTimer;
|
||||
s16 throwPlayerTimer;
|
||||
s16 ceilingMoveTimer;
|
||||
s16 squishFlatTimer;
|
||||
s16 riseCounter;
|
||||
s16 grabPlayerTimer;
|
||||
s16 formBigslimeCutsceneTimer;
|
||||
s16 defeatTimer;
|
||||
s16 despawnTimer;
|
||||
s16 spawnFrogTimer;
|
||||
s16 isDespawned;
|
||||
s16 isInitJump;
|
||||
};
|
||||
/* 0x02BC */ s16 wavySurfaceTimer; // decrements from 24, used in sin_rad for currData2
|
||||
/* 0x02BE */ s16 stunTimer;
|
||||
/* 0x02C0 */ union {
|
||||
s16 freezeTimer;
|
||||
s16 meltCounter;
|
||||
};
|
||||
/* 0x02C2 */ s16 ceilingDropTimer; // Bigslime is still during this timer and shakes before dropping
|
||||
/* 0x02C4 */ s16 numGekkoPosGrabPlayer; // The Gekko will melee-attack link at 6 positions while engulfed in bigslime
|
||||
/* 0x02C6 */ s16 camId;
|
||||
/* 0x02C8 */ s16 cameraYawGrabPlayer;
|
||||
/* 0x02CA */ s16 rotation; // is always 0, used in Matrix_RotateY
|
||||
/* 0x02CC */ s16 itemDropTimer; // items only drop when zero, Set to 40 then decrements, prevents itemDrop spam
|
||||
/* 0x02CE */ Vec3s gekkoRot;
|
||||
/* 0x02D4 */ Vec3f gekkoPosOffset; // Used when Bigslime grabs link
|
||||
/* 0x02E0 */ Vec3f gekkoProjectedPos;
|
||||
/* 0x02EC */ union {
|
||||
Vec3f iceShardRefPos;
|
||||
Vec3f eyeDistToFrog; // Used to zoom into frogs as Gekko despawns/Frog spawns
|
||||
};
|
||||
/* 0x02F8 */ Vec3f limbPos[12];
|
||||
/* 0x0388 */ f32 unk_388; // used as arg to func_800BE680
|
||||
/* 0x038C */ f32 unk_38C; // used as arg to func_800BE680
|
||||
/* 0x0390 */ f32 unk_390; // used as arg to func_800BE680
|
||||
/* 0x0394 */ f32 gekkoScale;
|
||||
/* 0x0398 */ f32 vtxSurfacePerturbation[BIGSLIME_NUM_VTX];
|
||||
/* 0x0620 */ f32 vtxScaleX;
|
||||
/* 0x0624 */ f32 vtxScaleZ;
|
||||
/* 0x0628 */ f32 iceShardScale;
|
||||
/* 0x062C */ ColliderCylinder gekkoCollider;
|
||||
/* 0x0678 */ ColliderCylinder bigslimeCollider[BIGSLIME_NUM_RING_FACES];
|
||||
/* 0x0A14 */ EnMinislime* minislime[MINISLIME_NUM_SPAWN];
|
||||
/* 0x0A44 */ EnMinislime* minislimeToThrow;
|
||||
/* 0x0A48 */ AnimatedMaterial* bigslimeFrozenTex;
|
||||
/* 0x0A4C */ AnimatedMaterial* minislimeFrozenTex;
|
||||
/* 0x0A50 */ AnimatedMaterial* iceShardTex;
|
||||
/* 0x0A54 */ EnBigslimeIceShardEffect iceShardEffect[BIGSLIME_NUM_ICE_SHARD]; // 312 = 162 (bigslime) + 10 * 15 (minislime)
|
||||
} EnBigslime; // size = 0x3634
|
||||
|
||||
extern const ActorInit En_Bigslime_InitVars;
|
||||
|
||||
@@ -1358,13 +1358,13 @@ void func_80B452EC(EnInvadepoh* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void func_80B453F4(EnInvadepoh* this, GlobalContext* globalCtx, s32 arg2) {
|
||||
Actor_SpawnWithParent(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_INVADEPOH, this->actor.home.pos.x,
|
||||
this->actor.home.pos.y, this->actor.home.pos.z, 0, 0, 0, (arg2 & 7) | 0x20);
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_INVADEPOH, this->actor.home.pos.x,
|
||||
this->actor.home.pos.y, this->actor.home.pos.z, 0, 0, 0, (arg2 & 7) | 0x20);
|
||||
}
|
||||
|
||||
void func_80B45460(EnInvadepoh* this, GlobalContext* globalCtx) {
|
||||
Actor_SpawnWithParent(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_INVADEPOH, this->actor.home.pos.x,
|
||||
this->actor.home.pos.y, this->actor.home.pos.z, 0, 0, 0, 0x40);
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_INVADEPOH, this->actor.home.pos.x,
|
||||
this->actor.home.pos.y, this->actor.home.pos.z, 0, 0, 0, 0x40);
|
||||
}
|
||||
|
||||
void func_80B454BC(EnInvadepoh* this, GlobalContext* globalCtx) {
|
||||
@@ -1745,8 +1745,8 @@ void EnInvadepoh_InitAlien(EnInvadepoh* this, GlobalContext* globalCtx) {
|
||||
void EnInvadepoh_InitParentCow(EnInvadepoh* this, GlobalContext* globalCtx) {
|
||||
Actor_ProcessInitChain(&this->actor, sInitChainParentCow);
|
||||
this->actor.update = func_80B47FA8;
|
||||
Actor_SpawnWithParent(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_INVADEPOH, 0.0f, 0.0f, 0.0f, 0, 0, 0,
|
||||
0x30);
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_INVADEPOH, 0.0f, 0.0f, 0.0f, 0, 0, 0,
|
||||
0x30);
|
||||
this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_COW);
|
||||
if (this->bankIndex < 0) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
/*
|
||||
* File: z_en_minislime.c
|
||||
* Overlay: En_Minislime
|
||||
* Description: Mad Jelly & Gekko Miniboss: Mini Jelly Droplets
|
||||
*/
|
||||
|
||||
#include "z_en_minislime.h"
|
||||
#include "overlays/actors/ovl_En_Bigslime/z_en_bigslime.h"
|
||||
|
||||
#define FLAGS 0x00000235
|
||||
|
||||
@@ -8,7 +15,32 @@ void EnMinislime_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnMinislime_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnMinislime_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
#if 0
|
||||
void EnMinislime_SetupDisappear(EnMinislime* this);
|
||||
void EnMinislime_Disappear(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupFall(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_Fall(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupBreakFromBigslime(EnMinislime* this);
|
||||
void EnMinislime_BreakFromBigslime(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_IceArrowDamage(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_FireArrowDamage(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupGrowAndShrink(EnMinislime* this);
|
||||
void EnMinislime_GrowAndShrink(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupIdle(EnMinislime* this);
|
||||
void EnMinislime_SetupBounce(EnMinislime* this);
|
||||
void EnMinislime_Idle(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_Bounce(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupDespawn(EnMinislime* this);
|
||||
void EnMinislime_Despawn(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_MoveToBigslime(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_Knockback(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_DefeatIdle(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupDefeatMelt(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_DefeatMelt(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupMoveToGekko(EnMinislime* this);
|
||||
void EnMinislime_MoveToGekko(EnMinislime* this, GlobalContext* globalCtx);
|
||||
void EnMinislime_SetupGekkoThrow(EnMinislime* this);
|
||||
void EnMinislime_GekkoThrow(EnMinislime* this, GlobalContext* globalCtx);
|
||||
|
||||
const ActorInit En_Minislime_InitVars = {
|
||||
ACTOR_EN_MINISLIME,
|
||||
ACTORCAT_BOSS,
|
||||
@@ -21,131 +53,719 @@ const ActorInit En_Minislime_InitVars = {
|
||||
(ActorFunc)NULL,
|
||||
};
|
||||
|
||||
|
||||
// static ColliderCylinderInit sCylinderInit = {
|
||||
static ColliderCylinderInit D_809857E0 = {
|
||||
{ COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE | AC_TYPE_PLAYER, OC1_NONE | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
|
||||
{ ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, },
|
||||
static ColliderCylinderInit sCylinderInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_NONE | AT_TYPE_ENEMY,
|
||||
AC_NONE | AC_TYPE_PLAYER,
|
||||
OC1_NONE | OC1_TYPE_ALL,
|
||||
OC2_TYPE_1,
|
||||
COLSHAPE_CYLINDER,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xF7CFFFFF, 0x00, 0x04 },
|
||||
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_HARD,
|
||||
BUMP_ON | BUMP_HOOKABLE,
|
||||
OCELEM_ON,
|
||||
},
|
||||
{ 54, 60, -30, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
static CollisionCheckInfoInit sColChkInfoInit = { 4, 40, 40, 30 };
|
||||
|
||||
// sColChkInfoInit
|
||||
static CollisionCheckInfoInit D_8098580C = { 4, 40, 40, 30 };
|
||||
typedef enum {
|
||||
/* 0x0 */ MINISLIME_DMGEFF_NONE,
|
||||
/* 0x2 */ MINISLIME_DMGEFF_FIRE = 0x2,
|
||||
/* 0x3 */ MINISLIME_DMGEFF_ICE,
|
||||
/* 0xE */ MINISLIME_DMGEFF_HOOKSHOT = 0xE,
|
||||
/* 0xF */ MINISLIME_DMGEFF_BREAK_ICE,
|
||||
} MinislimeDamageEffect;
|
||||
|
||||
|
||||
// static DamageTable sDamageTable = {
|
||||
static DamageTable D_80985814 = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, 0x0),
|
||||
/* Deku Stick */ DMG_ENTRY(1, 0x0),
|
||||
/* Horse trample */ DMG_ENTRY(1, 0x0),
|
||||
/* Explosives */ DMG_ENTRY(1, 0xF),
|
||||
/* Zora boomerang */ DMG_ENTRY(1, 0x0),
|
||||
/* Normal arrow */ DMG_ENTRY(1, 0x0),
|
||||
/* UNK_DMG_0x06 */ DMG_ENTRY(1, 0x0),
|
||||
/* Hookshot */ DMG_ENTRY(0, 0xE),
|
||||
/* Goron punch */ DMG_ENTRY(1, 0xF),
|
||||
/* Sword */ DMG_ENTRY(1, 0x0),
|
||||
/* Goron pound */ DMG_ENTRY(1, 0xF),
|
||||
/* Fire arrow */ DMG_ENTRY(1, 0x2),
|
||||
/* Ice arrow */ DMG_ENTRY(1, 0x3),
|
||||
/* Light arrow */ DMG_ENTRY(1, 0x0),
|
||||
/* Goron spikes */ DMG_ENTRY(1, 0xF),
|
||||
/* Deku spin */ DMG_ENTRY(1, 0x0),
|
||||
/* Deku bubble */ DMG_ENTRY(1, 0x0),
|
||||
/* Deku launch */ DMG_ENTRY(1, 0x0),
|
||||
/* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0),
|
||||
/* Zora barrier */ DMG_ENTRY(1, 0x0),
|
||||
/* 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, 0xF),
|
||||
static DamageTable sDamageTable = {
|
||||
/* Deku Nut */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Deku Stick */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Horse trample */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Explosives */ DMG_ENTRY(1, MINISLIME_DMGEFF_BREAK_ICE),
|
||||
/* Zora boomerang */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Normal arrow */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x06 */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Hookshot */ DMG_ENTRY(0, MINISLIME_DMGEFF_HOOKSHOT),
|
||||
/* Goron punch */ DMG_ENTRY(1, MINISLIME_DMGEFF_BREAK_ICE),
|
||||
/* Sword */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Goron pound */ DMG_ENTRY(1, MINISLIME_DMGEFF_BREAK_ICE),
|
||||
/* Fire arrow */ DMG_ENTRY(1, MINISLIME_DMGEFF_FIRE),
|
||||
/* Ice arrow */ DMG_ENTRY(1, MINISLIME_DMGEFF_ICE),
|
||||
/* Light arrow */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Goron spikes */ DMG_ENTRY(1, MINISLIME_DMGEFF_BREAK_ICE),
|
||||
/* Deku spin */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Deku bubble */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Deku launch */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x12 */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Zora barrier */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Normal shield */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Light ray */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Thrown object */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Zora punch */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Spin attack */ DMG_ENTRY(1, MINISLIME_DMGEFF_NONE),
|
||||
/* Sword beam */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Normal Roll */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1B */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1C */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Unblockable */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1E */ DMG_ENTRY(0, MINISLIME_DMGEFF_NONE),
|
||||
/* Powder Keg */ DMG_ENTRY(1, MINISLIME_DMGEFF_BREAK_ICE),
|
||||
};
|
||||
|
||||
void EnMinislime_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnMinislime* this = THIS;
|
||||
|
||||
extern ColliderCylinderInit D_809857E0;
|
||||
extern CollisionCheckInfoInit D_8098580C;
|
||||
extern DamageTable D_80985814;
|
||||
#endif
|
||||
this->actor.flags &= ~1;
|
||||
Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
|
||||
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
|
||||
this->id = this->actor.params;
|
||||
this->actor.shape.shadowAlpha = 255;
|
||||
EnMinislime_SetupDisappear(this);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/EnMinislime_Init.asm")
|
||||
void EnMinislime_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnMinislime* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/EnMinislime_Destroy.asm")
|
||||
Collider_DestroyCylinder(globalCtx, &this->collider);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_8098399C.asm")
|
||||
void EnMinislime_CheckBackgroundCollision(EnMinislime* this) {
|
||||
f32 scaleX = this->actor.scale.x * 400.0f;
|
||||
f32 scaleY = this->actor.scale.y * 400.0f;
|
||||
f32 scaleZ = this->actor.scale.z * 400.0f;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80983B38.asm")
|
||||
this->actor.bgCheckFlags &= ~(0x10 | 0x8 | 0x2);
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80983DBC.asm")
|
||||
if ((this->actor.world.pos.y + scaleY) > GBT_ROOM_5_MAX_Y) {
|
||||
this->actor.bgCheckFlags |= 0x10;
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
this->actor.world.pos.y = GBT_ROOM_5_MAX_Y - scaleY;
|
||||
} else if ((this->actor.world.pos.y - scaleY) < GBT_ROOM_5_MIN_Y) {
|
||||
this->actor.world.pos.y = GBT_ROOM_5_MIN_Y + scaleY;
|
||||
if (!(this->actor.bgCheckFlags & 1)) {
|
||||
this->actor.bgCheckFlags |= 2;
|
||||
}
|
||||
this->actor.bgCheckFlags |= 1;
|
||||
} else {
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80983E9C.asm")
|
||||
if ((this->actor.world.pos.x + scaleX) > GBT_ROOM_5_MAX_X) {
|
||||
this->actor.bgCheckFlags |= 8;
|
||||
this->actor.world.pos.x = GBT_ROOM_5_MAX_X - scaleX;
|
||||
} else if ((this->actor.world.pos.x - scaleX) < GBT_ROOM_5_MIN_X) {
|
||||
this->actor.world.pos.x = GBT_ROOM_5_MIN_X + scaleX;
|
||||
this->actor.bgCheckFlags |= 8;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80983EB4.asm")
|
||||
if ((this->actor.world.pos.z + scaleZ) > GBT_ROOM_5_MAX_Z) {
|
||||
this->actor.bgCheckFlags |= 8;
|
||||
this->actor.world.pos.z = GBT_ROOM_5_MAX_Z - scaleZ;
|
||||
} else if ((this->actor.world.pos.z - scaleZ) < GBT_ROOM_5_MIN_Z) {
|
||||
this->actor.world.pos.z = GBT_ROOM_5_MIN_Z + scaleZ;
|
||||
this->actor.bgCheckFlags |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80983F1C.asm")
|
||||
void EnMinislime_AddIceShardEffect(EnMinislime* this) {
|
||||
EnBigslime* bigslime = (EnBigslime*)this->actor.parent;
|
||||
EnBigslimeIceShardEffect* iceShardEffect;
|
||||
s32 i = 10 * this->id + BIGSLIME_NUM_VTX;
|
||||
s32 i_end = i + 10;
|
||||
VecSph vecSph;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984030.asm")
|
||||
vecSph.yaw = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_809840A8.asm")
|
||||
for (; i < i_end; i++) {
|
||||
iceShardEffect = &bigslime->iceShardEffect[i];
|
||||
vecSph.pitch = Rand_S16Offset(0x1000, 0x3000);
|
||||
iceShardEffect->vel.x = Math_CosS(vecSph.pitch) * Math_SinS(vecSph.yaw);
|
||||
iceShardEffect->vel.y = Math_SinS(vecSph.pitch);
|
||||
iceShardEffect->vel.z = Math_CosS(vecSph.pitch) * Math_CosS(vecSph.yaw);
|
||||
iceShardEffect->pos.x = this->actor.world.pos.x + (400.0f * this->actor.scale.x) * iceShardEffect->vel.x;
|
||||
iceShardEffect->pos.y =
|
||||
this->actor.world.pos.y + (((iceShardEffect->vel.y * 2.0f) - 1.0f) * 400.0f * this->actor.scale.y);
|
||||
iceShardEffect->pos.z = this->actor.world.pos.z + (400.0f * this->actor.scale.z) * iceShardEffect->vel.z;
|
||||
iceShardEffect->rotation.x = Rand_Next() >> 0x10;
|
||||
iceShardEffect->rotation.y = Rand_Next() >> 0x10;
|
||||
iceShardEffect->rotation.z = Rand_Next() >> 0x10;
|
||||
iceShardEffect->isActive = true;
|
||||
Math_Vec3f_ScaleAndStore(&iceShardEffect->vel, Rand_ZeroFloat(3.0f) + 7.0f, &iceShardEffect->vel);
|
||||
iceShardEffect->scale = (Rand_ZeroFloat(6.0f) + 2.0f) * 0.001f;
|
||||
vecSph.yaw += 0x1999;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_8098419C.asm")
|
||||
this->frozenAlpha = 0;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_8098420C.asm")
|
||||
void EnMinislime_AddIceSmokeEffect(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
Vec3f pos;
|
||||
Vec3f vel;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984248.asm")
|
||||
pos.x = (randPlusMinusPoint5Scaled(200.0f) * this->actor.scale.x) + this->actor.world.pos.x;
|
||||
pos.y = CLAMP_MIN(this->actor.world.pos.y, GBT_ROOM_5_MIN_Y + 30.0f);
|
||||
pos.z = (randPlusMinusPoint5Scaled(200.0f) * this->actor.scale.z) + this->actor.world.pos.z;
|
||||
vel.x = randPlusMinusPoint5Scaled(1.5f);
|
||||
vel.z = randPlusMinusPoint5Scaled(1.5f);
|
||||
vel.y = 2.0f;
|
||||
EffectSsIceSmoke_Spawn(globalCtx, &pos, &vel, &D_801D15B0, 500);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984410.asm")
|
||||
void EnMinislime_SetupDisappear(EnMinislime* this) {
|
||||
this->actor.params = MINISLIME_DISAPPEAR;
|
||||
this->actionFunc = EnMinislime_Disappear;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984450.asm")
|
||||
void EnMinislime_Disappear(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
if (this->actor.params == MINISLIME_BREAK_BIGSLIME) {
|
||||
EnMinislime_SetupBreakFromBigslime(this);
|
||||
} else if (this->actor.params == MINISLIME_INIT_FALL) {
|
||||
EnMinislime_SetupFall(this, globalCtx);
|
||||
} else if (this->actor.params == MINISLIME_DESPAWN) {
|
||||
EnMinislime_SetupDespawn(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_809844FC.asm")
|
||||
void EnMinislime_SetupFall(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
s16 yaw;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_809845A4.asm")
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->collider.base.ocFlags1 |= OC1_ON;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actor.gravity = -2.0f;
|
||||
if (this->actionFunc != EnMinislime_GekkoThrow) {
|
||||
this->actor.scale.x = 0.095f;
|
||||
this->actor.scale.z = 0.095f;
|
||||
this->actor.scale.y = 0.10700001f;
|
||||
if (Actor_XZDistanceBetweenActors(&this->actor, &player->actor) < 225.0f) {
|
||||
yaw = Actor_YawBetweenActors(&player->actor, &this->actor);
|
||||
this->actor.world.pos.x = Math_SinS(yaw) * 225.0f + player->actor.world.pos.x;
|
||||
this->actor.world.pos.z = Math_CosS(yaw) * 225.0f + player->actor.world.pos.z;
|
||||
}
|
||||
}
|
||||
this->actionFunc = EnMinislime_Fall;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_8098470C.asm")
|
||||
void EnMinislime_Fall(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
Math_StepToF(&this->actor.scale.x, 0.17999999f, 0.003f);
|
||||
Math_StepToF(&this->actor.scale.y, 0.05f, 0.003f);
|
||||
this->actor.scale.z = this->actor.scale.x;
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
EnMinislime_SetupGrowAndShrink(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984748.asm")
|
||||
void EnMinislime_SetupBreakFromBigslime(EnMinislime* this) {
|
||||
f32 velY;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984964.asm")
|
||||
this->actor.world.rot.y = Actor_YawBetweenActors(this->actor.parent, &this->actor);
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
this->actor.speedXZ = Math_CosS(this->actor.world.rot.x) * 15.0f;
|
||||
velY = Math_SinS(this->actor.world.rot.x) * 15.0f;
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
this->actor.velocity.y = velY + 2.0f;
|
||||
this->actor.gravity = -1.0f;
|
||||
this->frozenScale = 0.1f;
|
||||
this->actor.world.rot.x = Rand_S16Offset(0x800, 0x800);
|
||||
this->actor.shape.rot.x = (s16)(Rand_Next() >> 0x10);
|
||||
this->actor.shape.rot.z = (s16)(Rand_Next() >> 0x10);
|
||||
this->actor.scale.x = 0.15f;
|
||||
this->actor.scale.y = 0.075f;
|
||||
this->actor.scale.z = 0.15f;
|
||||
this->frozenAlpha = 200;
|
||||
this->actionFunc = EnMinislime_BreakFromBigslime;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_809849C4.asm")
|
||||
void EnMinislime_BreakFromBigslime(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
this->actor.shape.rot.x += this->actor.world.rot.x;
|
||||
if (this->actor.velocity.y < 0.0f) {
|
||||
this->collider.base.ocFlags1 |= OC1_ON;
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
EnMinislime_AddIceShardEffect(this);
|
||||
this->attackTimer = 40;
|
||||
EnMinislime_SetupGrowAndShrink(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984B34.asm")
|
||||
void EnMinislime_SetupIceArrowDamage(EnMinislime* this) {
|
||||
this->collider.base.atFlags &= ~AT_ON;
|
||||
this->frozenTimer = 80;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->frozenScale = 0.1f;
|
||||
this->actionFunc = EnMinislime_IceArrowDamage;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984C28.asm")
|
||||
void EnMinislime_IceArrowDamage(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
f32 invFrozenTimer;
|
||||
s32 pad;
|
||||
f32 randFloat;
|
||||
s32 randSign;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984CA8.asm")
|
||||
if (this->frozenTimer == 80) {
|
||||
this->frozenAlpha += 10;
|
||||
func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG);
|
||||
if (this->frozenAlpha >= 200) {
|
||||
this->frozenAlpha = 200;
|
||||
this->frozenTimer--;
|
||||
}
|
||||
} else if (this->frozenTimer > 0) {
|
||||
this->frozenTimer--;
|
||||
if (this->frozenTimer == 40) {
|
||||
Math_Vec3f_Copy(&this->shakeRefPos, &this->actor.world.pos);
|
||||
} else if (this->frozenTimer > 0) {
|
||||
if ((this->frozenTimer < 20) || ((this->frozenTimer < 40) && ((this->frozenTimer % 2) != 0))) {
|
||||
invFrozenTimer = 1.0f / this->frozenTimer;
|
||||
randFloat = Rand_ZeroFloat(invFrozenTimer);
|
||||
randSign = Rand_ZeroOne() < 0.5f ? -1 : 1;
|
||||
this->actor.world.pos.x = randSign * (invFrozenTimer + randFloat) + this->shakeRefPos.x;
|
||||
randFloat = Rand_ZeroFloat(invFrozenTimer);
|
||||
randSign = Rand_ZeroOne() < 0.5f ? -1 : 1;
|
||||
this->actor.world.pos.z = randSign * (invFrozenTimer + randFloat) + this->shakeRefPos.z;
|
||||
dummy:; // required for match
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EnMinislime_AddIceShardEffect(this);
|
||||
EnMinislime_SetupIdle(this);
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984D08.asm")
|
||||
if (this->actor.bgCheckFlags & 2) {
|
||||
EnMinislime_AddIceShardEffect(this);
|
||||
EnMinislime_SetupGrowAndShrink(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984E38.asm")
|
||||
void EnMinislime_SetupFireArrowDamage(EnMinislime* this) {
|
||||
this->meltTimer = 40;
|
||||
this->actor.shape.rot.x = 0;
|
||||
this->actor.shape.rot.y = 0;
|
||||
this->actor.shape.rot.z = 0;
|
||||
this->actor.world.rot.x = 0;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnMinislime_FireArrowDamage;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80984ECC.asm")
|
||||
void EnMinislime_FireArrowDamage(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
this->meltTimer--;
|
||||
if ((this->meltTimer % 25) == 0) {
|
||||
EnMinislime_AddIceSmokeEffect(this, globalCtx);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80985018.asm")
|
||||
this->frozenScale = this->meltTimer * 0.0025f;
|
||||
if ((10 * this->meltTimer) > 200) {
|
||||
this->frozenAlpha = 200;
|
||||
} else {
|
||||
this->frozenAlpha = 10 * this->meltTimer;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80985088.asm")
|
||||
func_800B9010(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG);
|
||||
if (this->meltTimer == 0) {
|
||||
EnMinislime_SetupIdle(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80985154.asm")
|
||||
void EnMinislime_SetupGrowAndShrink(EnMinislime* this) {
|
||||
this->collider.base.ocFlags1 |= OC1_ON;
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->actor.shape.rot.x = 0;
|
||||
this->actor.shape.rot.y = 0;
|
||||
this->actor.shape.rot.z = 0;
|
||||
this->actor.world.rot.x = 0;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos);
|
||||
this->growShrinkTimer = 42;
|
||||
this->actor.scale.x = 0.19f;
|
||||
this->actor.scale.y = 0.044999998f;
|
||||
this->actor.scale.z = 0.19f;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_SLIME_JUMP2);
|
||||
this->actionFunc = EnMinislime_GrowAndShrink;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80985168.asm")
|
||||
void EnMinislime_GrowAndShrink(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
f32 scaleFactor;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_8098518C.asm")
|
||||
this->growShrinkTimer--;
|
||||
scaleFactor = (this->growShrinkTimer / 6) + 1.0f;
|
||||
this->actor.scale.z = this->actor.scale.x =
|
||||
((cos_rad(this->growShrinkTimer * (M_PI / 3)) * (scaleFactor * (2.0f / 30.0f))) + 1.5f) * 0.1f;
|
||||
this->actor.scale.y = ((sin_rad(this->growShrinkTimer * (M_PI / 3)) * (scaleFactor * 0.05f)) + 0.75f) * 0.1f;
|
||||
if (this->actor.params == MINISLIME_SETUP_GEKKO_THROW) {
|
||||
EnMinislime_SetupMoveToGekko(this);
|
||||
} else if ((this->actor.xzDistToPlayer < 150.0f) && (this->growShrinkTimer < 38)) {
|
||||
EnMinislime_SetupBounce(this);
|
||||
} else if (this->growShrinkTimer == 0) {
|
||||
EnMinislime_SetupIdle(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_809851E8.asm")
|
||||
void EnMinislime_SetupIdle(EnMinislime* this) {
|
||||
this->idleTimer = 20;
|
||||
this->collider.base.atFlags |= AT_ON;
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->actor.params = MINISLIME_IDLE;
|
||||
this->actionFunc = EnMinislime_Idle;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_809852DC.asm")
|
||||
void EnMinislime_Idle(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
f32 speedXZ;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_8098537C.asm")
|
||||
this->idleTimer--;
|
||||
speedXZ = sin_rad(this->idleTimer * (M_PI / 10));
|
||||
this->actor.speedXZ = speedXZ * 1.5f;
|
||||
this->actor.speedXZ = CLAMP_MIN(this->actor.speedXZ, 0.0f);
|
||||
Math_StepToF(&this->actor.scale.x, ((0.14f * speedXZ) + 1.5f) * 0.1f, 0.010000001f);
|
||||
Math_StepToF(&this->actor.scale.y, ((cos_rad(this->idleTimer * (M_PI / 10)) * 0.07f) + 0.75f) * 0.1f, 0.010000001f);
|
||||
Math_StepToF(&this->actor.scale.z, 0.3f - this->actor.scale.x, 0.010000001f);
|
||||
if (this->idleTimer == 0) {
|
||||
if (this->actor.xzDistToPlayer < 300.0f) {
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
} else {
|
||||
if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 200.0f) {
|
||||
this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
|
||||
} else {
|
||||
this->actor.world.rot.y += (s16)(Rand_Next() >> 19);
|
||||
}
|
||||
}
|
||||
this->idleTimer = 20;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/func_80985480.asm")
|
||||
if (this->actor.params == MINISLIME_SETUP_GEKKO_THROW) {
|
||||
EnMinislime_SetupMoveToGekko(this);
|
||||
} else if (this->actor.xzDistToPlayer < 150.0f) {
|
||||
EnMinislime_SetupBounce(this);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Minislime_0x809838F0/EnMinislime_Update.asm")
|
||||
void EnMinislime_SetupBounce(EnMinislime* this) {
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->bounceTimer = (this->actionFunc == EnMinislime_GrowAndShrink) ? 1 : 4;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_SLIME_JUMP1);
|
||||
this->actionFunc = EnMinislime_Bounce;
|
||||
}
|
||||
|
||||
void EnMinislime_Bounce(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
if (this->actor.params == MINISLIME_SETUP_GEKKO_THROW) {
|
||||
EnMinislime_SetupMoveToGekko(this);
|
||||
} else {
|
||||
if (this->bounceTimer > 0) {
|
||||
this->bounceTimer--;
|
||||
if (this->bounceTimer == 0) {
|
||||
this->actor.gravity = -2.0f;
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
this->actor.speedXZ = 1.0f;
|
||||
this->actor.velocity.y = 12.0f;
|
||||
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||
}
|
||||
Math_StepToF(&this->actor.scale.x, 0.17999999f, 0.010000001f);
|
||||
Math_StepToF(&this->actor.scale.y, 0.05f, 0.010000001f);
|
||||
} else if (this->actor.velocity.y > 0.0f) {
|
||||
Math_StepToF(&this->actor.scale.x, 0.095f, 0.020000001f);
|
||||
Math_StepToF(&this->actor.scale.y, 0.10700001f, 0.020000001f);
|
||||
} else {
|
||||
Math_StepToF(&this->actor.scale.x, 0.17999999f, 0.003f);
|
||||
Math_StepToF(&this->actor.scale.y, 0.05f, 0.003f);
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
EnMinislime_SetupGrowAndShrink(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->actor.scale.z = this->actor.scale.x;
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_SetupMoveToBigslime(EnMinislime* this) {
|
||||
this->actor.gravity = 0.0f;
|
||||
this->actor.speedXZ = 15.0f;
|
||||
this->actor.shape.rot.x = Actor_PitchToPoint(&this->actor, &this->actor.parent->home.pos);
|
||||
this->actor.shape.rot.y = Actor_YawToPoint(&this->actor, &this->actor.parent->home.pos);
|
||||
this->actor.world.rot.x = -this->actor.shape.rot.x;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
this->collider.base.atFlags &= ~AT_ON;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->collider.base.ocFlags1 &= ~OC1_ON;
|
||||
this->actor.scale.x = 0.095f;
|
||||
this->actor.scale.y = 0.095f;
|
||||
this->actor.scale.z = 0.15f;
|
||||
if (this->frozenAlpha > 20) {
|
||||
EnMinislime_AddIceShardEffect(this);
|
||||
}
|
||||
this->frozenAlpha = 0;
|
||||
|
||||
if ((this->actor.flags & 0x2000) == 0x2000) {
|
||||
this->actor.flags &= ~0x2000;
|
||||
}
|
||||
this->actionFunc = EnMinislime_MoveToBigslime;
|
||||
}
|
||||
|
||||
void EnMinislime_MoveToBigslime(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
if (this->actor.params == MINISLIME_DISAPPEAR) {
|
||||
EnMinislime_SetupDisappear(this);
|
||||
} else if ((this->actor.scale.x > 0.0f) && (this->actor.world.pos.y > (GBT_ROOM_5_MAX_Y - 100.0f))) {
|
||||
this->actor.params = MINISLIME_SETUP_DISAPPEAR;
|
||||
this->actor.speedXZ = 0.0f;
|
||||
Actor_SetScale(&this->actor, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_SetupKnockback(EnMinislime* this) {
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->collider.base.ocFlags1 |= OC1_ON;
|
||||
this->knockbackTimer = 30;
|
||||
this->actor.speedXZ = 20.0f;
|
||||
func_800BE504(&this->actor, &this->collider);
|
||||
this->actionFunc = EnMinislime_Knockback;
|
||||
}
|
||||
|
||||
void EnMinislime_Knockback(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
f32 sqrtFrozenTimer;
|
||||
|
||||
this->knockbackTimer--;
|
||||
Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f);
|
||||
sqrtFrozenTimer = sqrtf(this->knockbackTimer);
|
||||
this->actor.scale.x = ((cos_rad(this->knockbackTimer * (M_PI / 3)) * (0.05f * sqrtFrozenTimer)) + 1.0f) * 0.15f;
|
||||
this->actor.scale.z = this->actor.scale.x;
|
||||
if (this->knockbackTimer == 15) {
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
}
|
||||
|
||||
this->actor.scale.y = ((sin_rad(this->knockbackTimer * (M_PI / 3)) * (0.05f * sqrtFrozenTimer)) + 1.0f) * 0.075f;
|
||||
if (this->actor.params == MINISLIME_SETUP_GEKKO_THROW) {
|
||||
EnMinislime_SetupMoveToGekko(this);
|
||||
} else if (this->knockbackTimer == 0) {
|
||||
EnMinislime_SetupIdle(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_SetupDefeatIdle(EnMinislime* this) {
|
||||
this->actor.params = MINISLIME_DISAPPEAR;
|
||||
this->idleTimer = 20;
|
||||
this->collider.base.atFlags &= ~(AT_ON | AT_HIT);
|
||||
this->collider.base.acFlags &= ~(AC_ON | AC_HIT);
|
||||
this->actor.speedXZ = 0.0f;
|
||||
if (this->frozenAlpha > 20) {
|
||||
EnMinislime_AddIceShardEffect(this);
|
||||
}
|
||||
|
||||
this->frozenAlpha = 0;
|
||||
if ((this->actor.flags & 0x2000) == 0x2000) {
|
||||
this->actor.flags &= ~0x2000;
|
||||
}
|
||||
|
||||
this->actor.shape.rot.x = 0;
|
||||
this->actor.shape.rot.z = 0;
|
||||
this->actionFunc = EnMinislime_DefeatIdle;
|
||||
}
|
||||
|
||||
void EnMinislime_DefeatIdle(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
f32 xzScale;
|
||||
|
||||
this->idleTimer--;
|
||||
xzScale = sin_rad(this->idleTimer * (M_PI / 10));
|
||||
Math_StepToF(&this->actor.scale.x, ((0.14f * xzScale) + 1.5f) * 0.1f, 0.010000001f);
|
||||
Math_StepToF(&this->actor.scale.y, ((0.07f * cos_rad(this->idleTimer * (M_PI / 10))) + 0.75f) * 0.1f, 0.010000001f);
|
||||
Math_StepToF(&this->actor.scale.z, 0.3f - this->actor.scale.x, 0.010000001f);
|
||||
if (this->idleTimer == 0) {
|
||||
this->idleTimer = 20;
|
||||
}
|
||||
|
||||
if (this->actor.params == MINISLIME_DEFEAT_MELT) {
|
||||
EnMinislime_SetupDefeatMelt(this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_SetupDefeatMelt(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
this->actor.gravity = 0.0f;
|
||||
this->actor.velocity.y = -50.0f;
|
||||
this->meltTimer = Rand_ZeroFloat(25.0f);
|
||||
EnMinislime_AddIceSmokeEffect(this, globalCtx);
|
||||
this->actor.params = MINISLIME_DISAPPEAR;
|
||||
this->actionFunc = EnMinislime_DefeatMelt;
|
||||
}
|
||||
|
||||
void EnMinislime_DefeatMelt(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
this->meltTimer++;
|
||||
if (((this->meltTimer % 25) == 0) && (this->actor.shape.shadowAlpha > 25)) {
|
||||
EnMinislime_AddIceSmokeEffect(this, globalCtx);
|
||||
}
|
||||
|
||||
func_800B9010(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG);
|
||||
if (Math_StepToF(&this->actor.scale.y, 0.001f, 0.00075f)) {
|
||||
if ((this->actor.shape.shadowAlpha - 4) <= 0) {
|
||||
this->actor.shape.shadowAlpha = 0;
|
||||
EnMinislime_SetupDisappear(this);
|
||||
} else {
|
||||
this->actor.shape.shadowAlpha -= 4;
|
||||
}
|
||||
}
|
||||
Math_StepToF(&this->actor.scale.x, 0.25f, 0.001f);
|
||||
this->actor.scale.z = this->actor.scale.x;
|
||||
}
|
||||
|
||||
void EnMinislime_SetupDespawn(EnMinislime* this) {
|
||||
this->actionFunc = EnMinislime_Despawn;
|
||||
}
|
||||
|
||||
void EnMinislime_Despawn(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
}
|
||||
|
||||
void EnMinislime_SetupMoveToGekko(EnMinislime* this) {
|
||||
this->actor.speedXZ = 0.0f;
|
||||
this->actor.gravity = 0.0f;
|
||||
this->actor.velocity.y = 0.0f;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->collider.base.ocFlags1 &= ~OC1_ON;
|
||||
if ((this->actor.flags & 0x2000) == 0x2000) {
|
||||
this->actor.flags &= ~0x2000;
|
||||
}
|
||||
|
||||
this->actionFunc = EnMinislime_MoveToGekko;
|
||||
}
|
||||
|
||||
void EnMinislime_MoveToGekko(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
Math_StepToF(&this->actor.world.pos.x, this->actor.parent->world.pos.x, 10.0f);
|
||||
Math_StepToF(&this->actor.world.pos.z, this->actor.parent->world.pos.z, 10.0f);
|
||||
Math_StepToF(&this->actor.world.pos.y, this->actor.parent->world.pos.y + 80.0f, 10.0f);
|
||||
Math_StepToF(&this->actor.scale.x, 0.15f, 0.0075000003f);
|
||||
Math_StepToF(&this->actor.scale.y, 0.075f, 0.0037500001f);
|
||||
Math_StepToF(&this->actor.scale.z, 0.15f, 0.0075000003f);
|
||||
if (this->actor.params == MINISLIME_GEKKO_THROW) {
|
||||
EnMinislime_SetupGekkoThrow(this);
|
||||
} else if (this->actor.params == MINISLIME_IDLE) {
|
||||
EnMinislime_SetupFall(this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_SetupGekkoThrow(EnMinislime* this) {
|
||||
f32 xzDistToPlayer;
|
||||
|
||||
this->collider.base.acFlags |= AC_ON;
|
||||
this->collider.base.ocFlags1 |= OC1_ON;
|
||||
xzDistToPlayer = CLAMP_MIN(this->actor.xzDistToPlayer, 200.0f);
|
||||
this->actor.speedXZ = 17.5f;
|
||||
this->actor.world.rot.y = this->actor.yawTowardsPlayer;
|
||||
this->actor.gravity = -1.0f;
|
||||
this->actor.velocity.y = ((xzDistToPlayer - 200.0f) * 0.01f) + 3.0f;
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
this->throwTimer = 10;
|
||||
this->actionFunc = EnMinislime_GekkoThrow;
|
||||
}
|
||||
|
||||
void EnMinislime_GekkoThrow(EnMinislime* this, GlobalContext* globalCtx) {
|
||||
f32 xzScale;
|
||||
|
||||
this->throwTimer--;
|
||||
xzScale = sin_rad(this->throwTimer * (M_PI / 5));
|
||||
this->actor.scale.x = ((0.3f * xzScale) + 1.5f) * 0.1f;
|
||||
this->actor.scale.y = ((cos_rad(this->throwTimer * (M_PI / 5)) * 0.2f) + 0.75f) * 0.1f;
|
||||
this->actor.scale.z = 0.3f - this->actor.scale.x;
|
||||
if (this->throwTimer == 0) {
|
||||
this->throwTimer = 10;
|
||||
}
|
||||
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
EnMinislime_SetupGrowAndShrink(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_ApplyDamage(EnMinislime* this) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
this->collider.base.acFlags &= ~AC_HIT;
|
||||
if (this->actionFunc == EnMinislime_IceArrowDamage) {
|
||||
if (this->actor.colChkInfo.damageEffect != MINISLIME_DMGEFF_HOOKSHOT) {
|
||||
if (this->actor.colChkInfo.damageEffect == MINISLIME_DMGEFF_BREAK_ICE) {
|
||||
EnMinislime_AddIceShardEffect(this);
|
||||
EnMinislime_SetupIdle(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == MINISLIME_DMGEFF_FIRE) {
|
||||
EnMinislime_SetupFireArrowDamage(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this->actor.colChkInfo.damageEffect != MINISLIME_DMGEFF_HOOKSHOT) {
|
||||
if (this->actor.colChkInfo.damageEffect == MINISLIME_DMGEFF_ICE) {
|
||||
EnMinislime_SetupIceArrowDamage(this);
|
||||
} else {
|
||||
EnMinislime_SetupKnockback(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnMinislime_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnMinislime* this = THIS;
|
||||
Player* player;
|
||||
s32 pad;
|
||||
Vec3f vec1;
|
||||
|
||||
if ((this->actor.params == MINISLIME_DEFEAT_IDLE) && (this->actor.bgCheckFlags & 1)) {
|
||||
EnMinislime_SetupDefeatIdle(this);
|
||||
} else if (this->actor.params == MINISLIME_DEFEAT_MELT) {
|
||||
EnMinislime_SetupDefeatMelt(this, globalCtx);
|
||||
} else if ((this->actor.params == MINISLIME_FORM_BIGSLIME) && (this->actionFunc != EnMinislime_MoveToBigslime)) {
|
||||
EnMinislime_SetupMoveToBigslime(this);
|
||||
} else {
|
||||
if ((this->actor.flags & 0x2000) == 0x2000) {
|
||||
this->collider.base.acFlags &= ~AC_HIT;
|
||||
return;
|
||||
}
|
||||
EnMinislime_ApplyDamage(this);
|
||||
}
|
||||
|
||||
if (this->collider.base.atFlags & AT_HIT) {
|
||||
this->attackTimer = 10;
|
||||
this->collider.base.atFlags &= ~AT_HIT;
|
||||
}
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
|
||||
if ((this->actionFunc != EnMinislime_Disappear) && (this->actionFunc != EnMinislime_Despawn)) {
|
||||
if (this->actionFunc == EnMinislime_MoveToBigslime) {
|
||||
Actor_SetVelocityAndMoveXYRotation(&this->actor);
|
||||
} else {
|
||||
Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
|
||||
}
|
||||
|
||||
EnMinislime_CheckBackgroundCollision(this);
|
||||
Collider_UpdateCylinder(&this->actor, &this->collider);
|
||||
this->collider.dim.radius = this->actor.scale.x * 360.0f;
|
||||
this->collider.dim.height = this->actor.scale.y * 800.0f;
|
||||
this->collider.dim.yShift = ((EnMinislime*)thisx)->actor.scale.y * -400.0f;
|
||||
|
||||
if ((this->attackTimer == 0) && (this->collider.base.atFlags & AT_ON)) {
|
||||
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->attackTimer != 0) {
|
||||
this->attackTimer--;
|
||||
}
|
||||
|
||||
if (this->actor.bgCheckFlags & 2) {
|
||||
player = PLAYER;
|
||||
vec1.x = this->actor.world.pos.x;
|
||||
vec1.z = this->actor.world.pos.z;
|
||||
vec1.y = player->actor.world.pos.y + player->actor.yDistToWater;
|
||||
EffectSsGRipple_Spawn(globalCtx, &vec1, 500, 720, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,49 @@
|
||||
|
||||
struct EnMinislime;
|
||||
|
||||
typedef void (*EnMinislimeActionFunc)(struct EnMinislime*, GlobalContext*);
|
||||
|
||||
#define MINISLIME_NUM_SPAWN 15
|
||||
|
||||
typedef enum {
|
||||
/* 0x0 */ MINISLIME_DISAPPEAR, // Either Bigslime is active or Gekko is defeated
|
||||
/* 0x1 */ MINISLIME_INIT_FALL, // Initial fall when Gekko first calls
|
||||
/* 0x2 */ MINISLIME_BREAK_BIGSLIME,
|
||||
/* 0x3 */ MINISLIME_IDLE,
|
||||
/* 0x4 */ MINISLIME_FORM_BIGSLIME,
|
||||
/* 0x5 */ MINISLIME_SETUP_DISAPPEAR,
|
||||
/* 0x6 */ MINISLIME_UNUSED,
|
||||
/* 0x7 */ MINISLIME_DEFEAT_IDLE,
|
||||
/* 0x8 */ MINISLIME_DEFEAT_MELT,
|
||||
/* 0x9 */ MINISLIME_DESPAWN,
|
||||
/* 0xA */ MINISLIME_SETUP_GEKKO_THROW,
|
||||
/* 0xB */ MINISLIME_GEKKO_THROW,
|
||||
} EnMinislimeState;
|
||||
|
||||
typedef enum {
|
||||
/* 0x0 */ MINISLIME_INACTIVE_STATE,
|
||||
/* 0x1 */ MINISLIME_ACTIVE_CONTINUE_STATE,
|
||||
/* 0x2 */ MINISLIME_ACTIVE_INIT_STATE,
|
||||
} EnMinislimeActiveState;
|
||||
|
||||
typedef struct EnMinislime {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ char unk_144[0x68];
|
||||
/* 0x144 */ EnMinislimeActionFunc actionFunc;
|
||||
/* 0x148 */ u8 frozenAlpha;
|
||||
/* 0x149 */ u8 id; // 0-14, each of the 15 minislimes gets a unique number
|
||||
/* 0x14A */ union {
|
||||
s16 frozenTimer;
|
||||
s16 bounceTimer;
|
||||
s16 growShrinkTimer;
|
||||
s16 idleTimer;
|
||||
s16 knockbackTimer;
|
||||
s16 meltTimer;
|
||||
s16 throwTimer;
|
||||
};
|
||||
/* 0x14C */ s16 attackTimer;
|
||||
/* 0x150 */ f32 frozenScale;
|
||||
/* 0x154 */ Vec3f shakeRefPos;
|
||||
/* 0x160 */ ColliderCylinder collider;
|
||||
} EnMinislime; // size = 0x1AC
|
||||
|
||||
extern const ActorInit En_Minislime_InitVars;
|
||||
|
||||
@@ -280,8 +280,8 @@ void EnNiw_SpawnAttackNiw(EnNiw* this, GlobalContext* globalCtx) {
|
||||
newNiwPos.x = ((Rand_ZeroOne() - 0.5f) * xView) + globalCtx->view.eye.x;
|
||||
newNiwPos.y = randPlusMinusPoint5Scaled(0.3f) + (globalCtx->view.eye.y + 50.0f + (yView * 0.5f));
|
||||
newNiwPos.z = ((Rand_ZeroOne() - 0.5f) * zView) + globalCtx->view.eye.z;
|
||||
attackNiw = Actor_SpawnWithParent(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ATTACK_NIW,
|
||||
newNiwPos.x, newNiwPos.y, newNiwPos.z, 0, 0, 0, 0);
|
||||
attackNiw = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ATTACK_NIW, newNiwPos.x,
|
||||
newNiwPos.y, newNiwPos.z, 0, 0, 0, 0);
|
||||
|
||||
if (attackNiw) {
|
||||
this->unk290++;
|
||||
|
||||
@@ -55,8 +55,8 @@ void EnPametfrog_JumpToLink(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_SetupMeleeAttack(EnPametfrog* this);
|
||||
void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_SetupCutscene(EnPametfrog* this);
|
||||
void func_8086CC04(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void func_8086CD04(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_Damage(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_Stun(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_SetupCallSnapper(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_CallSnapper(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
void EnPametfrog_SetupSnapperSpawn(EnPametfrog* this, GlobalContext* globalCtx);
|
||||
@@ -98,39 +98,48 @@ const ActorInit En_Pametfrog_InitVars = {
|
||||
(ActorFunc)EnPametfrog_Draw,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
/* 0x0 */ GEKKO_DMGEFF_NONE,
|
||||
/* 0x1 */ GEKKO_DMGEFF_STUN,
|
||||
/* 0x2 */ GEKKO_DMGEFF_FIRE,
|
||||
/* 0x3 */ GEKKO_DMGEFF_ICE,
|
||||
/* 0x4 */ GEKKO_DMGEFF_LIGHT,
|
||||
/* 0x5 */ GEKKO_DMGEFF_ZORA_BARRIER,
|
||||
} EnPametfrogDamageEffect;
|
||||
|
||||
static DamageTable sDamageTable = {
|
||||
/* 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, 0x1),
|
||||
/* Goron punch */ DMG_ENTRY(1, 0x0),
|
||||
/* Sword */ DMG_ENTRY(1, 0x0),
|
||||
/* Goron pound */ DMG_ENTRY(1, 0x0),
|
||||
/* Fire arrow */ DMG_ENTRY(2, 0x2),
|
||||
/* Ice arrow */ DMG_ENTRY(2, 0x3),
|
||||
/* Light arrow */ DMG_ENTRY(2, 0x4),
|
||||
/* Goron spikes */ DMG_ENTRY(1, 0x0),
|
||||
/* Deku spin */ DMG_ENTRY(0, 0x1),
|
||||
/* 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(1, 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),
|
||||
/* Deku Nut */ DMG_ENTRY(0, GEKKO_DMGEFF_STUN),
|
||||
/* Deku Stick */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Horse trample */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* Explosives */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Zora boomerang */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Normal arrow */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x06 */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* Hookshot */ DMG_ENTRY(0, GEKKO_DMGEFF_STUN),
|
||||
/* Goron punch */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Sword */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Goron pound */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Fire arrow */ DMG_ENTRY(2, GEKKO_DMGEFF_FIRE),
|
||||
/* Ice arrow */ DMG_ENTRY(2, GEKKO_DMGEFF_ICE),
|
||||
/* Light arrow */ DMG_ENTRY(2, GEKKO_DMGEFF_LIGHT),
|
||||
/* Goron spikes */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Deku spin */ DMG_ENTRY(0, GEKKO_DMGEFF_STUN),
|
||||
/* Deku bubble */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Deku launch */ DMG_ENTRY(2, GEKKO_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x12 */ DMG_ENTRY(0, GEKKO_DMGEFF_STUN),
|
||||
/* Zora barrier */ DMG_ENTRY(0, GEKKO_DMGEFF_ZORA_BARRIER),
|
||||
/* Normal shield */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* Light ray */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* Thrown object */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Zora punch */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Spin attack */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Sword beam */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
/* Normal Roll */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1B */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1C */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* Unblockable */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* UNK_DMG_0x1E */ DMG_ENTRY(0, GEKKO_DMGEFF_NONE),
|
||||
/* Powder Keg */ DMG_ENTRY(1, GEKKO_DMGEFF_NONE),
|
||||
};
|
||||
|
||||
static ColliderJntSphElementInit sJntSphElementsInit[2] = {
|
||||
@@ -213,12 +222,12 @@ void EnPametfrog_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius;
|
||||
}
|
||||
|
||||
if (Actor_SpawnWithParent(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BIGPAMET,
|
||||
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0,
|
||||
0) == NULL) {
|
||||
if (Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BIGPAMET,
|
||||
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0,
|
||||
0) == NULL) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
} else {
|
||||
this->actor.params = ENPAMETFROG_PRE_SNAPPER;
|
||||
this->actor.params = GEKKO_PRE_SNAPPER;
|
||||
EnPametfrog_SetupLookAround(this);
|
||||
}
|
||||
}
|
||||
@@ -241,8 +250,8 @@ u8 EnPametfrog_Vec3fNormalize(Vec3f* vec) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_8086A024(EnPametfrog* this) {
|
||||
this->mode = 10;
|
||||
void EnPametfrog_ChangeColliderFreeze(EnPametfrog* this) {
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_FROZEN;
|
||||
this->collider.base.colType = COLTYPE_HIT3;
|
||||
this->collider.elements->info.elemType = ELEMTYPE_UNK0;
|
||||
this->unk_2C8 = 0.75f;
|
||||
@@ -250,14 +259,14 @@ void func_8086A024(EnPametfrog* this) {
|
||||
this->unk_2C4 = 1.0f;
|
||||
}
|
||||
|
||||
void func_8086A068(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
void EnPametfrog_ChangeColliderThaw(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
this->freezeTimer = 0;
|
||||
if (this->mode == 10) {
|
||||
this->mode = 0;
|
||||
if (this->drawEffect == GEKKO_DRAW_EFFECT_FROZEN) {
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_NONE;
|
||||
this->collider.base.colType = COLTYPE_HIT6;
|
||||
this->collider.elements->info.elemType = ELEMTYPE_UNK1;
|
||||
this->unk_2C4 = 0.0f;
|
||||
func_800BF7CC(globalCtx, &this->actor, &this->unk_2F4[0], 12, 2, 0.3f, 0.2f);
|
||||
func_800BF7CC(globalCtx, &this->actor, this->limbPos, 12, 2, 0.3f, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,33 +405,33 @@ void EnPametfrog_JumpOnGround(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_8086A724(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
if (this->actor.colChkInfo.damageEffect == 2) {
|
||||
this->mode = 0;
|
||||
void EnPametfrog_ApplyMagicArrowEffects(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) {
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_NONE;
|
||||
this->unk_2C4 = 3.0f;
|
||||
this->unk_2C8 = 0.75f;
|
||||
} else if (this->actor.colChkInfo.damageEffect == 4) {
|
||||
this->mode = 20;
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) {
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS;
|
||||
this->unk_2C8 = 0.75f;
|
||||
this->unk_2C4 = 3.0f;
|
||||
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_LARGE_LIGHT_RAYS);
|
||||
} else if (this->actor.colChkInfo.damageEffect == 3) {
|
||||
func_8086A024(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ICE) {
|
||||
EnPametfrog_ChangeColliderFreeze(this);
|
||||
}
|
||||
}
|
||||
|
||||
void func_8086A80C(EnPametfrog* this) {
|
||||
void EnPametfrog_ApplyElectricStun(EnPametfrog* this) {
|
||||
this->freezeTimer = 40;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
|
||||
func_800BCB70(&this->actor, 0, 255, 0, 40);
|
||||
this->mode = 30;
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_ELECTRIC_STUN;
|
||||
this->unk_2C8 = 0.75f;
|
||||
this->unk_2C4 = 2.0f;
|
||||
}
|
||||
|
||||
void func_8086A878(EnPametfrog* this) {
|
||||
void EnPametfrog_ApplyStun(EnPametfrog* this) {
|
||||
this->freezeTimer = 40;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE);
|
||||
func_800BCB70(&this->actor, 0, 255, 0, 40);
|
||||
@@ -438,7 +447,7 @@ void EnPametfrog_SetupRearOnSnapper(EnPametfrog* this) {
|
||||
}
|
||||
|
||||
this->actor.flags &= ~1;
|
||||
this->actor.params = ENPAMETFROG_ON_SNAPPER;
|
||||
this->actor.params = GEKKO_ON_SNAPPER;
|
||||
this->actionFunc = EnPametfrog_RearOnSnapper;
|
||||
}
|
||||
|
||||
@@ -486,7 +495,7 @@ void EnPametfrog_RearOnSnapperWave(EnPametfrog* this, GlobalContext* globalCtx)
|
||||
void EnPametfrog_SetupRearOnSnapperRise(EnPametfrog* this) {
|
||||
SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_060050B8);
|
||||
this->timer = 10;
|
||||
this->actor.params = ENPAMETFROG_REAR_ON_SNAPPER;
|
||||
this->actor.params = GEKKO_REAR_ON_SNAPPER;
|
||||
this->actor.shape.rot.x = 0;
|
||||
this->actor.shape.rot.z = 0;
|
||||
this->actor.shape.rot.y = this->actor.child->world.rot.y;
|
||||
@@ -509,7 +518,7 @@ void EnPametfrog_SetupFallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx
|
||||
s16 yaw;
|
||||
|
||||
SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06001F20);
|
||||
this->actor.params = ENPAMETFROG_FALL_OFF_SNAPPER;
|
||||
this->actor.params = GEKKO_FALL_OFF_SNAPPER;
|
||||
this->actor.speedXZ = 7.0f;
|
||||
this->actor.velocity.y = 15.0f;
|
||||
this->actor.world.rot.y = BINANG_ROT180(this->actor.child->world.rot.y);
|
||||
@@ -725,7 +734,7 @@ void EnPametfrog_SetupClimbDownWall(EnPametfrog* this) {
|
||||
this->actor.world.pos.x += 30.0f * Math_SinS(yaw);
|
||||
this->actor.world.pos.z += 30.0f * Math_CosS(yaw);
|
||||
this->actor.bgCheckFlags &= ~1;
|
||||
this->actor.params = ENPAMETFROG_RETURN_TO_SNAPPER;
|
||||
this->actor.params = GEKKO_RETURN_TO_SNAPPER;
|
||||
this->actionFunc = EnPametfrog_ClimbDownWall;
|
||||
}
|
||||
|
||||
@@ -746,7 +755,7 @@ void EnPametfrog_ClimbDownWall(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
|
||||
void EnPametfrog_SetupRunToSnapper(EnPametfrog* this) {
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_060039C4, 2.0f, 0.0f, 0.0f, 0, -2.0f);
|
||||
this->actor.params = ENPAMETFROG_RETURN_TO_SNAPPER;
|
||||
this->actor.params = GEKKO_RETURN_TO_SNAPPER;
|
||||
this->actionFunc = EnPametfrog_RunToSnapper;
|
||||
}
|
||||
|
||||
@@ -777,7 +786,7 @@ void EnPametfrog_SetupJumpOnSnapper(EnPametfrog* this) {
|
||||
this->actor.velocity.y = 0.0f;
|
||||
this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, this->actor.child);
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
this->actor.params = ENPAMETFROG_JUMP_ON_SNAPPER;
|
||||
this->actor.params = GEKKO_JUMP_ON_SNAPPER;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_GREET);
|
||||
this->actionFunc = EnPametfrog_JumpOnSnapper;
|
||||
}
|
||||
@@ -803,7 +812,7 @@ void EnPametfrog_JumpOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
void EnPametfrog_SetupLandOnSnapper(EnPametfrog* this) {
|
||||
SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06000994);
|
||||
this->actor.shape.rot.y = this->actor.child->shape.rot.y;
|
||||
this->actor.params = ENPAMETFROG_ON_SNAPPER;
|
||||
this->actor.params = GEKKO_ON_SNAPPER;
|
||||
this->actionFunc = EnPametfrog_LandOnSnapper;
|
||||
}
|
||||
|
||||
@@ -821,7 +830,7 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
|
||||
SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06001F20);
|
||||
if (this->actor.colChkInfo.health > 0) {
|
||||
this->actor.params = ENPAMETFROG_RETURN_TO_SNAPPER;
|
||||
this->actor.params = GEKKO_RETURN_TO_SNAPPER;
|
||||
}
|
||||
|
||||
this->actor.speedXZ = 0.0f;
|
||||
@@ -834,7 +843,7 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DAMAGE);
|
||||
}
|
||||
|
||||
func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x10);
|
||||
func_800BCB70(&this->actor, 0x4000, 255, 0, 16);
|
||||
yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos);
|
||||
this->actor.world.pos.x += 30.0f * Math_SinS(yaw);
|
||||
this->actor.world.pos.z += 30.0f * Math_CosS(yaw);
|
||||
@@ -867,7 +876,7 @@ void EnPametfrog_FallInAir(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
this->actor.colChkInfo.mass = 50;
|
||||
}
|
||||
} else {
|
||||
this->yaw += 0xF00;
|
||||
this->spinYaw += 0xF00;
|
||||
if (this->camId != 0) {
|
||||
func_8016970C(globalCtx, this->camId, &this->actor.world.pos, &Play_GetCamera(globalCtx, this->camId)->eye);
|
||||
}
|
||||
@@ -881,11 +890,11 @@ void EnPametfrog_FallInAir(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
void EnPametfrog_SetupFallOnGround(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_ChangeAnimDefaultStop(&this->skelAnime, &D_06004298);
|
||||
this->actor.shape.rot.x = 0;
|
||||
this->actor.shape.rot.y += this->yaw;
|
||||
this->actor.shape.rot.y += this->spinYaw;
|
||||
this->actor.shape.rot.z = 0;
|
||||
this->yaw = 0;
|
||||
this->spinYaw = 0;
|
||||
this->timer = 5;
|
||||
func_8086A068(this, globalCtx);
|
||||
EnPametfrog_ChangeColliderThaw(this, globalCtx);
|
||||
EnPametfrog_JumpWaterEffects(this, globalCtx);
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EV_WALK_WATER);
|
||||
this->actionFunc = EnPametfrog_FallOnGround;
|
||||
@@ -918,7 +927,7 @@ void EnPametfrog_SetupDefeatGekko(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
eye.y = this->actor.child->focus.pos.y + 20.0f;
|
||||
eye.z = this->actor.child->focus.pos.z + 150.0f * Math_CosS(yaw);
|
||||
func_8016970C(globalCtx, this->camId, &this->actor.child->focus.pos, &eye);
|
||||
this->actor.params = ENPAMETFROG_DEFEAT;
|
||||
this->actor.params = GEKKO_DEFEAT;
|
||||
this->timer = 38;
|
||||
this->actionFunc = EnPametfrog_DefeatGekko;
|
||||
}
|
||||
@@ -980,7 +989,8 @@ void EnPametfrog_SetupSpawnFrog(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
vel.x = randPlusMinusPoint5Scaled(5.0f);
|
||||
vel.y = Rand_ZeroFloat(3.0f) + 4.0f;
|
||||
vel.z = randPlusMinusPoint5Scaled(5.0f);
|
||||
EffectSsHahen_Spawn(globalCtx, &this->actor.world.pos, &vel, &sAccel, 0, Rand_S16Offset(12, 3), -1, 10, 0);
|
||||
EffectSsHahen_Spawn(globalCtx, &this->actor.world.pos, &vel, &sAccel, 0, Rand_S16Offset(12, 3),
|
||||
HAHEN_OBJECT_DEFAULT, 10, 0);
|
||||
}
|
||||
|
||||
this->timer = 40;
|
||||
@@ -1018,7 +1028,7 @@ void EnPametfrog_PlayCutscene(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
this->camId = ActorCutscene_GetCurrentCamera(this->cutscene);
|
||||
func_800B724C(globalCtx, &this->actor, 7);
|
||||
if (this->actor.colChkInfo.health == 0) {
|
||||
if (this->actor.params == ENPAMETFROG_PRE_SNAPPER) {
|
||||
if (this->actor.params == GEKKO_PRE_SNAPPER) {
|
||||
EnPametfrog_SetupCallSnapper(this, globalCtx);
|
||||
} else {
|
||||
EnPametfrog_SetupFallInAir(this, globalCtx);
|
||||
@@ -1120,20 +1130,20 @@ void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_8086CB4C(EnPametfrog* this) {
|
||||
void EnPametfrog_SetupDamage(EnPametfrog* this) {
|
||||
SkelAnime_ChangeAnimTransitionStop(&this->skelAnime, &D_06005D54, -3.0f);
|
||||
this->timer = 20;
|
||||
this->collider.base.atFlags &= ~AT_ON;
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
this->actor.speedXZ = 10.0f;
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DAMAGE);
|
||||
func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 20);
|
||||
func_800BCB70(&this->actor, 0x4000, 255, 0, 20);
|
||||
func_800BE5CC(&this->actor, &this->collider, 0);
|
||||
this->actor.shape.rot.y = BINANG_ROT180(this->actor.world.rot.y);
|
||||
this->actionFunc = func_8086CC04;
|
||||
this->actionFunc = EnPametfrog_Damage;
|
||||
}
|
||||
|
||||
void func_8086CC04(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
void EnPametfrog_Damage(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
this->timer--;
|
||||
Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f);
|
||||
@@ -1146,7 +1156,7 @@ void func_8086CC04(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
void func_8086CC84(EnPametfrog* this) {
|
||||
void EnPametfrog_SetupStun(EnPametfrog* this) {
|
||||
if (this->skelAnime.animCurrentSeg == &D_060039C4) {
|
||||
this->skelAnime.animCurrentFrame = 0.0f;
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
@@ -1159,16 +1169,16 @@ void func_8086CC84(EnPametfrog* this) {
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
}
|
||||
|
||||
this->actionFunc = func_8086CD04;
|
||||
this->actionFunc = EnPametfrog_Stun;
|
||||
}
|
||||
|
||||
void func_8086CD04(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
void EnPametfrog_Stun(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
this->freezeTimer--;
|
||||
if (this->freezeTimer == 0) {
|
||||
func_8086A068(this, globalCtx);
|
||||
EnPametfrog_ChangeColliderThaw(this, globalCtx);
|
||||
EnPametfrog_SetupJumpToLink(this);
|
||||
} else if (this->freezeTimer == 78) {
|
||||
func_8086A068(this, globalCtx);
|
||||
EnPametfrog_ChangeColliderThaw(this, globalCtx);
|
||||
this->actor.colorFilterTimer = 0;
|
||||
EnPametfrog_SetupCutscene(this);
|
||||
}
|
||||
@@ -1254,7 +1264,7 @@ void EnPametfrog_SnapperSpawn(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
void EnPametfrog_SetupTransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
this->actor.params = ENPAMETFROG_GET_SNAPPER;
|
||||
this->actor.params = GEKKO_GET_SNAPPER;
|
||||
Quake_RemoveFromIdx(this->quake);
|
||||
this->quake = Quake_Add(ACTIVE_CAM, 3);
|
||||
Quake_SetSpeed(this->quake, 20000);
|
||||
@@ -1265,41 +1275,41 @@ void EnPametfrog_SetupTransitionGekkoSnapper(EnPametfrog* this, GlobalContext* g
|
||||
}
|
||||
|
||||
void EnPametfrog_TransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
if (this->actor.params == ENPAMETFROG_INIT_SNAPPER) {
|
||||
if (this->actor.params == GEKKO_INIT_SNAPPER) {
|
||||
func_801A2E54(0x38);
|
||||
EnPametfrog_SetupRunToSnapper(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EnPametfrog_ApplyDamage(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
this->collider.base.acFlags &= ~AC_HIT;
|
||||
if ((this->mode != 10) || !(this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) {
|
||||
if (this->actor.params == ENPAMETFROG_PRE_SNAPPER) {
|
||||
if ((this->drawEffect != GEKKO_DRAW_EFFECT_FROZEN) ||
|
||||
!(this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) {
|
||||
if (this->actor.params == GEKKO_PRE_SNAPPER) {
|
||||
if (func_800BE22C(&this->actor) == 0) {
|
||||
func_801A2ED8();
|
||||
}
|
||||
|
||||
// Nuts/Hookshot/Deku Mask Spin all freeze Gekko for 40 frames
|
||||
if (this->actor.colChkInfo.damageEffect == 5) {
|
||||
func_8086A80C(this);
|
||||
func_8086CC84(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == 1) {
|
||||
func_8086A878(this);
|
||||
func_8086CC84(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == 3) { // Ice arrows?
|
||||
func_8086A024(this);
|
||||
if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ZORA_BARRIER) {
|
||||
EnPametfrog_ApplyElectricStun(this);
|
||||
EnPametfrog_SetupStun(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_STUN) {
|
||||
EnPametfrog_ApplyStun(this);
|
||||
EnPametfrog_SetupStun(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ICE) {
|
||||
EnPametfrog_ChangeColliderFreeze(this);
|
||||
this->freezeTimer = 80;
|
||||
func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x50);
|
||||
func_8086CC84(this);
|
||||
EnPametfrog_SetupStun(this);
|
||||
} else {
|
||||
func_8086A068(this, globalCtx);
|
||||
if (this->actor.colChkInfo.damageEffect == 2) {
|
||||
this->mode = 0;
|
||||
EnPametfrog_ChangeColliderThaw(this, globalCtx);
|
||||
if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) {
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_NONE;
|
||||
this->unk_2C8 = 0.75f;
|
||||
this->unk_2C4 = 4.0f;
|
||||
} else if (this->actor.colChkInfo.damageEffect == 4) {
|
||||
this->mode = 20;
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) {
|
||||
this->drawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS;
|
||||
this->unk_2C8 = 0.75f;
|
||||
this->unk_2C4 = 4.0f;
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG,
|
||||
@@ -1308,21 +1318,21 @@ void EnPametfrog_ApplyDamage(EnPametfrog* this, GlobalContext* globalCtx) {
|
||||
this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0,
|
||||
CLEAR_TAG_LARGE_LIGHT_RAYS);
|
||||
}
|
||||
func_8086CB4C(this);
|
||||
EnPametfrog_SetupDamage(this);
|
||||
}
|
||||
} else if (func_800BE22C(&this->actor) == 0) {
|
||||
this->collider.base.acFlags &= ~AC_ON;
|
||||
func_8086A724(this, globalCtx);
|
||||
EnPametfrog_ApplyMagicArrowEffects(this, globalCtx);
|
||||
func_800BBA88(globalCtx, &this->actor);
|
||||
this->actor.flags &= ~1;
|
||||
func_801A2ED8();
|
||||
EnPametfrog_SetupCutscene(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == 5) {
|
||||
func_8086A80C(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == 1) {
|
||||
func_8086A878(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ZORA_BARRIER) {
|
||||
EnPametfrog_ApplyElectricStun(this);
|
||||
} else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_STUN) {
|
||||
EnPametfrog_ApplyStun(this);
|
||||
} else {
|
||||
func_8086A724(this, globalCtx);
|
||||
EnPametfrog_ApplyMagicArrowEffects(this, globalCtx);
|
||||
EnPametfrog_SetupFallInAir(this, globalCtx);
|
||||
}
|
||||
}
|
||||
@@ -1334,10 +1344,10 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
f32 unk2C4;
|
||||
f32 arg3;
|
||||
|
||||
if (this->actor.params == ENPAMETFROG_CUTSCENE) {
|
||||
if (this->actor.params == GEKKO_CUTSCENE) {
|
||||
EnPametfrog_SetupCutscene(this);
|
||||
} else if (this->actionFunc != EnPametfrog_PlayCutscene) {
|
||||
EnPametfrog_ApplyDamage(this, globalCtx);
|
||||
EnPametfrog_ApplyDamageEffect(this, globalCtx);
|
||||
} else {
|
||||
this->collider.base.acFlags &= ~AC_HIT;
|
||||
}
|
||||
@@ -1367,7 +1377,7 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
if (this->unk_2C4 > 0.0f) {
|
||||
if ((this->mode != 10) && (this->actionFunc != EnPametfrog_PlayCutscene)) {
|
||||
if ((this->drawEffect != GEKKO_DRAW_EFFECT_FROZEN) && (this->actionFunc != EnPametfrog_PlayCutscene)) {
|
||||
Math_StepToF(&this->unk_2C4, 0.0f, 0.05f);
|
||||
unk2C4 = ((this->unk_2C4 + 1.0f) * 0.375f);
|
||||
this->unk_2C8 = unk2C4;
|
||||
@@ -1378,7 +1388,21 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
static s8 D_8086DA28[] = {
|
||||
/* index -1: Limb Not used
|
||||
* index 0: GEKKO_LIMB_WAIST
|
||||
* index 1: GEKKO_LIMB_L_SHIN
|
||||
* index 2: GEKKO_LIMB_L_FOOT
|
||||
* index 3: GEKKO_LIMB_R_SHIN
|
||||
* index 4: GEKKO_LIMB_R_FOOT
|
||||
* index 5: GEKKO_LIMB_L_UPPER_ARM
|
||||
* index 6: GEKKO_LIMB_L_FOREARM
|
||||
* index 7: GEKKO_LIMB_L_HAND
|
||||
* index 8: GEKKO_LIMB_R_UPPER_ARM
|
||||
* index 9: GEKKO_LIMB_R_FOREARM
|
||||
* index 10: GEKKO_LIMB_R_HAND
|
||||
* index 11: GEKKO_LIMB_JAW
|
||||
*/
|
||||
static s8 limbPosIndex[] = {
|
||||
-1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, 6, -1, 7, 8, 9, -1, 10, -1, 11, -1, -1,
|
||||
};
|
||||
|
||||
@@ -1388,7 +1412,7 @@ void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi
|
||||
Vec3s* center;
|
||||
s8 index;
|
||||
|
||||
if (limbIndex == 20) {
|
||||
if (limbIndex == GEKKO_LIMB_HEAD) {
|
||||
SysMatrix_GetStateTranslation(&this->actor.focus.pos);
|
||||
this->actor.focus.rot.y = this->actor.shape.rot.y;
|
||||
SysMatrix_GetStateTranslationAndScaledY(2500.0f, &vec);
|
||||
@@ -1402,9 +1426,9 @@ void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi
|
||||
center->z = (Math_CosS(this->actor.shape.rot.y) * 35.0f) + this->actor.focus.pos.z;
|
||||
}
|
||||
|
||||
index = D_8086DA28[limbIndex];
|
||||
index = limbPosIndex[limbIndex];
|
||||
if (index != -1) {
|
||||
SysMatrix_GetStateTranslation(&this->unk_2F4[index]);
|
||||
SysMatrix_GetStateTranslation(&this->limbPos[index]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1412,9 +1436,9 @@ void EnPametfrog_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnPametfrog* this = THIS;
|
||||
|
||||
func_8012C28C(globalCtx->state.gfxCtx);
|
||||
Matrix_RotateY(this->yaw, MTXMODE_APPLY);
|
||||
Matrix_RotateY(this->spinYaw, MTXMODE_APPLY);
|
||||
SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, NULL,
|
||||
EnPametfrog_PostLimbDraw, &this->actor);
|
||||
func_800BE680(globalCtx, &this->actor, &this->unk_2F4[0], 12, this->unk_2C8, this->unk_2CC, this->unk_2C4,
|
||||
this->mode);
|
||||
func_800BE680(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->unk_2C8, this->unk_2CC,
|
||||
this->unk_2C4, this->drawEffect);
|
||||
}
|
||||
|
||||
@@ -8,32 +8,67 @@ struct EnPametfrog;
|
||||
typedef void (*EnPametfrogActionFunc)(struct EnPametfrog*, GlobalContext*);
|
||||
|
||||
typedef enum {
|
||||
/* 0x0 */ ENPAMETFROG_PRE_SNAPPER,
|
||||
/* 0x1 */ ENPAMETFROG_GET_SNAPPER,
|
||||
/* 0x2 */ ENPAMETFROG_INIT_SNAPPER,
|
||||
/* 0x3 */ ENPAMETFROG_ON_SNAPPER,
|
||||
/* 0x4 */ ENPAMETFROG_REAR_ON_SNAPPER,
|
||||
/* 0x5 */ ENPAMETFROG_CUTSCENE,
|
||||
/* 0x6 */ ENPAMETFROG_FALL_OFF_SNAPPER,
|
||||
/* 0x7 */ ENPAMETFROG_RETURN_TO_SNAPPER,
|
||||
/* 0x8 */ ENPAMETFROG_JUMP_ON_SNAPPER,
|
||||
/* 0x9 */ ENPAMETFROG_DEFEAT,
|
||||
/* 0x0 */ GEKKO_PRE_SNAPPER,
|
||||
/* 0x1 */ GEKKO_GET_SNAPPER,
|
||||
/* 0x2 */ GEKKO_INIT_SNAPPER,
|
||||
/* 0x3 */ GEKKO_ON_SNAPPER,
|
||||
/* 0x4 */ GEKKO_REAR_ON_SNAPPER,
|
||||
/* 0x5 */ GEKKO_CUTSCENE,
|
||||
/* 0x6 */ GEKKO_FALL_OFF_SNAPPER,
|
||||
/* 0x7 */ GEKKO_RETURN_TO_SNAPPER,
|
||||
/* 0x8 */ GEKKO_JUMP_ON_SNAPPER,
|
||||
/* 0x9 */ GEKKO_DEFEAT,
|
||||
} EnPametfrogState;
|
||||
|
||||
typedef enum {
|
||||
/* 00 */ GEKKO_DRAW_EFFECT_NONE, // May be GEKKO_DRAW_EFFECT_THAW
|
||||
/* 10 */ GEKKO_DRAW_EFFECT_FROZEN = 10,
|
||||
/* 20 */ GEKKO_DRAW_EFFECT_LIGHT_ORBS = 20,
|
||||
/* 30 */ GEKKO_DRAW_EFFECT_ELECTRIC_STUN = 30,
|
||||
} EnPametfrogDrawEffectType;
|
||||
|
||||
typedef enum {
|
||||
/* 0x00 */ GEKKO_LIMB_NONE,
|
||||
/* 0x01 */ GEKKO_LIMB_ROOT,
|
||||
/* 0x02 */ GEKKO_LIMB_WAIST,
|
||||
/* 0x03 */ GEKKO_LIMB_L_THIGH,
|
||||
/* 0x04 */ GEKKO_LIMB_L_SHIN,
|
||||
/* 0x05 */ GEKKO_LIMB_L_ANKLE,
|
||||
/* 0x06 */ GEKKO_LIMB_L_FOOT,
|
||||
/* 0x07 */ GEKKO_LIMB_R_THIGH,
|
||||
/* 0x08 */ GEKKO_LIMB_R_SHIN,
|
||||
/* 0x09 */ GEKKO_LIMB_R_ANKLE,
|
||||
/* 0x0A */ GEKKO_LIMB_R_FOOT,
|
||||
/* 0x0B */ GEKKO_LIMB_TORSO,
|
||||
/* 0x0C */ GEKKO_LIMB_L_UPPER_ARM,
|
||||
/* 0x0D */ GEKKO_LIMB_L_FOREARM,
|
||||
/* 0x0E */ GEKKO_LIMB_L_WRIST,
|
||||
/* 0x0F */ GEKKO_LIMB_L_HAND,
|
||||
/* 0x10 */ GEKKO_LIMB_R_UPPER_ARM,
|
||||
/* 0x11 */ GEKKO_LIMB_R_FOREARM,
|
||||
/* 0x12 */ GEKKO_LIMB_R_WRIST,
|
||||
/* 0x13 */ GEKKO_LIMB_R_HAND,
|
||||
/* 0x14 */ GEKKO_LIMB_HEAD,
|
||||
/* 0x15 */ GEKKO_LIMB_JAW,
|
||||
/* 0x16 */ GEKKO_LIMB_L_EYE,
|
||||
/* 0x17 */ GEKKO_LIMB_R_EYE,
|
||||
/* 0x18 */ GEKKO_LIMB_MAX,
|
||||
} EnPametfrogLimb;
|
||||
|
||||
typedef struct EnPametfrog {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ SkelAnime skelAnime;
|
||||
/* 0x188 */ Vec3s limbDrawTable[24];
|
||||
/* 0x218 */ Vec3s transitionDrawTable[24];
|
||||
/* 0x188 */ Vec3s limbDrawTable[GEKKO_LIMB_MAX];
|
||||
/* 0x218 */ Vec3s transitionDrawTable[GEKKO_LIMB_MAX];
|
||||
/* 0x2A8 */ EnPametfrogActionFunc actionFunc;
|
||||
/* 0x2AC */ u8 mode; // 0/10/20/30
|
||||
/* 0x2AC */ u8 drawEffect;
|
||||
/* 0x2AD */ u8 wallPauseTimer; // Gekko stops 10 times along wall/ceiling after being blown off of Snapper
|
||||
/* 0x2AE */ u8 unk_2AE; // True/False
|
||||
/* 0x2B0 */ s16 cutscene;
|
||||
/* 0x2B2 */ s16 params;
|
||||
/* 0x2B4 */ s16 quake;
|
||||
/* 0x2B6 */ s16 timer;
|
||||
/* 0x2B8 */ s16 yaw;
|
||||
/* 0x2B8 */ s16 spinYaw;
|
||||
/* 0x2BA */ s16 camId;
|
||||
/* 0x2BC */ s16 freezeTimer;
|
||||
/* 0x2C0 */ f32 wallRotation;
|
||||
@@ -43,7 +78,7 @@ typedef struct EnPametfrog {
|
||||
/* 0x2D0 */ Vec3f unk_2D0; // MtxF zx/zy/zz
|
||||
/* 0x2DC */ Vec3f unk_2DC; // MtxF yx/yy/yz: wallNorm/floorNorm/Base of Gekko walking???
|
||||
/* 0x2E8 */ Vec3f unk_2E8; // MtxF xx/xy/xz
|
||||
/* 0x2F4 */ Vec3f unk_2F4[12];
|
||||
/* 0x2F4 */ Vec3f limbPos[12];
|
||||
/* 0x384 */ ColliderJntSph collider;
|
||||
/* 0x3A4 */ ColliderJntSphElement colElement[2];
|
||||
} EnPametfrog; // size = 0x424
|
||||
|
||||
@@ -1510,8 +1510,8 @@ void EnSuttari_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList
|
||||
if (this->actor.child == NULL) {
|
||||
if (this->flags1 & 0x100) {
|
||||
bombBag =
|
||||
Actor_SpawnWithParent(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_NIMOTSU,
|
||||
curState->mf[3][0], curState->mf[3][1], curState->mf[3][2], 0, 0, 0, -1);
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_NIMOTSU,
|
||||
curState->mf[3][0], curState->mf[3][1], curState->mf[3][2], 0, 0, 0, -1);
|
||||
if (bombBag != NULL) {
|
||||
func_8018219C(curState, &bombBag->shape.rot, 0);
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ void func_80B3C2B0(ObjGhaka* this) {
|
||||
|
||||
void func_80B3C2C4(ObjGhaka* this, GlobalContext* globalCtx) {
|
||||
if (!(gSaveContext.weekEventReg[20] & 0x20)) {
|
||||
Actor_SpawnWithParentAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_BG_GORON_OYU, 0.0f, 25.0f, 261.0f, 0, 0,
|
||||
0, 0, this->dyna.actor.cutscene, this->dyna.actor.unk20, 0);
|
||||
Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_BG_GORON_OYU, 0.0f, 25.0f, 261.0f, 0, 0, 0,
|
||||
0, this->dyna.actor.cutscene, this->dyna.actor.unk20, 0);
|
||||
} else {
|
||||
Actor_SpawnWithParentAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_BG_GORON_OYU, 0.0f, 25.0f, 261.0f, 0, 0,
|
||||
0, 1, -1, this->dyna.actor.unk20, 0);
|
||||
Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_BG_GORON_OYU, 0.0f, 25.0f, 261.0f, 0, 0, 0,
|
||||
1, -1, this->dyna.actor.unk20, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +78,9 @@ void ObjRaillift_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
isColorful = true;
|
||||
}
|
||||
if (type == DEKU_FLOWER_PLATFORM) {
|
||||
Actor_SpawnWithParent(&globalCtx->actorCtx, thisx, globalCtx, ACTOR_OBJ_ETCETERA, thisx->world.pos.x,
|
||||
thisx->world.pos.y, thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y,
|
||||
thisx->shape.rot.z, 0);
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, thisx, globalCtx, ACTOR_OBJ_ETCETERA, thisx->world.pos.x,
|
||||
thisx->world.pos.y, thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y,
|
||||
thisx->shape.rot.z, 0);
|
||||
if (isColorful) {
|
||||
thisx->draw = ObjRaillift_DrawDekuFlowerPlatformColorful;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user