Linux multi-monitor fullscreen support
[ryzomcore.git] / ryzom / tools / leveldesign / mission_compiler_lib / mission_compiler.h
blobb5f0dbf79a6b8dacbf199f7432eb64898c583721
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2011 Fabien HENON
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "nel/misc/types_nl.h"
21 #include "nel/misc/debug.h"
22 #include "nel/misc/string_common.h"
23 #include "nel/misc/path.h"
24 #include "nel/misc/sstring.h"
25 #include "nel/misc/smart_ptr.h"
26 #include "nel/misc/factory.h"
27 #include "nel/ligo/primitive.h"
28 #include "nel/ligo/primitive_utils.h"
29 #include "nel/ligo/ligo_config.h"
30 #include "../../../common/src/game_share/string_manager_sender.h"
31 #include "nel/misc/string_conversion.h"
32 #include <string>
33 #include <numeric>
35 class CMissionData;
36 class IStep;
38 const std::string NL("\n\r");
40 /// Exception thows when the parser meet somethink invalid.
41 struct EParseException
43 EParseException(NLLIGO::IPrimitive *prim, const char *why)
44 : Primitive(prim),
45 Why(why)
49 NLLIGO::IPrimitive *Primitive;
50 std::string Why;
54 // utility to untag a variable (tag are the '$' added before and after the var name)
55 inline void untagVar(std::string &var)
57 if (!var.empty())
59 if (var[0] != '$')
60 var.clear();
61 else
63 var = var.substr(1);
64 if (var[var.size()-1] != '$')
65 var.clear();
66 else
67 var = var.substr(0, var.size()-1);
72 // utility to 'tabulate' the lines in a string
73 void tabulateLine(std::string &text, uint nbTabs);
76 /* Interface class for variables types*/
77 class IVar
79 public:
81 typedef NLLIGO::IPrimitive * TCtorParam;
83 enum TVarType
85 vt_integer,
86 vt_npc,
87 vt_item,
88 vt_place,
89 vt_text
92 IVar(TVarType type, NLLIGO::IPrimitive *prim)
94 _VarType = type;
95 _VarName = getPrimProperty(prim, "var_name");
98 // force virtual destructor
99 virtual ~IVar() {}
101 /** Return the variable type. Should return a string to
102 * limit coupling with implementation ?
104 TVarType getVarType() const
106 return _VarType;
109 /** Return the type of the variable as defined in the string manager.
110 * Can return NB_ENTITY_TYPES for compiler variable that don't match
111 * to a type in the string manager.
113 virtual STRING_MANAGER::TParamType getStringManagerType()=0;
115 /// Return the name of the variable.
116 const std::string getVarName() const
118 return _VarName;
121 /// Evaluate the content of the variable with an optional sub part.
122 virtual std::string evalVar(const std::string &subPart) = 0;
124 /** Factory method to create new variable. Caller become responsible
125 * for deleting the allocated variable.
127 static IVar *createVar(CMissionData &md, NLLIGO::IPrimitive *prim);
129 /// Generate variable declaration in mission script
130 virtual std::string genDecl(CMissionData &md) = 0;
132 /// Generate the phrase
133 virtual std::string genPhrase()
135 static std::string emptyString;
136 return emptyString;
139 protected:
140 /// Helper function to read a primitive property.
141 std::string getPrimProperty(NLLIGO::IPrimitive *prim, const std::string &propName)
143 std::string *s;
144 if (prim->getPropertyByName(propName.c_str(), s))
145 return *s;
146 else
147 return "";
150 /// Helper function to read a primitive array property
151 std::vector<std::string> getPrimPropertyArray(NLLIGO::IPrimitive *prim, const std::string &propName)
153 std::vector<std::string> *sv;
154 if (prim->getPropertyByName(propName.c_str(), sv))
155 return *sv;
156 else
157 return std::vector<std::string>();
159 protected:
160 /// Variable type.
161 TVarType _VarType;
162 /// Variable name.
163 std::string _VarName;
166 class CMissionData;
169 /** Class for text management.
170 * Handle different expression of text such
171 * phrase identifier, reference to text variable
172 * or literal string.
173 * The class also handle the parameter list for
174 * the phrase.
176 class CPhrase
178 public:
179 /// Structure to store phrase parameters infos.
180 struct TParamInfo
182 /// The name of the parameter
183 std::string ParamName;
184 /// Compiler param
185 std::string CompilerParam;
186 /// The type of the parameters (as defined in the string manager).
187 STRING_MANAGER::TParamType ParamType;
189 TParamInfo()
190 : ParamType(STRING_MANAGER::NB_PARAM_TYPES)
194 TParamInfo(const std::string &name, STRING_MANAGER::TParamType type, const std::string &compilerParam = "")
195 : ParamName(name),
196 CompilerParam(compilerParam),
197 ParamType(type)
203 typedef std::vector<std::vector<TParamInfo> > TPredefParams;
205 private:
207 /** Number of variant for this phrase.
208 * Zero denote that there is no variant, thus no need to add
209 * a postfix number after the phrase identifier for literal
210 * generated phrase.
212 uint32 _NumEntry;
214 /** The phrase id. This is the identifier that must be use with the
215 * string manager.
217 std::string _PhraseId;
218 /** String literal value. When the user fill a quoted string, then
219 * this property receive the string value of the quoted string.
221 std::vector<std::string> _PhraseLiterals;
222 /** Suffixe for literal string identifier */
223 std::string _Suffixe;
224 /// The list of default parameters.
225 TPredefParams _DefaultParams;
226 /// The list of additional parameters.
227 std::vector<TParamInfo> _AdditionalParams;
228 public:
231 /// init the phrase
232 void initPhrase (CMissionData &md,
233 NLLIGO::IPrimitive *prim,
234 const std::vector<std::string> &texts,
235 uint32 numEntry = 0,
236 const TPredefParams &predefParams = TPredefParams());
238 /// generate the common string script for any script instruction.
239 std::string genScript(CMissionData &md);
241 /** generate the phrase file content. Return empty string
242 * if the phrase is not a literal.
244 std::string genPhrase();
246 /// Test if the phrase is empty
247 bool isEmpty();
249 /// Test if the phrase contains some additionnal parameters
250 bool asAdditionnalParams();
254 /* Class for jumps */
255 struct TJumpInfo
257 std::string StepName;
258 std::string JumpName;
259 bool Discardable;
261 TJumpInfo(const std::string &stepName, const std::string &jumpName = std::string(), bool discardable = true)
262 : StepName(stepName),
263 JumpName(jumpName),
264 Discardable(discardable)
267 bool operator <(const TJumpInfo &other) const
269 return StepName < other.StepName;
274 /* Class for mission information storing */
275 class CMissionData : public NLMISC::CRefCount
277 public:
279 CMissionData();
280 ~CMissionData();
283 // void setAlias(const std::string &alias) { _Alias = alias; }
284 // const std::string &getAlias() { return _Alias; }
286 void setMissionName(const std::string &missionName);
287 const std::string &getMissionName();
289 const std::string &getGiverPrimitive() { return _GiverPrimitive; }
290 void setGiverPrimitive(const std::string &giverPrimitive) { _GiverPrimitive = giverPrimitive; }
292 const std::string &getGiverName() { return _MissionGiver; }
293 void setGiverName(const std::string &giverName) { _MissionGiver = giverName; }
295 bool addVariable(NLLIGO::IPrimitive *prim, IVar *var);
297 IVar *getVariable(const std::string &varName);
299 bool addStep(IStep *step);
300 void addStepName(const std::string &name, IStep *step) { _StepsByNames[name] = step; }
302 IStep *getNextStep(IStep *current);
304 IStep *getStepByName(const std::string &stepName);
306 std::string generateMissionScript(const std::string &primFileName);
308 std::string generatePhraseFile();
310 std::string generateDotScript();
312 void parseMissionHeader(NLLIGO::IPrimitive *prim);
313 void initHeaderPhrase(NLLIGO::IPrimitive *prim);
314 void parsePrerequisites(NLLIGO::IPrimitive *prim);
316 std::string replaceVar(NLLIGO::IPrimitive *prim, const std::string &str);
317 std::vector<std::string> replaceVar(NLLIGO::IPrimitive *prim, const std::vector<std::string> &strs);
319 std::string getProperty(NLLIGO::IPrimitive *prim, const std::string &propertyName, bool replaceVar, bool canFail);
320 std::vector<std::string> getPropertyArray(NLLIGO::IPrimitive *prim, const std::string &propertyName, bool replaceVar, bool canFail);
323 bool isThereAJumpTo(const std::string &stepName);
325 bool isGuildMission() const
327 return _Guild;
330 private:
332 std::string genPreRequisites();
334 // forbidden copy constructor !
335 CMissionData(const CMissionData &other):NLMISC::CRefCount()
337 nlstop;
340 // std::string _Alias;
341 std::string _MissionName;
342 std::string _MissionGiver;
343 std::string _GiverPrimitive;
344 bool _MonoInstance;
345 bool _RunOnce;
346 bool _Replayable;
347 bool _Solo;
348 bool _Guild;
349 bool _NotInJournal;
350 bool _AutoRemoveFromJournal; // When mission ends (fail or success) automatically remove it from the journal
351 std::string _MissionCategory;
352 uint32 _PlayerReplayTimer;
353 uint32 _GlobalReplayTimer;
354 bool _NotProposed;
355 bool _NonAbandonnable;
356 bool _NeedValidation;
357 bool _FailIfInventoryIsFull;
358 std::string _MissionIcon;
360 std::vector<std::string> _MissionTitleRaw;
361 CPhrase _MissionTitle;
362 std::vector<std::string> _MissionDescriptionRaw;
363 CPhrase _MissionDescription;
365 bool _MissionAuto;
366 std::vector<std::string> _MissionAutoMenuRaw;
367 CPhrase _MissionAutoMenu;
369 ////// Pre requisites /////////
370 struct TReqSkill
372 std::string Skill;
373 std::string MinLevel;
374 std::string MaxLevel;
377 struct TReqFame
379 std::string Faction;
380 std::string Fame;
382 std::vector<TReqSkill> _ReqSkills;
383 std::vector<std::string> _ReqMissionDone;
384 std::vector<std::string> _ReqMissionNotDone;
385 std::vector<std::string> _ReqMissionRunning;
386 std::vector<std::string> _ReqMissionNotRunning;
387 std::vector<std::string> _ReqWearItem;
388 std::vector<std::string> _ReqOwnItem;
389 std::string _ReqTitle;
390 std::vector<TReqFame> _ReqFames;
391 bool _ReqGuild;
392 std::string _ReqGrade;
393 std::string _ReqTeamSize;
394 std::vector<std::string> _ReqBrick;
395 std::string _ReqCharacterAge;
396 std::string _ReqMaxPlayerID;
397 std::string _ReqSeason;
398 // bool _ReqEncycloTasksDone;
399 std::string _ReqEncyclo;
400 std::string _ReqEncycloNeg;
401 std::string _ReqEventFaction;
403 /// The list of parent missions
404 std::set<std::string> _ParentMissions;
405 /// The list of variable by name
406 std::map<std::string, IVar*> _Variables;
407 /// The list of variable in primitive order
408 std::vector<IVar*> _VariablesOrder;
409 /// the list of step in execution order
410 std::vector<IStep*> _Steps;
411 /// The list of step sorted by step name
412 std::map<std::string, IStep *> _StepsByNames;
414 std::set<TJumpInfo> _JumpPoints;
418 typedef NLMISC::CSmartPtr<CMissionData> TMissionDataPtr;
420 /** This class manage the compilation of missions contained under a
421 * primitive file node.
423 class CMissionCompiler
425 public:
427 /** Generate the dot language script for the missions under the specified node.
428 * This method is primarily used for world editor mission display.
430 // std::vector<std::string> generateDotScript(NLLIGO::NLLIGO::IPrimitive *rootPrim);
431 bool generateDotScript(NLLIGO::IPrimitive *missionPrim, std::string &dotScript, std::string &log);
433 /** compile one mission. The primitive node must be
434 * a mission tree root node.
435 * fileName must receive the primitive file name. It is used
437 bool compileMission(NLLIGO::IPrimitive *rootPrim, const std::string &primFileName);
439 /** Compile all the missions found under the given primitive node.
440 * The primitive tree is searched recursively ti find all the
441 * mission tree nodes.
442 * All the compiled missions are stored internaly in precompiled form.
444 bool compileMissions(NLLIGO::IPrimitive *rootPrim, const std::string &primFileName);
446 /** Install the generated script into the destination primitive files */
447 bool installCompiledMission(NLLIGO::CLigoConfig &ligoConfig, const std::string &primFileName);
449 /// Publish the modified to the path parameter
450 bool publishFiles(const std::string &serverPathPrim, const std::string &serverPathText, const std::string &localPathText);
452 /// Search for text in the file : add it if it's not in
453 bool includeText(const std::string &filename, const std::string &text);
455 /// Parse the pre requisite node of a mission.
456 bool parsePreRequisite(CMissionData &md, NLLIGO::IPrimitive *preReq);
458 /// Parse the steps of a missions.
459 bool parseSteps(CMissionData &md, NLLIGO::IPrimitive *steps, IStep *parent=NULL);
460 bool parseOneStep(CMissionData &md, NLLIGO::IPrimitive *stepToParse, IStep *parent, bool bEndOfBranch);
462 /// Helper to retrive a property in a primitive node.
463 std::string getProp(NLLIGO::IPrimitive *prim, const std::string &propName);
464 /// Helper to retreive the class name of a primitive node.
465 std::string getClass(NLLIGO::IPrimitive *prim);
466 /// Parse the variable of a missions.
467 bool parseVariables(CMissionData &md, NLLIGO::IPrimitive *variables);
470 /// Get full paths of files to publish
471 uint getFileToPublishCount() { return (uint)_FilesToPublish.size(); }
472 std::string getFileToPublish(uint index) { nlassert(index < _FilesToPublish.size()); return _FilesToPublish[index]; }
475 std::vector <TMissionDataPtr> &getMissions()
477 return _CompiledMission;
479 uint getMissionsCount()
481 return (uint)_CompiledMission.size();
483 TMissionDataPtr getMission(uint index)
485 nlassert(index < _CompiledMission.size());
486 return _CompiledMission[index];
490 private:
492 /// Storage for loaded primitive
493 struct TLoadedPrimitive
495 NLLIGO::CPrimitives *PrimDoc;
496 std::string FullFileName;
498 TLoadedPrimitive()
499 : PrimDoc(NULL)
502 TLoadedPrimitive(NLLIGO::CPrimitives *primDoc, const std::string &fullFileName)
503 : PrimDoc(primDoc),
504 FullFileName(fullFileName)
509 /// Storage for precompiled missions.
510 std::vector <TMissionDataPtr> _CompiledMission;
512 /// Storage for files to publish
513 std::vector<std::string> _FilesToPublish;
517 // Class to easily handle var and var name pair
518 struct TCompilerVarName
520 typedef std::vector <std::vector<struct TCompilerVarName> > TPredefParams;
521 // Default parameter name
522 std::string _DefaultName;
523 // Type of script parameter
524 STRING_MANAGER::TParamType _ParamType;
525 // the name of the compiler var, like 'the_creature' in $the_creature$ = chab1
526 std::string _VarName;
527 // the value of the compiler var line 'chab1' in $the_creature$ = chab1
528 std::string _VarValue;
530 void init(const std::string &defaultName, STRING_MANAGER::TParamType type, CMissionData &md, NLLIGO::IPrimitive *prim, const std::string propName);
532 void initWithText(const std::string &defaultName, STRING_MANAGER::TParamType type, CMissionData &md, NLLIGO::IPrimitive *prim, const std::string &text);
534 CPhrase::TParamInfo getParamInfo() const;
536 bool empty() const;
538 operator const std::string () const;
540 operator CPhrase::TParamInfo() const;
542 //static void getPhrasePredef(const TCompilerVarName::TPredefParams& compilerParams, CPhrase::TPredefParams& params);
544 static std::vector<TCompilerVarName> getPropertyArrayWithText(const std::string &defaultName, STRING_MANAGER::TParamType type, CMissionData &md, NLLIGO::IPrimitive *prim, const std::string & arrayProperyName);
545 static std::vector<TCompilerVarName> getPropertyArrayWithTextStaticDefaultName(const std::string &defaultName, STRING_MANAGER::TParamType type, CMissionData &md, NLLIGO::IPrimitive *prim, const std::string & arrayProperyName);
550 std::string operator+(const TCompilerVarName& left, const std::string & right);
551 std::string operator+(const std::string & left, const TCompilerVarName& right);