Fix css style order when using external css files
[ryzomcore.git] / ryzom / client / src / r2 / instance.cpp
blob78845fb665c2835c586d414b61dc66dc2996c452
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 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
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 "stdpch.h"
22 #include "instance.h"
24 #include "editor.h"
25 #include "tool_pick.h"
26 #include "tool_select_rotate.h"
27 #include "tool_select_move.h"
29 #include "../entities.h"
30 #include "../interface_v3/interface_manager.h"
31 #include "nel/gui/lua_ihm.h"
32 #include "../interface_v3/lua_ihm_ryzom.h"
34 #include "displayer_visual_entity.h"
36 #ifdef DEBUG_NEW
37 #define new DEBUG_NEW
38 #endif
40 using namespace NLMISC;
42 namespace R2
46 // TMP TMP
47 #define TEST_LUA_PROJ
48 //#define TEST_LUA_PROJ nlassert(_ToLua._LuaProjection.isUserData());
50 // *********************************************************************************************************
51 /*static*/ void setDisplayedInstance(CDisplayerBase *displayer, CInstance *displayedInstance)
53 displayer->setDisplayedInstance(displayedInstance);
56 // *********************************************************************************************************
57 CInstance::CInstance(const CObjectTable *objectTable, CLuaState &ls)
59 CLuaStackChecker lsc(&ls);
60 nlassert(objectTable);
61 _ObjectTable = objectTable;
62 // create projection in lua
63 getEditor().projectInLua(objectTable);
64 _ToLua._LuaProjection.pop(getEditor().getLua());
65 TEST_LUA_PROJ;
66 static volatile bool debugMetatable = false;
67 if (debugMetatable)
69 _ToLua._LuaProjection.push();
70 if (!ls.getMetaTable())
72 ls.pop();
73 nlwarning("No metatable found");
75 else
77 CLuaObject mt(ls);
78 mt.dump();
80 ls.pop();
82 _Selectable = true;
83 _LastParentOk = false;
84 _LastParent = NULL;
85 _RegisteredInDispNameList = false;
86 _ClassIndex = getEditor().classToIndex(getClassName());
87 if (_ClassIndex < 0)
89 nlwarning("Class index not found for '%s'", getClassName().c_str());
93 // *********************************************************************************************************
94 std::string CInstance::getName() const
96 //H_AUTO(R2_CInstance_getName)
97 TEST_LUA_PROJ;
98 return getString(_ObjectTable, "Name");
101 // *********************************************************************************************************
102 std::string CInstance::getPaletteId()
104 //H_AUTO(R2_CInstance_getPaletteId)
105 TEST_LUA_PROJ;
106 return getString(_ObjectTable, "Base");
109 // *********************************************************************************************************
110 ucstring CInstance::getDisplayName()
112 //H_AUTO(R2_CInstance_getDisplayName)
113 TEST_LUA_PROJ;
114 CLuaState &ls = getEditor().getLua();
115 CLuaStackRestorer lsr(&ls, ls.getTop());
116 if (getLuaProjection()["getDisplayName"].isNil())
118 // object is not displayed -> ignore name
119 return ucstring("");
121 if (getLuaProjection().callMethodByNameNoThrow("getDisplayName", 0, 1))
123 #ifdef RYZOM_LUA_UCSTRING
124 ucstring result;
125 if (CLuaIHM::pop(ls, result)) return result;
126 #else
127 std::string res = ls.toString();
128 ls.pop();
129 if (!res.empty()) return res;
130 #endif
132 TEST_LUA_PROJ;
133 return ucstring("Can't find display name");
136 // *********************************************************************************************************
137 void CInstance::visit(IInstanceVisitor &visitor)
139 //H_AUTO(R2_CInstance_visit)
140 TEST_LUA_PROJ;
141 nlassert(_ObjectTable);
142 // forward object vistor call to 'instance' visitor call
143 struct CInstanceVisitor : public IObjectVisitor
145 IInstanceVisitor *Visitor;
146 virtual void visit(CObjectTable &obj)
148 CInstance *inst = getEditor().getInstanceFromObject(&obj);
149 if (inst)
151 Visitor->visit(*inst);
155 CInstanceVisitor instanceVisitor;
156 instanceVisitor.Visitor = &visitor;
157 const_cast<CObjectTable *>(_ObjectTable)->visit(instanceVisitor); // 'const' is respected here, because CInstanceVisitor gives a reference to CInstance
158 // which in turn only allow a const reference on CObjectTable
159 TEST_LUA_PROJ;
162 // *********************************************************************************************************
163 void CInstance::setDisplayerVisual(CDisplayerVisual *displayer)
165 //H_AUTO(R2_CInstance_setDisplayerVisual)
166 TEST_LUA_PROJ;
167 if (_DisplayerVisual)
169 setDisplayedInstance(_DisplayerVisual, NULL);
171 if (displayer)
173 setDisplayedInstance(displayer, this);
175 _DisplayerVisual = displayer;
176 TEST_LUA_PROJ;
179 // *********************************************************************************************************
180 CDisplayerVisual *CInstance::getDisplayerVisual() const
182 //H_AUTO(R2_CInstance_getDisplayerVisual)
183 TEST_LUA_PROJ;
184 if (!_DisplayerVisual) return NULL;
185 return NLMISC::safe_cast<CDisplayerVisual *>((CDisplayerBase *)_DisplayerVisual);
189 // *********************************************************************************************************
190 void CInstance::setDisplayerUI(CDisplayerBase *displayer)
192 //H_AUTO(R2_CInstance_setDisplayerUI)
193 TEST_LUA_PROJ;
194 if (_DisplayerUI)
196 setDisplayedInstance(_DisplayerUI, NULL);
198 if (displayer)
200 setDisplayedInstance(displayer, this);
202 _DisplayerUI = displayer;
205 // *********************************************************************************************************
206 void CInstance::setDisplayerProperties(CDisplayerBase *displayer)
208 //H_AUTO(R2_CInstance_setDisplayerProperties)
209 TEST_LUA_PROJ;
210 if (_DisplayerProperties)
212 setDisplayedInstance(_DisplayerProperties, NULL);
214 if (displayer)
216 setDisplayedInstance(displayer, this);
218 _DisplayerProperties = displayer;
221 // *********************************************************************************************************
222 CInstance::~CInstance()
224 TEST_LUA_PROJ;
225 setDisplayerVisual(NULL);
226 setDisplayerUI(NULL);
227 setDisplayerProperties(NULL);
228 TEST_LUA_PROJ;
232 // *********************************************************************************************************
233 void CInstance::onPreActChanged()
235 //H_AUTO(R2_CInstance_onPreActChanged)
236 TEST_LUA_PROJ;
237 if (_DisplayerVisual) getDisplayerVisual()->onPreActChanged();
238 if (_DisplayerUI) _DisplayerUI->onPreActChanged();
239 if (_DisplayerProperties) _DisplayerProperties->onPreActChanged();
240 _ToLua.onActChanged();
241 TEST_LUA_PROJ;
244 // *********************************************************************************************************
245 void CInstance::onActChanged()
247 //H_AUTO(R2_CInstance_onActChanged)
248 TEST_LUA_PROJ;
249 if (_DisplayerVisual) getDisplayerVisual()->onActChanged();
250 if (_DisplayerUI) _DisplayerUI->onActChanged();
251 if (_DisplayerProperties) _DisplayerProperties->onActChanged();
252 _ToLua.onActChanged();
253 TEST_LUA_PROJ;
254 refreshDisplayNameHandle();
257 // *********************************************************************************************************
258 void CInstance::onContinentChanged()
260 //H_AUTO(R2_CInstance_onContinentChanged)
261 TEST_LUA_PROJ;
262 if (_DisplayerVisual) getDisplayerVisual()->onContinentChanged();
263 if (_DisplayerUI) _DisplayerUI->onContinentChanged();
264 if (_DisplayerProperties) _DisplayerProperties->onContinentChanged();
265 _ToLua.onContinentChanged();
266 TEST_LUA_PROJ;
270 // *********************************************************************************************************
271 void CInstance::onCreate()
273 //H_AUTO(R2_CInstance_onCreate)
274 TEST_LUA_PROJ;
275 if (_DisplayerVisual) getDisplayerVisual()->onCreate();
276 if (_DisplayerUI) _DisplayerUI->onCreate();
277 if (_DisplayerProperties) _DisplayerProperties->onCreate();
278 _ToLua.onCreate();
279 TEST_LUA_PROJ;
282 // *********************************************************************************************************
283 void CInstance::onPostCreate()
285 //H_AUTO(R2_CInstance_onPostCreate)
286 TEST_LUA_PROJ;
287 _LastParentOk = false;
288 if (_DisplayerVisual) getDisplayerVisual()->onPostCreate();
289 if (_DisplayerUI) _DisplayerUI->onPostCreate();
290 if (_DisplayerProperties) _DisplayerProperties->onPostCreate();
291 _ToLua.onPostCreate();
292 TEST_LUA_PROJ;
293 nlassert(!_RegisteredInDispNameList);
294 getEditor().registerInstanceDispName(getDisplayName(), this);
295 _RegisteredInDispNameList = true;
298 // *********************************************************************************************************
299 void CInstance::onErase()
301 //H_AUTO(R2_CInstance_onErase)
302 TEST_LUA_PROJ;
303 if (_DisplayerVisual) getDisplayerVisual()->onErase();
304 if (_DisplayerUI) _DisplayerUI->onErase();
305 if (_DisplayerProperties) _DisplayerProperties->onErase();
306 _ToLua.onErase();
307 TEST_LUA_PROJ;
308 if (_RegisteredInDispNameList)
310 getEditor().unregisterInstanceDispName(this);
311 _RegisteredInDispNameList = false;
315 // *********************************************************************************************************
316 void CInstance::refreshDisplayNameHandle()
318 if (_RegisteredInDispNameList)
320 getEditor().unregisterInstanceDispName(this);
321 getEditor().registerInstanceDispName(getDisplayName(), this);
325 // *********************************************************************************************************
326 void CInstance::onPreHrcMove()
328 //H_AUTO(R2_CInstance_onPreHrcMove)
329 TEST_LUA_PROJ;
330 if (_DisplayerVisual) getDisplayerVisual()->onPreHrcMove();
331 if (_DisplayerUI) _DisplayerUI->onPreHrcMove();
332 if (_DisplayerProperties) _DisplayerProperties->onPreHrcMove();
333 _ToLua.onPreHrcMove();
334 TEST_LUA_PROJ;
337 // *********************************************************************************************************
338 void CInstance::onPostHrcMove()
340 //H_AUTO(R2_CInstance_onPostHrcMove)
341 TEST_LUA_PROJ;
342 _LastParentOk = false;
343 if (_DisplayerVisual) getDisplayerVisual()->onPostHrcMove();
344 if (_DisplayerUI) _DisplayerUI->onPostHrcMove();
345 if (_DisplayerProperties) _DisplayerProperties->onPostHrcMove();
346 _ToLua.onPostHrcMove();
347 TEST_LUA_PROJ;
348 refreshDisplayNameHandle();
352 // *********************************************************************************************************
353 void CInstance::onFocus(bool highlighted)
355 //H_AUTO(R2_CInstance_onFocus)
356 TEST_LUA_PROJ;
357 if (_DisplayerVisual) getDisplayerVisual()->onFocus(highlighted);
358 if (_DisplayerUI) _DisplayerUI->onFocus(highlighted);
359 if (_DisplayerProperties) _DisplayerProperties->onFocus(highlighted);
360 _ToLua.onFocus(highlighted);
361 TEST_LUA_PROJ;
364 // *********************************************************************************************************
365 void CInstance::onSelect(bool selected)
367 //H_AUTO(R2_CInstance_onSelect)
368 TEST_LUA_PROJ;
369 if (_DisplayerVisual) getDisplayerVisual()->onSelect(selected);
370 if (_DisplayerUI) _DisplayerUI->onSelect(selected);
371 if (_DisplayerProperties) _DisplayerProperties->onSelect(selected);
372 _ToLua.onSelect(selected);
373 TEST_LUA_PROJ;
376 // *********************************************************************************************************
377 void CInstance::onAttrModified(const std::string &attrName, sint32 attrIndex)
379 //H_AUTO(R2_CInstance_onAttrModified)
380 TEST_LUA_PROJ;
381 if (attrName == "InstanceId")
383 nlwarning("InstanceId modification not allowed !! Please create a new object with a new id");
384 _Id.clear(); // nevertheless invalidate the cache
386 if (_DisplayerVisual) getDisplayerVisual()->onAttrModified(attrName, attrIndex);
387 if (_DisplayerUI) _DisplayerUI->onAttrModified(attrName, attrIndex);
388 if (_DisplayerProperties) _DisplayerProperties->onAttrModified(attrName, attrIndex);
389 _ToLua.onAttrModified(attrName, attrIndex);
390 TEST_LUA_PROJ;
391 if (attrName == "Name" || attrName == "Title")
393 refreshDisplayNameHandle();
397 // *********************************************************************************************************
398 /*void CInstance::onTableModified(const std::string &tableName, const std::string &keyInTable, sint32 indexInTable)
400 if (_DisplayerVisual) getDisplayerVisual()->onTableModified(tableName, keyInTable, indexInTable);
401 if (_DisplayerUI) _DisplayerUI->onTableModified(tableName, keyInTable, indexInTable);
402 if (_DisplayerProperties) _DisplayerProperties->onTableModified(tableName, keyInTable, indexInTable);
405 // *********************************************************************************************************
406 void CInstance::onTargetInstanceCreated(const std::string &refMakerAttr, sint32 refMakerAttrIndex)
408 //H_AUTO(R2_CInstance_onTargetInstanceCreated)
409 TEST_LUA_PROJ;
410 if (_DisplayerVisual) getDisplayerVisual()->onTargetInstanceCreated(refMakerAttr, refMakerAttrIndex);
411 if (_DisplayerUI) _DisplayerUI->onTargetInstanceCreated(refMakerAttr, refMakerAttrIndex);
412 if (_DisplayerProperties) _DisplayerProperties->onTargetInstanceCreated(refMakerAttr, refMakerAttrIndex);
413 _ToLua.onTargetInstanceCreated(refMakerAttr, refMakerAttrIndex);
414 TEST_LUA_PROJ;
417 // *********************************************************************************************************
418 void CInstance::onTargetInstanceErased(const std::string &refMakerAttr, sint32 refMakerAttrIndex)
420 //H_AUTO(R2_CInstance_onTargetInstanceErased)
421 TEST_LUA_PROJ;
422 if (_DisplayerVisual) getDisplayerVisual()->onTargetInstanceErased(refMakerAttr, refMakerAttrIndex);
423 if (_DisplayerUI) _DisplayerUI->onTargetInstanceErased(refMakerAttr, refMakerAttrIndex);
424 if (_DisplayerProperties) _DisplayerProperties->onTargetInstanceErased(refMakerAttr, refMakerAttrIndex);
425 _ToLua.onTargetInstanceErased(refMakerAttr, refMakerAttrIndex);
426 TEST_LUA_PROJ;
429 // *********************************************************************************************************
430 void CInstance::onTargetInstancePreHrcMove(const std::string &refMakerAttr,sint32 refMakerAttrIndex)
432 //H_AUTO(R2_CInstance_onTargetInstancePreHrcMove)
433 TEST_LUA_PROJ;
434 if (_DisplayerVisual) getDisplayerVisual()->onTargetInstancePreHrcMove(refMakerAttr, refMakerAttrIndex);
435 if (_DisplayerUI) _DisplayerUI->onTargetInstancePreHrcMove(refMakerAttr, refMakerAttrIndex);
436 if (_DisplayerProperties) _DisplayerProperties->onTargetInstancePreHrcMove(refMakerAttr, refMakerAttrIndex);
437 _ToLua.onTargetInstancePreHrcMove(refMakerAttr, refMakerAttrIndex);
438 TEST_LUA_PROJ;
441 // *********************************************************************************************************
442 void CInstance::onTargetInstancePostHrcMove(const std::string &refMakerAttr,sint32 refMakerAttrIndex)
444 //H_AUTO(R2_CInstance_onTargetInstancePostHrcMove)
445 TEST_LUA_PROJ;
446 if (_DisplayerVisual) getDisplayerVisual()->onTargetInstancePostHrcMove(refMakerAttr, refMakerAttrIndex);
447 if (_DisplayerUI) _DisplayerUI->onTargetInstancePostHrcMove(refMakerAttr, refMakerAttrIndex);
448 if (_DisplayerProperties) _DisplayerProperties->onTargetInstancePostHrcMove(refMakerAttr, refMakerAttrIndex);
449 _ToLua.onTargetInstancePostHrcMove(refMakerAttr, refMakerAttrIndex);
450 TEST_LUA_PROJ;
453 // *********************************************************************************************************
454 void CInstance::onTargetInstanceEraseRequested(const std::string &refMakerAttr,sint32 refMakerAttrIndex)
456 //H_AUTO(R2_CInstance_onTargetInstanceEraseRequested)
457 TEST_LUA_PROJ;
458 // forward to displayer for convenience & legacy code, but should not be handled by displayers ...
459 if (_DisplayerVisual) getDisplayerVisual()->onTargetInstanceEraseRequested(refMakerAttr, refMakerAttrIndex);
460 if (_DisplayerUI) _DisplayerUI->onTargetInstanceEraseRequested(refMakerAttr, refMakerAttrIndex);
461 if (_DisplayerProperties) _DisplayerProperties->onTargetInstanceEraseRequested(refMakerAttr, refMakerAttrIndex);
463 _ToLua.onTargetInstanceEraseRequested(refMakerAttr, refMakerAttrIndex);
464 TEST_LUA_PROJ;
467 // *********************************************************************************************************
468 void CInstance::onTargetInstanceAttrModified(const std::string &refMakerAttr, sint32 refMakerAttrIndex, const std::string &targetAttrName, sint32 targetAttrIndex)
470 //H_AUTO(R2_CInstance_onTargetInstanceAttrModified)
471 TEST_LUA_PROJ;
472 if (_DisplayerVisual) getDisplayerVisual()->onTargetInstanceAttrModified(refMakerAttr, refMakerAttrIndex, targetAttrName, targetAttrIndex);
473 if (_DisplayerUI) _DisplayerUI->onTargetInstanceAttrModified(refMakerAttr, refMakerAttrIndex, targetAttrName, targetAttrIndex);
474 if (_DisplayerProperties) _DisplayerProperties->onTargetInstanceAttrModified(refMakerAttr, refMakerAttrIndex, targetAttrName, targetAttrIndex);
475 _ToLua.onTargetInstanceAttrModified(refMakerAttr, refMakerAttrIndex, targetAttrName, targetAttrIndex);
476 TEST_LUA_PROJ;
479 // *********************************************************************************************************
480 void CInstance::onPreRender()
482 //H_AUTO(R2_CInstance_onPreRender)
483 TEST_LUA_PROJ;
484 if (_DisplayerVisual) getDisplayerVisual()->onPreRender();
485 TEST_LUA_PROJ;
488 // *********************************************************************************************************
489 void CInstance::onPostRender()
491 //H_AUTO(R2_CInstance_onPostRender)
492 TEST_LUA_PROJ;
493 if (_DisplayerVisual) getDisplayerVisual()->onPostRender();
494 TEST_LUA_PROJ;
497 // *********************************************************************************************************
498 CLuaObject &CInstance::getLuaProjection()
500 //H_AUTO(R2_CInstance_getLuaProjection)
501 TEST_LUA_PROJ;
502 nlassert(_ToLua._LuaProjection.isValid());
503 TEST_LUA_PROJ;
504 return _ToLua._LuaProjection;
507 // *********************************************************************************************************
508 std::string CInstance::getClassName() const
510 //H_AUTO(R2_CInstance_getClassName)
511 TEST_LUA_PROJ;
512 return getString(_ObjectTable, "Class");
515 // *********************************************************************************************************
516 CLuaObject &CInstance::getClass() const
518 //H_AUTO(R2_CInstance_getClass)
519 TEST_LUA_PROJ;
520 if (_ToLua._Class.isValid()) return _ToLua._Class;
521 _ToLua._Class = getEditor().getClasses()[getClassName()];
522 return _ToLua._Class;
525 // *********************************************************************************************************
526 TInstanceId CInstance::getId() const
528 //H_AUTO(R2_CInstance_getId)
529 TEST_LUA_PROJ;
530 if (!_Id.empty()) return _Id;
531 nlassert(_ObjectTable);
532 _Id = getString(_ObjectTable, "InstanceId");
533 return _Id;
537 // *********************************************************************************************************
538 CEntityCL *CInstance::getEntity() const
540 //H_AUTO(R2_CInstance_getEntity)
541 TEST_LUA_PROJ;
542 CDisplayerVisualEntity *dve = dynamic_cast<CDisplayerVisualEntity *>(getDisplayerVisual());
543 if (dve)
545 return dve->getEntity();
547 return NULL;
550 // *********************************************************************************************************
551 std::string CInstance::getSheet() const
553 CDisplayerVisualEntity *dve = dynamic_cast<CDisplayerVisualEntity *>(getDisplayerVisual());
554 if (dve)
556 return dve->getSheet();
558 return "";
561 // *********************************************************************************************************
562 CInstance *CInstance::getParent() const
564 //H_AUTO(R2_CInstance_getParent)
565 TEST_LUA_PROJ;
566 static volatile bool cacheTest = true;
567 if (cacheTest)
569 if (_LastParentOk)
571 return _LastParent;
574 CInstance *result = NULL;
575 CObject *currParent = _ObjectTable->getParent();
576 while (currParent)
578 CInstance *inst = getEditor().getInstanceFromObject(currParent);
579 if (inst)
581 result = inst;
582 break;
584 currParent = currParent->getParent();
586 _LastParentOk = true;
587 _LastParent = result;
588 return result;
591 // *********************************************************************************************************
592 bool CInstance::isSonOf(CInstance *other) const
594 //H_AUTO(R2_CInstance_isSonOf)
595 TEST_LUA_PROJ;
596 CInstance *curr =this->getParent();
597 while (curr)
599 if (curr == other) return true;
600 curr = curr->getParent();
602 return false;
605 // *********************************************************************************************************
606 bool CInstance::isKindOf(const std::string &className) const
608 //H_AUTO(R2_CInstance_isKindOf)
609 CEditor &ed = getEditor();
610 return ed.isKindOf(_ClassIndex, ed.classToIndex(className));
613 // *********************************************************************************************************
614 CInstance *CInstance::getParentAct() const
616 //H_AUTO(R2_CInstance_getParentAct)
617 TEST_LUA_PROJ;
618 CInstance *curr = getParent();
619 while (curr)
621 if (curr->isKindOf("Act")) return curr;
622 curr = curr->getParent();
624 return NULL;
627 // *********************************************************************************************************
628 void CInstance::CToLua::executeHandler(const CLuaString &name, int numArgs)
630 //H_AUTO(R2_CToLua_executeHandler)
631 CLuaState &ls = getEditor().getLua();
632 CLuaStackRestorer lsr(&ls, ls.getTop() - numArgs);
634 static volatile bool dumpStackWanted = false;
635 if (dumpStackWanted) ls.dumpStack();
636 _Class[ name.getStr().c_str() ].push();
637 if (ls.isNil(-1)) return; // not handled
638 if (dumpStackWanted) ls.dumpStack();
639 // put method before its args
640 ls.insert(- numArgs - 1);
641 if (dumpStackWanted) ls.dumpStack();
642 // Insert the 'this' as first parameter
643 _LuaProjection.push();
644 ls.insert(- numArgs - 1);
646 if (dumpStackWanted) ls.dumpStack();
647 CLuaIHMRyzom::executeFunctionOnStack(ls, numArgs + 1, 0);
648 if (dumpStackWanted) ls.dumpStack();
651 // *********************************************************************************************************
652 CLuaState *CInstance::CToLua::getLua()
654 //H_AUTO(R2_CToLua_getLua)
655 return _LuaProjection.getLuaState();
659 // *********************************************************************************************************
660 sint CInstance::getSelectedSequence() const
662 //H_AUTO(R2_CInstance_getSelectedSequence)
663 CLuaObject selected = const_cast<CInstance *>(this)->getLuaProjection()["User"]["SelectedSequence"];
664 sint index = 0;
665 if (selected.isInteger())
667 index = (sint) selected.toInteger();
669 return index;
673 ////////////////
674 // PROPERTIES //
675 ////////////////
677 // *********************************************************************************************************
678 void CInstance::setSelectable(bool selectable)
680 //H_AUTO(R2_CInstance_setSelectable)
681 TEST_LUA_PROJ;
682 if (selectable == _Selectable) return;
683 _Selectable = selectable;
684 CInstance *selInstance = getEditor().getSelectedInstance();
685 if (selInstance)
687 if (selInstance && (selInstance == this || selInstance->isSonOf(this)))
689 getEditor().setSelectedInstance(NULL);
692 onAttrModified("Selectable");
695 // *********************************************************************************************************
696 bool CInstance::getSelectableFromRoot() const
698 //H_AUTO(R2_CInstance_getSelectableFromRoot)
699 TEST_LUA_PROJ;
700 const CInstance *curr = this;
703 if (!curr->getSelectable()) return false;
704 curr = curr->getParent();
706 while (curr);
707 return true;
710 // *********************************************************************************************************
711 void CInstance::dummySetSelectableFromRoot(bool /* selectable */)
713 //H_AUTO(R2_CInstance_dummySetSelectableFromRoot)
714 nlwarning("SelectableFromRoot is a R/O property");
717 // *********************************************************************************************************
718 bool CInstance::getGhost() const
720 //H_AUTO(R2_CInstance_getGhost)
721 TEST_LUA_PROJ;
722 if (_ObjectTable) return getObjectTable()->getGhost();
723 return false;
725 // *********************************************************************************************************
726 void CInstance::setGhost(bool ghost)
728 //H_AUTO(R2_CInstance_setGhost)
729 TEST_LUA_PROJ;
730 if (_ObjectTable) getObjectTable()->setGhost(ghost);
733 // *********************************************************************************************************
734 CInstance *CInstance::getParentGroup()
736 //H_AUTO(R2_CInstance_getParentGroup)
737 if (isKindOf("NpcGrpFeature")) return this;
738 if (getParent() && getParent()->isKindOf("NpcGrpFeature"))
740 return getParent();
742 return this;
745 // *********************************************************************************************************
746 const CInstance *CInstance::getParentGroupLeader() const
748 //H_AUTO(R2_CInstance_getParentGroupLeader)
749 const CObjectTable *props = NULL;
750 if (isKindOf("NpcGrpFeature"))
752 props = getObjectTable();
754 else if (getParent() && getParent()->isKindOf("NpcGrpFeature"))
756 props = getParent()->getObjectTable();
758 else
760 return this;
762 if (!props) return NULL;
763 // this is a group
764 const CObject *components = props->findAttr("Components");
765 if (!components || components->getSize() == 0)
767 return NULL;
769 return getEditor().getInstanceFromObject(components->getValueAtPos(0));
772 // *********************************************************************************************************
773 CObject *CInstance::getGroupSelectedSequence() const
775 //H_AUTO(R2_CInstance_getGroupSelectedSequence)
776 const CInstance *leader = getParentGroupLeader();
777 if (leader)
779 sint selectedSequence = leader->getSelectedSequence();
780 const CObject *behav = leader->getObjectTable();
781 if (behav)
783 behav = behav->findAttr("Behavior");
784 if (behav)
786 const CObject *activities = behav->findAttr("Activities");
787 if (activities)
789 if (selectedSequence >= 0 && selectedSequence < (sint) activities->getSize())
791 return activities->getValueAtPos((sint32) selectedSequence);
797 return NULL;
801 // *********************************************************************************************************
802 bool CInstance::maxVisibleEntityExceeded() const
804 if (!_DisplayerVisual) return false;
805 return _DisplayerVisual->maxVisibleEntityExceeded();
808 // *********************************************************************************************************
809 std::string CInstance::getPosInstanceId() const
811 //H_AUTO(R2_CInstance_getPosInstanceId)
812 CObject *posObj = getObjectTable()->getAttr("Position");
813 if (!posObj)
815 nlwarning("<CInstance::getPosInstanceId> can't retrieve position from object");
816 return "";
818 return posObj->toString("InstanceId");
822 /////////////////////
823 // ACTION HANDLERS //
824 /////////////////////
826 // *********************************************************************************************************
827 // Select an instance from its id
828 class CAHSelectInstance : public IActionHandler
830 virtual void execute(CCtrlBase * /* pCaller */, const std::string &sParams)
832 // retrieve instance from its Id
833 CInstance *instance = getEditor().getInstanceFromId(sParams);
834 if(instance != NULL)
836 getEditor().setSelectedInstance(instance);
840 REGISTER_ACTION_HANDLER(CAHSelectInstance, "r2ed_select_instance");
843 // *********************************************************************************************************
844 // Delete selected instance
845 class CAHDeleteSelectedInstance : public IActionHandler
847 virtual void execute(CCtrlBase * /* pCaller */, const std::string &/* sParams */)
849 CInstance *selectedInstance = getEditor().getSelectedInstance();
850 if (selectedInstance)
852 getEditor().getDMC().requestEraseNode(selectedInstance->getId(), "", -1);
856 REGISTER_ACTION_HANDLER(CAHDeleteSelectedInstance, "r2ed_delete_selected_instance");
858 // *********************************************************************************************************
859 // handler to pick an instance
860 class CAHPickerLua : public IActionHandler
862 // TODO nico : replace this action handler by a CTool (in the same way that CToolChoosePosLua derives from CToolChoosePos)
863 virtual void execute(CCtrlBase * /* pCaller */, const std::string &sParams)
865 // TODO : put this class in a separate file
866 class CToolPickLua : public CToolPick
868 public:
869 CToolPickLua() {}
870 CToolPickLua(const std::string &cursCanPickInstance,
871 const std::string &cursCannotPickInstance,
872 const std::string &cursCanPickPos,
873 const std::string &cursCannotPickPos,
874 bool wantMouseUp
875 ) : CToolPick(cursCanPickInstance,
876 cursCannotPickInstance,
877 cursCanPickPos,
878 cursCannotPickPos,
879 wantMouseUp
883 NLMISC_DECLARE_CLASS(CToolPickLua);
884 void pick(CInstance &instance)
886 CTool::TSmartPtr holdThis(this); // prevent 'setCurrentTool' from deleting 'this'
887 getEditor().setCurrentTool(NULL);
888 if (!LuaPickFunc.empty())
890 getEditor().getLua().executeScriptNoThrow(LuaPickFunc + "('" + instance.getId() + "')");
893 void pick(const CVector &pos)
895 CTool::TSmartPtr holdThis(this); // prevent 'setCurrentTool' from deleting 'this'
896 getEditor().setCurrentTool(NULL);
897 if (!LuaPickPosFunc.empty())
899 getEditor().getLua().executeScriptNoThrow(NLMISC::toString("%s(%f, %f, %f)", LuaPickPosFunc.c_str(), pos.x, pos.y, pos.z));
902 bool canPick(const CInstance &instance) const
904 if (LuaPickFunc.empty()) return true;
905 CLuaState &lua = getEditor().getLua();
906 int initialSize = lua.getTop();
907 std::string script = "return " + LuaTestFunc + "('" + instance.getId() + "')";
908 if (lua.executeScriptNoThrow(script, 1))
910 bool result = lua.toBoolean(initialSize + 1);
911 lua.setTop(initialSize);
912 return result;
914 lua.setTop(initialSize);
915 return false;
918 std::string LuaTestFunc;
919 std::string LuaPickFunc;
920 std::string LuaPickPosFunc;
922 std::string cursCanPickInstance = getParam(sParams, "CursCanPickInstance");
923 std::string cursCannotPickInstance = getParam(sParams, "CursCannotPickInstance");
924 std::string cursCanPickPos = getParam(sParams, "CursCanPickPos");
925 std::string cursCannotPickPos = getParam(sParams, "CursCannotPickPos");
926 std::string wantMouseUp = getParam(sParams, "WantMouseUp");
927 std::string ignoreInstances = getParam(sParams, "IgnoreInstances");
929 if (cursCanPickInstance.empty()) cursCanPickInstance = "r2ed_tool_can_pick.tga";
930 if (cursCannotPickInstance.empty()) cursCannotPickInstance = "curs_stop.tga";
931 if (cursCanPickPos.empty()) cursCanPickPos = "r2ed_tool_pick.tga";
932 if (cursCannotPickPos.empty()) cursCannotPickPos = "r2ed_tool_pick.tga";
934 CToolPickLua *picker = new CToolPickLua(cursCanPickInstance, cursCannotPickInstance, cursCanPickPos, cursCannotPickPos, wantMouseUp == "true");
935 picker->LuaTestFunc = getParam(sParams, "TestFunc");
936 picker->LuaPickFunc = getParam(sParams, "PickFunc");
937 picker->LuaPickPosFunc = getParam(sParams, "PickPosFunc");
938 picker->setIgnoreInstances(ignoreInstances);
939 getEditor().setCurrentTool(picker);
942 REGISTER_ACTION_HANDLER(CAHPickerLua, "r2ed_picker_lua");
944 // *********************************************************************************************************
945 // rotate
946 class CAHRotateInstance : public IActionHandler
948 virtual void execute(CCtrlBase * /* pCaller */, const std::string &/* sParams */)
950 getEditor().setCurrentTool(new CToolSelectRotate);
953 REGISTER_ACTION_HANDLER(CAHRotateInstance, "r2ed_rotate");
955 // *********************************************************************************************************
956 // move
957 class CAHMoveInstance : public IActionHandler
959 virtual void execute(CCtrlBase * /* pCaller */, const std::string &/* sParams */)
961 getEditor().setCurrentTool(new CToolSelectMove);
964 REGISTER_ACTION_HANDLER(CAHMoveInstance, "r2ed_move");
968 // *********************************************************************************************************
969 // Debug : dump the lua table for current instance
970 class CAHDumpLuaTable : public IActionHandler
972 virtual void execute(CCtrlBase * /* pCaller */, const std::string &sParams)
974 if (!getEditor().getSelectedInstance()) return;
975 std::string maxDepthStr = getParam(sParams, "depth");
976 uint maxDepth;
977 if (maxDepthStr.empty())
978 maxDepth = 20;
979 else
980 fromString(maxDepthStr, maxDepth);
981 // don't want to display the parent
982 std::set<const void *> negativeFilter;
983 if (getEditor().getSelectedInstance()->getParent())
985 negativeFilter.insert(getEditor().getSelectedInstance()->getParent()->getLuaProjection().toPointer());
987 getEditor().getSelectedInstance()->getLuaProjection().dump(30, &negativeFilter);
990 REGISTER_ACTION_HANDLER(CAHDumpLuaTable, "r2ed_dump_lua_table");
995 } // R2