Finish documentation

This commit is contained in:
tom-overton
2021-11-08 01:43:35 -08:00
parent c2355edb95
commit 340462ea44
3 changed files with 289 additions and 237 deletions
@@ -1,7 +1,7 @@
/*
* File: z_obj_tokeidai.c
* Overlay: ovl_Obj_Tokeidai
* Description: Clock Face
* Description: Components of the Clock Tower (gears, clock face, counterweight, etc). Also used for wall clocks.
*/
#include "z_obj_tokeidai.h"
@@ -15,42 +15,45 @@ void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_Draw(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_CollapseGear(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TransformedGearIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TransformedClockFaceFall(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TransformedClockIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_CollapseTop(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TransformedTopIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_CollapseWalls(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_WallsIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerTransformationFinish(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerTransformationWait(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerTopFall(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerRaiseFinished(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerTransformationStart(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_DoNothing(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_StaircaseIntoTowerIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerClockIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_SmallClockIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerGearIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerTopIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_SetupTowerTransformationStart(ObjTokeidai* this);
void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_DrawTowerTop(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_DrawTowerGear(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_TowerClock_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerGear_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_Counterweight_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_TowerGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_Walls_Idle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_StaircaseIntoTower_Idle(ObjTokeidai* this, GlobalContext* globalCtx);
void ObjTokeidai_SetupTowerTransformation(ObjTokeidai* this);
void ObjTokeidai_Clock_Draw(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx);
void ObjTokeidai_TowerGear_Draw(Actor* thisx, GlobalContext* globalCtx);
// Silly overload defines that I'm not sure I should even be doing
#define settleTimer clockFaceAdditionalRotation
#define transformationRotationalVelocity clockFaceAdditionalRotation
#define transformationWaitTimer clockFaceAdditionalRotation
#define slidingClockFaceAngle clockFaceAdditionalRotation
#define settleAmount clockFaceRotationTimer
#define transformationRotationalAcceleration clockFaceRotationTimer
#define aerialClockFaceSpeed clockFaceRotationTimer
#define clockFaceRotationalVelocity sunMoonDiskAdditionalRotation
#define lightIntensity clockHour
// Used for regular clock functions
#define clockFaceRotationalVelocity actionVar1
#define clockFaceRotationTimer actionVar2
#define sunMoonDiskRotationalVelocity actionVar3
#define clockHour actionVar4
// Used for regular counterweight functions
#define spotlightIntensity actionVar4
// Used in ObjTokeidai_TowerTransformation_FinishRaise
#define settleTimer actionVar1
#define settleAmount actionVar2
// Used in ObjTokeidai_TowerTransformation_DropCounterweight
#define transformationRotationalVelocity actionVar1
#define transformationRotationalAcceleration actionVar2
// Used in ObjTokeidai_TowerTransformation_Wait
#define transformationWaitTimer actionVar1
// Used in ObjTokeidai_TowerClock_SlideOff and ObjTokeidai_TowerClock_Fall
#define slidingClockFaceAngle actionVar1
#define aerialClockFaceSpeed actionVar2
#define fallingClockFaceRotationalVelocity actionVar3
const ActorInit Obj_Tokeidai_InitVars = {
ACTOR_OBJ_TOKEIDAI,
@@ -72,19 +75,25 @@ static InitChainEntry D_80AB49E0[] = {
ICHAIN_F32(uncullZoneForward, 1100, ICHAIN_STOP),
};
extern Gfx D_06009A08[]; // central part of the tower
extern Gfx D_0600B0C0[]; // light beam
extern Gfx D_0600B208[]; // thing at the top of the tower
extern Gfx D_0600BA78[]; // gear on the side of the tower
extern Gfx D_06009A08[]; // the tower's four walls, used in Termina Field
extern Gfx D_0600B0C0[]; // spotlight emitted from the counterweight at night
extern Gfx D_0600B208[]; // the tower's counterweight
extern Gfx D_0600BA78[]; // rotating gear on the side of the tower
extern Gfx D_0600BEE8[]; // clock center and "hand"
extern Gfx D_0600C368[]; // sun and moon circle
extern Gfx D_0600C368[]; // sun and moon disk
extern Gfx D_0600CF28[]; // outer ring of the clock face
extern Gfx D_0600D388[]; // tower base?
extern Gfx D_0600D388[]; // unused tower wall
extern Gfx D_0600D8E0[]; // empty dlist
extern Gfx D_0600D8E8[]; // spiral staircase to tower interior
extern Gfx D_0600E818[]; // clock tower clock face
extern Gfx D_0600F518[]; // small and very small clock face
extern Gfx D_0600F518[]; // wall clock clock face
/**
* Returns the angle necessary to show the correct side of
* the sun and moon disk based on the time of day. The actual
* angle can differ from the target angle if the disk is in
* the middle of rotating.
*/
s32 ObjTokeidai_GetTargetSunMoonDiskRotation() {
if (gSaveContext.isNight) {
return 0x8000;
@@ -98,49 +107,51 @@ void ObjTokeidai_SetupClockOrGear(ObjTokeidai* this) {
currentMinute = OBJ_TOKEIDAI_GET_CURRENT_MINUTE(this);
this->clockMinute = currentMinute;
this->outerRingOrGearRotation = OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute);
this->outerRingOrGearAdditionalRotation = 0x3C;
this->outerRingOrGearRotationalVelocity = 0x3C;
this->outerRingOrGearRotationTimer = 0;
}
void ObjTokeidai_InitClock(ObjTokeidai* this) {
void ObjTokeidai_Clock_Init(ObjTokeidai* this) {
s32 currentHour;
ObjTokeidai_SetupClockOrGear(this);
currentHour = OBJ_TOKEIDAI_GET_CURRENT_HOUR(this);
this->clockHour = currentHour;
this->clockFaceRotation = OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour);
this->clockFaceAdditionalRotation = 0;
this->clockFaceRotationalVelocity = 0;
this->clockFaceRotationTimer = 0;
this->sunMoonDiskAdditionalRotation = 0;
this->sunMoonDiskRotationalVelocity = 0;
this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation();
}
void ObjTokeidai_InitTowerGear(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.draw = ObjTokeidai_DrawTowerGear;
void ObjTokeidai_TowerGear_Init(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.draw = ObjTokeidai_TowerGear_Draw;
this->opaDList = D_0600BA78;
ObjTokeidai_SetupClockOrGear(this);
if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 &&
globalCtx->csCtx.unk_12 == 0) ||
(globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0)) {
ObjTokeidai_SetupTowerTransformationStart(this);
} else if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) {
this->actionFunc = ObjTokeidai_TransformedGearIdle;
ObjTokeidai_SetupTowerTransformation(this);
} else if (OBJ_TOKEIDAI_IS_TRANSFORMED()) {
this->actionFunc = ObjTokeidai_TowerGear_TransformedIdle;
this->actor.world.pos.y += this->actor.scale.y * 1900.0f;
this->actor.shape.yOffset = 1500.0f;
gSaveContext.weekEventReg[8] |= 0x40;
} else {
this->actionFunc = ObjTokeidai_TowerGearIdle;
this->actionFunc = ObjTokeidai_TowerGear_Idle;
}
}
void ObjTokeidai_InitTowerClock(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.draw = ObjTokeidai_DrawClock;
ObjTokeidai_InitClock(this);
void ObjTokeidai_TowerClock_Init(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.draw = ObjTokeidai_Clock_Draw;
ObjTokeidai_Clock_Init(this);
if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 &&
globalCtx->csCtx.unk_12 == 0) ||
(globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0)) {
ObjTokeidai_SetupTowerTransformationStart(this);
} else if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) {
ObjTokeidai_SetupTowerTransformation(this);
} else if (OBJ_TOKEIDAI_IS_TRANSFORMED()) {
this->actor.world.pos.y += (this->actor.scale.y * 5191.0f) - 50.0f;
this->actor.world.pos.x += Math_SinS(this->actor.world.rot.y) * this->actor.scale.z * 1791.0f;
this->actor.world.pos.z += -Math_CosS(this->actor.world.rot.y) * this->actor.scale.z * 1791.0f;
@@ -149,52 +160,54 @@ void ObjTokeidai_InitTowerClock(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.home.pos = this->actor.world.pos;
this->actor.home.pos.y -= 1178.0f;
this->actor.home.pos.z += 13.0f;
this->actionFunc = ObjTokeidai_TransformedClockIdle;
this->actionFunc = ObjTokeidai_TowerClock_TransformedIdle;
} else {
this->actionFunc = ObjTokeidai_TowerClockIdle;
this->actionFunc = ObjTokeidai_TowerClock_Idle;
}
}
void ObjTokeidai_InitTowerTop(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_Counterweight_Init(ObjTokeidai* this, GlobalContext* globalCtx) {
s32 type;
this->actor.draw = ObjTokeidai_DrawTowerTop;
this->actor.draw = ObjTokeidai_Counterweight_Draw;
this->opaDList = D_0600B208;
this->xluDList = D_0600B0C0;
if (gSaveContext.isNight) {
this->lightIntensity = 100;
this->spotlightIntensity = 100;
} else {
this->lightIntensity = 0;
this->spotlightIntensity = 0;
}
if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 &&
globalCtx->csCtx.unk_12 == 0) ||
(globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 2 && globalCtx->csCtx.unk_12 == 0)) {
this->lightIntensity = 0;
ObjTokeidai_SetupTowerTransformationStart(this);
this->spotlightIntensity = 0;
ObjTokeidai_SetupTowerTransformation(this);
if (this->actor.child == NULL) {
type = OBJ_TOKEIDAI_TYPE(&this->actor);
if (type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN || type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) {
if (type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN ||
type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) {
this->actor.child =
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HANABI, this->actor.world.pos.x,
this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0);
}
}
if (this->actor.child != NULL) {
if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) {
if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) {
this->actor.child->home.rot.x = 0x384;
} else {
this->actor.child->home.rot.x = 0x12C;
}
}
} else if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4) {
this->lightIntensity = 0;
} else if (OBJ_TOKEIDAI_IS_TRANSFORMED()) {
this->spotlightIntensity = 0;
this->actor.world.pos.y += this->actor.scale.y * -2160.0f;
this->actor.world.pos.x += Math_SinS(this->actor.world.rot.y) * this->actor.scale.z * 5400.0f;
this->actor.world.pos.z += -Math_CosS(this->actor.world.rot.y) * this->actor.scale.z * 5400.0f;
this->actor.shape.rot.x = -0x4000;
this->actionFunc = ObjTokeidai_TransformedTopIdle;
this->actionFunc = ObjTokeidai_Counterweight_TransformedIdle;
} else {
this->actionFunc = ObjTokeidai_TowerTopIdle;
this->actionFunc = ObjTokeidai_Counterweight_Idle;
}
}
@@ -210,13 +223,14 @@ void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) {
this->clockFaceZTranslation = 0;
this->currentTime = gSaveContext.time;
this->actor.home.rot.x = 0;
switch (OBJ_TOKEIDAI_TYPE(&this->actor)) {
case OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD:
Actor_SetScale(&this->actor, 0.15f);
ObjTokeidai_InitTowerGear(this, globalCtx);
ObjTokeidai_TowerGear_Init(this, globalCtx);
break;
case OBJ_TOKEIDAI_TYPE_TOWER_GEAR_CLOCK_TOWN:
ObjTokeidai_InitTowerGear(this, globalCtx);
ObjTokeidai_TowerGear_Init(this, globalCtx);
break;
case OBJ_TOKEIDAI_TYPE_UNUSED_WALL:
this->opaDList = D_0600D388;
@@ -224,38 +238,38 @@ void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) {
case OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD:
Actor_SetScale(&this->actor, 1.0f);
this->opaDList = D_06009A08;
this->actionFunc = ObjTokeidai_WallsIdle;
this->actionFunc = ObjTokeidai_Walls_Idle;
break;
case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD:
Actor_SetScale(&this->actor, 0.15f);
ObjTokeidai_InitTowerClock(this, globalCtx);
ObjTokeidai_TowerClock_Init(this, globalCtx);
break;
case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN:
ObjTokeidai_InitTowerClock(this, globalCtx);
ObjTokeidai_TowerClock_Init(this, globalCtx);
break;
case OBJ_TOKEIDAI_TYPE_SMALL_CLOCK:
case OBJ_TOKEIDAI_TYPE_WALL_CLOCK:
Actor_SetScale(&this->actor, 0.02f);
this->actor.draw = ObjTokeidai_DrawClock;
ObjTokeidai_InitClock(this);
this->actionFunc = ObjTokeidai_SmallClockIdle;
this->actor.draw = ObjTokeidai_Clock_Draw;
ObjTokeidai_Clock_Init(this);
this->actionFunc = ObjTokeidai_WallClock_Idle;
break;
case OBJ_TOKEIDAI_TYPE_VERY_SMALL_CLOCK:
case OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK:
Actor_SetScale(&this->actor, 0.01f);
this->actor.draw = ObjTokeidai_DrawClock;
ObjTokeidai_InitClock(this);
this->actionFunc = ObjTokeidai_SmallClockIdle;
this->actor.draw = ObjTokeidai_Clock_Draw;
ObjTokeidai_Clock_Init(this);
this->actionFunc = ObjTokeidai_WallClock_Idle;
break;
case OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD:
case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD:
Actor_SetScale(&this->actor, 0.15f);
ObjTokeidai_InitTowerTop(this, globalCtx);
ObjTokeidai_Counterweight_Init(this, globalCtx);
break;
case OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN:
ObjTokeidai_InitTowerTop(this, globalCtx);
case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN:
ObjTokeidai_Counterweight_Init(this, globalCtx);
break;
case OBJ_TOKEIDAI_TYPE_STAIRCASE_INTO_TOWER:
this->opaDList = D_0600D8E8;
this->xluDList = D_0600D8E0;
this->actionFunc = ObjTokeidai_StaircaseIntoTowerIdle;
this->actionFunc = ObjTokeidai_StaircaseIntoTower_Idle;
break;
}
}
@@ -263,7 +277,7 @@ void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) {
void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
void ObjTokeidai_HandleMinute(ObjTokeidai* this, s32 playSound) {
void ObjTokeidai_RotateOnMinuteChange(ObjTokeidai* this, s32 playSound) {
s32 currentMinute;
currentMinute = OBJ_TOKEIDAI_GET_CURRENT_MINUTE(this);
@@ -271,10 +285,15 @@ void ObjTokeidai_HandleMinute(ObjTokeidai* this, s32 playSound) {
if (this->outerRingOrGearRotationTimer == 8 && playSound) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_SECOND_HAND);
}
if (this->outerRingOrGearRotationTimer >= 9) {
this->outerRingOrGearAdditionalRotation += 0x3C;
this->outerRingOrGearRotation += this->outerRingOrGearAdditionalRotation;
// This actually performs the rotation to the next minute
// for the outer ring or gear.
this->outerRingOrGearRotationalVelocity += 0x3C;
this->outerRingOrGearRotation += this->outerRingOrGearRotationalVelocity;
} else {
// This makes the outer ring or gear wiggle in place for a bit
// before rotating to the next position.
if ((this->outerRingOrGearRotationTimer & 3) == 0) {
this->outerRingOrGearRotation += 0x5A;
}
@@ -282,19 +301,20 @@ void ObjTokeidai_HandleMinute(ObjTokeidai* this, s32 playSound) {
this->outerRingOrGearRotation -= 0x5A;
}
}
this->outerRingOrGearRotationTimer++;
if ((currentMinute == 15 && this->outerRingOrGearRotation < 0) ||
(currentMinute != 15 &&
this->outerRingOrGearRotation > OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute))) {
this->outerRingOrGearRotation = OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute);
this->clockMinute = currentMinute;
this->outerRingOrGearAdditionalRotation = 0x5A;
this->outerRingOrGearRotationalVelocity = 0x5A;
this->outerRingOrGearRotationTimer = 0;
}
}
}
void ObjTokeidai_CollapseGear(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerGear_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) {
if ((this->actor.bgCheckFlags & 1) || this->actor.world.pos.y < 0.0f) {
this->actionFunc = ObjTokeidai_DoNothing;
return;
@@ -305,22 +325,25 @@ void ObjTokeidai_CollapseGear(ObjTokeidai* this, GlobalContext* globalCtx) {
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4);
}
void ObjTokeidai_TransformedGearIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) != 0) {
if (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 2) {
this->actionFunc = ObjTokeidai_CollapseGear;
this->actor.speedXZ = this->actor.scale.y * 5.0f;
this->actor.velocity.y = 0.0f;
this->actor.minVelocityY = this->actor.scale.y * -50.0f;
this->actor.gravity = this->actor.scale.y * -5.0f;
}
void ObjTokeidai_TowerGear_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 2) {
this->actionFunc = ObjTokeidai_TowerGear_Collapse;
this->actor.speedXZ = this->actor.scale.y * 5.0f;
this->actor.velocity.y = 0.0f;
this->actor.minVelocityY = this->actor.scale.y * -50.0f;
this->actor.gravity = this->actor.scale.y * -5.0f;
}
}
void ObjTokeidai_TransformedClockFaceFall(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.shape.rot.x += this->clockFaceRotationalVelocity;
if (this->clockFaceRotationalVelocity >= 0xA1) {
this->clockFaceRotationalVelocity -= 5;
/**
* This doesn't seem to be used in the final game. This, used in conjunction
* with the following function, would make the tower's clock slide off the
* tower and spin through the air.
*/
void ObjTokeidai_TowerClock_Fall(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.shape.rot.x += this->fallingClockFaceRotationalVelocity;
if (this->fallingClockFaceRotationalVelocity >= 0xA1) {
this->fallingClockFaceRotationalVelocity -= 5;
}
this->actor.world.pos.z += 4.0f;
Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
@@ -329,7 +352,11 @@ void ObjTokeidai_TransformedClockFaceFall(ObjTokeidai* this, GlobalContext* glob
}
}
void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext* globalCtx) {
/**
* This doesn't seem to be used in the final game. Presumably, this would make the
* tower's clock slide off as the moon crashes into it.
*/
void ObjTokeidai_TowerClock_SlideOff(ObjTokeidai* this, GlobalContext* globalCtx) {
f32 cos;
f32 sin;
Actor* thisx = &this->actor;
@@ -340,18 +367,19 @@ void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext*
if (this->slidingClockFaceAngle >= 0x801) {
this->aerialClockFaceSpeed += 4;
}
if (this->aerialClockFaceSpeed < 0x80) {
thisx->shape.rot.x = this->slidingClockFaceAngle - 0x4000;
this->clockFaceRotationalVelocity = 0x28;
this->fallingClockFaceRotationalVelocity = 0x28;
} else {
if (thisx->shape.rot.x < -0x1000) {
thisx->shape.rot.x += this->clockFaceRotationalVelocity;
if (this->clockFaceRotationalVelocity < 0x1E0) {
this->clockFaceRotationalVelocity += 0xA;
thisx->shape.rot.x += this->fallingClockFaceRotationalVelocity;
if (this->fallingClockFaceRotationalVelocity < 0x1E0) {
this->fallingClockFaceRotationalVelocity += 0xA;
}
} else {
thisx->shape.rot.x += this->clockFaceRotationalVelocity;
this->actionFunc = ObjTokeidai_TransformedClockFaceFall;
thisx->shape.rot.x += this->fallingClockFaceRotationalVelocity;
this->actionFunc = ObjTokeidai_TowerClock_Fall;
thisx->minVelocityY = -7.5f;
thisx->gravity = -0.75f;
thisx->velocity.y = -2.0f;
@@ -364,15 +392,15 @@ void ObjTokeidai_TransformedClockFaceSlideOff(ObjTokeidai* this, GlobalContext*
thisx->world.pos.z = (1178.0f * sin) + (this->aerialClockFaceSpeed * cos) + thisx->home.pos.z;
}
void ObjTokeidai_TransformedClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) {
this->actionFunc = ObjTokeidai_TransformedClockFaceSlideOff;
void ObjTokeidai_TowerClock_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) {
this->actionFunc = ObjTokeidai_TowerClock_SlideOff;
this->slidingClockFaceAngle = 0;
this->aerialClockFaceSpeed = -0xD;
}
}
void ObjTokeidai_CollapseTop(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_Counterweight_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) {
if (this->actor.world.pos.y < 0.0f) {
this->actionFunc = ObjTokeidai_DoNothing;
return;
@@ -381,31 +409,33 @@ void ObjTokeidai_CollapseTop(ObjTokeidai* this, GlobalContext* globalCtx) {
Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor);
}
void ObjTokeidai_TransformedTopIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) != 0) {
if (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 3) {
this->actionFunc = ObjTokeidai_CollapseTop;
this->xRotation = 0;
this->actor.velocity.y = 0.0f;
this->actor.minVelocityY = this->actor.scale.y * -50.0f;
this->actor.gravity = this->actor.scale.y * -5.0f;
}
void ObjTokeidai_Counterweight_TransformedIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 3) {
this->actionFunc = ObjTokeidai_Counterweight_Collapse;
this->xRotation = 0;
this->actor.velocity.y = 0.0f;
this->actor.minVelocityY = this->actor.scale.y * -50.0f;
this->actor.gravity = this->actor.scale.y * -5.0f;
}
}
void ObjTokeidai_CollapseWalls(ObjTokeidai* this, GlobalContext* globalCtx) {
/**
* This doesn't seem to be used in the final game. Presumably, this would make the walls of
* the clock tower appear to buckle as the moon crashes into it.
*/
void ObjTokeidai_Walls_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) {
if (this->actor.shape.rot.x < 0x4000) {
this->actor.shape.rot.x += +0x28;
}
}
void ObjTokeidai_WallsIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_Walls_Idle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) {
this->actionFunc = ObjTokeidai_CollapseWalls;
this->actionFunc = ObjTokeidai_Walls_Collapse;
}
}
void ObjTokeidai_TowerTransformationEndCutscene(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerTransformation_EndCutscene(ObjTokeidai* this, GlobalContext* globalCtx) {
if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 5) {
gSaveContext.weekEventReg[8] |= 0x40;
if ((globalCtx->sceneNum == SCENE_CLOCKTOWER && gSaveContext.sceneSetupIndex == 2 &&
@@ -429,16 +459,18 @@ void ObjTokeidai_TowerTransformationEndCutscene(ObjTokeidai* this, GlobalContext
}
}
void ObjTokeidai_TowerTransformationFinish(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerTransformation_FinishTransformation(ObjTokeidai* this, GlobalContext* globalCtx) {
s32 type;
if (this->clockFaceZTranslation >= -0x13F) {
// Recess the clock face before ending the cutscene, since the Termina
// Field version of the cutscene looks right at it.
this->clockFaceZTranslation -= 0xA;
} else {
type = OBJ_TOKEIDAI_TYPE(&this->actor);
if ((type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN) ||
(type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD)) {
ObjTokeidai_TowerTransformationEndCutscene(this, globalCtx);
ObjTokeidai_TowerTransformation_EndCutscene(this, globalCtx);
} else {
this->actionFunc = ObjTokeidai_DoNothing;
if (this->actor.child != NULL) {
@@ -448,24 +480,25 @@ void ObjTokeidai_TowerTransformationFinish(ObjTokeidai* this, GlobalContext* glo
}
}
void ObjTokeidai_TowerTransformationWait(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerTransformation_Wait(ObjTokeidai* this, GlobalContext* globalCtx) {
if (this->transformationWaitTimer > 0) {
this->transformationWaitTimer--;
} else {
this->actionFunc = ObjTokeidai_TowerTransformationFinish;
this->actionFunc = ObjTokeidai_TowerTransformation_FinishTransformation;
this->transformationWaitTimer = 0;
}
}
void ObjTokeidai_TowerTopFall(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerTransformation_DropCounterweight(ObjTokeidai* this, GlobalContext* globalCtx) {
this->xRotation += this->transformationRotationalVelocity;
if (this->xRotation < 0x4000) {
this->transformationRotationalVelocity += this->transformationRotationalAcceleration;
return;
}
this->transformationRotationalAcceleration = 0x14;
this->xRotation = 0x4000;
switch (this->reboundCount) {
switch (this->boundCount) {
case 0:
Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_0);
break;
@@ -476,22 +509,31 @@ void ObjTokeidai_TowerTopFall(ObjTokeidai* this, GlobalContext* globalCtx) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_2);
break;
}
this->reboundCount += 1;
this->boundCount++;
if (this->transformationRotationalVelocity >= 0x191) {
// This condition is met for the first bound, causing the counterweight
// to rebound upwards quickly.
this->transformationRotationalVelocity = -0xC8;
} else if (this->transformationRotationalVelocity >= 0x33) {
// This condition is met for the second bound, causing the counterweight
// to rebound upwards slowly.
this->transformationRotationalVelocity = -(this->transformationRotationalVelocity >> 1);
} else {
this->actionFunc = ObjTokeidai_TowerTransformationWait;
this->transformationWaitTimer = 0xA;
// This condition is met for the third bound, causing the counterweight
// to stop moving.
this->actionFunc = ObjTokeidai_TowerTransformation_Wait;
this->transformationWaitTimer = 10;
}
}
void ObjTokeidai_TowerRaiseFinished(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerTransformation_FinishRaise(ObjTokeidai* this, GlobalContext* globalCtx) {
s32 type;
if (this->settleTimer > 0) {
if ((this->settleTimer & 1) != 0) {
// Jiggle the parts of the tower up and down to give it the appearance
// of "settling" into place.
if (this->settleTimer & 1) {
this->yTranslation = this->settleAmount + 3400;
} else {
this->yTranslation = 3400 - this->settleAmount;
@@ -507,14 +549,14 @@ void ObjTokeidai_TowerRaiseFinished(ObjTokeidai* this, GlobalContext* globalCtx)
Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_FALL);
}
this->yTranslation = 3400;
this->actionFunc = ObjTokeidai_TowerTopFall;
this->actionFunc = ObjTokeidai_TowerTransformation_DropCounterweight;
this->transformationRotationalVelocity = 0;
this->transformationRotationalAcceleration = 0xA;
this->reboundCount = 0;
this->boundCount = 0;
}
}
void ObjTokeidai_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerTransformation_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) {
s32 type;
if (this->yTranslation < 3400) {
@@ -531,23 +573,22 @@ void ObjTokeidai_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_STOP);
}
this->yTranslation = 3400;
this->actionFunc = ObjTokeidai_TowerRaiseFinished;
this->actionFunc = ObjTokeidai_TowerTransformation_FinishRaise;
this->settleTimer = 10;
this->settleAmount = 20;
}
}
void ObjTokeidai_TowerTransformationStart(ObjTokeidai* this, GlobalContext* globalCtx) {
if ((func_800EE29C(globalCtx, 0x84) != 0 &&
globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 4) ||
((gSaveContext.weekEventReg[8] & 0x40) != 0)) {
this->actionFunc = ObjTokeidai_RaiseTower;
void ObjTokeidai_TowerTransformation_Start(ObjTokeidai* this, GlobalContext* globalCtx) {
if ((func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 4) ||
(gSaveContext.weekEventReg[8] & 0x40)) {
this->actionFunc = ObjTokeidai_TowerTransformation_RaiseTower;
}
}
void ObjTokeidai_SetupTowerTransformationStart(ObjTokeidai* this) {
this->actionFunc = ObjTokeidai_TowerTransformationStart;
this->clockFaceAdditionalRotation = 0;
void ObjTokeidai_SetupTowerTransformation(ObjTokeidai* this) {
this->actionFunc = ObjTokeidai_TowerTransformation_Start;
this->clockFaceRotationalVelocity = 0;
this->clockFaceRotationTimer = 0;
this->yTranslation = 0;
this->xRotation = 0;
@@ -557,9 +598,8 @@ void ObjTokeidai_SetupTowerTransformationStart(ObjTokeidai* this) {
void ObjTokeidai_DoNothing(ObjTokeidai* this, GlobalContext* globalCtx) {
}
void ObjTokeidai_StaircaseIntoTowerIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
if ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || (gSaveContext.day % 5 >= 4) ||
((gSaveContext.weekEventReg[8] & 0x40) != 0)) {
void ObjTokeidai_StaircaseIntoTower_Idle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (OBJ_TOKEIDAI_IS_TRANSFORMED() || (gSaveContext.weekEventReg[8] & 0x40)) {
this->actor.draw = ObjTokeidai_Draw;
} else {
this->actor.draw = NULL;
@@ -571,21 +611,25 @@ s32 ObjTokeidai_IsPostFirstCycleFinalHours(ObjTokeidai* this, GlobalContext* glo
return false;
}
if (gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) {
ObjTokeidai_SetupTowerTransformationStart(this);
ObjTokeidai_SetupTowerTransformation(this);
return true;
}
return false;
}
void ObjTokeidai_HandleHour(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_RotateOnHourChange(ObjTokeidai* this, GlobalContext* globalCtx) {
s32 currentHour;
currentHour = OBJ_TOKEIDAI_GET_CURRENT_HOUR(this);
if (currentHour != this->clockHour) {
if (this->clockFaceRotationTimer >= 13) {
this->clockFaceAdditionalRotation += 0xA;
this->clockFaceRotation += this->clockFaceAdditionalRotation;
// This actually performs the rotation to the next hour
// for the clock face.
this->clockFaceRotationalVelocity += 0xA;
this->clockFaceRotation += this->clockFaceRotationalVelocity;
} else {
// This makes the clock face wiggle in place for a bit
// before rotating to the next position.
if ((this->clockFaceRotationTimer & 3) == 0) {
this->clockFaceRotation += 0x3C;
}
@@ -593,46 +637,51 @@ void ObjTokeidai_HandleHour(ObjTokeidai* this, GlobalContext* globalCtx) {
this->clockFaceRotation -= 0x3C;
}
}
this->clockFaceRotationTimer++;
if ((currentHour == 12 && this->clockFaceRotation < 0) ||
(currentHour != 12 && this->clockFaceRotation > OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour))) {
this->clockFaceRotation = OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour);
this->clockHour = currentHour;
this->clockFaceAdditionalRotation = 0;
this->clockFaceRotationalVelocity = 0;
this->clockFaceRotationTimer = 0;
}
}
// If the sun and moon disk doesn't have the target rotation (e.g., the time of day
// just changed), rotate it until it matches the target.
if (this->sunMoonDiskRotation != ObjTokeidai_GetTargetSunMoonDiskRotation()) {
if (this->clockHour == 6) {
this->sunMoonDiskAdditionalRotation += 0x222;
this->sunMoonDiskRotation += this->sunMoonDiskAdditionalRotation;
this->sunMoonDiskRotationalVelocity += 0x222;
this->sunMoonDiskRotation += this->sunMoonDiskRotationalVelocity;
if (this->sunMoonDiskRotation >= 0x10001) {
this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation();
this->sunMoonDiskAdditionalRotation = 0;
this->sunMoonDiskRotationalVelocity = 0;
}
}
if (this->clockHour == 18) {
this->sunMoonDiskAdditionalRotation += 0x222;
this->sunMoonDiskRotation += this->sunMoonDiskAdditionalRotation;
this->sunMoonDiskRotationalVelocity += 0x222;
this->sunMoonDiskRotation += this->sunMoonDiskRotationalVelocity;
if (this->sunMoonDiskRotation >= 0x8001) {
this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation();
this->sunMoonDiskAdditionalRotation = 0;
this->sunMoonDiskRotationalVelocity = 0;
}
}
}
}
void ObjTokeidai_TowerClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (gSaveContext.day % 5 == 3 && this->clockHour < 6 && gSaveContext.time < CLOCK_TIME(6, 0)) {
this->actor.draw = ObjTokeidai_DrawClock;
ObjTokeidai_SetupTowerTransformationStart(this);
this->actor.draw = ObjTokeidai_Clock_Draw;
ObjTokeidai_SetupTowerTransformation(this);
gSaveContext.weekEventReg[8] |= 0x40;
return;
}
if (globalCtx->csCtx.state != 0) {
this->actor.home.rot.x = 1;
this->currentTime += 3;
this->actor.draw = ObjTokeidai_DrawClock;
this->actor.draw = ObjTokeidai_Clock_Draw;
} else {
if ((globalCtx->actorCtx.unk5 & 2) == 0 &&
OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD &&
@@ -641,30 +690,31 @@ void ObjTokeidai_TowerClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
}
this->currentTime = gSaveContext.time;
if (this->actor.home.rot.x != 0) {
ObjTokeidai_InitClock(this);
ObjTokeidai_Clock_Init(this);
this->actor.home.rot.x = 0;
}
}
if (gSaveContext.day % 5 != 3 || gSaveContext.time >= CLOCK_TIME(6, 0)) {
ObjTokeidai_HandleMinute(this, true);
ObjTokeidai_RotateOnMinuteChange(this, true);
}
ObjTokeidai_HandleHour(this, globalCtx);
ObjTokeidai_RotateOnHourChange(this, globalCtx);
}
void ObjTokeidai_SmallClockIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) {
this->currentTime = gSaveContext.time;
ObjTokeidai_HandleMinute(this, true);
ObjTokeidai_HandleHour(this, globalCtx);
ObjTokeidai_RotateOnMinuteChange(this, true);
ObjTokeidai_RotateOnHourChange(this, globalCtx);
}
void ObjTokeidai_TowerGearIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_TowerGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx) {
if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) {
this->actor.draw = ObjTokeidai_DrawTowerGear;
this->actor.draw = ObjTokeidai_TowerGear_Draw;
} else {
if (globalCtx->csCtx.state != 0) {
this->actor.home.rot.x = 1;
this->currentTime += 3;
this->actor.draw = ObjTokeidai_DrawTowerGear;
this->actor.draw = ObjTokeidai_TowerGear_Draw;
} else {
if ((globalCtx->actorCtx.unk5 & 2) == 0 &&
OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD &&
@@ -677,25 +727,26 @@ void ObjTokeidai_TowerGearIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
this->actor.home.rot.x = 0;
}
}
ObjTokeidai_HandleMinute(this, false);
ObjTokeidai_RotateOnMinuteChange(this, false);
}
}
void ObjTokeidai_TowerTopIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx) {
s32 type;
if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) {
this->lightIntensity = 0;
this->spotlightIntensity = 0;
if ((this->actor.child == NULL)) {
type = OBJ_TOKEIDAI_TYPE(&this->actor);
if (type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN || type == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) {
if (type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN ||
type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) {
this->actor.child =
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HANABI, this->actor.world.pos.x,
this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0);
}
}
if (this->actor.child != NULL) {
if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD) {
if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) {
this->actor.child->home.rot.x = 0x384;
} else {
this->actor.child->home.rot.x = 0x12C;
@@ -704,11 +755,11 @@ void ObjTokeidai_TowerTopIdle(ObjTokeidai* this, GlobalContext* globalCtx) {
} else {
this->actor.shape.rot.y -= 0x40;
if (gSaveContext.isNight != 0) {
if (this->lightIntensity < 100) {
this->lightIntensity += +4;
if (this->spotlightIntensity < 100) {
this->spotlightIntensity += +4;
}
} else if (this->lightIntensity > 0) {
this->lightIntensity -= 4;
} else if (this->spotlightIntensity > 0) {
this->spotlightIntensity -= 4;
}
}
}
@@ -737,7 +788,7 @@ void ObjTokeidai_Draw(Actor* thisx, GlobalContext* globalCtx) {
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx) {
void ObjTokeidai_Clock_Draw(Actor* thisx, GlobalContext* globalCtx) {
ObjTokeidai* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx);
@@ -757,8 +808,8 @@ void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_OPA_DISP++, D_0600BEE8);
Matrix_InsertZRotation_s(-this->clockFaceRotation * 2, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_SMALL_CLOCK ||
OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_VERY_SMALL_CLOCK) {
if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_WALL_CLOCK ||
OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK) {
gSPDisplayList(POLY_OPA_DISP++, D_0600F518);
} else {
gSPDisplayList(POLY_OPA_DISP++, D_0600E818);
@@ -771,7 +822,7 @@ void ObjTokeidai_DrawClock(Actor* thisx, GlobalContext* globalCtx) {
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
void ObjTokeidai_DrawTowerTop(Actor* thisx, GlobalContext* globalCtx) {
void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
u32 gameplayFrames = globalCtx->gameplayFrames;
ObjTokeidai* this = THIS;
@@ -792,13 +843,13 @@ void ObjTokeidai_DrawTowerTop(Actor* thisx, GlobalContext* globalCtx) {
gSPDisplayList(POLY_OPA_DISP++, this->opaDList);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
func_8012C2DC(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 255, 255, 235, 180, (s32)(this->lightIntensity * 2.55f));
gDPSetPrimColor(POLY_XLU_DISP++, 0, 255, 255, 235, 180, (s32)(this->spotlightIntensity * 2.55f));
gSPDisplayList(POLY_XLU_DISP++, this->xluDList);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
void ObjTokeidai_DrawTowerGear(Actor* thisx, GlobalContext* globalCtx) {
void ObjTokeidai_TowerGear_Draw(Actor* thisx, GlobalContext* globalCtx) {
ObjTokeidai* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx);
@@ -8,18 +8,19 @@
#define OBJ_TOKEIDAI_GET_CURRENT_MINUTE(this) ((s32)(this->currentTime * (360 * 2.0f / 0x10000)) % 30)
#define OBJ_TOKEIDAI_GET_CLOCK_FACE_ROTATION(currentHour) ((s16)(currentHour * (0x10000 / 24.0f)))
#define OBJ_TOKEIDAI_GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute) ((s16)(currentMinute * (0x10000 * 12.0f / 360)))
#define OBJ_TOKEIDAI_IS_TRANSFORMED() ((gSaveContext.day % 5 == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || gSaveContext.day % 5 >= 4)
typedef enum {
/* 0 */ OBJ_TOKEIDAI_TYPE_TOWER_GEAR_CLOCK_TOWN,
/* 1 */ OBJ_TOKEIDAI_TYPE_UNUSED_WALL,
/* 2 */ OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN,
/* 3 */ OBJ_TOKEIDAI_TYPE_TOWER_TOP_CLOCK_TOWN,
/* 3 */ OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN,
/* 4 */ OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD,
/* 5 */ OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD,
/* 6 */ OBJ_TOKEIDAI_TYPE_TOWER_TOP_TERMINA_FIELD,
/* 6 */ OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD,
/* 8 */ OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD = 8,
/* 9 */ OBJ_TOKEIDAI_TYPE_SMALL_CLOCK,
/* 10 */ OBJ_TOKEIDAI_TYPE_VERY_SMALL_CLOCK,
/* 9 */ OBJ_TOKEIDAI_TYPE_WALL_CLOCK,
/* 10 */ OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK,
/* 11 */ OBJ_TOKEIDAI_TYPE_STAIRCASE_INTO_TOWER,
} ObjTokeidaiType;
@@ -32,19 +33,19 @@ typedef struct ObjTokeidai {
/* 0x144 */ Gfx* opaDList;
/* 0x148 */ Gfx* xluDList;
/* 0x14C */ s16 outerRingOrGearRotation;
/* 0x14E */ s16 outerRingOrGearAdditionalRotation;
/* 0x14E */ s16 outerRingOrGearRotationalVelocity;
/* 0x150 */ s16 outerRingOrGearRotationTimer;
/* 0x152 */ s16 clockFaceRotation;
/* 0x154 */ s16 clockFaceAdditionalRotation; // overloaded in transformation seqeuence
/* 0x156 */ s16 clockFaceRotationTimer; // overloaded in transformation seqeuence
/* 0x154 */ s16 actionVar1;
/* 0x156 */ s16 actionVar2;
/* 0x158 */ s32 sunMoonDiskRotation;
/* 0x15C */ s16 sunMoonDiskAdditionalRotation; // overloaded to also be something weird with the clock
/* 0x15C */ s16 actionVar3;
/* 0x15E */ s16 yTranslation;
/* 0x160 */ s16 xRotation;
/* 0x162 */ s16 clockFaceZTranslation; // amount the clock face recesses inwards once it transforms
/* 0x164 */ s16 reboundCount;
/* 0x164 */ s16 boundCount;
/* 0x168 */ s32 clockMinute; // only 30 minutes in an hour
/* 0x16C */ s32 clockHour; // overloaded to also be the light beam intensity
/* 0x16C */ s32 actionVar4;
/* 0x170 */ u16 currentTime;
/* 0x174 */ ObjTokeidaiActionFunc actionFunc;
} ObjTokeidai; // size = 0x178
+31 -31
View File
@@ -11669,43 +11669,43 @@
0x80AB261C:("DmChar09_Draw",),
0x80AB2790:("ObjTokeidai_GetTargetSunMoonDiskRotation",),
0x80AB27B4:("ObjTokeidai_SetupClockOrGear",),
0x80AB2834:("ObjTokeidai_InitClock",),
0x80AB28C8:("ObjTokeidai_InitTowerGear",),
0x80AB29F8:("ObjTokeidai_InitTowerClock",),
0x80AB2BBC:("ObjTokeidai_InitTowerTop",),
0x80AB2834:("ObjTokeidai_Clock_Init",),
0x80AB28C8:("ObjTokeidai_TowerGear_Init",),
0x80AB29F8:("ObjTokeidai_TowerClock_Init",),
0x80AB2BBC:("ObjTokeidai_Counterweight_Init",),
0x80AB2DEC:("ObjTokeidai_Init",),
0x80AB3000:("ObjTokeidai_Destroy",),
0x80AB3010:("ObjTokeidai_HandleMinute",),
0x80AB319C:("ObjTokeidai_CollapseGear",),
0x80AB3240:("ObjTokeidai_TransformedGearIdle",),
0x80AB32F0:("ObjTokeidai_TransformedClockFaceFall",),
0x80AB3370:("ObjTokeidai_TransformedClockFaceSlideOff",),
0x80AB34CC:("ObjTokeidai_TransformedClockIdle",),
0x80AB3544:("ObjTokeidai_CollapseTop",),
0x80AB3598:("ObjTokeidai_TransformedTopIdle",),
0x80AB363C:("ObjTokeidai_CollapseWalls",),
0x80AB365C:("ObjTokeidai_WallsIdle",),
0x80AB36C4:("ObjTokeidai_TowerTransformationEndCutscene",),
0x80AB3808:("ObjTokeidai_TowerTransformationFinish",),
0x80AB3880:("ObjTokeidai_TowerTransformationWait",),
0x80AB38B0:("ObjTokeidai_TowerTopFall",),
0x80AB39BC:("ObjTokeidai_TowerRaiseFinished",),
0x80AB3A7C:("ObjTokeidai_RaiseTower",),
0x80AB3B34:("ObjTokeidai_TowerTransformationStart",),
0x80AB3BB0:("ObjTokeidai_SetupTowerTransformationStart",),
0x80AB3010:("ObjTokeidai_RotateOnMinuteChange",),
0x80AB319C:("ObjTokeidai_TowerGear_Collapse",),
0x80AB3240:("ObjTokeidai_TowerGear_TransformedIdle",),
0x80AB32F0:("ObjTokeidai_TowerClock_Fall",),
0x80AB3370:("ObjTokeidai_TowerClock_SlideOff",),
0x80AB34CC:("ObjTokeidai_TowerClock_TransformedIdle",),
0x80AB3544:("ObjTokeidai_Counterweight_Collapse",),
0x80AB3598:("ObjTokeidai_Counterweight_TransformedIdle",),
0x80AB363C:("ObjTokeidai_Walls_Collapse",),
0x80AB365C:("ObjTokeidai_Walls_Idle",),
0x80AB36C4:("ObjTokeidai_TowerTransformation_EndCutscene",),
0x80AB3808:("ObjTokeidai_TowerTransformation_FinishTransformation",),
0x80AB3880:("ObjTokeidai_TowerTransformation_Wait",),
0x80AB38B0:("ObjTokeidai_TowerTransformation_DropCounterweight",),
0x80AB39BC:("ObjTokeidai_TowerTransformation_FinishRaise",),
0x80AB3A7C:("ObjTokeidai_TowerTransformation_RaiseTower",),
0x80AB3B34:("ObjTokeidai_TowerTransformation_Start",),
0x80AB3BB0:("ObjTokeidai_SetupTowerTransformation",),
0x80AB3BD8:("ObjTokeidai_DoNothing",),
0x80AB3BE8:("ObjTokeidai_StaircaseIntoTowerIdle",),
0x80AB3BE8:("ObjTokeidai_StaircaseIntoTower_Idle",),
0x80AB3C50:("ObjTokeidai_IsPostFirstCycleFinalHours",),
0x80AB3CCC:("ObjTokeidai_HandleHour",),
0x80AB3ED0:("ObjTokeidai_TowerClockIdle",),
0x80AB4040:("ObjTokeidai_SmallClockIdle",),
0x80AB4080:("ObjTokeidai_TowerGearIdle",),
0x80AB4160:("ObjTokeidai_TowerTopIdle",),
0x80AB3CCC:("ObjTokeidai_RotateOnHourChange",),
0x80AB3ED0:("ObjTokeidai_TowerClock_Idle",),
0x80AB4040:("ObjTokeidai_WallClock_Idle",),
0x80AB4080:("ObjTokeidai_TowerGear_Idle",),
0x80AB4160:("ObjTokeidai_Counterweight_Idle",),
0x80AB4278:("ObjTokeidai_Update",),
0x80AB429C:("ObjTokeidai_Draw",),
0x80AB4394:("ObjTokeidai_DrawClock",),
0x80AB4664:("ObjTokeidai_DrawTowerTop",),
0x80AB4894:("ObjTokeidai_DrawTowerGear",),
0x80AB4394:("ObjTokeidai_Clock_Draw",),
0x80AB4664:("ObjTokeidai_Counterweight_Draw",),
0x80AB4894:("ObjTokeidai_TowerGear_Draw",),
0x80AB4D10:("func_80AB4D10",),
0x80AB4E34:("func_80AB4E34",),
0x80AB4E58:("func_80AB4E58",),