EnGe2 (Gerudo in Purple) OK and documented, object_gla documented (#1071)

* OK, data imported

* Permuter settings

* Name data, a few functions and variables, cleanup

* Small amount of cleanup on some related actors

* Oops

* Document object

* Type and other macros

* Some cutscene stuff and temporary function names

* Proper path function names

* Name a couple more functions

* A couple more function names

* Name PathStatus enum

* Name rest of functions and formalise the documentation a bit

* Apply suggestions from code review

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>

* limbs

* Format

* Review

* format

* weekeventregconvert and format

---------

Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: angie <angheloalf95@gmail.com>
This commit is contained in:
EllipticEllipsis 2023-02-24 14:59:17 +00:00 committed by GitHub
parent 3e257354c1
commit 69f7540e33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 993 additions and 254 deletions

View File

@ -1,73 +1,78 @@
<Root>
<!-- object for the assets for ovl_En_Ge2 (Purple-clad Gerudo) -->
<File Name="object_gla" Segment="6">
<Animation Name="object_gla_Anim_00030C" Offset="0x30C" />
<Animation Name="object_gla_Anim_000460" Offset="0x460" />
<Animation Name="object_gla_Anim_000794" Offset="0x794" />
<Animation Name="object_gla_Anim_000BF0" Offset="0xBF0" />
<Animation Name="object_gla_Anim_001664" Offset="0x1664" />
<Animation Name="object_gla_Anim_001A40" Offset="0x1A40" />
<Animation Name="object_gla_Anim_001FAC" Offset="0x1FAC" />
<DList Name="object_gla_DL_0039B0" Offset="0x39B0" />
<DList Name="object_gla_DL_003E50" Offset="0x3E50" />
<DList Name="object_gla_DL_003F88" Offset="0x3F88" />
<DList Name="object_gla_DL_004188" Offset="0x4188" />
<DList Name="object_gla_DL_0042C0" Offset="0x42C0" />
<DList Name="object_gla_DL_0044C0" Offset="0x44C0" />
<DList Name="object_gla_DL_004658" Offset="0x4658" />
<DList Name="object_gla_DL_004768" Offset="0x4768" />
<DList Name="object_gla_DL_004928" Offset="0x4928" />
<DList Name="object_gla_DL_004A38" Offset="0x4A38" />
<Texture Name="object_gla_TLUT_004BF8" OutName="tlut_004BF8" Format="rgba16" Width="16" Height="16" Offset="0x4BF8" />
<Texture Name="object_gla_Tex_004DF8" OutName="tex_004DF8" Format="ci8" Width="8" Height="8" Offset="0x4DF8" />
<Texture Name="object_gla_Tex_004E38" OutName="tex_004E38" Format="ci8" Width="8" Height="8" Offset="0x4E38" />
<Texture Name="object_gla_Tex_004E78" OutName="tex_004E78" Format="ci8" Width="16" Height="16" Offset="0x4E78" />
<Texture Name="object_gla_Tex_004F78" OutName="tex_004F78" Format="ci8" Width="16" Height="16" Offset="0x4F78" />
<Texture Name="object_gla_Tex_005078" OutName="tex_005078" Format="i8" Width="16" Height="16" Offset="0x5078" />
<!-- <Blob Name="object_gla_Blob_005178" Size="0x1B0" Offset="0x5178" /> -->
<Texture Name="object_gla_Tex_005328" OutName="tex_005328" Format="ci8" Width="8" Height="8" Offset="0x5328" />
<Texture Name="object_gla_Tex_005368" OutName="tex_005368" Format="ci8" Width="8" Height="16" Offset="0x5368" />
<!-- <Blob Name="object_gla_Blob_0053E8" Size="0x400" Offset="0x53E8" /> -->
<Texture Name="object_gla_Tex_0057E8" OutName="tex_0057E8" Format="ci8" Width="8" Height="8" Offset="0x57E8" />
<Texture Name="object_gla_Tex_005828" OutName="tex_005828" Format="i8" Width="16" Height="16" Offset="0x5828" />
<Texture Name="object_gla_Tex_005928" OutName="tex_005928" Format="ci8" Width="8" Height="16" Offset="0x5928" />
<Texture Name="object_gla_Tex_0059A8" OutName="tex_0059A8" Format="ci8" Width="8" Height="8" Offset="0x59A8" />
<!-- <Blob Name="object_gla_Blob_0059E8" Size="0x400" Offset="0x59E8" /> -->
<Texture Name="object_gla_Tex_005DE8" OutName="tex_005DE8" Format="i8" Width="8" Height="16" Offset="0x5DE8" />
<Texture Name="object_gla_Tex_005E68" OutName="tex_005E68" Format="ci8" Width="16" Height="16" Offset="0x5E68" />
<Texture Name="object_gla_Tex_005F68" OutName="tex_005F68" Format="i8" Width="16" Height="16" Offset="0x5F68" />
<!-- <Blob Name="object_gla_Blob_006068" Size="0x400" Offset="0x6068" /> -->
<DList Name="object_gla_DL_007DE8" Offset="0x7DE8" />
<DList Name="object_gla_DL_007FA8" Offset="0x7FA8" />
<DList Name="object_gla_DL_008168" Offset="0x8168" />
<DList Name="object_gla_DL_0082D0" Offset="0x82D0" />
<DList Name="object_gla_DL_008438" Offset="0x8438" />
<DList Name="object_gla_DL_008628" Offset="0x8628" />
<DList Name="object_gla_DL_0086E0" Offset="0x86E0" />
<DList Name="object_gla_DL_0087D0" Offset="0x87D0" />
<Limb Name="object_gla_Standardlimb_008C88" Type="Standard" EnumName="OBJECT_GLA_LIMB_01" Offset="0x8C88" />
<Limb Name="object_gla_Standardlimb_008C94" Type="Standard" EnumName="OBJECT_GLA_LIMB_02" Offset="0x8C94" />
<Limb Name="object_gla_Standardlimb_008CA0" Type="Standard" EnumName="OBJECT_GLA_LIMB_03" Offset="0x8CA0" />
<Limb Name="object_gla_Standardlimb_008CAC" Type="Standard" EnumName="OBJECT_GLA_LIMB_04" Offset="0x8CAC" />
<Limb Name="object_gla_Standardlimb_008CB8" Type="Standard" EnumName="OBJECT_GLA_LIMB_05" Offset="0x8CB8" />
<Limb Name="object_gla_Standardlimb_008CC4" Type="Standard" EnumName="OBJECT_GLA_LIMB_06" Offset="0x8CC4" />
<Limb Name="object_gla_Standardlimb_008CD0" Type="Standard" EnumName="OBJECT_GLA_LIMB_07" Offset="0x8CD0" />
<Limb Name="object_gla_Standardlimb_008CDC" Type="Standard" EnumName="OBJECT_GLA_LIMB_08" Offset="0x8CDC" />
<Limb Name="object_gla_Standardlimb_008CE8" Type="Standard" EnumName="OBJECT_GLA_LIMB_09" Offset="0x8CE8" />
<Limb Name="object_gla_Standardlimb_008CF4" Type="Standard" EnumName="OBJECT_GLA_LIMB_0A" Offset="0x8CF4" />
<Limb Name="object_gla_Standardlimb_008D00" Type="Standard" EnumName="OBJECT_GLA_LIMB_0B" Offset="0x8D00" />
<Limb Name="object_gla_Standardlimb_008D0C" Type="Standard" EnumName="OBJECT_GLA_LIMB_0C" Offset="0x8D0C" />
<Limb Name="object_gla_Standardlimb_008D18" Type="Standard" EnumName="OBJECT_GLA_LIMB_0D" Offset="0x8D18" />
<Limb Name="object_gla_Standardlimb_008D24" Type="Standard" EnumName="OBJECT_GLA_LIMB_0E" Offset="0x8D24" />
<Limb Name="object_gla_Standardlimb_008D30" Type="Standard" EnumName="OBJECT_GLA_LIMB_0F" Offset="0x8D30" />
<Limb Name="object_gla_Standardlimb_008D3C" Type="Standard" EnumName="OBJECT_GLA_LIMB_10" Offset="0x8D3C" />
<Limb Name="object_gla_Standardlimb_008D48" Type="Standard" EnumName="OBJECT_GLA_LIMB_11" Offset="0x8D48" />
<Limb Name="object_gla_Standardlimb_008D54" Type="Standard" EnumName="OBJECT_GLA_LIMB_12" Offset="0x8D54" />
<Limb Name="object_gla_Standardlimb_008D60" Type="Standard" EnumName="OBJECT_GLA_LIMB_13" Offset="0x8D60" />
<Limb Name="object_gla_Standardlimb_008D6C" Type="Standard" EnumName="OBJECT_GLA_LIMB_14" Offset="0x8D6C" />
<Limb Name="object_gla_Standardlimb_008D78" Type="Standard" EnumName="OBJECT_GLA_LIMB_15" Offset="0x8D78" />
<Skeleton Name="object_gla_Skel_008DD8" Type="Flex" LimbType="Standard" LimbNone="OBJECT_GLA_LIMB_NONE" LimbMax="OBJECT_GLA_LIMB_MAX" EnumName="ObjectGlaLimb" Offset="0x8DD8" />
<Animation Name="object_gla_Anim_0091D0" Offset="0x91D0" />
<Animation Name="object_gla_Anim_009D1C" Offset="0x9D1C" />
<Animation Name="object_gla_Anim_00A344" Offset="0xA344" />
<Animation Name="gGerudoPurpleRunningAwayCutsceneAnim" Offset="0x30C" /><!-- Original name: g_yari_nigedasu -->
<Animation Name="gGerudoPurpleGreatBayCutsceneAnim" Offset="0x460" /><!-- Original name: g_yari_twister -->
<!-- Identical to OoT's object_gla from here to the end -->
<Animation Name="gGerudoPurpleHorizontalSlashAnim" Offset="0x794" /><!-- Unused. Original name: geldA_attack -->
<Animation Name="gGerudoPurpleSlashToStandingAnim" Offset="0xBF0" /><!-- Usused. Original name: geldA_attack_end -->
<Animation Name="gGerudoPurpleFallingToGroundAnim" Offset="0x1664" /><!-- Original name: geldA_down -->
<Animation Name="gGerudoPurpleStandingToCrouchAnim" Offset="0x1A40" /><!-- Unused. Original name: geldA_find -->
<Animation Name="gGerudoPurpleCrouchingLookAroundAnim" Offset="0x1FAC" /><!-- Unused. Original name: geldA_find_wait -->
<DList Name="gGerudoPurpleTorsoDL" Offset="0x39B0" />
<DList Name="gGerudoPurpleLeftUpperArmDL" Offset="0x3E50" />
<DList Name="gGerudoPurpleLeftForearmDL" Offset="0x3F88" />
<DList Name="gGerudoPurpleRightUpperArmDL" Offset="0x4188" />
<DList Name="gGerudoPurpleRightForearmDL" Offset="0x42C0" />
<DList Name="gGerudoPurpleWaistDL" Offset="0x44C0" />
<DList Name="gGerudoPurpleRightThighDL" Offset="0x4658" />
<DList Name="gGerudoPurpleRightShinDL" Offset="0x4768" />
<DList Name="gGerudoPurpleLeftThighDL" Offset="0x4928" />
<DList Name="gGerudoPurpleLeftShinDL" Offset="0x4A38" />
<Texture Name="gGerudoPurple1TLUT" OutName="gerudo_purple_1_tlut" Format="rgba16" Width="16" Height="16" Offset="0x4BF8" />
<Texture Name="gGerudoPurpleSkinShadowTex" OutName="gerudo_purple_skin_shadow" Format="ci8" Width="8" Height="8" Offset="0x4DF8" TlutOffset="0x4BF8" />
<Texture Name="gGerudoPurpleDarkFabricTex" OutName="gerudo_purple_dark_fabric" Format="ci8" Width="8" Height="8" Offset="0x4E38" TlutOffset="0x4BF8" />
<Texture Name="gGerudoPurpleNavelTex" OutName="gerudo_purple_navel" Format="ci8" Width="16" Height="16" Offset="0x4E78" TlutOffset="0x4BF8" />
<Texture Name="gGerudoPurpleChestJewelTex" OutName="gerudo_purple_chest_jewel" Format="ci8" Width="16" Height="16" Offset="0x4F78" TlutOffset="0x4BF8" />
<Texture Name="gGerudoPurpleFabricFoldTex" OutName="gerudo_purple_fabric_fold" Format="i8" Width="16" Height="16" Offset="0x5078" />
<Texture Name="gGerudoPurple2TLUT" OutName="gerudo_purple_2_tlut" Format="rgba16" Width="18" Height="12" Offset="0x5178" />
<Texture Name="gGerudoPurpleSkinEdgeTex" OutName="gerudo_purple_skin_edge" Format="ci8" Width="8" Height="8" Offset="0x5328" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleEarTex" OutName="gerudo_purple_ear" Format="ci8" Width="8" Height="16" Offset="0x5368" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleEyeOpenTex" OutName="gerudo_purple_eye_open" Format="ci8" Width="32" Height="32" Offset="0x53E8" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleGlaiveGuard" OutName="gerudo_purple_glaive_guard" Format="i8" Width="8" Height="8" Offset="0x57E8" />
<Texture Name="gGerudoPurpleGlaiveBladeFabricPatternTex" OutName="gerudo_purple_fabric_pattern" Format="i8" Width="16" Height="16" Offset="0x5828" />
<Texture Name="gGerudoPurpleShoeUpperTex" OutName="gerudo_purple_shoe_upper" Format="ci8" Width="8" Height="16" Offset="0x5928" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleGlaiveHaftShoeSoleTex" OutName="gerudo_purple_glaive_haft_shoe_sole" Format="ci8" Width="8" Height="8" Offset="0x59A8" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleEyeHalfTex" OutName="gerudo_purple_eye_half" Format="ci8" Width="32" Height="32" Offset="0x59E8" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleMetalTex" OutName="gerudo_purple_metal" Format="i8" Width="8" Height="16" Offset="0x5DE8" />
<Texture Name="gGerudoPurpleHairTex" OutName="gerudo_purple_hair" Format="ci8" Width="16" Height="16" Offset="0x5E68" TlutOffset="0x5178" />
<Texture Name="gGerudoPurpleLipsFingersTex" OutName="gerudo_purple_lips_fingers" Format="i8" Width="16" Height="16" Offset="0x5F68" />
<Texture Name="gGerudoPurpleEyeClosedTex" OutName="gerudo_purple_eye_closed" Format="ci8" Width="32" Height="32" Offset="0x6068" TlutOffset="0x5178" />
<DList Name="gGerudoPurpleRightHandDL" Offset="0x7DE8" />
<DList Name="gGerudoPurpleGlaiveDL" Offset="0x7FA8" />
<DList Name="gGerudoPurpleLeftHandDL" Offset="0x8168" />
<DList Name="gGerudoPurpleLeftFootDL" Offset="0x82D0" />
<DList Name="gGerudoPurpleRightFootDL" Offset="0x8438" />
<DList Name="gGerudoPurpleVeilDL" Offset="0x8628" />
<DList Name="gGerudoPurplePonytailDL" Offset="0x86E0" />
<DList Name="gGerudoPurpleHeadDL" Offset="0x87D0" />
<Limb Name="gGerudoPurpleRootLimb" Type="Standard" EnumName="GERUDO_PURPLE_ROOT_LIMB" Offset="0x8C88" />
<Limb Name="gGerudoPurpleTorsoLimb" Type="Standard" EnumName="GERUDO_PURPLE_TORSO_LIMB" Offset="0x8C94" />
<Limb Name="gGerudoPurpleNeckLimb" Type="Standard" EnumName="GERUDO_PURPLE_NECK_LIMB" Offset="0x8CA0" />
<Limb Name="gGerudoPurplePonytailLimb" Type="Standard" EnumName="GERUDO_PURPLE_PONYTAIL_LIMB" Offset="0x8CAC" />
<Limb Name="gGerudoPurpleVeilLimb" Type="Standard" EnumName="GERUDO_PURPLE_VEIL_LIMB" Offset="0x8CB8" />
<Limb Name="gGerudoPurpleHeadLimb" Type="Standard" EnumName="GERUDO_PURPLE_HEAD_LIMB" Offset="0x8CC4" />
<Limb Name="gGerudoPurpleRightUpperArmLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_UPPER_ARM_LIMB" Offset="0x8CD0" />
<Limb Name="gGerudoPurpleRightForearmLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_FOREARM_LIMB" Offset="0x8CDC" />
<Limb Name="gGerudoPurpleRightWristLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_WRIST_LIMB" Offset="0x8CE8" />
<Limb Name="gGerudoPurpleRightHandLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_HAND_LIMB" Offset="0x8CF4" />
<Limb Name="gGerudoPurpleGlaiveLimb" Type="Standard" EnumName="GERUDO_PURPLE_GLAIVE_LIMB" Offset="0x8D00" />
<Limb Name="gGerudoPurpleLeftUpperArmLimb" Type="Standard" EnumName="GERUDO_PURPLE_LEFT_UPPER_ARM_LIMB" Offset="0x8D0C" />
<Limb Name="gGerudoPurpleLeftForearmLimb" Type="Standard" EnumName="GERUDO_PURPLE_LEFT_FOREARM_LIMB" Offset="0x8D18" />
<Limb Name="gGerudoPurpleLeftHandLimb" Type="Standard" EnumName="GERUDO_PURPLE_LEFT_HAND_LIMB" Offset="0x8D24" />
<Limb Name="gGerudoPurpleLeftThighLimb" Type="Standard" EnumName="GERUDO_PURPLE_LEFT_THIGH_LIMB" Offset="0x8D30" />
<Limb Name="gGerudoPurpleLeftShinLimb" Type="Standard" EnumName="GERUDO_PURPLE_LEFT_SHIN_LIMB" Offset="0x8D3C" />
<Limb Name="gGerudoPurpleLeftFootLimb" Type="Standard" EnumName="GERUDO_PURPLE_LEFT_FOOT_LIMB" Offset="0x8D48" />
<Limb Name="gGerudoPurpleRightThighLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_THIGH_LIMB" Offset="0x8D54" />
<Limb Name="gGerudoPurpleRightShinLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_SHIN_LIMB" Offset="0x8D60" />
<Limb Name="gGerudoPurpleRightFootLimb" Type="Standard" EnumName="GERUDO_PURPLE_RIGHT_FOOT_LIMB" Offset="0x8D6C" />
<Limb Name="gGerudoPurpleWaistLimb" Type="Standard" EnumName="GERUDO_PURPLE_WAIST_LIMB" Offset="0x8D78" />
<Skeleton Name="gGerudoPurpleSkel" Type="Flex" LimbType="Standard" LimbNone="GERUDO_PURPLE_LIMB_NONE" LimbMax="GERUDO_PURPLE_LIMB_MAX" EnumName="GerudoPurpleLimb" Offset="0x8DD8" />
<Animation Name="gGerudoPurpleChargingAnim" Offset="0x91D0" /><!-- Original name: geldA_run -->
<Animation Name="gGerudoPurpleLookingAboutAnim" Offset="0x9D1C" /><!-- Original name: geldA_wait -->
<Animation Name="gGerudoPurpleWalkingAnim" Offset="0xA344" /><!-- Original name: geldA_walk -->
</File>
</Root>

View File

@ -1218,7 +1218,10 @@ typedef enum SunsSongState {
#define WEEKEVENTREG_80_01 PACK_WEEKEVENTREG_FLAG(80, 0x01)
#define WEEKEVENTREG_80_02 PACK_WEEKEVENTREG_FLAG(80, 0x02)
#define WEEKEVENTREG_80_04 PACK_WEEKEVENTREG_FLAG(80, 0x04)
// Aveil has spotted Player
#define WEEKEVENTREG_80_08 PACK_WEEKEVENTREG_FLAG(80, 0x08)
#define WEEKEVENTREG_80_10 PACK_WEEKEVENTREG_FLAG(80, 0x10)
#define WEEKEVENTREG_80_20 PACK_WEEKEVENTREG_FLAG(80, 0x20)
#define WEEKEVENTREG_80_40 PACK_WEEKEVENTREG_FLAG(80, 0x40)
@ -1243,7 +1246,10 @@ typedef enum SunsSongState {
#define WEEKEVENTREG_82_40 PACK_WEEKEVENTREG_FLAG(82, 0x40)
#define WEEKEVENTREG_82_80 PACK_WEEKEVENTREG_FLAG(82, 0x80)
#define WEEKEVENTREG_83_01 PACK_WEEKEVENTREG_FLAG(83, 0x01)
// Knocked the Gerudo beehive down
#define WEEKEVENTREG_83_02 PACK_WEEKEVENTREG_FLAG(83, 0x02)
#define WEEKEVENTREG_83_04 PACK_WEEKEVENTREG_FLAG(83, 0x04)
#define WEEKEVENTREG_83_08 PACK_WEEKEVENTREG_FLAG(83, 0x08)
#define WEEKEVENTREG_83_10 PACK_WEEKEVENTREG_FLAG(83, 0x10)

View File

@ -147,6 +147,7 @@ typedef enum {
/* 22 */ TRANS_TYPE_WIPE5,
// transition types 23 - 31 are unused
// transition types 32 - 39 are Wipe4 TODO needs macro
/* 38 */ TRANS_TYPE_38 = 38,
// transition types 40 - 63 are unused
// transition types 64 - 127 are Wipe3 TODO needs macro
/* 64 */ TRANS_TYPE_64 = 64,

3
spec
View File

@ -4023,8 +4023,7 @@ beginseg
name "ovl_En_Ge2"
compress
include "build/src/overlays/actors/ovl_En_Ge2/z_en_ge2.o"
include "build/data/ovl_En_Ge2/ovl_En_Ge2.data.o"
include "build/data/ovl_En_Ge2/ovl_En_Ge2.reloc.o"
include "build/src/overlays/actors/ovl_En_Ge2/ovl_En_Ge2_reloc.o"
endseg
beginseg

View File

@ -674,7 +674,7 @@ void EnArrow_Draw(Actor* thisx, PlayState* play) {
gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_06F9F0);
} else {
func_800B8050(&this->actor, play, MTXMODE_NEW);
func_800B8050(&this->actor, play, 0);
gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06F380);
gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, 0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0,

View File

@ -189,13 +189,14 @@ void EnGe1_SetupPath(EnGe1* this, PlayState* play) {
Vec3s* point;
Vec3f nextPoint;
this->curPoint = 0;
this->curPointIndex = 0;
if (GERUDO_WHITE_GET_PATH(&this->picto.actor) != 0x3F) {
this->path = &play->setupPathList[GERUDO_WHITE_GET_PATH(&this->picto.actor)];
if (this->path != NULL) {
point = Lib_SegmentedToVirtual(this->path->points);
Math_Vec3s_ToVec3f(&this->picto.actor.world.pos, point);
this->curPoint++;
this->curPointIndex++;
point++;
Math_Vec3s_ToVec3f(&nextPoint, point);
@ -214,7 +215,7 @@ void EnGe1_SetupPath(EnGe1* this, PlayState* play) {
s32 EnGe1_FollowPath(EnGe1* this) {
s32 pad;
Path* path = this->path;
Vec3s* points;
Vec3s* curPoint;
Vec3f point;
s16 yawTarget;
s16 pitchTarget;
@ -223,10 +224,10 @@ s32 EnGe1_FollowPath(EnGe1* this) {
return true;
}
points = Lib_SegmentedToVirtual(this->path->points);
points += this->curPoint;
curPoint = Lib_SegmentedToVirtual(this->path->points);
curPoint += this->curPointIndex;
Math_Vec3s_ToVec3f(&point, points);
Math_Vec3s_ToVec3f(&point, curPoint);
yawTarget = Math_Vec3f_Yaw(&this->picto.actor.world.pos, &point);
pitchTarget = Math_Vec3f_Pitch(&this->picto.actor.world.pos, &point);
Math_SmoothStepToS(&this->picto.actor.world.rot.y, yawTarget, 0xA, 0x3E8, 0x64);
@ -260,9 +261,9 @@ void EnGe1_PerformCutsceneActions(EnGe1* this, PlayState* play) {
EnGe1_ChangeAnim(this, GERUDO_WHITE_ANIM_STIFF_SHIVERING, ANIMMODE_LOOP, 0.0f);
}
if (Cutscene_CheckActorAction(play, 0x79)) {
if (Cutscene_CheckActorAction(play, 121)) {
this->picto.actor.draw = EnGe1_Draw;
csAction = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 0x79)]->action;
csAction = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 121)]->action;
switch (csAction) {
case 8:
this->stateFlags &= ~GERUDO_WHITE_STATE_DISABLE_MOVEMENT;
@ -339,22 +340,27 @@ void EnGe1_PerformCutsceneActions(EnGe1* this, PlayState* play) {
this->picto.actor.draw = NULL;
}
if (this->csAction == 9) {
if ((this->curPoint < this->path->count) && EnGe1_FollowPath(this)) {
this->curPoint++;
}
switch (this->csAction) {
case 9:
if ((this->curPointIndex < this->path->count) && EnGe1_FollowPath(this)) {
this->curPointIndex++;
}
// Tumble in the air
this->picto.actor.shape.rot.x += 0x3E8;
this->picto.actor.shape.rot.y += 0x7D0;
this->picto.actor.shape.rot.z += 0x1F4;
// Tumble in the air
this->picto.actor.shape.rot.x += 0x3E8;
this->picto.actor.shape.rot.y += 0x7D0;
this->picto.actor.shape.rot.z += 0x1F4;
if (this->screamTimer > 0) {
this->screamTimer--;
} else {
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
EnGe1_Scream(this);
}
if (this->screamTimer > 0) {
this->screamTimer--;
} else {
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
EnGe1_Scream(this);
}
break;
default:
break;
}
}

View File

@ -29,7 +29,7 @@ typedef struct EnGe1 {
/* 0x2A4 */ Vec3s headRot;
/* 0x2AA */ Vec3s torsoRot;
/* 0x2B0 */ Path* path;
/* 0x2B4 */ s32 curPoint;
/* 0x2B4 */ s32 curPointIndex;
/* 0x2B8 */ s16 eyeIndex;
/* 0x2BA */ s16 blinkTimer;
/* 0x2BC */ u16 stateFlags;

View File

@ -15,18 +15,14 @@ void EnGe2_Destroy(Actor* thisx, PlayState* play);
void EnGe2_Update(Actor* thisx, PlayState* play);
void EnGe2_Draw(Actor* thisx, PlayState* play);
void func_80B8BCEC(EnGe2* this, PlayState* play);
void func_80B8BD38(EnGe2* this, PlayState* play);
void func_80B8BE08(EnGe2* this, PlayState* play);
void func_80B8BF04(EnGe2* this, PlayState* play);
void func_80B8C048(EnGe2* this, PlayState* play);
void func_80B8C0B0(EnGe2* this, PlayState* play);
void func_80B8C45C(EnGe2* this, PlayState* play);
void func_80B8C59C(EnGe2* this, PlayState* play);
void func_80B8C644(EnGe2* this, PlayState* play);
void func_80B8C9B8(EnGe2* this, PlayState* play);
s32 EnGe2_SetupPath(EnGe2* this, PlayState* play);
void EnGe2_LookAround(EnGe2* this, PlayState* play);
void EnGe2_Walk(EnGe2* this, PlayState* play);
void EnGe2_GuardStationary(EnGe2* this, PlayState* play);
s32 EnGe2_ValidatePictograph(PlayState* play, Actor* thisx);
#if 0
ActorInit En_Ge2_InitVars = {
ACTOR_EN_GE2,
ACTORCAT_NPC,
@ -39,78 +35,741 @@ ActorInit En_Ge2_InitVars = {
(ActorFunc)EnGe2_Draw,
};
// static ColliderCylinderInit sCylinderInit = {
static ColliderCylinderInit D_80B8CE40 = {
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x038BFBB3, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
typedef enum {
/* 0 */ GERUDO_PURPLE_DETECTION_UNDETECTED,
/* 1 */ GERUDO_PURPLE_DETECTION_HEARD,
/* 2 */ GERUDO_PURPLE_DETECTION_PROXIMITY //!< Higher priority
} GerudoPurpleDetection;
typedef enum {
/* 0 */ GERUDO_PURPLE_PATHSTATUS_NORMAL, //!< not near waypoint
/* 1 */ GERUDO_PURPLE_PATHSTATUS_AT_POINT, //!< no path or new waypoint
/* 2 */ GERUDO_PURPLE_PATHSTATUS_END //!< reached end of path
} GerudoPurplePathStatus;
#define GERUDO_PURPLE_STATE_PATH_REVERSE (1 << 0) //!< Follow path backwards instead of forwards.
#define GERUDO_PURPLE_STATE_KO (1 << 1)
#define GERUDO_PURPLE_STATE_STUNNED (1 << 2) //!< Specifically by Deku Nuts
#define GERUDO_PURPLE_STATE_DISABLE_MOVEMENT \
(1 << 3) //!< Disable normal movement to let pathing function control it completely.
#define GERUDO_PURPLE_STATE_CAPTURING (1 << 5) //!< Set but not used
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_1,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x038BFBB3, 0x00, 0x00 },
TOUCH_NONE | TOUCH_SFX_NORMAL,
BUMP_ON,
OCELEM_ON,
},
{ 30, 60, 0, { 0, 0, 0 } },
};
#endif
void EnGe2_Init(Actor* thisx, PlayState* play) {
s32 pad;
EnGe2* this = THIS;
extern ColliderCylinderInit D_80B8CE40;
ActorShape_Init(&this->picto.actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f);
SkelAnime_InitFlex(play, &this->skelAnime, &gGerudoPurpleSkel, NULL, this->jointTable, this->morphTable,
GERUDO_PURPLE_LIMB_MAX);
Animation_PlayLoop(&this->skelAnime, &gGerudoPurpleWalkingAnim);
extern UNK_TYPE D_06008DD8;
extern UNK_TYPE D_060091D0;
extern UNK_TYPE D_06009D1C;
extern UNK_TYPE D_0600A344;
Collider_InitAndSetCylinder(play, &this->collider, &this->picto.actor, &sCylinderInit);
this->picto.actor.colChkInfo.mass = MASS_IMMOVABLE;
Actor_SetScale(&this->picto.actor, 0.01f);
this->picto.actor.uncullZoneForward = 1200.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Init.s")
if (this->picto.actor.world.rot.z == 0) {
this->verticalDetectRange = 40.0f;
} else {
this->verticalDetectRange = fabsf(this->picto.actor.world.rot.z * 20.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Destroy.s")
this->picto.actor.world.rot.x = this->picto.actor.shape.rot.x = 0;
this->picto.actor.world.rot.z = this->picto.actor.shape.rot.z = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B514.s")
this->picto.actor.targetMode = 6;
this->stateFlags = 0;
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
this->csAction = -1;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B5AC.s")
this->picto.actor.terminalVelocity = -9.0f;
this->picto.actor.gravity = -1.0f;
this->picto.actor.speedXZ = 1.5f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B6B4.s")
this->actionFunc = EnGe2_Walk;
this->picto.validationFunc = EnGe2_ValidatePictograph;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B7A8.s")
EnGe2_SetupPath(this, play);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B848.s")
this->picto.actor.flags |= ACTOR_FLAG_10;
if (play->actorCtx.flags & ACTORCTX_FLAG_1) {
this->picto.actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B90C.s")
switch (GERUDO_PURPLE_GET_TYPE(&this->picto.actor)) {
case GERUDO_PURPLE_TYPE_BOAT_SENTRY:
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, 0.0f);
this->actionFunc = EnGe2_GuardStationary;
this->picto.actor.speedXZ = 0.0f;
this->picto.actor.uncullZoneForward = 4000.0f;
break;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BA40.s")
case GERUDO_PURPLE_TYPE_AVEIL_GUARD:
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_83_02)) {
Actor_Kill(&this->picto.actor);
}
break;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BB3C.s")
default:
break;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BC1C.s")
void EnGe2_Destroy(Actor* thisx, PlayState* play) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BC78.s")
// Detect Player through hearing or proximity
GerudoPurpleDetection EnGe2_DetectPlayer(PlayState* play, EnGe2* this) {
if (this->picto.actor.xzDistToPlayer > 250.0f) {
return GERUDO_PURPLE_DETECTION_UNDETECTED;
} else if ((Player_GetMask(play) != PLAYER_MASK_STONE) && (this->picto.actor.xzDistToPlayer < 50.0f)) {
return GERUDO_PURPLE_DETECTION_PROXIMITY;
} else if (func_800B715C(play)) {
return GERUDO_PURPLE_DETECTION_HEARD;
} else {
return GERUDO_PURPLE_DETECTION_UNDETECTED;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BCEC.s")
/**
* Spotted Player with line-of-sight
*
* @param play PlayState
* @param thisx Actor to use for range and angle checks
* @param pos Position to check from
* @param yaw Center of yaw range to check
* @param yawRange Spread of angles from `yaw` to check. If 0, do not check yaw
* @param xzRange Horizontal range to check
* @param yRange Vertical range to check
* @return true if Player is visible with these settings
*/
s32 EnGe2_LookForPlayer(PlayState* play, Actor* actor, Vec3f* pos, s16 yaw, s16 yawRange, f32 xzRange, f32 yRange) {
s16 yawToPlayer;
Vec3f posResult;
CollisionPoly* outPoly;
Player* player = GET_PLAYER(play);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BD38.s")
if (Player_GetMask(play) == PLAYER_MASK_STONE) {
return false;
}
if (actor->xzDistToPlayer > xzRange) {
return false;
}
if (fabsf(actor->playerHeightRel) > yRange) {
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BD90.s")
yawToPlayer = actor->yawTowardsPlayer - yaw;
if ((yawRange > 0) && (yawRange < ABS_ALT(yawToPlayer))) {
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BE08.s")
if (BgCheck_AnyLineTest1(&play->colCtx, pos, &player->bodyPartsPos[7], &posResult, &outPoly, false)) {
return false;
} else {
return true;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BF04.s")
/* Path functions */
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BFC8.s")
/**
* Set up the path if it exists, choose the end and direction
*
* @return true if path is set up in reverse
*/
s32 EnGe2_SetupPath(EnGe2* this, PlayState* play) {
if (GERUDO_PURPLE_GET_PATH(&this->picto.actor) != GERUDO_PURPLE_PATH_NONE) {
this->path = &play->setupPathList[GERUDO_PURPLE_GET_PATH(&this->picto.actor)];
if (this->path != NULL) {
Path* path = this->path;
Vec3s* points = Lib_SegmentedToVirtual(path->points);
f32 diffX = points[0].x - this->picto.actor.world.pos.x;
f32 diffZ = points[0].z - this->picto.actor.world.pos.z;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C048.s")
if ((SQ(diffX) + SQ(diffZ)) < SQ(10.0f)) {
this->curPointIndex = 0;
this->stateFlags &= ~GERUDO_PURPLE_STATE_PATH_REVERSE;
} else {
this->curPointIndex = path->count - 1;
this->stateFlags |= GERUDO_PURPLE_STATE_PATH_REVERSE;
return true;
}
}
} else {
this->path = NULL;
this->curPointIndex = 0;
}
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C0B0.s")
void EnGe2_GetNextPath(EnGe2* this, PlayState* play) {
Path* curPath;
Path* nextPath;
Vec3s* points;
u8 unk1;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C13C.s")
this->curPointIndex = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C45C.s")
if (GERUDO_PURPLE_GET_PATH(&this->picto.actor) != GERUDO_PURPLE_PATH_NONE) {
curPath = &play->setupPathList[GERUDO_PURPLE_GET_PATH(&this->picto.actor)];
unk1 = curPath->unk1;
nextPath = &play->setupPathList[unk1];
this->path = nextPath;
points = Lib_SegmentedToVirtual(nextPath->points);
this->picto.actor.world.pos.x = points[0].x;
this->picto.actor.world.pos.z = points[0].z;
} else {
this->path = NULL;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C59C.s")
void EnGe2_SetupBlownAwayPath(EnGe2* this, PlayState* play) {
s32 pad;
Vec3s* points;
Vec3f nextPoint;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C644.s")
this->curPointIndex = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C9B8.s")
if (GERUDO_PURPLE_GET_PATH(&this->picto.actor) != GERUDO_PURPLE_PATH_NONE) {
this->path = &play->setupPathList[GERUDO_PURPLE_GET_PATH(&this->picto.actor)];
if (this->path != NULL) {
points = Lib_SegmentedToVirtual(this->path->points);
Math_Vec3s_ToVec3f(&this->picto.actor.world.pos, points);
this->curPointIndex++;
points++;
Math_Vec3s_ToVec3f(&nextPoint, points);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Update.s")
this->picto.actor.world.rot.y = Math_Vec3f_Yaw(&this->picto.actor.world.pos, &nextPoint);
this->picto.actor.world.rot.x = Math_Vec3f_Pitch(&this->picto.actor.world.pos, &nextPoint);
this->picto.actor.speedXZ = 15.0f;
}
} else {
this->path = NULL;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8CC0C.s")
GerudoPurplePathStatus EnGe2_FollowPath(EnGe2* this) {
Path* path = this->path;
Vec3s* curPoint;
f32 diffX;
f32 diffZ;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8CCB4.s")
if (path == NULL) {
return GERUDO_PURPLE_PATHSTATUS_AT_POINT;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8CCFC.s")
curPoint = (Vec3s*)Lib_SegmentedToVirtual(path->points);
curPoint += this->curPointIndex;
diffX = curPoint->x - this->picto.actor.world.pos.x;
diffZ = curPoint->z - this->picto.actor.world.pos.z;
this->picto.actor.world.rot.y = Math_Atan2S(diffX, diffZ);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.world.rot.y, 2, 0x7D0, 0xC8);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Draw.s")
if ((SQ(diffX) + SQ(diffZ)) < SQ(10.0f)) {
if (this->stateFlags & GERUDO_PURPLE_STATE_PATH_REVERSE) {
this->curPointIndex--;
if (this->curPointIndex < 0) {
return GERUDO_PURPLE_PATHSTATUS_END;
}
} else {
this->curPointIndex++;
if (this->curPointIndex >= path->count) {
return GERUDO_PURPLE_PATHSTATUS_END;
}
}
return GERUDO_PURPLE_PATHSTATUS_AT_POINT;
}
return GERUDO_PURPLE_PATHSTATUS_NORMAL;
}
/**
* Used for Blown Away cutscene path.
*/
s32 EnGe2_FollowPathWithoutGravity(EnGe2* this) {
s32 pad;
Vec3s* curPoint;
Path* path = this->path;
Vec3f point;
s16 yawTarget;
s16 pitchTarget;
if (this->path == NULL) {
return true;
}
curPoint = Lib_SegmentedToVirtual(path->points);
curPoint += this->curPointIndex;
Math_Vec3s_ToVec3f(&point, curPoint);
yawTarget = Math_Vec3f_Yaw(&this->picto.actor.world.pos, &point);
pitchTarget = Math_Vec3f_Pitch(&this->picto.actor.world.pos, &point);
Math_SmoothStepToS(&this->picto.actor.world.rot.y, yawTarget, 0xA, 0x3E8, 0x64);
Math_SmoothStepToS(&this->picto.actor.world.rot.x, pitchTarget, 6, 0x7D0, 0xC8);
this->picto.actor.speedXZ = 15.0f;
Actor_MoveWithoutGravityReverse(&this->picto.actor);
if (Math_Vec3f_DistXYZ(&this->picto.actor.world.pos, &point) < 40.0f) {
return true;
} else {
return false;
}
}
/* Action and helper functions */
void EnGe2_SpawnEffects(EnGe2* this, PlayState* play) {
static Vec3f effectVelocity = { 0.0f, -0.05f, 0.0f };
static Vec3f effectAccel = { 0.0f, -0.025f, 0.0f };
static Color_RGBA8 effectPrimColor = { 255, 255, 255, 0 };
static Color_RGBA8 effectEnvColor = { 255, 150, 0, 0 };
s16 effectAngle = play->state.frames * 0x2800;
Vec3f effectPos;
effectPos.x = (Math_CosS(effectAngle) * 5.0f) + this->picto.actor.focus.pos.x;
effectPos.y = this->picto.actor.focus.pos.y + 10.0f;
effectPos.z = (Math_SinS(effectAngle) * 5.0f) + this->picto.actor.focus.pos.z;
EffectSsKirakira_SpawnDispersed(play, &effectPos, &effectVelocity, &effectAccel, &effectPrimColor, &effectEnvColor,
1000, 16);
}
void EnGe2_Scream(EnGe2* this) {
if ((s32)Rand_ZeroFloat(2.0f) == 0) {
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_VO_FPVO00);
} else {
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_VO_FPVO01);
}
}
/**
* Wait for timer to finish, then set up the captured/thrown out transition.
*/
void EnGe2_ThrowPlayerOut(EnGe2* this, PlayState* play) {
if (this->timer > 0) {
this->timer--;
} else if (play->nextEntrance != play->setupExitList[GERUDO_PURPLE_GET_EXIT(&this->picto.actor)]) {
play->nextEntrance = play->setupExitList[GERUDO_PURPLE_GET_EXIT(&this->picto.actor)];
play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_38;
}
}
/**
* Used if Aveil spots Player.
*/
void EnGe2_TurnToPlayerFast(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x1000, 0x200);
}
void EnGe2_CapturePlayer(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
EnGe2_ThrowPlayerOut(this, play);
}
void EnGe2_SetupCapturePlayer(EnGe2* this) {
this->picto.actor.speedXZ = 0.0f;
this->actionFunc = EnGe2_CapturePlayer;
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
}
void EnGe2_Charge(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
this->picto.actor.world.rot.y = this->picto.actor.shape.rot.y;
if (this->picto.actor.xzDistToPlayer < 50.0f) {
EnGe2_SetupCapturePlayer(this);
} else if (!(this->picto.actor.bgCheckFlags & 1)) {
this->picto.actor.world.pos = this->picto.actor.prevPos;
EnGe2_SetupCapturePlayer(this);
}
if (this->timer > 0) {
this->timer--;
} else {
EnGe2_ThrowPlayerOut(this, play);
}
if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) {
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_EV_PIRATE_WALK);
}
}
void EnGe2_SetupCharge(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
this->picto.actor.world.rot.y = this->picto.actor.shape.rot.y;
if (this->picto.actor.shape.rot.y == this->picto.actor.yawTowardsPlayer) {
Animation_Change(&this->skelAnime, &gGerudoPurpleChargingAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleChargingAnim), 0, -8.0f);
this->timer = 50;
this->picto.actor.speedXZ = 4.0f;
this->actionFunc = EnGe2_Charge;
}
}
void EnGe2_SetupLookAround(EnGe2* this) {
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
this->timer = 60;
this->picto.actor.speedXZ = 0.0f;
this->actionFunc = EnGe2_LookAround;
}
void EnGe2_Stunned(EnGe2* this, PlayState* play) {
if (this->picto.actor.colorFilterTimer == 0) {
EnGe2_SetupLookAround(this);
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
this->stateFlags &= ~GERUDO_PURPLE_STATE_STUNNED;
}
}
void EnGe2_KnockedOut(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
EnGe2_SpawnEffects(this, play);
if (this->timer > 0) {
this->timer--;
} else {
EnGe2_SetupLookAround(this);
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
this->stateFlags &= ~GERUDO_PURPLE_STATE_KO;
this->picto.actor.flags |= ACTOR_FLAG_1;
}
}
/**
* Carries out various patrol functions:
* - Turning to Player if being arrested
* - Turning to Player if spotted by Aveil
* - Looking for Player
* - Managing collisions and collider
*/
void EnGe2_PatrolDuties(EnGe2* this, PlayState* play) {
Player* player = GET_PLAYER(play);
f32 visionRange = gSaveContext.save.isNight ? 200.0f : 280.0f;
if (player->csMode == 0x1A) {
this->picto.actor.speedXZ = 0.0f;
this->actionFunc = EnGe2_SetupCharge;
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
this->stateFlags |= GERUDO_PURPLE_STATE_CAPTURING;
} else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_80_08)) {
this->picto.actor.speedXZ = 0.0f;
this->actionFunc = EnGe2_TurnToPlayerFast;
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
} else if (EnGe2_LookForPlayer(play, &this->picto.actor, &this->picto.actor.focus.pos,
this->picto.actor.shape.rot.y, 0x1800, visionRange, this->verticalDetectRange)) {
if ((GERUDO_PURPLE_GET_EXIT(&this->picto.actor) != GERUDO_PURPLE_EXIT_NONE) && !Play_InCsMode(play)) {
this->picto.actor.speedXZ = 0.0f;
func_800B7298(play, &this->picto.actor, 0x1A);
func_801000A4(NA_SE_SY_FOUND);
Message_StartTextbox(play, 0x1194, &this->picto.actor);
this->actionFunc = EnGe2_SetupCharge;
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
}
} else if (this->collider.base.acFlags & AC_HIT) {
if ((this->collider.info.acHitInfo != NULL) &&
(this->collider.info.acHitInfo->toucher.dmgFlags & DMG_DEKU_NUT)) {
Actor_SetColorFilter(&this->picto.actor, 0, 120, 0, 400);
this->picto.actor.speedXZ = 0.0f;
this->actionFunc = EnGe2_Stunned;
this->stateFlags |= GERUDO_PURPLE_STATE_STUNNED;
} else {
Animation_Change(&this->skelAnime, &gGerudoPurpleFallingToGroundAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleFallingToGroundAnim), 2, -8.0f);
this->timer = 200;
this->picto.actor.speedXZ = 0.0f;
this->actionFunc = EnGe2_KnockedOut;
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_EN_PIRATE_DEAD);
this->picto.actor.flags &= ~ACTOR_FLAG_1;
this->stateFlags |= GERUDO_PURPLE_STATE_KO;
}
} else if (this->picto.actor.home.rot.x == 0) {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
}
}
void EnGe2_LookAround(EnGe2* this, PlayState* play) {
u8 detectedStatus;
SkelAnime_Update(&this->skelAnime);
detectedStatus = EnGe2_DetectPlayer(play, this);
if (detectedStatus != GERUDO_PURPLE_DETECTION_UNDETECTED) {
this->timer = 100;
this->yawTarget = this->picto.actor.yawTowardsPlayer;
if (this->detectedStatus < detectedStatus) {
this->detectedStatus = detectedStatus;
}
}
if (this->timer > 0) {
this->timer--;
} else {
this->actionFunc = EnGe2_Walk;
Animation_Change(&this->skelAnime, &gGerudoPurpleWalkingAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleWalkingAnim), 0, -8.0f);
this->headRot.y = 0;
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
}
switch (this->detectedStatus) {
case GERUDO_PURPLE_DETECTION_HEARD:
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->yawTarget, 2, 0x3E8, 0x1F4);
break;
case GERUDO_PURPLE_DETECTION_PROXIMITY:
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->yawTarget, 2, 0xBB8, 0x3E8);
break;
default:
break;
}
this->picto.actor.world.rot.y = this->picto.actor.shape.rot.y;
EnGe2_PatrolDuties(this, play);
}
void EnGe2_Walk(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
this->picto.actor.speedXZ = 1.5f;
switch (EnGe2_FollowPath(this)) {
case GERUDO_PURPLE_PATHSTATUS_END:
EnGe2_SetupPath(this, play);
break;
case GERUDO_PURPLE_PATHSTATUS_AT_POINT:
EnGe2_SetupLookAround(this);
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
break;
default: // GERUDO_PURPLE_PATHSTATUS_NORMAL
break;
}
this->detectedStatus = EnGe2_DetectPlayer(play, this);
if (this->detectedStatus != GERUDO_PURPLE_DETECTION_UNDETECTED) {
EnGe2_SetupLookAround(this);
this->yawTarget = this->picto.actor.yawTowardsPlayer;
}
EnGe2_PatrolDuties(this, play);
}
void EnGe2_PerformCutsceneActions(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if (Cutscene_CheckActorAction(play, 476)) {
s16 csAction = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 476)]->action;
if (this->csAction != csAction) {
this->csAction = csAction;
switch (csAction) {
case ENGE2_CSACTION_BEEHIVE_PATROL:
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
EnGe2_GetNextPath(this, play);
break;
case ENGE2_CSACTION_BEEHIVE_RUN_AWAY:
Animation_Change(&this->skelAnime, &gGerudoPurpleRunningAwayCutsceneAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gGerudoPurpleRunningAwayCutsceneAnim), 0, -5.0f);
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
break;
case ENGE2_CSACTION_BEEHIVE_EXIT:
Actor_Kill(&this->picto.actor);
break;
case ENGE2_CSACTION_GBT_ENTR_STAND_STILL:
Animation_Change(&this->skelAnime, &gGerudoPurpleGreatBayCutsceneAnim, 0.0f, 0.0f, 0.0f, 2, 0.0f);
break;
case ENGE2_CSACTION_GBT_ENTR_BLOWN_AWAY:
Animation_Change(&this->skelAnime, &gGerudoPurpleGreatBayCutsceneAnim, 0.0f, 1.0f, 1.0f, 2, 0.0f);
EnGe2_SetupBlownAwayPath(this, play);
this->stateFlags |= GERUDO_PURPLE_STATE_DISABLE_MOVEMENT;
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
break;
default:
break;
}
}
}
switch (this->csAction) {
case ENGE2_CSACTION_BEEHIVE_RUN_AWAY:
EnGe2_FollowPath(this);
this->picto.actor.speedXZ = 5.0f;
if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) {
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_EV_PIRATE_WALK);
}
if (this->screamTimer > 0) {
this->screamTimer--;
} else {
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
EnGe2_Scream(this);
}
break;
case ENGE2_CSACTION_GBT_ENTR_BLOWN_AWAY:
if ((this->curPointIndex < this->path->count) && EnGe2_FollowPathWithoutGravity(this)) {
this->curPointIndex++;
}
// Tumble in the air
this->picto.actor.shape.rot.x += 0x3E8;
this->picto.actor.shape.rot.y += 0x7D0;
this->picto.actor.shape.rot.z += 0x1F4;
if (this->screamTimer > 0) {
this->screamTimer--;
} else {
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
EnGe2_Scream(this);
}
break;
default:
break;
}
}
// Used for those on boats
void EnGe2_GuardStationary(EnGe2* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
if (EnGe2_LookForPlayer(play, &this->picto.actor, &this->picto.actor.focus.pos, this->picto.actor.shape.rot.y,
0x4000, 720.0f, this->verticalDetectRange)) {
if ((GERUDO_PURPLE_GET_EXIT(&this->picto.actor) != GERUDO_PURPLE_EXIT_NONE) && !Play_InCsMode(play)) {
func_800B7298(play, &this->picto.actor, 0x1A);
func_801000A4(NA_SE_SY_FOUND);
Message_StartTextbox(play, 0x1194, &this->picto.actor);
this->timer = 50;
EnGe2_SetupCapturePlayer(this);
}
}
if (this->picto.actor.playerHeightRel < -150.0f) {
this->picto.actor.draw = NULL;
} else {
this->picto.actor.draw = EnGe2_Draw;
}
}
void EnGe2_Update(Actor* thisx, PlayState* play) {
s32 pad;
EnGe2* this = THIS;
if (!(this->stateFlags & GERUDO_PURPLE_STATE_DISABLE_MOVEMENT)) {
Actor_MoveWithGravity(&this->picto.actor);
}
Actor_UpdateBgCheckInfo(play, &this->picto.actor, 40.0f, 25.0f, 40.0f, 5);
Collider_UpdateCylinder(&this->picto.actor, &this->collider);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
if (Cutscene_CheckActorAction(play, 476)) {
this->actionFunc = EnGe2_PerformCutsceneActions;
this->stateFlags &= ~GERUDO_PURPLE_STATE_KO;
this->stateFlags &= ~GERUDO_PURPLE_STATE_PATH_REVERSE;
this->picto.actor.flags |= ACTOR_FLAG_20;
this->picto.actor.speedXZ = 0.0f;
}
this->actionFunc(this, play);
// Blinking
if (this->stateFlags & GERUDO_PURPLE_STATE_KO) {
this->eyeIndex = 2;
} else if (!(this->stateFlags & GERUDO_PURPLE_STATE_STUNNED)) {
if (DECR(this->blinkTimer) == 0) {
this->blinkTimer = Rand_S16Offset(60, 60);
}
this->eyeIndex = this->blinkTimer;
if (this->eyeIndex >= 3) {
this->eyeIndex = 0;
}
}
}
s32 EnGe2_ValidatePictograph(PlayState* play, Actor* thisx) {
s32 ret = Snap_ValidatePictograph(play, thisx, PICTO_VALID_PIRATE_GOOD, &thisx->focus.pos, &thisx->shape.rot, 10.0f,
400.0f, -1);
ret |= Snap_ValidatePictograph(play, thisx, PICTO_VALID_PIRATE_TOO_FAR, &thisx->focus.pos, &thisx->shape.rot, 10.0f,
1200.0f, -1);
return ret;
}
s32 EnGe2_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
EnGe2* this = THIS;
if (limbIndex == GERUDO_PURPLE_NECK_LIMB) {
rot->x += this->headRot.y;
rot->z += this->headRot.x;
}
return false;
}
void EnGe2_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
static Vec3f sFocusOffset = { 600.0f, 700.0f, 0.0f };
if (limbIndex == GERUDO_PURPLE_HEAD_LIMB) {
Matrix_MultVec3f(&sFocusOffset, &thisx->focus.pos);
}
}
void EnGe2_Draw(Actor* thisx, PlayState* play) {
static TexturePtr sEyeTextures[] = {
gGerudoPurpleEyeOpenTex,
gGerudoPurpleEyeHalfTex,
gGerudoPurpleEyeClosedTex,
};
s32 pad;
EnGe2* this = THIS;
OPEN_DISPS(play->state.gfxCtx);
func_8012C5B0(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyeTextures[this->eyeIndex]));
func_800B8050(&this->picto.actor, play, 0);
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnGe2_OverrideLimbDraw, EnGe2_PostLimbDraw, &this->picto.actor);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -2,14 +2,58 @@
#define Z_EN_GE2_H
#include "global.h"
#include "z64snap.h"
#include "objects/object_gla/object_gla.h"
struct EnGe2;
typedef void (*EnGe2ActionFunc)(struct EnGe2*, PlayState*);
#define GERUDO_PURPLE_GET_EXIT(thisx) (((thisx)->params) & 0x1F) //!< Exit to send Player to when caught
#define GERUDO_PURPLE_GET_TYPE(thisx) (((thisx)->params & 0xE0) >> 5)
#define GERUDO_PURPLE_GET_PATH(thisx) ((((thisx)->params) & 0xFC00) >> 10)
#define GERUDO_PURPLE_PARAMS(path, type, exit) (((path) & 0x1F) | (((type) & 7) << 5) | (((exit) & 0x3F) << 10))
#define GERUDO_PURPLE_EXIT_NONE 0x1F
#define GERUDO_PURPLE_PATH_NONE 0x3F
typedef enum {
/* 0 */ GERUDO_PURPLE_TYPE_CUTSCENE,
/* 1 */ GERUDO_PURPLE_TYPE_BOAT_SENTRY, //!< on boats
/* 2 */ GERUDO_PURPLE_TYPE_AVEIL_GUARD,
/* 7 */ GERUDO_PURPLE_TYPE_FORTRESS = 7 //!< In both courtyard and rooms
} GerudoPurpleType;
//! TODO: work out where to put this
typedef enum {
/* 1 */ ENGE2_CSACTION_BEEHIVE_PATROL = 1,
/* 2 */ ENGE2_CSACTION_BEEHIVE_RUN_AWAY,
/* 3 */ ENGE2_CSACTION_BEEHIVE_EXIT,
/* 4 */ ENGE2_CSACTION_GBT_ENTR_STAND_STILL,
/* 5 */ ENGE2_CSACTION_GBT_ENTR_BLOWN_AWAY
} EnGe2CsAction;
typedef struct EnGe2 {
/* 0x000 */ Actor actor;
/* 0x144 */ char unk_144[0x1C4];
/* 0x000 */ PictoActor picto;
/* 0x148 */ ColliderCylinder collider;
/* 0x194 */ SkelAnime skelAnime;
/* 0x1D8 */ Vec3s jointTable[GERUDO_PURPLE_LIMB_MAX];
/* 0x25C */ Vec3s morphTable[GERUDO_PURPLE_LIMB_MAX];
/* 0x2E0 */ s16 eyeIndex;
/* 0x2E2 */ s16 blinkTimer;
/* 0x2E4 */ Vec3s headRot;
/* 0x2E8 */ Vec3s torsoRot; // unused, inferred from similar usage in other actors
/* 0x2F0 */ Path* path;
/* 0x2F4 */ s32 curPointIndex;
/* 0x2F8 */ u16 stateFlags;
/* 0x2FA */ s16 yawTarget; //!< used when Player detected to fix the yaw to turn to
/* 0x2FC */ f32 verticalDetectRange; //!< vertical range to look for the player within
/* 0x300 */ u8 timer;
/* 0x301 */ u8 detectedStatus;
/* 0x302 */ s16 csAction;
/* 0x304 */ s16 unk304; // unused
/* 0x306 */ s16 screamTimer;
/* 0x308 */ EnGe2ActionFunc actionFunc;
} EnGe2; // size = 0x30C

