Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
power_shock.c
Go to the documentation of this file.
1#include "common.h"
2#include "battle/action_cmd.h"
3
4#define NAMESPACE action_command_power_shock
5
6s32 D_802A9AA0_42D9B0[] = { 0, 25, 50, 75, 75, 0, 0, 0};
7
9
10extern s32 actionCmdTablePowerShock[];
11
12API_CALLABLE(N(init)) {
13 ActionCommandStatus* actionCommandStatus = &gActionCommandStatus;
14 BattleStatus* battleStatus = &gBattleStatus;
15 s32 id;
16 s32 temp_v1;
17
18 battleStatus->unk_82 = 100;
20
22 battleStatus->actionSuccess = 0;
23 return ApiStatus_DONE2;
24 }
25
27 actionCommandStatus->actionCommandID = ACTION_COMMAND_POWER_SHOCK;
28 actionCommandStatus->state = 0;
29 actionCommandStatus->wrongButtonPressed = FALSE;
30 actionCommandStatus->barFillLevel = 0;
31 actionCommandStatus->barFillWidth = 0;
32 actionCommandStatus->thresholdLevel = rand_int(100);
33 actionCommandStatus->hudPrepareTime = 30;
34 actionCommandStatus->hudPosX = -48;
35 actionCommandStatus->isBarFilled = FALSE;
36 actionCommandStatus->thresholdMoveDir = 0;
37 D_802A9B00 = FALSE;
38 actionCommandStatus->hudPosY = 80;
39
41 actionCommandStatus->hudElements[0] = id;
43 hud_element_set_render_pos(id, actionCommandStatus->hudPosX, actionCommandStatus->hudPosY);
45
47 actionCommandStatus->hudElements[1] = id;
48 hud_element_set_render_pos(id, actionCommandStatus->hudPosX, actionCommandStatus->hudPosY + 28);
51
53 actionCommandStatus->hudElements[3] = id;
54 hud_element_set_render_pos(id, actionCommandStatus->hudPosX, actionCommandStatus->hudPosY + 28);
57
59 actionCommandStatus->hudElements[4] = id;
60 hud_element_set_render_pos(id, actionCommandStatus->hudPosX, actionCommandStatus->hudPosY + 28);
63
64 temp_v1 = (100 - actionCommandStatus->thresholdLevel) * 60;
65 temp_v1 /= 100;
66 temp_v1 = 29 - temp_v1;
67 hud_element_set_render_pos(actionCommandStatus->hudElements[3], actionCommandStatus->hudPosX - temp_v1, actionCommandStatus->hudPosY + 17);
68 return ApiStatus_DONE2;
69}
70
71API_CALLABLE(N(start)) {
72 ActionCommandStatus* actionCommandStatus = &gActionCommandStatus;
73 BattleStatus* battleStatus = &gBattleStatus;
74 Bytecode* args = script->ptrReadPos;
75
77 battleStatus->actionSuccess = 0;
78 return ApiStatus_DONE2;
79 }
80
82 actionCommandStatus->prepareTime = evt_get_variable(script, *args++);
83 actionCommandStatus->duration = evt_get_variable(script, *args++);
84 actionCommandStatus->difficulty = evt_get_variable(script, *args++);
85 actionCommandStatus->difficulty = adjust_action_command_difficulty(actionCommandStatus->difficulty);
86 actionCommandStatus->targetWeakness = evt_get_variable(script, *args++);
87 actionCommandStatus->wrongButtonPressed = FALSE;
88 actionCommandStatus->barFillLevel = 0;
89 actionCommandStatus->barFillWidth = 0;
90 battleStatus->actionSuccess = 0;
91 battleStatus->actionResult = ACTION_RESULT_FAIL;
92 actionCommandStatus->state = 10;
93 battleStatus->flags1 &= ~BS_FLAGS1_FREE_ACTION_COMMAND;
95 return ApiStatus_DONE2;
96}
97
98void N(update)(void) {
99 ActionCommandStatus* actionCommandStatus = &gActionCommandStatus;
100 BattleStatus* battleStatus = &gBattleStatus;
101 s32 id;
102 s32 phi_a1;
103 s32 cutoff;
104 s32 new_var;
105
106 switch (actionCommandStatus->state) {
107 case 0:
109 id = actionCommandStatus->hudElements[0];
110 if (actionCommandStatus->showHud) {
112 }
113 hud_element_set_alpha(id, 255);
114 id = actionCommandStatus->hudElements[1];
115 hud_element_set_alpha(id, 255);
116 if (actionCommandStatus->showHud) {
118 }
119 id = actionCommandStatus->hudElements[4];
120 hud_element_set_alpha(id, 255);
121 if (actionCommandStatus->showHud) {
123 }
124 actionCommandStatus->state = 1;
125 break;
126 case 1:
128 if (actionCommandStatus->hudPrepareTime != 0) {
129 actionCommandStatus->hudPrepareTime--;
130 } else {
131 actionCommandStatus->hudPosX += 20;
132 if (actionCommandStatus->hudPosX > 50) {
133 actionCommandStatus->hudPosX = 50;
134 }
136 actionCommandStatus->hudElements[0],
137 actionCommandStatus->hudPosX,
138 actionCommandStatus->hudPosY);
140 actionCommandStatus->hudElements[1],
141 actionCommandStatus->hudPosX,
142 actionCommandStatus->hudPosY + 28);
143
144 phi_a1 = 100 - actionCommandStatus->thresholdLevel;
145 new_var = 29 - (phi_a1 * 60) / 100;
147 actionCommandStatus->hudElements[4],
148 actionCommandStatus->hudPosX - new_var,
149 actionCommandStatus->hudPosY + 17);
150 }
151 break;
152 case 10:
154 if (actionCommandStatus->prepareTime != 0) {
155 actionCommandStatus->prepareTime--;
156 break;
157 }
158 hud_element_set_script(actionCommandStatus->hudElements[0], &HES_MashAButton);
159 actionCommandStatus->barFillLevel = 0;
160 actionCommandStatus->unk_5C = 0;
161 D_802A9B00 = TRUE;
162 actionCommandStatus->frameCounter = actionCommandStatus->duration;
164 actionCommandStatus->state = 11;
165 // fallthrough
166 case 11:
168
169 if (!actionCommandStatus->isBarFilled) {
170 if (actionCommandStatus->targetWeakness != 0) {
171 cutoff = actionCommandStatus->mashMeterCutoffs[actionCommandStatus->mashMeterIntervals];
172 actionCommandStatus->barFillLevel -= D_802A9AA0_42D9B0[actionCommandStatus->barFillLevel / cutoff / 20];
173 if (actionCommandStatus->barFillLevel < 0) {
174 actionCommandStatus->barFillLevel = 0;
175 }
176 } else {
177 actionCommandStatus->barFillLevel -= 10;
178 if (actionCommandStatus->barFillLevel < 0) {
179 actionCommandStatus->barFillLevel = 0;
180 }
181 }
182 }
183
184 if (battleStatus->curButtonsPressed & BUTTON_A) {
185 phi_a1 = actionCommandStatus->targetWeakness;
186 if (phi_a1 != 0) {
187 s32 a = battleStatus->actionCmdDifficultyTable[actionCommandStatus->difficulty];
188
189 phi_a1 = (((a * 850) / 100) * phi_a1) / 100;
190 actionCommandStatus->barFillLevel += phi_a1;
191 } else {
192 actionCommandStatus->barFillLevel += 100;
193 if (actionCommandStatus->barFillLevel >= 500) {
194 actionCommandStatus->barFillLevel = 500;
195 }
196 }
197 }
198
199 if (actionCommandStatus->barFillLevel > 10000) {
200 actionCommandStatus->barFillLevel = 10000;
201 actionCommandStatus->isBarFilled = TRUE;
202 id = actionCommandStatus->hudElements[3];
204 id,
205 actionCommandStatus->hudPosX + 50,
206 actionCommandStatus->hudPosY + 28);
208 }
209
210 battleStatus->actionQuality = actionCommandStatus->barFillLevel / 100;
212
213 if (actionCommandStatus->frameCounter == 0) {
214 phi_a1 = actionCommandStatus->barFillLevel;
215 if (actionCommandStatus->targetWeakness == 0) {
216 phi_a1 = 0;
217 }
218
219 battleStatus->actionQuality = phi_a1 / 100;
220 if (phi_a1 == 0) {
221 battleStatus->actionSuccess = -1;
222 } else if (battleStatus->actionQuality >= actionCommandStatus->thresholdLevel) {
223 battleStatus->actionSuccess = 1;
224 } else {
225 battleStatus->actionSuccess = 0;
226 }
227
228 cutoff = actionCommandStatus->mashMeterCutoffs[actionCommandStatus->mashMeterIntervals - 1];
229 if (cutoff / 2 < battleStatus->actionQuality) {
230 battleStatus->actionResult = ACTION_RESULT_SUCCESS;
231 } else {
232 battleStatus->actionResult = ACTION_RESULT_MINUS_4;
233 }
234
235 if (battleStatus->actionSuccess == 1) {
237 }
238
241 actionCommandStatus->frameCounter = 5;
242 actionCommandStatus->state = 12;
243 } else {
244 actionCommandStatus->frameCounter--;
245 }
246 break;
247 case 12:
248 if (actionCommandStatus->targetWeakness == 0) {
249 actionCommandStatus->barFillLevel -= 100;
250 if (actionCommandStatus->barFillLevel < 0) {
251 actionCommandStatus->barFillLevel = 0;
252 }
253 }
254 if (actionCommandStatus->frameCounter != 0) {
255 actionCommandStatus->frameCounter--;
256 break;
257 }
259 break;
260 }
261
262 // Invisible "run away"-like meter that determines success threshold.
263 // https://www.youtube.com/watch?v=FagUpV0c67s
264 switch (actionCommandStatus->state) {
265 case 1:
266 case 10:
267 case 11:
268 if (actionCommandStatus->thresholdMoveDir == 0) {
269 actionCommandStatus->thresholdLevel += 7;
270 if (actionCommandStatus->thresholdLevel >= 100) {
271 actionCommandStatus->thresholdLevel = 100;
272 actionCommandStatus->thresholdMoveDir = 1;
273 }
274 } else {
275 actionCommandStatus->thresholdLevel -= 7;
276 if (actionCommandStatus->thresholdLevel <= 0) {
277 actionCommandStatus->thresholdLevel = 0;
278 actionCommandStatus->thresholdMoveDir = 0;
279 }
280 }
281 }
282}
283
284void N(draw)(void) {
285 ActionCommandStatus* actionCommandStatus = &gActionCommandStatus;
286 s32 y;
287 s32 x;
288 s32 id;
289 s32 temp_a1;
290 s32 temp_v0;
291
292 temp_v0 = actionCommandStatus->thresholdLevel * 60;
293 x = 60 - temp_v0 / 100;
294 temp_a1 = x - 31;
295 hud_element_set_render_pos(actionCommandStatus->hudElements[4], actionCommandStatus->hudPosX - temp_a1, actionCommandStatus->hudPosY + 17);
296 hud_element_draw_clipped(actionCommandStatus->hudElements[0]);
297
298 id = actionCommandStatus->hudElements[1];
300 hud_element_get_render_pos(id, &x, &y);
301 // Redundant call, but needed to match.
302 hud_element_get_render_pos(id, &x, &y);
303
304 if (!D_802A9B00) {
305 draw_mash_meter_multicolor_with_divisor(x, y, actionCommandStatus->barFillLevel / 100, 1);
306 } else if (!actionCommandStatus->isBarFilled) {
307 draw_mash_meter_multicolor_with_divisor(x, y, actionCommandStatus->barFillLevel / 100, 4);
308 } else {
309 draw_mash_meter_blink_with_divisor(x, y, actionCommandStatus->barFillLevel / 100, 4);
310 }
311 id = actionCommandStatus->hudElements[3];
313}
314
void draw_mash_meter_blink_with_divisor(s32 posX, s32 posY, s32 fillValue, s32 divisor)
Definition action_cmd.c:251
BSS ActionCommandStatus gActionCommandStatus
Definition action_cmd.c:91
void func_80269160(void)
Definition action_cmd.c:655
void action_command_free(void)
Definition action_cmd.c:446
void draw_mash_meter_multicolor_with_divisor(s32 posX, s32 posY, s32 fillValue, s32 divisor)
Definition action_cmd.c:231
s32 adjust_action_command_difficulty(s32 arg0)
Definition action_cmd.c:101
void action_command_init_status(void)
Definition action_cmd.c:256
void func_80269118(void)
Definition action_cmd.c:641
HudScript HES_AButton
HudScript HES_BlueMeter
HudScript HES_RunAwayOK
HudScript HES_MashAButton
HudScript HES_100pct
@ ACTION_COMMAND_MODE_NOT_LEARNED
Definition action_cmd.h:38
#define rand_int
@ ACTION_COMMAND_POWER_SHOCK
Definition enums.h:3488
@ BUTTON_A
Definition enums.h:2790
@ SOUND_LOOP_CHARGE_BAR
Definition enums.h:1646
@ ACTION_RESULT_SUCCESS
Definition enums.h:1968
@ ACTION_RESULT_MINUS_4
Definition enums.h:1964
@ ACTION_RESULT_FAIL
Definition enums.h:1967
#define ApiStatus_DONE2
Definition evt.h:118
s32 Bytecode
Definition evt.h:7
void btl_set_popup_duration(s32 duration)
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
void hud_element_get_render_pos(s32 id, s32 *x, s32 *y)
void hud_element_set_alpha(s32 id, s32 opacity)
void hud_element_set_script(s32 id, HudScript *anim)
void hud_element_set_render_depth(s32 id, s32 z)
void hud_element_set_render_pos(s32 id, s32 x, s32 y)
s32 hud_element_create(HudScript *anim)
Creates a new HUD element and returns its ID.
void hud_element_set_flags(s32 id, s32 flags)
Turns on the given flags.
void hud_element_clear_flags(s32 id, s32 flags)
Turns off the given flags.
void hud_element_draw_clipped(s32 id)
void hud_element_free(s32 id)
@ HUD_ELEMENT_FLAG_DISABLED
Definition hud_element.h:74
@ HUD_ELEMENT_FLAG_80
Definition hud_element.h:80
BSS s32 D_802A9B00
Definition power_shock.c:8
void N free(void)
s32 actionCmdTablePowerShock[]
Definition action_cmd.c:43
void N update(void)
Definition power_shock.c:98
s32 D_802A9AA0_42D9B0[]
Definition power_shock.c:6
void N draw(void)
void sfx_stop_sound(s32 soundID)
Definition sfx.c:507
void sfx_adjust_env_sound_params(s32 soundID, u8 volume, u8 pan, s16 pitchShift)
Definition sfx.c:492
void sfx_play_sound_with_params(s32 soundID, u8 volume, u8 pan, s16 pitchShift)
Definition sfx.c:458
#define BSS
Definition macros.h:7
s32 * actionCmdDifficultyTable
BattleStatus gBattleStatus
Definition battle.c:11
void N init(Npc *bombette)
Definition bombette.c:66