Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / ryzom / common / src / game_share / scenario.cpp
blob3782c45cf2d2cafbeecbd069ac530b76f4caf1e9
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //-----------------------------------------------------------------------------
18 // includes
19 //-----------------------------------------------------------------------------
21 #include "stdpch.h"
23 #include "scenario.h"
24 #include "object.h"
28 #include "nel/misc/string_common.h"
29 #include "nel/misc/sstring.h"
30 #include "nel/misc/debug.h"
31 #include "nel/misc/file.h"
32 #include "nel/misc/algo.h"
34 #ifdef DEBUG_NEW
35 #define new DEBUG_NEW
36 #endif
38 using namespace R2;
39 //----------------------------------------------------------------
40 namespace R2
46 void CScenario::serial( NLMISC::IStream &f)
48 // _Palette is not backuped because only on client side
49 // There is no characters connected so _CurrentChars is not need,
50 // _InstanceMap is set dynamically
52 if ( f.isReading())
54 _Clean = false;
56 f.serialEnum(_SessionType);
57 f.serial(_Mode);
58 f.serial(_InitialActIndex);
60 if (!f.isReading())
63 CObjectSerializerServer hl(_HighLevel);
64 f.serial(hl);
65 CObjectSerializerServer bb(_BasicBricks);
66 f.serial(bb);
68 else
70 CObjectSerializerServer hl;
71 f.serial(hl);
72 CObjectSerializerServer bb;
73 f.serial(bb);
74 setHighLevel( hl.getData() ) ; // Set instance Map
75 delete _BasicBricks;
76 _BasicBricks = bb.getData();
80 CScenario::CScenario(CObject* object, TScenarioSessionType sessionType)
82 _HighLevel = object;
83 _BasicBricks = 0;
84 _InstanceMap = new CInstanceMap("InstanceId");
85 if (object){_InstanceMap->add(object);}
86 _Palette = 0;
88 _Mode = 1;
89 _SessionType = sessionType;
90 _InitialActIndex = 1;
91 _Clean = false;
95 void CScenario::setHighLevel(CObject* highLevel)
97 _Clean = false;
98 if (highLevel != _HighLevel)
100 delete _HighLevel;
101 _HighLevel = highLevel;
104 _InstanceMap->set(highLevel);
109 CObject *CScenario::find(const std::string& instanceId, const std::string & attrName, sint32 position, const std::string &key)
111 CObject *src = _InstanceMap->find(instanceId);
112 if (!src)
114 nlwarning("Can't find object with id %s", instanceId.c_str());
115 return NULL;
117 if (!attrName.empty())
119 CObject *subObj = src->getAttr(attrName);
120 if (!subObj)
122 nlwarning("Can't find attribute %s inside object with InstanceId = %s", attrName.c_str(), instanceId.c_str());
123 return NULL;
125 src = subObj;
127 if (position != -1)
129 CObject *subObj = src->getValueAtPos(position);
130 if (!subObj)
132 nlwarning("Can't find attribute %s[%d] inside object with InstanceId = %s", attrName.c_str(), (int) position, instanceId.c_str());
133 return NULL;
135 src = subObj;
137 if (!key.empty())
139 CObject *subObj = src->getAttr(key);
140 if (!subObj)
142 nlwarning("Can't find attribute %s['%s'] inside object with InstanceId = %s", attrName.c_str(), key.c_str(), instanceId.c_str());
143 return NULL;
145 src = subObj;
147 return src;
150 CScenario::~CScenario()
152 delete _HighLevel;
153 delete _BasicBricks;
154 delete _InstanceMap;
155 delete _Palette;
160 bool CScenario::setNode( const std::string& instanceId, const std::string& attrName, CObject* value)
162 _Clean = false;
163 CObject* found= _InstanceMap->find(instanceId);
165 if (!found)
167 nlwarning("CScenario::setNode : couldn't find object with id = %s", instanceId.c_str());
168 return false;
170 return found->setObject(attrName, value);
174 bool CScenario::insertNode(const std::string& instanceId, const std::string & attrName, sint32 position,
175 const std::string& key, CObject* value)
177 _Clean = false;
178 CObject* found= _InstanceMap->find(instanceId);
180 if (!found)
182 nlwarning("CScenario::insertNode : couldn't find object with id = %s", instanceId.c_str());
183 return false;
185 if (!attrName.empty())
187 found=found->getAttr(attrName);
189 if (!found)
191 nlwarning("CScenario::insertNode : couldn't find attribute '%s' in object with id = %s", attrName.c_str(), instanceId.c_str());
192 return false;
195 bool inserted = found->insert(key, value, position);
196 if (inserted)
198 _InstanceMap->add(value);
200 return inserted;
204 bool CScenario::eraseNode(const std::string& instanceId, const std::string & attrName, sint32 position)
206 _Clean = false;
207 CObject* found= _InstanceMap->find(instanceId);
208 if (!found)
210 nlwarning("CScenario::eraseNode : couldn't find object with id = %s", instanceId.c_str());
211 return false;
214 if (!attrName.empty()) { found=found->getAttr(attrName); }
215 if (!found)
217 nlwarning("CScenario::eraseNode : couldn't find attribute '%s' in object with id = %s", attrName.c_str(), instanceId.c_str());
218 return false;
221 CObject* removed = NULL;
222 if (found->isTable())
224 bool canRemove = found->canTake(position);
225 if (!canRemove)
227 nlwarning("CScenario::eraseNode : can not remove a non-existing object from a table (%s, %s, %d)", instanceId.c_str(), attrName.c_str(), position );
228 return false;
231 removed = found->take(position);
232 if (!removed)
234 nlwarning("CScenario::eraseNode remove a NULL object (%s, %s, %d)", instanceId.c_str(), attrName.c_str(), position );
235 return true;
238 else if (position == -1)
240 // removing a property
241 // this may happen in an undo if the property is redefined in the base
242 sint32 index = found->getParent()->findIndex(found);
243 nlassert(index != -1);
244 removed = found->getParent()->take(index);
246 else
248 nlwarning("CScenario::eraseNode when removing (%s, %s) : position must be -1, because object is not a table", instanceId.c_str(), attrName.c_str());
249 return true;
251 _InstanceMap->remove(removed);
252 delete removed;
253 return true;
256 bool CScenario::moveNode( const std::string& instanceId1, const std::string& attrName1, int position1,
257 const std::string& instanceId2, const std::string& attrName2, int position2)
259 _Clean = false;
261 static volatile bool verboseMoveNode = false;
262 CObject* from= _InstanceMap->find(instanceId1);
263 if (from && !attrName1.empty()) { from=from->getAttr(attrName1); }
264 if (!from)
266 nlwarning("<CScenario::moveNode> 'from' node with id (%s, %s) not found", instanceId1.c_str(), attrName1.c_str());
267 return false;
269 CObject* to = _InstanceMap->find(instanceId2);
270 if (to && verboseMoveNode)
272 nlwarning("Insertion object is : ");
273 to->dump();
275 if (to && !attrName2.empty())
277 to=to->getAttr(attrName2);
278 if (to && verboseMoveNode)
280 nlwarning("Insertion object sub element is : ");
281 to->dump();
284 if (!to)
286 nlwarning("<CScenario::moveNode> 'to' node with id (%s, %s) not found", instanceId2.c_str(), attrName2.c_str());
287 return false;
291 if ( ! (to->isTable() && -1<= position2 && position2 <= static_cast<sint32>(to->getSize())) )
293 nlwarning("<CScenario::moveNode> Can not move node to (%s, %s, %d)", instanceId2.c_str(), attrName2.c_str(), position2);
294 return false;
298 if (! from->canTake(position1))
300 nlwarning("<CScenario::moveNode> Can not move node from (%s, %s, %d)", instanceId1.c_str(), attrName1.c_str(), position1);
301 return false;
304 CObject* removed = from->take(position1);
306 if (!removed)
308 nlwarning("<CScenario::moveNode> Error: try to move a non-existing object from a table (%s, %s, %d)", instanceId1.c_str(), attrName1.c_str(), position1 );
309 return false;
312 if (verboseMoveNode)
314 nlwarning("Removed object is : ");
315 removed->dump();
318 if (verboseMoveNode)
320 nlwarning("After removal, 'from' object is : ");
321 from->dump();
324 bool inserted = to->insert("", removed, position2);
327 if (verboseMoveNode)
329 nlwarning("After insertion, destination object is : ");
330 to->dump();
333 return inserted;
336 CObject* CScenario::getHighLevel() const { return _HighLevel;}
338 void CScenario::setRtData(CObject* rtScenario)
340 _Clean = false;
341 if (_BasicBricks) { delete _BasicBricks; }
342 this->_BasicBricks = rtScenario;
345 CObject* CScenario::getRtData() const { return _BasicBricks;}
346 sint32 CScenario::getMaxId(const std::string& eid)
348 return _InstanceMap->getMaxId(eid);
351 void CScenario::setMaxId(const std::string& eid, sint32 maxId)
353 _InstanceMap->setMaxId(eid, maxId);
357 //----------------------------------------------------------------
360 void CInstanceMap::add(CObject* root)
362 if (root->isTable())
364 if ( root->isString(_IdName) )
366 std::string instanceId = root->toString(_IdName);
367 if ( _Map.find(instanceId) != _Map.end())
369 nlwarning("Trying to add object to the instance map but object already exist. Objec t is :");
370 root->dump();
371 return;
373 _Map[instanceId] = root;
374 if (_IdName == "InstanceId")
376 std::string user;
377 sint32 maxId;
378 NLMISC::CSString str(instanceId);
379 user=str.strtok("_");
380 std::string tmp=str.strtok("_");
381 NLMISC::fromString(tmp,maxId);
382 std::map<std::string,sint32>::iterator it=_MapEids.find(user);
383 if(it==_MapEids.end() || it->second<maxId)
385 _MapEids[user]=maxId;
391 sint32 size = root->getSize() ;
392 sint32 first = 0;
393 for (first = 0 ; first != size ; ++first)
395 CObject* value = root->getValueAtPos(first);
396 add(value);
403 void CInstanceMap::remove(CObject* root)
405 if (root->isTable())
407 if ( root->isString("InstanceId") )
409 std::string instanceId = root->toString(_IdName);
410 std::map<std::string, CObject*>::iterator found(_Map.find(instanceId));
411 if ( found == _Map.end())
413 nlwarning("Trying to remove object from instance map but object is not found. Objec t is :");
414 root->dump();
415 return;
417 _Map.erase(found);
419 sint32 size = root->getSize() ;
420 sint32 first = 0;
421 for (first = 0 ; first != size ; ++first)
423 CObject* value = root->getValueAtPos(first);
424 remove(value);
430 void CInstanceMap::set(CObject* root)
432 _Map.clear();
433 if(root)
434 add(root);
437 CObject* CInstanceMap::find (const std::string& instanceId)
439 std::map< std::string , CObject*>::const_iterator found = _Map.find(instanceId);
440 if (found != _Map.end()) { return found->second; }
442 return 0;
445 sint32 CInstanceMap::getMaxId(const std::string& eid)
447 std::map<std::string, sint32>::iterator it=_MapEids.find(eid);
448 if(it!=_MapEids.end())
450 return it->second;
452 else
454 return 0;
459 void CInstanceMap::setMaxId(const std::string& eid, sint32 maxId)
461 std::map<std::string, sint32>::iterator it=_MapEids.find(eid);
462 if(it!=_MapEids.end())
463 it->second = maxId;
467 bool CScenario::isEditing() const
469 return _SessionType == st_edit && (_Mode != 2 && _Mode != 3);
472 bool CScenario::isRunning() const
474 return !isEditing();
477 bool CScenario::isWaiting() const
479 return false;
484 //--------------------------------------------------------------------------------
486 CUserComponent::CUserComponent()
488 UncompressedData = 0;
489 UncompressedDataLength = 0;
490 CompressedData = 0;
491 CompressedDataLength = 0;
494 CUserComponent::CUserComponent(const std::string &filename,
495 uint8* uncompressedData, uint32 uncompressedDataLength,
496 uint8* compressedData, uint32 compressedDataLength
498 :Filename(filename), UncompressedData(uncompressedData), UncompressedDataLength(uncompressedDataLength),
499 CompressedData(compressedData), CompressedDataLength(compressedDataLength)
501 computeMd5();
505 CUserComponent::~CUserComponent()
507 if (UncompressedData) { delete [] UncompressedData; }
508 if (CompressedData) { delete [] CompressedData; }
511 void CUserComponent::computeMd5()
513 Md5 = NLMISC::getMD5(UncompressedData, UncompressedDataLength);
516 void CUserComponent::serial(NLMISC::IStream &f)
518 f.serial(Md5);
519 f.serial(Md5Id);
520 f.serialEnum(ComponentType);
522 f.serial(Name);
523 f.serial(Description);
525 f.serial(Filename);
526 f.serial(CompressedDataLength);
527 f.serial(UncompressedDataLength);
529 if (f.isReading())
531 delete [] CompressedData;
532 CompressedData = new uint8[CompressedDataLength];
535 f.serialBuffer(CompressedData, CompressedDataLength);
539 uint8* CUserComponent::getUncompressedData() const { return UncompressedData; }
541 uint32 CUserComponent::getUncompressedDataLength() const { return UncompressedDataLength; }
543 std::string getBehavior(const std::string& emoteId);
546 CEmoteBehavior::CEmoteBehavior()
550 std::string CEmoteBehavior::get(const std::string& emoteId) const
552 if (_EmotesMap.empty()) { load(); } //lazy initialization
553 std::map<std::string, std::string>::const_iterator found( _EmotesMap.find( emoteId));
554 if (found == _EmotesMap.end()) return "";
555 return found->second;
558 void CEmoteBehavior::load() const
561 _EmotesMap["Absentminded"] = "afk" ;
562 _EmotesMap["Adventurous"] = "impatient" ;
563 _EmotesMap["Aggressive"] = "roar" ;
564 _EmotesMap["Agree"] = "agree" ;
565 _EmotesMap["Alert"] = "alert" ;
566 _EmotesMap["Altruist"] = "smile" ;
567 _EmotesMap["Amazed"] = "cheer" ;
568 _EmotesMap["Ambivalent"] = "apologize" ;
569 _EmotesMap["Amused"] = "laugh" ;
570 _EmotesMap["Angry"] = "angry" ;
571 _EmotesMap["Annoyed"] = "angry" ;
572 _EmotesMap["Apathetic"] = "afk" ;
573 _EmotesMap["Approve"] = "agree" ;
574 _EmotesMap["Arrogant"] = "giggle" ;
575 _EmotesMap["Ashamed"] = "ashamed_disgusted_desillusioned_loathing_pitying" ;
576 _EmotesMap["Belligerent"] = "gesture" ;
577 _EmotesMap["Bitter"] = "unhappy" ;
578 _EmotesMap["Bloodthirsty"] = "gesture" ;
579 _EmotesMap["Bored"] = "afk" ;
580 _EmotesMap["Bow"] = "bow" ;
581 _EmotesMap["Brave"] = "brave_great" ;
582 _EmotesMap["Bubbly"] = "laugh" ;
583 _EmotesMap["Burp"] = "burp" ;
584 _EmotesMap["Calm"] = "calm" ;
585 _EmotesMap["Calmdown"] = "calm" ;
586 _EmotesMap["Careful"] = "calm" ;
587 _EmotesMap["Careless"] = "relieved_sigh" ;
588 _EmotesMap["Casual"] = "relaxed" ;
589 _EmotesMap["Chaotic"] = "unhappy" ;
590 _EmotesMap["Cheer"] = "cheer" ;
591 _EmotesMap["Clinical"] = "follow" ;
592 _EmotesMap["Cold"] = "cold_contemptuous_disdainful_haughty_megalomaniac_obnoxious" ;
593 _EmotesMap["Compassionate"] = "smile" ;
594 _EmotesMap["Condescending"] = "smile" ;
595 _EmotesMap["Confident"] = "smile" ;
596 _EmotesMap["Confused"] = "unhappy" ;
597 _EmotesMap["Contemptuous"] = "cold_contemptuous_disdainful_haughty_megalomaniac_obnoxious" ;
598 _EmotesMap["Content"] = "smile" ;
599 _EmotesMap["Courageous"] = "roar" ;
600 _EmotesMap["Courtly"] = "smile" ;
601 _EmotesMap["Coward"] = "blush" ;
602 _EmotesMap["Crazy"] = "dance" ;
603 _EmotesMap["Crude"] = "gesture" ;
604 _EmotesMap["Cruel"] = "giggle" ;
605 _EmotesMap["Curious"] = "curious" ;
606 _EmotesMap["Cynical"] = "smile" ;
607 _EmotesMap["Dainty"] = "apologize" ;
608 _EmotesMap["Dance"] = "dance" ;
609 _EmotesMap["Defensive"] = "calm" ;
610 _EmotesMap["Depressed"] = "sad" ;
611 _EmotesMap["Desire"] = "kiss" ;
612 _EmotesMap["Despaired"] = "cry" ;
613 _EmotesMap["Destructive"] = "angry" ;
614 _EmotesMap["Die"] = "" ;
615 _EmotesMap["Dignified"] = "relaxed" ;
616 _EmotesMap["Diplomatic"] = "bow" ;
617 _EmotesMap["Disappointed"] = "unhappy" ;
618 _EmotesMap["Discreet"] = "discreet_hardsilence" ;
619 _EmotesMap["Disdainful"] = "cold_contemptuous_disdainful_haughty_megalomaniac_obnoxious" ;
620 _EmotesMap["Disgruntled"] = "roar" ;
621 _EmotesMap["Disgusted"] = "ashamed_disgusted_desillusioned_loathing_pitying" ;
622 _EmotesMap["Disillusioned"] = "ashamed_disgusted_desillusioned_loathing_pitying" ;
623 _EmotesMap["Dismayed"] = "sad" ;
624 _EmotesMap["Disoriented"] = "puzzled_thoughtful_troubled" ;
625 _EmotesMap["Distracted"] = "afk" ;
626 _EmotesMap["Doubtful"] = "doubtful" ;
627 _EmotesMap["Dramatic"] = "dramatic" ;
628 _EmotesMap["Dreamy"] = "afk" ;
629 _EmotesMap["Drunk"] = "drunk" ;
630 _EmotesMap["Dutiful"] = "kneel" ;
631 _EmotesMap["Eager"] = "impatient" ;
632 _EmotesMap["Earnest"] = "firm" ;
633 _EmotesMap["Ecstatic"] = "applaud" ;
634 _EmotesMap["Egoistic"] = "pompous" ;
635 _EmotesMap["Embarrassed"] = "blush" ;
636 _EmotesMap["Emotional"] = "" ;
637 _EmotesMap["Emotionless"] = "discreet_hardsilence" ;
638 _EmotesMap["Emphatic"] = "cheer" ;
639 _EmotesMap["Encouraging"] = "cheer" ;
640 _EmotesMap["Enraged"] = "roar" ;
641 _EmotesMap["Enthusiastic"] = "dance" ;
642 _EmotesMap["Envious"] = "" ;
643 _EmotesMap["Evil"] = "gesture" ;
644 _EmotesMap["Excited"] = "impatient" ;
645 _EmotesMap["Exercise"] = "exercise" ;
646 _EmotesMap["Exhausted"] = "calm" ;
647 _EmotesMap["Exuberant"] = "lol" ;
648 _EmotesMap["Faithful"] = "" ;
649 _EmotesMap["Fanatical"] = "" ;
650 _EmotesMap["Fastidious"] = "" ;
651 _EmotesMap["FBT"] = "FBT" ;
652 _EmotesMap["Fearful"] = "fearful_insecure_nervous_panic_scared" ;
653 _EmotesMap["Firm"] = "firm" ;
654 _EmotesMap["Forgive"] = "forgive" ;
655 _EmotesMap["Fraternal"] = "cheer" ;
656 _EmotesMap["Friendly"] = "cheer" ;
657 _EmotesMap["Frustrated"] = "sad" ;
658 _EmotesMap["Funny"] = "laugh" ;
659 _EmotesMap["Generous"] = "smile" ;
660 _EmotesMap["Gimme5"] = "" ;
661 _EmotesMap["Gloomy"] = "sad" ;
662 _EmotesMap["Goofy"] = "" ;
663 _EmotesMap["Great"] = "brave_great" ;
664 _EmotesMap["Grin"] = "smile" ;
665 _EmotesMap["Grumpy"] = "unhappy" ;
666 _EmotesMap["Guilty"] = "guilty" ;
667 _EmotesMap["Happy"] = "smile" ;
668 _EmotesMap["Hardsilence"] = "discreet_hardsilence" ;
669 _EmotesMap["Haughty"] = "cold_contemptuous_disdainful_haughty_megalomaniac_obnoxious" ;
670 _EmotesMap["Helpful"] = "" ;
671 _EmotesMap["Heroic"] = "heroic" ;
672 _EmotesMap["Hiha"] = "wave" ;
673 _EmotesMap["Honest"] = "" ;
674 _EmotesMap["Hopeful"] = "" ;
675 _EmotesMap["Hopeless"] = "cry" ;
676 _EmotesMap["Humble"] = "bow" ;
677 _EmotesMap["Hungry"] = "hungry" ;
678 _EmotesMap["Hurried"] = "impatient" ;
679 _EmotesMap["Hurry"] = "impatient" ;
680 _EmotesMap["Hysterical"] = "roar" ;
681 _EmotesMap["Imploring"] = "kneel" ;
682 _EmotesMap["Indifferent"] = "indifferent_neutral_noclue_resigned" ;
683 _EmotesMap["Indignant"] = "shocked" ;
684 _EmotesMap["Indulgent"] = "" ;
685 _EmotesMap["Innocent"] = "sincerely" ;
686 _EmotesMap["Insecure"] = "fearful_insecure_nervous_panic_scared" ;
687 _EmotesMap["Interested"] = "interested" ;
688 _EmotesMap["Jealous"] = "angry" ;
689 _EmotesMap["Joyful"] = "laugh" ;
690 _EmotesMap["Kind"] = "smile" ;
691 _EmotesMap["Lazy"] = "none" ;
692 _EmotesMap["Loathing"] = "loathing" ;
693 _EmotesMap["Logical"] = "" ;
694 _EmotesMap["Lonely"] = "sad" ;
695 _EmotesMap["Loud"] = "pompous" ;
696 _EmotesMap["Love"] = "kiss" ;
697 _EmotesMap["Loyal"] = "agree" ;
698 _EmotesMap["Lustful"] = "" ;
699 _EmotesMap["Malevolent"] = "cold_contemptuous_disdainful_haughty_megalomaniac_obnoxious" ;
700 _EmotesMap["Malicious"] = "giggle" ;
701 _EmotesMap["Mean"] = "" ;
702 _EmotesMap["Megalomaniac"] = "cold_contemptuous_disdainful_haughty_megalomaniac_obnoxious" ;
703 _EmotesMap["Merciful"] = "" ;
704 _EmotesMap["Mischievous"] = "smile" ;
705 _EmotesMap["Mocking"] = "giggle" ;
706 _EmotesMap["Nervous"] = "fearful_insecure_nervous_panic_scared" ;
707 _EmotesMap["Neutral"] = "indifferent_neutral_noclue_resigned" ;
708 _EmotesMap["Nice"] = "smile" ;
709 _EmotesMap["Noclue"] = "indifferent_neutral_noclue_resigned" ;
710 _EmotesMap["None"] = "none" ;
711 _EmotesMap["Nostalgic"] = "" ;
712 _EmotesMap["Obnoxious"] = "obnoxious" ;
713 _EmotesMap["Obscure"] = "" ;
714 _EmotesMap["Obsessed"] = "" ;
715 _EmotesMap["Offended"] = "angry" ;
716 _EmotesMap["Optimistic"] = "smile" ;
717 _EmotesMap["Over"] = "over" ;
718 _EmotesMap["Pacific"] = "cheer" ;
719 _EmotesMap["Painful"] = "cry" ;
720 _EmotesMap["Panick"] = "fearful_insecure_nervous_panic_scared" ;
721 _EmotesMap["Patient"] = "calm" ;
722 _EmotesMap["Patriotic"] = "" ;
723 _EmotesMap["Pedantic"] = "" ;
724 _EmotesMap["Perturbed"] = "puzzled_thoughtful_troubled" ;
725 _EmotesMap["Pessimistic"] = "unhappy" ;
726 _EmotesMap["Petulant"] = "petulant" ;
727 _EmotesMap["Philosophical"] = "" ;
728 _EmotesMap["Pitying"] = "pitying" ;
729 _EmotesMap["Playful"] = "playful" ;
730 _EmotesMap["Pleased"] = "smile" ;
731 _EmotesMap["Point"] = "point" ;
732 _EmotesMap["Pointback"] = "pointback" ;
733 _EmotesMap["Pointfront"] = "point" ;
734 _EmotesMap["Pointleft"] = "pointleft" ;
735 _EmotesMap["Pointright"] = "pointright" ;
736 _EmotesMap["Polite"] = "smile" ;
737 _EmotesMap["Pompous"] = "pompous" ;
738 _EmotesMap["Powerful"] = "" ;
739 _EmotesMap["Praying"] = "praying" ;
740 _EmotesMap["Proud"] = "" ;
741 _EmotesMap["Provocative"] = "point" ;
742 _EmotesMap["Puzzled"] = "puzzled_thoughtful_troubled" ;
743 _EmotesMap["Quiet"] = "calm" ;
744 _EmotesMap["Ready"] = "impatient" ;
745 _EmotesMap["Reassured"] = "" ;
746 _EmotesMap["Rebellious"] = "" ;
747 _EmotesMap["Reckless"] = "impatient" ;
748 _EmotesMap["Regretful"] = "apologize" ;
749 _EmotesMap["Relaxed"] = "relaxed" ;
750 _EmotesMap["Relieved"] = "relieved" ;
751 _EmotesMap["Reluctant"] = "sad" ;
752 _EmotesMap["Remorseful"] = "sad" ;
753 _EmotesMap["Resigned"] = "indifferent_neutral_noclue_resigned" ;
754 _EmotesMap["Respectful"] = "bow" ;
755 _EmotesMap["Revengeful"] = "revengeful_spitful" ;
756 _EmotesMap["Rice"] = "rice" ;
757 _EmotesMap["Ridicule"] = "giggle" ;
758 _EmotesMap["Righteous"] = "righteous" ;
759 _EmotesMap["Romantic"] = "kiss" ;
760 _EmotesMap["Rude"] = "gesture" ;
761 _EmotesMap["Sad"] = "sad" ;
762 _EmotesMap["Sarcastic"] = "smile" ;
763 _EmotesMap["Scared"] = "fearful_insecure_nervous_panic_scared" ;
764 _EmotesMap["Scolding"] = "angry" ;
765 _EmotesMap["Sedate"] = "calm" ;
766 _EmotesMap["Selfish"] = "" ;
767 _EmotesMap["Serious"] = "serious" ;
768 _EmotesMap["Shameless"] = "giggle" ;
769 _EmotesMap["Sheepish"] = "blush" ;
770 _EmotesMap["Shifty"] = "shifty" ;
771 _EmotesMap["Shocked"] = "shocked" ;
772 _EmotesMap["Shutup"] = "angry" ;
773 _EmotesMap["Shy"] = "blush" ;
774 _EmotesMap["Sigh"] = "sigh" ;
775 _EmotesMap["Silence"] = "calm" ;
776 _EmotesMap["Silly"] = "silly" ;
777 _EmotesMap["Sincerely"] = "sincerely" ;
778 _EmotesMap["Sleepy"] = "sleepy_yawn_tired" ;
779 _EmotesMap["Sly"] = "smile" ;
780 _EmotesMap["Smack"] = "smack" ;
781 _EmotesMap["Smug"] = "smile" ;
782 _EmotesMap["Sorry"] = "apologize" ;
783 _EmotesMap["Spiteful"] = "" ;
784 _EmotesMap["Squeamish"] = "squeamish" ;
785 _EmotesMap["Stop"] = "disagree" ;
786 _EmotesMap["Strong"] = "roar" ;
787 _EmotesMap["Stubborn"] = "" ;
788 _EmotesMap["Suffering"] = "cry" ;
789 _EmotesMap["Surprised"] = "surprised" ;
790 _EmotesMap["Suspicious"] = "suspicious" ;
791 _EmotesMap["Taunting"] = "gesture" ;
792 _EmotesMap["Terrified"] = "unhappy" ;
793 _EmotesMap["Thankful"] = "thank" ;
794 _EmotesMap["Thirsty"] = "thirsty" ;
795 _EmotesMap["Thoughtful"] = "puzzled_thoughtful_troubled";
796 _EmotesMap["Tired"] = "sleepy_yawn_tired" ;
797 _EmotesMap["Tolerant"] = "agree" ;
798 _EmotesMap["Troubled"] = "" ;
799 _EmotesMap["Uncertain"] = "apologize" ;
800 _EmotesMap["Unhappy"] = "unhappy" ;
801 _EmotesMap["Unwilling"] = "unwilling" ;
802 _EmotesMap["Vengeful"] = "gesture" ;
803 _EmotesMap["Wait"] = "wait" ;
804 _EmotesMap["Warm"] = "smile" ;
805 _EmotesMap["Wary"] = "" ;
806 _EmotesMap["Wave"] = "wave" ;
807 _EmotesMap["Whine"] = "cry" ;
808 _EmotesMap["Wicked"] = "wicked" ;
809 _EmotesMap["Wise"] = "" ;
810 _EmotesMap["Wistful"] = "" ;
811 _EmotesMap["Worried"] = "puzzled_thoughtful_troubled" ;
812 _EmotesMap["Wounded"] = "" ;
813 _EmotesMap["Yawn"] = "sleepy_yawn_tired" ;
814 _EmotesMap["Youandme"] = "youandme";
822 bool CScenarioValidator::setScenarioToLoad( const std::string& filename, CScenarioValidator::TValues& values, std::string& md5, std::string& signature, bool checkMD5)
825 values.clear();
827 _Filename = filename;
828 _Values.clear();
829 // open our input file
830 NLMISC::CIFile inf;
831 if (!inf.open(_Filename, true) )
833 nlwarning("Can't load scenario %s", _Filename.c_str());
834 return false;
839 static const char * header = "---- Header\n";
840 static const char * slashheader = "---- /Header\n\n";
841 static const char * comment = "-- ";
843 static const uint headerLen = (uint)strlen(header);
844 static const uint slasheaderLen = (uint)strlen(slashheader);
845 static const uint commentLen = (uint)strlen(comment);
848 NLMISC::CSString tmp;
849 tmp.resize( inf.getFileSize() );
850 inf.serialBuffer((uint8*)&tmp[0], (uint)tmp.size());
851 _ScenarioBody = tmp.replace("\r\n", "\n");
857 // Scenario without header
858 if (_ScenarioBody.size() < headerLen ||_ScenarioBody.substr(0, headerLen) != header )
860 md5.clear();
861 signature.clear();
862 inf.close();
863 return true;
866 std::string::size_type endHeader = _ScenarioBody.find(slashheader, headerLen);
867 if (endHeader == std::string::npos ) { inf.close(); return false; }
868 std::string::size_type startHeader = headerLen;
870 std::vector<std::string> lines;
871 NLMISC::splitString( _ScenarioBody.substr(startHeader, endHeader - startHeader), "'\n", lines);
872 std::vector<std::string>::const_iterator firstLine(lines.begin()), lastLine(lines.end());
873 std::vector<std::string> result;
875 for (; firstLine != lastLine ; ++firstLine)
877 result.clear();
878 NLMISC::splitString(*firstLine, " = '", result);
879 if (result.size() == 1)
881 result.push_back("");
883 if (result.size() == 2)
885 if (result[0].find(comment) != std::string::npos)
887 //>result[1]"\\n" => "\n"
888 NLMISC::CSString tmp = result[1];
889 tmp = tmp.replace("\\n", "\n");
891 values.push_back( std::make_pair( result[0].substr(commentLen), tmp));
896 if (values.size() >=2
897 && values[0].first == "Version"
898 && values[1].first == "Signature"
899 && values[2].first == "HeaderMD5" && values[3].first =="BodyMD5")
901 std::string headerBodyMd5;
902 std::string::size_type subHeader = _ScenarioBody.find("-- BodyMD5", startHeader);
903 if (checkMD5)
905 std::string md5Id1 = NLMISC::getMD5((uint8*)(_ScenarioBody.data() + subHeader), (uint32)(endHeader - subHeader)).toString();
906 if (values[2].second != md5Id1 )
908 return false;
910 std::string md5Id2 = NLMISC::getMD5((uint8*)(_ScenarioBody.data() + endHeader + slasheaderLen), (uint32)(_ScenarioBody.size() - (endHeader + slasheaderLen))).toString();
911 if (values[3].second != md5Id2)
913 return false;
917 md5 = values[2].second;
918 signature = values[1].second;
924 catch(...)
926 _Values = values;
927 nlwarning("Can't load scenario %s", _Filename.c_str());
928 return false;
931 _Values = values;
932 // close the file
933 inf.close();
934 return true;
939 void CScenarioValidator::applyLoad(std::string& filename, std::string& body, CScenarioValidator::TValues& values)
941 filename = _Filename;
942 body = _ScenarioBody;
943 values = _Values;
944 if (_LoadCb)
946 _LoadCb->doOperation(filename, body, values);
950 bool CScenarioValidator::setScenarioToSave(const std::string& filename, CObject* scenario, const CScenarioValidator::TValues& values, std::string& headerMD5)
952 _Filename = filename;
953 //std::ostringstream out2;
954 //out2.str("");
955 std::string out2;
957 if (!scenario)
959 return false;
962 //out2 <<"scenario = "<< *scenario ;
963 out2 += "scenario = ";
964 scenario->serialize(out2);
966 _ScenarioBody = out2;
968 NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_ScenarioBody.data(),(uint32) _ScenarioBody.size());
969 _BodyMd5 = md5Id.toString().c_str();
973 out2.clear();
974 //out2.str("");
975 out2 += NLMISC::toString("-- BodyMD5 = '%s'\n", _BodyMd5.c_str() );
976 TValues::const_iterator first(values.begin()), last(values.end());
977 for (; first != last; ++first)
979 //>first->second.c_str()) "\n" => "\\n"
980 NLMISC::CSString tmp = first->second.c_str();
981 tmp = tmp.replace("\n", "\\n");
983 out2 += NLMISC::toString("-- %s = '%s'\n", first->first.c_str(), tmp.c_str());
986 _HeaderBody =out2;
987 std::string headerBodyMd5;
989 NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_HeaderBody.data(), (uint32)_HeaderBody.size());
990 _HeaderMd5 = md5Id.toString().c_str();
991 headerMD5 = _HeaderMd5;
993 return true;
996 std::string CScenarioValidator::AutoSaveSignature;
998 bool CScenarioValidator::applySave(const std::string& signature)
1000 NLMISC::COFile out;
1002 std::string::size_type index = NLMISC::CFile::getLastSeparator(_Filename);
1003 if (index != std::string::npos)
1005 std::string dir = _Filename.substr(0, index);
1006 if (NLMISC::CFile::isExists(dir) == false )
1008 if (NLMISC::CFile::createDirectory(dir) == false)
1010 return false;
1015 if (!out.open(_Filename, false, false, true))
1018 nlwarning("Can't save: the file %s can not be saved.", _Filename.c_str());
1019 return false;
1026 //std::stringstream out2;
1028 //out2.str("");
1029 //out2 << "---- Header\n";
1030 //out2 << NLMISC::toString("-- Version = '%u'\n", 1 );
1031 //out2 << NLMISC::toString("-- Signature = '%s'\n", signature.c_str() );
1032 //out2 << NLMISC::toString("-- HeaderMD5 = '%s'\n", _HeaderMd5.c_str() );
1033 //out2 << _HeaderBody;
1034 //out2 << "---- /Header\n\n";
1035 //out2 << _ScenarioBody;
1037 std::string out2;
1039 out2 += "---- Header\n";
1040 out2 += NLMISC::toString("-- Version = '%u'\n", 1 );
1041 out2 += NLMISC::toString("-- Signature = '%s'\n", signature.c_str() );
1042 out2 += NLMISC::toString("-- HeaderMD5 = '%s'\n", _HeaderMd5.c_str() );
1043 out2 += _HeaderBody;
1044 out2 += "---- /Header\n\n";
1045 out2 += _ScenarioBody;
1047 out.serialBuffer((uint8*)out2.c_str(), (uint)out2.size());
1048 if (_Filename != std::string("save/r2_buffer.dat") )
1050 nlinfo("Scenario %s saved", _Filename.c_str());
1052 else
1054 AutoSaveSignature = signature;
1057 out.close();
1059 return true;
1061 catch (...)
1063 nlwarning("Can't save: the file %s can not be saved.", _Filename.c_str());
1064 out.close();
1066 return false;
1069 return true;
1073 CScenarioValidator::CScenarioValidator(CScenarioValidatorLoadSuccededCallback* loadCb ):_LoadCb(loadCb){}
1075 CScenarioValidator::~CScenarioValidator(){ delete _LoadCb; }
1078 /**********************************************************/
1079 /******* USER COMPONENT MD5 MANAGEMENT ********************/
1080 /**********************************************************/
1081 bool CUserComponentValidator::setUserComponentToLoad( const std::string& filename, CScenarioValidator::TValues& values, std::string& md5, std::string& signature, bool checkMD5)
1084 values.clear();
1086 _Filename = filename;
1087 _Values.clear();
1088 // open our input file
1089 NLMISC::CIFile inf;
1090 if (!inf.open(_Filename, true) )
1092 nlwarning("Can't load usercomponent in file %s", _Filename.c_str());
1093 return false;
1098 static const char * header = "---- Header\n";
1099 static const char * slashheader = "---- /Header\n\n";
1100 static const char * comment = "-- ";
1102 static const uint headerLen = (uint)strlen(header);
1103 static const uint slasheaderLen = (uint)strlen(slashheader);
1104 static const uint commentLen = (uint)strlen(comment);
1107 NLMISC::CSString tmp;
1108 tmp.resize( inf.getFileSize() );
1109 inf.serialBuffer((uint8*)&tmp[0], (uint)tmp.size());
1110 _UserComponentBody = tmp.replace("\r\n", "\n");
1112 // Scenario without header
1113 if (_UserComponentBody.size() < headerLen ||_UserComponentBody.substr(0, headerLen) != header )
1115 md5.clear();
1116 signature.clear();
1117 inf.close();
1118 return true;
1121 std::string::size_type endHeader = _UserComponentBody.find(slashheader, headerLen);
1122 if (endHeader == std::string::npos ) { inf.close(); return false; }
1123 std::string::size_type startHeader = headerLen;
1125 std::vector<std::string> lines;
1126 NLMISC::splitString( _UserComponentBody.substr(startHeader, endHeader - startHeader), "'\n", lines);
1127 std::vector<std::string>::const_iterator firstLine(lines.begin()), lastLine(lines.end());
1128 std::vector<std::string> result;
1130 for (; firstLine != lastLine ; ++firstLine)
1132 result.clear();
1133 NLMISC::splitString(*firstLine, " = '", result);
1134 if (result.size() == 1)
1136 result.push_back("");
1138 if (result.size() == 2)
1140 if (result[0].find(comment) != std::string::npos)
1142 //>result[1]"\\n" => "\n"
1143 NLMISC::CSString tmp = result[1];
1144 tmp = tmp.replace("\\n", "\n");
1146 values.push_back( std::make_pair( result[0].substr(commentLen), tmp));
1151 if (values.size() >=2
1152 && values[0].first == "Version"
1153 && values[1].first == "Signature"
1154 && values[2].first == "HeaderMD5" && values[3].first =="BodyMD5")
1156 std::string headerBodyMd5;
1157 std::string::size_type subHeader = _UserComponentBody.find("-- BodyMD5", startHeader);
1158 if (checkMD5)
1160 std::string md5Id1 = NLMISC::getMD5((uint8*)(_UserComponentBody.data() + subHeader), (uint32)(endHeader - subHeader)).toString();
1161 if (values[2].second != md5Id1 )
1163 return false;
1165 std::string md5Id2 = NLMISC::getMD5((uint8*)(_UserComponentBody.data() + endHeader + slasheaderLen), (uint32)(_UserComponentBody.size() - (endHeader + slasheaderLen))).toString();
1166 if (values[3].second != md5Id2)
1168 return false;
1172 md5 = values[2].second;
1173 signature = values[1].second;
1179 catch(...)
1181 _Values = values;
1182 nlwarning("Can't load UserComponent defined in %s", _Filename.c_str());
1183 return false;
1186 _Values = values;
1187 // close the file
1188 inf.close();
1189 return true;
1194 void CUserComponentValidator::applyLoad(std::string& filename, std::string& body, CScenarioValidator::TValues& values)
1196 filename = _Filename;
1197 body = _UserComponentBody;
1198 values = _Values;
1199 if (_LoadCb)
1201 _LoadCb->doOperation(filename, body, values);
1205 bool CUserComponentValidator::setUserComponentToSave(const std::string& filename, const CUserComponentValidator::TValues& values, std::string& headerMD5, const std::string &body)
1207 _Filename = filename;
1208 // std::ostringstream out2;
1209 // out2.str(body);
1211 // _UserComponentBody =out2.str();
1213 _UserComponentBody = body;
1216 NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_UserComponentBody.data(), (uint32)_UserComponentBody.size());
1217 _BodyMd5 = md5Id.toString().c_str();
1220 // out2.str("");
1221 // out2 << NLMISC::toString("-- BodyMD5 = '%s'\n", _BodyMd5.c_str() );
1222 // TValues::const_iterator first(values.begin()), last(values.end());
1223 // for (; first != last; ++first)
1224 // {
1225 //>first->second.c_str()) "\n" => "\\n"
1226 // NLMISC::CSString tmp = first->second.c_str();
1227 // tmp = tmp.replace("\n", "\\n");
1229 // out2 << NLMISC::toString("-- %s = '%s'\n", first->first.c_str(), tmp.c_str());
1230 // }
1233 // _HeaderBody =out2.str();
1236 _HeaderBody = NLMISC::toString("-- BodyMD5 = '%s'\n", _BodyMd5.c_str() );
1238 TValues::const_iterator first(values.begin()), last(values.end());
1239 for (; first != last; ++first)
1241 //>first->second.c_str()) "\n" => "\\n"
1242 NLMISC::CSString tmp = first->second.c_str();
1243 tmp = tmp.replace("\n", "\\n");
1245 _HeaderBody += NLMISC::toString("-- %s = '%s'\n", first->first.c_str(), tmp.c_str());
1249 std::string headerBodyMd5;
1251 NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_HeaderBody.data(), (uint32)_HeaderBody.size());
1252 _HeaderMd5 = md5Id.toString().c_str();
1253 headerMD5 = _HeaderMd5;
1256 return true;
1259 std::string CUserComponentValidator::AutoSaveSignature;
1261 bool CUserComponentValidator::applySave(const std::string& signature)
1263 NLMISC::COFile out;
1265 std::string::size_type index = NLMISC::CFile::getLastSeparator(_Filename);
1266 if (index != std::string::npos)
1268 std::string dir = _Filename.substr(0, index);
1269 if (NLMISC::CFile::isExists(dir) == false )
1271 if (NLMISC::CFile::createDirectory(dir) == false)
1273 return false;
1278 if (!out.open(_Filename, false, false, true))
1281 nlwarning("Can't save: the file %s can not be saved.", _Filename.c_str());
1282 return false;
1289 //std::stringstream out2;
1291 //out2.str("");
1292 //out2 << "---- Header\n";
1293 //out2 << NLMISC::toString("-- Version = '%u'\n", 1 );
1294 //out2 << NLMISC::toString("-- Signature = '%s'\n", signature.c_str() );
1295 //out2 << NLMISC::toString("-- HeaderMD5 = '%s'\n", _HeaderMd5.c_str() );
1296 //out2 << _HeaderBody;
1297 //out2 << "---- /Header\n\n";
1298 //out2 << _UserComponentBody;
1301 //out.serialBuffer((uint8*)out2.str().c_str(),out2.str().size());
1303 std::string out2;
1305 out2 += "---- Header\n";
1306 out2 += NLMISC::toString("-- Version = '%u'\n", 1 );
1307 out2 += NLMISC::toString("-- Signature = '%s'\n", signature.c_str() );
1308 out2 += NLMISC::toString("-- HeaderMD5 = '%s'\n", _HeaderMd5.c_str() );
1309 out2 += _HeaderBody;
1310 out2 += "---- /Header\n\n";
1311 out2 += _UserComponentBody;
1314 out.serialBuffer((uint8*)out2.c_str(),(uint)out2.size());
1315 if (_Filename != std::string("save/r2_buffer.dat") )
1317 nlinfo("UserComponent %s saved", _Filename.c_str());
1320 out.close();
1322 return true;
1324 catch (...)
1326 nlwarning("Can't save user component: the file %s can not be saved.", _Filename.c_str());
1327 out.close();
1329 return false;
1332 return true;
1336 CUserComponentValidator::CUserComponentValidator(CUserComponentValidatorLoadSuccededCallback* loadCb ):_LoadCb(loadCb){}
1338 CUserComponentValidator::~CUserComponentValidator(){ delete _LoadCb; }
1339 /********************************************************************/