41 #define TAG_START "[color=#aa55ff]" 42 #define TAG_END "[/color]" 45 #define QC_CAN_RESTART -1 79 for (
const auto qs : quest->
steps) {
107 int warned = 0,
state;
112 file = fopen(
final,
"r");
118 while (fgets(read,
sizeof(read), file) != NULL) {
119 if (sscanf(read,
"quest %s\n", data)) {
128 LOG(
llevError,
"quest: invalid file format for %s\n",
final);
133 if (sscanf(read,
"state %d\n", &
state)) {
135 if (quest != NULL &&
state != -1 &&
state != 0) {
145 if (strcmp(read,
"end_quest\n") == 0) {
160 if (sscanf(read,
"completed %d\n", &
state)) {
165 LOG(
llevError,
"quest: invalid line in %s: %s\n",
final, read);
169 LOG(
llevError,
"quest: missing end_quest in %s\n",
final);
195 fprintf(file,
"quest %s\n", state->
code);
196 fprintf(file,
"state %d\n", state->
state);
198 fprintf(file,
"end_quest\n");
219 if (qs->
code == name)
305 if (conditions.empty())
307 for (
const auto cond : conditions) {
309 if (cond->minstep < 0 && cond->maxstep < 0) {
314 if (current_step < cond->minstep || current_step > cond->maxstep)
326 new_step=new_step<step->
step?step->
step:new_step;
331 if (new_step > current_step) {
363 LOG(
llevError,
"quest: asking for set_state of unknown quest %s!\n", quest_code);
368 if (!dm && state < 0) {
369 LOG(
llevDebug,
"quest_set_player_state: warning: called with invalid state %d for quest %s, player %s\n", state, pl->
ob->
name, quest_code);
373 if (started && qs->
state == 0) {
375 LOG(
llevDebug,
"quest_set_player_state: warning: called for player %s not having started quest %s\n", pl->
ob->
name, quest_code);
385 if (!step && state != 0) {
389 LOG(
llevError,
"quest_set_player_state: couldn't find state definition %d for quest %s, player %s\n", state, quest_code, pl->
ob->
name);
403 }
else if (step != 0) {
431 const char *not_started =
"Not started.";
456 int completed_count = 0, restart_count = 0, total_count = 0, current_count = 0;
461 if (quest->
parent == NULL) {
473 if (completed_count > 0) {
475 if (restart_count > 0)
477 "%s completed %d out of %zu quests, of which %d may be restarted.", name, completed_count,
quests_count(
false), restart_count);
480 "%s completed %d quests", name, completed_count);
481 current_count = completed_count;
484 "%s completed the following quests:", name);
488 if (quest->
parent == NULL) {
493 "(%3d) %s%s", ++current_count, quest->
quest_title, restart);
500 if (total_count > completed_count) {
502 "%s started the following quests:", name);
506 if (quest->
parent == NULL) {
550 if (number <= 0 || !pq) {
558 if (++questnum == number)
return state;
566 if (++questnum == number)
return state;
600 std::for_each(quest->
steps.cbegin(), quest->
steps.cend(), [&pl] (
const auto &step) {
608 const char *restart =
"";
610 restart =
i18n(pl->
ob,
" (can be replayed)");
626 prefix =
"Current Status";
634 if (child->
parent == quest)
693 LOG(
llevError,
"quest_start: requested unknown quest %s\n", quest_code);
701 LOG(
llevDebug,
"quest_start: negative state %d for %s quest %s\n", state, pl->
ob->
name, quest_code);
706 LOG(
llevDebug,
"quest_start: warning: player %s has already started quest %s\n", pl->
ob->
name, quest_code);
750 LOG(
llevError,
"command_quest called for a non player!\n");
754 if (!params || *params ==
'\0') {
760 char* dup = strdup(params);
761 char* space = strchr(dup,
' ');
769 params = params + (space - dup) + 1;
782 name =
i18n(op,
"You");
785 if (strcmp(params,
"list all") == 0) {
790 if (strcmp(params,
"list") == 0) {
795 if (strncmp(params,
"info ", 5) == 0) {
796 int number = atoi(params+5);
805 if (strncmp(params,
"info_c ", 7) == 0) {
806 int number = atoi(params+7);
824 if (strncmp(params,
"reset ", 6) == 0) {
825 int number = atoi(params+6);
829 "You cannot reset a quest that you haven't started.");
834 "Quest progress reset.");
839 char *dup = strdup(params + 4);
840 char *space = strrchr(dup,
' ');
856 state = atoi(space + 1);
883 for (
int i = 0; i < d->
level; i++) {
884 strncat(prefix,
"-",
MAX_BUF - 1);
892 r.level = d->
level + 1;
921 player_states = NULL;
944 for (state = states->
quests; state != NULL; state = state->
next) {
989 if (qp != NULL && qp->
quests != NULL) {
#define NDI_DELAYED
If set, then message is sent only after the player's tick completes.
sstring step_description
Step description to show player.
void SockList_Reset(SockList *sl)
Resets the length of the stored data for writing.
static quest_state * get_or_create_state(quest_player *pq, sstring name)
Get the state of a quest for a player, creating it if not existing yet.
static void free_state(quest_player *pq)
Free quests structures.
#define NS_FACESENT_FACE
Bitmask for the faces_sent[] array - what portion of the face have we sent?
Definition of an in-game quest.
FILE * logfile
Used by server/daemon.c.
void command_quest(object *op, const char *params)
Command handler for 'quest'.
void SockList_Init(SockList *sl)
Initializes the SockList instance.
void quest_start(player *pl, sstring quest_code, int state)
Start a quest for a player.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
void quest_send_initial_states(player *pl)
Send the current quest states for the specified player, if the client supports those notifications...
#define MSG_TYPE_COMMAND_FAILURE
Failed result from command.
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
std::vector< quest_step_definition * > steps
Quest steps.
static void update_quests(player *pl)
Look through all of the quests for the given player, and see if any need to be updated.
const char * i18n(const object *who, const char *code)
Translate a message in the appropriate language.
quest_state * next
Next quest on the list.
void quest_set_player_state(player *pl, sstring quest_code, int state)
Set the state of a quest for a player.
const char * playerdir
Where the player files are.
sstring add_string(const char *str)
Share a string.
void SockList_AddShort(SockList *sl, uint16_t data)
Adds a 16 bit value.
static quest_step_definition * quest_get_step(quest_definition *quest, int step)
Get a step for the specified quest.
void SockList_AddLen16Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 16 bit length field.
uint32_t client_code
The code used to communicate with the client, merely a unique index.
void quest_for_each(quest_op op, void *user)
Iterate over all quests.
#define MSG_TYPE_ADMIN_LOADSAVE
load/save operations
sstring add_refcount(sstring str)
Like add_string(), but the string is already a shared string.
void SockList_AddInt(SockList *sl, uint32_t data)
Adds a 32 bit value.
Structure used when dumping quests to stdout.
sstring code
Quest internal code.
static void quest_write_player_data(const quest_player *pq)
Write quest-data information for a player.
int sent_to_client
Whether this state was sent to the client or not.
Global type definitions and header inclusions.
struct player * contr
Pointer to the player which control this object.
static void quest_read_player_data(quest_player *pq)
Read quest-data information for a player.
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
const quest_definition * parent
Parent to dump from.
static quest_state * get_new_quest_state(void)
Return a new quest_state*, calling fatal() if memory shortage.
void dump_quests(void)
Dump all of the quests, then calls exit() - useful in terms of debugging to make sure that quests are...
uint16_t notifications
Notifications this client wants to get.
#define MSG_TYPE_ADMIN_DM
DM related admin actions.
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Information about a player.
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
static quest_state * get_state(quest_player *pq, sstring name)
Get the state of a quest for a player, not creating if not existing yet.
static void do_update(const quest_definition *quest, void *user)
int was_completed
Whether the quest was completed once or not, indepandently of the state.
FILE * of_open(OutputFile *of, const char *fname)
Opens an output file.
int quest_get_player_state(player *pl, sstring quest_code)
Get the quest state for a player.
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
#define NDI_ALL_DMS
Inform all logged in DMs.
static int evaluate_quest_conditions(const std::vector< quest_condition *> conditions, player *pl)
Checks whether the conditions for a given step are met.
#define QUERY_FLAG(xyz, p)
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
static quest_state * get_quest_by_number(player *pl, int number)
returns the quest state which corresponds to a certain number for the given player.
uint32_t has_directory
If 0, the player was not yet saved, its directory doesn't exist.
static quest_player * get_or_create_quest(player *pl)
Get quest status for a player, creating it if it doesn't exist yet.
socket_struct * socket
Socket information for this player.
SockList * player_get_delayed_buffer(player *pl)
Get a delayed socket buffer, that will be sent after the player's tick is complete.
sstring quest_code
Quest internal code.
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
object * ob
The object representing the player.
#define MSG_TYPE_COMMAND_QUESTS
Quest info.
static void output_quests(const quest_definition *quest, void *user)
Dump one quest on the logfile, then its children.
std::vector< quest_condition * > conditions
The conditions that must be satisfied to trigger the step.
static quest_player * get_quest(player *pl)
Get quest status for a player, not creating it if it doesn't exist.
struct Settings settings
Global settings.
quest_state * quests
Quests done or in progress.
int quest_was_completed(player *pl, sstring quest_code)
Check if a quest was completed once for a player, without taking account the current state...
Information about a quest for a player.
size_t SockList_Avail(const SockList *sl)
Returns the available bytes in a SockList instance.
uint16_t number
This is the image unique identifier.
sstring quest_title
Quest title for player.
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
#define FLAG_WIZ
Object has special privilegies.
quest_player * next
Next player on the list.
#define MAX_BUF
Used for all kinds of things.
sstring player_name
Player's name.
struct quest_definition * parent
Parent for this quest, NULL if it is a 'top-level' quest.
#define QC_CAN_RESTART
Quest status that indicates a quest was completed and may be restarted.
const Face * face
Face associated with this quest.
void free_quest(void)
Free all quest status structures.
void command_help(object *op, const char *params)
Player is asking for some help.
void SockList_AddChar(SockList *sl, unsigned char c)
Adds an 8 bit value.
int is_completion_step
Whether this step completes the quest (1) or not (0)
quest_definition * quest_get_by_code(sstring code)
Find a quest from its code if it exists.
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
Sends a face to a client if they are in pixmap mode, nothing gets sent in bitmap mode.
int is_complete
Whether the quest is complete in the current playthrough.
static void quest_list(player *pl, player *who, int showall, const char *name)
Display current and completed player quests.
void quest_first_player_save(player *pl)
Ensure the quest state is correctly saved for a player.
const char * localdir
Read/write data files.
sstring name
The name of the object, obviously...
Only for debugging purposes.
int of_close(OutputFile *of)
Closes an output file.
int quest_restart
If non zero, can be restarted.
static void quest_info(player *pl, player *who, quest_state *qs, int level)
Give details about a quest.
Functions for creating text output files.
static quest_player * player_states
Player quest state.
static void quest_display(player *pl, quest_player *pq, int showall, const char *name)
Utility function to display a quest list.
#define NDI_UNIQUE
Print immediately, don't buffer.
C function wrappers to interact with assets.
static int quests_count
Count of quests.
sstring quest_description
Quest longer description.
Contains the base information we use to make up a packet we want to send.
static void quest_set_state(player *dm, player *pl, sstring quest_code, int state, int started)
Set the state of a quest for a player.
quest_definition * quest_find_by_code(sstring code)
Find a quest from its code, logging if no matching quest.
int level
Indentation level.
player * find_player_partial_name(const char *plname)
Find a player by a partial name.
uint8_t * faces_sent
This is a bitmap on sent face status.
int state
State for the player.
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.