Go to the documentation of this file.
41 #define TAG_START "[color=#aa55ff]"
42 #define TAG_END "[/color]"
45 #define QC_CAN_RESTART -1
74 for (
const auto qs :
quest->steps) {
102 int warned = 0,
state;
107 file = fopen(
final,
"r");
113 while (fgets(read,
sizeof(read),
file) != NULL) {
114 if (sscanf(read,
"quest %s\n",
data)) {
123 LOG(
llevError,
"quest: invalid file format for %s\n",
final);
128 if (sscanf(read,
"state %d\n", &
state)) {
140 if (strcmp(read,
"end_quest\n") == 0) {
155 if (sscanf(read,
"completed %d\n", &
state)) {
160 LOG(
llevError,
"quest: invalid line in %s: %s\n",
final, read);
164 LOG(
llevError,
"quest: missing end_quest in %s\n",
final);
190 fprintf(
file,
"quest %s\n",
state->code);
191 fprintf(
file,
"state %d\n",
state->state);
192 fprintf(
file,
"completed %d\n",
state->was_completed);
193 fprintf(
file,
"end_quest\n");
300 if (conditions.empty())
302 for (
const auto cond : conditions) {
304 if (cond->minstep < 0 && cond->maxstep < 0) {
309 if (current_step < cond->minstep || current_step > cond->maxstep)
321 new_step=new_step<step->
step?step->
step:new_step;
326 if (new_step > current_step) {
358 LOG(
llevError,
"quest: asking for set_state of unknown quest %s!\n", quest_code);
363 if (!dm &&
state <= 0) {
364 LOG(
llevDebug,
"quest_set_player_state: warning: called with invalid state %d for quest %s, player %s\n",
state,
pl->ob->name, quest_code);
368 if (started && qs->
state == 0) {
370 LOG(
llevDebug,
"quest_set_player_state: warning: called for player %s not having started quest %s\n",
pl->ob->name, quest_code);
385 LOG(
llevError,
"quest_set_player_state: couldn't find state definition %d for quest %s, player %s\n",
state, quest_code,
pl->ob->name);
395 if (
quest->quest_restart)
405 if (
pl->socket->notifications > 0) {
425 assert(step != NULL);
432 if (
pl->has_directory)
450 int completed_count = 0, restart_count = 0, total_count = 0, current_count = 0;
455 if (
quest->parent == NULL) {
461 }
else if(
state->is_complete) {
467 if (completed_count > 0) {
469 if (restart_count > 0)
471 "%s completed %d out of %zu quests, of which %d may be restarted.",
name, completed_count,
quests_count(
false), restart_count);
474 "%s completed %d quests",
name, completed_count);
475 current_count = completed_count;
478 "%s completed the following quests:",
name);
482 if (
quest->parent == NULL) {
487 "(%3d) %s%s", ++current_count,
quest->quest_title, restart);
494 if (total_count > completed_count) {
496 "%s started the following quests:",
name);
500 if (
quest->parent == NULL) {
504 "(%3d) %s", ++current_count,
quest->quest_title);
544 if (number <= 0 || !pq) {
552 if (++questnum == number)
return state;
560 if (++questnum == number)
return state;
594 std::for_each(
quest->steps.cbegin(),
quest->steps.cend(), [&
pl] (
const auto &step) {
595 draw_ext_info_format(NDI_UNIQUE, 0, pl->ob, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_QUESTS,
" " TAG_START
"Step:" TAG_END
" %d (%s)", step->step, step->step_description);
602 const char *restart =
"";
603 if (
quest->quest_restart)
604 restart =
i18n(
pl->ob,
" (can be replayed)");
620 prefix =
"Current Status";
687 LOG(
llevError,
"quest_start: requested unknown quest %s\n", quest_code);
695 LOG(
llevDebug,
"quest_start: negative state %d for %s quest %s\n",
state,
pl->ob->name, quest_code);
700 LOG(
llevDebug,
"quest_start: warning: player %s has already started quest %s\n",
pl->ob->name, quest_code);
744 LOG(
llevError,
"command_quest called for a non player!\n");
754 char* dup = strdup(
params);
755 char* space = strchr(dup,
' ');
779 if (strcmp(
params,
"list all") == 0) {
784 if (strcmp(
params,
"list") == 0) {
789 if (strncmp(
params,
"info ", 5) == 0) {
790 int number = atoi(
params+5);
799 if (strncmp(
params,
"info_c ", 7) == 0) {
800 int number = atoi(
params+7);
805 if (
q &&
q->client_code == (uint32_t)number) {
819 char *dup = strdup(
params + 4);
820 char *space = strrchr(dup,
' ');
836 state = atoi(space + 1);
863 for (
int i = 0; i < d->
level; i++) {
868 fprintf(
logfile,
"%s%s - %s - %zu steps (%srestartable)\n",
prefix,
quest->quest_code,
quest->quest_title,
quest->steps.size(),
quest->quest_restart ?
"" :
"not ");
917 if (
pl->socket->notifications < 1)
927 if (
state->state == -1)
932 size = 2 + (2 + strlen(
quest->quest_title)) + 4 + 1 + (2 + (step != NULL ? strlen(step->
step_description) : 0));
953 state->sent_to_client = 1;
969 if (qp != NULL && qp->
quests != NULL) {
void SockList_AddInt(SockList *sl, uint32_t data)
static void output_quests(const quest_definition *quest, void *user)
#define MSG_TYPE_COMMAND_SUCCESS
void quest_for_each(quest_op op, void *user)
void LOG(LogLevel logLevel, const char *format,...)
int of_close(OutputFile *of)
FILE * of_open(OutputFile *of, const char *fname)
static quest_player * get_or_create_quest(player *pl)
#define QUERY_FLAG(xyz, p)
static void quest_write_player_data(const quest_player *pq)
static quest_state * get_new_quest_state(void)
void quest_first_player_save(player *pl)
void SockList_AddString(SockList *sl, const char *data)
static void quest_set_state(player *dm, player *pl, sstring quest_code, int state, int started)
static void quest_info(player *pl, player *who, quest_state *qs, int level)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
#define MSG_TYPE_COMMAND_QUESTS
static quest_player * get_quest(player *pl)
const quest_definition * parent
static quest_state * get_quest_by_number(player *pl, int number)
void SockList_AddLen16Data(SockList *sl, const void *data, size_t len)
void SockList_Reset(SockList *sl)
static void free_state(quest_player *pq)
size_t SockList_Avail(const SockList *sl)
#define MSG_TYPE_ADMIN_DM
sstring add_refcount(sstring str)
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
static void do_update(const quest_definition *quest, void *user)
sstring add_string(const char *str)
void SockList_AddShort(SockList *sl, uint16_t data)
void SockList_AddChar(SockList *sl, unsigned char c)
static quest_step_definition * quest_get_step(quest_definition *quest, int step)
struct quest_definition * parent
static void update_quests(player *pl)
static void quest_list(player *pl, player *who, int showall, const char *name)
void command_help(object *op, const char *params)
quest_definition * quest_get_by_code(sstring code)
void SockList_Init(SockList *sl)
static void quest_display(player *pl, quest_player *pq, int showall, const char *name)
static quest_state * get_or_create_state(quest_player *pq, sstring name)
void fatal(enum fatal_error err)
void quest_set_player_state(player *pl, sstring quest_code, int state)
#define MSG_TYPE_ADMIN_LOADSAVE
void free_string(sstring str)
void quest_send_initial_states(player *pl)
void SockList_Term(SockList *sl)
int quest_get_player_state(player *pl, sstring quest_code)
#define MSG_TYPE_COMMAND_FAILURE
quest_definition * quest_find_by_code(sstring code)
void quest_start(player *pl, sstring quest_code, int state)
static void quest_read_player_data(quest_player *pq)
const typedef char * sstring
static quest_state * get_state(quest_player *pq, sstring name)
int quest_was_completed(player *pl, sstring quest_code)
player * find_player_partial_name(const char *plname)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
void command_quest(object *op, const char *params)
std::vector< quest_condition * > conditions
SockList * player_get_delayed_buffer(player *pl)
void Send_With_Handling(socket_struct *ns, SockList *sl)
static quest_player * player_states
static int evaluate_quest_conditions(const std::vector< quest_condition * > conditions, player *pl)
const char * i18n(const object *who, const char *code)