View File

@ -1134,7 +1134,7 @@ void func_80B43074(EnKgy* this, PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
func_8012C28C(play->state.gfxCtx);
func_800B8050(&this->actor, play, MTXMODE_NEW);
func_800B8050(&this->actor, play, 0);
Matrix_Push();
Matrix_Translate(-800.0f, 3100.0f, 8400.0f, MTXMODE_APPLY);
Matrix_RotateXS(0x4000, MTXMODE_APPLY);

View File

@ -16,7 +16,7 @@ void ObjBoat_Destroy(Actor* thisx, PlayState* play);
void ObjBoat_Update(Actor* thisx, PlayState* play);
void ObjBoat_Draw(Actor* thisx, PlayState* play);
void func_80B9B428(Actor* thisx, PlayState* play2);
void ObjBoat_UpdateCutscene(Actor* thisx, PlayState* play2);
ActorInit Obj_Boat_InitVars = {
ACTOR_OBJ_BOAT,
@ -37,14 +37,21 @@ static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
s16 func_80B9AF50(ObjBoat* this, Vec3f* arg0) {
/**
* Get the next point on the path and the yaw to use to get there.
*
* @param this
* @param nextPoint Position of next point on path
* @return yaw to use (or opposite of yaw if reversing)
*/
s16 ObjBoat_GetNextPoint(ObjBoat* this, Vec3f* nextPoint) {
s16 yaw;
Vec3s* temp = &this->unk_164[(s32)this->unk_15C];
Vec3s* curPoint = &this->points[(s32)this->curPointIndex];
Math_Vec3s_ToVec3f(arg0, &temp[this->unk_15D]);
yaw = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, arg0);
Math_Vec3s_ToVec3f(nextPoint, &curPoint[this->direction]);
yaw = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, nextPoint);
return ((this->unk_15D > 0) ? yaw : (yaw + 0x8000));
return ((this->direction > 0) ? yaw : yaw + 0x8000);
}
void ObjBoat_Init(Actor* thisx, PlayState* play) {
@ -57,17 +64,17 @@ void ObjBoat_Init(Actor* thisx, PlayState* play) {
DynaPolyActor_Init(&this->dyna, 3);
DynaPolyActor_LoadMesh(play, &this->dyna, &object_kaizoku_obj_Colheader_009A88);
if (thisx->params < 0) {
this->dyna.actor.update = func_80B9B428;
this->dyna.actor.update = ObjBoat_UpdateCutscene;
} else {
path = &play->setupPathList[OBJBOAT_GET_PATH(thisx)];
this->unk_163 = path->count - 1;
this->unk_164 = Lib_SegmentedToVirtual(path->points);
this->unk_15D = 1;
this->dyna.actor.world.pos.x = this->unk_164[this->unk_15C].x;
this->dyna.actor.world.pos.z = this->unk_164[this->unk_15C].z;
this->dyna.actor.shape.rot.y = func_80B9AF50(this, &sp24);
this->maxPointIndex = path->count - 1;
this->points = Lib_SegmentedToVirtual(path->points);
this->direction = 1;
this->dyna.actor.world.pos.x = this->points[this->curPointIndex].x;
this->dyna.actor.world.pos.z = this->points[this->curPointIndex].z;
this->dyna.actor.shape.rot.y = ObjBoat_GetNextPoint(this, &sp24);
this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y;
this->unk_15D = -this->unk_15D;
this->direction = -this->direction;
}
}
@ -77,11 +84,11 @@ void ObjBoat_Destroy(Actor* thisx, PlayState* play) {
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
}
void func_80B9B124(ObjBoat* this) {
this->unk_160 += 1000;
this->dyna.actor.world.pos.y = Math_SinS(this->unk_160) + this->dyna.actor.home.pos.y;
this->dyna.actor.shape.rot.x = Math_SinS(this->unk_160) * 100.0f;
this->dyna.actor.shape.rot.z = Math_SinS(this->unk_160 * 2) * 50.0f;
void ObjBoat_SetRotations(ObjBoat* this) {
this->angle += 0x3E8;
this->dyna.actor.world.pos.y = Math_SinS(this->angle) + this->dyna.actor.home.pos.y;
this->dyna.actor.shape.rot.x = Math_SinS(this->angle) * 100.0f;
this->dyna.actor.shape.rot.z = Math_SinS(this->angle * 2) * 50.0f;
}
void ObjBoat_Update(Actor* thisx, PlayState* play) {
@ -89,93 +96,102 @@ void ObjBoat_Update(Actor* thisx, PlayState* play) {
ObjBoat* this = THIS;
Player* player = GET_PLAYER(play);
s32 temp = DynaPolyActor_IsInRidingMovingState(&this->dyna);
f32 sp3C = 0.0f;
s16 sp3A = this->dyna.actor.shape.rot.y;
Vec3f sp2C;
f32 speedTarget = 0.0f;
s16 yawTarget = this->dyna.actor.shape.rot.y;
Vec3f nextPoint;
if ((temp != 0) || ((DynaPolyActor_IsInRidingFallingState(&this->dyna)))) {
if ((this->unk_15F == 0) && (OBJBOAT_GET_4000(thisx) || ((temp != 0) && (this->unk_15C == this->unk_15E)))) {
this->unk_15D = -this->unk_15D;
if (this->unk_15D > 0) {
this->unk_15E = this->unk_163;
if (temp || ((DynaPolyActor_IsInRidingFallingState(&this->dyna)))) {
if ((this->timer == 0) &&
(OBJBOAT_GET_4000(thisx) || (temp && (this->curPointIndex == this->lastPointIndex)))) {
this->direction = -this->direction;
if (this->direction > 0) {
this->lastPointIndex = this->maxPointIndex;
} else {
this->unk_15E = 0;
this->lastPointIndex = 0;
}
this->unk_15F = 60;
this->timer = 60;
}
} else if (this->dyna.actor.speedXZ == 0.0f) {
if (this->unk_15F != 0) {
this->unk_15F--;
if (this->timer != 0) {
this->timer--;
}
}
if (this->unk_15C != this->unk_15E) {
sp3A = func_80B9AF50(this, &sp2C);
if (Math_Vec3f_DistXZ(&this->dyna.actor.world.pos, &sp2C) < 200.0f) {
this->unk_15C += this->unk_15D;
if (this->unk_15C == this->unk_15E) {
if (this->curPointIndex != this->lastPointIndex) {
yawTarget = ObjBoat_GetNextPoint(this, &nextPoint);
if (Math_Vec3f_DistXZ(&this->dyna.actor.world.pos, &nextPoint) < 200.0f) {
this->curPointIndex += this->direction;
if (this->curPointIndex == this->lastPointIndex) {
if (OBJBOAT_GET_4000(thisx)) {
this->unk_15C = 0;
this->curPointIndex = 0;
} else if (this->dyna.actor.speedXZ == 0.0f) {
this->unk_15C = 0;
this->unk_15D = -1;
this->curPointIndex = 0;
this->direction = -1;
}
}
} else {
sp3C = this->unk_15D * (OBJBOAT_GET_4000(thisx) ? 5.0f : 3.0f);
speedTarget = this->direction * (OBJBOAT_GET_4000(thisx) ? 5.0f : 3.0f);
}
}
if (player->csMode != PLAYER_CSMODE_26) {
Math_ScaledStepToS(&this->dyna.actor.shape.rot.y, sp3A, (s16)(s32)(fabsf(this->dyna.actor.speedXZ) * 40.0f));
Math_ScaledStepToS(&this->dyna.actor.shape.rot.y, yawTarget, (s32)(fabsf(this->dyna.actor.speedXZ) * 40.0f));
this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y;
Math_StepToF(&this->dyna.actor.speedXZ, sp3C, 0.05f);
Math_StepToF(&this->dyna.actor.speedXZ, speedTarget, 0.05f);
Actor_MoveWithGravity(&this->dyna.actor);
if (this->dyna.actor.speedXZ != 0.0f) {
func_800B9010(&this->dyna.actor, NA_SE_EV_PIRATE_SHIP - SFX_FLAG);
}
}
func_80B9B124(this);
ObjBoat_SetRotations(this);
}
void func_80B9B428(Actor* thisx, PlayState* play2) {
// Update used in cutscenes
void ObjBoat_UpdateCutscene(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
ObjBoat* this = THIS;
if (Cutscene_CheckActorAction(play, 511)) {
CsCmdActorAction* actionIndex = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 511)];
if (this->unk_15F != actionIndex->action) {
if (this->csAction != actionIndex->action) {
this->dyna.actor.shape.rot.x = actionIndex->urot.x;
if (actionIndex->action != 1) {
Path* path = &play->setupPathList[OBJBOAT_GET_PATH(&this->dyna.actor)];
if (actionIndex->action == 3) {
path = &play->setupPathList[path->unk1];
}
this->unk_163 = path->count;
this->unk_164 = Lib_SegmentedToVirtual(path->points);
Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, this->unk_164);
this->maxPointIndex = path->count;
this->points = Lib_SegmentedToVirtual(path->points);
Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, this->points);
this->dyna.actor.speedXZ = actionIndex->urot.z * (45.0f / 0x2000);
this->unk_164++;
this->unk_15C = 1;
this->points++;
this->curPointIndex = 1;
}
this->unk_15F = actionIndex->action;
this->csAction = actionIndex->action;
} else {
if (actionIndex->action != 1) {
Vec3f vec;
f32 step;
Vec3f posTarget;
f32 distRemaining;
Math_Vec3s_ToVec3f(&vec, this->unk_164);
step = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &vec, this->dyna.actor.speedXZ);
if ((this->unk_15C < this->unk_163) && (step < this->dyna.actor.speedXZ)) {
this->unk_164++;
this->unk_15C++;
Math_Vec3s_ToVec3f(&posTarget, this->points);
distRemaining = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &posTarget, this->dyna.actor.speedXZ);
if ((this->curPointIndex < this->maxPointIndex) && (distRemaining < this->dyna.actor.speedXZ)) {
this->points++;
this->curPointIndex++;
}
}
if (actionIndex->action != 3) {
func_80B9B124(this);
ObjBoat_SetRotations(this);
if (actionIndex->action == 2) {
func_800B9010(&this->dyna.actor, NA_SE_EV_PIRATE_SHIP - SFX_FLAG);
}
} else {
// Tumble in the air
this->dyna.actor.shape.rot.y += 0x7D0;
this->dyna.actor.shape.rot.x += 0x3E8;
this->dyna.actor.shape.rot.z += 0x1F4;

View File

@ -10,14 +10,17 @@ struct ObjBoat;
typedef struct ObjBoat {
/* 0x000 */ DynaPolyActor dyna;
/* 0x15C */ u8 unk_15C;
/* 0x15D */ s8 unk_15D;
/* 0x15E */ u8 unk_15E;
/* 0x15F */ u8 unk_15F;
/* 0x160 */ s16 unk_160;
/* 0x15C */ u8 curPointIndex;
/* 0x15D */ s8 direction; // To follow the path
/* 0x15E */ u8 lastPointIndex; // max point if direction is negative, first point if forwards
/* 0x15F */ union {
u8 timer;
u8 csAction;
};
/* 0x160 */ s16 angle; // Angle used to set rotations
/* 0x162 */ UNK_TYPE1 pad_162;
/* 0x163 */ u8 unk_163;
/* 0x164 */ Vec3s* unk_164;
/* 0x163 */ u8 maxPointIndex; // point at the other end from 0
/* 0x164 */ Vec3s* points;
} ObjBoat; // size = 0x168
#endif // Z_OBJ_BOAT_H

View File

@ -135,16 +135,16 @@ void func_80AF0514(ObjLupygamelift* this) {
}
void func_80AF0530(ObjLupygamelift* this, PlayState* play) {
f32 step;
f32 distRemaining;
Vec3f target;
target.x = this->points[this->pointIndex].x;
target.y = this->points[this->pointIndex].y;
target.z = this->points[this->pointIndex].z;
step = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &target, this->dyna.actor.speedXZ);
if (step > 30.0f) {
distRemaining = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &target, this->dyna.actor.speedXZ);
if (distRemaining > 30.0f) {
Math_SmoothStepToF(&this->dyna.actor.speedXZ, this->targetSpeedXZ, 0.5f, 5.0f, 0.1f);
} else if (step > 0.0f) {
} else if (distRemaining > 0.0f) {
Math_SmoothStepToF(&this->dyna.actor.speedXZ, 5.0f, 0.5f, 5.0f, 1.0f);
} else {
if (this->pointIndex < (this->count - 1)) {

View File

@ -14704,33 +14704,33 @@
0x80B8A718:("EnKaizoku_Draw",),
0x80B8B2D0:("EnGe2_Init",),
0x80B8B504:("EnGe2_Destroy",),
0x80B8B514:("func_80B8B514",),
0x80B8B5AC:("func_80B8B5AC",),
0x80B8B6B4:("func_80B8B6B4",),
0x80B8B7A8:("func_80B8B7A8",),
0x80B8B848:("func_80B8B848",),
0x80B8B90C:("func_80B8B90C",),
0x80B8BA40:("func_80B8BA40",),
0x80B8BB3C:("func_80B8BB3C",),
0x80B8BC1C:("func_80B8BC1C",),
0x80B8BC78:("func_80B8BC78",),
0x80B8BCEC:("func_80B8BCEC",),
0x80B8BD38:("func_80B8BD38",),
0x80B8BD90:("func_80B8BD90",),
0x80B8BE08:("func_80B8BE08",),
0x80B8BF04:("func_80B8BF04",),
0x80B8BFC8:("func_80B8BFC8",),
0x80B8C048:("func_80B8C048",),
0x80B8C0B0:("func_80B8C0B0",),
0x80B8C13C:("func_80B8C13C",),
0x80B8C45C:("func_80B8C45C",),
0x80B8C59C:("func_80B8C59C",),
0x80B8C644:("func_80B8C644",),
0x80B8C9B8:("func_80B8C9B8",),
0x80B8B514:("EnGe2_DetectPlayer",),
0x80B8B5AC:("EnGe2_LookForPlayer",),
0x80B8B6B4:("EnGe2_SetupPath",),
0x80B8B7A8:("EnGe2_GetNextPath",),
0x80B8B848:("EnGe2_SetupBlownAwayPath",),
0x80B8B90C:("EnGe2_FollowPath",),
0x80B8BA40:("EnGe2_FollowPathWithoutGravity",),
0x80B8BB3C:("EnGe2_SpawnEffects",),
0x80B8BC1C:("EnGe2_Scream",),
0x80B8BC78:("EnGe2_ThrowPlayerOut",),
0x80B8BCEC:("EnGe2_TurnToPlayerFast",),
0x80B8BD38:("EnGe2_CapturePlayer",),
0x80B8BD90:("EnGe2_SetupCapturePlayer",),
0x80B8BE08:("EnGe2_Charge",),
0x80B8BF04:("EnGe2_SetupCharge",),
0x80B8BFC8:("EnGe2_SetupLookAround",),
0x80B8C048:("EnGe2_Stunned",),
0x80B8C0B0:("EnGe2_KnockedOut",),
0x80B8C13C:("EnGe2_PatrolDuties",),
0x80B8C45C:("EnGe2_LookAround",),
0x80B8C59C:("EnGe2_Walk",),
0x80B8C644:("EnGe2_PerformCutsceneActions",),
0x80B8C9B8:("EnGe2_GuardStationary",),
0x80B8CAA8:("EnGe2_Update",),
0x80B8CC0C:("func_80B8CC0C",),
0x80B8CCB4:("func_80B8CCB4",),
0x80B8CCFC:("func_80B8CCFC",),
0x80B8CC0C:("EnGe2_ValidatePictograph",),
0x80B8CCB4:("EnGe2_OverrideLimbDraw",),
0x80B8CCFC:("EnGe2_PostLimbDraw",),
0x80B8CD3C:("EnGe2_Draw",),
0x80B8D030:("EnMaYts_UpdateEyes",),
0x80B8D0BC:("EnMaYts_ChangeAnim",),
@ -14960,9 +14960,9 @@
0x80B9AF50:("func_80B9AF50",),
0x80B9AFE0:("ObjBoat_Init",),
0x80B9B0F0:("ObjBoat_Destroy",),
0x80B9B124:("func_80B9B124",),
0x80B9B124:("ObjBoat_SetRotations",),
0x80B9B1B8:("ObjBoat_Update",),
0x80B9B428:("func_80B9B428",),
0x80B9B428:("ObjBoat_UpdateCutscene",),
0x80B9B628:("ObjBoat_Draw",),
0x80B9B6E0:("func_80B9B6E0",),
0x80B9B74C:("func_80B9B74C",),

View File

@ -15182,13 +15182,13 @@
0x80B8ADB0:("D_80B8ADB0","f32","",0x4),
0x80B8ADB4:("D_80B8ADB4","f32","",0x4),
0x80B8CE20:("En_Ge2_InitVars","UNK_TYPE1","",0x1),
0x80B8CE40:("D_80B8CE40","UNK_TYPE1","",0x1),
0x80B8CE6C:("D_80B8CE6C","UNK_TYPE1","",0x1),
0x80B8CE78:("D_80B8CE78","UNK_TYPE1","",0x1),
0x80B8CE84:("D_80B8CE84","UNK_TYPE1","",0x1),
0x80B8CE88:("D_80B8CE88","UNK_TYPE1","",0x1),
0x80B8CE8C:("D_80B8CE8C","UNK_TYPE1","",0x1),
0x80B8CE98:("D_80B8CE98","UNK_TYPE1","",0x1),
0x80B8CE40:("sCylinderInit","ColliderCylinderInit","",0x2C),
0x80B8CE6C:("effectVelocity","Vec3f","",0xC),
0x80B8CE78:("effectAccel","Vec3f","",0xC),
0x80B8CE84:("effectPrimColor","Color_RGBA8","",0x4),
0x80B8CE88:("effectEnvColor","Color_RGBA8","",0x4),
0x80B8CE8C:("sFocusOffset","Vec3f","",0x1),
0x80B8CE98:("sEyeTextures","TexturePtr","[3]",0xC),
0x80B8CEB0:("jtbl_80B8CEB0","UNK_PTR","",0x4),
0x80B8E150:("En_Ma_Yts_InitVars","UNK_TYPE1","",0x1),
0x80B8E170:("D_80B8E170","ColliderCylinderInit","",0x2C),