aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/adrift/scevents.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/glk/adrift/scevents.cpp')
-rw-r--r--engines/glk/adrift/scevents.cpp1312
1 files changed, 622 insertions, 690 deletions
diff --git a/engines/glk/adrift/scevents.cpp b/engines/glk/adrift/scevents.cpp
index 18d95b19ec..0048cd6dd9 100644
--- a/engines/glk/adrift/scevents.cpp
+++ b/engines/glk/adrift/scevents.cpp
@@ -43,19 +43,17 @@ static sc_bool evt_trace = FALSE;
* Return TRUE if any task at all matches the given completion state.
*/
static sc_bool
-evt_any_task_in_state (sc_gameref_t game, sc_bool state)
-{
- sc_int task;
-
- /* Scan tasks for any whose completion matches input. */
- for (task = 0; task < gs_task_count (game); task++)
- {
- if (gs_task_done (game, task) == state)
- return TRUE;
- }
-
- /* No tasks matched. */
- return FALSE;
+evt_any_task_in_state(sc_gameref_t game, sc_bool state) {
+ sc_int task;
+
+ /* Scan tasks for any whose completion matches input. */
+ for (task = 0; task < gs_task_count(game); task++) {
+ if (gs_task_done(game, task) == state)
+ return TRUE;
+ }
+
+ /* No tasks matched. */
+ return FALSE;
}
@@ -65,39 +63,37 @@ evt_any_task_in_state (sc_gameref_t game, sc_bool state)
* Return TRUE if player is in the right room for event text.
*/
sc_bool
-evt_can_see_event (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[5];
- sc_int type;
-
- /* Check room list for the event and return it. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "Where";
- vt_key[3].string = "Type";
- type = prop_get_integer (bundle, "I<-siss", vt_key);
- switch (type)
- {
- case ROOMLIST_NO_ROOMS:
- return FALSE;
- case ROOMLIST_ALL_ROOMS:
- return TRUE;
-
- case ROOMLIST_ONE_ROOM:
- vt_key[3].string = "Room";
- return prop_get_integer (bundle, "I<-siss", vt_key)
- == gs_playerroom (game);
-
- case ROOMLIST_SOME_ROOMS:
- vt_key[3].string = "Rooms";
- vt_key[4].integer = gs_playerroom (game);
- return prop_get_boolean (bundle, "B<-sissi", vt_key);
-
- default:
- sc_fatal ("evt_can_see_event: invalid type, %ld\n", type);
- return FALSE;
- }
+evt_can_see_event(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[5];
+ sc_int type;
+
+ /* Check room list for the event and return it. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Where";
+ vt_key[3].string = "Type";
+ type = prop_get_integer(bundle, "I<-siss", vt_key);
+ switch (type) {
+ case ROOMLIST_NO_ROOMS:
+ return FALSE;
+ case ROOMLIST_ALL_ROOMS:
+ return TRUE;
+
+ case ROOMLIST_ONE_ROOM:
+ vt_key[3].string = "Room";
+ return prop_get_integer(bundle, "I<-siss", vt_key)
+ == gs_playerroom(game);
+
+ case ROOMLIST_SOME_ROOMS:
+ vt_key[3].string = "Rooms";
+ vt_key[4].integer = gs_playerroom(game);
+ return prop_get_boolean(bundle, "B<-sissi", vt_key);
+
+ default:
+ sc_fatal("evt_can_see_event: invalid type, %ld\n", type);
+ return FALSE;
+ }
}
@@ -107,55 +103,50 @@ evt_can_see_event (sc_gameref_t game, sc_int event)
* Move an object from within an event.
*/
static void
-evt_move_object (sc_gameref_t game, sc_int object, sc_int destination)
-{
- /* Ignore negative values of object. */
- if (object >= 0)
- {
- if (evt_trace)
- {
- sc_trace ("Event: moving object %ld to room %ld\n",
- object, destination);
- }
-
- /* Move object depending on destination. */
- switch (destination)
- {
- case -1: /* Hidden. */
- gs_object_make_hidden (game, object);
- break;
-
- case 0: /* Held by player. */
- gs_object_player_get (game, object);
- break;
-
- case 1: /* Same room as player. */
- gs_object_to_room (game, object, gs_playerroom (game));
- break;
-
- default:
- if (destination < gs_room_count (game) + 2)
- gs_object_to_room (game, object, destination - 2);
- else
- {
- sc_int roomgroup, room;
-
- roomgroup = destination - gs_room_count (game) - 2;
- room = lib_random_roomgroup_member (game, roomgroup);
- gs_object_to_room (game, object, room);
- }
- break;
- }
-
- /*
- * If static, mark as no longer unmoved.
- *
- * TODO Is this the only place static objects can be moved? And just
- * how static is a static object if it's moveable, anyway?
- */
- if (obj_is_static (game, object))
- gs_set_object_static_unmoved (game, object, FALSE);
- }
+evt_move_object(sc_gameref_t game, sc_int object, sc_int destination) {
+ /* Ignore negative values of object. */
+ if (object >= 0) {
+ if (evt_trace) {
+ sc_trace("Event: moving object %ld to room %ld\n",
+ object, destination);
+ }
+
+ /* Move object depending on destination. */
+ switch (destination) {
+ case -1: /* Hidden. */
+ gs_object_make_hidden(game, object);
+ break;
+
+ case 0: /* Held by player. */
+ gs_object_player_get(game, object);
+ break;
+
+ case 1: /* Same room as player. */
+ gs_object_to_room(game, object, gs_playerroom(game));
+ break;
+
+ default:
+ if (destination < gs_room_count(game) + 2)
+ gs_object_to_room(game, object, destination - 2);
+ else {
+ sc_int roomgroup, room;
+
+ roomgroup = destination - gs_room_count(game) - 2;
+ room = lib_random_roomgroup_member(game, roomgroup);
+ gs_object_to_room(game, object, room);
+ }
+ break;
+ }
+
+ /*
+ * If static, mark as no longer unmoved.
+ *
+ * TODO Is this the only place static objects can be moved? And just
+ * how static is a static object if it's moveable, anyway?
+ */
+ if (obj_is_static(game, object))
+ gs_set_object_static_unmoved(game, object, FALSE);
+ }
}
@@ -168,36 +159,34 @@ evt_move_object (sc_gameref_t game, sc_int object, sc_int destination)
* can do the same thing here, though it's ugly.
*/
static sc_bool
-evt_fixup_v390_v380_immediate_restart (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_int version;
-
- vt_key[0].string = "Version";
- version = prop_get_integer (bundle, "I<-s", vt_key);
- if (version < TAF_VERSION_400)
- {
- sc_int time1, time2;
-
- if (evt_trace)
- sc_trace ("Event: applying 3.9/3.8 restart fixup\n");
-
- /* Set to running state. */
- gs_set_event_state (game, event, ES_RUNNING);
-
- /* Set up event time to be one less than a proper start. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "Time1";
- time1 = prop_get_integer (bundle, "I<-sis", vt_key);
- vt_key[2].string = "Time2";
- time2 = prop_get_integer (bundle, "I<-sis", vt_key);
- gs_set_event_time (game, event, sc_randomint (time1, time2) - 1);
- }
-
- /* Return TRUE if we applied the fixup. */
- return version < TAF_VERSION_400;
+evt_fixup_v390_v380_immediate_restart(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_int version;
+
+ vt_key[0].string = "Version";
+ version = prop_get_integer(bundle, "I<-s", vt_key);
+ if (version < TAF_VERSION_400) {
+ sc_int time1, time2;
+
+ if (evt_trace)
+ sc_trace("Event: applying 3.9/3.8 restart fixup\n");
+
+ /* Set to running state. */
+ gs_set_event_state(game, event, ES_RUNNING);
+
+ /* Set up event time to be one less than a proper start. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Time1";
+ time1 = prop_get_integer(bundle, "I<-sis", vt_key);
+ vt_key[2].string = "Time2";
+ time2 = prop_get_integer(bundle, "I<-sis", vt_key);
+ gs_set_event_time(game, event, sc_randomint(time1, time2) - 1);
+ }
+
+ /* Return TRUE if we applied the fixup. */
+ return version < TAF_VERSION_400;
}
@@ -207,58 +196,55 @@ evt_fixup_v390_v380_immediate_restart (sc_gameref_t game, sc_int event)
* Change an event from WAITING to RUNNING.
*/
static void
-evt_start_event (sc_gameref_t game, sc_int event)
-{
- const sc_filterref_t filter = gs_get_filter (game);
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[4];
- sc_int time1, time2, obj1, obj1dest;
-
- if (evt_trace)
- sc_trace ("Event: starting event %ld\n", event);
-
- /* If event is visible, print its start text. */
- if (evt_can_see_event (game, event))
- {
- const sc_char *starttext;
-
- /* Get and print start text. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "StartText";
- starttext = prop_get_string (bundle, "S<-sis", vt_key);
- if (!sc_strempty (starttext))
- {
- pf_buffer_string (filter, starttext);
- pf_buffer_character (filter, '\n');
- }
-
- /* Handle any associated resource. */
- vt_key[2].string = "Res";
- vt_key[3].integer = 0;
- res_handle_resource (game, "sisi", vt_key);
- }
-
- /* Move event object to destination. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "Obj1";
- obj1 = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- vt_key[2].string = "Obj1Dest";
- obj1dest = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- evt_move_object (game, obj1, obj1dest);
-
- /* Set the event's state and time. */
- gs_set_event_state (game, event, ES_RUNNING);
-
- vt_key[2].string = "Time1";
- time1 = prop_get_integer (bundle, "I<-sis", vt_key);
- vt_key[2].string = "Time2";
- time2 = prop_get_integer (bundle, "I<-sis", vt_key);
- gs_set_event_time (game, event, sc_randomint (time1, time2));
-
- if (evt_trace)
- sc_trace ("Event: start event handling done, %ld\n", event);
+evt_start_event(sc_gameref_t game, sc_int event) {
+ const sc_filterref_t filter = gs_get_filter(game);
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[4];
+ sc_int time1, time2, obj1, obj1dest;
+
+ if (evt_trace)
+ sc_trace("Event: starting event %ld\n", event);
+
+ /* If event is visible, print its start text. */
+ if (evt_can_see_event(game, event)) {
+ const sc_char *starttext;
+
+ /* Get and print start text. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "StartText";
+ starttext = prop_get_string(bundle, "S<-sis", vt_key);
+ if (!sc_strempty(starttext)) {
+ pf_buffer_string(filter, starttext);
+ pf_buffer_character(filter, '\n');
+ }
+
+ /* Handle any associated resource. */
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 0;
+ res_handle_resource(game, "sisi", vt_key);
+ }
+
+ /* Move event object to destination. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "Obj1";
+ obj1 = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ vt_key[2].string = "Obj1Dest";
+ obj1dest = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ evt_move_object(game, obj1, obj1dest);
+
+ /* Set the event's state and time. */
+ gs_set_event_state(game, event, ES_RUNNING);
+
+ vt_key[2].string = "Time1";
+ time1 = prop_get_integer(bundle, "I<-sis", vt_key);
+ vt_key[2].string = "Time2";
+ time2 = prop_get_integer(bundle, "I<-sis", vt_key);
+ gs_set_event_time(game, event, sc_randomint(time1, time2));
+
+ if (evt_trace)
+ sc_trace("Event: start event handling done, %ld\n", event);
}
@@ -268,18 +254,17 @@ evt_start_event (sc_gameref_t game, sc_int event)
* Return the starter type for an event.
*/
static sc_int
-evt_get_starter_type (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_int startertype;
-
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "StarterType";
- startertype = prop_get_integer (bundle, "I<-sis", vt_key);
-
- return startertype;
+evt_get_starter_type(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_int startertype;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "StarterType";
+ startertype = prop_get_integer(bundle, "I<-sis", vt_key);
+
+ return startertype;
}
@@ -289,148 +274,136 @@ evt_get_starter_type (sc_gameref_t game, sc_int event)
* Move an event to FINISHED, or restart it.
*/
static void
-evt_finish_event (sc_gameref_t game, sc_int event)
-{
- const sc_filterref_t filter = gs_get_filter (game);
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[4];
- sc_int obj2, obj2dest, obj3, obj3dest;
- sc_int task, startertype, restarttype;
- sc_bool taskdir;
-
- if (evt_trace)
- sc_trace ("Event: finishing event %ld\n", event);
-
- /* Set up invariant parts of the key. */
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
-
- /* If event is visible, print its finish text. */
- if (evt_can_see_event (game, event))
- {
- const sc_char *finishtext;
-
- /* Get and print finish text. */
- vt_key[2].string = "FinishText";
- finishtext = prop_get_string (bundle, "S<-sis", vt_key);
- if (!sc_strempty (finishtext))
- {
- pf_buffer_string (filter, finishtext);
- pf_buffer_character (filter, '\n');
- }
-
- /* Handle any associated resource. */
- vt_key[2].string = "Res";
- vt_key[3].integer = 4;
- res_handle_resource (game, "sisi", vt_key);
- }
-
- /* Move event objects to destination. */
- vt_key[2].string = "Obj2";
- obj2 = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- vt_key[2].string = "Obj2Dest";
- obj2dest = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- evt_move_object (game, obj2, obj2dest);
-
- vt_key[2].string = "Obj3";
- obj3 = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- vt_key[2].string = "Obj3Dest";
- obj3dest = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- evt_move_object (game, obj3, obj3dest);
-
- /* See if there is an affected task. */
- vt_key[2].string = "TaskAffected";
- task = prop_get_integer (bundle, "I<-sis", vt_key) - 1;
- if (task >= 0)
- {
- vt_key[2].string = "TaskFinished";
- taskdir = !prop_get_boolean (bundle, "B<-sis", vt_key);
- if (task_can_run_task_directional (game, task, taskdir))
- {
- if (evt_trace)
- {
- sc_trace ("Event: event running task %ld, %s\n",
- task, taskdir ? "forwards" : "backwards");
- }
-
- task_run_task (game, task, taskdir);
- }
- else
- {
- if (evt_trace)
- sc_trace ("Event: event can't run task %ld\n", task);
- }
- }
-
- /* Handle possible restart. */
- vt_key[2].string = "RestartType";
- restarttype = prop_get_integer (bundle, "I<-sis", vt_key);
- switch (restarttype)
- {
- case 0: /* Don't restart. */
- startertype = evt_get_starter_type (game, event);
- switch (startertype)
- {
- case 1: /* Immediate. */
- case 2: /* Random delay. */
- case 3: /* After task. */
- gs_set_event_state (game, event, ES_FINISHED);
- gs_set_event_time (game, event, 0);
- break;
-
- default:
- sc_fatal ("evt_finish_event:"
- " unknown value for starter type, %ld\n", startertype);
- }
- break;
-
- case 1: /* Restart immediately. */
- if (evt_fixup_v390_v380_immediate_restart (game, event))
- break;
- else
- evt_start_event (game, event);
- break;
-
- case 2: /* Restart after delay. */
- startertype = evt_get_starter_type (game, event);
- switch (startertype)
- {
- case 1: /* Immediate. */
- if (evt_fixup_v390_v380_immediate_restart (game, event))
- break;
- else
- evt_start_event (game, event);
- break;
-
- case 2: /* Random delay. */
- {
- sc_int start, end;
-
- gs_set_event_state (game, event, ES_WAITING);
- vt_key[2].string = "StartTime";
- start = prop_get_integer (bundle, "I<-sis", vt_key);
- vt_key[2].string = "EndTime";
- end = prop_get_integer (bundle, "I<-sis", vt_key);
- gs_set_event_time (game, event, sc_randomint (start, end));
- break;
- }
-
- case 3: /* After task. */
- gs_set_event_state (game, event, ES_AWAITING);
- gs_set_event_time (game, event, 0);
- break;
-
- default:
- sc_fatal ("evt_finish_event: unknown StarterType\n");
- }
- break;
-
- default:
- sc_fatal ("evt_finish_event: unknown RestartType\n");
- }
-
- if (evt_trace)
- sc_trace ("Event: finish event handling done, %ld\n", event);
+evt_finish_event(sc_gameref_t game, sc_int event) {
+ const sc_filterref_t filter = gs_get_filter(game);
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[4];
+ sc_int obj2, obj2dest, obj3, obj3dest;
+ sc_int task, startertype, restarttype;
+ sc_bool taskdir;
+
+ if (evt_trace)
+ sc_trace("Event: finishing event %ld\n", event);
+
+ /* Set up invariant parts of the key. */
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ /* If event is visible, print its finish text. */
+ if (evt_can_see_event(game, event)) {
+ const sc_char *finishtext;
+
+ /* Get and print finish text. */
+ vt_key[2].string = "FinishText";
+ finishtext = prop_get_string(bundle, "S<-sis", vt_key);
+ if (!sc_strempty(finishtext)) {
+ pf_buffer_string(filter, finishtext);
+ pf_buffer_character(filter, '\n');
+ }
+
+ /* Handle any associated resource. */
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 4;
+ res_handle_resource(game, "sisi", vt_key);
+ }
+
+ /* Move event objects to destination. */
+ vt_key[2].string = "Obj2";
+ obj2 = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ vt_key[2].string = "Obj2Dest";
+ obj2dest = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ evt_move_object(game, obj2, obj2dest);
+
+ vt_key[2].string = "Obj3";
+ obj3 = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ vt_key[2].string = "Obj3Dest";
+ obj3dest = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ evt_move_object(game, obj3, obj3dest);
+
+ /* See if there is an affected task. */
+ vt_key[2].string = "TaskAffected";
+ task = prop_get_integer(bundle, "I<-sis", vt_key) - 1;
+ if (task >= 0) {
+ vt_key[2].string = "TaskFinished";
+ taskdir = !prop_get_boolean(bundle, "B<-sis", vt_key);
+ if (task_can_run_task_directional(game, task, taskdir)) {
+ if (evt_trace) {
+ sc_trace("Event: event running task %ld, %s\n",
+ task, taskdir ? "forwards" : "backwards");
+ }
+
+ task_run_task(game, task, taskdir);
+ } else {
+ if (evt_trace)
+ sc_trace("Event: event can't run task %ld\n", task);
+ }
+ }
+
+ /* Handle possible restart. */
+ vt_key[2].string = "RestartType";
+ restarttype = prop_get_integer(bundle, "I<-sis", vt_key);
+ switch (restarttype) {
+ case 0: /* Don't restart. */
+ startertype = evt_get_starter_type(game, event);
+ switch (startertype) {
+ case 1: /* Immediate. */
+ case 2: /* Random delay. */
+ case 3: /* After task. */
+ gs_set_event_state(game, event, ES_FINISHED);
+ gs_set_event_time(game, event, 0);
+ break;
+
+ default:
+ sc_fatal("evt_finish_event:"
+ " unknown value for starter type, %ld\n", startertype);
+ }
+ break;
+
+ case 1: /* Restart immediately. */
+ if (evt_fixup_v390_v380_immediate_restart(game, event))
+ break;
+ else
+ evt_start_event(game, event);
+ break;
+
+ case 2: /* Restart after delay. */
+ startertype = evt_get_starter_type(game, event);
+ switch (startertype) {
+ case 1: /* Immediate. */
+ if (evt_fixup_v390_v380_immediate_restart(game, event))
+ break;
+ else
+ evt_start_event(game, event);
+ break;
+
+ case 2: { /* Random delay. */
+ sc_int start, end;
+
+ gs_set_event_state(game, event, ES_WAITING);
+ vt_key[2].string = "StartTime";
+ start = prop_get_integer(bundle, "I<-sis", vt_key);
+ vt_key[2].string = "EndTime";
+ end = prop_get_integer(bundle, "I<-sis", vt_key);
+ gs_set_event_time(game, event, sc_randomint(start, end));
+ break;
+ }
+
+ case 3: /* After task. */
+ gs_set_event_state(game, event, ES_AWAITING);
+ gs_set_event_time(game, event, 0);
+ break;
+
+ default:
+ sc_fatal("evt_finish_event: unknown StarterType\n");
+ }
+ break;
+
+ default:
+ sc_fatal("evt_finish_event: unknown RestartType\n");
+ }
+
+ if (evt_trace)
+ sc_trace("Event: finish event handling done, %ld\n", event);
}
@@ -443,102 +416,89 @@ evt_finish_event (sc_gameref_t game, sc_int event)
* Return the status of start, pause and resume states of an event.
*/
static sc_bool
-evt_has_starter_task (sc_gameref_t game, sc_int event)
-{
- sc_int startertype;
+evt_has_starter_task(sc_gameref_t game, sc_int event) {
+ sc_int startertype;
- startertype = evt_get_starter_type (game, event);
- return startertype == 3;
+ startertype = evt_get_starter_type(game, event);
+ return startertype == 3;
}
static sc_bool
-evt_starter_task_is_complete (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_int task;
- sc_bool start;
-
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
- vt_key[2].string = "TaskNum";
- task = prop_get_integer (bundle, "I<-sis", vt_key);
-
- start = FALSE;
- if (task == 0)
- {
- if (evt_any_task_in_state (game, TRUE))
- start = TRUE;
- }
- else if (task > 0)
- {
- if (gs_task_done (game, task - 1))
- start = TRUE;
- }
-
- return start;
+evt_starter_task_is_complete(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_int task;
+ sc_bool start;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+ vt_key[2].string = "TaskNum";
+ task = prop_get_integer(bundle, "I<-sis", vt_key);
+
+ start = FALSE;
+ if (task == 0) {
+ if (evt_any_task_in_state(game, TRUE))
+ start = TRUE;
+ } else if (task > 0) {
+ if (gs_task_done(game, task - 1))
+ start = TRUE;
+ }
+
+ return start;
}
static sc_bool
-evt_pauser_task_is_complete (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_int pausetask;
- sc_bool completed, pause;
-
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
-
- vt_key[2].string = "PauseTask";
- pausetask = prop_get_integer (bundle, "I<-sis", vt_key);
- vt_key[2].string = "PauserCompleted";
- completed = !prop_get_boolean (bundle, "B<-sis", vt_key);
-
- pause = FALSE;
- if (pausetask == 1)
- {
- if (evt_any_task_in_state (game, completed))
- pause = TRUE;
- }
- else if (pausetask > 1)
- {
- if (completed == gs_task_done (game, pausetask - 2))
- pause = TRUE;
- }
-
- return pause;
+evt_pauser_task_is_complete(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_int pausetask;
+ sc_bool completed, pause;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ vt_key[2].string = "PauseTask";
+ pausetask = prop_get_integer(bundle, "I<-sis", vt_key);
+ vt_key[2].string = "PauserCompleted";
+ completed = !prop_get_boolean(bundle, "B<-sis", vt_key);
+
+ pause = FALSE;
+ if (pausetask == 1) {
+ if (evt_any_task_in_state(game, completed))
+ pause = TRUE;
+ } else if (pausetask > 1) {
+ if (completed == gs_task_done(game, pausetask - 2))
+ pause = TRUE;
+ }
+
+ return pause;
}
static sc_bool
-evt_resumer_task_is_complete (sc_gameref_t game, sc_int event)
-{
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[3];
- sc_int resumetask;
- sc_bool completed, resume;
-
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
-
- vt_key[2].string = "ResumeTask";
- resumetask = prop_get_integer (bundle, "I<-sis", vt_key);
- vt_key[2].string = "ResumerCompleted";
- completed = !prop_get_boolean (bundle, "B<-sis", vt_key);
-
- resume = FALSE;
- if (resumetask == 1)
- {
- if (evt_any_task_in_state (game, completed))
- resume = TRUE;
- }
- else if (resumetask > 1)
- {
- if (completed == gs_task_done (game, resumetask - 2))
- resume = TRUE;
- }
-
- return resume;
+evt_resumer_task_is_complete(sc_gameref_t game, sc_int event) {
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[3];
+ sc_int resumetask;
+ sc_bool completed, resume;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ vt_key[2].string = "ResumeTask";
+ resumetask = prop_get_integer(bundle, "I<-sis", vt_key);
+ vt_key[2].string = "ResumerCompleted";
+ completed = !prop_get_boolean(bundle, "B<-sis", vt_key);
+
+ resume = FALSE;
+ if (resumetask == 1) {
+ if (evt_any_task_in_state(game, completed))
+ resume = TRUE;
+ } else if (resumetask > 1) {
+ if (completed == gs_task_done(game, resumetask - 2))
+ resume = TRUE;
+ }
+
+ return resume;
}
@@ -549,50 +509,45 @@ evt_resumer_task_is_complete (sc_gameref_t game, sc_int event)
* and getting close to some number of turns from its end.
*/
static void
-evt_handle_preftime_notifications (sc_gameref_t game, sc_int event)
-{
- const sc_filterref_t filter = gs_get_filter (game);
- const sc_prop_setref_t bundle = gs_get_bundle (game);
- sc_vartype_t vt_key[4];
- sc_int preftime1, preftime2;
- const sc_char *preftext;
-
- vt_key[0].string = "Events";
- vt_key[1].integer = event;
-
- vt_key[2].string = "PrefTime1";
- preftime1 = prop_get_integer (bundle, "I<-sis", vt_key);
- if (preftime1 == gs_event_time (game, event))
- {
- vt_key[2].string = "PrefText1";
- preftext = prop_get_string (bundle, "S<-sis", vt_key);
- if (!sc_strempty (preftext))
- {
- pf_buffer_string (filter, preftext);
- pf_buffer_character (filter, '\n');
- }
-
- vt_key[2].string = "Res";
- vt_key[3].integer = 2;
- res_handle_resource (game, "sisi", vt_key);
- }
-
- vt_key[2].string = "PrefTime2";
- preftime2 = prop_get_integer (bundle, "I<-sis", vt_key);
- if (preftime2 == gs_event_time (game, event))
- {
- vt_key[2].string = "PrefText2";
- preftext = prop_get_string (bundle, "S<-sis", vt_key);
- if (!sc_strempty (preftext))
- {
- pf_buffer_string (filter, preftext);
- pf_buffer_character (filter, '\n');
- }
-
- vt_key[2].string = "Res";
- vt_key[3].integer = 3;
- res_handle_resource (game, "sisi", vt_key);
- }
+evt_handle_preftime_notifications(sc_gameref_t game, sc_int event) {
+ const sc_filterref_t filter = gs_get_filter(game);
+ const sc_prop_setref_t bundle = gs_get_bundle(game);
+ sc_vartype_t vt_key[4];
+ sc_int preftime1, preftime2;
+ const sc_char *preftext;
+
+ vt_key[0].string = "Events";
+ vt_key[1].integer = event;
+
+ vt_key[2].string = "PrefTime1";
+ preftime1 = prop_get_integer(bundle, "I<-sis", vt_key);
+ if (preftime1 == gs_event_time(game, event)) {
+ vt_key[2].string = "PrefText1";
+ preftext = prop_get_string(bundle, "S<-sis", vt_key);
+ if (!sc_strempty(preftext)) {
+ pf_buffer_string(filter, preftext);
+ pf_buffer_character(filter, '\n');
+ }
+
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 2;
+ res_handle_resource(game, "sisi", vt_key);
+ }
+
+ vt_key[2].string = "PrefTime2";
+ preftime2 = prop_get_integer(bundle, "I<-sis", vt_key);
+ if (preftime2 == gs_event_time(game, event)) {
+ vt_key[2].string = "PrefText2";
+ preftext = prop_get_string(bundle, "S<-sis", vt_key);
+ if (!sc_strempty(preftext)) {
+ pf_buffer_string(filter, preftext);
+ pf_buffer_character(filter, '\n');
+ }
+
+ vt_key[2].string = "Res";
+ vt_key[3].integer = 3;
+ res_handle_resource(game, "sisi", vt_key);
+ }
}
@@ -602,203 +557,183 @@ evt_handle_preftime_notifications (sc_gameref_t game, sc_int event)
* Attempt to advance an event by one turn.
*/
static void
-evt_tick_event (sc_gameref_t game, sc_int event)
-{
- if (evt_trace)
- {
- sc_trace ("Event: ticking event %ld: state %ld, time %ld\n", event,
- gs_event_state (game, event), gs_event_time (game, event));
- }
-
- /* Handle call based on current event state. */
- switch (gs_event_state (game, event))
- {
- case ES_WAITING:
- {
- if (evt_trace)
- sc_trace ("Event: ticking waiting event %ld\n", event);
-
- /*
- * Because we also tick an event that goes from waiting to running,
- * events started here will tick through RUNNING too, and have their
- * time decremented. To get around this, so that the timer for one-
- * shot events doesn't look one lower than it should after this
- * transition, we need to set the initial time for events that start
- * as soon as the game starts to one greater than that set by
- * evt_start_time(). Here's the hack to do that; if the event starts
- * immediately, its time will already be zero, even before decrement,
- * which is how we tell which events to apply this hack to.
- *
- * TODO This seems to work, but also seems very dodgy.
- */
- if (gs_event_time (game, event) == 0)
- {
- evt_start_event (game, event);
-
- /* If the event time was set to zero, finish immediately. */
- if (gs_event_time (game, event) <= 0)
- evt_finish_event (game, event);
- else
- gs_set_event_time (game, event, gs_event_time (game, event) + 1);
- break;
- }
-
- /*
- * Decrement the event's time, and if it goes to zero, start running
- * the event.
- */
- gs_decrement_event_time (game, event);
-
- if (gs_event_time (game, event) <= 0)
- {
- evt_start_event (game, event);
-
- /* If the event time was set to zero, finish immediately. */
- if (gs_event_time (game, event) <= 0)
- evt_finish_event (game, event);
- }
- }
- break;
-
- case ES_RUNNING:
- {
- if (evt_trace)
- sc_trace ("Event: ticking running event %ld\n", event);
-
- /*
- * Re-check the starter task; if it's no longer completed, we need
- * to set the event back to waiting on task.
- */
- if (evt_has_starter_task (game, event))
- {
- if (!evt_starter_task_is_complete (game, event))
- {
- if (evt_trace)
- sc_trace ("Event: starter task not complete\n");
-
- gs_set_event_state (game, event, ES_AWAITING);
- gs_set_event_time (game, event, 0);
- break;
- }
- }
-
- /* If the pauser has completed, but resumer not, pause this event. */
- if (evt_pauser_task_is_complete (game, event)
- && !evt_resumer_task_is_complete (game, event))
- {
- if (evt_trace)
- sc_trace ("Event: pause complete\n");
-
- gs_set_event_state (game, event, ES_PAUSED);
- break;
- }
-
- /*
- * Decrement the event's time, and print any notifications for a set
- * number of turns from the event end.
- */
- gs_decrement_event_time (game, event);
-
- if (evt_can_see_event (game, event))
- evt_handle_preftime_notifications (game, event);
-
- /* If the time goes to zero, finish running the event. */
- if (gs_event_time (game, event) <= 0)
- evt_finish_event (game, event);
- }
- break;
-
- case ES_AWAITING:
- {
- if (evt_trace)
- sc_trace ("Event: ticking awaiting event %ld\n", event);
-
- /*
- * Check the starter task. If it's completed, start running the
- * event.
- */
- if (evt_starter_task_is_complete (game, event))
- {
- evt_start_event (game, event);
-
- /* If the event time was set to zero, finish immediately. */
- if (gs_event_time (game, event) <= 0)
- evt_finish_event (game, event);
- else
- {
- /*
- * If the pauser has completed, but resumer not, immediately
- * also pause this event.
- */
- if (evt_pauser_task_is_complete (game, event)
- && !evt_resumer_task_is_complete (game, event))
- {
- if (evt_trace)
- sc_trace ("Event: pause complete, immediate pause\n");
-
- gs_set_event_state (game, event, ES_PAUSED);
- }
- }
- }
- }
- break;
-
- case ES_FINISHED:
- {
- if (evt_trace)
- sc_trace ("Event: ticking finished event %ld\n", event);
-
- /*
- * Check the starter task; if it's not completed, we need to set the
- * event back to waiting on task.
- *
- * A completed event needs to go back to waiting on its task, but we
- * don't want to set it there as soon as the event finishes. We need
- * to wait for the starter task to first become undone, otherwise the
- * event just cycles endlessly, and they don't in Adrift itself. Here
- * is where we wait for starter tasks to become undone.
- */
- if (evt_has_starter_task (game, event))
- {
- if (!evt_starter_task_is_complete (game, event))
- {
- if (evt_trace)
- sc_trace ("Event: starter task not complete\n");
-
- gs_set_event_state (game, event, ES_AWAITING);
- gs_set_event_time (game, event, 0);
- break;
- }
- }
- }
- break;
-
- case ES_PAUSED:
- {
- if (evt_trace)
- sc_trace ("Event: ticking paused event %ld\n", event);
-
- /* If the resumer has completed, resume this event. */
- if (evt_resumer_task_is_complete (game, event))
- {
- if (evt_trace)
- sc_trace ("Event: resume complete\n");
-
- gs_set_event_state (game, event, ES_RUNNING);
- break;
- }
- }
- break;
-
- default:
- sc_fatal ("evt_tick: invalid event state\n");
- }
-
- if (evt_trace)
- {
- sc_trace ("Event: after ticking event %ld: state %ld, time %ld\n", event,
- gs_event_state (game, event), gs_event_time (game, event));
- }
+evt_tick_event(sc_gameref_t game, sc_int event) {
+ if (evt_trace) {
+ sc_trace("Event: ticking event %ld: state %ld, time %ld\n", event,
+ gs_event_state(game, event), gs_event_time(game, event));
+ }
+
+ /* Handle call based on current event state. */
+ switch (gs_event_state(game, event)) {
+ case ES_WAITING: {
+ if (evt_trace)
+ sc_trace("Event: ticking waiting event %ld\n", event);
+
+ /*
+ * Because we also tick an event that goes from waiting to running,
+ * events started here will tick through RUNNING too, and have their
+ * time decremented. To get around this, so that the timer for one-
+ * shot events doesn't look one lower than it should after this
+ * transition, we need to set the initial time for events that start
+ * as soon as the game starts to one greater than that set by
+ * evt_start_time(). Here's the hack to do that; if the event starts
+ * immediately, its time will already be zero, even before decrement,
+ * which is how we tell which events to apply this hack to.
+ *
+ * TODO This seems to work, but also seems very dodgy.
+ */
+ if (gs_event_time(game, event) == 0) {
+ evt_start_event(game, event);
+
+ /* If the event time was set to zero, finish immediately. */
+ if (gs_event_time(game, event) <= 0)
+ evt_finish_event(game, event);
+ else
+ gs_set_event_time(game, event, gs_event_time(game, event) + 1);
+ break;
+ }
+
+ /*
+ * Decrement the event's time, and if it goes to zero, start running
+ * the event.
+ */
+ gs_decrement_event_time(game, event);
+
+ if (gs_event_time(game, event) <= 0) {
+ evt_start_event(game, event);
+
+ /* If the event time was set to zero, finish immediately. */
+ if (gs_event_time(game, event) <= 0)
+ evt_finish_event(game, event);
+ }
+ }
+ break;
+
+ case ES_RUNNING: {
+ if (evt_trace)
+ sc_trace("Event: ticking running event %ld\n", event);
+
+ /*
+ * Re-check the starter task; if it's no longer completed, we need
+ * to set the event back to waiting on task.
+ */
+ if (evt_has_starter_task(game, event)) {
+ if (!evt_starter_task_is_complete(game, event)) {
+ if (evt_trace)
+ sc_trace("Event: starter task not complete\n");
+
+ gs_set_event_state(game, event, ES_AWAITING);
+ gs_set_event_time(game, event, 0);
+ break;
+ }
+ }
+
+ /* If the pauser has completed, but resumer not, pause this event. */
+ if (evt_pauser_task_is_complete(game, event)
+ && !evt_resumer_task_is_complete(game, event)) {
+ if (evt_trace)
+ sc_trace("Event: pause complete\n");
+
+ gs_set_event_state(game, event, ES_PAUSED);
+ break;
+ }
+
+ /*
+ * Decrement the event's time, and print any notifications for a set
+ * number of turns from the event end.
+ */
+ gs_decrement_event_time(game, event);
+
+ if (evt_can_see_event(game, event))
+ evt_handle_preftime_notifications(game, event);
+
+ /* If the time goes to zero, finish running the event. */
+ if (gs_event_time(game, event) <= 0)
+ evt_finish_event(game, event);
+ }
+ break;
+
+ case ES_AWAITING: {
+ if (evt_trace)
+ sc_trace("Event: ticking awaiting event %ld\n", event);
+
+ /*
+ * Check the starter task. If it's completed, start running the
+ * event.
+ */
+ if (evt_starter_task_is_complete(game, event)) {
+ evt_start_event(game, event);
+
+ /* If the event time was set to zero, finish immediately. */
+ if (gs_event_time(game, event) <= 0)
+ evt_finish_event(game, event);
+ else {
+ /*
+ * If the pauser has completed, but resumer not, immediately
+ * also pause this event.
+ */
+ if (evt_pauser_task_is_complete(game, event)
+ && !evt_resumer_task_is_complete(game, event)) {
+ if (evt_trace)
+ sc_trace("Event: pause complete, immediate pause\n");
+
+ gs_set_event_state(game, event, ES_PAUSED);
+ }
+ }
+ }
+ }
+ break;
+
+ case ES_FINISHED: {
+ if (evt_trace)
+ sc_trace("Event: ticking finished event %ld\n", event);
+
+ /*
+ * Check the starter task; if it's not completed, we need to set the
+ * event back to waiting on task.
+ *
+ * A completed event needs to go back to waiting on its task, but we
+ * don't want to set it there as soon as the event finishes. We need
+ * to wait for the starter task to first become undone, otherwise the
+ * event just cycles endlessly, and they don't in Adrift itself. Here
+ * is where we wait for starter tasks to become undone.
+ */
+ if (evt_has_starter_task(game, event)) {
+ if (!evt_starter_task_is_complete(game, event)) {
+ if (evt_trace)
+ sc_trace("Event: starter task not complete\n");
+
+ gs_set_event_state(game, event, ES_AWAITING);
+ gs_set_event_time(game, event, 0);
+ break;
+ }
+ }
+ }
+ break;
+
+ case ES_PAUSED: {
+ if (evt_trace)
+ sc_trace("Event: ticking paused event %ld\n", event);
+
+ /* If the resumer has completed, resume this event. */
+ if (evt_resumer_task_is_complete(game, event)) {
+ if (evt_trace)
+ sc_trace("Event: resume complete\n");
+
+ gs_set_event_state(game, event, ES_RUNNING);
+ break;
+ }
+ }
+ break;
+
+ default:
+ sc_fatal("evt_tick: invalid event state\n");
+ }
+
+ if (evt_trace) {
+ sc_trace("Event: after ticking event %ld: state %ld, time %ld\n", event,
+ gs_event_state(game, event), gs_event_time(game, event));
+ }
}
@@ -808,35 +743,33 @@ evt_tick_event (sc_gameref_t game, sc_int event)
* Attempt to advance each event by one turn.
*/
void
-evt_tick_events (sc_gameref_t game)
-{
- sc_int event;
-
- /*
- * Tick all events. If an event transitions into a running state from a
- * paused or waiting state, tick that event again.
- */
- for (event = 0; event < gs_event_count (game); event++)
- {
- sc_int prior_state, state;
-
- /* Note current state, and tick event forwards. */
- prior_state = gs_event_state (game, event);
- evt_tick_event (game, event);
-
- /*
- * If the event went from paused or waiting to running, tick again.
- * This looks dodgy, and probably is, but it does keep timers correct
- * by only re-ticking events that have transitioned from non-running
- * states to a running one, and not already-running events. This is
- * in effect just adding a bit of turn processing to a tick that would
- * otherwise change state alone; a bit of laziness, in other words.
- */
- state = gs_event_state (game, event);
- if (state == ES_RUNNING
- && (prior_state == ES_PAUSED || prior_state == ES_WAITING))
- evt_tick_event (game, event);
- }
+evt_tick_events(sc_gameref_t game) {
+ sc_int event;
+
+ /*
+ * Tick all events. If an event transitions into a running state from a
+ * paused or waiting state, tick that event again.
+ */
+ for (event = 0; event < gs_event_count(game); event++) {
+ sc_int prior_state, state;
+
+ /* Note current state, and tick event forwards. */
+ prior_state = gs_event_state(game, event);
+ evt_tick_event(game, event);
+
+ /*
+ * If the event went from paused or waiting to running, tick again.
+ * This looks dodgy, and probably is, but it does keep timers correct
+ * by only re-ticking events that have transitioned from non-running
+ * states to a running one, and not already-running events. This is
+ * in effect just adding a bit of turn processing to a tick that would
+ * otherwise change state alone; a bit of laziness, in other words.
+ */
+ state = gs_event_state(game, event);
+ if (state == ES_RUNNING
+ && (prior_state == ES_PAUSED || prior_state == ES_WAITING))
+ evt_tick_event(game, event);
+ }
}
@@ -846,9 +779,8 @@ evt_tick_events (sc_gameref_t game)
* Set event tracing on/off.
*/
void
-evt_debug_trace (sc_bool flag)
-{
- evt_trace = flag;
+evt_debug_trace(sc_bool flag) {
+ evt_trace = flag;
}
} // End of namespace Adrift