summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2023-06-01 15:11:11 -0400
committerGitHub <noreply@github.com>2023-06-01 15:11:11 -0400
commiteb24680be36616c36009e17e1e09608db17560b8 (patch)
treeeb75033e198852c8bbac91489b2493ea04360f33 /src/code
parent64959177d90f158e2e39ca3a6b728f915bf084b5 (diff)
`z_horse.c` OK (#1245)
* func_800F3940 * func_800F3B2C, func_800F415C and func_800F41E4 * func_800F40A0 * func_800F3ED4 * func_800F3C44 * func_800F3B68 NON_MATCHING * func_800F3A64 kinda * func_800F39B4 * cleanups * import data * fix fake match * format * Scene enum * minor cleanup on data usage * Horse_RotateToPoint and ENHORSE_PARAMS * scene setup index Co-authored-by: Tom Overton <tom-overton@users.noreply.github.com> * fix merge * z64horse.h * Renames * and even more renames * format * fix * review * Horse_IsActive * review * bss * fix * remove comments * Update src/code/z_horse.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * review * Update src/code/z_horse.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * review --------- Co-authored-by: Tom Overton <tom-overton@users.noreply.github.com> Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_actor.c7
-rw-r--r--src/code/z_horse.c232
-rw-r--r--src/code/z_sram_NES.c7
3 files changed, 230 insertions, 16 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index c46b6ec3b..b5a24cfac 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -4,6 +4,7 @@
*/
#include "global.h"
+#include "z64horse.h"
#include "z64load.h"
#include "z64quake.h"
#include "z64rumble.h"
@@ -1357,8 +1358,8 @@ s32 func_800B7200(Player* player) {
return (player->stateFlags1 & (PLAYER_STATE1_80 | PLAYER_STATE1_20000000)) || (player->csMode != PLAYER_CSMODE_0);
}
-void func_800B722C(GameState* gameState, Player* player) {
- func_800F40A0(gameState, player);
+void Actor_SpawnHorse(PlayState* play, Player* player) {
+ Horse_Spawn(play, player);
}
s32 func_800B724C(PlayState* play, Actor* actor, u8 csMode) {
@@ -2304,7 +2305,7 @@ void Actor_InitContext(PlayState* play, ActorContext* actorCtx, ActorEntry* acto
Actor_TargetContextInit(&actorCtx->targetContext, actorCtx->actorLists[ACTORCAT_PLAYER].first, play);
Actor_InitHalfDaysBit(actorCtx);
Fault_AddClient(&sActorFaultClient, (void*)Actor_PrintLists, actorCtx, NULL);
- func_800B722C(&play->state, (Player*)actorCtx->actorLists[ACTORCAT_PLAYER].first);
+ Actor_SpawnHorse(play, (Player*)actorCtx->actorLists[ACTORCAT_PLAYER].first);
}
/**
diff --git a/src/code/z_horse.c b/src/code/z_horse.c
index 976ea2948..ac0142fae 100644
--- a/src/code/z_horse.c
+++ b/src/code/z_horse.c
@@ -1,21 +1,233 @@
#include "global.h"
+#include "z64horse.h"
+#include "overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h"
+#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F3940.s")
+s32 Horse_GetJumpingFencePathIndex(PlayState* play) {
+ Actor* actor;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F39B4.s")
+ for (actor = NULL;; actor = actor->next) {
+ actor = SubS_FindActor(play, actor, ACTORCAT_PROP, ACTOR_BG_UMAJUMP);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F3A64.s")
+ if (actor == NULL) {
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F3B2C.s")
+ if (actor->params == BG_UMAJUMP_TYPE_2) {
+ return ((BgUmajump*)actor)->pathIndex;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F3B68.s")
+ return -1;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F3C44.s")
+// unused
+s32 Horse_CopyPointFromPathList(PlayState* play, s32 pathIndex, s32 pointIndex, Vec3s* dst, s16* arg4) {
+ Path* path = &play->setupPathList[pathIndex];
+ Vec3s* points;
+ s32 count = path->count;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F3ED4.s")
+ dst->x = 0;
+ dst->y = 0;
+ dst->z = 0;
+ *arg4 = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F40A0.s")
+ if (count == 0) {
+ return false;
+ }
+ if (pointIndex >= count) {
+ return false;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F415C.s")
+ points = Lib_SegmentedToVirtual(path->points);
+ points += pointIndex;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_horse/func_800F41E4.s")
+ dst->x = points->x;
+ dst->y = points->y;
+ dst->z = points->z;
+ *arg4 = 0;
+
+ return true;
+}
+
+typedef struct HorseValidScene {
+ /* 0x0 */ s16 sceneId;
+ /* 0x2 */ s16 sceneLayerMinusOne;
+} HorseValidScene; // size = 0x4
+
+HorseValidScene sHorseValidScenes[] = {
+ { SCENE_00KEIKOKU, 0 }, // Termina Field
+ { SCENE_24KEMONOMITI, 0 }, // Road to southern swap
+ { SCENE_F01, 0 }, // Romani ranch
+ { SCENE_KOEPONARACE, 0 }, // Gorman track
+ { SCENE_20SICHITAI, 0 }, // Southern swamp poisoned
+ { SCENE_20SICHITAI2, 0 }, // Souther swamp clear
+ { SCENE_30GYOSON, 0 }, // Great bay coast
+ { SCENE_31MISAKI, 0 }, // Zora cape
+ { SCENE_ROMANYMAE, 0 }, // Milk road
+ { SCENE_IKANAMAE, 0 }, // Road to Ikana
+ { SCENE_13HUBUKINOMITI, 0 }, // Path to Mountain Village
+};
+
+s32 Horse_IsValidSpawn(s16 sceneId) {
+ s32 i;
+
+ for (i = 0; i < ARRAY_COUNT(sHorseValidScenes); i++) {
+ if (sceneId == sHorseValidScenes[i].sceneId) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void Horse_ResetHorseData(PlayState* play) {
+ gSaveContext.save.saveInfo.horseData.sceneId = SCENE_F01;
+ gSaveContext.save.saveInfo.horseData.pos.x = -1420;
+ gSaveContext.save.saveInfo.horseData.pos.y = 257;
+ gSaveContext.save.saveInfo.horseData.pos.z = -1285;
+ gSaveContext.save.saveInfo.horseData.yaw = 0x2AAA;
+}
+
+s32 gHorseIsMounted = false;
+s32 D_801BDAA0 = false;
+s32 gHorsePlayedEponasSong = false;
+
+HorseValidScene sHorseValidSceneLayers[] = {
+ { SCENE_00KEIKOKU, 5 - 1 }, // Termina Field - First Cycle
+ { SCENE_30GYOSON, 1 - 1 }, // Great Bay Coast - Post-Gyorg
+ { SCENE_31MISAKI, 1 - 1 }, // Zora Cape - Post-Gyorg
+ { SCENE_13HUBUKINOMITI, 1 - 1 }, // Path to Mountain Village - Post-Goht
+};
+
+s32 Horse_IsValidSceneLayer(PlayState* play, Player* player) {
+ s32 i;
+
+ if (gSaveContext.sceneLayer == 0) {
+ return true;
+ }
+
+ for (i = 0; i < ARRAY_COUNT(sHorseValidSceneLayers); i++) {
+ if ((sHorseValidSceneLayers[i].sceneId == play->sceneId) &&
+ (gSaveContext.sceneLayer == sHorseValidSceneLayers[i].sceneLayerMinusOne + 1)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Horse_SpawnOverworld(PlayState* play, Player* player) {
+ if (!Horse_IsValidSceneLayer(play, player)) {
+ return;
+ }
+
+ if (gHorseIsMounted && CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) {
+ s32 pad;
+ Vec3f pos = player->actor.world.pos;
+ f32 yIntersect;
+ CollisionPoly* poly;
+ s32 pad2[3];
+
+ pos.y += 5.0f;
+ yIntersect = BgCheck_EntityRaycastFloor1(&play->colCtx, &poly, &pos);
+ if (yIntersect == BGCHECK_Y_MIN) {
+ yIntersect = player->actor.world.pos.y;
+ }
+
+ player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, player->actor.world.pos.x, yIntersect,
+ player->actor.world.pos.z, player->actor.shape.rot.x, player->actor.shape.rot.y,
+ player->actor.shape.rot.z, ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_11));
+ Actor_MountHorse(play, player, player->rideActor);
+ Actor_SetCameraHorseSetting(play, player);
+ } else if ((play->sceneId == gSaveContext.save.saveInfo.horseData.sceneId) && CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) {
+ if (Horse_IsValidSpawn(gSaveContext.save.saveInfo.horseData.sceneId)) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, gSaveContext.save.saveInfo.horseData.pos.x,
+ gSaveContext.save.saveInfo.horseData.pos.y, gSaveContext.save.saveInfo.horseData.pos.z, 0,
+ gSaveContext.save.saveInfo.horseData.yaw, 0, ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_1));
+ } else {
+ Horse_ResetHorseData(play);
+ }
+ } else if ((play->sceneId == SCENE_F01) && !CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -1420.0f, 257.0f, -1285.0f, 0, 0x2AAA, 0,
+ ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_1));
+ } else if (CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && Horse_IsValidSpawn(play->sceneId)) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, player->actor.world.pos.x, player->actor.world.pos.y,
+ player->actor.world.pos.z, 0, player->actor.shape.rot.y, 0,
+ ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_2));
+ }
+}
+
+void Horse_SpawnMinigame(PlayState* play, Player* player) {
+ if ((play->sceneId == SCENE_KOEPONARACE) &&
+ (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_START)) {
+ player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -1262.0f, -106.0f, 470.0f, 0, 0x7FFF, 0,
+ ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_13));
+ Actor_MountHorse(play, player, player->rideActor);
+ Actor_SetCameraHorseSetting(play, player);
+ } else if ((play->sceneId == SCENE_KOEPONARACE) &&
+ ((GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_3) ||
+ (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_2))) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -1741.0f, -106.0f, -641.0f, 0, -0x4FA4, 0,
+ ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_1));
+ } else if ((gSaveContext.save.entrance == ENTRANCE(ROMANI_RANCH, 0)) && (Cutscene_GetSceneLayer(play) != 0) &&
+ (player->transformation == PLAYER_FORM_HUMAN)) {
+ player->rideActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -1106.0f, 260.0f, -1185.0f, 0, 0x13, 0,
+ ENHORSE_PARAMS(ENHORSE_PARAM_4000, ENHORSE_7));
+ Actor_MountHorse(play, player, player->rideActor);
+ Actor_SetCameraHorseSetting(play, player);
+ }
+}
+
+void Horse_Spawn(PlayState* play, Player* player) {
+ if (((play->sceneId == SCENE_KOEPONARACE) &&
+ (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_START)) ||
+ ((play->sceneId == SCENE_F01) && (((gSaveContext.sceneLayer == 1)) || (gSaveContext.sceneLayer == 5)) &&
+ (player->transformation == PLAYER_FORM_HUMAN)) ||
+ ((play->sceneId == SCENE_KOEPONARACE) &&
+ (((GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_3)) ||
+ (GET_WEEKEVENTREG_HORSE_RACE_STATE == WEEKEVENTREG_HORSE_RACE_STATE_2)))) {
+ // Gorman Track and horse state is either STATE_START, STATE_2 or STATE_3
+ // or Romani Ranch, Player is Human and scene layer is either 1 or 5
+ Horse_SpawnMinigame(play, player);
+ } else {
+ Horse_SpawnOverworld(play, player);
+ }
+
+ D_801BDAA0 = false;
+}
+
+void Horse_RotateToPoint(Actor* actor, Vec3f* pos, s16 turnYaw) {
+ s16 yaw = Math_Vec3f_Yaw(&actor->world.pos, pos) - actor->world.rot.y;
+
+ if (yaw > turnYaw) {
+ actor->world.rot.y += turnYaw;
+ } else if (yaw < -turnYaw) {
+ actor->world.rot.y -= turnYaw;
+ } else {
+ actor->world.rot.y += yaw;
+ }
+
+ actor->shape.rot.y = actor->world.rot.y;
+}
+
+s32 Horse_IsActive(PlayState* play, ActorContext* actorCtx) {
+ Actor* bgActor = actorCtx->actorLists[ACTORCAT_BG].first;
+
+ if (bgActor != NULL) {
+ while (true) {
+ if ((bgActor->update != NULL) && (bgActor->init == NULL)) {
+ if (Object_IsLoaded(&play->objectCtx, bgActor->objBankIndex)) {
+ if ((bgActor->id == ACTOR_EN_HORSE) && (((EnHorse*)bgActor)->action != ENHORSE_ACTION_INACTIVE)) {
+ return true;
+ }
+ }
+ }
+ bgActor = bgActor->next;
+ if (bgActor == NULL) {
+ break;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c
index cfd230569..ac68f0fac 100644
--- a/src/code/z_sram_NES.c
+++ b/src/code/z_sram_NES.c
@@ -1,5 +1,6 @@
#include "prevent_bss_reordering.h"
#include "global.h"
+#include "z64horse.h"
#include "overlays/gamestates/ovl_file_choose/z_file_choose.h"
void func_80146EBC(SramContext* sramCtx, s32 curPage, s32 numPages);
@@ -454,7 +455,7 @@ void Sram_SaveEndOfCycle(PlayState* play) {
gSaveContext.jinxTimer = 0;
gSaveContext.rupeeAccumulator = 0;
- func_800F3B2C(play);
+ Horse_ResetHorseData(play);
}
void Sram_IncrementDay(void) {
@@ -884,8 +885,8 @@ void Sram_ResetSaveFromMoonCrash(SramContext* sramCtx) {
gSaveContext.timerPausedOsTimes[i] = 0;
}
- D_801BDAA0 = 1;
- D_801BDA9C = 0;
+ D_801BDAA0 = true;
+ gHorseIsMounted = false;
gSaveContext.powderKegTimer = 0;
gSaveContext.unk_1014 = 0;
gSaveContext.jinxTimer = 0;