Crossfire Server, Trunk
quest.c File Reference
#include "global.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "output_file.h"
#include "sproto.h"
#include "quest.h"
#include "assets.h"
+ Include dependency graph for quest.c:

Go to the source code of this file.

Data Structures

struct  dump
 
struct  quest_player
 
struct  quest_state
 

Macros

#define QC_CAN_RESTART   -1
 
#define TAG_END   "[/color]"
 
#define TAG_START   "[color=#aa55ff]"
 

Typedefs

typedef struct quest_player quest_player
 
typedef struct quest_state quest_state
 

Functions

void command_quest (object *op, const char *params)
 
static void do_update (const quest_definition *quest, void *user)
 
void dump_quests (void)
 
static int evaluate_quest_conditions (const quest_condition *condition, player *pl)
 
void free_quest (void)
 
static void free_state (quest_player *pq)
 
static quest_stateget_new_quest_state (void)
 
static quest_playerget_or_create_quest (player *pl)
 
static quest_stateget_or_create_state (quest_player *pq, sstring name)
 
static quest_playerget_quest (player *pl)
 
static quest_stateget_quest_by_number (player *pl, int number)
 
static quest_stateget_state (quest_player *pq, sstring name)
 
static void output_quests (const quest_definition *quest, void *user)
 
static void quest_display (player *pl, quest_player *pq, int showall, const char *name)
 
void quest_first_player_save (player *pl)
 
int quest_get_player_state (player *pl, sstring quest_code)
 
static quest_step_definitionquest_get_step (quest_definition *quest, int step)
 
static void quest_info (player *pl, player *who, quest_state *qs, int level)
 
static void quest_list (player *pl, player *who, int showall, const char *name)
 
static void quest_read_player_data (quest_player *pq)
 
void quest_send_initial_states (player *pl)
 
void quest_set_player_state (player *pl, sstring quest_code, int state)
 
static void quest_set_state (player *dm, player *pl, sstring quest_code, int state, int started)
 
void quest_start (player *pl, sstring quest_code, int state)
 
int quest_was_completed (player *pl, sstring quest_code)
 
static void quest_write_player_data (const quest_player *pq)
 
static void update_quests (player *pl)
 

Variables

static quest_playerplayer_states = NULL
 

Detailed Description

Quest-related low-level mechanisms.

You should only need to call the public functions, all that are not static.

Data is loaded on a need-only basis - when a player quest state is queried or modified, data is read. Also, free_quest() can be called to release memory without preventing quest operations after.

Write is done for each player whenever the state changes, to ensure data integrity.

Definition in file quest.c.

Macro Definition Documentation

◆ QC_CAN_RESTART

#define QC_CAN_RESTART   -1

Quest status that indicates a quest was completed and may be restarted.

Definition at line 45 of file quest.c.

◆ TAG_END

#define TAG_END   "[/color]"

Definition at line 42 of file quest.c.

◆ TAG_START

#define TAG_START   "[color=#aa55ff]"

Definition at line 41 of file quest.c.

Typedef Documentation

◆ quest_player

typedef struct quest_player quest_player

Information about a player.

◆ quest_state

typedef struct quest_state quest_state

Information about a quest for a player.

Function Documentation

◆ command_quest()

void command_quest ( object op,
const char *  params 
)

Command handler for 'quest'.

Parameters
opplayer asking for information, warning emitted if not a player.
paramsextra parameters for command.

Definition at line 750 of file quest.c.

References quest_state::code, command_help(), draw_ext_info(), draw_ext_info_format(), find_player_partial_name(), FLAG_WIZ, get_quest(), get_quest_by_number(), i18n(), llevError, LOG(), MSG_TYPE_ADMIN_DM, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, MSG_TYPE_COMMAND_QUESTS, MSG_TYPE_COMMAND_SUCCESS, give::name, NDI_UNIQUE, quest_state::next, pl::ob, give::op, roll-o-matic::params, item::q, QUERY_FLAG, quest_get_by_code(), quest_info(), quest_list(), quest_set_state(), quest_player::quests, quest::state, and autojail::who.

Referenced by commands_init().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_update()

static void do_update ( const quest_definition quest,
void *  user 
)
static

Definition at line 323 of file quest.c.

References quest_step_definition::conditions, evaluate_quest_conditions(), quest_step_definition::next, quest_get_player_state(), quest_set_state(), and quest_step_definition::step.

