Alchemy
Loading...
Searching...
No Matches

party.c

Go to the documentation of this file.
1/// @file
2/// Enemy units, the active party, coins and counters, and summons.
3/// Part of game.c, the game object, compiled only through it.
4
5#include "../game_internal.h"
6
7// The letter that tells apart enemies of one kind: digits from 1 abroad, the
8// alphabet in Japan.
9#if (LANGUAGE != LANGUAGE_JAPANESE)
10#define ENEMY_SUFFIX_FIRST '1'
11#define ENEMY_SUFFIX_LAST 8
12#else
13#define ENEMY_SUFFIX_FIRST 'A'
14#define ENEMY_SUFFIX_LAST 25
15#endif
16
17/// Fills battle unit `unitId` (0x80 to 0x86) with enemy `enemyId`: stats,
18/// name with its suffix letter, the items it carries, rewards and elements.
19/// Enemies 158 to 171 fight on the party's side. Returns 0 for an id out of
20/// range. Called by the battle set-up (Battle_RunEncounter,
21/// BattleFormation_BuildEnemyList) and by BattleTargetExec when an enemy calls
22/// for help.
23/// XXX: which enemies 158 to 171 are, and when they join the party's side, is
24/// unknown; the encounter tables that place them would say.
25s32 BattleUnitSet(s32 unitId, s32 enemyId, s32 suffix) {
26 struct BattleUnit *unit;
27 const struct EnemyDefinition *enemy;
28 u16 name[15];
29 s32 i;
30 u32 index;
31 s32 q;
32 s32 count;
33
34 index = enemyId - 8;
35 if (unitId <= 127)
36 return 0;
37 if (unitId > 134)
38 return 0;
39 if (index > 242)
40 return 0;
41 unit = UnitGet(unitId);
43 if (index > 164)
44 index = 0;
45 enemy = &gEnemy_Definitions[index];
46 unit->level = enemy->level;
47 unit->baseHp = enemy->hp;
48 unit->hp = enemy->hp;
49 unit->maxHp = enemy->hp;
50 unit->basePp = enemy->pp;
51 unit->pp = enemy->pp;
52 unit->maxPp = enemy->pp;
53 unit->hpGauge = 0x4000;
54 unit->ppGauge = 0x4000;
55 unit->baseAttack = enemy->atk;
56 unit->baseDefense = enemy->def;
57 unit->baseAgility = enemy->agi;
58 unit->baseLuck = enemy->luck;
59 unit->baseActionCount = enemy->turns;
60 unit->baseHpRegen = enemy->hpRegen;
61 unit->basePpRegen = enemy->ppRegen;
62 UiText_DecodeMessageFar(index + MsgEnemyName, name, 15);
63 for (i = 0; i < 14 && name[i] != 0; i++)
64 unit->name[i] = name[i];
65 // Enemies of one kind are told apart by a letter after the name; past the
66 // last letter the name stays bare.
67 if (suffix <= ENEMY_SUFFIX_LAST) {
68 unit->name[i] = ENEMY_SUFFIX_FIRST + suffix;
69 i++;
70 }
71 unit->name[i] = 0;
72 unit->name[14] = 0;
73 count = 0;
74 for (i = 0; i < 4; i++) {
75 if (enemy->items[i] != 0) {
76 for (q = 0; q < enemy->counts[i]; q++) {
77 if (count < INVENTORY_SLOTS)
78 unit->inventory[count++] = enemy->items[i];
79 }
80 }
81 }
82 unit->rewards = enemy->rewards;
83 unit->classIndex = 0;
84 unit->classId = enemyId;
85#ifdef UBFIX
87#else
88 Unit_CalcBaseElements(unitId, (s16 (*)[2])unit->baseElement);
89#endif
90 UnitCalc(unitId);
91 unit->side = BATTLE_UNIT_ENEMY;
92 switch (unit->classId) {
93 case 158:
94 case 159:
95 case 160:
96 case 161:
97 case 162:
98 case 163:
99 case 164:
100 case 165:
101 case 166:
102 case 167:
103 case 168:
104 case 169:
105 case 170:
106 case 171:
107 unit->side = BATTLE_UNIT_PARTY;
108 break;
109 }
110 return 1;
111}
112
113// The party: flags 0 to 7 say who is in it, and gGameState.activeOwners
114// lists them in order.
115
116/// Returns the number of party members, counted from game flags 0 to 7.
118 s32 owner;
119 s32 count;
120
121 count = 0;
122 owner = 0;
123 do {
124 if (GameFlag_Test(owner) != 0)
125 count++;
126 owner++;
127 } while (owner <= 7);
128 return count;
129}
130
131/// Adds character `owner` to the end of the party: sets its game flag and
132/// appends it to gGameState.activeOwners unless it is already listed.
133/// Returns the party size. Called by the scenes where a character joins, by
134/// the member chooser and the file select screen, and by the debug presets.
136 s32 partySize = Party_CountActiveOwners();
137 s32 partyIndex;
138
139 GameFlag_SetBit(owner);
140 partyIndex = 0;
141 while (partyIndex < partySize) {
142 if (gGameState.activeOwners[partyIndex] == owner)
143 return partySize;
144 partyIndex++;
145 }
146 gGameState.activeOwners[partyIndex] = owner;
147 return partySize + 1;
148}
149
150/// Takes character `owner` out of the party: clears its game flag and closes
151/// the gap it leaves in gGameState.activeOwners. Returns the party size.
152/// Called by the scenes where a character leaves, by the member chooser and
153/// the file select screen, and by the debug presets.
155 s32 partySize = Party_CountActiveOwners();
156 s32 removedIndex;
157 s32 partyIndex;
158
159 GameFlag_ClearBit(owner);
160 for (removedIndex = 0; removedIndex < partySize; removedIndex++) {
161 if (gGameState.activeOwners[removedIndex] == owner)
162 break;
163 }
164 for (partyIndex = removedIndex; partyIndex < partySize - 1; partyIndex++)
165 gGameState.activeOwners[partyIndex] =
166 gGameState.activeOwners[partyIndex + 1];
168}
169
170/// Writes the party members to `owners`, ending with 0xff, and returns how
171/// many there are. Every screen that lists the party starts here: the menus,
172/// the shops, the inn and the party inventory searches.
174 s32 count = 0;
175
176 if (owners != NULL) {
177 s32 index;
178
179 count = Party_CountActiveOwners();
180 index = 0;
181 if (count != 0) {
182 do {
183 *owners++ = gGameState.activeOwners[index];
184 index++;
185 } while (index != count);
186 }
187 *owners = 0xff;
188 }
189 return count;
190}
191
192/// Adds `amount` to the party's coins, kept between 0 and 999999, and returns
193/// the new total. Called by the shops, the inn and the sanctum to charge,
194/// by the battle spoils to pay, and by the Lucky Dice game.
196 s32 value;
197 struct GameState *work;
198 struct GameState *store;
199
200 work = &gGameState;
201 value = work->coins;
202 value += amount;
203 store = work;
204 if (value > 999999) {
205 value = 999999;
206 }
207 if (value < 0) {
208 value = 0;
209 }
210 work = store;
211 work->coins = value;
212 return value;
213}
214
215/// The party's Djinn recovery table as the summon list reads it: a mask of
216/// summons, bit n for summon n.
219};
220
221/// Each adds `amount` to a game state counter, kept between 0 and `max`, and
222/// returns the new value. The shops call the two: each purchase adds its
223/// price to the credit, and each Game Ticket given spends credit and counts
224/// one more gift.
225#define PARTY_DEFINE_ADJUST(name, field, max) \
226 s32 name(s32 amount) { \
227 s32 value; \
228 struct GameState *progress = &gGameState; \
229 \
230 value = progress->field; \
231 value += amount; \
232 if (value > max) \
233 value = max; \
234 if (value < 0) \
235 value = 0; \
236 progress->field = value; \
237 return value; \
238 }
239
242
243/// Writes the summons whose bit is set in the first word of the party's Djinn
244/// table to `output`, in menu order, ending with 32. Returns how many.
245/// Called by SummonMenu_SelectSummon to list the battle's Summon command.
247 u8 *source = gSummon_OrderList;
248 u8 *end = gSummon_OrderList + 15;
249 s32 count = 0;
250
251 do {
252 u8 value = *source++;
253 if ((((struct TradeFlags *)Djinn_GetRecoveryTable(0))->flags &
254 (1 << value)) != 0) {
255 *output++ = value;
256 count++;
257 }
258 } while (source <= end);
259 *output = 32;
260 return count;
261}
262
263/// Returns summon `summonId`'s definition, or NULL past the sixteenth. Reached
264/// only through GAME.S, as SummonDefinition_Get.
266 if (summonId > 15)
267 return NULL;
268 return &gSummon_DefinitionTable[summonId];
269}
270
271#undef ENEMY_SUFFIX_FIRST
272#undef ENEMY_SUFFIX_LAST
273#undef PARTY_DEFINE_ADJUST
@ BATTLE_UNIT_ENEMY
@ BATTLE_UNIT_PARTY
@ BATTLE_UNIT_SIZE
Definition battle_unit.h:13
void UiText_DecodeMessageFar(s32 message, u16 *text, s32 capacity)
s32 GameFlag_Test(s32 flag)
Returns 1 when flag is set.
Definition flags.c:13
s32 GameFlag_SetBit(s32 flag)
Sets flag and returns its byte number.
Definition flags.c:27
void GameFlag_ClearBit(s32 flag)
Clears flag.
Definition flags.c:40
u32 Unit_CalcBaseElements(s32 owner, s16 destination[4][2])
Definition classes.c:101
const struct SummonDefinition gSummon_DefinitionTable[]
u8 gSummon_OrderList[16]
const struct EnemyDefinition gEnemy_Definitions[]
What every part of the game object shares: its includes and the inventory helper two parts use.
struct GameState gGameState
@ INVENTORY_SLOTS
Definition item.h:23
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
s32 BattleUnitSet(s32 unitId, s32 enemyId, s32 suffix)
Fills battle unit unitId (0x80 to 0x86) with enemy enemyId: stats, name with its suffix letter,...
Definition party.c:25
#define ENEMY_SUFFIX_FIRST
Definition party.c:10
s32 Party_AdjustShopCredit(s32 amount)
Definition party.c:240
#define ENEMY_SUFFIX_LAST
Definition party.c:11
s32 Party_CountActiveOwners(void)
Returns the number of party members, counted from game flags 0 to 7.
Definition party.c:117
s32 Party_RemoveActiveOwner(s32 owner)
Takes character owner out of the party: clears its game flag and closes the gap it leaves in gGameSta...
Definition party.c:154
s32 Summon_ListLearned(u8 *output)
Writes the summons whose bit is set in the first word of the party's Djinn table to output,...
Definition party.c:246
const struct SummonDefinition * SummonDefinition_GetNear(u32 summonId)
Returns summon summonId's definition, or NULL past the sixteenth.
Definition party.c:265
s32 Party_AdjustShopGifts(s32 amount)
Definition party.c:241
s32 Party_AdjustCoins(s32 amount)
Adds amount to the party's coins, kept between 0 and 999999, and returns the new total.
Definition party.c:195
#define PARTY_DEFINE_ADJUST(name, field, max)
Each adds amount to a game state counter, kept between 0 and max, and returns the new value.
Definition party.c:225
s32 Party_AddActiveOwner(s32 owner)
Adds character owner to the end of the party: sets its game flag and appends it to gGameState....
Definition party.c:135
s32 Party_ListActiveOwners(s16 *owners)
Writes the party members to owners, ending with 0xff, and returns how many there are.
Definition party.c:173
#define NULL
Definition bilibin.h:6
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
u32 rewards
Copied from the enemy's definition, where it is 0 in every row.
u8 side
BATTLE_UNIT_ABSENT (0), BATTLE_UNIT_ENEMY (1) or BATTLE_UNIT_PARTY (2).
s16 maxPp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
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 hp
current HP, 0 when downed
s16 ppGauge
pp / maxPp in 0..0x4000; 1 while any PP remains
s16 pp
current PP
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.
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).
struct BattleElementStats baseElement[4]
Power and resistance before equipment and stages: an enemy's from its element preset,...
s16 basePp
before equipment, Djinn and class (UnitCalc)
s16 maxHp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
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_*...
An enemy's definition: its level and stats, items, element preset, the actions it chooses from and it...
Definition character.h:89
u16 items[4]
items the enemy carries, 0 for none
Definition character.h:109
u32 rewards
0 in every row; copied to BattleUnit.rewards
Definition character.h:107
u16 hp
The base stats BattleUnitSet copies into the unit.
Definition character.h:96
u8 counts[4]
how many of each item it carries
Definition character.h:110
u8 turns
actions a round (BattleUnit.baseActionCount)
Definition character.h:102
The game's state: play time, coins, the scene and the leader's position, the active party and the opt...
Definition game_state.h:14
u8 activeOwners[8]
the party in order
Definition game_state.h:60
A summon: its name's message and the Djinn of each element it needs.
The party's Djinn recovery table as the summon list reads it: a mask of summons, bit n for summon n.
Definition party.c:217
u32 flags
Definition party.c:218
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
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
void * Djinn_GetRecoveryTable(s32 enemySide)
Returns the party's Djinn recovery bank (the standby Djinn and their turns to recover),...
Definition units.c:42