Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
hammer.c File Reference

Go to the source code of this file.

Data Structures

struct  HammerHitData
 

Enumerations

enum  { SUBSTATE_HAMMER_0 = 0 , SUBSTATE_HAMMER_1 = 1 , SUBSTATE_HAMMER_2 = 2 }
 

Functions

void action_hammer_end_swing (void)
 
s32 action_hammer_is_swinging_away (s32 animID)
 
void action_hammer_play_hit_fx (s32 hitID)
 
HitID action_hammer_test_swing_collision (void)
 
void action_update_hammer (void)
 

Variables

BSS HammerHitData D_802B6E90
 
HammerHitDataHammerHit = &D_802B6E90
 

Data Structure Documentation

◆ HammerHitData

struct HammerHitData
Data Fields
Vec3f hitPos
s32 unk_0C
s32 hitID
s32 unk_14
s32 timer
s32 unk_1C

Enumeration Type Documentation

◆ anonymous enum

Enumerator
SUBSTATE_HAMMER_0 
SUBSTATE_HAMMER_1 
SUBSTATE_HAMMER_2 

Definition at line 6 of file hammer.c.

6 {
10};
@ SUBSTATE_HAMMER_2
Definition hammer.c:9
@ SUBSTATE_HAMMER_1
Definition hammer.c:8
@ SUBSTATE_HAMMER_0
Definition hammer.c:7

Function Documentation

◆ action_hammer_end_swing()

void action_hammer_end_swing ( void )

Definition at line 287 of file hammer.c.

