diff --git a/assets/xml/objects/object_pr.xml b/assets/xml/objects/object_pr.xml index cabdfa630b..4b7367221b 100644 --- a/assets/xml/objects/object_pr.xml +++ b/assets/xml/objects/object_pr.xml @@ -43,6 +43,7 @@ + @@ -60,7 +61,6 @@ - diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index 310da3bec2..16079531d1 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -31,15 +31,15 @@ ActorProfile En_Encount1_Profile = { 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 + ACTOR_EN_PR2, // EN_ENCOUNT1_SKULLFISH_RESPAWNING + ACTOR_EN_PR2, // EN_ENCOUNT1_SKULLFISH_PATHING }; static s16 sActorParams[] = { DRAGONFLY_PARAMS(DRAGONFLY_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 + ENPR2_PARAMS(1, 0), // EN_ENCOUNT1_SKULLFISH_RESPAWNING + ENPR2_PARAMS(3, 0) // EN_ENCOUNT1_SKULLFISH_PATHING }; void EnEncount1_Init(Actor* thisx, PlayState* play) { @@ -54,7 +54,7 @@ void EnEncount1_Init(Actor* thisx, PlayState* play) { 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->spawnDropTable = ENENCOUNT1_GET_SPAWN_DROP_TABLE(&this->actor); this->spawnDistanceMax = (ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(&this->actor) * 40.0f) + 120.0f; if (this->spawnTotalMax >= ENENCOUNT1_SPAWNS_TOTAL_MAX_INFINITE) { @@ -63,7 +63,7 @@ void EnEncount1_Init(Actor* thisx, PlayState* play) { if (ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(&this->actor) < 0) { this->spawnDistanceMax = -1.0f; } - if (this->type == EN_ENCOUNT1_SKULLFISH_2) { + if (this->type == EN_ENCOUNT1_SKULLFISH_PATHING) { this->pathIndex = ENENCOUNT1_GET_PATH_INDEX(&this->actor); this->path = SubS_GetPathByIndex(play, this->pathIndex, ENENCOUNT1_PATH_INDEX_NONE); this->spawnTotalMax = -1; @@ -122,7 +122,7 @@ void EnEncount1_SpawnActor(EnEncount1* this, PlayState* play) { Math_Vec3f_Copy(&spawnPos, &player->actor.world.pos); break; - case EN_ENCOUNT1_SKULLFISH: + case EN_ENCOUNT1_SKULLFISH_RESPAWNING: scale = Rand_CenteredFloat(250.0f) + 500.0f; rotY = player->actor.shape.rot.y; spawnPos.x = player->actor.world.pos.x + (Math_SinS(rotY) * scale) + Rand_CenteredFloat(40.0f); @@ -135,7 +135,7 @@ void EnEncount1_SpawnActor(EnEncount1* this, PlayState* play) { } break; - case EN_ENCOUNT1_SKULLFISH_2: + case EN_ENCOUNT1_SKULLFISH_PATHING: if ((this->path != NULL) && !SubS_CopyPointFromPath(this->path, 0, &spawnPos)) { Actor_Kill(&this->actor); } diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h index d8f7680617..bff4fc084e 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h @@ -8,19 +8,19 @@ #define ENENCOUNT1_GET_TYPE(thisx) (((thisx)->params >> 11) & 0x1F) #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_PATH_INDEX(thisx) ((thisx)->params & 0x3F) // Used only by EN_ENCOUNT1_SKULLFISH_PATHING which doesn't use SpawnTotalMax #define ENENCOUNT1_PATH_INDEX_NONE 0x3F #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_DROP_TABLE(thisx) ((thisx)->world.rot.y) // Read from EnPr2 #define ENENCOUNT1_GET_SPAWN_DISTANCE_MAX(thisx) ((thisx)->world.rot.z) // Negative means infinite distance typedef enum EnEncount1Enemy { /* 0 */ EN_ENCOUNT1_GRASSHOPPER, /* 1 */ EN_ENCOUNT1_WALLMASTER, - /* 2 */ EN_ENCOUNT1_SKULLFISH, - /* 3 */ EN_ENCOUNT1_SKULLFISH_2 // path required + /* 2 */ EN_ENCOUNT1_SKULLFISH_RESPAWNING, + /* 3 */ EN_ENCOUNT1_SKULLFISH_PATHING // path required } EnEncount1Enemy; struct EnEncount1; @@ -39,7 +39,7 @@ typedef struct EnEncount1 { /* 0x156 */ s16 timer; /* 0x158 */ s16 spawnTimeMin; /* 0x15A */ s16 pathIndex; - /* 0x15C */ s32 spawnUnusedProp; + /* 0x15C */ s32 spawnDropTable; // unused by us, passed to EnPr2 /* 0x160 */ f32 spawnDistanceMax; } EnEncount1; // size = 0x164 diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c index 9c919c22d4..998638df8d 100644 --- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c +++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c @@ -96,25 +96,25 @@ ActorProfile En_Pr2_Profile = { }; typedef enum EnPr2Animation { - /* 0 */ PR2_ANIM_GENTLE_SWIM, - /* 1 */ PR2_ANIM_FAST_SWIM, - /* 2 */ PR2_ANIM_FLINCH, + /* 0 */ PR2_ANIM_SWIM, + /* 1 */ PR2_ANIM_ATTACK, + /* 2 */ PR2_ANIM_DIE, /* 3 */ ENPR2_ANIM_MAX } EnPr2Animation; static AnimationHeader* sAnimations[ENPR2_ANIM_MAX] = { - &gSkullFishSwimAnim, // PR2_ANIM_GENTLE_SWIM - &gSkullFishAttackAnim, // PR2_ANIM_FAST_SWIM - &gSkullFishDieAnim, // PR2_ANIM_FLINCH + &gSkullFishSwimAnim, // PR2_ANIM_SWIM + &gSkullFishAttackAnim, // PR2_ANIM_ATTACK + &gSkullFishDieAnim, // PR2_ANIM_DIE }; static u8 sAnimationModes[ENPR2_ANIM_MAX] = { - ANIMMODE_LOOP, // PR2_ANIM_GENTLE_SWIM - ANIMMODE_LOOP, // PR2_ANIM_FAST_SWIM - ANIMMODE_ONCE, // PR2_ANIM_FLINCH + ANIMMODE_LOOP, // PR2_ANIM_SWIM + ANIMMODE_LOOP, // PR2_ANIM_ATTACK + ANIMMODE_ONCE, // PR2_ANIM_DIE }; -// ... why? why not just lshift the index by 4? +// ... ? why not just lshift the index by 4? static s16 sDropTables[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, }; @@ -132,27 +132,29 @@ void EnPr2_Init(Actor* thisx, PlayState* play) { this->morphTable, OBJECT_PR_2_LIMB_MAX); this->type = ENPR2_GET_TYPE(&this->actor); this->actor.colChkInfo.mass = 10; - Math_Vec3f_Copy(&this->originalHome, &this->actor.home.pos); + Math_Vec3f_Copy(&this->newHome, &this->actor.home.pos); if (this->type == PR2_TYPE_RESIDENT) { - this->agroDistance = ENPR2_GET_FF0(&this->actor) * 20.0f; + this->agroDistance = ENPR2_GET_AGRO_DISTANCE(&this->actor) * 20.0f; } + this->alpha = 255; this->actor.shape.yOffset = 500.0f; this->actor.shape.shadowScale = 12.0f; - if (this->type < PR2_TYPE_BROKEN) { + if (this->type < PR2_TYPE_BROKEN) { // regular spawns ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); this->dropID = -1; this->scale = 0.0f; + // spawned by EnEncount1 if (this->actor.parent != NULL) { Actor* encount1 = this->actor.parent; if (encount1->update != NULL) { - if (ENPR2_GET_PARENTY_DROPID(encount1) != 0) { - this->dropID = ENPR2_GET_PARENTY_DROPID(encount1) - 1; + if (ENPR2_GETY_PARENT_DROPID(encount1) != 0) { + this->dropID = ENPR2_GETY_PARENT_DROPID(encount1) - 1; } } } else if (ENPR2_GETZ_DROPID(thisx) != 0) { @@ -167,7 +169,7 @@ void EnPr2_Init(Actor* thisx, PlayState* play) { if (encount1->update != NULL) { this->pathIndex = ((EnEncount1*)encount1)->pathIndex; this->path = SubS_GetPathByIndex(play, this->pathIndex, ENPR2_PATH_INDEX_NONE); - this->agroDistance = ENPR2_GET_PARENTZ_UNK(encount1) * 20.0f; + this->agroDistance = ENPR2_GETZ_PARENT_AGRO_DISTANCE(encount1) * 20.0f; if (this->agroDistance < 20.0f) { this->agroDistance = 20.0f; } @@ -191,6 +193,7 @@ void EnPr2_Init(Actor* thisx, PlayState* play) { UPDBGCHECKINFO_FLAG_10); if (!(this->actor.bgCheckFlags & (BGCHECKFLAG_WATER | BGCHECKFLAG_WATER_TOUCH))) { + // no spawning in air Actor_Kill(&this->actor); } } @@ -232,8 +235,7 @@ s32 EnPr2_IsOnScreen(EnPr2* this, PlayState* play) { } } -// control yaw direction? is this overall? -void func_80A7436C(EnPr2* this, s16 targetYRot) { +void EnPr2_HandleYaw(EnPr2* this, s16 targetYRot) { s16 yawDiff = targetYRot - this->actor.world.rot.y; if (yawDiff > 10000) { @@ -273,7 +275,7 @@ void EnPr2_ChangeAnim(EnPr2* this, s32 animIndex) { } void EnPr2_SetupFollowPath(EnPr2* this) { - EnPr2_ChangeAnim(this, PR2_ANIM_GENTLE_SWIM); + EnPr2_ChangeAnim(this, PR2_ANIM_SWIM); this->state = PR2_STATE_PATHING; this->actionFunc = EnPr2_FollowPath; } @@ -317,7 +319,7 @@ void EnPr2_FollowPath(EnPr2* this, PlayState* play) { if (waypointDist < (Rand_ZeroFloat(20.0f) + 15.0f)) { this->waypoint++; - Math_Vec3f_Copy(&this->originalHome, &this->actor.world.pos); + Math_Vec3f_Copy(&this->newHome, &this->actor.world.pos); if (this->waypoint >= this->path->count) { // destination reached this->type = PR2_TYPE_RESIDENT; @@ -326,32 +328,32 @@ void EnPr2_FollowPath(EnPr2* this, PlayState* play) { } this->yawTowardsWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); - func_80A7436C(this, this->yawTowardsWaypoint); + EnPr2_HandleYaw(this, this->yawTowardsWaypoint); } void EnPr2_SetupIdle(EnPr2* this) { - EnPr2_ChangeAnim(this, PR2_ANIM_GENTLE_SWIM); + EnPr2_ChangeAnim(this, PR2_ANIM_SWIM); this->waypointTimer = 2; - this->timer = 0; - Math_Vec3f_Copy(&this->waypointPos, &this->originalHome); + this->mainTimer = 0; + Math_Vec3f_Copy(&this->waypointPos, &this->newHome); this->state = PR2_STATE_IDLE; this->actionFunc = EnPr2_Idle; } void EnPr2_Idle(EnPr2* this, PlayState* play) { Player* player = GET_PLAYER(play); - f32 deltaX; // reused for two separate purposes + f32 deltaX; // reused for both dist-to-player and dist-to-home f32 deltaZ; f32 sqrtXZ; - s32 updateFlag = false; // think this is "Needs updated pos/target" - s32 swimming = false; // TODO needs double checking + s32 changingCourse = false; + s32 swimmingStraight = false; Vec3f currentPos; // this describes where it starts, not what its doing, rename Math_ApproachF(&this->scale, 0.02f, 0.1f, 0.005f); Actor_PlaySfx(&this->actor, NA_SE_EN_PIRANHA_EXIST - SFX_FLAG); if (fabsf(this->actor.world.rot.y - this->yawTowardsWaypoint) < 200.0f) { - swimming = true; + swimmingStraight = true; SkelAnime_Update(&this->skelAnime); } @@ -365,7 +367,7 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { switch (this->type) { case PR2_TYPE_SPAWNED: if (this->targetingTimer == 0) { - updateFlag = true; + changingCourse = true; EnPr2_SetupAttack(this, play); } else if (!EnPr2_IsOnScreen(this, play) && (this->alpha == 255)) { // despawn if not on screen @@ -376,25 +378,25 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { case PR2_TYPE_RESIDENT: if (this->returnHomeTimer == 0) { // distance diff from player to home - deltaX = player->actor.world.pos.x - this->originalHome.x; - deltaZ = player->actor.world.pos.z - this->originalHome.z; + deltaX = player->actor.world.pos.x - this->newHome.x; + deltaZ = player->actor.world.pos.z - this->newHome.z; sqrtXZ = sqrtf(SQ(deltaX) + SQ(deltaZ)); - if (swimming && (player->stateFlags1 & PLAYER_STATE1_8000000) && (sqrtXZ < this->agroDistance)) { - updateFlag = true; + if (swimmingStraight && (player->stateFlags1 & PLAYER_STATE1_8000000) && (sqrtXZ < this->agroDistance)) { + changingCourse = true; EnPr2_SetupAttack(this, play); } } else { // distance diff from current pos to home - deltaX = this->actor.world.pos.x - this->originalHome.x; - deltaZ = this->actor.world.pos.z - this->originalHome.z; + deltaX = this->actor.world.pos.x - this->newHome.x; + deltaZ = this->actor.world.pos.z - this->newHome.z; sqrtXZ = sqrtf(SQ(deltaX) + SQ(deltaZ)); if (sqrtXZ > 20.0f) { this->returnHomeTimer = 5; - updateFlag = true; + changingCourse = true; this->targetingTimer = 0; - Math_Vec3f_Copy(&this->waypointPos, &this->originalHome); + Math_Vec3f_Copy(&this->waypointPos, &this->newHome); Math_ApproachF(&this->actor.speed, 3.0f, 0.3f, 0.2f); } } @@ -404,7 +406,8 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { break; } - if (!updateFlag) { + // if we already plan to change behavior, ignore this expensive maintanence code + if (!changingCourse) { this->waypointPos.y = this->actor.world.pos.y; if (this->waypointTimer != 0) { if ((Rand_ZeroOne() < 0.3f) && !this->bubbleToggle) { @@ -414,8 +417,8 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { Math_ApproachZeroF(&this->actor.speed, 0.1f, 0.2f); if (this->waypointTimer == 1) { - this->timer = Rand_S16Offset(100, 100); - Math_Vec3f_Copy(¤tPos, &this->originalHome); + this->mainTimer = Rand_S16Offset(100, 100); + Math_Vec3f_Copy(¤tPos, &this->newHome); currentPos.x += Rand_CenteredFloat(300.0f); currentPos.z += Rand_CenteredFloat(300.0f); Math_Vec3f_Copy(&this->waypointPos, ¤tPos); @@ -428,10 +431,10 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { if (fabsf(this->actor.world.rot.y - this->yawTowardsWaypoint) < 100.0f) { if (BgCheck_SphVsFirstPoly(&play->colCtx, ¤tPos, 20.0f) || (this->actor.bgCheckFlags & BGCHECKFLAG_WALL)) { - // dam + // Dam this->targetingTimer = 0; this->wallCollisionCounter++; - Math_Vec3f_Copy(&this->waypointPos, &this->originalHome); + Math_Vec3f_Copy(&this->waypointPos, &this->newHome); if (this->wallCollisionCounter > 10) { this->wallCollisionAngleAdjustment += 0x2000; } @@ -441,7 +444,7 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { } } - if ((this->timer == 0) || ((fabsf(this->waypointPos.x - this->actor.world.pos.x) < 10.0f) && + if ((this->mainTimer == 0) || ((fabsf(this->waypointPos.x - this->actor.world.pos.x) < 10.0f) && (fabsf(this->waypointPos.z - this->actor.world.pos.z) < 10.0f))) { this->waypointTimer = Rand_S16Offset(20, 30); } @@ -450,7 +453,7 @@ void EnPr2_Idle(EnPr2* this, PlayState* play) { if (this->waypointTimer == 0) { this->yawTowardsWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos) + this->wallCollisionAngleAdjustment; - func_80A7436C(this, this->yawTowardsWaypoint); + EnPr2_HandleYaw(this, this->yawTowardsWaypoint); } } } @@ -459,14 +462,14 @@ void EnPr2_SetupAttack(EnPr2* this, PlayState* play) { Player* player = GET_PLAYER(play); this->wallCollisionAngleAdjustment = 0; - EnPr2_ChangeAnim(this, PR2_ANIM_FAST_SWIM); + EnPr2_ChangeAnim(this, PR2_ANIM_ATTACK); Actor_PlaySfx(&this->actor, NA_SE_EN_PIRANHA_ATTACK); Math_Vec3f_Copy(&this->waypointPos, &player->actor.world.pos); this->yawTowardsWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); this->randomTargetHeightOffset = Rand_ZeroFloat(30.0f); this->targetingTimer = 0; - this->timer = (3 * 20) + 10; + this->mainTimer = 3.5 * 20; this->state = PR2_STATE_ATTACKING; this->actionFunc = EnPr2_Attack; } @@ -476,7 +479,7 @@ void EnPr2_Attack(EnPr2* this, PlayState* play) { WaterBox* waterBox; Math_ApproachF(&this->scale, 0.02f, 0.1f, 0.005f); - if ((this->timer == 0) || !(player->stateFlags1 & PLAYER_STATE1_8000000) || (this->type == PR2_TYPE_PASSIVE)) { + if ((this->mainTimer == 0) || !(player->stateFlags1 & PLAYER_STATE1_8000000) || (this->type == PR2_TYPE_PASSIVE)) { EnPr2_SetupIdle(this); return; } @@ -504,8 +507,8 @@ void EnPr2_Attack(EnPr2* this, PlayState* play) { this->wallCollisionAngleAdjustment = 0; if (this->type == PR2_TYPE_RESIDENT) { - f32 deltaX = this->actor.world.pos.x - this->originalHome.x; - f32 deltaZ = this->actor.world.pos.z - this->originalHome.z; + f32 deltaX = this->actor.world.pos.x - this->newHome.x; + f32 deltaZ = this->actor.world.pos.z - this->newHome.z; f32 homeDistance = sqrtf(SQ(deltaX) + SQ(deltaZ)); if (homeDistance > this->agroDistance) { @@ -514,8 +517,8 @@ void EnPr2_Attack(EnPr2* this, PlayState* play) { return; } } else { - // like scuttlebug? - Math_Vec3f_Copy(&this->originalHome, &this->actor.world.pos); + // home moves to follow player, like scuttlebug + Math_Vec3f_Copy(&this->newHome, &this->actor.world.pos); } if (WaterBox_GetSurface1(play, &play->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, @@ -532,13 +535,13 @@ void EnPr2_Attack(EnPr2* this, PlayState* play) { } else { if (this->collider.base.atFlags & AT_HIT) { this->targetingTimer = Rand_S16Offset(30, 30); - this->timer = 20 * 5; + this->mainTimer = 5 * 20; if (this->type != PR2_TYPE_RESIDENT) { EnPr2_SetupIdle(this); } } this->yawTowardsWaypoint = Math_Vec3f_Yaw(&this->actor.world.pos, &this->waypointPos); - func_80A7436C(this, this->yawTowardsWaypoint); + EnPr2_HandleYaw(this, this->yawTowardsWaypoint); } } } @@ -548,12 +551,12 @@ void EnPr2_SetupDie(EnPr2* this) { this->actor.flags |= ACTOR_FLAG_LOCK_ON_DISABLED; this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED; if (this->type < PR2_TYPE_BROKEN) { - EnPr2_ChangeAnim(this, PR2_ANIM_FLINCH); + EnPr2_ChangeAnim(this, PR2_ANIM_DIE); } else { this->animEndFrame = Animation_GetLastFrame(&gSkullFishDieAnim); Animation_Change(&this->skelAnime, &gSkullFishDieAnim, 1.0f, this->animEndFrame, this->animEndFrame, ANIMMODE_ONCE, 0.0f); - this->timer = Rand_S16Offset(20, 30); + this->mainTimer = Rand_S16Offset(20, 30); this->targetZRot = 0x4000; if (Rand_ZeroOne() < 0.5f) { this->targetZRot = -0x4000; @@ -562,7 +565,7 @@ void EnPr2_SetupDie(EnPr2* this) { this->actor.shape.rot.x = this->actor.world.rot.x; this->actor.shape.rot.y = this->actor.world.rot.y; this->actor.shape.rot.z = this->actor.world.rot.z; - this->timer = 20 + 10; + this->mainTimer = 1.5 * 20; this->actor.speed = Rand_ZeroFloat(0.5f); this->actor.world.rot.y = Rand_CenteredFloat(0x8000); } @@ -582,7 +585,7 @@ void EnPr2_Die(EnPr2* this, PlayState* play) { curFrame = this->skelAnime.curFrame; - if (curFrame >= this->animEndFrame) { // flinch animation done + if (curFrame >= this->animEndFrame) { // death animation done // spawn LIMB_COUNT EnPr2, one for each limb, to draw floating pieces for (i = 0; i < ARRAY_COUNT(this->limbPos); i++) { Actor_Spawn(&play->actorCtx, play, ACTOR_EN_PR2, this->limbPos[i].x, this->limbPos[i].y, @@ -614,7 +617,7 @@ void EnPr2_Die(EnPr2* this, PlayState* play) { } } - if ((this->timer == 0) || nearSurface) { + if ((this->mainTimer == 0) || nearSurface) { s32 i; Math_SmoothStepToS(&this->alpha, 0, 1, 15, 50); @@ -655,7 +658,7 @@ void EnPr2_ApplyDamage(EnPr2* this, PlayState* play) { } } - // Huh? + // against mikau shild? if (this->collider.base.atFlags & AT_BOUNCED) { this->actor.speed = -10.0f; } @@ -670,7 +673,7 @@ void EnPr2_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); DECR(this->waypointTimer); - DECR(this->timer); + DECR(this->mainTimer); DECR(this->targetingTimer); DECR(this->returnHomeTimer); @@ -748,6 +751,7 @@ s32 EnPr2_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p if (this->type < PR2_TYPE_BROKEN) { if (limbIndex == OBJECT_PR_2_LIMB_02) { + // head is upside down in the animations for some reason, they decided to fix it here? rot->y += TRUNCF_BINANG(this->slowLimbYaw) * -1; } } else if ((limbIndex + PR2_TYPE_BROKEN) != this->type) { diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h index 3d3286bc52..02e755ff94 100644 --- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h +++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h @@ -8,13 +8,19 @@ struct EnPr2; typedef void (*EnPr2ActionFunc)(struct EnPr2*, PlayState*); -#define ENPR2_GET_TYPE(thisx) ((thisx)->params & 0xF) -// distance? -#define ENPR2_GET_FF0(thisx) (((thisx)->params >> 4) & 0xFF) +// I wonder if they planned more for this actor, because there +// is room enough in params without using rotation of the parent +#define ENPR2_GET_TYPE(thisx) ((thisx)->params & 0xF) +// only used for type PR2_TYPE_RESIDENT (agro distance is 1/20th of final units) +#define ENPR2_GET_AGRO_DISTANCE(thisx) (((thisx)->params >> 4) & 0xFF) + +// only if we are NOT spawned by a parent actor #define ENPR2_GETZ_DROPID(thisx) ((thisx)->world.rot.z) -#define ENPR2_GET_PARENTY_DROPID(parent) ((parent)->world.rot.y) -#define ENPR2_GET_PARENTZ_UNK(parent) ((parent)->world.rot.z) +// only if we are spawned by En_Encount1 +#define ENPR2_GETY_PARENT_DROPID(parent) ((parent)->world.rot.y) +// agro distance is 1/20th of final distance +#define ENPR2_GETZ_PARENT_AGRO_DISTANCE(parent) ((parent)->world.rot.z) #define ENPR2_PATH_INDEX_NONE 0x3F #define ENPR2_PARAMS(paramF, paramFF0) (((paramF) & 0xF) | (((paramFF0) << 4) & 0xFF0)) @@ -46,7 +52,7 @@ typedef struct EnPr2 { /* 0x1D0 */ s32 waypoint; /* 0x1D4 */ s16 state; /* 0x1D6 */ s16 bubbleToggle; - /* 0x1D8 */ s16 timer; + /* 0x1D8 */ s16 mainTimer; /* 0x1DA */ s16 waypointTimer; // path related, maybe rename /* 0x1DC */ s16 targetingTimer; // on zero, attack attempt on player /* 0x1DE */ s16 returnHomeTimer; // frames until attacking player acceptable again @@ -70,7 +76,7 @@ typedef struct EnPr2 { /* 0x214 */ UNK_TYPE1 unk214[4]; /* 0x218 */ s32 dropID; /* 0x21C */ Vec3f waypointPos; - /* 0x228 */ Vec3f originalHome; + /* 0x228 */ Vec3f newHome; /* 0x234 */ Vec3f limbPos[5]; /* 0x270 */ Vec3f limbJawPos; /* 0x27C */ ColliderCylinder collider; diff --git a/tools/disasm/n64-us/functions.txt b/tools/disasm/n64-us/functions.txt index 41989384a6..d3e9f42176 100644 --- a/tools/disasm/n64-us/functions.txt +++ b/tools/disasm/n64-us/functions.txt @@ -11015,7 +11015,7 @@ EnDno_PostLimbDraw = 0x80A73654; // type:func EnPr2_Init = 0x80A73FA0; // type:func EnPr2_Destroy = 0x80A7422C; // type:func EnPr2_IsOnScreen = 0x80A7429C; // type:func -func_80A7436C = 0x80A7436C; // type:func +EnPr2_HandleYaw = 0x80A7436C; // type:func EnPr2_ChangeAnim = 0x80A74510; // type:func EnPr2_SetupFollowPath = 0x80A745C4; // type:func EnPr2_FollowPath = 0x80A745FC; // type:func