Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
event.c
Go to the documentation of this file.
1/* The events: their scripts of commands, or a task of their own. Their
2 rodata, at 0x80082598 (USA), starts FIELDSTG.PRO's third object (see
3 data/fieldstg.c). */
4
5#include "field/field_mode.h"
6
7/* The actor of an event's cast with the id, below the script commands' ids
8 (0x320) */
10 s32 i;
11
12 if (id < 0x320) {
13 for (i = 0; i < 30; i++) {
14 if (task->entries[i].id == 0) {
15 break;
16 }
17 if (task->entries[i].id == id) {
18 return task->entries[i].actor;
19 }
20 }
21 }
22 return NULL;
23}
24
25/* An event's pose command (SCRIPT_POSE): puts its actor in a pose, or, for
26 an id of the script commands (SCRIPT_COMMAND), creates the command's task
27 if needed and hands it the other two words, a command and its argument */
29 s32 id = op[1];
30 s32 set = op[2]; /* or the command */
31 s32 dir = op[3]; /* or its argument */
32 Actor *actor;
33 s32 target;
34 s32 i;
35
36 if (id < 0x320) {
37 actor = FIELDSTG_findEventActor(task, id);
38 if (actor != NULL) {
39 actor->setPose(actor, set, dir);
40 }
41 } else {
42 target = (s32)TASK_REGISTRY.funcs.find(id, -1, -1);
43 if (target == 0) {
44 for (i = 0; i < 10; i++) {
45 if (children->scripts[i] == 0) {
46 children->scripts[i] = FIELDSTG_createScriptCommand(id);
47 if (children->scripts[i] != 0) {
48 target = children->scripts[i];
49 }
50 break;
51 }
52 }
53 }
54 if (target != 0) {
55 FIELDSTG_handleScriptCommand(target, id, set, dir);
56 }
57 }
58 return 4;
59}
60
61/* Gives the characters the event held their controls back */
62static inline void releaseEventActors(EventTask *task) {
63 s32 i;
64
65 for (i = 0; i < 30; i++) {
66 if (task->entries[i].id == 0) {
67 break;
68 }
69 task->entries[i].actor->resetControl(task->entries[i].actor);
70 }
71}
72
73/*
74 * Runs an event: in TASK_INIT it waits for the event's text file and the
75 * field (FIELD_TASK_FIELD) and holds the characters; in TASK_RUN it runs the script
76 * until a command waits (kind 0 ends it, 1 moves or turns a character, 2
77 * opens a message box, 3 waits, 6 runs FIELDSTG_followWithCamera or FIELDSTG_pointCamera), or
78 * without a script runs start's task until it ends; TASK_KILL releases the
79 * characters and calls end. The match depends on next and actor being two
80 * variables, and sub an s16.
81 */
83 Actor *actor;
84 Actor *next;
85 s16 *pc;
86 s32 running;
87 s16 sub;
88 s32 i;
89
90 switch (task->state) {
91 case TASK_INIT:
92 default:
94 ((Task *)TASK_REGISTRY.funcs.find(FIELD_TASK_FIELD, -1, -1))->state == TASK_RUN) {
96 for (i = 0; next != NULL; next = TASK_REGISTRY.funcs.findNext()) {
97 actor = next;
98 task->entries[i].actor = actor;
99 task->entries[i].id = actor->key1;
100 i++;
101 actor->startWalk(actor);
102 if (i == 30) {
103 break;
104 }
105 }
106 task->nextState(task);
107 }
108 break;
109 case TASK_RUN:
110 if (task->pc != NULL) {
111 pc = task->pc;
112 running = 1;
113 do {
114 sub = *pc & 0xFF;
115 switch (*pc >> 8) {
116 case 0:
117 default:
118 task->setState(task, TASK_KILL);
119 running = 0;
120 break;
121 case 1:
122 switch (sub) {
123 case 0:
124 default:
125 actor = FIELDSTG_findEventActor(task, pc[1]);
126 if (actor != NULL) {
127 actor->pos.x = pc[2] << 8;
128 actor->pos.y = pc[3] << 8;
129 }
130 pc += 4;
131 break;
132 case 1:
133 pc += FIELDSTG_setEventPose(task, pc, children);
134 break;
135 case 2:
136 actor = FIELDSTG_findEventActor(task, pc[1]);
137 if (actor != NULL) {
138 actor->setGoal(actor, pc[2], pc[3], pc[4]);
139 }
140 pc += 5;
141 break;
142 }
143 break;
144 case 2: {
145 s32 box = pc[1];
146 s32 text = pc[2];
147 s32 kind = pc[4];
148 s32 id = pc[3];
149
150 actor = NULL;
151 if (kind != 4) {
152 actor = FIELDSTG_findEventActor(task, id);
153 if (actor != NULL) {
154 children->boxes[box] = FIELDSTG_createSpeech(actor, text, kind, 0);
155 }
156 } else {
157 children->boxes[box] = FIELDSTG_createSpeech(actor, text, 4, 1);
158 }
159 pc += 5;
160 break;
161 }
162 case 3:
163 switch (sub) {
164 case 0:
165 default:
166 if (task->wait == 0) {
167 task->wait = pc[1];
168 }
169 if (--task->wait != 0) {
170 running = 0;
171 } else {
172 pc += 2;
173 }
174 break;
175 case 1:
176 if (children->boxes[0] != NULL) {
177 running = 0;
178 } else {
179 pc += 1;
180 }
181 break;
182 case 2:
183 actor = FIELDSTG_findEventActor(task, pc[1]);
184 if (actor != NULL && actor->isWalking(actor)) {
185 running = 0;
186 } else {
187 pc += 2;
188 }
189 break;
190 case 3:
191 actor = FIELDSTG_findEventActor(task, pc[1]);
192 if (actor == NULL || actor->isAnimDone(actor)) {
193 pc += 2;
194 } else {
195 running = 0;
196 }
197 break;
198 case 4:
199 FIELDSTG_leaveField(pc[1], -1, pc[2] << 8, pc[3] << 8, pc[4]);
200 running = 0;
201 task->setState(task, TASK_DONE);
202 break;
203 }
204 break;
205 case 6:
206 switch (sub) {
207 case 0:
208 default:
209 FIELDSTG_followWithCamera(pc[1], pc[2]);
210 pc += 3;
211 break;
212 case 1:
213 FIELDSTG_pointCamera(pc[1], pc[2], pc[3]);
214 pc += 4;
215 break;
216 }
217 break;
218 }
219 } while (running);
220 task->pc = pc;
221 break;
222 }
223 switch (task->substate) {
224 case 0:
225 default:
226 children->task = task->start();
227 task->nextSubstate(task);
228 /* fallthrough */
229 case 1:
230 if (children->task == NULL) {
231 task->setState(task, TASK_KILL);
232 }
233 break;
234 }
235 break;
236 case TASK_DONE:
237 break;
238 case TASK_KILL:
239 releaseEventActors(task);
241 if (task->end != NULL) {
242 task->end();
243 }
244 break;
245 }
246}
247
248/* Starts the event id of FieldState.events: its script, start and end, and
249 its text; the player stands still, except for the events 8000 to 8999 */
251 EventTask *task = createTask(FIELDSTG_runEvent, sizeof(EventTask), 0x38);
252 FieldEvent *entry;
253 Task *other;
254 s32 text;
255
256 for (entry = FIELDSTG_state.events; entry->id != -1; entry++) {
257 if (entry->id == id) {
258 task->event = id;
259 task->pc = entry->script;
260 task->start = entry->start;
261 task->end = entry->end;
262 FIELDSTG_state.eventText = text = entry->text;
263 if (text != 0) {
264 FIELDSTG_state.eventText = text + (TEXT_FILE(1) << 16);
265 FILE_CACHE.request(entry->text >> 16);
266 }
268 if (id < 8000 || id >= 9000) {
270 if (other != NULL && other->state == TASK_RUN) {
271 other->setSubstate(other, ACTOR_STAND);
272 }
273 }
274 break;
275 }
276 }
277 if (FIELDSTG_state.busy == 0) {
278 task->setState(task, TASK_KILL);
279 }
280 return task;
281}
void FIELDSTG_followWithCamera(s32 snap, s32 id)
Points the camera at the actor id, at once if snap.
Definition camera.c:147
void FIELDSTG_pointCamera(s32 snap, s32 x, s32 y)
Points the camera at the spot (x, y), at once if snap.
Definition camera.c:161
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
signed short s16
Definition common.h:9
#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
Actor * FIELDSTG_findEventActor(EventTask *task, s32 id)
The actor of an event's cast with the id, below the script commands' ids (0x320)
Definition event.c:9
void FIELDSTG_runEvent(EventTask *task, EventChildren *children)
Runs an event: in TASK_INIT it waits for the event's text file and the field (FIELD_TASK_FIELD) and h...
Definition event.c:82
EventTask * FIELDSTG_startEvent(s32 id)
Starts the event id of FieldState.events: its script, start and end, and its text; the player stands ...
Definition event.c:250
s32 FIELDSTG_setEventPose(EventTask *task, s16 *op, EventChildren *children)
An event's pose command (SCRIPT_POSE): puts its actor in a pose, or, for an id of the script commands...
Definition event.c:28
static void releaseEventActors(EventTask *task)
Gives the characters the event held their controls back.
Definition event.c:62
void FIELDSTG_leaveField(s32 mode, s32 arg, s32 x, s32 y, s32 dir)
Leaves the field for a mode now (the executable calls it by this name)
Definition field.c:702
#define FIELD_TASK_ACTOR
every character (FIELDSTG_createActor)
Definition field_map.h:26
#define FIELD_TASK_FIELD
the field's main task (FIELDSTG_createField)
Definition field_map.h:27
#define ACTOR_STAND
Definition field_map.h:306
FIELDSTG.PRO: the field mode, where the player walks around the map.
FieldState FIELDSTG_state
Definition fieldstg.c:2641
#define TEXT_FILE(file)
Definition file.h:190
FileCache FILE_CACHE
The file cache.
Definition file_cache.c:7
TaskRegistry TASK_REGISTRY
Definition registry.c:122
void FIELDSTG_handleScriptCommand(s32 task, s32 id, s32 command, s32 arg)
Hands the task of script command id a command and its argument, through the command's handle.
Definition script.c:93
s32 FIELDSTG_createScriptCommand(s32 id)
Creates the task of script command id, or returns 0.
Definition script.c:81
Speech * FIELDSTG_createSpeech(Actor *actor, s32 entry, s32 type, s32 isMessage)
Creates the speech of an event's text entry: a message box, or a talk box of a type.
Definition speech.c:64
A character on the field (FIELDSTG_createActor): the player (kind 0) and the other characters.
Definition field_map.h:334
void(* setGoal)(struct Actor *, s32, s32, s32)
Definition field_map.h:390
void(* startWalk)(struct Actor *)
Definition field_map.h:386
s32(* isAnimDone)(struct Actor *)
Definition field_map.h:389
Vec2 pos
Definition field_map.h:336
s32(* isWalking)(struct Actor *)
Definition field_map.h:391
void(* resetControl)(struct Actor *)
Definition field_map.h:387
void(* setPose)(struct Actor *, s32, s32 dir)
Definition field_map.h:393
s32 key1
Definition field_map.h:335
The children of an EventTask.
Definition field_mode.h:291
struct Speech * boxes[3]
the script's message boxes
Definition field_mode.h:293
s32 scripts[10]
FIELDSTG_createScriptCommand's tasks.
Definition field_mode.h:294
struct Task * task
start's
Definition field_mode.h:292
An event (FIELDSTG_runEvent, made by FIELDSTG_startEvent): it runs a script of 16-bit words,...
Definition field_mode.h:277
void(* end)(void)
Definition field_mode.h:282
struct Actor * actor
Definition field_mode.h:286
void *(* start)(void)
Definition field_mode.h:281
s32 id
0 ends the list
Definition field_mode.h:278
struct EventTask::@13 entries[30]
the characters, held while the event runs
s32 wait
frames left of a wait command
Definition field_mode.h:283
void(* setState)(struct EventTask *task, s32 state)
Definition field_mode.h:278
void(* nextSubstate)(struct EventTask *task)
Definition field_mode.h:278
s32 event
its id
Definition field_mode.h:279
void(* nextState)(struct EventTask *task)
Definition field_mode.h:278
An event of the table FieldState.events, up to the first id -1, which FIELDSTG_startEvent starts.
Definition field_map.h:141
void(* end)(void)
or NULL
Definition field_map.h:147
s32 text
a file and index, the file counted from TEXT_FILE(1); or 0
Definition field_map.h:144
void *(* start)(void)
without a script: the task it starts, or NULL
Definition field_map.h:146
s16 * script
FIELDSTG_runEvent's, or NULL.
Definition field_map.h:143
s32 busy
an event, a warp, a launch or a battle has the player
Definition field_map.h:468
FieldEvent * events
up to the first id -1
Definition field_map.h:451
s32 eventText
the running event's text file and entry
Definition field_map.h:462
s32(* isLoading)(s32 file)
Definition file.h:88
void(* request)(s32 file)
Definition file.h:90
void *(* findNext)(void)
Definition task.h:19
void *(* find)(s32 id, s32 key1, s32 key2)
Definition task.h:18
TaskFuncs funcs
Definition task.h:76
Any task, seen through its header.
Definition task.h:62
void(* setSubstate)(struct Task *task, s32 substate)
Definition task.h:63
s32 state
Definition task.h:63
s32 y
Definition gfx.h:354
s32 x
Definition gfx.h:353
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105