287 {
290 f32 yaw;
291 f32 angle;
295 f32 x, y, z;
296 s32 result;
297 s32 hammerLevel;
298 s32 soundID;
299 s32 ten;
300 s32 i;
301
302 yaw = player_get_side_angle();
303 if (action_hammer_is_swinging_away(playerStatus->trueAnimation)) {
304 angle = clamp_angle(yaw + 90.0f - gCameras[gCurrentCameraID].curYaw);
305 if (angle >= 90.0f && angle < 270.0f) {
306 yaw += -30.0f;
307 } else {
308 yaw += 30.0f;
309 }
310 }
311
313 playerX = playerStatus->pos.x;
314 playerY = playerStatus->pos.y;
315 playerZ = playerStatus->pos.z;
316
317 // check collision along 16 points in a line away from the player
318 for (i = 1; i < 16; i++) {
319 x = playerX + (outSinTheta * i);
320 y = playerY;
321 z = playerZ - (outCosTheta * i);
322 result = player_test_lateral_overlap(PLAYER_COLLISION_HAMMER, playerStatus, &x, &y, &z, 4.0f, yaw);
323 if (HammerHit->unk_14 == 0) {
324 collisionStatus->lastWallHammered = result;
325 if (result > NO_COLLIDER) {
326 if (result & COLLISION_WITH_ENTITY_BIT) {
328 }
329 }
330 }
331
332 if (result > NO_COLLIDER) {
333 break;
334 }
335 }
336
337 if (i >= 16) {
338 yaw = player_get_side_angle();
339 if (action_hammer_is_swinging_away(playerStatus->trueAnimation) == 0) {
340 angle = clamp_angle(yaw + 90.0f - gCameras[gCurrentCameraID].curYaw);
341 if (angle >= 90.0f && angle < 270.0f) {
342 yaw += 15.0f;
343 } else {
344 yaw += -15.0f;
345 }
346 }
348
349 // check collision along 16 points in a line away from the player
350 for (i = 1; i < 16; i++) {
351 x = playerX + (outSinTheta * i);
352 y = playerY;
353 z = playerZ - (outCosTheta * i);
354 result = player_test_lateral_overlap(PLAYER_COLLISION_HAMMER, playerStatus, &x, &y, &z, 4.0f, yaw);
355 if (HammerHit->unk_14 == 0) {
356 collisionStatus->lastWallHammered = result;
357 if (result > NO_COLLIDER) {
358 if (result & COLLISION_WITH_ENTITY_BIT) {
360 }
361 }
362 }
363
364 if (result > NO_COLLIDER) {
365 break;
366 }
367 }
368 }
369
370 if (HammerHit->timer == 2) {
371 hammerLevel = gPlayerData.hammerLevel;
372 if (hammerLevel == 2) {
373 soundID = SOUND_HAMMER_SWING_3;
374 } else if (hammerLevel == 1) {
375 soundID = SOUND_HAMMER_SWING_2;
376 } else {
377 soundID = SOUND_HAMMER_SWING_1;
378 }
380
382
383 if (collisionStatus->lastWallHammered > NO_COLLIDER && (collisionStatus->lastWallHammered & COLLISION_WITH_ENTITY_BIT)) {
384 get_entity_by_index(collisionStatus->lastWallHammered)->collisionTimer = 0;
386 } else if (HammerHit->hitID <= NO_COLLIDER) {
388 }
389
393 }
394 }
395
396 if (playerStatus->actionSubstate == SUBSTATE_HAMMER_0 && result > NO_COLLIDER && HammerHit->unk_14 == 0) {
397 playerStatus->actionSubstate++;
398 }
399 if (playerStatus->actionSubstate == SUBSTATE_HAMMER_1 && result <= NO_COLLIDER) {
400 playerStatus->actionSubstate = SUBSTATE_HAMMER_2;
401 }
402 HammerHit->timer++;
403 if (result > NO_COLLIDER) {
404 HammerHit->unk_14 = 1;
405 }
406 if (HammerHit->timer == 6) {
408 }
409
410 if (playerStatus->animNotifyValue == 1) {
411 if (HammerHit->timer >= 7 && (playerStatus->pressedButtons & BUTTON_B)) {
412 HammerHit->unk_1C = 1;
413 }
414
415 HammerHit->unk_14 = 0;
416 ten = 10; // required to match
417 if (HammerHit->unk_1C != 0 || HammerHit->timer > ten) {
420 }
422 }
423}
BSS s32 PopupMenu_SelectedIndex
#define clamp_angle
@ BUTTON_B
Definition enums.h:2775
@ PS_FLAG_HAMMER_CHECK
Definition enums.h:3107
@ PLAYER_COLLISION_HAMMER
Definition enums.h:4300
@ SOUND_HAMMER_SWING_3
Definition enums.h:1559
@ SOUND_HAMMER_SWING_1
Definition enums.h:1557
@ SOUND_HAMMER_SWING_2
Definition enums.h:1558
@ ACTION_STATE_IDLE
Definition enums.h:2412
@ SOUND_SPACE_DEFAULT
Definition enums.h:1740
Entity * get_entity_by_index(s32 index)
Definition entity.c:530
f32 player_get_side_angle(void)
Definition 7BB60.c:1178
s32 player_test_lateral_overlap(s32, PlayerStatus *, f32 *, f32 *, f32 *, f32, f32)
Definition 77480.c:369
void set_action_state(s32 actionState)
Definition 7E9D0.c:209
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
Definition 43F0.c:706
void sfx_play_sound_at_player(s32 soundID, s32 arg1)
#define COLLISION_WITH_ENTITY_BIT
Definition macros.h:163
#define DEG_TO_RAD(deg)
Definition macros.h:145
#define NO_COLLIDER
Definition macros.h:167
s8 collisionTimer
CollisionStatus gCollisionStatus
Definition 7BB60.c:5
Camera gCameras[4]
Definition cam_main.c:16
PlayerData gPlayerData
Definition 77480.c:39
PlayerStatus gPlayerStatus
Definition 77480.c:38
s32 gCurrentCameraID
Definition cam_math.c:5
HiddenPanelsData gCurrentHiddenPanels
Definition entity.c:36
s32 action_hammer_is_swinging_away(s32 animID)
Definition hammer.c:27
void action_hammer_play_hit_fx(s32 hitID)
Definition hammer.c:45
HammerHitData * HammerHit
Definition hammer.c:23

Referenced by action_update_hammer().

◆ action_hammer_is_swinging_away()

s32 action_hammer_is_swinging_away ( s32 animID)

Definition at line 27 of file hammer.c.

27 {
28 if (animID & SPRITE_ID_BACK_FACING) {
29 return true;
30 }
31
32 // back facing swing anims
33 switch (animID) {
40 return true;
41 }
42 return false;
43}
@ SPRITE_ID_BACK_FACING
Definition sprite.h:17

Referenced by action_hammer_end_swing(), and action_hammer_test_swing_collision().

◆ action_hammer_play_hit_fx()

void action_hammer_play_hit_fx ( s32 hitID)

Definition at line 45 of file hammer.c.

