Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/game/behaviors/bowling_ball.inc.c
7861 views
1
// bowling_ball.c.inc
2
3
static struct ObjectHitbox sBowlingBallHitbox = {
4
/* interactType: */ INTERACT_DAMAGE,
5
/* downOffset: */ 0,
6
/* damageOrCoinValue: */ 2,
7
/* health: */ 0,
8
/* numLootCoins: */ 0,
9
/* radius: */ 100,
10
/* height: */ 150,
11
/* hurtboxRadius: */ 0,
12
/* hurtboxHeight: */ 0,
13
};
14
15
static Trajectory sThiHugeMetalBallTraj[] = {
16
TRAJECTORY_POS(0, /*pos*/ -4786, 101, -2166),
17
TRAJECTORY_POS(1, /*pos*/ -5000, 81, -2753),
18
TRAJECTORY_POS(2, /*pos*/ -5040, 33, -3846),
19
TRAJECTORY_POS(3, /*pos*/ -4966, 38, -4966),
20
TRAJECTORY_POS(4, /*pos*/ -4013, -259, -4893),
21
TRAJECTORY_POS(5, /*pos*/ -2573, -1019, -4780),
22
TRAJECTORY_POS(6, /*pos*/ -1053, -1399, -4806),
23
TRAJECTORY_POS(7, /*pos*/ 760, -1637, -4833),
24
TRAJECTORY_POS(8, /*pos*/ 2866, -2047, -4886),
25
TRAJECTORY_POS(9, /*pos*/ 3386, -6546, -4833),
26
TRAJECTORY_END(),
27
};
28
29
static Trajectory sThiTinyMetalBallTraj[] = {
30
TRAJECTORY_POS(0, /*pos*/ -1476, 29, -680),
31
TRAJECTORY_POS(1, /*pos*/ -1492, 14, -1072),
32
TRAJECTORY_POS(2, /*pos*/ -1500, 3, -1331),
33
TRAJECTORY_POS(3, /*pos*/ -1374, -17, -1527),
34
TRAJECTORY_POS(4, /*pos*/ -1178, -83, -1496),
35
TRAJECTORY_POS(5, /*pos*/ -292, -424, -1425),
36
TRAJECTORY_POS(6, /*pos*/ 250, -491, -1433),
37
TRAJECTORY_POS(7, /*pos*/ 862, -613, -1449),
38
TRAJECTORY_POS(8, /*pos*/ 1058, -1960, -1449),
39
TRAJECTORY_END(),
40
};
41
42
void bhv_bowling_ball_init(void) {
43
o->oGravity = 5.5f;
44
o->oFriction = 1.0f;
45
o->oBuoyancy = 2.0f;
46
}
47
48
void bowling_ball_set_hitbox(void) {
49
obj_set_hitbox(o, &sBowlingBallHitbox);
50
51
if (o->oInteractStatus & INT_STATUS_INTERACTED)
52
o->oInteractStatus = 0;
53
}
54
55
void bowling_ball_set_waypoints(void) {
56
switch (o->oBehParams2ndByte) {
57
case BBALL_BP_STYPE_BOB_UPPER:
58
o->oPathedStartWaypoint = segmented_to_virtual(bob_seg7_metal_ball_path0);
59
break;
60
61
case BBALL_BP_STYPE_TTM:
62
o->oPathedStartWaypoint = segmented_to_virtual(ttm_seg7_trajectory_070170A0);
63
break;
64
65
case BBALL_BP_STYPE_BOB_LOWER:
66
o->oPathedStartWaypoint = segmented_to_virtual(bob_seg7_metal_ball_path1);
67
break;
68
69
case BBALL_BP_STYPE_THI_LARGE:
70
o->oPathedStartWaypoint = (struct Waypoint *) sThiHugeMetalBallTraj;
71
break;
72
73
case BBALL_BP_STYPE_THI_SMALL:
74
o->oPathedStartWaypoint = (struct Waypoint *) sThiTinyMetalBallTraj;
75
break;
76
}
77
}
78
79
void bhv_bowling_ball_roll_loop(void) {
80
s16 collisionFlags;
81
s32 sp18;
82
#ifdef AVOID_UB
83
sp18 = 0;
84
#endif
85
86
bowling_ball_set_waypoints();
87
collisionFlags = object_step();
88
89
//! Uninitialzed parameter, but the parameter is unused in the called function
90
sp18 = cur_obj_follow_path(sp18);
91
92
o->oBowlingBallTargetYaw = o->oPathedTargetYaw;
93
o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, o->oBowlingBallTargetYaw, 0x400);
94
if (o->oForwardVel > 70.0) {
95
o->oForwardVel = 70.0;
96
}
97
98
bowling_ball_set_hitbox();
99
100
if (sp18 == -1) {
101
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 7000)) {
102
spawn_mist_particles();
103
spawn_mist_particles_variable(0, 0, 92.0f);
104
}
105
106
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
107
}
108
109
if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) && (o->oVelY > 5.0f))
110
cur_obj_play_sound_2(SOUND_GENERAL_QUIET_POUND1_LOWPRIO);
111
}
112
113
void bhv_bowling_ball_initializeLoop(void) {
114
s32 sp1c;
115
#ifdef AVOID_UB
116
sp1c = 0;
117
#endif
118
119
bowling_ball_set_waypoints();
120
121
//! Uninitialzed parameter, but the parameter is unused in the called function
122
sp1c = cur_obj_follow_path(sp1c);
123
124
o->oMoveAngleYaw = o->oPathedTargetYaw;
125
126
switch (o->oBehParams2ndByte) {
127
case BBALL_BP_STYPE_BOB_UPPER:
128
o->oForwardVel = 20.0f;
129
break;
130
131
case BBALL_BP_STYPE_TTM:
132
o->oForwardVel = 10.0f;
133
break;
134
135
case BBALL_BP_STYPE_BOB_LOWER:
136
o->oForwardVel = 20.0f;
137
break;
138
139
case BBALL_BP_STYPE_THI_LARGE:
140
o->oForwardVel = 25.0f;
141
break;
142
143
case BBALL_BP_STYPE_THI_SMALL:
144
o->oForwardVel = 10.0f;
145
cur_obj_scale(0.3f);
146
o->oGraphYOffset = 39.0f;
147
break;
148
}
149
}
150
151
void bhv_bowling_ball_loop(void) {
152
switch (o->oAction) {
153
case BBALL_ACT_INITIALIZE:
154
o->oAction = BBALL_ACT_ROLL;
155
bhv_bowling_ball_initializeLoop();
156
break;
157
158
case BBALL_ACT_ROLL:
159
bhv_bowling_ball_roll_loop();
160
break;
161
}
162
163
if (o->oBehParams2ndByte != 4)
164
set_camera_shake_from_point(SHAKE_POS_BOWLING_BALL, o->oPosX, o->oPosY, o->oPosZ);
165
166
set_object_visibility(o, 4000);
167
}
168
169
void bhv_generic_bowling_ball_spawner_init(void) {
170
switch (o->oBehParams2ndByte) {
171
case BBALL_BP_STYPE_BOB_UPPER:
172
o->oBBallSpawnerMaxSpawnDist = 7000.0f;
173
o->oBBallSpawnerSpawnOdds = 2.0f;
174
break;
175
176
case BBALL_BP_STYPE_TTM:
177
o->oBBallSpawnerMaxSpawnDist = 8000.0f;
178
o->oBBallSpawnerSpawnOdds = 1.0f;
179
break;
180
181
case BBALL_BP_STYPE_BOB_LOWER:
182
o->oBBallSpawnerMaxSpawnDist = 6000.0f;
183
o->oBBallSpawnerSpawnOdds = 2.0f;
184
break;
185
}
186
}
187
188
void bhv_generic_bowling_ball_spawner_loop(void) {
189
struct Object *bowlingBall;
190
191
if (o->oTimer == 256)
192
o->oTimer = 0;
193
194
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 1000)
195
|| (o->oPosY < gMarioObject->header.gfx.pos[1]))
196
return;
197
198
if ((o->oTimer & o->oBBallSpawnerPeriodMinus1) == 0) /* Modulus */
199
{
200
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, o->oBBallSpawnerMaxSpawnDist)) {
201
if ((s32)(random_float() * o->oBBallSpawnerSpawnOdds) == 0) {
202
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
203
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
204
}
205
}
206
}
207
}
208
209
void bhv_thi_bowling_ball_spawner_loop(void) {
210
struct Object *bowlingBall;
211
212
if (o->oTimer == 256)
213
o->oTimer = 0;
214
215
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 800)
216
|| (o->oPosY < gMarioObject->header.gfx.pos[1]))
217
return;
218
219
if ((o->oTimer % 64) == 0) {
220
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 12000)) {
221
if ((s32)(random_float() * 1.5) == 0) {
222
bowlingBall = spawn_object(o, MODEL_BOWLING_BALL, bhvBowlingBall);
223
bowlingBall->oBehParams2ndByte = o->oBehParams2ndByte;
224
}
225
}
226
}
227
}
228
229
void bhv_bob_pit_bowling_ball_init(void) {
230
o->oGravity = 12.0f;
231
o->oFriction = 1.0f;
232
o->oBuoyancy = 2.0f;
233
}
234
235
void bhv_bob_pit_bowling_ball_loop(void) {
236
struct FloorGeometry *sp1c;
237
UNUSED s16 collisionFlags = object_step();
238
239
find_floor_height_and_data(o->oPosX, o->oPosY, o->oPosZ, &sp1c);
240
if ((sp1c->normalX == 0) && (sp1c->normalZ == 0))
241
o->oForwardVel = 28.0f;
242
243
bowling_ball_set_hitbox();
244
set_camera_shake_from_point(SHAKE_POS_BOWLING_BALL, o->oPosX, o->oPosY, o->oPosZ);
245
cur_obj_play_sound_1(SOUND_ENV_UNKNOWN2);
246
set_object_visibility(o, 3000);
247
}
248
249
void bhv_free_bowling_ball_init(void) {
250
o->oGravity = 5.5f;
251
o->oFriction = 1.0f;
252
o->oBuoyancy = 2.0f;
253
o->oHomeX = o->oPosX;
254
o->oHomeY = o->oPosY;
255
o->oHomeZ = o->oPosZ;
256
o->oForwardVel = 0;
257
o->oMoveAngleYaw = 0;
258
}
259
260
void bhv_free_bowling_ball_roll_loop(void) {
261
s16 collisionFlags = object_step();
262
bowling_ball_set_hitbox();
263
264
if (o->oForwardVel > 10.0f) {
265
set_camera_shake_from_point(SHAKE_POS_BOWLING_BALL, o->oPosX, o->oPosY, o->oPosZ);
266
cur_obj_play_sound_1(SOUND_ENV_UNKNOWN2);
267
}
268
269
if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) && !(collisionFlags & OBJ_COL_FLAGS_LANDED))
270
cur_obj_play_sound_2(SOUND_GENERAL_QUIET_POUND1_LOWPRIO);
271
272
if (!is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 6000)) {
273
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
274
cur_obj_become_intangible();
275
276
o->oPosX = o->oHomeX;
277
o->oPosY = o->oHomeY;
278
o->oPosZ = o->oHomeZ;
279
bhv_free_bowling_ball_init();
280
o->oAction = FREE_BBALL_ACT_RESET;
281
}
282
}
283
284
void bhv_free_bowling_ball_loop(void) {
285
o->oGravity = 5.5f;
286
287
switch (o->oAction) {
288
case FREE_BBALL_ACT_IDLE:
289
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 3000)) {
290
o->oAction = FREE_BBALL_ACT_ROLL;
291
o->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
292
cur_obj_become_tangible();
293
}
294
break;
295
296
case FREE_BBALL_ACT_ROLL:
297
bhv_free_bowling_ball_roll_loop();
298
break;
299
300
case FREE_BBALL_ACT_RESET:
301
if (is_point_within_radius_of_mario(o->oPosX, o->oPosY, o->oPosZ, 5000))
302
o->oAction = FREE_BBALL_ACT_IDLE;
303
break;
304
}
305
}
306
307