Referenced by update_quests().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_quests()

void dump_quests ( void  )

Dump all of the quests, then calls exit() - useful in terms of debugging to make sure that quests are set up and recognised correctly.

Definition at line 899 of file quest.c.

References dump::level, output_quests(), dump::parent, and quest_for_each().

+ Here is the call graph for this function:

◆ evaluate_quest_conditions()

static int evaluate_quest_conditions ( const quest_condition condition,
player pl 
)
static

Checks whether the conditions for a given step are met.

Parameters
conditionthe linked list of conditions to check.
plthe player to evaluate conditions for.
Returns
1 if the conditions match, 0 if they don't.

Definition at line 301 of file quest.c.

References quest_condition::maxstep, quest_condition::minstep, quest_condition::next, quest_condition::quest_code, quest_get_player_state(), and quest_was_completed().

Referenced by do_update().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ free_quest()

void free_quest ( void  )

Free all quest status structures. It is all right to call quest functions again after that.

Definition at line 910 of file quest.c.

References free_state(), free_string(), give::next, quest_player::next, quest_player::player_name, and player_states.

Referenced by cleanup(), command_purge_quest(), and free_server().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ free_state()

static void free_state ( quest_player pq)
static

Free quests structures.

Parameters
pqwhat to free.

Definition at line 651 of file quest.c.

References quest_state::code, free_string(), give::next, quest_state::next, and quest_player::quests.

Referenced by free_quest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_new_quest_state()

static quest_state* get_new_quest_state ( void  )
static

Return a new quest_state*, calling fatal() if memory shortage.

Returns
new value, never NULL.

Definition at line 91 of file quest.c.

References fatal(), and OUT_OF_MEMORY.

Referenced by quest_read_player_data().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_or_create_quest()

static quest_player* get_or_create_quest ( player pl)
static

Get quest status for a player, creating it if it doesn't exist yet. Calls fatal() if memory allocation error.

Parameters
plplayer to get information of.
Returns
quest status, never NULL.

Definition at line 276 of file quest.c.

References add_refcount(), fatal(), get_quest(), obj::name, quest_player::next, pl::ob, OUT_OF_MEMORY, quest_player::player_name, player_states, and quest_read_player_data().

Referenced by get_quest_by_number(), quest_get_player_state(), quest_info(), quest_list(), quest_send_initial_states(), quest_set_state(), quest_start(), and quest_was_completed().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_or_create_state()

static quest_state* get_or_create_state ( quest_player pq,
sstring  name 
)
static

Get the state of a quest for a player, creating it if not existing yet.

Parameters
pqplayer to get state for.
namequest to get state of.
Returns
quest's state information, newly created if it wasn't done yet.

Definition at line 232 of file quest.c.

References add_refcount(), quest_state::code, fatal(), get_state(), give::name, quest_state::next, OUT_OF_MEMORY, and quest_player::quests.

Referenced by quest_set_state(), and quest_start().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_quest()

static quest_player* get_quest ( player pl)
static

Get quest status for a player, not creating it if it doesn't exist.

Parameters
plplayer to get information of.
Returns
quest status, NULL if not loaded/found yet.

Definition at line 258 of file quest.c.

References obj::name, quest_player::next, pl::ob, quest_player::player_name, and player_states.

Referenced by command_quest(), get_or_create_quest(), and quest_first_player_save().

+ Here is the caller graph for this function:

◆ get_quest_by_number()

static quest_state* get_quest_by_number ( player pl,
int  number 
)
static

returns the quest state which corresponds to a certain number for the given player.

Parameters
plplayer asking for details.
numberquest number.
Returns
quest state corresponding to the number provided, NULL if there is no such quest state.

Definition at line 550 of file quest.c.

References get_or_create_quest(), quest_definition::parent, QC_CAN_RESTART, quest_find_by_code(), quest_player::quests, and quest::state.

Referenced by command_quest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_state()

static quest_state* get_state ( quest_player pq,
sstring  name 
)
static

Get the state of a quest for a player, not creating if not existing yet.

Parameters
pqplayer to get state for.
namequest to get state of.
Returns
NULL if quest isn't started yet for this player, else quest's state information.

Definition at line 214 of file quest.c.

References quest_state::code, give::name, quest_state::next, and quest_player::quests.

Referenced by get_or_create_state(), quest_get_player_state(), and quest_was_completed().

+ Here is the caller graph for this function:

