Crossfire Server, Trunk  1.75.0
QuestLoader.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2021 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #include "QuestLoader.h"
14 #include "AssetsCollection.h"
15 #include "Quests.h"
16 #include "assets.h"
17 #include "AssetsManager.h"
18 
25 #define QUESTFILE_NEXTQUEST 0
26 #define QUESTFILE_QUEST 1
27 #define QUESTFILE_QUESTDESC 2
28 #define QUESTFILE_STEP 3
29 #define QUESTFILE_STEPDESC 4
30 #define QUESTFILE_STEPCOND 5
31 #define QUESTFILE_COMMENT 6
33 
34 QuestLoader::QuestLoader(Quests *quests, Faces *faces, AssetsTracker *tracker) : quests(quests), faces(faces), tracker(tracker) {
35 }
36 
37 void QuestLoader::load(BufferReader *reader, const std::string &filename) {
38  int i, in = QUESTFILE_NEXTQUEST;
39  quest_definition *quest = NULL;
40  quest_condition *cond = NULL;
42  char *read;
43  StringBuffer *buf = NULL;
44 
45  while ((read = bufferreader_next_line(reader)) != NULL) {
46  if (in == QUESTFILE_STEPCOND) {
47  if (strcmp(read, "end_setwhen") == 0) {
49  continue;
50  }
51  /*
52  * We are reading in a list of conditions for the 'setwhen' block for a quest step
53  * There will be one entry per line, containing the quest, and the steps that it applies to.
54  */
55 
56  cond = quest_create_condition();
57  if (!quest_condition_from_string(cond, read)) {
58  LOG(llevError, "Invalid line '%s' in setwhen block for quest %s=n", read, quest->quest_code);
59  free(cond);
60  continue;
61  }
62 
63  step->conditions.push_back(cond);
64  LOG(llevDebug, "condition added for step %d of quest %s, looking for quest %s between steps %d and %d\n",
65  step->step, quest->quest_code, cond->quest_code, cond->minstep, cond->maxstep);
66  continue;
67  }
68  if (in == QUESTFILE_STEPDESC) {
69  if (strcmp(read, "end_description") == 0) {
70  char *message;
71 
73 
75  buf = NULL;
76 
77  step->step_description = (*message != '\0') ? add_string(message + 1) : NULL; // Skip initial newline
78  free(message);
79 
80  continue;
81  }
82 
85  continue;
86  }
87 
88  if (in == QUESTFILE_STEP) {
89  if (strcmp(read, "end_step") == 0) {
90  step = NULL;
92  continue;
93  }
94  if (strcmp(read, "finishes_quest") == 0) {
95  step->is_completion_step = 1;
96  continue;
97  }
98  if (strcmp(read, "description") == 0) {
101  continue;
102  }
103  if (strcmp(read, "setwhen") == 0) {
105  continue;
106  }
107  LOG(llevError, "quests: invalid line %s in definition of quest %s in %s:%zu!\n",
108  read, quest->quest_code, filename.c_str(), bufferreader_current_line(reader));
109  continue;
110  }
111 
112  if (in == QUESTFILE_QUESTDESC) {
113  if (strcmp(read, "end_description") == 0) {
115 
117  buf = NULL;
118 
119  quest->quest_description = (*message != '\0') ? add_string(message + 1) : NULL; // Remove initial newline
120  free(message);
121 
122  continue;
123  }
126  continue;
127  }
128 
129  if (in == QUESTFILE_COMMENT) {
130  // Quest comment is ignored here, only used in eg CRE.
131  if (strcmp(read, "end_comment") == 0) {
133  auto comment = stringbuffer_finish(buf);
134  buf = nullptr;
135  quest->quest_comment = (*comment != '\0') ? add_string(comment + 1) : NULL; // Skip initial newline
136  free(comment);
137  continue;
138  }
141  continue;
142  }
143 
144  if (in == QUESTFILE_QUEST) {
145  if (strcmp(read, "end_quest") == 0) {
146  quests->define(quest->quest_code, quest);
147  if (tracker) {
148  tracker->assetDefined(quest, filename);
149  }
150  quest = NULL;
152  continue;
153  }
154 
155  if (strcmp(read, "description") == 0) {
157  buf = stringbuffer_new();
158  continue;
159  }
160 
161  if (strncmp(read, "title ", 6) == 0) {
162  quest->quest_title = add_string(read + 6);
163  continue;
164  }
165 
166  if (sscanf(read, "step %d", &i)) {
168  step->step = i;
169  quest->steps.push_back(step);
170  in = QUESTFILE_STEP;
171  continue;
172  }
173 
174  if (sscanf(read, "restart %d", &i)) {
175  quest->quest_restart = i;
176  continue;
177  }
178  if (strncmp(read, "parent ", 7) == 0) {
179  quest->parent = quests->get(read + 7);
180  continue;
181  }
182 
183  if (strncmp(read, "face ", 5) == 0) {
184  quest->face = faces->get(read + 5);
185  continue;
186  }
187 
188  if (strncmp(read, "comment", 7) == 0) {
190  buf = stringbuffer_new();
191  continue;
192  }
193 
194  if (sscanf(read, "is_system %d", &i)) {
195  quest->quest_is_system = (i ? true : false);
196  continue;
197  }
198  }
199 
200  if (read[0] == '#')
201  continue;
202 
203  if (strncmp(read, "quest ", 6) == 0) {
204  if (quest) {
205  LOG(llevError, "'quest' while in quest '%s' in file %s\n", quest->quest_code, filename.c_str());
206  }
207  quest = quest_create(read + 6);
208  /* Set a default face, which will be overwritten if a face is defined. */
209  quest->face = faces->get("quest_generic.111");
211  continue;
212  }
213 
214  if (strcmp(read, "") == 0)
215  continue;
216 
217  LOG(llevError, "quest: invalid file format for %s, I don't know what to do with the line %s\n", filename.c_str(), read);
218  }
219 
220  if (in != 0) {
221  LOG(llevError, "quest: quest definition file %s read in, ends with state %d\n", filename.c_str(), in);
222 
223  /* The buffer may not have been freed. */
224  if (buf != NULL) {
226  }
227  }
228 }
quest_condition::quest_code
sstring quest_code
The quest that triggers the condition.
Definition: quest.h:21
bufferreader_current_line
size_t bufferreader_current_line(BufferReader *br)
Return the index of the last line returned by bufferreader_next_line().
Definition: bufferreader.cpp:140
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
quest_create_step
quest_step_definition * quest_create_step(void)
Allocate a quest_step_definition, will call fatal() if out of memory.
Definition: Quests.cpp:49
quest_condition::maxstep
int maxstep
The latest step that triggers the condition, to match, the stages must be between minstep and maxstep...
Definition: quest.h:24
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
QuestLoader::tracker
AssetsTracker * tracker
Definition: QuestLoader.h:38
QUESTFILE_STEPDESC
#define QUESTFILE_STEPDESC
In a quest step description.
Definition: QuestLoader.cpp:29
QuestLoader::faces
Faces * faces
Definition: QuestLoader.h:37
AssetsManager.h
QUESTFILE_QUESTDESC
#define QUESTFILE_QUESTDESC
In a quest description.
Definition: QuestLoader.cpp:27
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.cpp:57
quest_definition::quest_description
sstring quest_description
Quest longer description.
Definition: quest.h:40
in
same as sound ncom command like but with extra the client want tick commands so it knows animation timing the client wants to be informed of pickup mode changes Mode will be sent when the player successfully logs in
Definition: protocol.txt:408
QuestLoader::quests
Quests * quests
Definition: QuestLoader.h:36
quest_definition::quest_is_system
bool quest_is_system
If set then the quest isn't counted or listed.
Definition: quest.h:45
buf
StringBuffer * buf
Definition: readable.cpp:1565
quest_step_definition
One step of a quest.
Definition: quest.h:29
quest_definition::quest_title
sstring quest_title
Quest title for player.
Definition: quest.h:39
quest_definition::quest_comment
sstring quest_comment
Quest comment, not visible to players.
Definition: quest.h:41
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.cpp:76
QuestLoader::QuestLoader
QuestLoader(Quests *quests, Faces *faces, AssetsTracker *tracker)
Definition: QuestLoader.cpp:34
QUESTFILE_STEPCOND
#define QUESTFILE_STEPCOND
In a quest step conditions.
Definition: QuestLoader.cpp:30
AssetsTracker
Base class to be informed of where an asset is defined.
Definition: AssetsTracker.h:24
Quests
Definition: Quests.h:19
quest_definition::face
const Face * face
Face associated with this quest.
Definition: quest.h:43
AssetsCollection::define
T * define(const Key &name, T *asset)
Define an asset, erasing an existing one.
Definition: AssetsCollection.h:120
QUESTFILE_QUEST
#define QUESTFILE_QUEST
In a quest definition.
Definition: QuestLoader.cpp:26
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
quest_definition::quest_code
sstring quest_code
Quest internal code.
Definition: quest.h:38
AssetsTracker::assetDefined
virtual void assetDefined(const archetype *asset, const std::string &filename)
Function called when an asset is defined in a file.
Definition: AssetsTracker.h:32
quest_definition::parent
struct quest_definition * parent
Parent for this quest, NULL if it is a 'top-level' quest.
Definition: quest.h:47
message
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your message
Definition: survival-guide.txt:34
AssetsCollection.h
step
How to Install a Crossfire Server on you must install a python script engine on your computer Python is the default script engine of Crossfire You can find the python engine you have only to install them The VisualC Crossfire settings are for but you habe then to change the pathes in the VC settings Go in Settings C and Settings Link and change the optional include and libs path to the new python installation path o step
Definition: INSTALL_WIN32.txt:20
Quests.h
AssetsCollection::get
T * get(const Key &name)
Get a named asset.
Definition: AssetsCollection.h:89
stringbuffer_append_string
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Append a string to a string buffer instance.
Definition: stringbuffer.cpp:95
Faces
Definition: Faces.h:19
StringBuffer
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.cpp:25
quest_condition::minstep
int minstep
The earliest step in the quest that triggers the condition, -1 means finished, 0 means not started.
Definition: quest.h:22
QUESTFILE_NEXTQUEST
#define QUESTFILE_NEXTQUEST
Waiting for next quest definition.
Definition: QuestLoader.cpp:25
QuestLoader.h
quest_condition
One condition to automatically move to a quest step.
Definition: quest.h:20
QUESTFILE_STEP
#define QUESTFILE_STEP
In a quest step.
Definition: QuestLoader.cpp:28
quest_definition
Definition of an in-game quest.
Definition: quest.h:37
assets.h
QuestLoader::load
virtual void load(BufferReader *reader, const std::string &filename) override
Load assets from the specified reader.
Definition: QuestLoader.cpp:37
quest_definition::quest_restart
int quest_restart
If non zero, can be restarted.
Definition: quest.h:42
QUESTFILE_COMMENT
#define QUESTFILE_COMMENT
In a quest comment.
Definition: QuestLoader.cpp:31
quests
static struct_quest ** quests
All quests in the game.
Definition: mapper.cpp:943
quest_create
quest_definition * quest_create(const char *name)
Definition: Quests.cpp:63
quest_condition_from_string
int quest_condition_from_string(quest_condition *condition, const char *buffer)
Parse a single step condition.
Definition: Quests.cpp:100
BufferReader
Definition: bufferreader.cpp:21
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:13
quest_create_condition
quest_condition * quest_create_condition(void)
Allocate a quest_condition, will call fatal() if out of memory.
Definition: Quests.cpp:56
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
Definition: bufferreader.cpp:102
quest_definition::steps
std::vector< quest_step_definition * > steps
Quest steps.
Definition: quest.h:46