Alchemy
Loading...
Searching...
No Matches

artifacts.c

Go to the documentation of this file.
1/// @file
2/// The Game Ticket counter, the gift items and every shop's stock.
3/// Part of shop.c, the shop object, compiled only through it.
4
5#include "../shop_internal.h"
6
7/// The shop credit each Game Ticket costs, by how many have been given: five
8/// at each price: 300, then 500 doubling to 8000.
9// clang-format off
10static const s16 sGameTicketCreditCosts[30] = {
11 300, 300, 300, 300, 300,
12 500, 500, 500, 500, 500,
13 1000, 1000, 1000, 1000, 1000,
14 2000, 2000, 2000, 2000, 2000,
15 4000, 4000, 4000, 4000, 4000,
16 8000, 8000, 8000, 8000, 8000,
17};
18
19/// Gift items, terminated by 0; no function reads this table. They are the
20/// Long Sword to the Muramasa, the Short Sword, Mint, the Demon Axe, Asura's
21/// Armor, the Cotton Shirt, the Travel Vest, Herb, Nut and an unused row.
23 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
24 16, 195, 38, 84, 89, 90, 180, 181, 190, 0,
25};
26// clang-format on
27
28/// Gives a Game Ticket once the party's shop credit (what it has spent in
29/// shops) reaches the next ticket's cost, and lets the player choose who
30/// takes it. Spends the credit and counts the gift, not coins. Called by
31/// Shop_SelectBuy after each purchase.
32void Shop_BuySpecialItem(struct UiWindow *window, struct UiWindow *itemWindow) {
33 struct ShopRuntime *shop = gMenuWork;
34 s32 creditCost;
35 u32 savedSelectedItem;
36 s32 redraw;
37 s32 unitId;
38 s32 memberIndex;
39 s32 messageBase;
40 s32 slot;
41
42 redraw = 1;
43 unitId = 0;
44 savedSelectedItem = shop->selectedItem;
46 memberIndex = 0;
47
48 // Gifts spend accumulated shop credit; they do not debit the party's coins.
49 if (creditCost > gGameState.shopCredit)
50 return;
53 messageBase = MsgTokenGift;
56 UiMessage_ShowAndRestoreState(messageBase + 1);
57
58 while (1) {
59 if (redraw != 0) {
60 redraw = 0;
61 memberIndex =
62 (memberIndex + shop->partyMemberCount) % shop->partyMemberCount;
63 unitId = shop->partyMemberIds[memberIndex];
64 Shop_PlaceCursor(window, memberIndex * 24 - 12, 0);
65 shop->mode = 3;
66 Shop_DrawParty(window, memberIndex, shop->selectedItem);
68 }
69 if ((gKeysPressed & KEY_A) != 0) {
70 // Probe capacity before the keeper's confirmation; the gift is committed
71 // only after that line finishes.
72 slot = Inventory_AddItemFar(unitId, shop->selectedItem);
73 if (slot < 0) {
75 UiWork_PushValueSlotFar(unitId, 1);
78 UiMessage_ShowAndWait(MsgPackFull);
79 else
80 UiMessage_ShowAndWait(MsgCannotCarryItem);
81 continue;
82 }
83 Inventory_RemoveFar(unitId, slot);
87 Party_AdjustShopCreditFar(-creditCost);
89 break;
90 }
91 if ((gKeysPressed & KEY_B) != 0) {
92 UiMessage_ShowAndRestoreState(MsgDontWantIt);
94 break;
95 }
96 if ((gKeysRepeat & KEY_LEFT) != 0) {
98 memberIndex--;
99 redraw = 1;
100 }
101 if ((gKeysRepeat & KEY_RIGHT) != 0) {
103 memberIndex++;
104 redraw = 1;
105 }
106 WaitFrames(1);
107 }
108 shop->selectedItem = savedSelectedItem;
109}
110
111/// The shops' stock, one row per shop: up to 24 items, then up to 8 artifacts
112/// (each list ending with 0 when shorter), then the shop's type.
113enum {
121};
122
123// clang-format off
125 {
126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0,
128 0,
129 },
130 {
131 1, 16, 43, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0,
133 1,
134 },
135 {
136 89, 90, 103, 118, 127, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0,
138 2,
139 },
140 {
141 180, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0,
143 0,
144 },
145 {
146 1, 16, 31, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
147 56, 0, 0, 0, 0, 0, 0, 0,
148 1,
149 },
150 {
151 90, 118, 127, 136, 156, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152 0, 0, 0, 0, 0, 0, 0, 0,
153 2,
154 },
155 {
156 180, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
157 0, 0, 0, 0, 0, 0, 0, 0,
158 0,
159 },
160 {
161 1, 2, 17, 31, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
162 57, 0, 0, 0, 0, 0, 0, 0,
163 1,
164 },
165 {
166 75, 90, 104, 119, 128, 136, 145, 157, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0, 0,
168 2,
169 },
170 {
171 180, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172 0, 0, 0, 0, 0, 0, 0, 0,
173 0,
174 },
175 {
176 2, 17, 31, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 58, 0, 0, 0, 0, 0, 0, 0,
178 1,
179 },
180 {
181 75, 92, 119, 128, 136, 145, 157, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182 0, 0, 0, 0, 0, 0, 0, 0,
183 2,
184 },
185 {
186 180, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0,
188 0,
189 },
190 {
191 2, 17, 32, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192 0, 0, 0, 0, 0, 0, 0, 0,
193 1,
194 },
195 {
196 75, 92, 119, 128, 137, 146, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197 0, 0, 0, 0, 0, 0, 0, 0,
198 2,
199 },
200 {
201 180, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0,
203 0,
204 },
205 {
206 2, 18, 32, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
207 0, 0, 0, 0, 0, 0, 0, 0,
208 1,
209 },
210 {
211 92, 105, 120, 137, 146, 157, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
212 106, 0, 0, 0, 0, 0, 0, 0,
213 2,
214 },
215 {
216 180, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0,
218 0,
219 },
220 {
221 3, 18, 32, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222 59, 0, 0, 0, 0, 0, 0, 0,
223 1,
224 },
225 {
226 77, 92, 105, 120, 129, 137, 147, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0,
228 2,
229 },
230 {
231 180, 181, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0,
233 0,
234 },
235 {
236 3, 18, 33, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 60, 0, 0, 0, 0, 0, 0, 0,
238 1,
239 },
240 {
241 77, 107, 120, 129, 138, 147, 158, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0,
243 2,
244 },
245 {
246 180, 181, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, 0, 0, 0, 0,
248 0,
249 },
250 {
251 180, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0,
253 0,
254 },
255 {
256 4, 19, 33, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 61, 0, 0, 0, 0, 0, 0, 0,
258 1,
259 },
260 {
261 78, 94, 107, 121, 129, 138, 148, 158, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0,
263 2,
264 },
265 {
266 180, 181, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
267 182, 189, 0, 0, 0, 0, 0, 0,
268 0,
269 },
270 {
271 4, 19, 33, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
272 5, 20, 34, 62, 0, 0, 0, 0,
273 1,
274 },
275 {
276 79, 139, 149, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 109, 131, 0, 0, 0, 0, 0, 0,
278 2,
279 },
280 {
281 180, 181, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282 182, 183, 189, 186, 0, 0, 0, 0,
283 0,
284 },
285 {
286 4, 19, 33, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
287 6, 21, 47, 63, 0, 0, 0, 0,
288 1,
289 },
290 {
291 80, 150, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
292 110, 122, 140, 159, 0, 0, 0, 0,
293 2,
294 },
295 {
296 180, 181, 187, 188, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
297 182, 183, 189, 186, 0, 0, 0, 0,
298 0,
299 },
300};
301// clang-format on
302
303/// Returns how many stock rows there are; Shop_Run refuses a row past them.
305
306/// Adds a shop's artifacts to the shared stock counters once, on its first
307/// visit, and sets the shop's flag (FLAG_SHOP_ARTIFACTS_STOCKED + row) to
308/// remember it. Called by Shop_Run as a shop opens.
310 const s16 *stockEntries;
311 const s16 *artifactCursor;
312 s32 itemId;
313 s32 artifactIndex;
314 s32 initializedFlag;
315
316 initializedFlag = stockRow + FLAG_SHOP_ARTIFACTS_STOCKED;
317 if (GameFlag_TestFar(initializedFlag) == 0) {
318 GameFlag_SetBitFar(initializedFlag);
319 artifactIndex = 0;
320 itemId = sStockTable[stockRow][SHOP_STOCK_ARTIFACTS];
321 if (itemId != 0) {
322 stockEntries = sStockTable[stockRow];
323 artifactCursor = stockEntries + SHOP_STOCK_ARTIFACTS;
324 do {
325 Item_AdjustCounterFar(itemId, 1);
326 artifactIndex++;
327 if (artifactIndex > SHOP_STOCK_ARTIFACT_COUNT - 1)
328 break;
329 artifactCursor++;
330 itemId = *artifactCursor;
331 } while (itemId != 0);
332 }
333 }
334}
335
336/// Copies the shop's ordinary stock, up to 24 items, to `output` with a 0
337/// after, and returns how many. Called by Shop_Run for Buy.
339 const s16 *src;
340 s16 *dst;
341 s32 count;
342
343 count = 0;
344 if (sStockTable[stockRow][SHOP_STOCK_ITEMS] != 0) {
345 dst = output;
346 src = sStockTable[stockRow];
347 do {
348 /* FAKEMATCH: only the copy read is volatile, so its lifetime stays
349 * separate from the signed sentinel read; without volatile, 41
350 * instructions differ in tbs-en. */
351 *dst = *(const volatile s16 *)src;
352 count++;
353 src++;
354 dst++;
355 if (count > SHOP_STOCK_ITEM_COUNT - 1)
356 break;
357 } while (*src != 0);
358 }
359 output[count] = 0;
360 return count;
361}
362
363/// Returns the shop's type from the last column of its stock row: 0 items,
364/// 1 weapons, 2 armor, as Item_GetEquipmentGroup sorts items. Called by
365/// Shop_Run.
367 return sStockTable[stockRow][SHOP_STOCK_TYPE];
368}
static const s16 sStockTable[SHOP_STOCK_ROWS][SHOP_STOCK_COLUMNS]
Definition artifacts.c:124
s32 EventTable_CopyRowHeader(s32 stockRow, s16 *output)
Copies the shop's ordinary stock, up to 24 items, to output with a 0 after, and returns how many.
Definition artifacts.c:338
@ SHOP_STOCK_ITEM_COUNT
Definition artifacts.c:115
@ SHOP_STOCK_TYPE
Definition artifacts.c:118
@ SHOP_STOCK_ARTIFACTS
Definition artifacts.c:116
@ SHOP_STOCK_ARTIFACT_COUNT
Definition artifacts.c:117
@ SHOP_STOCK_COLUMNS
Definition artifacts.c:119
@ SHOP_STOCK_ROWS
Definition artifacts.c:120
@ SHOP_STOCK_ITEMS
Definition artifacts.c:114
static const s16 sGameTicketCreditCosts[30]
The shop credit each Game Ticket costs, by how many have been given: five at each price: 300,...
Definition artifacts.c:10
s32 EventTable_GetRowType(s32 stockRow)
Returns the shop's type from the last column of its stock row: 0 items, 1 weapons,...
Definition artifacts.c:366
s32 EventTable_GetRowLimit(void)
Returns how many stock rows there are; Shop_Run refuses a row past them.
Definition artifacts.c:304
void Shop_BuySpecialItem(struct UiWindow *window, struct UiWindow *itemWindow)
Gives a Game Ticket once the party's shop credit (what it has spent in shops) reaches the next ticket...
Definition artifacts.c:32
void EventTable_ApplyRowAbilities(s32 stockRow)
Adds a shop's artifacts to the shared stock counters once, on its first visit, and sets the shop's fl...
Definition artifacts.c:309
const s16 gShop_GiftItemIds[21]
Gift items, terminated by 0; no function reads this table.
Definition artifacts.c:22
void Shop_DrawParty(struct UiWindow *window, s32 selected, s32 itemId)
Shows the chosen member walking and the others standing, and draws at four fifths of their size the m...
Definition buy.c:382
void Shop_DrawUnitItem(struct UiWindow *window, s32 unitId, s32 itemId)
Shows the quantity already carried and the member's inventory icons.
Definition buy.c:484
void Shop_PlaceCursor(struct UiWindow *window, s32 x, s32 y)
Starts the hand cursor's glide to (x, y) pixels inside window (the screen when it is NULL),...
Definition cursor.c:273
s32 Item_AdjustCounterFar(s32 item_id, s32 delta)
s32 GameFlag_TestFar(s32 flag)
s32 Inventory_CountFar(s32 owner)
s32 Inventory_AddItemFar(s32 owner_id, s32 item_id)
s32 GameFlag_SetBitFar(s32 flag)
s32 Inventory_RemoveFar(s32 owner, s32 slot)
s32 Party_AdjustShopGiftsFar(s32 amount)
s32 Party_AdjustShopCreditFar(s32 amount)
void AudioCommand_PlayFar(s32 id)
void UiWork_PushValueSlotFar(u32 value, u32 kind)
#define FLAG_SHOP_ARTIFACTS_STOCKED
Plus a row of the shop stock table: that place's artifacts are in stock.
Definition flags.h:90
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
struct GameState gGameState
void * gMenuWork
@ KEY_B
Definition io_reg.h:244
@ KEY_LEFT
Definition io_reg.h:248
@ KEY_RIGHT
Definition io_reg.h:247
@ KEY_A
Definition io_reg.h:243
@ INVENTORY_SLOTS
Definition item.h:23
@ ITEM_GAME_TICKET
Definition item_ids.h:69
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
void UiMessage_ShowAndRestoreState(s32 messageId)
Shows a shopkeeper's line as UiMessage_ShowAndWait does, hiding the hand cursor while it shows and pu...
Definition run.c:239
void UiMessage_ShowAndWait(s32 messageId)
Shows a shopkeeper's line and waits for its window to finish, one more frame included.
Definition run.c:214
What every part of the shop object shares: its includes, the shop actions and sanctum services,...
#define SE_SHOP_PURCHASE
Definition songs.h:94
#define SE_MENU_CANCEL
Definition songs.h:106
#define SE_MENU_CURSOR_MOVE
Definition songs.h:104
s8 shopGifts
indexes the Game Ticket's credit cost
Definition game_state.h:28
s32 shopCredit
spent on a Game Ticket; not written by name in TBS
Definition game_state.h:27
A shop's work: its windows, the party members' icons, the stock, the cursor and its icons,...
Definition shop.h:18
s8 partyMemberCount
Definition shop.h:47
struct UiWindow * itemWindow
Definition shop.h:22
s16 partyMemberIds[9]
the party in order (Party_ListActiveOwners)
Definition shop.h:30
u16 selectedItem
the item being bought, sold or repaired
Definition shop.h:43
u8 mode
passed on as the hand cursor's kind; set to 12 at first
Definition shop.h:48
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
Definition uiwindow.h:11
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12