+
+
+/* Do god commands to create / position things generate their fields of view? */
+static uint8_t do_fov = 0;
+
+
+
+static uint8_t parse_carry(char * tok0, char * tok1, struct Thing * t)
+{
+ uint8_t id;
+ if (parse_val(tok0, tok1, s[S_CMD_CARRIES], '8', (char *) &id))
+ {
+ if (!err_line(id == t->id, "Thing cannot carry itself."))
+ {
+ struct Thing * o = get_thing(world.things, id, 0);
+ if (!err_line(!o, "Thing cannot carry thing that does not exist."))
+ {
+ own_thing(&(t->owns), &world.things, id);
+ o->pos = t->pos;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t parse_position(char* tok0, char * tok1, struct Thing * t)
+{
+ char axis = 0;
+ if (!strcmp(tok0, s[S_CMD_POS_Y]))
+ {
+ axis = 'y';
+ }
+ else if (!strcmp(tok0, s[S_CMD_POS_X]))
+ {
+ axis = 'x';
+ }
+ if (axis && !parsetest_int(tok1, '8'))
+ {
+ uint8_t length = atoi(tok1);
+ char * err = "Position is outside of map.";
+ if (!err_line(length >= world.map.length, err))
+ {
+ if ('y' == axis)
+ {
+ t->pos.y = length;
+ }
+ else if ('x' == axis)
+ {
+ t->pos.x = length;
+ }
+ free(t->fov_map);
+ t->fov_map= do_fov && t->lifepoints ? build_fov_map(t) : t->fov_map;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t parse_thing_type(char * tok0, char * tok1, struct Thing * t)
+{
+ uint8_t type;
+ if (parse_val(tok0, tok1, s[S_CMD_TYPE], '8', (char *) &type))
+ {
+ struct ThingType * tt = world.thing_types;
+ for (; NULL != tt && type != tt->id; tt = tt->next);
+ if (!err_line(!tt, "Thing type does not exist."))
+ {
+ t->type = type;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t parse_thing_command(char * tok0, char * tok1, struct Thing * t)
+{
+ uint8_t command;
+ if (parse_val(tok0, tok1, s[S_CMD_COMMAND], '8', (char *) &command))
+ {
+ if (!command)
+ {
+ t->command = command;
+ return 1;
+ }
+ struct ThingAction * ta = world.thing_actions;
+ for (; NULL != ta && command != ta->id; ta = ta->next);
+ if (!err_line(!ta, "Thing action does not exist."))
+ {
+ t->command = command;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t parse_do_fov(char * tok0, char * tok1)
+{
+ if (parse_val(tok0, tok1, s[S_CMD_DO_FOV], '8', (char *) &do_fov))
+ {
+ if (do_fov)
+ {
+ struct Thing * ti;
+ for (ti = world.things; ti; ti = ti->next)
+ {
+ ti->fov_map = ti->lifepoints ? build_fov_map(ti) : ti->fov_map;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t parse_thing_manipulation(char * tok0, char * tok1)
+{
+ uint8_t id;
+ static struct Thing * t = NULL;
+ if (t && ( parse_thing_type(tok0, tok1, t)
+ || parse_thing_command(tok0, tok1, t)
+ || parse_val(tok0, tok1, s[S_CMD_ARGUMENT], '8', (char *)&t->arg)
+ || parse_val(tok0,tok1,s[S_CMD_PROGRESS],'8',(char *)&t->progress)
+ || parse_val(tok0, tok1, s[S_CMD_LIFEPOINTS], '8',
+ (char *) &t->lifepoints)
+ || parse_position(tok0, tok1, t)
+ || parse_carry(tok0, tok1, t)));
+ else if (parse_val(tok0, tok1, s[S_CMD_THING], '8', (char *) &id))
+ {
+ t = get_thing(world.things, id, 1);
+ if (!t)
+ {
+ t = add_thing(id, 0, 0);
+ set_cleanup_flag(CLEANUP_THINGS);
+ t->fov_map= do_fov && t->lifepoints ? build_fov_map(t) : t->fov_map;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+
+static uint8_t parse_player_command_0arg(char * tok0, char * tok1)
+{
+ struct Thing * player = get_player();
+ if (!strcmp(tok0, s[S_CMD_WAIT]) || !strcmp(tok0, s[S_CMD_PICKUP]))
+ {
+ player->command = get_thing_action_id_by_name(tok0);
+ player->arg = 0;
+ turn_over();
+ err_line (NULL != tok1, "No arguments expected, ignoring arguments.");
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t set_char_by_string_comparison(char * string, char * comparand,
+ char * c_to_set, char value)
+{
+ if (!strcmp(string, comparand))
+ {
+ * c_to_set = value;
+ return 1;
+ }
+ return 0;
+}
+
+
+
+static uint8_t parse_player_command_1arg(char * tok0, char * tok1)
+{
+ struct Thing * player = get_player();
+ if (
+ parse_val(tok0, tok1, s[S_CMD_DROP], '8', (char *) &player->arg)
+ || parse_val(tok0, tok1, s[S_CMD_USE], '8', (char *) &player->arg))
+ {
+ player->command = get_thing_action_id_by_name(tok0);
+ turn_over();
+ }
+ else if (!strcmp(tok0, s[S_CMD_MOVE]))
+ {
+ char dir = '\0';
+ if (!( set_char_by_string_comparison(tok1, "east", &dir, 'd')
+ || set_char_by_string_comparison(tok1, "south-east", &dir, 'c')
+ || set_char_by_string_comparison(tok1, "south-west", &dir, 'x')
+ || set_char_by_string_comparison(tok1, "west", &dir, 's')
+ || set_char_by_string_comparison(tok1, "north-west", &dir, 'w')
+ || set_char_by_string_comparison(tok1, "north-east", &dir, 'e')))
+ {
+ return 0;
+ }
+ player->arg = dir;
+ player->command = get_thing_action_id_by_name(tok0);
+ turn_over();
+ }
+ else
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+
+static uint8_t parse_command_1arg(char * tok0, char * tok1)
+{
+ char * tok2 = token_from_line(NULL);
+ if ( parse_thing_manipulation(tok0, tok1)
+ || parse_player_command_1arg(tok0, tok1)
+ || parse_val(tok0, tok1, s[S_CMD_SEED_RAND], 'U', (char *) &world.seed)
+ || parse_val(tok0, tok1, s[S_CMD_TURN], 'u', (char *) &world.turn)
+ || parse_do_fov(tok0, tok1));
+ else if (parse_val(tok0,tok1,s[S_CMD_SEED_MAP],'U',(char *)&world.seed_map))
+
+ {
+ remake_map();
+ }
+ else if (parse_val(tok0, tok1, s[S_CMD_MAKE_WORLD],'U',(char *)&world.seed))
+ {
+ remake_world();
+ }
+ else
+ {
+ return 0;
+ }
+ char * err = "But one argument expected, ignoring further arguments.";
+ err_line (NULL != tok2, err);
+ return 1;
+}
+
+
+
+static void server_test()
+{
+ char * f_name = "server_test()";
+ char test[10 + 1 + 10 + 1 + 1];
+ FILE * file = try_fopen(s[S_PATH_OUT], "r", f_name);
+ try_fgets(test, 10 + 10 + 1 + 1, file, f_name);
+ try_fclose(file, f_name);
+ if (strcmp(test, world.server_test))
+ {
+ unset_cleanup_flag(CLEANUP_WORLDSTATE);
+ unset_cleanup_flag(CLEANUP_OUT);
+ unset_cleanup_flag(CLEANUP_IN);
+ char * msg = "Server test string in server output file does not match. "
+ "This indicates that the current server process has been "
+ "superseded by another one.";
+ exit_err(1, msg);
+ }
+}