Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/behaviors/arrow_lift.inc.c
7861 views
1
/**
2
* Behavior for WDW arrow lifts.
3
* When a player stands on an arrow lift, it starts moving between
4
* two positions 384 units apart.
5
* Arrow lifts move either along the X axis or the Z axis.
6
* Their facing angle is always perpendicular to the axis they move on.
7
* The angle the arrow lifts move initially is 90º clockwise of the face angle.
8
* This means an arrow lift at (0, 0, 0) with face angle 0 (positive Z) will
9
* move between (0, 0, 0) and (-384, 0, 0).
10
*/
11
12
/**
13
* Move the arrow lift away from its original position.
14
*/
15
static s32 arrow_lift_move_away(void) {
16
s8 status = ARROW_LIFT_NOT_DONE_MOVING;
17
18
o->oMoveAngleYaw = o->oFaceAngleYaw - 0x4000;
19
o->oVelY = 0;
20
o->oForwardVel = 12;
21
// Cumulative displacement is used to keep track of how far the platform
22
// has travelled, so that it can stop.
23
o->oArrowLiftDisplacement += o->oForwardVel;
24
25
// Stop the platform after moving 384 units.
26
if (o->oArrowLiftDisplacement > 384) {
27
o->oForwardVel = 0;
28
o->oArrowLiftDisplacement = 384;
29
status = ARROW_LIFT_DONE_MOVING;
30
}
31
32
obj_move_xyz_using_fvel_and_yaw(o);
33
return status;
34
}
35
36
/**
37
* Move the arrow lift back to its original position.
38
*/
39
static s8 arrow_lift_move_back(void) {
40
s8 status = ARROW_LIFT_NOT_DONE_MOVING;
41
42
o->oMoveAngleYaw = o->oFaceAngleYaw + 0x4000;
43
o->oVelY = 0;
44
o->oForwardVel = 12;
45
o->oArrowLiftDisplacement -= o->oForwardVel;
46
47
// Stop the platform after returning back to its original position.
48
if (o->oArrowLiftDisplacement < 0) {
49
o->oForwardVel = 0;
50
o->oArrowLiftDisplacement = 0;
51
status = ARROW_LIFT_DONE_MOVING;
52
}
53
54
obj_move_xyz_using_fvel_and_yaw(o);
55
return status;
56
}
57
58
/**
59
* Arrow lift update function.
60
*/
61
void bhv_arrow_lift_loop(void) {
62
switch (o->oAction) {
63
case ARROW_LIFT_ACT_IDLE:
64
// Wait 61 frames before moving.
65
if (o->oTimer > 60) {
66
if (gMarioObject->platform == o) {
67
o->oAction = ARROW_LIFT_ACT_MOVING_AWAY;
68
}
69
}
70
71
break;
72
73
case ARROW_LIFT_ACT_MOVING_AWAY:
74
if (arrow_lift_move_away() == ARROW_LIFT_DONE_MOVING) {
75
o->oAction = ARROW_LIFT_ACT_MOVING_BACK;
76
}
77
78
break;
79
80
case ARROW_LIFT_ACT_MOVING_BACK:
81
// Wait 61 frames before moving (after stopping after moving forwards).
82
if (o->oTimer > 60) {
83
if (arrow_lift_move_back() == ARROW_LIFT_DONE_MOVING) {
84
o->oAction = ARROW_LIFT_ACT_IDLE;
85
}
86
}
87
88
break;
89
}
90
}
91
92