Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
inn.c
Go to the documentation of this file.
1#include "engine/game.h"
2
3/* updateInnMenu's substates: each group runs in order, by substate++ */
5 INN_OPEN_NAME, /* the inn's name and the money */
7 INN_SHOW_QUESTION, /* the price and yes/no */
12 INN_PAY = 20, /* the jingle and the fade to black */
13 INN_SLEEP, /* pay and heal behind the black screen */
16 INN_NO_MONEY = 30, /* the "not enough money" message */
19};
20
21/* Starts opening or closing a menu panel, with its sound */
23 panel->active = 1;
24 if (open) {
26 panel->level = 0;
27 panel->step = ONE / panel->duration;
28 } else {
30 panel->level = ONE;
31 panel->step = -((ONE / panel->duration) * 2);
32 }
33}
34
35/* Moves a panel's level one frame on; 1 once it is fully open or closed */
37 if (!panel->active) {
38 return 1;
39 }
40 panel->level += panel->step;
41 if (panel->step > 0) {
42 if (panel->level > ONE) {
43 panel->level = ONE;
44 panel->active = 0;
45 return 1;
46 }
47 } else if (panel->level < 0) {
48 panel->level = 0;
49 panel->active = 0;
50 return 1;
51 }
52 return 0;
53}
54
55/* Restores HP, MP and status of the party (the inn) */
56void healParty(void) {
57 PartnerStats *p;
58 s32 i;
59 s32 j;
60 s32 index;
61
62 for (i = 0; i < PARTY_SIZE; i++) {
63 index = GAME.funcs.getPartyMember(i);
64 if (index >= 0) {
65 p = GAME.funcs.getPartnerStats(index);
68 for (j = 2; j >= 0; j--) {
69 p->status[j] = 0;
70 }
71 }
72 }
73}
74
75/* One inn per game mode */
76typedef struct InnInfo {
77 /* 0x0 */ s32 mode;
78 /* 0x4 */ s16 string; /* in file 0x5D */
79 /* 0x6 */ s16 price;
80} InnInfo;
81
83 { 0x20A, 1, 8 },
84 { 0x223, 2, 12 },
85 { 0x22F, 3, 16 },
86 { 0x238, 4, 32 },
87 { 0x23F, 5, 36 },
88 { 0x25B, 6, 48 },
89 { 0x25D, 7, 44 },
90 { 0x263, 8, 80 },
91 { 0x26F, 9, 84 },
92 { 0x26D, 10, 88 },
93 { 0x279, 11, 52 },
94 { 0x292, 2, 56 },
95 { 0x29D, 12, 60 },
96 { 0x2A5, 4, 68 },
97 { 0x2AC, 13, 72 },
98 { 0x2C4, 6, 80 },
99 { 0x2C6, 14, 76 },
100 { 0x2CB, 8, 84 },
101 { 0x2D6, 15, 88 },
102 { 0x249, 21, 44 },
103 { 0x2B3, 21, 76 },
104 { 0, 1, 1 }, /* the end of the list */
105};
106
107/* INN_CHOOSE: moves the cursor between yes and no; on yes pays if the party can,
108 else shows the "not enough money" message; no or a cancel closes the question */
109static inline void chooseInnAnswer(Inn *task, InnChildren *data) {
110 s32 prev;
111
112 prev = task->choice;
114 task->choice = 0;
115 } else if (PAD_PRESSED(PAD_DOWN) || PAD_REPEATED(PAD_DOWN)) {
116 task->choice = 1;
117 }
118 if (prev != task->choice) {
120 data->cursor->setPos(data->cursor, 0xB8, task->choice * 16 + 0x5F);
121 return;
122 }
123 if (PAD_PRESSED(PAD_CROSS)) {
125 if (task->choice != 0) {
127 } else if (GAME.money >= INNS[task->inn].price * task->count) {
128 task->substate = INN_PAY;
129 } else {
131 task->step = 1;
132 }
133 } else if (PAD_PRESSED(PAD_TRIANGLE)) {
136 }
137}
138
139/* Under the fade: hides the panels and windows, pays the night and heals the party */
140static inline void sleepAtInn(Inn *task, InnChildren *data) {
141 task->panels[0].level = 0;
142 task->panels[1].level = 0;
143 data->windows[0]->setVisible(data->windows[0], 0);
144 data->windows[1]->setVisible(data->windows[1], 0);
145 data->windows[2]->setVisible(data->windows[2], 0);
146 data->windows[3]->setVisible(data->windows[3], 0);
147 data->windows[4]->setVisible(data->windows[4], 0);
148 data->windows[5]->setVisible(data->windows[5], 0);
149 data->cursor->setVisible(data->cursor, 0);
150 GAME.money -= INNS[task->inn].price * task->count;
151 healParty();
152}
153
154/*
155 * The inn's menu (INN_*): open the panels and ask (price x party size), then
156 * close, pay and sleep, or show the "not enough money" message.
157 */
158void updateInnMenu(Inn *task, InnChildren *data) {
159 switch (task->substate) {
160 case INN_OPEN_NAME:
161 default:
162 innStartPanel(&task->panels[0], 1);
163 task->substate++;
164 break;
166 if (innUpdatePanel(&task->panels[0])) {
168 data->windows[1]->setNumber(data->windows[1], 0, GAME.money);
169 data->windows[1]->setRightAlign(data->windows[1], 1);
170 data->windows[2]->setString(data->windows[2], FILE_CACHE.load(TEXT_FILE(TEXT_INN_NAMES)), 0x10);
171 innStartPanel(&task->panels[1], 1);
172 task->substate++;
173 }
174 break;
176 if (innUpdatePanel(&task->panels[1])) {
177 data->windows[3]->setString(data->windows[3], FILE_CACHE.load(TEXT_FILE(TEXT_INN_NAMES)), 0x11);
178 data->windows[3]->setNumber(data->windows[3], 1, INNS[task->inn].price);
179 data->windows[4]->setString(data->windows[4], FILE_CACHE.load(TEXT_FILE(TEXT_INN_NAMES)), 0x12);
180 data->windows[5]->setString(data->windows[5], FILE_CACHE.load(TEXT_FILE(TEXT_INN_NAMES)), 0x13);
181 data->cursor->setVisible(data->cursor, 1);
182 task->substate++;
183 }
184 break;
185 case INN_CHOOSE:
186 chooseInnAnswer(task, data);
187 break;
189 innStartPanel(&task->panels[1], 0);
190 data->windows[3]->setVisible(data->windows[3], 0);
191 data->windows[4]->setVisible(data->windows[4], 0);
192 data->windows[5]->setVisible(data->windows[5], 0);
193 data->cursor->setVisible(data->cursor, 0);
194 task->substate++;
195 break;
197 if (innUpdatePanel(&task->panels[1])) {
198 if (task->step != 0) {
199 innStartPanel(&task->panels[2], 1);
200 task->substate = INN_NO_MONEY;
201 } else {
202 innStartPanel(&task->panels[0], 0);
203 data->windows[0]->setVisible(data->windows[0], 0);
204 data->windows[1]->setVisible(data->windows[1], 0);
205 data->windows[2]->setVisible(data->windows[2], 0);
206 task->substate++;
207 }
208 }
209 break;
211 if (innUpdatePanel(&task->panels[0])) {
212 task->state = TASK_KILL;
213 }
214 break;
215 case INN_PAY:
216 task->music = SOUND.music;
217 task->time = GFX.funcs.getTime();
219 data->fade = createScreenFade(task->layerId);
220 data->fade->start(data->fade, 0, 0x14);
221 task->substate++;
222 break;
223 case INN_SLEEP:
224 if (data->fade->state == TASK_DONE) {
225 sleepAtInn(task, data);
226 task->substate++;
227 }
228 break;
229 case INN_WAKE:
230 if (GFX.funcs.getTime() - task->time > 0xF0) {
231 data->fade->start(data->fade, 1, 0x14);
232 task->substate++;
233 }
234 break;
235 case INN_WAIT_AWAKE:
236 if (data->fade->state == TASK_DONE) {
237 SOUND.playSound(task->music);
238 task->state = TASK_KILL;
239 }
240 break;
241 case INN_NO_MONEY:
242 if (innUpdatePanel(&task->panels[2])) {
243 data->windows[3]->setString(data->windows[3], FILE_CACHE.load(TEXT_FILE(TEXT_INN_NAMES)), 0x14);
244 task->step = 0;
245 task->substate++;
246 }
247 break;
249 if (PAD_PRESSED(PAD_CROSS)) {
251 data->windows[3]->setVisible(data->windows[3], 0);
252 innStartPanel(&task->panels[2], 0);
253 task->substate++;
254 }
255 break;
257 if (innUpdatePanel(&task->panels[2])) {
258 innStartPanel(&task->panels[1], 1);
260 }
261 break;
262 }
263}
264
265/* The inn task: creates its windows, then runs the menu and draws the panels at their levels */
266void updateInn(Inn *task, InnChildren *data) {
267 SpriteDrawer obj;
268 s32 i;
269 s32 n;
270 s32 id;
271
272 switch (task->state) {
273 case TASK_INIT:
274 default:
275 task->nextState(task);
276 id = GAME.funcs.getMode();
277 for (n = 0; INNS[n].mode != 0; n++) {
278 if (id == INNS[n].mode) {
279 break;
280 }
281 }
282 task->inn = n;
283 for (i = 0; i < PARTY_SIZE; i++) {
284 if (GAME.funcs.getPartyMember(i) >= 0) {
285 task->count++;
286 }
287 }
288 data->windows[0] = createTextWindow(task->layerId, 1, 0x1D, 0x14);
289 data->windows[1] = createTextWindow(task->layerId, 3, 0x117, 0x17);
290 data->windows[2] = createTextWindow(task->layerId, 3, 0x11A, 0x17);
291 data->windows[3] = createTextWindow(task->layerId, 1, 0x79, 0x34);
292 data->windows[4] = createTextWindow(task->layerId, 1, 0xC5, 0x5F);
293 data->windows[5] = createTextWindow(task->layerId, 1, 0xC5, 0x6F);
294 data->cursor = createCursor(task->layerId, 0, 0xB8, 0x5F);
295 data->cursor->setVisible(data->cursor, 0);
296 task->panels[0].duration = 10;
297 task->panels[1].duration = 10;
298 task->panels[2].duration = 10;
299 break;
300 case TASK_RUN:
301 updateInnMenu(task, data);
302 initSpriteDrawer(&obj);
303 obj.setTexture(0x140, 0);
304 obj.setLayerId(task->layerId, task->depth);
305 obj.setFollowScroll(0);
306 if (task->panels[0].level != 0) {
307 if (task->panels[0].level != ONE) {
308 obj.setScale(task->panels[0].level, ONE, ONE);
309 obj.setPivot(0x57, 0x19);
310 }
311 obj.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x41, 0x16, 0x12);
312 if (task->panels[0].level != ONE) {
313 obj.setPivot(0x140, 0x18);
314 }
315 obj.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x42, 0xD6, 0xF);
316 }
317 if (task->panels[1].level != 0) {
318 if (task->panels[1].level != ONE) {
319 obj.setScale(task->panels[1].level, ONE, ONE);
320 obj.setPivot(0x140, 0x41);
321 }
322 obj.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x43, 0x4C, 0x2E);
323 if (task->panels[1].level != ONE) {
324 obj.setPivot(0x140, 0x6D);
325 }
326 obj.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x44, 0xAF, 0x59);
327 }
328 if (task->panels[2].level != 0) {
329 if (task->panels[2].level != ONE) {
330 obj.setScale(task->panels[2].level, ONE, ONE);
331 obj.setPivot(0x140, 0x41);
332 }
333 obj.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x43, 0x4C, 0x2E);
334 }
335 break;
336 case TASK_DONE:
337 case TASK_KILL:
338 break;
339 }
340}
341
342/* Starts the inn of the current game mode on a layer */
343Inn *createInn(s32 layerId) {
344 Inn *task = createTask(updateInn, 0xA0, sizeof(InnChildren));
345
346 task->layerId = layerId;
347 task->depth = 1;
348 return task;
349}
signed int s32
Definition common.h:11
signed short s16
Definition common.h:9
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
GameState GAME
The save data, the game mode and the methods.
Definition state.c:64
#define TASK_RUN
Definition task.h:35
#define TASK_KILL
Definition task.h:37
#define TASK_INIT
Tasks: every game object is a task, a heap block that starts with this header and is updated once per...
Definition task.h:34
#define TASK_DONE
Definition task.h:36
Cursor * createCursor(s16 layerId, s32 depth, s16 x, s16 y)
A menu cursor on a layer at (x, y)
Definition cursor.c:92
#define TEXT_INN_NAMES
HTLNAM.
Definition file.h:213
#define TEXT_FILE(file)
Definition file.h:190
#define FILE_MENU_SPRITES
Files the engine loads by number.
Definition file.h:188
FileCache FILE_CACHE
The file cache.
Definition file_cache.c:7
long open(char *name, unsigned long mode)
The kernel's file functions (libapi.h); the sim: device is the PC's.
#define STAT_MP
Definition game_state.h:283
#define PARTY_SIZE
How many partners the party holds.
Definition game_state.h:475
#define STAT_MAX_HP
Definition game_state.h:282
#define STAT_HP
Definition game_state.h:281
#define STAT_MAX_MP
Definition game_state.h:284
static void sleepAtInn(Inn *task, InnChildren *data)
Under the fade: hides the panels and windows, pays the night and heals the party.
Definition inn.c:140
InnSubstate
updateInnMenu's substates: each group runs in order, by substate++
Definition inn.c:4
@ INN_SHOW_QUESTION
the price and yes/no
Definition inn.c:7
@ INN_WAIT_QUESTION_CLOSED
Definition inn.c:10
@ INN_CLOSE_QUESTION
Definition inn.c:9
@ INN_WAIT_AWAKE
Definition inn.c:15
@ INN_OPEN_NAME
the inn's name and the money
Definition inn.c:5
@ INN_OPEN_QUESTION
Definition inn.c:6
@ INN_NO_MONEY_WAIT
Definition inn.c:17
@ INN_NO_MONEY
the "not enough money" message
Definition inn.c:16
@ INN_SLEEP
pay and heal behind the black screen
Definition inn.c:13
@ INN_WAKE
Definition inn.c:14
@ INN_NO_MONEY_CLOSE
Definition inn.c:18
@ INN_CHOOSE
Definition inn.c:8
@ INN_WAIT_NAME_CLOSED
Definition inn.c:11
@ INN_PAY
the jingle and the fade to black
Definition inn.c:12
void updateInnMenu(Inn *task, InnChildren *data)
The inn's menu (INN_*): open the panels and ask (price x party size), then close, pay and sleep,...
Definition inn.c:158
void updateInn(Inn *task, InnChildren *data)
The inn task: creates its windows, then runs the menu and draws the panels at their levels.
Definition inn.c:266
s32 innUpdatePanel(PanelAnim *panel)
Moves a panel's level one frame on; 1 once it is fully open or closed.
Definition inn.c:36
void innStartPanel(PanelAnim *panel, s32 open)
Starts opening or closing a menu panel, with its sound.
Definition inn.c:22
InnInfo INNS[]
Definition inn.c:82
Inn * createInn(s32 layerId)
Starts the inn of the current game mode on a layer.
Definition inn.c:343
static void chooseInnAnswer(Inn *task, InnChildren *data)
INN_CHOOSE: moves the cursor between yes and no; on yes pays if the party can, else shows the "not en...
Definition inn.c:109
void healParty(void)
Restores HP, MP and status of the party (the inn)
Definition inn.c:56
#define PAD_CROSS
Definition pad.h:31
#define PAD_DOWN
Definition pad.h:24
#define PAD_TRIANGLE
Definition pad.h:32
#define PAD_PRESSED(button)
One button of pad 1: newly pressed, auto-repeated while held, or held.
Definition pad.h:140
#define PAD_UP
Definition pad.h:22
#define PAD_REPEATED(button)
Definition pad.h:141
ScreenFade * createScreenFade(s32 layerId)
A screen fade task on a layer, idle until started.
Definition screen_fade.c:76
SoundState SOUND
rsin and rcos (libgte) read rsin_tbl[a - 0x800] and the like: their addresses before the table fall i...
Definition sound.c:180
#define SOUND_MENU_CLOSE
SYSTEM04.
Definition sound.h:42
#define SOUND_MENU_CONFIRM
SYSTEM07.
Definition sound.h:44
#define SOUND_INN_JINGLE
JINGLE04: a night at the inn.
Definition sound.h:49
#define SOUND_SELECT
Sounds the overlays share, with SOUNDTST's names.
Definition sound.h:38
#define SOUND_MENU_OPEN
SYSTEM03.
Definition sound.h:41
#define SOUND_MENU_CANCEL
SYSTEM01.
Definition sound.h:39
#define SOUND_CURSOR
SYSTEM02: a cursor moves.
Definition sound.h:40
void initSpriteDrawer(SpriteDrawer *obj)
Clears a sprite drawer to neutral (no scale, gray tint, follows the scroll), gives it its methods and...
void(* setPos)()
(cursor, x, y)
Definition text.h:34
void(* setVisible)()
(cursor, visible)
Definition text.h:33
void *(* load)(u32 file)
Definition file.h:92
void *(* getEntry)(u32 fileAndIndex)
Definition file.h:96
s32(* getMode)(void)
Definition game_state.h:19
struct PartnerStats *(* getPartnerStats)(s32 partner)
Definition game_state.h:38
s32(* getPartyMember)(u32 index)
Definition game_state.h:24
GameFuncs funcs
Definition game_state.h:582
s32(* getTime)(void)
Definition gfx.h:31
GfxFuncs funcs
Definition gfx.h:77
TextWindow * windows[6]
Definition menu.h:80
struct ScreenFade * fade
Definition menu.h:79
Cursor * cursor
Definition menu.h:81
One inn per game mode.
Definition inn.c:76
s16 price
Definition inn.c:79
s32 mode
Definition inn.c:77
s16 string
in file 0x5D
Definition inn.c:78
The inn: pay INNS[inn].price per party member to restore HP, MP and status, with a fade to black and ...
Definition menu.h:66
s32 choice
0 yes, 1 no
Definition menu.h:71
void(* nextState)(struct Inn *task)
Definition menu.h:67
s32 count
party members
Definition menu.h:72
s32 inn
Definition menu.h:70
s32 step
Definition menu.h:67
s32 substate
Definition menu.h:67
s32 depth
Definition menu.h:69
s32 layerId
Definition menu.h:68
PanelAnim panels[3]
Definition menu.h:75
s32 music
Definition menu.h:73
s32 time
Definition menu.h:74
s32 state
Definition menu.h:67
Opens or closes a menu panel: level goes 0 -> ONE in duration frames (or back at twice the speed),...
Definition menu.h:18
s32 step
Definition menu.h:20
s32 level
Definition menu.h:21
s32 active
Definition menu.h:22
s32 duration
Definition menu.h:19
A partner Digimon from its name on (Partner.info), as getPartnerStats gives it.
Definition game_state.h:303
s16 stats[19]
Definition game_state.h:306
s16 status[3]
Definition game_state.h:307
void(* start)(struct ScreenFade *fade, s32 fadeIn, s32 frames)
TASK_DONE when done.
Definition gfx.h:368
s32 state
Definition gfx.h:362
s32 music
the exclusive sound playing
Definition sound.h:183
short(* playSound)(s32 id)
returns the voice of a key-on
Definition sound.h:187
Draws sprites from a sprite sheet (such as file 0x277, the menu graphics): a sheet has a table of fra...
Definition gfx.h:223
void(* setPivot)()
(x, y)
Definition gfx.h:250
void(* setScale)()
(x, y, z), ONE = 1.0
Definition gfx.h:248
void(* setLayerId)()
(id, depth)
Definition gfx.h:244
void(* setFollowScroll)()
(on)
Definition gfx.h:251
void(* draw)()
(sheet, frame, x, y)
Definition gfx.h:246
void(* setTexture)()
(x, y)
Definition gfx.h:242
void(* setRightAlign)()
no prototype: callers would truncate u8 args
Definition text.h:178
void(* setNumber)()
Definition text.h:166
void(* setString)()
Definition text.h:165
void(* setVisible)(struct TextWindow *obj, u8 arg)
Definition text.h:177
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
TextWindow * createTextWindow(s16 layerId, s16 style, s16 x, s16 y)
A text window on a layer, in a font style, at (x, y)