1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2011 Fabien HENON
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"
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
)
49 NLLIGO::IPrimitive
*Primitive
;
54 // utility to untag a variable (tag are the '$' added before and after the var name)
55 inline void untagVar(std::string
&var
)
64 if (var
[var
.size()-1] != '$')
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*/
81 typedef NLLIGO::IPrimitive
* TCtorParam
;
92 IVar(TVarType type
, NLLIGO::IPrimitive
*prim
)
95 _VarName
= getPrimProperty(prim
, "var_name");
98 // force virtual destructor
101 /** Return the variable type. Should return a string to
102 * limit coupling with implementation ?
104 TVarType
getVarType() const
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
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
;
140 /// Helper function to read a primitive property.
141 std::string
getPrimProperty(NLLIGO::IPrimitive
*prim
, const std::string
&propName
)
144 if (prim
->getPropertyByName(propName
.c_str(), s
))
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
))
157 return std::vector
<std::string
>();
163 std::string _VarName
;
169 /** Class for text management.
170 * Handle different expression of text such
171 * phrase identifier, reference to text variable
173 * The class also handle the parameter list for
179 /// Structure to store phrase parameters infos.
182 /// The name of the parameter
183 std::string ParamName
;
185 std::string CompilerParam
;
186 /// The type of the parameters (as defined in the string manager).
187 STRING_MANAGER::TParamType ParamType
;
190 : ParamType(STRING_MANAGER::NB_PARAM_TYPES
)
194 TParamInfo(const std::string
&name
, STRING_MANAGER::TParamType type
, const std::string
&compilerParam
= "")
196 CompilerParam(compilerParam
),
203 typedef std::vector
<std::vector
<TParamInfo
> > TPredefParams
;
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
214 /** The phrase id. This is the identifier that must be use with the
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
;
232 void initPhrase (CMissionData
&md
,
233 NLLIGO::IPrimitive
*prim
,
234 const std::vector
<std::string
> &texts
,
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
249 /// Test if the phrase contains some additionnal parameters
250 bool asAdditionnalParams();
254 /* Class for jumps */
257 std::string StepName
;
258 std::string JumpName
;
261 TJumpInfo(const std::string
&stepName
, const std::string
&jumpName
= std::string(), bool discardable
= true)
262 : StepName(stepName
),
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
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
332 std::string
genPreRequisites();
334 // forbidden copy constructor !
335 CMissionData(const CMissionData
&other
):NLMISC::CRefCount()
340 // std::string _Alias;
341 std::string _MissionName
;
342 std::string _MissionGiver
;
343 std::string _GiverPrimitive
;
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
;
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
;
366 std::vector
<std::string
> _MissionAutoMenuRaw
;
367 CPhrase _MissionAutoMenu
;
369 ////// Pre requisites /////////
373 std::string MinLevel
;
374 std::string MaxLevel
;
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
;
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
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
];
492 /// Storage for loaded primitive
493 struct TLoadedPrimitive
495 NLLIGO::CPrimitives
*PrimDoc
;
496 std::string FullFileName
;
502 TLoadedPrimitive(NLLIGO::CPrimitives
*primDoc
, const std::string
&fullFileName
)
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;
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
);