Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
first_tech.c
Go to the documentation of this file.
1/* FIGHTSTG's first technique, the one a side starts the battle with. */
2
4
5/* Picks the side's first technique and says it is used (or, for an enemy
6 without the MP, that it is not), noting whether the other side's fighter
7 was asleep. */
8static inline void announceFirstTech(FirstTech *task, BattleChild *children) {
9 BattleFighter *fighter;
10 TechData *tech;
11
12 if (task->side == 0) {
14 } else {
16 }
17 fighter = ACTIVE_FIGHTER(1);
18 tech = &TECHS[task->tech - 1];
19 if (task->side != 0 && tech->mp > fighter->mp) {
20 children[0].message = FIGHTSTG_createMessage();
21 task->lines[0] = 0x8D;
22 task->lines[1] = task->side;
23 children[0].message->show(children[0].message, 2, task->lines);
24 task->substate = 2;
25 } else {
26 children[0].message = FIGHTSTG_createMessage();
27 task->lines[0] = 8;
28 task->lines[1] = task->side;
29 children[0].message->show(children[0].message, 2, task->lines);
30 FIGHTSTG_action.start(task->side, task->tech);
31 }
32 {
33 s32 other = 1 - (task->side >> 4);
34
35 fighter = FIGHTSTG_getActiveFighter(other);
36 }
37 if (fighter->flags & FIGHTER_ASLEEP) {
38 task->asleep = 1;
39 }
40}
41
42/* Shows the technique's result (its hits, its knockout, the 70 percent of
43 the partner's HP that TECH_EFFECT_END_BATTLE takes, its damage or its
44 miss) and keeps the damage to take. */
45static inline void showFirstTechResult(FirstTech *task, BattleChild *children) {
46 children[0].message = FIGHTSTG_createMessage();
48 task->lines[0] = SIDE_ENEMY - task->side;
49 task->lines[1] = FIGHTSTG_action.damage;
51 children[0].message->show(children[0].message, 0x10, task->lines);
53#if VERSION_EU || VERSION_JP
54 if (task->damage >= 10000) {
55 task->damage = 9999;
56 }
57#endif
59 s32 other = task->side == 0;
60
61 FIGHTSTG_getActiveFighter(other)->hp = 0;
62 FIGHTSTG_queueKnockOut(other << 4);
63 children[0].task->state = 3;
65 task->damage = ACTIVE_FIGHTER(0)->hp * 7 / 10;
66 task->lines[0] = 0;
67 task->lines[1] = task->damage;
68 children[0].message->show(children[0].message, 4, task->lines);
69 } else if (FIGHTSTG_action.hits[0]) {
70 task->lines[0] = (task->side == 0) << 4;
71 task->lines[1] = FIGHTSTG_action.damage;
72 children[0].message->show(children[0].message, 4, task->lines);
74 } else {
75 task->lines[0] = 0x1D;
76 task->lines[1] = (task->side == 0) << 4;
77 children[0].message->show(children[0].message, 2, task->lines);
78 }
79}
80
81/* Takes the damage from the other side's active fighter, queueing its
82 knockout at 0 HP (and setting step, which ends the technique). */
83static inline void takeFirstTechDamage(FirstTech *task) {
84 BattleFighter *struck;
85
86 if (task->damage != 0) {
87 s32 other = task->side == 0;
88
89 struck = FIGHTSTG_getActiveFighter(other);
90 struck->hp -= task->damage;
91 if (struck->hp <= 0) {
92 struck->hp = 0;
93 FIGHTSTG_queueKnockOut((task->side == 0) << 4);
94 task->step = 1;
95 }
96 }
97}
98
99/* Wakes up COUNTERED, the sleeping fighter the technique struck in row
100 INDEX, says so and ends its sleep's event. */
101static inline void wakeCounteredUp(FirstTech *task, BattleChild *children, BattleFighter *countered, s32 index) {
102 task->lines[0] = 0x2B;
103 task->lines[1] = SIDE_ENEMY - task->side;
104 task->lines[2] = FIGHTSTG_battle.state.active[index];
105 children[0].message = FIGHTSTG_createMessage();
106 children[0].message->show(children[0].message, 7, task->lines);
107 countered->flags &= ~FIGHTER_ASLEEP;
108 {
110
111 if (event >= 0) {
112 FIGHTSTG_events.events[event].type = 0;
113 }
114 }
115}
116
117/* A side's first technique (FIGHTSTG_startFirstTech): the partner's skills[0] or the
118 enemy's battle table techs[0], its message (announceFirstTech) and WFIGHTMN's
119 WFIGHTMN_startTech, then the damage to the other side's active fighter
120 (showFirstTechResult, takeFirstTechDamage: TECH_EFFECT_KNOCK_OUT knocks it out,
121 TECH_EFFECT_END_BATTLE takes 70 percent of the partner's HP), its waking up when
122 that fighter is asleep (substate 4, wakeCounteredUp) and FIGHTSTG_startEnemyAttack
123 when the partner misses in BATTLE_KIND_FINAL_LAST. The match depends on the other
124 side's fighter being found as its row's offset, other * 0x60, added as an int to its
125 slot in the first row, each in a variable of its own in a block of its own (as an
126 index, gcc folds the row into (other * 3 + active) * 32); on the blocks
127 of their own of substate 0's row and of the event that wakeCounteredUp finds;
128 on announceFirstTech's MP test being written tech->mp > fighter->mp and on
129 TECH_EFFECT_END_BATTLE's damage being stored before lines[0]. */
131 BattleFighter *countered;
132 s32 index;
133
134 switch (task->state) {
135 case TASK_INIT:
136 default:
137 announceFirstTech(task, children);
138 task->nextState(task);
139 break;
140 case TASK_RUN:
141 switch (task->substate) {
142 case 0:
143 default:
144 if (children[0].task == NULL) {
145 children[0].script = WFIGHTMN_startTech(task->side, task->tech);
146 {
148
149 if (task->side != 0) {
150 fighters = FIGHTSTG_battle.state.fighters[1];
151 }
152 fighters[FIGHTSTG_battle.state.active[task->side != 0]].charge = 0;
153 }
154 task->substate++;
155 }
156 break;
157 case 1:
158 if (children[0].task == NULL) {
159 showFirstTechResult(task, children);
161 task->substate++;
162 }
163 break;
164 case 2:
165 if (children[0].task == NULL) {
167 children[0].events = FIGHTSTG_startActionEvents(task->side);
168 task->nextSubstate(task);
169 } else if (task->step != 0) {
170 task->state = 3;
171 } else if (task->damage == 0) {
173 task->state = 3;
174 } else {
175 task->setSubstate(task, 6);
176 }
177 } else {
178 children[0].events = FIGHTSTG_startActionEvents(task->side);
179 task->nextSubstate(task);
180 }
181 }
182 break;
183 case 3:
184 if (children[0].task == NULL) {
185 task->nextSubstate(task);
186 }
187 break;
188 case 4:
189 index = task->side == 0;
190 countered = ACTIVE_FIGHTER(index);
191 if (countered->flags & FIGHTER_ASLEEP) {
192 if (task->asleep != 0 && FIGHTSTG_battleFuncs.testWakeUp(SIDE_ENEMY - task->side, task->damage) != 0) {
193 wakeCounteredUp(task, children, countered, index);
194 task->substate = 8;
195 } else {
196 task->state = 3;
197 }
198 } else {
199 children[0].counter = FIGHTSTG_startCounterattack(index << 4, task->damage, 0);
200 task->substate++;
201 }
202 break;
203 case 5:
204 if (children[0].task != NULL) {
205 if (children[0].task->state != 2) {
206 break;
207 }
208 WFIGHTMN_chargeGauge(task->side, task->damage);
209 }
210 task->state = 3;
211 break;
212 case 6:
213 if (children[0].task == NULL) {
214 children[0].enemyAttack = FIGHTSTG_startEnemyAttack(1, 0);
215 task->nextSubstate(task);
216 }
217 break;
218 case 7:
219 if (children[0].task == NULL) {
220 task->setState(task, 3);
221 }
222 break;
223 case 8:
224 if (children[0].task == NULL) {
225 children[0].counter = FIGHTSTG_startCounterattack((task->side == 0) << 4, task->damage, 0);
226 task->substate = 5;
227 }
228 break;
229 }
230 break;
231 case 2:
232 case 3:
233 break;
234 }
235}
236
237/* Starts side's first technique (FIGHTSTG_updateFirstTech) */
239 FirstTech *task = createTask(FIGHTSTG_updateFirstTech, sizeof(FirstTech), sizeof(Task *));
240
241 task->side = side;
242 return task;
243}
ActionEvents * FIGHTSTG_startActionEvents(s32 side)
Starts running the current action's events for SIDE (FIGHTSTG_updateActionEvents)
BattleAction FIGHTSTG_action
the command being carried out
Definition battle.c:12
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
static BattleFighter * FIGHTSTG_getActiveFighter(s32 row)
Row's active fighter (FIGHTSTG_battle.state.fighters[row][active[row]]), as the row's offset in bytes...
Definition battle.h:497
#define TECH_EFFECT_MULTI_HIT
Definition battle.h:258
#define TECH_EFFECT_KNOCK_OUT
Definition battle.h:256
#define TECH_EFFECT_END_BATTLE
in BATTLE_KIND_UNK2: takes 70 percent of the partner's HP, ends as BATTLE_FLED
Definition battle.h:271
#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 BATTLE_KIND_FINAL_LAST
its third enemy; winning plays the ending
Definition battle.h:130
#define FIGHTER_ASLEEP
can't act or run away; a hit may wake it up
Definition battle.h:185
#define SIDE_ENEMY
Definition battle.h:178
EventQueue FIGHTSTG_events
the battle's events and their functions
Definition events.c:43
FIGHTSTG.PRO: the battle.
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 ...
EnemyAttack * FIGHTSTG_startEnemyAttack(s32 kind, s32 noKnockout)
Starts an attack on the player's active fighter (FIGHTSTG_updateEnemyAttack): kind 0 for the enemy's ...
#define TASK_RUN
Definition task.h:35
#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
static void announceFirstTech(FirstTech *task, BattleChild *children)
Picks the side's first technique and says it is used (or, for an enemy without the MP,...
Definition first_tech.c:8
static void wakeCounteredUp(FirstTech *task, BattleChild *children, BattleFighter *countered, s32 index)
Wakes up COUNTERED, the sleeping fighter the technique struck in row INDEX, says so and ends its slee...
Definition first_tech.c:101
static void takeFirstTechDamage(FirstTech *task)
Takes the damage from the other side's active fighter, queueing its knockout at 0 HP (and setting ste...
Definition first_tech.c:83
void FIGHTSTG_updateFirstTech(FirstTech *task, BattleChild *children)
A side's first technique (FIGHTSTG_startFirstTech): the partner's skills[0] or the enemy's battle tab...
Definition first_tech.c:130
static void showFirstTechResult(FirstTech *task, BattleChild *children)
Shows the technique's result (its hits, its knockout, the 70 percent of the partner's HP that TECH_EF...
Definition first_tech.c:45
FirstTech * FIGHTSTG_startFirstTech(s32 side)
Starts side's first technique (FIGHTSTG_updateFirstTech)
Definition first_tech.c:238
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
u8 effects[0x28]
by TECH_EFFECT_*: what each one does, 0 for none
Definition battle.h:283
void(* start)(u8 side, s32 tech)
FIGHTSTG_startAction.
Definition battle.h:285
s16 hitsLanded
Definition battle.h:281
s32 damage
per hit
Definition battle.h:278
u8 hits[4]
whether each hit lands
Definition battle.h:280
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(* testWakeUp)(u8 side, s32 value)
Definition battle.h:356
void(* show)()
FIGHTSTG_showMessage: (task, type, data)
Definition menu.h:182
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
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
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
FIGHTSTG_updateFirstTech's task (FIGHTSTG_startFirstTech): a side's first technique.
Definition action.h:12
u8 side
the side that uses it, 0 or 0x10
Definition action.h:14
void(* nextSubstate)(struct FirstTech *task)
Definition action.h:13
void(* nextState)(struct FirstTech *task)
Definition action.h:13
s32 state
Definition action.h:13
s32 step
Definition action.h:13
s32 damage
Definition action.h:16
s32 asleep
whether the other side's fighter was asleep
Definition action.h:17
void(* setState)(struct FirstTech *task, s32 state)
Definition action.h:13
void(* setSubstate)(struct FirstTech *task, s32 substate)
Definition action.h:13
s32 substate
Definition action.h:13
s32 lines[8]
FIGHTSTG_updateMessage's.
Definition action.h:18
s32 tech
Definition action.h:15
s16 type
0 for a free entry
Definition battle.h:110
Any task, seen through its header.
Definition task.h:62
s32 state
Definition task.h:63
A technique (TECHS, from 1: technique n is TECHS[n - 1])
Definition game_state.h:110
u16 mp
its cost
Definition game_state.h:111
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
BattleScript * WFIGHTMN_startTech(u8 actor, s32 id)
Starts the effect of actor's move id (FIGHTSTG's FIGHTSTG_createBattleScript): its kind and motions f...
Definition techs.c:150
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
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
Counterattack * counter
a counterattack (FIGHTSTG_startCounterattack)
Definition task.h:32
ActionEvents * events
the queued events (FIGHTSTG_startActionEvents)
Definition task.h:33
BattleMessageBox * message
FIGHTSTG_createMessage.
Definition task.h:18
Task * task
Definition task.h:17
BattleScript * script
a technique's (FIGHTSTG_createBattleScript)
Definition task.h:19
EnemyAttack * enemyAttack
an attack on the player's fighter (FIGHTSTG_startEnemyAttack)
Definition task.h:25