Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
counterattack.c
Go to the documentation of this file.
1/* FIGHTSTG's counterattack, and the European version's revival of a fighter. */
2
4
5/* Starts the battle script of the counterattack's technique, with its
6 element's stage, and its hit result, and empties the countering fighter's
7 charge. */
8static inline void playCounterTech(Counterattack *task, BattleChild *children) {
9 TechData *tech = &TECHS[task->tech - 1];
10 s32 other = task->side != 0;
11 BattleFighter *row;
12 s32 element;
13
14 children[0].script = FIGHTSTG_createBattleScript();
15 children[0].script->enemy = task->side;
16 if (task->side == 0 && tech->script == 5) {
17 children[0].script->index = 6;
18 } else {
19 children[0].script->index = tech->script;
20 }
21 if (tech->scriptSound != 0) {
22 children[0].script->sound = tech->scriptSound;
23 }
24 {
26
27 if (tech->element >= ELEMENT_FIRST || stats->element >= ELEMENT_FIRST) {
28 if (tech->element >= ELEMENT_FIRST) {
29 element = tech->element - ELEMENT_FIRST;
30 } else {
31 element = stats->element - ELEMENT_FIRST;
32 }
33 element = element * 3 + 0x21;
34 if (stats->elementPower >= 0x40) {
35 children[0].script->stage = element + 1;
36 } else {
37 children[0].script->stage = element;
38 }
39 } else {
40 children[0].script->stage = -1;
41 }
42 }
43 if (tech->scriptEffect != 0) {
44 children[0].script->effect = tech->scriptEffect;
45 } else if (tech->script == 5) {
46 children[0].script->effect = 0x2E;
47 children[0].script->sound = 0x1E;
48 }
49 row = FIGHTSTG_battle.state.fighters[1 - other];
50 if (task->hit != 0) {
51 if (row[FIGHTSTG_battle.state.active[1 - other]].hp - task->damage <= 0) {
52 children[0].script->hits[3] = 2;
53 } else {
54 children[0].script->hits[3] = 1;
55 WFIGHTMN_countHit(task->side, task->damage);
57 }
58 } else {
59 children[0].script->hits[3] = 3;
60 }
62 if (task->side != 0) {
64 }
65 row[FIGHTSTG_battle.state.active[task->side != 0]].charge = 0;
66}
67
68/* Shows whether the counterattack hit and for how much, and takes the damage
69 from the countered fighter's HP (queueing its knockout at 0). */
70static inline void showCounterResult(Counterattack *task, BattleChild *children) {
71 children[0].message = FIGHTSTG_createMessage();
72 if (task->hit != 0) {
73 task->lines[0] = (task->side == 0) << 4;
74 task->lines[1] = task->damage;
75 children[0].message->show(children[0].message, 4, task->lines);
76 } else {
77 task->lines[0] = 0x1D;
78 task->lines[1] = (task->side == 0) << 4;
79 children[0].message->show(children[0].message, 2, task->lines);
80 }
81 if (task->damage != 0) {
82 s32 index = task->side == 0;
84
85 fighter->hp -= task->damage;
86 if (fighter->hp <= 0) {
87 fighter->hp = 0;
88 if (task->noKnockOutEvent == 0) {
89 FIGHTSTG_queueKnockOut(index << 4);
90 }
91 }
92 }
93}
94
95/* A counterattack (FIGHTSTG_startCounterattack): the player's from an event of type 8 or
96 the partner's first technique, the enemy's from its table entry; substate
97 0 plays the technique (playCounterTech), 1 shows the damage and takes the
98 HP (showCounterResult), 2 hands received to WFIGHTMN_chargeGauge. The
99 match depends on playCounterTech's technique and side being declared in
100 it, on the event index and the stats being variables of their own, on the
101 stage being written element * 3 + 0x21 and one more and on one row
102 variable for both of playCounterTech's rows. */
104 BattleFighter *fighter;
105 BattleTableEntry *entry;
106 s32 other;
107
108 switch (task->state) {
109 case TASK_INIT:
110 default:
111 if (task->received == 0) {
112 task->state = TASK_DONE;
113 break;
114 }
115 other = task->side != 0;
116 fighter = &FIGHTSTG_battle.state.fighters[other][FIGHTSTG_battle.state.active[other]];
117 if ((fighter->flags & FIGHTER_PARALYZED) && FIGHTSTG_battleFuncs.testParalysis(task->side) != 0) {
118 task->state = TASK_DONE;
119 break;
120 }
121 if (task->side == 0) {
123
124 if (index >= 0) {
125 task->tech = FIGHTSTG_events.events[index].args[2];
126 task->substate = 0;
127 FIGHTSTG_events.events[index].type = 0;
128#if VERSION_US
130#elif VERSION_EU || VERSION_JP
132 && FIGHTSTG_battleFuncs.rollCounter(0, task->received) != 0) {
133#endif
134 task->tech = GET_DIGIMON(fighter->id)->skills[0];
135 task->substate = 1;
136 } else {
137 task->state = TASK_DONE;
138 break;
139 }
140 } else {
141 entry = FIGHTSTG_battleTableFunc(fighter->id);
142 if (entry->counter.condition == 0) {
143 task->state = TASK_DONE;
144 break;
145 }
147 task->state = TASK_DONE;
148 break;
149 }
151 if (task->tech == 1) {
153 task->substate = 1;
154 }
155 }
156 children[0].message = FIGHTSTG_createMessage();
157 task->lines[0] = task->side;
158 task->lines[1] = task->tech;
159 children[0].message->show(children[0].message, task->substate + 5, task->lines);
160 task->hit = FIGHTSTG_battleFuncs.rollHit(task->side, task->tech);
161 if (task->hit != 0) {
164 task->damage = WFIGHTMN_limitDamage(task->side, task->damage, 0);
165 }
166 }
167 task->nextState(task);
168 break;
169 case TASK_RUN:
170 switch (task->substate) {
171 case 0:
172 default:
173 if (children[0].message == NULL) {
174 playCounterTech(task, children);
175 task->substate++;
176 }
177 break;
178 case 1:
179 if (children[0].script == NULL) {
180 showCounterResult(task, children);
181 task->substate++;
182 }
183 break;
184 case 2:
185 if (children[0].message == NULL) {
186 WFIGHTMN_chargeGauge(task->side, task->received);
187 task->state = TASK_KILL;
188 }
189 break;
190 }
191 break;
192 case TASK_DONE:
193 case TASK_KILL:
194 break;
195 }
196}
197
198/* Starts SIDE's counterattack (FIGHTSTG_updateCounterattack) to RECEIVED
199 damage; NOKNOCKOUTEVENT keeps a knockout from queueing its event */
200Counterattack *FIGHTSTG_startCounterattack(s32 side, s32 received, s32 noKnockOutEvent) {
202
203 task->side = side;
204 task->received = received;
205 task->noKnockOutEvent = noKnockOutEvent;
206 return task;
207}
208
209#if VERSION_EU || VERSION_JP
210/* Revives one of the player's fighters at full HP, clearing its status
211 events, and raises its defense by tech's effectPower (FIGHTSTG_battleFuncs.changeBoost) */
212void FIGHTSTG_reviveFighter(s32 tech, s32 fighter) {
214 TechData *entry = &TECHS[tech - 1];
215 s32 index;
216 s32 i;
217
218 if (fighters[fighter].id == 0) {
219 return;
220 }
221 for (i = 0; i < 6; i++) {
222 index = FIGHTSTG_events.funcs.find(FIGHTSTG_clearIds[i], 0, fighter);
223 if (index >= 0) {
224 FIGHTSTG_events.events[index].type = 0;
225 }
226 }
227 if (fighters[fighter].hp == 0) {
228 WFIGHTMN_checkEquip(fighter);
229 }
230 fighters[fighter].flags = 0;
231 fighters[fighter].hp = fighters[fighter].maxHp;
232 FIGHTSTG_battleFuncs.changeBoost(0, fighter, 1, entry->effectPower);
233 FIGHTSTG_queueBoostEnd(SIDE_PLAYER, fighter, 1, tech);
234}
235#endif
Battle FIGHTSTG_battle
the battle: its fighters, speed and drawing functions
Definition battle.c:16
BattleFuncs FIGHTSTG_battleFuncs
the battle's stats and the functions that compute with them
Definition battle.c:25
void FIGHTSTG_queueKnockOut(u8 side)
Queues the fall of side's active fighter (event 20), first.
Definition battle.c:107
#define FIGHTER_PARALYZED
loses turns at random (FIGHTSTG_battleFuncs.testParalysis)
Definition battle.h:183
#define BATTLE_KIND_NORMAL
The kinds of battle (Battle.kind), which WFIGHTMN picks by the battle and the mode it came from.
Definition battle.h:124
#define ACTIVE_FIGHTER(side)
SIDE's active fighter as its row plus the index, which GCC adds with the row's address first.
Definition battle.h:493
#define EVENT_PARTNER_TECH
a technique of the partner's, run as its command
Definition battle.h:88
#define SIDE_PLAYER
The battle's sides, as the functions that take a side want them: side >> 4 is its row of FIGHTSTG_bat...
Definition battle.h:177
#define SIDE_ENEMY
Definition battle.h:178
#define ELEMENT_FIRST
The elements (TechData.element, BattleStats.element) and the families (TechData.family,...
Definition battle.h:37
EventQueue FIGHTSTG_events
the battle's events and their functions
Definition events.c:43
void FIGHTSTG_queueBoostEnd(u8 side, s32 fighter, s32 kind, s32 tech)
Queues the end of a fighter's boost of stat kind, 12 frames on when a technique (tech) gave it and 8 ...
Definition events.c:565
FIGHTSTG.PRO: the battle.
BattleScript * FIGHTSTG_createBattleScript(void)
Creates a battle script, which plays a technique (FIGHTSTG_updateBattleScript)
BattleTableEntry *(* FIGHTSTG_battleTableFunc)(s32 id)
how the fight stage and WFIGHTMN read the battle table
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
Counterattack * FIGHTSTG_startCounterattack(s32 side, s32 received, s32 noKnockOutEvent)
Starts SIDE's counterattack (FIGHTSTG_updateCounterattack) to RECEIVED damage; NOKNOCKOUTEVENT keeps ...
static void playCounterTech(Counterattack *task, BattleChild *children)
Starts the battle script of the counterattack's technique, with its element's stage,...
void FIGHTSTG_reviveFighter(s32 tech, s32 fighter)
Revives one of the player's fighters at full HP, clearing its status events, and raises its defense b...
static void showCounterResult(Counterattack *task, BattleChild *children)
Shows whether the counterattack hit and for how much, and takes the damage from the countered fighter...
void FIGHTSTG_updateCounterattack(Counterattack *task, BattleChild *children)
A counterattack (FIGHTSTG_startCounterattack): the player's from an event of type 8 or the partner's ...
s32 FIGHTSTG_getEnemyAction(u8 kind)
What an enemy's action target makes it do (EnemyTurn.target): 1 its first technique,...
Definition enemy_turn.c:438
s32 FIGHTSTG_testEnemyCondition(u8 condition, s16 arg)
Whether the condition of an enemy's action holds (BattleTableAction): always, a chance in 128,...
Definition enemy_turn.c:303
#define TASK_RUN
Definition task.h:35
#define TASK_KILL
Definition task.h:37
#define TASK_INIT
Tasks: every game object is a task, a heap block that starts with this header and is updated once per...
Definition task.h:34
#define TASK_DONE
Definition task.h:36
DigimonData *(* GET_DIGIMON)(s32 id)
getDigimon for the overlays, in the small data (.sdata) between game/items.c's and file/file_table....
Definition get_digimon.c:10
TechData TECHS[443]
The techniques, from 1: technique n is TECHS[n - 1].
Definition items.c:906
BattleMessageBox * FIGHTSTG_createMessage(void)
Creates a battle message box (FIGHTSTG_updateMessage)
Definition message.c:440
void WFIGHTMN_checkEquip(s32 member)
Queues a recovery (FIGHTSTG_queueRecovery) for party member MEMBER's partner when it has WFIGHTMN_REC...
Definition setup.c:81
One of the battle's fighters, three on each side (WFIGHTMN's BattleUnit): a partner's HP and MP go ba...
Definition battle.h:191
u8 flags
FIGHTER_*.
Definition battle.h:204
s16 charge
added in 64ths to its next technique's damage, which uses it up
Definition battle.h:199
s16 id
the Digimon (DIGIMON_DATA)
Definition battle.h:192
s32(* rollCounter)(s32 arg0, s32 arg1)
Definition battle.h:352
void(* changeBoost)(u8 side, s32 index, s32 stat, s32 percent)
changes a fighter's stat boost
Definition battle.h:359
s32(* computeCounterDamage)(u8 side, s32 id, s32 value)
Definition battle.h:335
s32(* testParalysis)(u8 side)
whether side's paralysis costs it the turn
Definition battle.h:358
s32(* rollHit)(u8 side, s32 tech)
whether a hit lands
Definition battle.h:338
BattleStats *(* computeStats)(u8 side, s32 which, s32 index)
Definition battle.h:331
void(* show)()
FIGHTSTG_showMessage: (task, type, data)
Definition menu.h:182
s32 enemy
the script is the enemy's (nonzero) or the partner's
Definition effect.h:146
s32 sound
what the sound commands' 0x62 and 0x63 stand for on a hit
Definition effect.h:151
s32 effect
the sprite effect the effect command's 9999 stands for
Definition effect.h:150
s32 hits[4]
0 a hit, 3 a miss; [3] how it ended
Definition effect.h:148
s32 index
the script, in the fighter's archive
Definition effect.h:147
s32 stage
what the stage command's 0x38 stands for
Definition effect.h:149
s32 active[2]
each side's fighter
Definition battle.h:226
BattleFighter fighters[2][3]
Definition battle.h:227
s16 kind
the kind of battle
Definition battle.h:230
A side's stats as FIGHTSTG_computeStats works them out.
Definition battle.h:305
u8 elementPower
Definition battle.h:315
u8 counter
answers hits with the partner's first skill
Definition battle.h:319
u8 element
the accessory's, for techniques without one
Definition battle.h:314
BattleTableAction counter
its counterattack (FIGHTSTG_updateCounterattack)
Definition battle.h:68
s16 techs[3]
its first, then those of FIGHTSTG_getEnemyAction's kinds 2 and 3
Definition battle.h:63
BattleState state
Definition battle.h:240
A counterattack (FIGHTSTG_startCounterattack)
Definition action.h:99
s32 noKnockOutEvent
a knockout doesn't call FIGHTSTG_queueKnockOut
Definition action.h:107
s32 lines[8]
FIGHTSTG_updateMessage's.
Definition action.h:101
s32 hit
whether the technique hits (FIGHTSTG_battleFuncs.rollHit)
Definition action.h:105
void(* nextState)(struct Counterattack *task)
Definition action.h:100
u8 side
the side that counters, 0 or 0x10
Definition action.h:102
s32 received
the damage it answers, 0 for none
Definition action.h:103
u16 skills[7]
[1]-[6] are learnt at skillLevels
Definition game_state.h:90
s32(* find)(s32 type, u8 side, s32 fighter)
Definition battle.h:146
EventQueueFuncs funcs
Definition battle.h:171
QueuedEvent events[99]
Definition battle.h:165
s16 type
0 for a free entry
Definition battle.h:110
s32 args[6]
Definition battle.h:112
A technique (TECHS, from 1: technique n is TECHS[n - 1])
Definition game_state.h:110
u8 scriptSound
its script's hit sound (BattleScript.sound)
Definition game_state.h:124
u8 scriptEffect
its script's sprite effect (BattleScript.effect)
Definition game_state.h:123
u8 effectPower
the effect's strength (a boost's amount, a drain's 128ths)
Definition game_state.h:121
u8 element
ELEMENT_FIRST and up, under it none.
Definition game_state.h:116
u8 script
its script in the user's archive (BattleScript.index); 5 and 12 are special
Definition game_state.h:125
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
s32 FIGHTSTG_clearIds[]
the event types that the European version's FIGHTSTG_reviveFighter clears
Definition tech_action.c:33
s32 WFIGHTMN_limitDamage(u8 side, s32 damage, s32 hits)
In BATTLE_KIND_ESCAPE and BATTLE_KIND_UNK2, cuts the damage that the partner's hits do so that the en...
Definition techs.c:321
void WFIGHTMN_countHit(u8 side, s32 damage)
In BATTLE_KIND_FINAL_LAST, the partner's third hit that does damage weakens the enemy (FIGHTSTG's FIG...
Definition techs.c:301
void WFIGHTMN_chargeGauge(u8 side, s32 damage)
Adds what damage gives to the current partner's gauge (BATTLE_SETUP.gauges), up to 1000.
Definition techs.c:35
s32 WFIGHTMN_setIdleMotion(u8 id, s32 damage)
Sets the idle motion of side id >> 4's fighter: 1 (weak) if damage leaves it with a quarter of its HP...
Definition techs.c:280
A turn's or a counterattack's one child, and what WFIGHTMN's battle menu waits for (NULL when it is d...
Definition task.h:16
BattleMessageBox * message
FIGHTSTG_createMessage.
Definition task.h:18
BattleScript * script
a technique's (FIGHTSTG_createBattleScript)
Definition task.h:19