Linux multi-monitor fullscreen support
[ryzomcore.git] / ryzom / tools / leveldesign / mission_compiler_lib / variables.cpp
blob9fe80c878bdb08c836d7f983323ecbfd94249425
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) 2013 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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 "mission_compiler.h"
22 using namespace std;
23 using namespace NLMISC;
24 using namespace NLLIGO;
27 class IVarFactory
29 public:
30 virtual IVar *createVar(CMissionData &md, IPrimitive *prim) = 0;
34 template <class VarClass>
35 class CVarFactory : public IVarFactory
37 IVar *createVar(CMissionData &md, IPrimitive *prim)
39 return new VarClass(md, prim);
43 #define REGISTER_VAR_INDIRECT(varClass, key) typedef CVarFactory<varClass> TVarFactory##varClass; \
44 NLMISC_REGISTER_OBJECT_INDIRECT(IVarFactory, TVarFactory##varClass, string, string(key));
47 //#define REGISTER_VARIABLE(className, varName) NLMISC_REGISTER_OBJECT(IVar, className, std::string, string(varName));
49 /* Class for npc variable */
50 class CVarNpc : public IVar
52 public:
53 CVarNpc(CMissionData &md, IPrimitive *prim)
54 : IVar(vt_npc, prim)
56 _NpcLabel = getPrimProperty(prim, "npc_name");
57 _NpcFunction = getPrimProperty(prim, "npc_function");
58 if (!_NpcFunction.empty())
60 _NpcFunction = "$"+_NpcFunction+"$";
63 IVar *nameVar = CFactoryIndirect<IVarFactory, string>::instance().getFactory("var_npc_name")->createVar(md, prim);
64 md.addVariable(prim, nameVar);
67 const std::string getNpcLabel()
69 return _NpcLabel;
71 const std::string getNpcFunction()
73 return _NpcFunction;
75 const std::string getNpcFullName()
77 return _NpcLabel+_NpcFunction;
80 string evalVar(const string &subPart)
82 if (subPart == "fullname")
83 return getNpcFullName();
84 else if (subPart == "function")
85 return _NpcFunction;
86 else if (subPart.empty())
87 return _NpcLabel;
89 throw EParseException(NULL, toString("var_npc don't have a subpart '%s'", subPart.c_str()).c_str());
92 STRING_MANAGER::TParamType getStringManagerType()
94 return STRING_MANAGER::bot;
97 string genDecl(CMissionData &md)
99 return "decl : bot : "+evalVar("")+NL;
101 private:
102 string _NpcLabel;
103 string _NpcFunction;
106 REGISTER_VAR_INDIRECT(CVarNpc, "var_npc");
108 /** Var for npc name (aka bot_name)
109 * This class is implicitly instancied by
110 * CVarNpc.
112 class CVarNpcName : public IVar
114 public:
115 CVarNpcName(CMissionData &md, IPrimitive *prim)
116 : IVar(vt_npc, prim)
118 // Change the var name
119 _VarName += "_name";
120 _NpcLabel = getPrimProperty(prim, "npc_name");
121 _NpcFunction = getPrimProperty(prim, "npc_function");
122 if (!_NpcFunction.empty())
124 _NpcFunction = "$"+_NpcFunction+"$";
128 const std::string getNpcLabel()
130 return _NpcLabel;
132 const std::string getNpcFunction()
134 return _NpcFunction;
136 const std::string getNpcFullName()
138 return _NpcLabel+_NpcFunction;
141 string evalVar(const string &subPart)
143 if (subPart.empty())
144 return string("\"")+_NpcLabel+"\"";
146 throw EParseException(NULL, toString("var_npc_name don't have a subpart '%s'", subPart.c_str()).c_str());
149 STRING_MANAGER::TParamType getStringManagerType()
151 return STRING_MANAGER::bot_name;
154 string genDecl(CMissionData &md)
156 return string();
159 private:
160 string _NpcLabel;
161 string _NpcFunction;
163 REGISTER_VAR_INDIRECT(CVarNpcName, "var_npc_name");
165 /* Class for npc variable */
166 class CVarGroup : public IVar
168 public:
169 CVarGroup(CMissionData &md, IPrimitive *prim)
170 : IVar(vt_npc, prim)
172 _GroupName = getPrimProperty(prim, "group_name");
175 string evalVar(const string &subPart)
177 if (subPart.empty())
178 return _GroupName;
179 else if (subPart == "quoted")
180 return string("\"")+_GroupName+"\"";
181 else
182 nlassert(false);
183 return "";
186 STRING_MANAGER::TParamType getStringManagerType()
188 return STRING_MANAGER::bot_name;
191 string genDecl(CMissionData &md)
193 // return "decl : bot : "+evalVar("no_quote")+NL;
194 return "decl : bot : "+evalVar("")+NL;
196 private:
197 string _GroupName;
200 REGISTER_VAR_INDIRECT(CVarGroup, "var_group");
201 //NLMISC_REGISTER_OBJECT(IVar, CVarGroup, std::string, string("var_group"));
204 /* Class for item */
205 class CVarItem : public IVar
207 public:
208 CVarItem(CMissionData &md, IPrimitive *prim)
209 : IVar(vt_item, prim)
211 _ItemSheet = getPrimProperty(prim, "item_sheet");
214 const std::string getItemSheet()
216 return _ItemSheet;
219 string evalVar(const string &subPart)
221 nlassert(subPart.empty());
222 return _ItemSheet;
225 STRING_MANAGER::TParamType getStringManagerType()
227 return STRING_MANAGER::item;
230 string genDecl(CMissionData &md)
232 return "decl : item : "+evalVar("")+NL;
234 private:
235 string _ItemSheet;
238 REGISTER_VAR_INDIRECT(CVarItem, "var_item");
239 //NLMISC_REGISTER_OBJECT(IVar, CVarItem, std::string, string("var_item"));
242 /* Class for race */
243 class CVarRace : public IVar
245 public:
246 CVarRace(CMissionData &md, IPrimitive *prim)
247 : IVar(vt_item, prim)
249 _Race = getPrimProperty(prim, "race");
252 string evalVar(const string &subPart)
254 nlassert(subPart.empty());
255 return _Race;
258 STRING_MANAGER::TParamType getStringManagerType()
260 return STRING_MANAGER::race;
263 string genDecl(CMissionData &md)
265 return "decl : race : "+evalVar("")+NL;
267 private:
268 string _Race;
271 REGISTER_VAR_INDIRECT(CVarRace, "var_race");
273 /* Class for sphrase */
274 class CVarSPhrase : public IVar
276 public:
277 CVarSPhrase(CMissionData &md, IPrimitive *prim)
278 : IVar(vt_item, prim)
280 _SPhrase = getPrimProperty(prim, "sphrase_sheet");
283 string evalVar(const string &subPart)
285 nlassert(subPart.empty());
286 return _SPhrase;
289 STRING_MANAGER::TParamType getStringManagerType()
291 return STRING_MANAGER::sphrase;
294 string genDecl(CMissionData &md)
296 return "decl : sphrase : "+evalVar("")+NL;
298 private:
299 string _SPhrase;
302 REGISTER_VAR_INDIRECT(CVarSPhrase, "var_sphrase");
304 /* Class for sbrick */
305 class CVarSBrick : public IVar
307 public:
308 CVarSBrick(CMissionData &md, IPrimitive *prim)
309 : IVar(vt_item, prim)
311 _SBrick = getPrimProperty(prim, "sbrick_sheet");
314 string evalVar(const string &subPart)
316 nlassert(subPart.empty());
317 return _SBrick;
320 STRING_MANAGER::TParamType getStringManagerType()
322 return STRING_MANAGER::sbrick;
325 string genDecl(CMissionData &md)
327 return "decl : sbrick : "+evalVar("")+NL;
329 private:
330 string _SBrick;
333 REGISTER_VAR_INDIRECT(CVarSBrick, "var_sbrick");
336 /* for special item */
337 const char *SpecialItemProp[] =
339 "Durability",
340 "Weight",
341 "SapLoad",
342 "Dmg",
343 "Speed",
344 "Range",
345 "DodgeModifier",
346 "ParryModifier",
347 "AdversaryDodgeModifier",
348 "AdversaryParryModifier",
349 "ProtectionFactor",
350 "MaxSlashingProtection",
351 "MaxBluntProtection",
352 "MaxPiercingProtection",
353 "HpBuff",
354 "SapBuff",
355 "StaBuff",
356 "FocusBuff"
359 struct TItemProperty
361 string PropName;
362 string PropValue;
365 /* Class for special item */
366 class CVarSpecialItem : public IVar
368 public:
369 CVarSpecialItem(CMissionData &md, IPrimitive *prim)
370 : IVar(vt_item, prim)
372 static bool init = false;
373 static set<string> propertyNames;
375 if (!init)
377 for (uint i=0; i<sizeof(SpecialItemProp)/sizeof(char*); ++i)
378 propertyNames.insert(SpecialItemProp[i]);
380 init = true;
383 _ItemSheet = getPrimProperty(prim, "item_sheet");
384 _ReqSkill = getPrimProperty(prim, "req_skill_level");
385 vector<string> vs;
386 vs = getPrimPropertyArray(prim, "properties/values");
387 // parse the strings vector
388 for (uint i=0; i<vs.size(); ++i)
390 vector<string> parts;
391 explode(vs[i], string(" "), parts, true);
392 if (!parts.empty() && parts.size() != 2)
394 string s = toString("Invalid special item property at line %u", i+1);
395 throw EParseException(prim, s.c_str());
398 if (parts.size() == 2)
400 TItemProperty ip;
401 ip.PropName = parts[0];
402 ip.PropValue = parts[1];
404 if (propertyNames.find(ip.PropName) == propertyNames.end())
406 string s = toString("Invalid property name '%s'", ip.PropName.c_str());
407 throw EParseException(prim, s.c_str());
410 _Properties.push_back(ip);
413 _Action = getPrimProperty(prim, "item_action");
414 vs.clear();
415 vs = getPrimPropertyArray(prim, "phrase_item_name");
416 _ItemPhrase.initPhrase(md, prim, vs);
418 string s;
419 s = getPrimProperty(prim, "no_drop");
420 _NoDrop = (s == "true");
423 // const std::string getItemSheet()
424 // {
425 // return _ItemSheet;
426 // }
428 string evalVar(const string &subPart)
430 nlassert(subPart.empty());
431 return _VarName;
434 STRING_MANAGER::TParamType getStringManagerType()
436 return STRING_MANAGER::item;
439 string genDecl(CMissionData &md)
441 string ret = string("decl_item : ")+_VarName+" : "+_ItemSheet+" : "+_ReqSkill;
442 if (!_Properties.empty() ||!_Action.empty())
443 ret += " : ";
444 for (uint i=0; i<_Properties.size(); ++i)
446 TItemProperty &ip = _Properties[i];
447 ret += ip.PropName+" "+ip.PropValue;
448 if (i < _Properties.size()-1 || !_Action.empty())
449 ret += "; ";
452 if (!_Action.empty())
453 ret += _Action;
455 ret += " : "+_ItemPhrase.genScript(md);
457 if (_NoDrop)
458 ret += " : no_drop";
460 ret += NL;
462 return ret;
465 std::string genPhrase()
467 return _ItemPhrase.genPhrase();
471 private:
472 /// the item sheet used as base for this special item
473 string _ItemSheet;
474 /// The skill required to use the item
475 string _ReqSkill;
476 /// The list of properties
477 vector<TItemProperty> _Properties;
478 // Optional action (enchantement)
479 string _Action;
480 // Name of the item
481 CPhrase _ItemPhrase;
482 // No drop flag
483 bool _NoDrop;
485 string _Color;
489 REGISTER_VAR_INDIRECT(CVarSpecialItem, "var_special_item");
490 //NLMISC_REGISTER_OBJECT(IVar, CVarSpecialItem, std::string, string("var_special_item"));
492 /* Class for place variable */
493 class CVarPlace : public IVar
495 public:
496 CVarPlace(CMissionData &md, IPrimitive *prim)
497 : IVar(vt_npc, prim)
499 _PlaceLabel = getPrimProperty(prim, "place_name");
502 /* const std::string getPlaceLabel()
504 return _PlaceLabel;
507 string evalVar(const string &subPart)
509 nlassert(subPart.empty());
510 return _PlaceLabel;
513 STRING_MANAGER::TParamType getStringManagerType()
515 return STRING_MANAGER::place;
518 string genDecl(CMissionData &md)
520 return "decl : place : "+evalVar("")+NL;
523 private:
524 string _PlaceLabel;
526 REGISTER_VAR_INDIRECT(CVarPlace, "var_place");
527 //NLMISC_REGISTER_OBJECT(IVar, CVarPlace, std::string, string("var_place"));
529 /* Class for integer variable */
530 class CVarInteger : public IVar
532 public:
533 CVarInteger(CMissionData &md, IPrimitive *prim)
534 : IVar(vt_integer, prim)
536 if (prim->checkProperty("value"))
537 _Value = getPrimProperty(prim, "value");
538 else if (prim->checkProperty("quantity"))
539 _Value = getPrimProperty(prim, "quantity");
540 else if (prim->checkProperty("quality"))
541 _Value = getPrimProperty(prim, "quality");
542 else
544 string err = toString("Can't find a valid property for integer variable");
545 throw EParseException(prim, err.c_str());
549 const std::string getIntegerValue()
551 return _Value;
554 string evalVar(const string &subPart)
556 nlassert(subPart.empty());
557 return _Value;;
560 STRING_MANAGER::TParamType getStringManagerType()
562 return STRING_MANAGER::integer;
565 string genDecl(CMissionData &md)
567 // nothing to declare for this pseudo var
568 return string();
570 private:
571 string _Value;
573 REGISTER_VAR_INDIRECT(CVarInteger, "var_integer");
574 //NLMISC_REGISTER_OBJECT(IVar, CVarInteger, std::string, string("var_integer"));
575 typedef CVarInteger CVarQuantity;
576 REGISTER_VAR_INDIRECT(CVarQuantity, "var_quantity");
577 //NLMISC_REGISTER_OBJECT(IVar, CVarQuantity, std::string, string("var_quantity"));
578 typedef CVarInteger CVarQuality;
579 REGISTER_VAR_INDIRECT(CVarQuality, "var_quality");
580 //NLMISC_REGISTER_OBJECT(IVar, CVarQuality, std::string, string("var_quality"));
583 /* Class for text var */
584 class CVarText : public IVar
586 public:
587 CVarText(CMissionData &md, IPrimitive *prim)
588 : IVar(vt_item, prim)
590 _TextValue = getPrimPropertyArray(prim, "text");
593 const vector<std::string> &getText()
595 return _TextValue;;
598 string evalVar(const string &subPart)
600 nlassert(subPart.empty());
601 string t;
602 return std::accumulate(_TextValue.begin(), _TextValue.end(), string(""));
603 return t;
606 STRING_MANAGER::TParamType getStringManagerType()
608 nlassert(false);
609 return STRING_MANAGER::NB_PARAM_TYPES;
612 string genDecl(CMissionData &md)
614 // nothing to declare for this one
615 return string();
617 private:
618 vector<string> _TextValue;
620 REGISTER_VAR_INDIRECT(CVarText, "var_text");
621 //NLMISC_REGISTER_OBJECT(IVar, CVarText, std::string, string("var_text"));
623 /* Class for creature var */
624 class CVarCreature : public IVar
626 public:
627 CVarCreature(CMissionData &md, IPrimitive *prim)
628 : IVar(vt_item, prim)
630 _CreatureSheet = getPrimProperty(prim, "creature_sheet");
633 string evalVar(const string &subPart)
635 nlassert(subPart.empty());
636 return _CreatureSheet;
639 STRING_MANAGER::TParamType getStringManagerType()
641 // return STRING_MANAGER::creature;
642 return STRING_MANAGER::creature_model;
645 string genDecl(CMissionData &md)
647 // declare a creature sheet
648 // return "decl : creature : "+_CreatureSheet+NL;
649 return "decl : creature_model : "+_CreatureSheet+NL;
651 private:
652 string _CreatureSheet;
654 REGISTER_VAR_INDIRECT(CVarCreature, "var_creature");
655 //NLMISC_REGISTER_OBJECT(IVar, CVarCreature, std::string, string("var_creature"));
657 /* Class for faction var */
658 class CVarFaction : public IVar
660 public:
661 CVarFaction(CMissionData &md, IPrimitive *prim)
662 : IVar(vt_item, prim)
664 _FactionName = getPrimProperty(prim, "faction_name");
667 string evalVar(const string &subPart)
669 nlassert(subPart.empty());
670 return _FactionName;
673 STRING_MANAGER::TParamType getStringManagerType()
675 return STRING_MANAGER::faction;
678 string genDecl(CMissionData &md)
680 // declare a creature sheet
681 return "decl : faction : "+_FactionName+NL;
683 private:
684 string _FactionName;
686 REGISTER_VAR_INDIRECT(CVarFaction, "var_faction");
687 //NLMISC_REGISTER_OBJECT(IVar, CVarFaction, std::string, string("var_faction"));
689 // Variable factory.
690 IVar *IVar::createVar(CMissionData &md, IPrimitive *prim)
692 string *c;
693 if (!prim->getPropertyByName("class", c))
694 throw EParseException(prim, "Can't find property 'class' on primitive");
696 return CFactoryIndirect<IVarFactory, string>::instance().getFactory(*c)->createVar(md, prim);
698 return NULL;
700 //IVar *IVar::createVar(CMissionData &md, IPrimitive *prim)
702 // string *className;
703 // if (!prim->getPropertyByName("class", className))
704 // throw EParseException(prim, "Can't find property 'class' in primitive");
706 // IVar *ret = NLMISC_GET_FACTORY_INDIRECT(IVar, std::string).createObject(md, *className, prim);
708 // return ret;