◆ output_quests()

static void output_quests ( const quest_definition quest,
void *  user 
)
static

Dump one quest on the logfile, then its children. Will call itself through quest_for_each().

Parameters
questquest to dump.
userpointer to a dump struct.

Definition at line 868 of file quest.c.

References dump::level, logfile, MAX_BUF, quest_step_definition::next, dump::parent, castle_read::prefix, quest_for_each(), and ring_occidental_mages::r.

Referenced by dump_quests().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_display()

static void quest_display ( player pl,
quest_player pq,
int  showall,
const char *  name 
)
static

Utility function to display a quest list. Will show a header before the list if not empty.

Parameters
plplayer to display list of quests.
pqquests to display.
showallif 0, only shows quests in progress and a summary of completed quests, else shows all quests.
nameeither 'You' or the player's name, if pl is a DM asking about another player.

Definition at line 457 of file quest.c.

References draw_ext_info_format(), i18n(), MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_QUESTS, give::name, NDI_UNIQUE, pl::ob, QC_CAN_RESTART, quest_find_by_code(), quest_player::quests, quests_count, and quest::state.

Referenced by quest_list().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_first_player_save()

void quest_first_player_save ( player pl)

Ensure the quest state is correctly saved for a player. This function should only be called once, when the player's save directory is created. All other quest functions save the state automatically, but save can only happen when the player directory exists.

Parameters
plwho to save quests for.

Definition at line 986 of file quest.c.

References get_quest(), quest_write_player_data(), and quest_player::quests.

Referenced by save_player().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_get_player_state()

int quest_get_player_state ( player pl,
sstring  quest_code 
)

Get the quest state for a player.

Parameters
plplayer.
quest_codeinternal quest code.
Returns
QC_COMPLETED if finished and quest can't be replayed, 0 if not started or finished and can be replayed, else quest-specific value.

Definition at line 672 of file quest.c.

References get_or_create_quest(), get_state(), item::q, QC_CAN_RESTART, quest_find_by_code(), and quest_state::state.

Referenced by cfapi_player_quest(), do_update(), and evaluate_quest_conditions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_get_step()

static quest_step_definition* quest_get_step ( quest_definition quest,
int  step 
)
static

Get a step for the specified quest.

Parameters
questquest to consider.
stepstep to find.
Returns
step, or NULL if no such step in which case a llevError is emitted.

Definition at line 73 of file quest.c.

References llevError, LOG(), quest_step_definition::next, and quest_step_definition::step.

Referenced by quest_info(), quest_read_player_data(), quest_send_initial_states(), and quest_set_state().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_info()

static void quest_info ( player pl,
player who,
quest_state qs,
int  level 
)
static

Give details about a quest.

Parameters
plplayer to give quest details to.
whoplayer to give quest details of.
qsquest_state to give details about
levelThe level of recursion for the quest info that's being provided

Definition at line 585 of file quest.c.

References quest_state::code, draw_ext_info(), draw_ext_info_format(), FLAG_WIZ, get_or_create_quest(), i18n(), quest_state::is_complete, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_QUESTS, NDI_UNIQUE, quest_step_definition::next, pl::ob, quest_definition::parent, castle_read::prefix, QC_CAN_RESTART, QUERY_FLAG, quest_find_by_code(), quest_get_step(), quest_player::quests, quest::state, quest_state::state, quest_step_definition::step, quest_step_definition::step_description, TAG_END, TAG_START, and autojail::who.

Referenced by command_quest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_list()

static void quest_list ( player pl,
player who,
int  showall,
const char *  name 
)
static

Display current and completed player quests.

Parameters
plplayer to display to.
whoplayer to display information for.
showall- whether to show all of the quests in full, just summary information for the completed ones
nameeither 'You' or the player's name, if pl is a DM asking about another player.

Definition at line 530 of file quest.c.

References draw_ext_info_format(), get_or_create_quest(), MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_QUESTS, give::name, NDI_UNIQUE, pl::ob, quest_display(), quest_player::quests, and autojail::who.

Referenced by command_quest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_read_player_data()

static void quest_read_player_data ( quest_player pq)
static

◆ quest_send_initial_states()

void quest_send_initial_states ( player pl)

Send the current quest states for the specified player, if the client supports those notifications.

Parameters
plwho to send quests for.

Definition at line 928 of file quest.c.