45 {
48 s32 time;
49 s32 radius;
50 s32 soundID;
53 f32 x, y, z;
54
55 if (gPlayerData.hammerLevel == 2) {
56 shakeAmt = 1.2f;
57 time = 1;
58 radius = 28;
59 soundID = SOUND_HAMMER_STRIKE_3;
60 } else if (gPlayerData.hammerLevel == 1) {
61 shakeAmt = 0.8f;
62 time = 1;
63 radius = 16;
64 soundID = SOUND_HAMMER_STRIKE_2;
65 } else {
66 shakeAmt = 0.4f;
67 time = 1;
68 radius = 4;
69 soundID = SOUND_HAMMER_STRIKE_1;
70 }
71
73 sinTheta = sin_rad(theta) * 25.0f;
74 cosTheta = cos_rad(theta) * -25.0f;
75
76 if (hitID <= NO_COLLIDER) {
77 numParticles = 6;
78 x = playerStatus->pos.x + sinTheta;
79 y = playerStatus->pos.y;
80 z = playerStatus->pos.z + cosTheta;
81 } else {
82 numParticles = 3;
84 y = HammerHit->hitPos.y + playerStatus->colliderHeight - 5.0f;
86 radius = 1;
87 }
88
90 fx_smoke_impact(0, x, y, z, radius, numParticles, 0, (time + 3) * 3);
91
93 case 1:
95 break;
96 case 2:
97 soundID = SOUND_PLANTS_BELL;
98 break;
99 case 3:
100 soundID = SOUND_SLIDE_WHISTLE_OUT;
101 break;
102 case 4:
103 soundID = SOUND_YOSHI;
104 break;
105 case 5:
106 soundID = SOUND_HIT_WHACKA;
107 break;
108 case 6:
109 soundID = SOUND_FLOWERS_LAUGH;
110 break;
111 }
112
114 start_rumble(256, 50);
115}
@ CAM_SHAKE_DECAYING_VERTICAL
Definition enums.h:1835
@ ABILITY_ATTACK_FX
Definition enums.h:451
@ SOUND_HAMMER_STRIKE_3
Definition enums.h:1562
@ SOUND_FLOWERS_LAUGH
Definition enums.h:1392
@ SOUND_HAMMER_STRIKE_1
Definition enums.h:1560
@ SOUND_SLIDE_WHISTLE_OUT
Definition enums.h:718
@ SOUND_HIT_WHACKA
Definition enums.h:1415
@ SOUND_PLANTS_BELL
Definition enums.h:730
@ SOUND_HAMMER_STRIKE_2
Definition enums.h:1561
@ SOUND_LIFE_SHROOM_CHIME
Definition enums.h:1189
@ SOUND_YOSHI
Definition enums.h:1414
@ CAM_DEFAULT
Definition enums.h:1826
void start_rumble(s32, s32)
Definition rumble.c:15
s32 is_ability_active(s32 arg0)
Definition inventory.c:1735
f32 cos_rad(f32 x)
Definition 43F0.c:717
void exec_ShakeCamX(s32 arg0, s32 arg1, s32 arg2, f32 arg3)
Definition cam_api.c:374
f32 sin_rad(f32 x)
Definition 43F0.c:713
Vec3f hitPos
Definition hammer.c:13

Referenced by action_hammer_end_swing().

◆ action_hammer_test_swing_collision()

HitID action_hammer_test_swing_collision ( void )

Definition at line 117 of file hammer.c.

117 {
119 HitID ret;
120 f32 yaw;
121 f32 angle;
125 f32 x, y, z;
126 s32 i;
127
128 // first attempt
129 yaw = player_get_side_angle();
130 if (action_hammer_is_swinging_away(playerStatus->trueAnimation)) {
131 angle = clamp_angle(yaw + 90.0f - gCameras[gCurrentCameraID].curYaw);
132 if (angle >= 90.0f && angle < 270.0f) {
133 yaw += -30.0f;
134 } else {
135 yaw += 30.0f;
136 }
137 }
138
140 playerX = playerStatus->pos.x;
141 playerY = playerStatus->pos.y;
142 playerZ = playerStatus->pos.z;
143
144 // check collision along 16 points in a line away from the player
145 for (i = 1; i < 16; i++) {
146 x = playerX + (outSinTheta * i);
147 y = playerY;
148 z = playerZ - (outCosTheta * i);
150 if (ret > NO_COLLIDER) {
151 HammerHit->hitPos.x = x;
152 HammerHit->hitPos.y = y;
153 HammerHit->hitPos.z = z;
154 break;
155 }
156 }
157
158 // second attempt
159 if (i >= 16) {
160 yaw = player_get_side_angle();
161 if (!action_hammer_is_swinging_away(playerStatus->trueAnimation)) {
162 angle = clamp_angle(yaw + 90.0f - gCameras[gCurrentCameraID].curYaw);
163 if (angle >= 90.0f && angle < 270.0f) {
164 yaw += 15.0f;
165 } else {
166 yaw += -15.0f;
167 }
168 }
169
170 // check collision along 16 points in a line away from the player
172 for (i = 1; i < 16; i++) {
173 x = playerX + (outSinTheta * i);
174 y = playerY;
175 z = playerZ - (outCosTheta * i);
176
178 if (ret > NO_COLLIDER) {
179 HammerHit->hitPos.x = x;
180 HammerHit->hitPos.y = y;
181 HammerHit->hitPos.z = z;
182 break;
183 }
184 }
185 }
186
188 s32 hammerLevel = gPlayerData.hammerLevel;
189
190 switch (get_entity_type(ret)) {
193 if (hammerLevel >= 0) {
194 ret = -1;
195 } else {
196 playerStatus->animFlags |= PA_FLAG_SHIVERING;
197 }
198 break;
201 if (hammerLevel >= 1) {
202 ret = -1;
203 } else {
204 playerStatus->animFlags |= PA_FLAG_SHIVERING;
205 }
206 break;
209 if (hammerLevel >= 2) {
210 ret = -1;
211 } else {
212 playerStatus->animFlags |= PA_FLAG_SHIVERING;
213 }
214 break;
217 playerStatus->animFlags |= PA_FLAG_SHIVERING;
218 break;
222 ret = -1;
223 break;
224 }
225 }
226
227 return ret;
228}
s32 HitID
@ ENTITY_TYPE_HAMMER1_BLOCK
Definition enums.h:2550
@ ENTITY_TYPE_BOMBABLE_ROCK
Definition enums.h:2567
@ ENTITY_TYPE_HAMMER3_BLOCK
Definition enums.h:2552
@ ENTITY_TYPE_BLUE_SWITCH
Definition enums.h:2536
@ ENTITY_TYPE_HAMMER2_BLOCK
Definition enums.h:2551
@ ENTITY_TYPE_HAMMER3_BLOCK_TINY
Definition enums.h:2555
@ ENTITY_TYPE_RED_SWITCH
Definition enums.h:2537
@ ENTITY_TYPE_BRICK_BLOCK
Definition enums.h:2542
@ ENTITY_TYPE_HAMMER2_BLOCK_TINY
Definition enums.h:2554
@ ENTITY_TYPE_HAMMER1_BLOCK_TINY
Definition enums.h:2553
@ ENTITY_TYPE_WOODEN_CRATE
Definition enums.h:2565
@ PA_FLAG_SHIVERING
Definition enums.h:3135
u32 get_entity_type(s32 arg0)
Definition entity.c:568

Referenced by action_update_hammer().

◆ action_update_hammer()

void action_update_hammer ( void )

Definition at line 230 of file hammer.c.

230 {
232
233 HammerHit->unk_1C = 0;
234
236 AnimID anim;
237 s32 soundID;
238
241 HammerHit->timer = 0;
242 playerStatus->actionSubstate = SUBSTATE_HAMMER_0;
243 playerStatus->curSpeed = 0.0f;
244 playerStatus->animNotifyValue = 0;
246
247 if (gPlayerData.hammerLevel == 2) {
248 soundID = SOUND_HAMMER_SWING_3;
250 if (HammerHit->hitID <= NO_COLLIDER) {
251 soundID = SOUND_HAMMER_SWING_3;
253 }
254 } else if (gPlayerData.hammerLevel == 1) {
255 soundID = SOUND_HAMMER_SWING_2;
257 if (HammerHit->hitID <= NO_COLLIDER) {
258 soundID = SOUND_HAMMER_SWING_2;
260 }
261 } else {
262 soundID = SOUND_HAMMER_SWING_1;
264 if (HammerHit->hitID <= NO_COLLIDER) {
265 soundID = SOUND_HAMMER_SWING_1;
267 }
268 }
269
272 HammerHit->unk_0C = 0;
273 HammerHit->unk_14 = 0;
274 }
275
277 if (HammerHit->timer < 3 && (playerStatus->flags & PS_FLAG_ENTERING_BATTLE)) {
278 // This is probably to stop Mario from triggering multiple battles at once by hammering while one is starting.
280 } else if (HammerHit->timer < 2) {
281 HammerHit->timer++;
282 } else {
284 }
285}
u32 AnimID
@ PS_FLAG_TIME_STOPPED
Definition enums.h:3115
@ PS_FLAG_ENTERING_BATTLE
Definition enums.h:3095
@ PS_FLAG_ACTION_STATE_CHANGED
Definition enums.h:3118
@ PS_FLAG_NO_FLIPPING
Definition enums.h:3101
void suggest_player_anim_allow_backward(AnimID anim)
Definition 77480.c:893
void action_hammer_end_swing(void)
Definition hammer.c:287
HitID action_hammer_test_swing_collision(void)
Definition hammer.c:117

Variable Documentation

◆ D_802B6E90

BSS HammerHitData D_802B6E90

Definition at line 21 of file hammer.c.

◆ HammerHit