Alchemy
Loading...
Searching...
No Matches

levels.c

Go to the documentation of this file.
1/// @file
2/// Actions and Psynergy lists, characters, experience and levelling up.
3/// Part of game.c, the game object, compiled only through it.
4
5#include "../game_internal.h"
6
7/// Returns the definition of action `actionId` (its low 14 bits); an id
8/// past the table gives the first. Reached through GAME.S as
9/// BattleActGet, which every bank uses to read an ability.
11 u32 entryIndex;
12
13 entryIndex = actionId & OWNER_ACTION_ID_MASK;
14 // BUG: the bound is one past the table's 519 rows, so id 519 reads the
15 // enemy table's first bytes as an action.
16#ifdef BUGFIX
17 if (entryIndex >= 519U) {
18#else
19 if (entryIndex >= 0x208U) {
20#endif
21 entryIndex = 0;
22 }
23 return &gBattleAction_DefinitionTable[entryIndex];
24}
25
26/// Returns 1 when `actionId` is in the unit's action list. Called by the
27/// events that check whether a member knows a Psynergy
28/// (Event_ValidatePackedId).
29s32 Unit_KnowsAction(s32 owner, s32 actionId) {
30 struct BattleUnit *unit = UnitGet(owner);
31 struct OwnerActionSlot *entry;
32 s32 actionMask = OWNER_ACTION_ID_MASK;
33 s32 index = 0;
34
35 entry = unit->actionSlots;
36 do {
37 s32 currentAction = entry->encodedAction;
38
39 currentAction &= actionMask;
40 entry++;
41 if (currentAction == actionId) {
42 return 1;
43 }
44 index++;
45 } while (index <= 31);
46 return 0;
47}
48
49/// Marks on an action list entry: learned from the class, or granted by an
50/// equipped item. Plain entries were taught for good.
51enum { OWNER_ACTION_CLASS = 0x8000, OWNER_ACTION_ITEM = 0x4000 };
52
53// Slots are four-byte records, not a flat halfword array. The native view
54// preserves load scheduling; the typed view shortens the English object by
55// 52 bytes. UBFIX accesses each record through its actual declared type.
56#ifdef UBFIX
57#define PSYNERGY_ACTION_AT(slots, index) ((slots)[index].encodedAction)
58#else
59#define PSYNERGY_ACTION_AT(slots, index) (((u16 *)(slots))[(index) * 2])
60#endif
61
62/// Rebuilds a character's Psynergy list: drops the actions its class and items
63/// gave, closes up the list, adds every class action learned by its level and
64/// the action of each equipped item that grants one, and closes it up again.
65/// Writes only the unit's actionSlots; enemies (class 0) are left alone.
66/// Called whenever the class, level or equipment changes: Inventory_Equip,
67/// Unit_UpdateClass, Owner_LevelUp, Unit_LearnPsynergy and the item menu.
69 struct BattleUnit *unit;
70 struct OwnerActionSlot *abilities;
71 struct ClassDefinition *classDefinition;
72 struct ItemDefinition *itemDefinition;
73 s32 slot;
74 s32 sourceIndex;
75 u16 originFlag;
76 struct ClassAbility *classAbility;
77
78 unit = UnitGet(owner);
79 abilities = unit->actionSlots;
80 classDefinition = Class_GetDefinition(unit->classIndex);
81 if (unit->classIndex == 0)
82 return 0;
83 // Remove actions inherited from the previous class and equipment.
84 originFlag = OWNER_ACTION_CLASS;
85 for (sourceIndex = 0; sourceIndex < 32; sourceIndex++) {
86 if (PSYNERGY_ACTION_AT(abilities, sourceIndex) & originFlag)
87 PSYNERGY_ACTION_AT(abilities, sourceIndex) = 0;
88 }
89 originFlag = OWNER_ACTION_ITEM;
90 for (sourceIndex = 0; sourceIndex < 32; sourceIndex++) {
91 if (PSYNERGY_ACTION_AT(abilities, sourceIndex) & originFlag)
92 PSYNERGY_ACTION_AT(abilities, sourceIndex) = 0;
93 }
94 // Pack permanent actions at the end to leave room for class abilities.
95 for (slot = 31, sourceIndex = 31; slot >= 0;) {
96 if (PSYNERGY_ACTION_AT(abilities, slot) == 0) {
97 slot--;
98 } else {
99 PSYNERGY_ACTION_AT(abilities, sourceIndex) =
100 PSYNERGY_ACTION_AT(abilities, slot);
101 slot--;
102 sourceIndex--;
103 }
104 }
105 for (; sourceIndex >= 0; sourceIndex--)
106 PSYNERGY_ACTION_AT(abilities, sourceIndex) = 0;
107
108 // Add level-eligible class abilities, followed by equipped-item abilities.
109 originFlag = OWNER_ACTION_CLASS;
110 for (sourceIndex = 0; sourceIndex < 16; sourceIndex++) {
111 classAbility = &classDefinition->abilities[sourceIndex];
112 if (classDefinition->abilities[sourceIndex].ability == 0)
113 continue;
114 if (unit->level < classDefinition->abilities[sourceIndex].level)
115 continue;
116 slot = 0;
117 while (slot < 32 && PSYNERGY_ACTION_AT(abilities, slot) !=
118 classDefinition->abilities[sourceIndex].ability)
119 slot++;
120 if (slot != 32)
121 continue;
122 for (slot = 0; slot < 32; slot++) {
123 if (PSYNERGY_ACTION_AT(abilities, slot) == 0) {
124 PSYNERGY_ACTION_AT(abilities, slot) =
125 classAbility->ability | originFlag;
126 break;
127 }
128 }
129 if (slot == 32)
130 break;
131 }
132
133 for (sourceIndex = 0; sourceIndex < INVENTORY_SLOTS; sourceIndex++) {
134 if (unit->inventory[sourceIndex] == 0)
135 continue;
136 if (!(unit->inventory[sourceIndex] & INVENTORY_EQUIPPED))
137 continue;
138 itemDefinition = Item_GetDirect(unit->inventory[sourceIndex]);
139 if (itemDefinition->useType != ITEM_USE_TEACHES)
140 continue;
141 for (slot = 0; slot < 32; slot++) {
142 if ((PSYNERGY_ACTION_AT(abilities, slot) & OWNER_ACTION_ID_MASK) ==
143 itemDefinition->actionId)
144 break;
145 }
146 if (slot != 32)
147 continue;
148 for (slot = 0; slot < 32; slot++) {
149 if (PSYNERGY_ACTION_AT(abilities, slot) == 0) {
150 PSYNERGY_ACTION_AT(abilities, slot) =
151 itemDefinition->actionId | OWNER_ACTION_ITEM;
152 break;
153 }
154 }
155 if (slot == 32)
156 break;
157 }
158
159 // Restore a dense display list with empty slots at the end.
160 for (slot = 0, sourceIndex = 0; slot < 32;) {
161 if (PSYNERGY_ACTION_AT(abilities, slot) == 0) {
162 slot++;
163 } else {
164 PSYNERGY_ACTION_AT(abilities, sourceIndex) =
165 PSYNERGY_ACTION_AT(abilities, slot);
166 slot++;
167 sourceIndex++;
168 }
169 }
170 for (; sourceIndex < 32; sourceIndex++)
171 PSYNERGY_ACTION_AT(abilities, sourceIndex) = 0;
172 return 0;
173}
174
175/// Scratch for Owner_LevelUp, in the alternate pool.
177 s32 classIndex; ///< the unit's class, written and not read again
178 s32 level; ///< the level before this one
179 struct CharacterDefinition *growth; ///< the character's growth curves
180 u8 unk0c[0x20]; ///< never written
181};
182
183/// Teaches a character action `value` for good (or makes a class action
184/// permanent by clearing its marks), then rebuilds its list. Returns the
185/// action's place in the list, or -1 when the list is full. Called by the
186/// events that teach Psynergy, the prologue's end, the debug presets and the
187/// debug shortcut menu.
188s32 Unit_LearnPsynergy(s32 stateIndex, s32 value) {
189 struct BattleUnit *state = UnitGet(stateIndex);
190 s32 key = value & OWNER_ACTION_ID_MASK;
191 s32 found = -1;
192 s32 index;
193
194 for (index = 0; index <= 30; index++) {
195 s32 masked = state->actionSlots[index].encodedAction & OWNER_ACTION_ID_MASK;
196
197 if ((masked ^ key) == 0) {
198 state->actionSlots[index].encodedAction = masked;
199 found = index;
200 break;
201 }
202 }
203
204 if (found < 0) {
205 /* FAKEMATCH: the slot offset index * 4 + 88 is recomputed each pass as the
206 * bytes do; as state->actionSlots[index].encodedAction, 22 instructions
207 * differ in tbs-en. */
208 for (index = 0; index <= 30; index++) {
209 s32 offset = index * sizeof(state->actionSlots[0]) +
210 (s32)&((struct BattleUnit *)0)->actionSlots;
211
212 if (*(u16 *)((u8 *)state + offset) == 0) {
213 *(u16 *)((u8 *)state + offset) = key;
214 found = index;
215 break;
216 }
217 }
218 if (found < 0) {
219 return -1;
220 }
221 }
222
223 Unit_RefreshPsynergy(stateIndex);
224 for (index = 0; index <= 31; index++) {
225 if (state->actionSlots[index].encodedAction == key) {
226 break;
227 }
228 }
229 return index;
230}
231
232/// Levels the character up once if it has the experience. Returns `gains`
233/// filled with the gains, or NULL. Only GAME.S's bare veneer reaches it;
234/// nothing calls it by name.
236 struct LevelUpResult *gains) {
237 return Unit_TryLevelUp(owner, gains);
238}
239
240/// Returns character `index`'s definition: growth curves, starting level and
241/// equipment.
243 struct CharacterDefinition *base;
244
246 return &base[index];
247}
248
249/// Sets up all eight characters for a new game: names from the message table,
250/// starting equipment equipped, class and elements worked out, and levels
251/// raised to their starting level. Called by GameState_InitDefaults.
253 struct BattleUnit *unit;
254 struct CharacterDefinition *character;
255 u16 nameBuf[16];
256 s32 owner;
257 const s32 *startingOwner = gCharacter_StartingEquipOwnerIds;
258 s32 i;
259 s32 slot;
260 u8 *name;
261
262 for (owner = 0; owner <= 7; owner++) {
263 unit = UnitGet(owner);
264 Ui_AdjustValueWithoutLimitFar(owner + MsgCharacterName, nameBuf);
265 name = unit->name;
266 name[0] = nameBuf[0];
267 i = 0;
268 if (nameBuf[0] != 0) {
269 do {
270 i++;
271 if (i > 13)
272 break;
273 name[i] = nameBuf[i];
274 } while (nameBuf[i] != 0);
275 }
276 unit->name[14] = 0;
277 }
278
279 // gCharacter_StartingEquipOwnerIds lists the characters given starting
280 // equipment, ended by -1 (starting_equipment.c).
281 if (*startingOwner != -1) {
282 do {
283 unit = UnitGet(*startingOwner);
284 if (unit != 0) {
285 unit->classId = *startingOwner;
286 character = Character_GetDefinition(unit->classId);
287
288 for (i = 14; i >= 0; i--)
289 unit->inventory[i] = 0;
290
291 for (i = 0; i < sizeof(character->items) / sizeof(character->items[0]);
292 i++) {
293 slot = Inventory_AddItem(*startingOwner, character->items[i] & 0x1ff);
294 Inventory_Equip(*startingOwner, slot);
295 }
296
297 Unit_UpdateClass(*startingOwner);
298 unit->ppGauge = 0x4000;
299 unit->hpGauge = 0x4000;
300 Unit_LevelUpTo(*startingOwner, character->startingLevel);
301 UnitCalc(*startingOwner);
302 }
303 startingOwner++;
304 } while (*startingOwner != -1);
305 }
306}
307
308/// Unused reserved entry; keeps its place in the far-call table.
310
311/// Returns the experience a character needs for `level` (0 for level 0 and
312/// below); -1 for an enemy or a level above 99. Called by the levelling code
313/// and by the two status screens to show the experience to the next level.
315 struct BattleUnit *unit = UnitGet(owner);
316
317 if (unit->classIndex != 0) {
318 if (level <= 0) {
319 return 0;
320 }
322 return gCharacter_LevelExpTable[unit->classId * 99 + level - 1];
323 }
324 }
325 return -1;
326}
327
328/// Raises a character one level (up to 99), adding to each base stat the
329/// growth between the two points of its growth curve around the new level
330/// (one point every 20 levels), a twentieth of it per level with a random
331/// part. Writes the unit's level, base stats and, if short, its experience,
332/// then rebuilds its Psynergy and stats. The gains go to `gains`, which is
333/// returned.
334struct LevelUpResult *Owner_LevelUp(s32 owner, struct LevelUpResult *gains) {
335 struct BattleUnit *unit;
336 struct LevelUpWork *work;
337 u32 requiredExperience;
338 s16 growthBand;
339 s32 growthDifference;
340 s32 level;
341
342 unit = UnitGet(owner);
343 work = Runtime_BumpAllocateAlternatePool(sizeof(struct LevelUpWork));
344 work->classIndex = unit->classIndex;
345 level = unit->level;
346 work->level = level;
347 gains->level = level;
348 gains->ability = 0xffff;
349 gains->hp = 0;
350 gains->pp = 0;
351 gains->atk = 0;
352 gains->def = 0;
353 gains->agi = 0;
354 gains->luck = 0;
355 if (level < 99) {
356 unit->level++;
357 gains->level = level + 1;
358 requiredExperience = Unit_GetExperienceForLevel(owner, unit->level);
359 if (requiredExperience != -1 && unit->experience < requiredExperience)
360 unit->experience = requiredExperience;
361 work->growth = Character_GetDefinition(owner);
362 // Level 1 starts from the curve's first point.
363 if (gains->level == 1) {
364 gains->hp += work->growth->hp[0];
365 gains->pp += work->growth->pp[0];
366 gains->atk += work->growth->atk[0];
367 gains->def += work->growth->def[0];
368 gains->agi += work->growth->agi[0];
369 gains->luck += work->growth->luck[0];
370 }
371 // Each twenty-level band interpolates between adjacent growth points.
372 // Keep one RNG draw per stat, in HP, PP, attack, defense, agility, luck
373 // order.
374 growthBand = gains->level / 20;
375 CLAMP(growthBand, 0, 4);
376 growthDifference =
377 work->growth->hp[growthBand + 1] - work->growth->hp[growthBand];
378 gains->hp += ((Random16() * 20 >> 16) + growthDifference) / 20;
379 growthDifference =
380 work->growth->pp[growthBand + 1] - work->growth->pp[growthBand];
381 gains->pp += ((Random16() * 20 >> 16) + growthDifference) / 20;
382 growthDifference =
383 work->growth->atk[growthBand + 1] - work->growth->atk[growthBand];
384 gains->atk += ((Random16() * 20 >> 16) + growthDifference) / 20;
385 growthDifference =
386 work->growth->def[growthBand + 1] - work->growth->def[growthBand];
387 gains->def += ((Random16() * 20 >> 16) + growthDifference) / 20;
388 growthDifference =
389 work->growth->agi[growthBand + 1] - work->growth->agi[growthBand];
390 gains->agi += ((Random16() * 20 >> 16) + growthDifference) / 20;
391 growthDifference =
392 work->growth->luck[growthBand + 1] - work->growth->luck[growthBand];
393 gains->luck += ((Random16() * 20 >> 16) + growthDifference) / 20;
394 // Commit the six gains before rebuilding Psynergy and derived stats.
395 unit->baseHp += gains->hp;
396 unit->basePp += gains->pp;
397 unit->baseAttack += gains->atk;
398 unit->baseDefense += gains->def;
399 unit->baseAgility += gains->agi;
400 unit->baseLuck += gains->luck;
401 unit->baseActionCount = 1;
402 unit->baseHpRegen = 0;
403 unit->basePpRegen = 0;
405 UnitCalc(owner);
406 }
407 MemFree(work);
408 return gains;
409}
410
411/// Levels the character up once if its experience reaches the next level.
412/// Returns `gains` filled with the gains, or NULL. Called after a battle by
413/// Battle_AwardSpoils, once for each level a member reaches.
414struct LevelUpResult *Unit_TryLevelUp(s32 owner, struct LevelUpResult *gains) {
415 struct BattleUnit *unit;
416
417 unit = UnitGet(owner);
418 if ((unit->experience >=
419 Unit_GetExperienceForLevel(owner, unit->level + 1)) &&
420 (Owner_LevelUp(owner, gains) != NULL)) {
421 return gains;
422 }
423 return 0;
424}
425
426/// Levels character `owner` up one level at a time until `targetLevel`, then
427/// recomputes its stats. Called by Party_InitCharacters for the starting
428/// levels, and by the debug menus and presets.
429void Unit_LevelUpTo(s32 owner, s32 targetLevel) {
430 // Each level's gains are discarded.
431 struct LevelUpResult gains;
432 s32 currentLevel = UnitGet(owner)->level;
433
434 while (currentLevel < targetLevel) {
435 Owner_LevelUp(owner, &gains);
436 currentLevel++;
437 }
438 UnitCalc(owner);
439}
440
441#undef PSYNERGY_ACTION_AT
@ OWNER_ACTION_ID_MASK
Definition battle_unit.h:14
struct CharacterDefinition gCharacter_DefinitionTable[]
void Ui_AdjustValueWithoutLimitFar(s32 message, u16 *buf)
void Unit_UpdateClass(s32 ownerId)
Works out a character's class again after its Djinn change, then its Psynergy list and its base eleme...
Definition classes.c:232
struct ClassDefinition * Class_GetDefinition(s32 classId)
Returns class classId's definition: its series, element requirements, stat multipliers and the Psyner...
Definition classes.c:223
struct BattleAct gBattleAction_DefinitionTable[]
u32 gCharacter_LevelExpTable[]
What every part of the game object shares: its includes and the inventory helper two parts use.
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
s32 Inventory_AddItem(s32 owner, s32 itemId)
Gives a unit one item, joining its first matching stack (up to 30) or taking the first free slot.
Definition inventory.c:144
s32 Inventory_Equip(s32 owner, s32 slot)
Equips the item in slot, clearing the equipped bit of the item of the same type it replaces.
Definition inventory.c:257
struct ItemDefinition * Item_GetDirect(s32 item)
Returns item item's definition; an inventory entry may be passed, its equipped and quantity bits are ...
Definition inventory.c:10
#define ITEM_USE_TEACHES
Not used up: equipped, it teaches its actionId as Psynergy.
Definition item.h:38
@ INVENTORY_EQUIPPED
Definition item.h:17
@ INVENTORY_SLOTS
Definition item.h:23
u32 Unit_GetExperienceForLevel(s32 owner, s32 level)
Returns the experience a character needs for level (0 for level 0 and below); -1 for an enemy or a le...
Definition levels.c:314
#define PSYNERGY_ACTION_AT(slots, index)
Definition levels.c:59
s32 Unit_KnowsAction(s32 owner, s32 actionId)
Returns 1 when actionId is in the unit's action list.
Definition levels.c:29
UNUSED void Owner_LevelNoOp(void)
Unused reserved entry; keeps its place in the far-call table.
Definition levels.c:309
struct LevelUpResult * Owner_LevelUp(s32 owner, struct LevelUpResult *gains)
Raises a character one level (up to 99), adding to each base stat the growth between the two points o...
Definition levels.c:334
void Unit_LevelUpTo(s32 owner, s32 targetLevel)
Levels character owner up one level at a time until targetLevel, then recomputes its stats.
Definition levels.c:429
s32 Unit_RefreshPsynergy(s32 owner)
Rebuilds a character's Psynergy list: drops the actions its class and items gave, closes up the list,...
Definition levels.c:68
struct CharacterDefinition * Character_GetDefinition(s32 index)
Returns character index's definition: growth curves, starting level and equipment.
Definition levels.c:242
struct LevelUpResult * Unit_TryLevelUp(s32 owner, struct LevelUpResult *gains)
Levels the character up once if its experience reaches the next level.
Definition levels.c:414
s32 Unit_LearnPsynergy(s32 stateIndex, s32 value)
Teaches a character action value for good (or makes a class action permanent by clearing its marks),...
Definition levels.c:188
struct LevelUpResult * Unit_CheckLevelUp(s32 owner, struct LevelUpResult *gains)
Levels the character up once if it has the experience.
Definition levels.c:235
void Party_InitCharacters(void)
Sets up all eight characters for a new game: names from the message table, starting equipment equippe...
Definition levels.c:252
@ OWNER_ACTION_CLASS
Definition levels.c:51
@ OWNER_ACTION_ITEM
Definition levels.c:51
struct BattleAct * BattleAction_GetDirect(s32 actionId)
Returns the definition of action actionId (its low 14 bits); an id past the table gives the first.
Definition levels.c:10
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
Definition macros.h:23
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void MemFree(void *buffer)
#define NULL
Definition bilibin.h:6
const s32 gCharacter_StartingEquipOwnerIds[6]
Characters given starting equipment, terminated by -1.
An ability's definition, a row of gBattleAction_DefinitionTable: its targeting, kind,...
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u16 baseDefense
before equipment, Djinn, class and stages
u16 baseAttack
before equipment, Djinn, class and stages
u16 baseAgility
before equipment, Djinn, class and stages
s16 hpGauge
hp / maxHp in 0..0x4000; 1 while any HP remains
u8 name[0x0f]
The name, one byte a character, ending in 0.
s16 ppGauge
pp / maxPp in 0..0x4000; 1 while any PP remains
u8 baseActionCount
Actions a round before equipment: the low four bits are read.
u8 baseHpRegen
HP regained each turn before equipment; 0 for a character.
struct OwnerActionSlot actionSlots[32]
The action list: Psynergy taught for good, then the class's and the equipment's (Unit_RefreshPsynergy...
u8 baseLuck
before equipment, Djinn and class
u8 classId
Who the unit is: a character's id (ISAAC to JENNA, below 8) or an enemy's id (BattleUnitSet).
s16 basePp
before equipment, Djinn and class (UnitCalc)
u32 experience
a character's experience points
u8 basePpRegen
PP regained each turn before equipment and lighthouses.
u8 classIndex
The character's class, worked out from its Djinn (Unit_UpdateClass); 0 marks an enemy,...
s16 baseHp
before equipment, Djinn and class (UnitCalc)
u8 level
1 to 99 for a character
u16 inventory[15]
Items held, one entry each: bits 15..11 quantity | 10 broken | 9 equipped | 8..0 item id (INVENTORY_*...
A character's definition: the growth curves of its stats, its element bonus, starting level and start...
Definition character.h:17
u16 items[13]
The starting items, each added and equipped at a new game; the low nine bits are the item.
Definition character.h:37
s16 hp[6]
The growth curves: each stat at levels 0, 20, 40, 60, 80 and 100.
Definition character.h:23
u8 startingLevel
the level a new game raises the character to
Definition character.h:33
An ability a class teaches, and the level it is learned at.
Definition character.h:42
u8 level
the level it is taught at
Definition character.h:44
u8 ability
the action taught, 0 for none
Definition character.h:43
A class: its series, the element levels it needs, its stat multipliers and the abilities it teaches.
Definition character.h:50
struct ClassAbility abilities[16]
the Psynergy the class teaches
Definition character.h:64
An item's definition: its price, type, who can equip it, its bonuses and unleash, its effects and the...
Definition item.h:104
u8 useType
what using it costs (ITEM_USE_), or 0 for nothing
Definition item.h:113
u16 actionId
the ability used, or taught as Psynergy
Definition item.h:120
A level up's result: the level reached, an ability learned and the gain in each stat.
Definition character.h:136
Scratch for Owner_LevelUp, in the alternate pool.
Definition levels.c:176
s32 level
the level before this one
Definition levels.c:178
struct CharacterDefinition * growth
the character's growth curves
Definition levels.c:179
u8 unk0c[0x20]
never written
Definition levels.c:180
s32 classIndex
the unit's class, written and not read again
Definition levels.c:177
An entry in a unit's action list: the action's id (OWNER_ACTION_ID_MASK) and marks for an action its ...
Definition battle_unit.h:19
u16 encodedAction
bits: 15 from the class | 14 from an equipped item | 13..0 action id.
Definition battle_unit.h:22
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
void UnitCalc(s32 owner)
Recomputes a unit's stats from its base stats, equipment, set Djinn, class and battle stat levels,...
Definition units.c:149
struct BattleUnit * UnitGet(u32 owner)
Returns the unit record of owner: 0 to 7 are the playable characters in the game state,...
Definition units.c:73