mirror of https://github.com/zeldaret/mm.git
Documents EnEncount1 (Dragonfly, Wallmaster, and Skullfish spawner) (#1206)
* Document everything * missed some () * PR * format * spawnActiveCount * spawnTotalCount
This commit is contained in:
parent
35c45eab70
commit
858d10a38b
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
#include "z_en_encount1.h"
|
||||
#include "overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.h"
|
||||
#include "overlays/actors/ovl_En_Wallmas/z_en_wallmas.h"
|
||||
#include "overlays/actors/ovl_En_Pr2/z_en_pr2.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_CANT_LOCK_ON)
|
||||
|
||||
|
@ -13,7 +16,7 @@
|
|||
void EnEncount1_Init(Actor* thisx, PlayState* play);
|
||||
void EnEncount1_Update(Actor* thisx, PlayState* play);
|
||||
|
||||
void func_808E0954(EnEncount1* this, PlayState* play);
|
||||
void EnEncount1_SpawnActor(EnEncount1* this, PlayState* play);
|
||||
|
||||
ActorInit En_Encount1_InitVars = {
|
||||
ACTOR_EN_ENCOUNT1,
|
||||
|
@ -27,14 +30,19 @@ ActorInit En_Encount1_InitVars = {
|
|||
(ActorFunc)NULL,
|
||||
};
|
||||
|
||||
static s16 sActorList[] = {
|
||||
ACTOR_EN_GRASSHOPPER,
|
||||
ACTOR_EN_WALLMAS,
|
||||
ACTOR_EN_PR2,
|
||||
ACTOR_EN_PR2,
|
||||
static s16 sActorIds[] = {
|
||||
ACTOR_EN_GRASSHOPPER, // EN_ENCOUNT1_GRASSHOPPER
|
||||
ACTOR_EN_WALLMAS, // EN_ENCOUNT1_WALLMASTER
|
||||
ACTOR_EN_PR2, // EN_ENCOUNT1_SKULLFISH
|
||||
ACTOR_EN_PR2, // EN_ENCOUNT1_SKULLFISH_2
|
||||
};
|
||||
|
||||
static s16 sActorParams[] = { 1, 0, 1, 3 };
|
||||
static s16 sActorParams[] = {
|
||||
EN_GRASSHOPPER_PARAMS(EN_GRASSHOPPER_TYPE_GROWS_WHEN_SPAWNED), // EN_ENCOUNT1_GRASSHOPPER
|
||||
WALLMASTER_PARAMS(WALLMASTER_TYPE_TIMER_ONLY, 0, false), // EN_ENCOUNT1_WALLMASTER
|
||||
ENPR2_PARAMS(1, 0), // EN_ENCOUNT1_SKULLFISH
|
||||
ENPR2_PARAMS(3, 0) // EN_ENCOUNT1_SKULLFISH_2
|
||||
};
|
||||
|
||||
void EnEncount1_Init(Actor* thisx, PlayState* play) {
|
||||
EnEncount1* this = THIS;
|
||||
|
@ -44,69 +52,72 @@ void EnEncount1_Init(Actor* thisx, PlayState* play) {
|
|||
return;
|
||||
}
|
||||
|
||||
this->actorType = ENENCOUNT1_GET_TYPE(&this->actor);
|
||||
this->unk_14C = ENENCOUNT1_GET_7C0(&this->actor);
|
||||
this->unk_154 = ENENCOUNT1_GET_PATH(&this->actor);
|
||||
this->unk_158 = this->actor.world.rot.x;
|
||||
this->unk_15C = this->actor.world.rot.y;
|
||||
this->unk_160 = (this->actor.world.rot.z * 40.0f) + 120.0f;
|
||||
this->type = ENENCOUNT1_GET_TYPE(&this->actor);
|
||||
this->spawnActiveMax = ENENCOUNT1_GET_SPAWN_ACTIVE_MAX(&this->actor);
|
||||
this->spawnTotalMax = ENENCOUNT1_GET_SPAWN_TOTAL_MAX(&this->actor);
|
||||
this->spawnTimeMin = ENENCOUNT1_GET_SPAWN_TIME_MIN(&this->actor);
|
||||
this->spawnUnusedProp = ENENCOUNT1_GET_SPAWN_UNUSED_PROP(&this->actor);
|
||||
this->spawnDistanceMax = (ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(&this->actor) * 40.0f) + 120.0f;
|
||||
|
||||
if (this->unk_154 >= 0x3F) {
|
||||
this->unk_154 = -1;
|
||||
if (this->spawnTotalMax >= ENENCOUNT1_SPAWNS_TOTAL_MAX_INFINITE) {
|
||||
this->spawnTotalMax = -1;
|
||||
}
|
||||
if (this->actor.world.rot.z < 0) {
|
||||
this->unk_160 = -1.0f;
|
||||
if (ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(&this->actor) < 0) {
|
||||
this->spawnDistanceMax = -1.0f;
|
||||
}
|
||||
if (this->actorType == EN_ENCOUNT1_SKULLFISH_2) {
|
||||
this->unk_15A = ENENCOUNT1_GET_PATH(&this->actor);
|
||||
this->path = SubS_GetPathByIndex(play, this->unk_15A, 0x3F);
|
||||
this->unk_154 = -1;
|
||||
this->unk_160 = -1.0f;
|
||||
if (this->type == EN_ENCOUNT1_SKULLFISH_2) {
|
||||
this->pathIndex = ENENCOUNT1_GET_PATH_INDEX(&this->actor);
|
||||
this->path = SubS_GetPathByIndex(play, this->pathIndex, 0x3F);
|
||||
this->spawnTotalMax = -1;
|
||||
this->spawnDistanceMax = -1.0f;
|
||||
}
|
||||
this->actor.flags &= ~ACTOR_FLAG_1;
|
||||
this->actionFunc = func_808E0954;
|
||||
this->actionFunc = EnEncount1_SpawnActor;
|
||||
}
|
||||
|
||||
void func_808E0954(EnEncount1* this, PlayState* play) {
|
||||
void EnEncount1_SpawnActor(EnEncount1* this, PlayState* play) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
Vec3f spawnPos;
|
||||
f32 sp64;
|
||||
f32 temp_fv0_2;
|
||||
s16 sp5E;
|
||||
s16 actorList;
|
||||
f32 scale;
|
||||
f32 floorHeight;
|
||||
s16 rotY;
|
||||
s16 actorId;
|
||||
s32 actorParams;
|
||||
CollisionPoly* sp54;
|
||||
s32 sp50;
|
||||
CollisionPoly* floorPoly;
|
||||
s32 bgId;
|
||||
|
||||
if (((this->unk_14E >= this->unk_14C) || ((this->unk_160 > 0.0f) && (this->unk_160 < this->actor.xzDistToPlayer)) ||
|
||||
((this->unk_154 > 0) && (this->unk_154 <= this->unk_152)))) {
|
||||
if (((this->spawnActiveCount >= this->spawnActiveMax) ||
|
||||
((this->spawnDistanceMax > 0.0f) && (this->spawnDistanceMax < this->actor.xzDistToPlayer)) ||
|
||||
((this->spawnTotalMax > 0) && (this->spawnTotalMax <= this->spawnTotalCount)))) {
|
||||
return;
|
||||
} else if (this->unk_156 != 0) {
|
||||
this->unk_156++;
|
||||
if (this->unk_156 < this->unk_158) {
|
||||
}
|
||||
|
||||
if (this->timer != 0) {
|
||||
this->timer++;
|
||||
if (this->timer < this->spawnTimeMin) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->unk_156 = 0;
|
||||
switch (this->actorType) {
|
||||
this->timer = 0;
|
||||
switch (this->type) {
|
||||
case EN_ENCOUNT1_GRASSHOPPER:
|
||||
sp64 = randPlusMinusPoint5Scaled(40.0f) + 200.0f;
|
||||
sp5E = player->actor.shape.rot.y;
|
||||
if (this->unk_14E & 1) {
|
||||
sp5E = -sp5E;
|
||||
sp64 = randPlusMinusPoint5Scaled(20.0f) + 100.0f;
|
||||
scale = randPlusMinusPoint5Scaled(40.0f) + 200.0f;
|
||||
rotY = player->actor.shape.rot.y;
|
||||
if (this->spawnActiveCount & 1) {
|
||||
rotY = -rotY;
|
||||
scale = randPlusMinusPoint5Scaled(20.0f) + 100.0f;
|
||||
}
|
||||
spawnPos.x = player->actor.world.pos.x + (Math_SinS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f);
|
||||
spawnPos.x = player->actor.world.pos.x + (Math_SinS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f);
|
||||
spawnPos.y = player->actor.floorHeight + 120.0f;
|
||||
spawnPos.z = player->actor.world.pos.z + (Math_CosS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f);
|
||||
temp_fv0_2 = BgCheck_EntityRaycastFloor5(&play->colCtx, &sp54, &sp50, &this->actor, &spawnPos);
|
||||
if ((temp_fv0_2 <= BGCHECK_Y_MIN) ||
|
||||
spawnPos.z = player->actor.world.pos.z + (Math_CosS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f);
|
||||
floorHeight = BgCheck_EntityRaycastFloor5(&play->colCtx, &floorPoly, &bgId, &this->actor, &spawnPos);
|
||||
if ((floorHeight <= BGCHECK_Y_MIN) ||
|
||||
((player->actor.depthInWater != BGCHECK_Y_MIN) &&
|
||||
(temp_fv0_2 < (player->actor.world.pos.y - player->actor.depthInWater)))) {
|
||||
(floorHeight < (player->actor.world.pos.y - player->actor.depthInWater)))) {
|
||||
return;
|
||||
}
|
||||
spawnPos.y = temp_fv0_2;
|
||||
spawnPos.y = floorHeight;
|
||||
break;
|
||||
|
||||
case EN_ENCOUNT1_WALLMASTER:
|
||||
|
@ -114,36 +125,36 @@ void func_808E0954(EnEncount1* this, PlayState* play) {
|
|||
break;
|
||||
|
||||
case EN_ENCOUNT1_SKULLFISH:
|
||||
sp64 = randPlusMinusPoint5Scaled(250.0f) + 500.0f;
|
||||
sp5E = player->actor.shape.rot.y;
|
||||
spawnPos.x = player->actor.world.pos.x + Math_SinS(sp5E) * sp64 + randPlusMinusPoint5Scaled(40.0f);
|
||||
scale = randPlusMinusPoint5Scaled(250.0f) + 500.0f;
|
||||
rotY = player->actor.shape.rot.y;
|
||||
spawnPos.x = player->actor.world.pos.x + (Math_SinS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f);
|
||||
spawnPos.y = player->actor.world.pos.y - Rand_ZeroFloat(20.0f);
|
||||
spawnPos.z = player->actor.world.pos.z + (Math_CosS(sp5E) * sp64) + randPlusMinusPoint5Scaled(40.0f);
|
||||
temp_fv0_2 = BgCheck_EntityRaycastFloor5(&play->colCtx, &sp54, &sp50, &this->actor, &spawnPos);
|
||||
if ((!(player->stateFlags1 & 0x8000000) || (temp_fv0_2 <= (BGCHECK_Y_MIN)) ||
|
||||
(player->actor.depthInWater < temp_fv0_2))) {
|
||||
spawnPos.z = player->actor.world.pos.z + (Math_CosS(rotY) * scale) + randPlusMinusPoint5Scaled(40.0f);
|
||||
floorHeight = BgCheck_EntityRaycastFloor5(&play->colCtx, &floorPoly, &bgId, &this->actor, &spawnPos);
|
||||
if (!(player->stateFlags1 & PLAYER_STATE1_8000000) || (floorHeight <= BGCHECK_Y_MIN) ||
|
||||
(player->actor.depthInWater < floorHeight)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case EN_ENCOUNT1_SKULLFISH_2:
|
||||
if ((this->path != NULL) && (!SubS_CopyPointFromPath(this->path, 0, &spawnPos))) {
|
||||
if ((this->path != NULL) && !SubS_CopyPointFromPath(this->path, 0, &spawnPos)) {
|
||||
Actor_Kill(&this->actor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
actorList = sActorList[this->actorType];
|
||||
actorParams = sActorParams[this->actorType];
|
||||
if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, actorList, spawnPos.x, spawnPos.y, spawnPos.z, 0, 0, 0,
|
||||
actorId = sActorIds[this->type];
|
||||
actorParams = sActorParams[this->type];
|
||||
if (Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, actorId, spawnPos.x, spawnPos.y, spawnPos.z, 0, 0, 0,
|
||||
actorParams) != NULL) {
|
||||
this->unk_14E++;
|
||||
if (this->unk_154 > 0) {
|
||||
this->unk_152++;
|
||||
this->spawnActiveCount++;
|
||||
if (this->spawnTotalMax > 0) {
|
||||
this->spawnTotalCount++;
|
||||
}
|
||||
|
||||
if ((this->unk_14E >= this->unk_14C) && (this->unk_158 != 0)) {
|
||||
this->unk_156 = 1;
|
||||
if ((this->spawnActiveCount >= this->spawnActiveMax) && (this->spawnTimeMin != 0)) {
|
||||
this->timer = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,22 @@
|
|||
|
||||
#include "global.h"
|
||||
|
||||
#define ENENCOUNT1_SPAWNS_TOTAL_MAX_INFINITE 63 // aka 0x3F, All bits set
|
||||
|
||||
#define ENENCOUNT1_GET_TYPE(thisx) (((thisx)->params >> 11) & 0x1F)
|
||||
#define ENENCOUNT1_GET_7C0(thisx) (((thisx)->params >> 6) & 0x1F)
|
||||
#define ENENCOUNT1_GET_PATH(thisx) ((thisx)->params & 0x3F)
|
||||
#define ENENCOUNT1_GET_SPAWN_ACTIVE_MAX(thisx) (((thisx)->params >> 6) & 0x1F)
|
||||
#define ENENCOUNT1_GET_SPAWN_TOTAL_MAX(thisx) ((thisx)->params & 0x3F)
|
||||
#define ENENCOUNT1_GET_PATH_INDEX(thisx) ((thisx)->params & 0x3F) // Used only by EN_ENCOUNT1_SKULLFISH_2 which doesn't use SpawnTotalMax
|
||||
|
||||
#define ENENCOUNT1_GET_SPAWN_TIME_MIN(thisx) ((thisx)->world.rot.x) // Time to wait between spawning
|
||||
#define ENENCOUNT1_GET_SPAWN_UNUSED_PROP(thisx) ((thisx)->world.rot.y) // Unused spawn property
|
||||
#define ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(thisx) ((thisx)->world.rot.z) // Negative means infinite distance
|
||||
|
||||
typedef enum EnEncount1Enemy {
|
||||
/* 0x0 */ EN_ENCOUNT1_GRASSHOPPER,
|
||||
/* 0x1 */ EN_ENCOUNT1_WALLMASTER,
|
||||
/* 0x2 */ EN_ENCOUNT1_SKULLFISH,
|
||||
/* 0x3 */ EN_ENCOUNT1_SKULLFISH_2,
|
||||
/* 0 */ EN_ENCOUNT1_GRASSHOPPER,
|
||||
/* 1 */ EN_ENCOUNT1_WALLMASTER,
|
||||
/* 2 */ EN_ENCOUNT1_SKULLFISH,
|
||||
/* 3 */ EN_ENCOUNT1_SKULLFISH_2,
|
||||
} EnEncount1Enemy;
|
||||
|
||||
struct EnEncount1;
|
||||
|
@ -22,16 +29,16 @@ typedef struct EnEncount1 {
|
|||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ EnEncount1ActionFunc actionFunc;
|
||||
/* 0x148 */ Path* path;
|
||||
/* 0x14C */ s16 unk_14C;
|
||||
/* 0x14E */ s16 unk_14E;
|
||||
/* 0x150 */ s16 actorType;
|
||||
/* 0x152 */ s16 unk_152;
|
||||
/* 0x154 */ s16 unk_154;
|
||||
/* 0x156 */ s16 unk_156;
|
||||
/* 0x158 */ s16 unk_158;
|
||||
/* 0x15A */ s16 unk_15A;
|
||||
/* 0x15C */ s32 unk_15C;
|
||||
/* 0x160 */ f32 unk_160;
|
||||
/* 0x14C */ s16 spawnActiveMax;
|
||||
/* 0x14E */ s16 spawnActiveCount;
|
||||
/* 0x150 */ s16 type;
|
||||
/* 0x152 */ s16 spawnTotalCount;
|
||||
/* 0x154 */ s16 spawnTotalMax;
|
||||
/* 0x156 */ s16 timer;
|
||||
/* 0x158 */ s16 spawnTimeMin;
|
||||
/* 0x15A */ s16 pathIndex;
|
||||
/* 0x15C */ s32 spawnUnusedProp;
|
||||
/* 0x160 */ f32 spawnDistanceMax;
|
||||
} EnEncount1; // size = 0x164
|
||||
|
||||
#endif // Z_EN_ENCOUNT1_H
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#define EN_GRASSHOPPER_GET_TYPE(thisx) ((thisx)->params)
|
||||
|
||||
#define EN_GRASSHOPPER_PARAMS(type) (type)
|
||||
|
||||
struct EnGrasshopper;
|
||||
|
||||
typedef void (*EnGrasshopperActionFunc)(struct EnGrasshopper*, PlayState*);
|
||||
|
|
|
@ -151,7 +151,7 @@ void EnPr2_Init(Actor* thisx, PlayState* play) {
|
|||
Actor* parent = this->actor.parent;
|
||||
|
||||
if (parent->update != NULL) {
|
||||
this->unk_1C8 = ((EnEncount1*)parent)->unk_15A;
|
||||
this->unk_1C8 = ((EnEncount1*)parent)->pathIndex;
|
||||
this->path = SubS_GetPathByIndex(play, this->unk_1C8, 0x3F);
|
||||
this->unk_208 = parent->world.rot.z * 20.0f;
|
||||
if (this->unk_208 < 20.0f) {
|
||||
|
@ -190,8 +190,8 @@ void EnPr2_Destroy(Actor* thisx, PlayState* play) {
|
|||
if (this->actor.parent != NULL) {
|
||||
EnEncount1* encount1 = (EnEncount1*)this->actor.parent;
|
||||
|
||||
if ((encount1->actor.update != NULL) && (encount1->unk_14E > 0)) {
|
||||
encount1->unk_14E--;
|
||||
if ((encount1->actor.update != NULL) && (encount1->spawnActiveCount > 0)) {
|
||||
encount1->spawnActiveCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ typedef void (*EnPr2ActionFunc)(struct EnPr2*, PlayState*);
|
|||
#define ENPR2_GET_F(thisx) ((thisx)->params & 0xF)
|
||||
#define ENPR2_GET_FF0(thisx) (((thisx)->params >> 4) & 0xFF)
|
||||
|
||||
#define ENPR2_PARAMS(paramF, paramFF0) (((paramF) & 0xF) | (((paramFF0) << 4) & 0xFF0))
|
||||
|
||||
typedef struct EnPr2 {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ SkelAnime skelAnime;
|
||||
|
|
|
@ -191,8 +191,8 @@ void EnWallmas_Destroy(Actor* thisx, PlayState* play) {
|
|||
if (this->actor.parent != NULL) {
|
||||
EnEncount1* encount1 = (EnEncount1*)this->actor.parent;
|
||||
|
||||
if ((encount1->actor.update != NULL) && (encount1->unk_14E > 0)) {
|
||||
encount1->unk_14E--;
|
||||
if ((encount1->actor.update != NULL) && (encount1->spawnActiveCount > 0)) {
|
||||
encount1->spawnActiveCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#define WALLMASTER_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 8) & 0xFF)
|
||||
#define WALLMASTER_IS_FROZEN(thisx) ((thisx)->params & 0x80)
|
||||
|
||||
#define WALLMASTER_PARAMS(type, switchFlag, isFrozen) ((type) | (((switchFlag) << 8) & 0xFF) | (((isFrozen) << 7) & 0x80))
|
||||
|
||||
/**
|
||||
* This type determines under what conditions the Wallmaster will drop from the ceiling.
|
||||
* - WALLMASTER_TYPE_TIMER_ONLY: These Wallmasters don't check for anything to determine
|
||||
|
|
|
@ -6504,7 +6504,7 @@
|
|||
0x808E06B0:("DoorAna_Update",),
|
||||
0x808E0704:("DoorAna_Draw",),
|
||||
0x808E0830:("EnEncount1_Init",),
|
||||
0x808E0954:("func_808E0954",),
|
||||
0x808E0954:("EnEncount1_SpawnActor",),
|
||||
0x808E0DA8:("EnEncount1_Update",),
|
||||
0x808E0E40:("DemoTreLgt_Init",),
|
||||
0x808E0EBC:("DemoTreLgt_Destroy",),
|
||||
|
|
Loading…
Reference in New Issue