Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
techs.c
Go to the documentation of this file.
1/* What FIGHTSTG asks WFIGHTMN about techniques: the final battles' records,
2 the gauge, the start of a technique and its idle motions, and the damage
3 limits of the special battles. */
4
6
7/* In BATTLE_KIND_FINAL, keeps the partner's technique ID in
8 FIGHTSTG_battle.state.tech when its script is not 5 or 12 and it has an effect
9 (not 0-1, 9-10 or 12) or an element;
10 WFIGHTMN_bringLastEnemy makes technique 440 from it */
11void WFIGHTMN_recordTech(u8 side, s32 id) {
12 TechData *info = &TECHS[id - 1];
13 s32 flag;
14 u8 kind;
15
16 if (side == 0 && FIGHTSTG_battle.state.kind == BATTLE_KIND_FINAL) {
17 flag = 0;
18 if (info->script != 5 && info->script != 12) {
19 kind = info->effect;
20 if (!(kind <= 1 || (kind >= 9 && kind <= 10) || kind == 12)) {
21 flag = 1;
22 }
23 if (info->element >= ELEMENT_FIRST) {
24 flag = 1;
25 }
26 if (flag) {
28 }
29 }
30 }
31}
32
33/* Adds what damage gives to the current partner's gauge
34 (BATTLE_SETUP.gauges), up to 1000 */
35void WFIGHTMN_chargeGauge(u8 side, s32 damage) {
38
39 if (side != 0 && damage != 0 && unit->hp != 0 && unit->temporary == 0) {
41 if (BATTLE_SETUP.gauges[member] >= 1000) {
42 BATTLE_SETUP.gauges[member] = 1000;
44 }
45 }
46}
47
48/* Picks the script of the partner's technique: 8 with the triple hit, 6 with
49 an action effect or a weapon of the enemy's family, else its own one */
50static inline void choosePartnerScript(BattleScript *task, TechData *info, BattleStats *own, BattleStats *other) {
51 s32 i;
52
53 if (info->script == 5) {
54 if (own->tripleHit != 0) {
55 task->index = 8;
56 task->effect = info->scriptEffect;
57 task->sound = info->scriptSound;
58 } else {
59 for (i = 2; i < 13; i++) {
60 if (FIGHTSTG_action.effects[i] != 0) {
61 task->index = 6;
63 task->sound = WFIGHTMN_actionEffects[i - 2].sound;
64 break;
65 }
66 }
67 if (task->index == 0) {
68 for (i = 0; i < 3; i++) {
69 if (own->weaponFamilies[i] >= FAMILY_FIRST && own->weaponFamilies[i] == other->family) {
70 task->index = 6;
71 task->effect = info->scriptEffect;
72 task->sound = info->scriptSound;
73 break;
74 }
75 }
76 if (task->index == 0) {
77 task->index = info->script;
78 task->effect = info->scriptEffect;
79 task->sound = info->scriptSound;
80 }
81 }
82 }
83 } else {
84 if (info->effect < TECH_EFFECT_FIRST && info->icon == TECH_PHYSICAL && info->script == 6 && own->tripleHit != 0) {
85 task->index = 8;
86 } else {
87 task->index = info->script;
88 }
89 task->effect = info->scriptEffect;
90 task->sound = info->scriptSound;
91 if (info->element >= ELEMENT_FIRST || (info->family >= FAMILY_FIRST && info->family == other->family)) {
92 task->stage = info->scriptStage;
93 } else {
94 task->stage = -1;
95 }
96 }
97}
98
99/* Sets the fighters' idle motions for the damage a technique does; an attack
100 also counts for the final battles, anything else ends the enemy's weakness */
101static inline void setTechIdleMotions(TechData *info, u8 actor, s32 id, s32 damage) {
102 if (info->icon == TECH_PHYSICAL || info->icon == TECH_MAGIC) {
103 WFIGHTMN_recordTech(actor, id);
104 WFIGHTMN_countHit(actor, damage);
105 WFIGHTMN_setIdleMotion(SIDE_ENEMY - actor, damage);
108 }
109 } else {
111 WFIGHTMN_setIdleMotion(actor, damage);
112 }
113}
114
115/* Returns what a technique that does not attack heals, as negative damage */
116static inline s32 getHealDamage(u8 actor, s32 id) {
117 switch (id) {
118 case 0x64:
119 case 0x177:
120 return -9999;
121 case 0xB8:
122 case 0xB9:
123 case 0xBA:
124 case 0xBB:
125 case 0xBC:
126 case 0x190:
127 return -FIGHTSTG_battleFuncs.computeHeal(actor, id);
128 default:
129 return 0;
130 }
131}
132
133/* Gives the enemy's technique its own script, and its stage effect when it
134 has an element or the target's family */
135static inline void chooseEnemyScript(BattleScript *task, TechData *info, BattleStats *other) {
136 task->index = info->script;
137 task->effect = info->scriptEffect;
138 task->sound = info->scriptSound;
139 if (info->element >= ELEMENT_FIRST || (info->family >= FAMILY_FIRST && info->family == other->family)) {
140 task->stage = info->scriptStage;
141 } else {
142 task->stage = -1;
143 }
144}
145
146/* Starts the effect of actor's move id (FIGHTSTG's FIGHTSTG_createBattleScript): its kind
147 and motions from TECHS (choosePartnerScript, chooseEnemyScript), which hits
148 land from FIGHTSTG_action, then sets the fighters' idle motions for the
149 damage it does (setTechIdleMotions) */
151 TechData *info;
152 s32 side;
153 BattleStats *own;
154 BattleStats *other;
155 BattleScript *task;
156 BattleFighter *units;
157 s32 damage;
158 s32 i;
159
160 side = actor != 0;
161 info = &TECHS[id - 1];
165 task->enemy = actor;
166 if (actor == 0) {
167 choosePartnerScript(task, info, own, other);
168 if (task->stage <= 0) {
169 if (own->element >= ELEMENT_FIRST) {
170 s32 n;
171 s32 m;
172
173 if (info->element >= ELEMENT_FIRST) {
174 n = info->element - ELEMENT_FIRST;
175 } else {
176 n = own->element - ELEMENT_FIRST;
177 }
178 m = n * 3 + 0x21;
179 if (own->elementPower >= 0x40) {
180 task->stage = m + 1;
181 } else {
182 task->stage = m;
183 }
184 } else if (info->family < FAMILY_FIRST) {
185 for (i = 0; i < 3; i++) {
186 if (own->weaponFamilies[i] == 2 && other->family == 2) {
187 task->stage = 0x35;
188 break;
189 }
190 if (own->weaponFamilies[i] == 10 && other->family == 10) {
191 task->stage = 0x36;
192 break;
193 }
194 }
195 }
196 }
197 } else {
198 chooseEnemyScript(task, info, other);
199 }
200 units = FIGHTSTG_battle.state.fighters[1 - side];
201 if (id == 0x1B5) {
202 damage = 9999;
203 task->hits[3] = 1;
204 } else if (info->effect == TECH_EFFECT_DOUBLE_MAGIC) {
205 if (FIGHTSTG_action.hitsLanded != 0) {
207 if (units[FIGHTSTG_battle.state.active[1 - side]].hp - damage <= 0) {
208 if (FIGHTSTG_action.hitsLanded == 1) {
209 task->hits[0] = 3;
210 } else {
211 task->hits[0] = 0;
212 }
213 task->hits[3] = 2;
214 } else {
215 for (i = 0; i < 2; i++) {
216 if (FIGHTSTG_action.hits[i] != 0) {
217 task->hits[i * 3] = 0;
218 } else {
219 task->hits[i * 3] = 3;
220 }
221 }
222 }
223 } else {
224 damage = 0;
225 task->hits[0] = 3;
226 task->hits[3] = 3;
227 }
230 if (units[FIGHTSTG_battle.state.active[1 - side]].hp - damage <= 0) {
231 for (i = 0; i < FIGHTSTG_action.hitsLanded - 1; i++) {
232 if (FIGHTSTG_action.hits[i] != 0) {
233 task->hits[i] = 0;
234 } else {
235 task->hits[i] = 3;
236 }
237 }
238 task->hits[3] = 2;
239 } else {
240 for (i = 0; i < FIGHTSTG_action.hitCount - 1; i++) {
241 if (FIGHTSTG_action.hits[i] != 0) {
242 task->hits[i] = 0;
243 } else {
244 task->hits[i] = 3;
245 }
246 }
247 if (FIGHTSTG_action.hits[i] != 0) {
248 task->hits[3] = 1;
249 } else {
250 task->hits[3] = 3;
251 }
252 }
254 task->hits[3] = 2;
255 damage = 9999;
257 task->hits[3] = 1;
258 damage = FIGHTSTG_action.damage;
259 } else if (info->icon == TECH_PHYSICAL || info->icon == TECH_MAGIC) {
260 if (FIGHTSTG_action.hits[0] != 0) {
261 if (units[FIGHTSTG_battle.state.active[1 - side]].hp - FIGHTSTG_action.damage <= 0) {
262 task->hits[3] = 2;
263 } else {
264 task->hits[3] = 1;
265 }
266 damage = FIGHTSTG_action.damage;
267 } else {
268 task->hits[3] = 3;
269 damage = 0;
270 }
271 } else {
272 damage = getHealDamage(actor, id);
273 }
274 setTechIdleMotions(info, actor, id, damage);
275 return task;
276}
277
278/* Sets the idle motion of side id >> 4's fighter: 1 (weak) if damage
279 leaves it with a quarter of its HP or less; returns whether it did */
281 u32 side = id >> 4;
283 BattleMenuChildren *children = menu->children;
284 BattleFighter *unit;
285
286 if (id == 0x10 && FIGHTSTG_battle.state.kind == BATTLE_KIND_FINAL_LAST) {
287 children->models->setIdleMotion(children->models, 0x10, FIGHTSTG_battle.state.weakened);
288 return 1;
289 }
291 if (unit->hp - damage <= unit->maxHp / 4) {
292 children->models->setIdleMotion(children->models, id, 1);
293 return 1;
294 }
295 children->models->setIdleMotion(children->models, id, 0);
296 return 0;
297}
298
299/* In BATTLE_KIND_FINAL_LAST, the partner's third hit that does damage weakens
300 the enemy (FIGHTSTG's FIGHTSTG_weakenEnemy) */
301void WFIGHTMN_countHit(u8 side, s32 damage) {
302 if (FIGHTSTG_battle.state.kind == BATTLE_KIND_FINAL_LAST && side == 0 && FIGHTSTG_battle.state.weakened == 0 && damage != 0) {
303 if (++FIGHTSTG_battle.state.hitCount >= 3) {
306 }
307 }
308}
309
310/* In BATTLE_KIND_FINAL_LAST, anything the partner does but an attack ends
311 the enemy's weakness (FIGHTSTG's FIGHTSTG_endEnemyWeakness) */
317
318/* In BATTLE_KIND_ESCAPE and BATTLE_KIND_UNK2, cuts the damage that the
319 partner's hits do so that the enemy keeps at least an eleventh of its HP;
320 in BATTLE_KIND_NO_DAMAGE the partner does none */
321s32 WFIGHTMN_limitDamage(u8 side, s32 damage, s32 hits) {
322 s32 other = side == 0;
324 s32 limit;
325 s32 total;
326
327 switch (FIGHTSTG_battle.state.kind) {
329 case BATTLE_KIND_UNK2:
330 if (side == 0) {
331 limit = unit->maxHp / 11;
332 if (hits != 0) {
333 /* the match depends on total, which multiplies before the
334 branches */
335 total = damage * hits;
336 if (unit->hp > limit) {
337 if (unit->hp - total < limit) {
338 damage = (unit->hp - limit) / hits;
339 }
340 } else {
341 damage = 0;
342 }
343 } else if (unit->hp > limit) {
344 if (unit->hp - damage < limit) {
345 damage = unit->hp - limit;
346 }
347 } else {
348 damage = 0;
349 }
350 }
351 break;
353 if (side == 0) {
354 damage = 0;
355 }
356 break;
357 }
358 return damage;
359}
void FIGHTSTG_queueBlast(void)
Queues the partner's digivolution for the battle (event 18), now.
Definition battle.c:90
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
void FIGHTSTG_weakenEnemy(void)
Weakens the enemy in BATTLE_KIND_FINAL_LAST: halves its boosts of stats 1 and 2 and queues the end (e...
Definition battle.c:160
BattleFuncs FIGHTSTG_battleFuncs
the battle's stats and the functions that compute with them
Definition battle.c:25
void FIGHTSTG_endEnemyWeakness(void)
Ends the enemy's weakness now: its queued event 24 runs next.
Definition battle.c:173
#define TECH_EFFECT_DOUBLE_MAGIC
two magic hits, as techniques 0x1B9 and 0x1BA
Definition battle.h:267
#define BATTLE_KIND_ESCAPE
the enemy runs away under a tenth of its HP
Definition battle.h:125
#define TECH_EFFECT_MULTI_HIT
Definition battle.h:258
#define TECH_EFFECT_FIRST
A technique's effect (TechData.effect), which FIGHTSTG_applyTechEffect carries out when its hit lands...
Definition battle.h:251
#define FAMILY_FIRST
Definition battle.h:39
#define TECH_MAGIC
FIGHTSTG_rollMagicHit and FIGHTSTG_computeMagicDamage.
Definition battle.h:43
#define BATTLE_KIND_UNK2
the enemy keeps an eleventh of its HP
Definition battle.h:126
#define TECH_EFFECT_KNOCK_OUT
Definition battle.h:256
#define BATTLE_KIND_NO_DAMAGE
the partner's hits do no damage
Definition battle.h:127
#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 TECH_EFFECT_DRAIN
HP, in 128ths of the damage.
Definition battle.h:257
#define TECH_PHYSICAL
TechData.icon's kinds of attack.
Definition battle.h:42
#define BATTLE_KIND_FINAL
battle 0x144, the last one: its first enemy
Definition battle.h:128
#define BATTLE_KIND_FINAL_LAST
its third enemy; winning plays the ending
Definition battle.h:130
#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
#define BATTLE_TASK_MENU
The ids that the battle's tasks register with, for the others to find them (TASK_REGISTRY....
Definition types.h:18
BattleScript * FIGHTSTG_createBattleScript(void)
Creates a battle script, which plays a technique (FIGHTSTG_updateBattleScript)
signed int s32
Definition common.h:11
unsigned int u32
Definition common.h:12
unsigned char u8
Definition common.h:8
GameState GAME
The save data, the game mode and the methods.
Definition state.c:64
TechData TECHS[443]
The techniques, from 1: technique n is TECHS[n - 1].
Definition items.c:906
BattleSetup BATTLE_SETUP
Definition items.c:886
WFIGHTMN.PRO: the battle's sub-overlay.
TaskRegistry TASK_REGISTRY
Definition registry.c:122
s32 drain
the HP or MP that TECH_EFFECT_DRAIN or TECH_EFFECT_DRAIN_MP takes
Definition battle.h:279
u8 effects[0x28]
by TECH_EFFECT_*: what each one does, 0 for none
Definition battle.h:283
s16 hitCount
rolled in hits
Definition battle.h:282
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
s32 hitDamage[2]
TECH_EFFECT_DOUBLE_MAGIC's.
Definition battle.h:284
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 temporary
id is a temporary Digimon
Definition battle.h:202
s32(* getGaugeGain)(s32 damage)
from the partner's damage, up to 1000
Definition battle.h:360
s32(* computeHeal)(u8 side, s32 id)
Definition battle.h:336
BattleStats *(* computeStats)(u8 side, s32 which, s32 index)
Definition battle.h:331
The battle menu's children.
The battle menu (WFIGHTMN_start), registered as BATTLE_TASK_MENU.
void * children
A fighter's battle script (FIGHTSTG_updateBattleScript): a list of s16 commands in an archive entry o...
Definition effect.h:144
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
s16 gauges[8]
filled in battle, up to 1000
Definition game_state.h:393
s8 hitCount
BATTLE_KIND_FINAL_LAST: the partner's hits that did damage.
Definition battle.h:232
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
u8 weakened
BATTLE_KIND_FINAL_LAST: the enemy is weakened (FIGHTSTG_weakenEnemy)
Definition battle.h:233
s16 tech
a technique id, set by WFIGHTMN
Definition battle.h:231
A side's stats as FIGHTSTG_computeStats works them out.
Definition battle.h:305
u8 tripleHit
plain physical techniques hit 3 times for 0.4 of the damage
Definition battle.h:317
u8 weaponFamilies[3]
from the equipment, as are the ones after
Definition battle.h:313
u8 elementPower
Definition battle.h:315
u8 element
the accessory's, for techniques without one
Definition battle.h:314
BattleState state
Definition battle.h:240
s32(* getPartyMember)(u32 index)
Definition game_state.h:24
GameFuncs funcs
Definition game_state.h:582
void(* setIdleMotion)(struct Models *task, s32 id, s32 motion)
Definition model.h:293
void *(* find)(s32 id, s32 key1, s32 key2)
Definition task.h:18
TaskFuncs funcs
Definition task.h:76
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 effect
TECH_EFFECT_* (fightstg/battle.h), under TECH_EFFECT_FIRST none.
Definition game_state.h:119
u8 family
FAMILY_FIRST and up, under it none.
Definition game_state.h:118
u8 element
ELEMENT_FIRST and up, under it none.
Definition game_state.h:116
u8 icon
a frame of the menu sprites, from 0x37
Definition game_state.h:113
u8 scriptStage
its script's stage (BattleScript.stage)
Definition game_state.h:122
u8 script
its script in the user's archive (BattleScript.index); 5 and 12 are special
Definition game_state.h:125
static s32 getHealDamage(u8 actor, s32 id)
Returns what a technique that does not attack heals, as negative damage.
Definition techs.c:116
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
static void chooseEnemyScript(BattleScript *task, TechData *info, BattleStats *other)
Gives the enemy's technique its own script, and its stage effect when it has an element or the target...
Definition techs.c:135
static void choosePartnerScript(BattleScript *task, TechData *info, BattleStats *own, BattleStats *other)
Picks the script of the partner's technique: 8 with the triple hit, 6 with an action effect or a weap...
Definition techs.c:50
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_recordTech(u8 side, s32 id)
In BATTLE_KIND_FINAL, keeps the partner's technique ID in FIGHTSTG_battle.state.tech when its script ...
Definition techs.c:11
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
static void setTechIdleMotions(TechData *info, u8 actor, s32 id, s32 damage)
Sets the fighters' idle motions for the damage a technique does; an attack also counts for the final ...
Definition techs.c:101
void WFIGHTMN_endWeakness(u8 side)
In BATTLE_KIND_FINAL_LAST, anything the partner does but an attack ends the enemy's weakness (FIGHTST...
Definition techs.c:312
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
ScriptLook WFIGHTMN_actionEffects[]
WFIGHTMN_startTech's effects (BattleScript.effect and sound) by the first of FIGHTSTG_action....
Definition wfightmn_2.c:58