+
+/* Pass to obey_msg() lines from file at "path", on "record" write to same. Do
+ * not pass lines that consist only of a newline character. Transform newline
+ * in the line passed to \0.
+ */
+static void obey_lines_from_file(char * path, uint8_t record);
+
+/* Replay game from record file up to the turn named in world.replay, then turn
+ * over to manual replay via io_loop().
+ */
+static void replay_game();
+
+/* Return 1 if the type defined by world.player_type has a .start_n of 0.
+ * Return 2 if no thing action with .name of s[S_CMD_WAIT] is defined.
+ * Else, return 0.
+ */
+static uint8_t world_cannot_be_made();
+
+
+static void obey_lines_from_file(char * path, uint8_t record)
+{
+ FILE * file = try_fopen(path, "r", __func__);
+ uint32_t linemax = textfile_width(file);
+ char * line = try_malloc(linemax + 1, __func__);
+ while (NULL != try_fgets(line, linemax + 1, file, __func__))
+ {
+ if (strlen(line))
+ {
+ if (strcmp("\n", line))
+ {
+ char * nl = strchr(line, '\n');
+ if (nl)
+ {
+ *nl = '\0';
+ }
+ obey_msg(line, record, 1);
+ }
+ err_line_inc();
+ }
+ }
+ free(line);
+ try_fclose(file, __func__);
+}
+
+
+
+static void replay_game()
+{
+ exit_err(access(s[S_PATH_RECORD], F_OK), "No record found to replay.");
+ FILE * file = try_fopen(s[S_PATH_RECORD], "r", __func__);
+ uint32_t linemax = textfile_width(file);
+ char * line = try_malloc(linemax + 1, __func__);
+ while ( world.turn < world.replay
+ && NULL != try_fgets(line, linemax + 1, file, __func__))
+ {
+ obey_msg(line, 0, 1);
+ err_line_inc();
+ }
+ uint8_t end = 0;
+ while (!io_loop())
+ {
+ if (!end)
+ {
+ end = (NULL == try_fgets(line, linemax + 1, file, __func__));
+ if (!end)
+ {
+ obey_msg(line, 0, 1);
+ err_line_inc();
+ }
+ }
+ }
+ free(line);
+ try_fclose(file, __func__);
+}
+
+
+
+static uint8_t world_cannot_be_made()
+{
+ uint8_t player_will_be_generated = 0;
+ struct ThingType * tt;
+ for (tt = world.thing_types; NULL != tt; tt = tt->next)
+ {
+ if (world.player_type == tt->id)
+ {
+ player_will_be_generated = 0 < tt->start_n;
+ break;
+ }
+ }
+ if (!player_will_be_generated)
+ {
+ return 1;
+ }
+ if (!get_thing_action_id_by_name(s[S_CMD_WAIT]))
+ {
+ return 2;
+ }
+ return 0;
+}
+
+
+