38 #define QC_CAN_RESTART -1 154 #define QUESTFILE_NEXTQUEST 0 155 #define QUESTFILE_QUEST 1 156 #define QUESTFILE_QUESTDESC 2 157 #define QUESTFILE_STEP 3 158 #define QUESTFILE_STEPDESC 4 159 #define QUESTFILE_STEPCOND 5 170 int minstep, maxstep;
181 int loaded_quests =0, found =0;
183 file = fopen(
final,
"r");
185 LOG(
llevError,
"Can't open %s for reading quests\n", filename);
189 while (fgets(read,
sizeof(read), file) != NULL) {
191 if (strcmp(read,
"end_setwhen\n") == 0) {
206 condition_parsed = 0;
208 if (sscanf(read,
"%s %d-%d\n", namedquest, &minstep, &maxstep)!=3) {
209 if (sscanf(read,
"%s <=%d\n", namedquest, &maxstep)== 2) {
212 }
else if (sscanf(read,
"%s %d\n", namedquest, &minstep)==2) {
215 }
else if (strstr(read,
"finished")) {
216 if (sscanf(read,
"%s finished\n", namedquest)==1) {
217 minstep = maxstep = -1;
223 if (!condition_parsed) {
234 LOG(
llevDebug,
"condition added for step %d of quest %s, looking for quest %s between steps %d and %d\n",
239 if (strcmp(read,
"end_description\n") == 0) {
258 if (strcmp(read,
"end_step\n") == 0) {
263 if (strcmp(read,
"finishes_quest\n") == 0) {
267 if (strcmp(read,
"description\n") == 0) {
272 if (strcmp(read,
"setwhen\n") == 0) {
276 LOG(
llevError,
"quests: invalid line %s in definition of quest %s in file %s!\n",
282 if (strcmp(read,
"end_description\n") == 0) {
300 if (strcmp(read,
"end_quest\n") == 0) {
306 if (strcmp(read,
"description\n") == 0) {
312 if (strncmp(read,
"title ", 6) == 0) {
313 read[strlen(read) - 1] =
'\0';
318 if (sscanf(read,
"step %d\n", &i)) {
327 if (sscanf(read,
"restart %d\n", &i)) {
331 if (strncmp(read,
"parent ", 7) == 0) {
332 read[strlen(read) - 1] =
'\0';
335 LOG(
llevError,
"Quest %s lists %s, as a parent, but this hasn't been defined\n", quest->
quest_code, questname);
343 if (strncmp(read,
"face ", 5) == 0) {
345 read[strlen(read) - 1] =
'\0';
359 if (strncmp(read,
"quest ", 6) == 0) {
361 read[strlen(read) - 1] =
'\0';
364 LOG(
llevError,
"Quest %s is listed in file %s, but this quest has already been defined\n", quest->
quest_code, filename);
378 if (sscanf(read,
"include %s\n", includefile)) {
383 LOG(
llevDebug,
"loaded %d quests from file %s\n", found, inc_path);
384 loaded_quests += found;
386 LOG(
llevError,
"Failed to load quests from file %s\n", inc_path);
391 if (strcmp(read,
"\n") == 0)
394 LOG(
llevError,
"quest: invalid file format for %s, I don't know what to do with the line %s\n",
final, read);
400 LOG(
llevError,
"quest: quest definition file %s read in, ends with state %d\n",
final, in);
408 return loaded_quests;
435 if (qsd->
step == step)
457 LOG(
llevError,
"quest %s required but not found!\n", code);
482 int warned = 0,
state;
490 file = fopen(
final,
"r");
496 while (fgets(read,
sizeof(read), file) != NULL) {
497 if (sscanf(read,
"quest %s\n", data)) {
506 LOG(
llevError,
"quest: invalid file format for %s\n",
final);
511 if (sscanf(read,
"state %d\n", &
state)) {
513 if (quest != NULL &&
state != -1) {
523 if (strcmp(read,
"end_quest\n") == 0) {
538 if (sscanf(read,
"completed %d\n", &
state)) {
543 LOG(
llevError,
"quest: invalid line in %s: %s\n",
final, read);
547 LOG(
llevError,
"quest: missing end_quest in %s\n",
final);
573 fprintf(file,
"quest %s\n", state->
code);
574 fprintf(file,
"state %d\n", state->
state);
576 fprintf(file,
"end_quest\n");
597 if (qs->
code == name)
694 if (current_step < cond->minstep || current_step > cond->
maxstep)
714 int new_step, current_step;
722 new_step=new_step<step->
step?step->
step:new_step;
728 if (new_step > current_step) {
754 LOG(
llevError,
"quest: asking for set_state of unknown quest %s!\n", quest_code);
761 LOG(
llevDebug,
"quest_set_player_state: warning: called with invalid state %d for quest %s, player %s\n", state, pl->
ob->
name, quest_code);
771 LOG(
llevError,
"quest_set_player_state: couldn't find state definition %d for quest %s, player %s\n", state, quest_code, pl->
ob->
name);
776 if (started && qs->
state == 0) {
778 LOG(
llevDebug,
"quest_set_player_state: warning: called for player %s not having started quest %s\n", pl->
ob->
name, quest_code);
819 assert(step != NULL);
847 int completed_count = 0, restart_count = 0, total_count = 0, current_count = 0;
852 if (quest->
parent == NULL) {
864 if (completed_count > 0) {
866 if (restart_count > 0)
868 "%s completed %d quests, of which %d may be restarted", name, completed_count, restart_count);
871 "%s completed %d quests", name, completed_count);
872 current_count = completed_count;
875 "%s completed the following quests:", name);
879 if (quest->
parent == NULL) {
884 "(%3d) %s%s", ++current_count, quest->
quest_title, restart);
891 if (total_count > completed_count) {
893 "%s started the following quests:", name);
897 if (quest->
parent == NULL) {
959 if (number <= 0 || !pq) {
967 if (++questnum == number)
return state;
975 if (++questnum == number)
return state;
1010 for (step = quest->
steps; step != NULL; step = step->
next) {
1018 const char *restart =
"";
1020 restart =
" (can be replayed)";
1036 prefix =
"Current Status";
1044 if (child->
parent == quest)
1046 state = state->
next;
1103 LOG(
llevError,
"quest_start: requested unknown quest %s\n", quest_code);
1111 LOG(
llevDebug,
"quest_start: negative state %d for %s quest %s\n", state, pl->
ob->
name, quest_code);
1116 LOG(
llevDebug,
"quest_start: warning: player %s has already started quest %s\n", pl->
ob->
name, quest_code);
1160 LOG(
llevError,
"command_quest called for a non player!\n");
1164 if (!params || *params ==
'\0') {
1170 char* dup =
strdup(params);
1171 char* space = strchr(dup,
' ');
1174 if (space == NULL) {
1179 params = params + (space - dup) + 1;
1182 if (other == NULL) {
1195 if (strcmp(params,
"list all") == 0) {
1200 if (strcmp(params,
"list") == 0) {
1205 if (strncmp(params,
"info ", 5) == 0) {
1206 int number = atoi(params+5);
1215 if (strncmp(params,
"info_c ", 7) == 0) {
1216 int number = atoi(params+7);
1235 char *dup =
strdup(params + 4);
1236 char *space = strrchr(dup,
' ');
1239 if (space == NULL) {
1252 state = atoi(space + 1);
1272 int questcount = 0, stepcount, i;
1277 for (i=0; i<level; i++) {
1278 strncat(prefix,
"-",
MAX_BUF - 1);
1284 if (quest->
parent == parent) {
1287 step = quest->
steps;
1295 quest = quest->
next;
1322 player_states = NULL;
1335 while (quest != NULL) {
1336 next_quest = quest->
next;
1342 step = quest->
steps;
1343 while (step != NULL) {
1344 next_step = step->
next;
1347 while (condition != NULL) {
1348 next_condition = condition->
next;
1351 condition = next_condition;
1387 for (state = states->
quests; state != NULL; state = state->
next) {
1390 if (state->
state == -1)
1432 if (qp != NULL && qp->
quests != NULL) {
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
void quest_first_player_save(player *pl)
static void output_quests(quest_definition *parent, int level)
void SockList_Reset(SockList *sl)
struct quest_player quest_player
void SockList_Init(SockList *sl)
sstring add_refcount(sstring str)
#define MSG_TYPE_COMMAND_FAILURE
static void quest_read_player_data(quest_player *pq)
void fatal(enum fatal_error err)
static quest_definition * quest_create_definition(void)
struct quest_step_definition quest_step_definition
struct quest_player * next
StringBuffer * stringbuffer_new(void)
void free_string(sstring str)
static quest_condition * quest_create_condition(void)
void SockList_AddShort(SockList *sl, uint16_t data)
struct quest_state * quests
void SockList_AddLen16Data(SockList *sl, const void *data, size_t len)
#define MSG_TYPE_ADMIN_LOADSAVE
void SockList_AddInt(SockList *sl, uint32_t data)
static void quest_info(player *pl, player *who, quest_state *qs, int level)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
static quest_player * get_quest(player *pl)
struct quest_condition quest_condition
static quest_state * get_quest_by_number(player *pl, int number)
static void update_quests(player *pl)
static void quest_list(player *pl, player *who, int showall, const char *name)
void quest_start(player *pl, sstring quest_code, int state)
struct quest_definition quest_definition
#define MSG_TYPE_ADMIN_DM
static quest_state * get_new_quest_state(void)
static int load_quests_from_file(const char *filename)
struct quest_state * next
void stringbuffer_append_string(StringBuffer *sb, const char *str)
static quest_state * get_state(quest_player *pq, sstring name)
#define MSG_TYPE_COMMAND_SUCCESS
struct quest_step_definition * next
void SockList_Term(SockList *sl)
static void quest_write_player_data(const quest_player *pq)
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
int of_close(OutputFile *of)
struct quest_definition * next
void SockList_AddString(SockList *sl, const char *data)
quest_condition * conditions
void quest_send_initial_states(player *pl)
static quest_step_definition * quest_get_step(quest_definition *quest, int step)
size_t SockList_Avail(const SockList *sl)
#define QUERY_FLAG(xyz, p)
#define QUESTFILE_QUESTDESC
void free_quest_definitions(void)
static int evaluate_quest_conditions(const quest_condition *condition, player *pl)
void quest_set_player_state(player *pl, sstring quest_code, int state)
static void quest_load_definitions(void)
struct quest_definition * parent
void SockList_AddChar(SockList *sl, unsigned char c)
#define QUESTFILE_NEXTQUEST
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
void command_quest(object *op, const char *params)
static void quest_set_state(player *dm, player *pl, sstring quest_code, int state, int started)
#define QUESTFILE_STEPCOND
static quest_step_definition * quest_create_step(void)
int quest_get_player_state(player *pl, sstring quest_code)
FILE * of_open(OutputFile *of, const char *fname)
#define MSG_TYPE_COMMAND_INFO
static void quest_display(player *pl, quest_player *pq, int showall, const char *name)
static quest_definition * quest_get(sstring code)
sstring add_string(const char *str)
static quest_state * get_or_create_state(quest_player *pq, sstring name)
struct quest_condition * next
static quest_definition * quests
char * strdup(const char *str)
void LOG(LogLevel logLevel, const char *format,...)
quest_step_definition * steps
int quest_was_completed(player *pl, sstring quest_code)
static void quest_help(player *pl)
sstring quest_description
const Face * find_face(const char *name, const Face *error)
static quest_player * player_states
static quest_player * get_or_create_quest(player *pl)
player * find_player_partial_name(const char *plname)
#define QUESTFILE_STEPDESC
static quest_definition * quest_get_by_code(sstring code)
static void free_state(quest_player *pq)
char * stringbuffer_finish(StringBuffer *sb)
struct quest_state quest_state
void Send_With_Handling(socket_struct *ns, SockList *sl)