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) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
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/>.
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"
40 using namespace NLMISC
;
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());
66 static volatile bool debugMetatable
= false;
69 _ToLua
._LuaProjection
.push();
70 if (!ls
.getMetaTable())
73 nlwarning("No metatable found");
83 _LastParentOk
= false;
85 _RegisteredInDispNameList
= false;
86 _ClassIndex
= getEditor().classToIndex(getClassName());
89 nlwarning("Class index not found for '%s'", getClassName().c_str());
93 // *********************************************************************************************************
94 std::string
CInstance::getName() const
96 //H_AUTO(R2_CInstance_getName)
98 return getString(_ObjectTable
, "Name");
101 // *********************************************************************************************************
102 std::string
CInstance::getPaletteId()
104 //H_AUTO(R2_CInstance_getPaletteId)
106 return getString(_ObjectTable
, "Base");
109 // *********************************************************************************************************
110 ucstring
CInstance::getDisplayName()
112 //H_AUTO(R2_CInstance_getDisplayName)
114 CLuaState
&ls
= getEditor().getLua();
115 CLuaStackRestorer
lsr(&ls
, ls
.getTop());
116 if (getLuaProjection()["getDisplayName"].isNil())
118 // object is not displayed -> ignore name
121 if (getLuaProjection().callMethodByNameNoThrow("getDisplayName", 0, 1))
123 #ifdef RYZOM_LUA_UCSTRING
125 if (CLuaIHM::pop(ls
, result
)) return result
;
127 std::string res
= ls
.toString();
129 if (!res
.empty()) return res
;
133 return ucstring("Can't find display name");
136 // *********************************************************************************************************
137 void CInstance::visit(IInstanceVisitor
&visitor
)
139 //H_AUTO(R2_CInstance_visit)
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
);
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
162 // *********************************************************************************************************
163 void CInstance::setDisplayerVisual(CDisplayerVisual
*displayer
)
165 //H_AUTO(R2_CInstance_setDisplayerVisual)
167 if (_DisplayerVisual
)
169 setDisplayedInstance(_DisplayerVisual
, NULL
);
173 setDisplayedInstance(displayer
, this);
175 _DisplayerVisual
= displayer
;
179 // *********************************************************************************************************
180 CDisplayerVisual
*CInstance::getDisplayerVisual() const
182 //H_AUTO(R2_CInstance_getDisplayerVisual)
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)
196 setDisplayedInstance(_DisplayerUI
, NULL
);
200 setDisplayedInstance(displayer
, this);
202 _DisplayerUI
= displayer
;
205 // *********************************************************************************************************
206 void CInstance::setDisplayerProperties(CDisplayerBase
*displayer
)
208 //H_AUTO(R2_CInstance_setDisplayerProperties)
210 if (_DisplayerProperties
)
212 setDisplayedInstance(_DisplayerProperties
, NULL
);
216 setDisplayedInstance(displayer
, this);
218 _DisplayerProperties
= displayer
;
221 // *********************************************************************************************************
222 CInstance::~CInstance()
225 setDisplayerVisual(NULL
);
226 setDisplayerUI(NULL
);
227 setDisplayerProperties(NULL
);
232 // *********************************************************************************************************
233 void CInstance::onPreActChanged()
235 //H_AUTO(R2_CInstance_onPreActChanged)
237 if (_DisplayerVisual
) getDisplayerVisual()->onPreActChanged();
238 if (_DisplayerUI
) _DisplayerUI
->onPreActChanged();
239 if (_DisplayerProperties
) _DisplayerProperties
->onPreActChanged();
240 _ToLua
.onActChanged();
244 // *********************************************************************************************************
245 void CInstance::onActChanged()
247 //H_AUTO(R2_CInstance_onActChanged)
249 if (_DisplayerVisual
) getDisplayerVisual()->onActChanged();
250 if (_DisplayerUI
) _DisplayerUI
->onActChanged();
251 if (_DisplayerProperties
) _DisplayerProperties
->onActChanged();
252 _ToLua
.onActChanged();
254 refreshDisplayNameHandle();
257 // *********************************************************************************************************
258 void CInstance::onContinentChanged()
260 //H_AUTO(R2_CInstance_onContinentChanged)
262 if (_DisplayerVisual
) getDisplayerVisual()->onContinentChanged();
263 if (_DisplayerUI
) _DisplayerUI
->onContinentChanged();
264 if (_DisplayerProperties
) _DisplayerProperties
->onContinentChanged();
265 _ToLua
.onContinentChanged();
270 // *********************************************************************************************************
271 void CInstance::onCreate()
273 //H_AUTO(R2_CInstance_onCreate)
275 if (_DisplayerVisual
) getDisplayerVisual()->onCreate();
276 if (_DisplayerUI
) _DisplayerUI
->onCreate();
277 if (_DisplayerProperties
) _DisplayerProperties
->onCreate();
282 // *********************************************************************************************************
283 void CInstance::onPostCreate()
285 //H_AUTO(R2_CInstance_onPostCreate)
287 _LastParentOk
= false;
288 if (_DisplayerVisual
) getDisplayerVisual()->onPostCreate();
289 if (_DisplayerUI
) _DisplayerUI
->onPostCreate();
290 if (_DisplayerProperties
) _DisplayerProperties
->onPostCreate();
291 _ToLua
.onPostCreate();
293 nlassert(!_RegisteredInDispNameList
);
294 getEditor().registerInstanceDispName(getDisplayName(), this);
295 _RegisteredInDispNameList
= true;
298 // *********************************************************************************************************
299 void CInstance::onErase()
301 //H_AUTO(R2_CInstance_onErase)
303 if (_DisplayerVisual
) getDisplayerVisual()->onErase();
304 if (_DisplayerUI
) _DisplayerUI
->onErase();
305 if (_DisplayerProperties
) _DisplayerProperties
->onErase();
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)
330 if (_DisplayerVisual
) getDisplayerVisual()->onPreHrcMove();
331 if (_DisplayerUI
) _DisplayerUI
->onPreHrcMove();
332 if (_DisplayerProperties
) _DisplayerProperties
->onPreHrcMove();
333 _ToLua
.onPreHrcMove();
337 // *********************************************************************************************************
338 void CInstance::onPostHrcMove()
340 //H_AUTO(R2_CInstance_onPostHrcMove)
342 _LastParentOk
= false;
343 if (_DisplayerVisual
) getDisplayerVisual()->onPostHrcMove();
344 if (_DisplayerUI
) _DisplayerUI
->onPostHrcMove();
345 if (_DisplayerProperties
) _DisplayerProperties
->onPostHrcMove();
346 _ToLua
.onPostHrcMove();
348 refreshDisplayNameHandle();
352 // *********************************************************************************************************
353 void CInstance::onFocus(bool highlighted
)
355 //H_AUTO(R2_CInstance_onFocus)
357 if (_DisplayerVisual
) getDisplayerVisual()->onFocus(highlighted
);
358 if (_DisplayerUI
) _DisplayerUI
->onFocus(highlighted
);
359 if (_DisplayerProperties
) _DisplayerProperties
->onFocus(highlighted
);
360 _ToLua
.onFocus(highlighted
);
364 // *********************************************************************************************************
365 void CInstance::onSelect(bool selected
)
367 //H_AUTO(R2_CInstance_onSelect)
369 if (_DisplayerVisual
) getDisplayerVisual()->onSelect(selected
);
370 if (_DisplayerUI
) _DisplayerUI
->onSelect(selected
);
371 if (_DisplayerProperties
) _DisplayerProperties
->onSelect(selected
);
372 _ToLua
.onSelect(selected
);
376 // *********************************************************************************************************
377 void CInstance::onAttrModified(const std::string
&attrName
, sint32 attrIndex
)
379 //H_AUTO(R2_CInstance_onAttrModified)
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
);
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)
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
);
417 // *********************************************************************************************************
418 void CInstance::onTargetInstanceErased(const std::string
&refMakerAttr
, sint32 refMakerAttrIndex
)
420 //H_AUTO(R2_CInstance_onTargetInstanceErased)
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
);
429 // *********************************************************************************************************
430 void CInstance::onTargetInstancePreHrcMove(const std::string
&refMakerAttr
,sint32 refMakerAttrIndex
)
432 //H_AUTO(R2_CInstance_onTargetInstancePreHrcMove)
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
);
441 // *********************************************************************************************************
442 void CInstance::onTargetInstancePostHrcMove(const std::string
&refMakerAttr
,sint32 refMakerAttrIndex
)
444 //H_AUTO(R2_CInstance_onTargetInstancePostHrcMove)
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
);
453 // *********************************************************************************************************
454 void CInstance::onTargetInstanceEraseRequested(const std::string
&refMakerAttr
,sint32 refMakerAttrIndex
)
456 //H_AUTO(R2_CInstance_onTargetInstanceEraseRequested)
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
);
467 // *********************************************************************************************************
468 void CInstance::onTargetInstanceAttrModified(const std::string
&refMakerAttr
, sint32 refMakerAttrIndex
, const std::string
&targetAttrName
, sint32 targetAttrIndex
)
470 //H_AUTO(R2_CInstance_onTargetInstanceAttrModified)
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
);
479 // *********************************************************************************************************
480 void CInstance::onPreRender()
482 //H_AUTO(R2_CInstance_onPreRender)
484 if (_DisplayerVisual
) getDisplayerVisual()->onPreRender();
488 // *********************************************************************************************************
489 void CInstance::onPostRender()
491 //H_AUTO(R2_CInstance_onPostRender)
493 if (_DisplayerVisual
) getDisplayerVisual()->onPostRender();
497 // *********************************************************************************************************
498 CLuaObject
&CInstance::getLuaProjection()
500 //H_AUTO(R2_CInstance_getLuaProjection)
502 nlassert(_ToLua
._LuaProjection
.isValid());
504 return _ToLua
._LuaProjection
;
507 // *********************************************************************************************************
508 std::string
CInstance::getClassName() const
510 //H_AUTO(R2_CInstance_getClassName)
512 return getString(_ObjectTable
, "Class");
515 // *********************************************************************************************************
516 CLuaObject
&CInstance::getClass() const
518 //H_AUTO(R2_CInstance_getClass)
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)
530 if (!_Id
.empty()) return _Id
;
531 nlassert(_ObjectTable
);
532 _Id
= getString(_ObjectTable
, "InstanceId");
537 // *********************************************************************************************************
538 CEntityCL
*CInstance::getEntity() const
540 //H_AUTO(R2_CInstance_getEntity)
542 CDisplayerVisualEntity
*dve
= dynamic_cast<CDisplayerVisualEntity
*>(getDisplayerVisual());
545 return dve
->getEntity();
550 // *********************************************************************************************************
551 std::string
CInstance::getSheet() const
553 CDisplayerVisualEntity
*dve
= dynamic_cast<CDisplayerVisualEntity
*>(getDisplayerVisual());
556 return dve
->getSheet();
561 // *********************************************************************************************************
562 CInstance
*CInstance::getParent() const
564 //H_AUTO(R2_CInstance_getParent)
566 static volatile bool cacheTest
= true;
574 CInstance
*result
= NULL
;
575 CObject
*currParent
= _ObjectTable
->getParent();
578 CInstance
*inst
= getEditor().getInstanceFromObject(currParent
);
584 currParent
= currParent
->getParent();
586 _LastParentOk
= true;
587 _LastParent
= result
;
591 // *********************************************************************************************************
592 bool CInstance::isSonOf(CInstance
*other
) const
594 //H_AUTO(R2_CInstance_isSonOf)
596 CInstance
*curr
=this->getParent();
599 if (curr
== other
) return true;
600 curr
= curr
->getParent();
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)
618 CInstance
*curr
= getParent();
621 if (curr
->isKindOf("Act")) return curr
;
622 curr
= curr
->getParent();
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"];
665 if (selected
.isInteger())
667 index
= (sint
) selected
.toInteger();
677 // *********************************************************************************************************
678 void CInstance::setSelectable(bool selectable
)
680 //H_AUTO(R2_CInstance_setSelectable)
682 if (selectable
== _Selectable
) return;
683 _Selectable
= selectable
;
684 CInstance
*selInstance
= getEditor().getSelectedInstance();
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)
700 const CInstance
*curr
= this;
703 if (!curr
->getSelectable()) return false;
704 curr
= curr
->getParent();
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)
722 if (_ObjectTable
) return getObjectTable()->getGhost();
725 // *********************************************************************************************************
726 void CInstance::setGhost(bool ghost
)
728 //H_AUTO(R2_CInstance_setGhost)
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"))
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();
762 if (!props
) return NULL
;
764 const CObject
*components
= props
->findAttr("Components");
765 if (!components
|| components
->getSize() == 0)
769 return getEditor().getInstanceFromObject(components
->getValueAtPos(0));
772 // *********************************************************************************************************
773 CObject
*CInstance::getGroupSelectedSequence() const
775 //H_AUTO(R2_CInstance_getGroupSelectedSequence)
776 const CInstance
*leader
= getParentGroupLeader();
779 sint selectedSequence
= leader
->getSelectedSequence();
780 const CObject
*behav
= leader
->getObjectTable();
783 behav
= behav
->findAttr("Behavior");
786 const CObject
*activities
= behav
->findAttr("Activities");
789 if (selectedSequence
>= 0 && selectedSequence
< (sint
) activities
->getSize())
791 return activities
->getValueAtPos((sint32
) selectedSequence
);
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");
815 nlwarning("<CInstance::getPosInstanceId> can't retrieve position from object");
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
);
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
870 CToolPickLua(const std::string
&cursCanPickInstance
,
871 const std::string
&cursCannotPickInstance
,
872 const std::string
&cursCanPickPos
,
873 const std::string
&cursCannotPickPos
,
875 ) : CToolPick(cursCanPickInstance
,
876 cursCannotPickInstance
,
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
);
914 lua
.setTop(initialSize
);
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 // *********************************************************************************************************
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 // *********************************************************************************************************
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");
977 if (maxDepthStr
.empty())
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");