References esrv_send_face(), socket_struct::faces_sent, get_or_create_quest(), quest_step_definition::is_completion_step, socket_struct::notifications, NS_FACESENT_FACE, quest_get_by_code(), quest_get_step(), quest_player::quests, Send_With_Handling(), pl::socket, SockList_AddChar(), SockList_AddInt(), SockList_AddLen16Data(), SockList_AddShort(), SockList_AddString(), SockList_Avail(), SockList_Init(), SockList_Reset(), SockList_Term(), quest::state, and quest_step_definition::step_description.

Referenced by check_login().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_set_player_state()

void quest_set_player_state ( player pl,
sstring  quest_code,
int  state 
)

Set the state of a quest for a player.

Parameters
plplayer to set the state for.
quest_codequest internal code.
statenew state for the quest, must be greater than 0 else forced to 100 and a warning is emitted.

Definition at line 728 of file quest.c.

References quest_set_state(), and quest::state.

Referenced by cfapi_player_quest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_set_state()

static void quest_set_state ( player dm,
player pl,
sstring  quest_code,
int  state,
int  started 
)
static

Set the state of a quest for a player.

Parameters
dmif NULL then the player is actually playing, else a DM is changing the quest's state manually.
plplayer to set the state for.
quest_codequest internal code.
statenew state for the quest, must be greater than 0 else forced to 100 and a warning is emitted.
startedif 1, quest must have been started first or a warning is emitted, else it doesn't matter.

Definition at line 359 of file quest.c.

References draw_ext_info(), draw_ext_info_format(), esrv_send_face(), socket_struct::faces_sent, get_or_create_quest(), get_or_create_state(), pl::has_directory, quest_state::is_complete, quest_step_definition::is_completion_step, llevDebug, llevError, LOG(), MSG_TYPE_ADMIN_DM, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, MSG_TYPE_COMMAND_QUESTS, obj::name, NDI_DELAYED, NDI_UNIQUE, socket_struct::notifications, NS_FACESENT_FACE, pl::ob, player_get_delayed_buffer(), QC_CAN_RESTART, quest_find_by_code(), quest_get_step(), quest_write_player_data(), quest_state::sent_to_client, pl::socket, SockList_AddChar(), SockList_AddInt(), SockList_AddLen16Data(), SockList_AddString(), quest::state, quest_state::state, quest_step_definition::step_description, update_quests(), and quest_state::was_completed.

Referenced by command_quest(), do_update(), quest_set_player_state(), and quest_start().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_start()

void quest_start ( player pl,
sstring  quest_code,
int  state 
)

Start a quest for a player. Will notify the player.

Parameters
plplayer.
quest_codeinternal quest code.
stateinitial quest state, must be greater than 0 else forced to 100 and warning emitted.

Definition at line 692 of file quest.c.

References draw_ext_info_format(), get_or_create_quest(), get_or_create_state(), llevDebug, llevError, LOG(), MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_QUESTS, obj::name, NDI_DELAYED, NDI_UNIQUE, pl::ob, item::q, quest_find_by_code(), quest_set_state(), and quest::state.

Referenced by cfapi_player_quest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_was_completed()

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.

Parameters
plwho to check for.
quest_codequest internal code.
Returns
1 if the quest was already completed at least once, 0 else.

Definition at line 738 of file quest.c.

References get_or_create_quest(), get_state(), and quest::state.

Referenced by cfapi_player_quest(), and evaluate_quest_conditions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quest_write_player_data()

static void quest_write_player_data ( const quest_player pq)
static

Write quest-data information for a player.

Parameters
pqplayer to write data for.
Todo:
rename/backup, stuff like that

Definition at line 177 of file quest.c.

References draw_ext_info(), mad_mage_user::file, Settings::localdir, MAX_BUF, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_LOADSAVE, NDI_ALL_DMS, NDI_UNIQUE, of_close(), of_open(), quest_player::player_name, Settings::playerdir, quest_player::quests, settings, and quest::state.

Referenced by quest_first_player_save(), and quest_set_state().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_quests()

static void update_quests ( player pl)
static

Look through all of the quests for the given player, and see if any need to be updated.

Parameters
pl

Definition at line 347 of file quest.c.

References do_update(), and quest_for_each().

Referenced by quest_set_state().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ player_states

quest_player* player_states = NULL
static

Player quest state.

Definition at line 65 of file quest.c.

Referenced by free_quest(), get_or_create_quest(), and get_quest().