Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
squirt.c
Go to the documentation of this file.
1#include "common.h"
2#include "battle/action_cmd.h"
3
4#define NAMESPACE action_command_squirt
5
6extern s32 actionCmdTableSquirt[];
7
8// indices into ActionCommandStatus::hudElements for this action command
9enum {
12};
13
14// how much to subtract from the meter per frame after overfilling it
15#define METER_DRAIN_RATE 250
16
17s32 N(DrainRateTable)[] = { 300, 300, 265, 220, 175, 175 };
18s32 N(FillRateTable)[] = { 300, 300, 265, 220, 175, 175 };
19
20// bug: the sixth entry is not accessible due to the way idx is calculated in these macros
21#define GET_DRAIN_RATE(pct) (N(DrainRateTable)[((pct) / (ONE_PCT_MASH / 5))])
22#define GET_FILL_RATE(pct) (N(FillRateTable)[((pct) / (ONE_PCT_MASH / 5))])
23
24API_CALLABLE(N(init)) {
26 BattleStatus* battleStatus = &gBattleStatus;
27 HudElemID hid;
28
29 battleStatus->maxActionQuality = 5;
31 if (battleStatus->actionCommandMode == AC_MODE_NOT_LEARNED) {
32 battleStatus->actionQuality = 0;
33 return ApiStatus_DONE2;
34 }
35
37
39 acs->state = AC_STATE_INIT;
40 acs->wrongButtonPressed = FALSE;
41 acs->meterFillLevel = 0;
42 acs->meterFillWidth = 0;
43 battleStatus->actionProgress = 0;
44 acs->hudPosX = -48;
45 acs->squirt.draining = FALSE;
46 acs->hudPosY = 80;
47
49 acs->hudElemIDs[HIDX_BUTTON] = hid;
53
55 acs->hudElemIDs[HIDX_METER] = hid;
56 hud_element_set_render_pos(hid, acs->hudPosX, acs->hudPosY + 28);
59
60 return ApiStatus_DONE2;
61}
62
63API_CALLABLE(N(start)) {
65 BattleStatus* battleStatus = &gBattleStatus;
66 Bytecode* args = script->ptrReadPos;
67
68 if (battleStatus->actionCommandMode == AC_MODE_NOT_LEARNED) {
69 battleStatus->actionQuality = 0;
70 return ApiStatus_DONE2;
71 }
72
74
75 acs->prepareTime = evt_get_variable(script, *args++);
76 acs->duration = evt_get_variable(script, *args++);
77 acs->difficulty = evt_get_variable(script, *args++);
79
80 acs->wrongButtonPressed = FALSE;
81 acs->meterFillLevel = 0;
82 acs->meterFillWidth = 0;
83 battleStatus->actionQuality = 0;
84 battleStatus->actionResult = ACTION_RESULT_FAIL;
85 acs->state = AC_STATE_START;
86 battleStatus->flags1 &= ~BS_FLAGS1_FREE_ACTION_COMMAND;
87
89
90 return ApiStatus_DONE2;
91}
92
93void N(update)(void) {
95 BattleStatus* battleStatus = &gBattleStatus;
96 HudElemID hid;
97 s32 fillPct;
98 s32 cutoff;
99 s32 idx;
100
101 switch (acs->state) {
102 case AC_STATE_INIT:
104
105 hid = acs->hudElemIDs[HIDX_BUTTON];
106 if (acs->showHud) {
108 }
109 hud_element_set_alpha(hid, 255);
110
111 hid = acs->hudElemIDs[HIDX_METER];
112 hud_element_set_alpha(hid, 255);
113 if (acs->showHud) {
115 }
116
117 acs->state = AC_STATE_APPEAR;
118 break;
119 case AC_STATE_APPEAR:
121
122 acs->hudPosX += 20;
123 if (acs->hudPosX > 50) {
124 acs->hudPosX = 50;
125 }
126
129 break;
130 case AC_STATE_START:
132
133 if (acs->prepareTime != 0) {
134 acs->prepareTime--;
135 break;
136 }
137
139 acs->meterFillLevel = 0;
140 acs->squirt.draining = FALSE;
141 acs->stateTimer = acs->duration;
143 acs->state = AC_STATE_ACTIVE;
144
145 // fallthrough
146 case AC_STATE_ACTIVE:
148
149 // meter filling and draining
150 cutoff = acs->mashMeterCutoffs[acs->mashMeterNumIntervals];
151 fillPct = acs->meterFillLevel / cutoff;
152 if (!acs->squirt.draining) {
153 if (!(battleStatus->curButtonsDown & BUTTON_A)) {
154 acs->meterFillLevel -= GET_DRAIN_RATE(fillPct);
155 if (acs->meterFillLevel < 0) {
156 acs->meterFillLevel = 0;
157 }
158 } else {
159 s32 amt = GET_FILL_RATE(fillPct);
160 acs->meterFillLevel += SCALE_BY_PCT(amt, battleStatus->actionCmdDifficultyTable[acs->difficulty]);
161 if (acs->meterFillLevel > MAX_MASH_UNITS) {
163 acs->squirt.draining = TRUE;
164 }
165 }
166 } else {
168 if (acs->meterFillLevel <= 0) {
169 acs->meterFillLevel = 0;
170 acs->squirt.draining = FALSE;
171 }
172 }
173
174 battleStatus->actionProgress = acs->meterFillLevel / ONE_PCT_MASH;
176
177 hid = acs->hudElemIDs[HIDX_BUTTON];
178 if (fillPct < 80) {
181 }
182 } else {
185 }
186 }
187
188 if (acs->stateTimer != 0) {
189 acs->stateTimer--;
190 break;
191 }
192
193 if (acs->meterFillLevel == 0) {
194 battleStatus->actionQuality = AC_QUALITY_FAILED;
195 } else {
196 battleStatus->actionQuality = battleStatus->actionProgress;
197 }
198
199 // a good result is filling the meter over halfway to the second-highest interval
200 cutoff = acs->mashMeterCutoffs[acs->mashMeterNumIntervals - 1];
201 if (battleStatus->actionProgress <= cutoff / 2) {
203 } else {
204 battleStatus->actionResult = ACTION_RESULT_SUCCESS;
205 }
206
207 if (battleStatus->actionQuality == 100) {
208 // only count 100% fill as success for this action command
210 }
211
214 acs->stateTimer = 5;
215 acs->state = AC_STATE_DISPOSE;
216 break;
217 case AC_STATE_DISPOSE:
218 if (acs->stateTimer != 0) {
219 acs->stateTimer--;
220 break;
221 }
223 break;
224 }
225}
226
227void N(draw)(void) {
229 s32 hudX, hudY;
230 HudElemID hid;
231
233 hid = acs->hudElemIDs[HIDX_METER];
235 hud_element_get_render_pos(hid, &hudX, &hudY);
236 if (!acs->squirt.draining) {
238 } else {
240 }
241}
242
BSS ActionCommandStatus gActionCommandStatus
Definition action_cmd.c:91
void action_command_free(void)
Definition action_cmd.c:446
void increment_action_command_attempt_count(void)
Definition action_cmd.c:641
void draw_mash_meter_multicolor_with_divisor(s32 posX, s32 posY, s32 fillValue, s32 divisor)
Definition action_cmd.c:231
void draw_mash_meter_mode_with_divisor(s32 posX, s32 posY, s32 fillValue, s32 divisor, s32 colorMode)
Definition action_cmd.c:241
s32 adjust_action_command_difficulty(s32 difficultyLevel)
Definition action_cmd.c:101
void increment_action_command_success_count(void)
Definition action_cmd.c:655
void action_command_init_status(void)
Definition action_cmd.c:256
#define AC_QUALITY_FAILED
Definition action_cmd.h:66
HudScript HES_AButton
HudElemID hudElemIDs[16]
Definition action_cmd.h:83
@ AC_STATE_APPEAR
Definition action_cmd.h:35
@ AC_STATE_DISPOSE
Definition action_cmd.h:38
@ AC_STATE_INIT
Definition action_cmd.h:34
@ AC_STATE_ACTIVE
Definition action_cmd.h:37
@ AC_STATE_START
Definition action_cmd.h:36
@ MASH_METER_MODE_ONE_COLOR
Definition action_cmd.h:55
#define ONE_PCT_MASH
Definition action_cmd.h:69
#define SCALE_BY_PCT(x, pct)
Definition action_cmd.h:77
HudScript HES_BlueMeter
HudScript HES_PressAButton
HudScript HES_AButtonDown
@ AC_MODE_NOT_LEARNED
Definition action_cmd.h:60
#define MAX_MASH_UNITS
Definition action_cmd.h:75
@ HIDX_METER
Definition squirt.c:11
@ HIDX_BUTTON
Definition squirt.c:10
#define METER_DRAIN_RATE
Definition squirt.c:15
#define GET_DRAIN_RATE(pct)
Definition squirt.c:21
#define GET_FILL_RATE(pct)
Definition squirt.c:22
void N free(void)
Definition squirt.c:243
void N update(void)
Definition squirt.c:93
s32 actionCmdTableSquirt[]
Definition action_cmd.c:42
void N draw(void)
Definition squirt.c:227
s32 HudElemID
@ ACTION_COMMAND_SQUIRT
Definition enums.h:3487
@ BUTTON_A
Definition enums.h:2790
@ SOUND_LOOP_CHARGE_METER
Definition enums.h:1646
@ ACTION_RESULT_SUCCESS
Definition enums.h:1968
@ ACTION_RESULT_METER_BELOW_HALF
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:1689
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)
HudScript * hud_element_get_script(s32 id)
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:72
@ HUD_ELEMENT_FLAG_80
Definition hud_element.h:78
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 POPUP_MSG_OFF
Definition battle.h:270
#define POPUP_MSG_ON
Definition battle.h:269
s32 * actionCmdDifficultyTable
BattleStatus gBattleStatus
Definition battle.c:11
void N init(Npc *bombette)
Definition bombette.c:66