mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-19 13:00:11 -07:00
z_horse: document horse-spawn helpers
Continuing the naming pass in `z_horse.c` for the decompilation. | old name | new name | purpose | |---------------|---------------------------|-----------------------------------| | func_8006CFC0 | Horse_IsValidScene | “is this scene horse-compatible?” | | func_8006D074 | Horse_SetDefaultSpawn | restore default save-file coords | | func_8006D0AC | Horse_PatchLakeHyliaSpawn | one-off Lake Hylia fixer | | func_8006D0EC | Horse_SetNormal | non-cutscene spawn path | | func_8006D684 | Horse_SetCutsceneMount | scripted mounts / races | | func_8006DC68 | Horse_InitForScene | init horse for a scene | | func_8006DD9C | Actor_RotateToPoint | generic actor rotation helper | Misc tidy-ups ============= * Added concise comments explaining each helper’s contract and quirks. * Updated declarations in `include/functions.h`. Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
ec54d02c0c
commit
76b7b756bb
8 changed files with 46 additions and 30 deletions
|
@ -889,13 +889,13 @@ void SkelCurve_SetAnim(SkelAnimeCurve* skelCurve, TransformUpdateIndex* transUpd
|
||||||
s32 SkelCurve_Update(PlayState* play, SkelAnimeCurve* skelCurve);
|
s32 SkelCurve_Update(PlayState* play, SkelAnimeCurve* skelCurve);
|
||||||
void SkelCurve_Draw(Actor* actor, PlayState* play, SkelAnimeCurve* skelCurve,
|
void SkelCurve_Draw(Actor* actor, PlayState* play, SkelAnimeCurve* skelCurve,
|
||||||
OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, void* data);
|
OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, void* data);
|
||||||
s32 func_8006CFC0(s32 scene);
|
s32 Horse_IsValidScene(s32 scene);
|
||||||
void func_8006D074(PlayState* play);
|
void Horse_SetDefaultSpawn(PlayState* play);
|
||||||
void func_8006D0AC(PlayState* play);
|
void Horse_PatchLakeHyliaSpawn(PlayState* play);
|
||||||
void func_8006D0EC(PlayState* play, Player* player);
|
void Horse_SetNormal(PlayState* play, Player* player);
|
||||||
void func_8006D684(PlayState* play, Player* player);
|
void Horse_SetCutsceneMount(PlayState* play, Player* player);
|
||||||
void func_8006DC68(PlayState* play, Player* player);
|
void Horse_InitForScene(PlayState* play, Player* player);
|
||||||
void func_8006DD9C(Actor* actor, Vec3f* arg1, s16 arg2);
|
void Actor_RotateToPoint(Actor* actor, Vec3f* target, s16 speed);
|
||||||
s32 Jpeg_Decode(void* data, void* zbuffer, void* workBuff, u32 workSize);
|
s32 Jpeg_Decode(void* data, void* zbuffer, void* workBuff, u32 workSize);
|
||||||
void KaleidoSetup_Update(PlayState* play);
|
void KaleidoSetup_Update(PlayState* play);
|
||||||
void KaleidoSetup_Init(PlayState* play);
|
void KaleidoSetup_Init(PlayState* play);
|
||||||
|
|
|
@ -1467,7 +1467,7 @@ s32 func_8002DEEC(Player* player) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8002DF18(PlayState* play, Player* player) {
|
void func_8002DF18(PlayState* play, Player* player) {
|
||||||
func_8006DC68(play, player);
|
Horse_InitForScene(play, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 func_8002DF38(PlayState* play, Actor* actor, u8 csAction) {
|
s32 func_8002DF38(PlayState* play, Actor* actor, u8 csAction) {
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
s32 func_8006CFC0(s32 scene) {
|
// Checks whether the current scene is one of the five “horse-compatible”
|
||||||
|
// outdoor maps (field, lake, two Gerudo areas, ranch).
|
||||||
|
s32 Horse_IsValidScene(s32 scene) {
|
||||||
s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS,
|
s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS,
|
||||||
SCENE_LON_LON_RANCH };
|
SCENE_LON_LON_RANCH };
|
||||||
s32 i;
|
s32 i;
|
||||||
|
@ -18,7 +20,9 @@ s32 func_8006CFC0(s32 scene) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8006D074(PlayState* play) {
|
// Hard-codes Epona’s default spawn information (Hyrule Field near the entrance
|
||||||
|
// to Gerudo Valley)
|
||||||
|
void Horse_SetDefaultSpawn(PlayState* play) {
|
||||||
gSaveContext.horseData.scene = SCENE_HYRULE_FIELD;
|
gSaveContext.horseData.scene = SCENE_HYRULE_FIELD;
|
||||||
gSaveContext.horseData.pos.x = -1840;
|
gSaveContext.horseData.pos.x = -1840;
|
||||||
gSaveContext.horseData.pos.y = 72;
|
gSaveContext.horseData.pos.y = 72;
|
||||||
|
@ -26,7 +30,10 @@ void func_8006D074(PlayState* play) {
|
||||||
gSaveContext.horseData.angle = -27353;
|
gSaveContext.horseData.angle = -27353;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8006D0AC(PlayState* play) {
|
// Only when the save already says “Lake Hylia”, overwrite the coords to the
|
||||||
|
// proper Lake Hylia shoreline start point. A one-off “oh, you’re at Lake, let me
|
||||||
|
// correct the numbers” fixer.
|
||||||
|
void Horse_PatchLakeHyliaSpawn(PlayState* play) {
|
||||||
if (gSaveContext.horseData.scene == SCENE_LAKE_HYLIA) {
|
if (gSaveContext.horseData.scene == SCENE_LAKE_HYLIA) {
|
||||||
gSaveContext.horseData.scene = SCENE_LAKE_HYLIA;
|
gSaveContext.horseData.scene = SCENE_LAKE_HYLIA;
|
||||||
gSaveContext.horseData.pos.x = -2065;
|
gSaveContext.horseData.pos.x = -2065;
|
||||||
|
@ -43,7 +50,9 @@ typedef struct {
|
||||||
/* 0x0A */ s16 type;
|
/* 0x0A */ s16 type;
|
||||||
} HorseSpawn;
|
} HorseSpawn;
|
||||||
|
|
||||||
void func_8006D0EC(PlayState* play, Player* player) {
|
// Decides whether to actually drop a horse actor into the world or instantly
|
||||||
|
// mount Link on one.
|
||||||
|
void Horse_SetNormal(PlayState* play, Player* player) {
|
||||||
s32 i;
|
s32 i;
|
||||||
HorseSpawn horseSpawns[] = {
|
HorseSpawn horseSpawns[] = {
|
||||||
{ SCENE_HYRULE_FIELD, -460, 100, 6640, 0, 2 }, { SCENE_LAKE_HYLIA, -1929, -1025, 768, 0, 2 },
|
{ SCENE_HYRULE_FIELD, -460, 100, 6640, 0, 2 }, { SCENE_LAKE_HYLIA, -1929, -1025, 768, 0, 2 },
|
||||||
|
@ -88,7 +97,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
|
||||||
osSyncPrintf("馬存在によるセット %d %d %d\n", gSaveContext.horseData.scene,
|
osSyncPrintf("馬存在によるセット %d %d %d\n", gSaveContext.horseData.scene,
|
||||||
Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED), DREG(1));
|
Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED), DREG(1));
|
||||||
|
|
||||||
if (func_8006CFC0(gSaveContext.horseData.scene)) {
|
if (Horse_IsValidScene(gSaveContext.horseData.scene)) {
|
||||||
Actor* horseActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, gSaveContext.horseData.pos.x,
|
Actor* horseActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, gSaveContext.horseData.pos.x,
|
||||||
gSaveContext.horseData.pos.y, gSaveContext.horseData.pos.z, 0,
|
gSaveContext.horseData.pos.y, gSaveContext.horseData.pos.z, 0,
|
||||||
gSaveContext.horseData.angle, 0, 1, true);
|
gSaveContext.horseData.angle, 0, 1, true);
|
||||||
|
@ -101,7 +110,7 @@ void func_8006D0EC(PlayState* play, Player* player) {
|
||||||
// "Horse_SetNormal():%d set spot is no good."
|
// "Horse_SetNormal():%d set spot is no good."
|
||||||
osSyncPrintf("Horse_SetNormal():%d セットスポットまずいです。\n", gSaveContext.horseData.scene);
|
osSyncPrintf("Horse_SetNormal():%d セットスポットまずいです。\n", gSaveContext.horseData.scene);
|
||||||
osSyncPrintf(VT_RST);
|
osSyncPrintf(VT_RST);
|
||||||
func_8006D074(play);
|
Horse_SetDefaultSpawn(play);
|
||||||
}
|
}
|
||||||
} else if ((play->sceneNum == SCENE_LON_LON_RANCH) && !Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) &&
|
} else if ((play->sceneNum == SCENE_LON_LON_RANCH) && !Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) &&
|
||||||
(DREG(1) == 0)) {
|
(DREG(1) == 0)) {
|
||||||
|
@ -137,7 +146,10 @@ typedef struct {
|
||||||
/* 0x10 */ s16 type;
|
/* 0x10 */ s16 type;
|
||||||
} struct_8011F9B8;
|
} struct_8011F9B8;
|
||||||
|
|
||||||
void func_8006D684(PlayState* play, Player* player) {
|
// Handles “special” scripted mounts: field reload points, Lon Lon race, Gerudo
|
||||||
|
// Fortress archery, etc. It mounts Link, positions the camera, or spawns
|
||||||
|
// passive horses depending on the cutscene index in that lookup table.
|
||||||
|
void Horse_SetCutsceneMount(PlayState* play, Player* player) {
|
||||||
s32 pad;
|
s32 pad;
|
||||||
s32 i;
|
s32 i;
|
||||||
Vec3s spawnPos;
|
Vec3s spawnPos;
|
||||||
|
@ -248,17 +260,19 @@ void func_8006D684(PlayState* play, Player* player) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8006DC68(PlayState* play, Player* player) {
|
// Top-level dispatcher for adult-Link scenes. Validates the saved spawn, then
|
||||||
|
// calls either Horse_SetCutsceneMount or Horse_SetNormal as appropriate.
|
||||||
|
void Horse_InitForScene(PlayState* play, Player* player) {
|
||||||
if (LINK_IS_ADULT) {
|
if (LINK_IS_ADULT) {
|
||||||
if (!func_8006CFC0(gSaveContext.horseData.scene)) {
|
if (!Horse_IsValidScene(gSaveContext.horseData.scene)) {
|
||||||
osSyncPrintf(VT_COL(RED, WHITE));
|
osSyncPrintf(VT_COL(RED, WHITE));
|
||||||
// "Horse_Set_Check():%d set spot is no good."
|
// "Horse_Set_Check():%d set spot is no good."
|
||||||
osSyncPrintf("Horse_Set_Check():%d セットスポットまずいです。\n", gSaveContext.horseData.scene);
|
osSyncPrintf("Horse_Set_Check():%d セットスポットまずいです。\n", gSaveContext.horseData.scene);
|
||||||
osSyncPrintf(VT_RST);
|
osSyncPrintf(VT_RST);
|
||||||
func_8006D074(play);
|
Horse_SetDefaultSpawn(play);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func_8006CFC0(play->sceneNum)) {
|
if (Horse_IsValidScene(play->sceneNum)) {
|
||||||
if ((gSaveContext.sceneSetupIndex > 3) ||
|
if ((gSaveContext.sceneSetupIndex > 3) ||
|
||||||
((gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_11 ||
|
((gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_11 ||
|
||||||
gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_12 ||
|
gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_12 ||
|
||||||
|
@ -267,15 +281,17 @@ void func_8006DC68(PlayState* play, Player* player) {
|
||||||
(gSaveContext.respawnFlag == 0)) ||
|
(gSaveContext.respawnFlag == 0)) ||
|
||||||
((play->sceneNum == SCENE_LON_LON_RANCH) && ((gSaveContext.eventInf[0] & 0xF) == 6) &&
|
((play->sceneNum == SCENE_LON_LON_RANCH) && ((gSaveContext.eventInf[0] & 0xF) == 6) &&
|
||||||
!Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) && (DREG(1) == 0))) {
|
!Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) && (DREG(1) == 0))) {
|
||||||
func_8006D684(play, player);
|
Horse_SetCutsceneMount(play, player);
|
||||||
} else {
|
} else {
|
||||||
func_8006D0EC(play, player);
|
Horse_SetNormal(play, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8006DD9C(Actor* actor, Vec3f* arg1, s16 arg2) {
|
// Generic helper: smoothly yaw an actor toward a target point, clamping the
|
||||||
|
// turn speed. It’s used by horse AI but isn’t horse-specific.
|
||||||
|
void Actor_RotateToPoint(Actor* actor, Vec3f* arg1, s16 arg2) {
|
||||||
s16 x = Math_Vec3f_Yaw(&actor->world.pos, arg1) - actor->world.rot.y;
|
s16 x = Math_Vec3f_Yaw(&actor->world.pos, arg1) - actor->world.rot.y;
|
||||||
|
|
||||||
if (x > arg2) {
|
if (x > arg2) {
|
||||||
|
|
|
@ -1913,7 +1913,7 @@ u8 Item_Give(PlayState* play, u8 item) {
|
||||||
osSyncPrintf(VT_RST);
|
osSyncPrintf(VT_RST);
|
||||||
|
|
||||||
if (item == ITEM_MEDALLION_WATER) {
|
if (item == ITEM_MEDALLION_WATER) {
|
||||||
func_8006D0AC(play);
|
Horse_PatchLakeHyliaSpawn(play);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
||||||
|
|
|
@ -235,7 +235,7 @@ void EnGe1_KickPlayer(EnGe1* this, PlayState* play) {
|
||||||
if (this->cutsceneTimer > 0) {
|
if (this->cutsceneTimer > 0) {
|
||||||
this->cutsceneTimer--;
|
this->cutsceneTimer--;
|
||||||
} else {
|
} else {
|
||||||
func_8006D074(play);
|
Horse_SetDefaultSpawn(play);
|
||||||
|
|
||||||
if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) {
|
if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) {
|
||||||
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1;
|
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1;
|
||||||
|
|
|
@ -244,7 +244,7 @@ void EnGe2_CaptureClose(EnGe2* this, PlayState* play) {
|
||||||
if (this->timer > 0) {
|
if (this->timer > 0) {
|
||||||
this->timer--;
|
this->timer--;
|
||||||
} else {
|
} else {
|
||||||
func_8006D074(play);
|
Horse_SetDefaultSpawn(play);
|
||||||
|
|
||||||
if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) {
|
if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) {
|
||||||
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1;
|
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1;
|
||||||
|
@ -274,7 +274,7 @@ void EnGe2_CaptureCharge(EnGe2* this, PlayState* play) {
|
||||||
if (this->timer > 0) {
|
if (this->timer > 0) {
|
||||||
this->timer--;
|
this->timer--;
|
||||||
} else {
|
} else {
|
||||||
func_8006D074(play);
|
Horse_SetDefaultSpawn(play);
|
||||||
|
|
||||||
if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) {
|
if ((INV_CONTENT(ITEM_HOOKSHOT) == ITEM_NONE) || (INV_CONTENT(ITEM_LONGSHOT) == ITEM_NONE)) {
|
||||||
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1;
|
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_1;
|
||||||
|
|
|
@ -532,7 +532,7 @@ void EnHorse_RaceWaypointPos(RaceWaypoint* waypoints, s32 idx, Vec3f* pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnHorse_RotateToPoint(EnHorse* this, PlayState* play, Vec3f* pos, s16 turnAmount) {
|
void EnHorse_RotateToPoint(EnHorse* this, PlayState* play, Vec3f* pos, s16 turnAmount) {
|
||||||
func_8006DD9C(&this->actor, pos, turnAmount);
|
Actor_RotateToPoint(&this->actor, pos, turnAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnHorse_UpdateIngoRaceInfo(EnHorse* this, PlayState* play, RaceInfo* raceInfo) {
|
void EnHorse_UpdateIngoRaceInfo(EnHorse* this, PlayState* play, RaceInfo* raceInfo) {
|
||||||
|
|
|
@ -453,7 +453,7 @@ void func_80A6A5A4(EnHorseLinkChild* this, PlayState* play) {
|
||||||
yawDiff = Actor_WorldYawTowardActor(&this->actor, &GET_PLAYER(play)->actor) - this->actor.world.rot.y;
|
yawDiff = Actor_WorldYawTowardActor(&this->actor, &GET_PLAYER(play)->actor) - this->actor.world.rot.y;
|
||||||
// 0.7071 = cos(pi/4)
|
// 0.7071 = cos(pi/4)
|
||||||
if ((Math_CosS(yawDiff) < 0.7071f) && (this->animationIdx == 2)) {
|
if ((Math_CosS(yawDiff) < 0.7071f) && (this->animationIdx == 2)) {
|
||||||
func_8006DD9C(&this->actor, &GET_PLAYER(play)->actor.world.pos, 300);
|
Actor_RotateToPoint(&this->actor, &GET_PLAYER(play)->actor.world.pos, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SkelAnime_Update(&this->skin.skelAnime)) {
|
if (SkelAnime_Update(&this->skin.skelAnime)) {
|
||||||
|
@ -490,9 +490,9 @@ void func_80A6A7D0(EnHorseLinkChild* this, PlayState* play) {
|
||||||
|
|
||||||
if ((this->animationIdx == 4) || (this->animationIdx == 3) || (this->animationIdx == 2)) {
|
if ((this->animationIdx == 4) || (this->animationIdx == 3) || (this->animationIdx == 2)) {
|
||||||
if (!this->unk_1E8) {
|
if (!this->unk_1E8) {
|
||||||
func_8006DD9C(&this->actor, &player->actor.world.pos, 300);
|
Actor_RotateToPoint(&this->actor, &player->actor.world.pos, 300);
|
||||||
} else {
|
} else {
|
||||||
func_8006DD9C(&this->actor, &this->actor.home.pos, 300);
|
Actor_RotateToPoint(&this->actor, &this->actor.home.pos, 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue