Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
MeleeHitbox.inc.c
Go to the documentation of this file.
1#ifndef _AI_MELEE_HITBOX_INC_
2#define _AI_MELEE_HITBOX_INC_ 0
3
4#include "common.h"
5#include "effects.h"
6
7void N(MeleeHitbox_30)(Evt* script) {
8 Enemy* enemy = script->owner1.enemy;
9 Npc* npc = get_npc_unsafe(enemy->npcID);
10
11 enemy->AI_VAR_ATTACK_STATE = MELEE_HITBOX_STATE_INIT;
12 // if flipping, wait for it to finish
13 if (npc->turnAroundYawAdjustment == 0) {
14 enemy->AI_VAR_ATTACK_STATE = MELEE_HITBOX_STATE_PRE;
15 npc->duration = enemy->AI_VAR_MELEE_PRE_TIME;
17 script->AI_TEMP_STATE = AI_STATE_MELEE_HITBOX_PRE;
18 }
19}
20
21void N(MeleeHitbox_31)(Evt* script) {
22 Enemy* enemy = script->owner1.enemy;
23 Npc* npc = get_npc_unsafe(enemy->npcID);
24
25 npc->duration--;
26 if (npc->duration <= 0) {
27 enemy->AI_VAR_ATTACK_STATE = MELEE_HITBOX_STATE_ACTIVE;
28 npc->duration = enemy->AI_VAR_MELEE_HIT_TIME;
30 script->AI_TEMP_STATE = AI_STATE_MELEE_HITBOX_ACTIVE;
31 }
32}
33
34void N(MeleeHitbox_32)(Evt* script) {
35 Enemy* enemy = script->owner1.enemy;
36 Npc* npc = get_npc_unsafe(enemy->npcID);
37 EffectInstance* emoteTemp;
38
39 npc->duration--;
40 if (npc->duration <= 0) {
41 enemy->AI_VAR_ATTACK_STATE = MELEE_HITBOX_STATE_POST;
43 npc->duration = enemy->AI_VAR_MELEE_MISS_TIME;
44 if (enemy->AI_VAR_MELEE_MISS_TIME >= 8) {
45 fx_emote(EMOTE_FRUSTRATION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, -20.0f, enemy->AI_VAR_MELEE_MISS_TIME - 1, &emoteTemp);
46 }
47 script->AI_TEMP_STATE = AI_STATE_MELEE_HITBOX_MISS;
48 }
49}
50
51void N(MeleeHitbox_33)(Evt* script) {
52 Enemy* enemy = script->owner1.enemy;
53 Npc* npc = get_npc_unsafe(enemy->npcID);
54
55 npc->duration--;
56 if (npc->duration <= 0) {
57 enemy->AI_VAR_ATTACK_STATE = MELEE_HITBOX_STATE_NONE;
58 script->AI_TEMP_STATE = AI_STATE_CHASE_INIT;
59 }
60}
61
63 Enemy* enemy = script->owner1.enemy;
64 Npc* npc = get_npc_unsafe(enemy->npcID);
65 Camera* camera = &gCameras[gCurrentCamID];
66 Enemy* hitboxEnemy = get_enemy(enemy->npcID + 1);
67 f32 angle;
68 s32 ret = TRUE;
69
70 if (dist2D(npc->pos.x, npc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z) > hitboxEnemy->AI_VAR_HITNPC_2) {
71 ret = FALSE;
72 }
73
74 if (clamp_angle(get_clamped_angle_diff(camera->curYaw, npc->yaw)) < 180.0) {
75 angle = 90.0f;
76 } else {
77 angle = 270.0f;
78 }
79
81 gPlayerStatusPtr->pos.z))) > hitboxEnemy->AI_VAR_HITNPC_3) {
82 ret = FALSE;
83 }
84
85 if ((2.0 * npc->collisionHeight) <= fabsf(npc->pos.y - gPlayerStatusPtr->pos.y)) {
86 ret = FALSE;
87 }
88
90 ret = FALSE;
91 }
92
94 ret = FALSE;
95 }
96
97 return ret;
98}
99
100API_CALLABLE(N(MeleeHitbox_Main)) {
101 Enemy* hitboxEnemy = script->owner1.enemy;
102 Npc* hitboxNpc = get_npc_unsafe(hitboxEnemy->npcID);
103 Enemy* baseEnemy;
104 Npc* baseNpc;
105 f32 posX, posZ;
106
107 if (isInitialCall || (hitboxEnemy->aiFlags & AI_FLAG_SUSPEND)) {
108 script->functionTemp[0] = 0;
109 hitboxNpc->duration = 0;
112 hitboxNpc->pos.x = NPC_DISPOSE_POS_X;
113 hitboxNpc->pos.y = NPC_DISPOSE_POS_Y;
114 hitboxNpc->pos.z = NPC_DISPOSE_POS_Z;
115 if (hitboxEnemy->aiFlags & AI_FLAG_SUSPEND) {
116 hitboxEnemy->aiFlags &= ~AI_FLAG_SUSPEND;
117 }
118 }
119
120 switch (script->AI_TEMP_STATE) {
121 case 0:
122 baseEnemy = get_enemy(hitboxEnemy->npcID - 1);
123 baseNpc = get_npc_unsafe(baseEnemy->npcID);
124 hitboxEnemy->hitboxIsActive = TRUE;
125 if (baseEnemy->AI_VAR_ATTACK_STATE == MELEE_HITBOX_STATE_ACTIVE) {
126 if (hitboxEnemy->AI_VAR_HITNPC_SOUND != 0) {
127 ai_enemy_play_sound(baseNpc, hitboxEnemy->AI_VAR_HITNPC_SOUND, 0);
128 }
129 posX = baseNpc->pos.x;
130 posZ = baseNpc->pos.z;
131 add_vec2D_polar(&posX, &posZ, hitboxEnemy->AI_VAR_HITNPC_DIST, 270.0f - baseNpc->renderYaw);
132
133 hitboxNpc->pos.x = posX;
134 hitboxEnemy->unk_10.x = hitboxNpc->pos.x;
135
136 hitboxNpc->pos.y = baseNpc->pos.y + hitboxEnemy->AI_VAR_HITNPC_YOFFSET;
137 hitboxEnemy->unk_10.y = hitboxNpc->pos.y;
138
139 hitboxNpc->pos.z = posZ;
140 hitboxEnemy->unk_10.z = hitboxNpc->pos.z;
141
142 hitboxNpc->yaw = atan2(hitboxNpc->pos.x, hitboxNpc->pos.z, gPlayerStatusPtr->pos.x, gPlayerStatusPtr->pos.z);
144 hitboxNpc->duration = 0;
145 script->functionTemp[0] = 1;
146 }
147 break;
148 case 1:
149 baseEnemy = get_enemy(hitboxEnemy->npcID - 1);
150 get_npc_unsafe(baseEnemy->npcID);
151 hitboxNpc->duration++;
152 if (hitboxNpc->duration >= hitboxEnemy->AI_VAR_HITNPC_4) {
153 hitboxEnemy->hitboxIsActive = FALSE;
154 }
155 if (baseEnemy->AI_VAR_ATTACK_STATE == MELEE_HITBOX_STATE_POST) {
157 hitboxNpc->pos.x = NPC_DISPOSE_POS_X;
158 hitboxNpc->pos.y = NPC_DISPOSE_POS_Y;
159 hitboxNpc->pos.z = NPC_DISPOSE_POS_Z;
160 hitboxEnemy->hitboxIsActive = TRUE;
161 script->functionTemp[0] = 0;
162 }
163 break;
164 }
165
166 return ApiStatus_BLOCK;
167}
168
169#endif
void N MeleeHitbox_31(Evt *script)
void N MeleeHitbox_32(Evt *script)
s32 N MeleeHitbox_CanSeePlayer(Evt *script)
void N MeleeHitbox_33(Evt *script)
void N MeleeHitbox_30(Evt *script)
#define clamp_angle
#define atan2
@ EMOTE_FRUSTRATION
Definition enums.h:498
@ ENEMY_ANIM_INDEX_MELEE_PRE
Definition enums.h:3434
@ ENEMY_ANIM_INDEX_IDLE
Definition enums.h:3426
@ ENEMY_ANIM_INDEX_MELEE_HIT
Definition enums.h:3435
@ AI_FLAG_SUSPEND
Definition enums.h:4571
@ AI_STATE_MELEE_HITBOX_ACTIVE
Definition enums.h:4602
@ AI_STATE_CHASE_INIT
Definition enums.h:4592
@ AI_STATE_MELEE_HITBOX_MISS
Definition enums.h:4603
@ AI_STATE_MELEE_HITBOX_PRE
Definition enums.h:4601
@ ENEMY_FLAG_IGNORE_HAMMER
Definition enums.h:4547
@ ENEMY_FLAG_IGNORE_PARTNER
Definition enums.h:4549
@ ENEMY_FLAG_SKIP_BATTLE
Definition enums.h:4541
@ ENEMY_FLAG_IGNORE_TOUCH
Definition enums.h:4545
@ ENEMY_FLAG_CANT_INTERACT
Definition enums.h:4548
@ ENEMY_FLAG_IGNORE_JUMP
Definition enums.h:4546
@ ENEMY_FLAG_ACTIVE_WHILE_OFFSCREEN
Definition enums.h:4542
@ MELEE_HITBOX_STATE_PRE
Definition enums.h:4645
@ MELEE_HITBOX_STATE_INIT
Definition enums.h:4644
@ MELEE_HITBOX_STATE_ACTIVE
Definition enums.h:4646
@ MELEE_HITBOX_STATE_NONE
Definition enums.h:4643
@ MELEE_HITBOX_STATE_POST
Definition enums.h:4647
@ PARTNER_BOW
Definition enums.h:2894
@ PARTNER_SUSHIE
Definition enums.h:2892
@ NPC_FLAG_IGNORE_PLAYER_COLLISION
Definition enums.h:3006
@ NPC_FLAG_INVISIBLE
Definition enums.h:2999
#define ApiStatus_BLOCK
Definition evt.h:116
f32 fabsf(f32 f)
void ai_enemy_play_sound(Npc *npc, s32 arg1, s32 arg2)
Definition 23680.c:543
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
void add_vec2D_polar(f32 *x, f32 *y, f32 r, f32 theta)
Definition 43F0.c:685
f32 get_clamped_angle_diff(f32, f32)
Definition 43F0.c:606
s32 flags
Definition npc.h:295
s16 npcID
Definition npc.h:300
Enemy * get_enemy(s32 npcID)
Looks for an enemy matching the specified npcID.
Definition npc.c:2540
s32 * animList
Definition npc.h:341
Npc * get_npc_unsafe(s32 npcID)
Definition npc.c:995
Vec3s unk_10
Definition npc.h:302
s8 hitboxIsActive
Definition npc.h:299
u32 aiFlags
Definition npc.h:332
Definition npc.h:294
#define NPC_DISPOSE_POS_Z
Definition macros.h:161
#define NPC_DISPOSE_POS_X
Definition macros.h:159
#define NPC_DISPOSE_POS_Y
Definition macros.h:160
s32 flags
f32 renderYaw
AnimID curAnim
s16 collisionHeight
s16 turnAroundYawAdjustment
Vec3f pos
s16 duration
PlayerStatus * gPlayerStatusPtr
PartnerStatus gPartnerStatus
Definition partners.c:42
Camera gCameras[4]
Definition cam_main.c:17
s16 gCurrentCamID
Definition cam_main.c:13