Alchemy
Loading...
Searching...
No Matches

repair.c

Go to the documentation of this file.
1/// @file
2/// Repairing broken items.
3/// Part of shop.c, the shop object, compiled only through it.
4
5#include "../shop_internal.h"
6
7/// Returns what a repair costs: a quarter of the price for a broken item,
8/// nothing for one that is not broken. Called by the repair list and
9/// Shop_RepairItem.
10s32 Shop_RepairPrice(s32 inventoryEntry) {
11 s32 repairCost = Item_GetDirectFar(inventoryEntry)->price / 4;
12
13 if ((inventoryEntry & INVENTORY_BROKEN) == 0) {
14 repairCost = 0;
15 }
16 return repairCost;
17}
18
19/// Runs the repair counter's member choice; always returns 0. Called by
20/// Shop_Run for Repair.
23 return 0;
24}
25
26/// Lets the player choose items to repair from the member's grid, one at a
27/// time, with each one's repair price, until B or the inventory is empty.
28/// Returns -1 when cancelled, 0 when the inventory ran out. Called by
29/// Shop_PickUnit.
31 struct ShopRuntime *shop;
32 s32 inventoryCount;
33 struct UiWindow *descriptionWindow;
34 struct UiWindow *priceWindow;
35 struct BattleUnit *unit;
36 s32 slot;
37 s32 redraw;
38 s32 result;
39 s32 itemId;
40 s32 repairCost;
41 struct UiWindow *window;
42 s32 x;
43 s32 y;
44
45 shop = gMenuWork;
46 unit = UnitGetFar(unitId);
47 inventoryCount = 1;
48 priceWindow = UiWindow_CreateFar(SHOP_LIST_X, 8, SHOP_LIST_WIDTH, 4, 2);
49 slot = 0;
50
51 for (;;) {
52 descriptionWindow = UiWindow_CreateFar(0, 5, 30, 3, 2);
53 shop->cursor.anchor->active = 18;
54 shop->mode = 12;
55 redraw = 1;
56
57 while (1) {
58 if (redraw != 0) {
59 redraw = 0;
60 inventoryCount = Inventory_CountFar(unitId);
61 if (slot > inventoryCount - 1)
62 slot = inventoryCount - 1;
63 itemId = ITEM_ID_MASK & unit->inventory[slot];
64 window = shop->itemWindow;
65 x = slot % SHOP_INVENTORY_COLUMNS * 16;
66 y = slot / SHOP_INVENTORY_COLUMNS * 16 + 8;
67 Shop_PlaceCursor(window, x, y);
68 shop->mode = 3;
69 repairCost = Shop_RepairPrice(unit->inventory[slot]);
70 Shop_DrawItemPrice(priceWindow, itemId, repairCost, 2);
71 Shop_DrawMsg(descriptionWindow, itemId + MsgItemPlainName);
72 }
73 if ((gKeysPressed & KEY_A) != 0) {
75 result = 0;
76 break;
77 }
78 if ((gKeysPressed & KEY_B) != 0) {
80 result = -1;
81 break;
82 }
83 if ((gKeysRepeat & KEY_LEFT) != 0) {
85 slot -= 1;
86 slot = (slot + inventoryCount) % inventoryCount;
87 redraw = 1;
88 }
89 if ((gKeysRepeat & KEY_RIGHT) != 0) {
91 slot += 1;
92 slot = (slot + inventoryCount) % inventoryCount;
93 redraw = 1;
94 }
95 if ((gKeysRepeat & KEY_UP) != 0) {
97 if (slot < 0)
98 slot += INVENTORY_SLOTS;
99 while (slot >= inventoryCount)
102 redraw = 1;
103 }
104 if ((gKeysRepeat & KEY_DOWN) != 0) {
106 if (slot >= inventoryCount)
107 slot -= INVENTORY_SLOTS;
108 while (slot < 0)
111 redraw = 1;
112 }
113 WaitFrames(1);
114 }
115
116 UiWork_FinalizeFar(descriptionWindow, 2);
117 WaitFrames(1);
118 if (result != 0)
119 break;
120
121 Shop_RepairItem(unitId, slot);
122 UiMessage_ShowAndWait(MsgRepairAnythingElse);
123 if (Inventory_CountFar(unitId) == 0)
124 break;
125 }
126
127 UiWork_FinalizeFar(priceWindow, 2);
128 return result;
129}
130
131/// Repairs the item in `slot`: refuses one that cannot break, is not broken
132/// or is equipped and cursed on, or that the coins do not cover; asks, then
133/// takes the item away for the smith's three hammer blows, gives it back
134/// mended, charges the price and offers to equip it. Called by
135/// Shop_SelectRepair.
136void Shop_RepairItem(s32 unitId, s32 slot) {
137 struct ShopRuntime *shop = gMenuWork;
138 struct BattleUnit *unit = UnitGetFar(unitId);
139 s32 itemId = unit->inventory[slot] & ITEM_ID_MASK;
140 struct ItemDefinition *item = Item_GetDirectFar(itemId);
141 s32 equipped = Inventory_FindEquippedFar(unitId, item->type);
142 u32 repairCost = Shop_RepairPrice(unit->inventory[slot]);
143 s32 messageBase;
144 u8 useType;
145 u32 savedEntry;
146
147 useType = item->useType;
149 UiWork_PushValueSlotFar(itemId, 2);
150 UiMessage_ShowAndRestoreState(MsgCannotRepairKind);
151 return;
152 }
153 if (!(unit->inventory[slot] & INVENTORY_BROKEN)) {
154 UiWork_PushValueSlotFar(itemId, 2);
155 UiMessage_ShowAndRestoreState(MsgNotDamaged);
156 return;
157 }
158 // useType is ITEM_USE_MAY_BREAK here, so this tests ITEM_CANNOT_UNEQUIP.
159 if ((unit->inventory[slot] & INVENTORY_EQUIPPED) && (useType & item->flags)) {
160 UiWork_PushValueSlotFar(itemId, 2);
161 UiMessage_ShowAndRestoreState(MsgCursedWontComeOff);
162 return;
163 }
164 if (repairCost > gGameState.coins) {
165 UiMessage_ShowAndRestoreState(MsgNotEnoughMoney);
166 return;
167 }
168 UiWork_PushValueSlotFar(itemId, 2);
169 UiWork_PushValueSlotFar(repairCost, 5);
170 messageBase = MsgShopRepairConfirm;
172 if (UiMessage_ShowChoice(0) != 0) {
173 UiMessage_ShowAndRestoreState(messageBase + 1);
174 return;
175 }
176 // Hide the item during the work sequence without compacting its slot.
177 savedEntry = unit->inventory[slot];
178 unit->inventory[slot] = 0;
179 Shop_DrawUnitGrid(shop->itemWindow, unitId);
180 UiWork_PushValueSlotFar(itemId, 2);
181 UiMessage_ShowAndRestoreState(messageBase + 2);
183 // The hammer blows are 110 frames apart; the item stays hidden throughout.
184 WaitFrames(10);
186 WaitFrames(110);
188 WaitFrames(110);
190 WaitFrames(110);
192 WaitFrames(20);
193 // Restore the entry, repair it, charge the fee and offer equipment changes.
194 unit->inventory[slot] = savedEntry;
195 Inventory_RepairFar(unitId, slot);
196 Party_AdjustCoinsFar(-repairCost);
198 Shop_DrawUnitGrid(shop->itemWindow, unitId);
199 UiWork_PushValueSlotFar(itemId, 2);
200 UiMessage_ShowAndRestoreState(messageBase + 3);
201 if (Shop_ConfirmEquip(unitId, slot))
202 Shop_SellOld(unitId, equipped);
203}
#define ITEM_USE_MAY_BREAK
breaks one time in eight
s32 Shop_ConfirmEquip(s32 unitId, s32 slot)
Offers to equip the item just bought, unless it is equipped already, the member cannot equip it,...
Definition buy.c:732
s32 Shop_SellOld(s32 unitId, s32 slot)
Offers to sell the item the new one replaced, unless there is none or it is a Psynergy item or indisp...
Definition buy.c:781
void Shop_DrawMoney(void)
Draws the party's coins in the coins window, in the edition's layout.
Definition buy.c:305
void Shop_DrawMsg(struct UiWindow *window, s32 message)
Shows message, an item's description, in the help window; a NULL window is ignored.
Definition buy.c:367
void Shop_DrawItemPrice(struct UiWindow *window, s32 itemId, s32 price, s32 priceKind)
Draws the item's name and below it its price.
Definition buy.c:328
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
struct BattleUnit * UnitGetFar(u32 owner)
struct ItemDefinition * Item_GetDirectFar(s32 item)
s32 Inventory_CountFar(s32 owner)
s32 Inventory_FindEquippedFar(s32 owner, s32 type)
s32 Inventory_RepairFar(s32 owner, s32 slot)
s32 Party_AdjustCoinsFar(s32 amount)
void AudioCommand_PlayFar(s32 id)
struct UiWindow * UiWindow_CreateFar(s32 x, s32 y, s32 width, s32 height, s32 attrs)
void UiWork_FinalizeFar(struct UiWindow *work, s32 release)
void UiWork_PushValueSlotFar(u32 value, u32 kind)
void UiWork_FinalizePendingCoreFar(void)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
struct GameState gGameState
void * gMenuWork
@ KEY_UP
Definition io_reg.h:249
@ 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
@ KEY_DOWN
Definition io_reg.h:250
@ INVENTORY_EQUIPPED
Definition item.h:17
@ INVENTORY_SLOTS
Definition item.h:23
@ ITEM_ID_MASK
Definition item.h:16
@ INVENTORY_BROKEN
Definition item.h:18
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
s32 Shop_SelectRepair(s32 unitId)
Lets the player choose items to repair from the member's grid, one at a time, with each one's repair ...
Definition repair.c:30
s32 Shop_RepairPrice(s32 inventoryEntry)
Returns what a repair costs: a quarter of the price for a broken item, nothing for one that is not br...
Definition repair.c:10
s32 Shop_SelectUnit(void)
Runs the repair counter's member choice; always returns 0.
Definition repair.c:21
void Shop_RepairItem(s32 unitId, s32 slot)
Repairs the item in slot: refuses one that cannot break, is not broken or is equipped and cursed on,...
Definition repair.c:136
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
s32 UiMessage_ShowChoice(s32 choice)
Runs the Yes or No choice beside the shopkeeper's line and returns it, keeping the hand cursor's moti...
Definition run.c:278
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
s32 Shop_PickUnit(void)
Lets the player choose whose items to sell or repair, with the coins window and the member's item gri...
Definition sell.c:11
void Shop_DrawUnitGrid(struct UiWindow *window, s32 unitId)
Draws the member's items as icons in rows of five, or a line saying it has none.
Definition sell.c:190
What every part of the shop object shares: its includes, the shop actions and sanctum services,...
@ SHOP_INVENTORY_COLUMNS
#define SE_MENU_CANCEL
Definition songs.h:106
#define SE_MENU_CURSOR_MOVE
Definition songs.h:104
#define SE_MENU_CONFIRM
Definition songs.h:105
#define SE_100
Definition songs.h:93
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u16 inventory[15]
Items held, one entry each: bits 15..11 quantity | 10 broken | 9 equipped | 8..0 item id (INVENTORY_*...
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
u8 type
enum ItemType; 0 for an item that is not equipment
Definition item.h:106
s16 price
coins
Definition item.h:105
u8 flags
enum ItemFlags
Definition item.h:107
s8 active
its UI_SPRITE_ motion; 0 while free
struct RenderOutput * anchor
the cursor's sprite, moved with its OAM
Definition cursor.h:14
A shop's work: its windows, the party members' icons, the stock, the cursor and its icons,...
Definition shop.h:18
struct UiWindow * itemWindow
Definition shop.h:22
struct ShopCursor cursor
the hand cursor
Definition shop.h:31
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
u16 y
tiles
Definition uiwindow.h:16
u16 x
tiles
Definition uiwindow.h:15
#define SHOP_LIST_X
#define SHOP_LIST_WIDTH
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
unsigned char u8
Definition types.h:11