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>
6 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "tool_pick.h"
27 #include "tool_select_rotate.h"
28 #include "tool_select_move.h"
30 #include "../entities.h"
31 #include "../interface_v3/interface_manager.h"
32 #include "nel/gui/lua_ihm.h"
33 #include "../interface_v3/lua_ihm_ryzom.h"
35 #include "displayer_visual_entity.h"
41 using namespace NLMISC
;
49 //#define TEST_LUA_PROJ nlassert(_ToLua._LuaProjection.isUserData());
51 // *********************************************************************************************************
52 /*static*/ void setDisplayedInstance(CDisplayerBase
*displayer
, CInstance
*displayedInstance
)
54 displayer
->setDisplayedInstance(displayedInstance
);
57 // *********************************************************************************************************
58 CInstance::CInstance(const CObjectTable
*objectTable
, CLuaState
&ls
)
60 CLuaStackChecker
lsc(&ls
);
61 nlassert(objectTable
);
62 _ObjectTable
= objectTable
;
63 // create projection in lua
64 getEditor().projectInLua(objectTable
);
65 _ToLua
._LuaProjection
.pop(getEditor().getLua());
67 static volatile bool debugMetatable
= false;
70 _ToLua
._LuaProjection
.push();
71 if (!ls
.getMetaTable())
74 nlwarning("No metatable found");
84 _LastParentOk
= false;
86 _RegisteredInDispNameList
= false;
87 _ClassIndex
= getEditor().classToIndex(getClassName());
90 nlwarning("Class index not found for '%s'", getClassName().c_str());
94 // *********************************************************************************************************
95 std::string
CInstance::getName() const
97 //H_AUTO(R2_CInstance_getName)
99 return getString(_ObjectTable
, "Name");
102 // *********************************************************************************************************
103 std::string
CInstance::getPaletteId()
105 //H_AUTO(R2_CInstance_getPaletteId)
107 return getString(_ObjectTable
, "Base");
110 // *********************************************************************************************************
111 ucstring
CInstance::getDisplayName()
113 //H_AUTO(R2_CInstance_getDisplayName)
115 CLuaState
&ls
= getEditor().getLua();
116 CLuaStackRestorer
lsr(&ls
, ls
.getTop());
117 if (getLuaProjection()["getDisplayName"].isNil())
119 // object is not displayed -> ignore name
122 if (getLuaProjection().callMethodByNameNoThrow("getDisplayName", 0, 1))
124 #ifdef RYZOM_LUA_UCSTRING
126 if (CLuaIHM::pop(ls
, result
)) return result
;
128 std::string res
= ls
.toString();
130 if (!res
.empty()) return res
;
134 return ucstring("Can't find display name");
137 // *********************************************************************************************************
138 void CInstance::visit(IInstanceVisitor
&visitor
)
140 //H_AUTO(R2_CInstance_visit)
142 nlassert(_ObjectTable
);
143 // forward object vistor call to 'instance' visitor call
144 struct CInstanceVisitor
: public IObjectVisitor
146 IInstanceVisitor
*Visitor
;
147 virtual void visit(CObjectTable
&obj
)
149 CInstance
*inst
= getEditor().getInstanceFromObject(&obj
);
152 Visitor
->visit(*inst
);
156 CInstanceVisitor instanceVisitor
;
157 instanceVisitor
.Visitor
= &visitor
;
158 const_cast<CObjectTable
*>(_ObjectTable
)->visit(instanceVisitor
); // 'const' is respected here, because CInstanceVisitor gives a reference to CInstance
159 // which in turn only allow a const reference on CObjectTable
163 // *********************************************************************************************************
164 void CInstance::setDisplayerVisual(CDisplayerVisual
*displayer
)
166 //H_AUTO(R2_CInstance_setDisplayerVisual)
168 if (_DisplayerVisual
)
170 setDisplayedInstance(_DisplayerVisual
, NULL
);
174 setDisplayedInstance(displayer
, this);
176 _DisplayerVisual
= displayer
;
180 // *********************************************************************************************************
181 CDisplayerVisual
*CInstance::getDisplayerVisual() const
183 //H_AUTO(R2_CInstance_getDisplayerVisual)
185 if (!_DisplayerVisual
) return NULL
;
186 return NLMISC::safe_cast
<CDisplayerVisual
*>((CDisplayerBase
*)_DisplayerVisual
);
190 // *********************************************************************************************************
191 void CInstance::setDisplayerUI(CDisplayerBase
*displayer
)
193 //H_AUTO(R2_CInstance_setDisplayerUI)
197 setDisplayedInstance(_DisplayerUI
, NULL
);
201 setDisplayedInstance(displayer
, this);
203 _DisplayerUI
= displayer
;
206 // *********************************************************************************************************
207 void CInstance::setDisplayerProperties(CDisplayerBase
*displayer
)
209 //H_AUTO(R2_CInstance_setDisplayerProperties)
211 if (_DisplayerProperties
)
213 setDisplayedInstance(_DisplayerProperties
, NULL
);
217 setDisplayedInstance(displayer
, this);
219 _DisplayerProperties
= displayer
;
222 // *********************************************************************************************************
223 CInstance::~CInstance()
226 setDisplayerVisual(NULL
);
227 setDisplayerUI(NULL
);
228 setDisplayerProperties(NULL
);
233 // *********************************************************************************************************
234 void CInstance::onPreActChanged()
236 //H_AUTO(R2_CInstance_onPreActChanged)
238 if (_DisplayerVisual
) getDisplayerVisual()->onPreActChanged();
239 if (_DisplayerUI
) _DisplayerUI
->onPreActChanged();
240 if (_DisplayerProperties
) _DisplayerProperties
->onPreActChanged();
241 _ToLua
.onActChanged();
245 // *********************************************************************************************************
246 void CInstance::onActChanged()
248 //H_AUTO(R2_CInstance_onActChanged)
250 if (_DisplayerVisual
) getDisplayerVisual()->onActChanged();
251 if (_DisplayerUI
) _DisplayerUI
->onActChanged();
252 if (_DisplayerProperties
) _DisplayerProperties
->onActChanged();
253 _ToLua
.onActChanged();
255 refreshDisplayNameHandle();
258 // *********************************************************************************************************
259 void CInstance::onContinentChanged()
261 //H_AUTO(R2_CInstance_onContinentChanged)
263 if (_DisplayerVisual
) getDisplayerVisual()->onContinentChanged();
264 if (_DisplayerUI
) _DisplayerUI
->onContinentChanged();
265 if (_DisplayerProperties
) _DisplayerProperties
->onContinentChanged();
266 _ToLua
.onContinentChanged();
271 // *********************************************************************************************************
272 void CInstance::onCreate()
274 //H_AUTO(R2_CInstance_onCreate)
276 if (_DisplayerVisual
) getDisplayerVisual()->onCreate();
277 if (_DisplayerUI
) _DisplayerUI
->onCreate();
278 if (_DisplayerProperties
) _DisplayerProperties
->onCreate();
283 // *********************************************************************************************************
284 void CInstance::onPostCreate()
286 //H_AUTO(R2_CInstance_onPostCreate)
288 _LastParentOk
= false;
289 if (_DisplayerVisual
) getDisplayerVisual()->onPostCreate();
290 if (_DisplayerUI
) _DisplayerUI
->onPostCreate();
291 if (_DisplayerProperties
) _DisplayerProperties
->onPostCreate();
292 _ToLua
.onPostCreate();
294 nlassert(!_RegisteredInDispNameList
);
295 getEditor().registerInstanceDispName(getDisplayName(), this);
296 _RegisteredInDispNameList
= true;
299 // *********************************************************************************************************
300 void CInstance::onErase()
302 //H_AUTO(R2_CInstance_onErase)
304 if (_DisplayerVisual
) getDisplayerVisual()->onErase();
305 if (_DisplayerUI
) _DisplayerUI
->onErase();
306 if (_DisplayerProperties
) _DisplayerProperties
->onErase();
309 if (_RegisteredInDispNameList
)
311 getEditor().unregisterInstanceDispName(this);
312 _RegisteredInDispNameList
= false;
316 // *********************************************************************************************************
317 void CInstance::refreshDisplayNameHandle()
319 if (_RegisteredInDispNameList
)
321 getEditor().unregisterInstanceDispName(this);
322 getEditor().registerInstanceDispName(getDisplayName(), this);
326 // *********************************************************************************************************
327 void CInstance::onPreHrcMove()
329 //H_AUTO(R2_CInstance_onPreHrcMove)
331 if (_DisplayerVisual
) getDisplayerVisual()->onPreHrcMove();
332 if (_DisplayerUI
) _DisplayerUI
->onPreHrcMove();
333 if (_DisplayerProperties
) _DisplayerProperties
->onPreHrcMove();
334 _ToLua
.onPreHrcMove();
338 // *********************************************************************************************************
339 void CInstance::onPostHrcMove()
341 //H_AUTO(R2_CInstance_onPostHrcMove)
343 _LastParentOk
= false;
344 if (_DisplayerVisual
) getDisplayerVisual()->onPostHrcMove();
345 if (_DisplayerUI
) _DisplayerUI
->onPostHrcMove();
346 if (_DisplayerProperties
) _DisplayerProperties
->onPostHrcMove();
347 _ToLua
.onPostHrcMove();
349 refreshDisplayNameHandle();
353 // *********************************************************************************************************
354 void CInstance::onFocus(bool highlighted
)
356 //H_AUTO(R2_CInstance_onFocus)
358 if (_DisplayerVisual
) getDisplayerVisual()->onFocus(highlighted
);
359 if (_DisplayerUI
) _DisplayerUI
->onFocus(highlighted
);
360 if (_DisplayerProperties
) _DisplayerProperties
->onFocus(highlighted
);
361 _ToLua
.onFocus(highlighted
);
365 // *********************************************************************************************************
366 void CInstance::onSelect(bool selected
)
368 //H_AUTO(R2_CInstance_onSelect)
370 if (_DisplayerVisual
) getDisplayerVisual()->onSelect(selected
);
371 if (_DisplayerUI
) _DisplayerUI
->onSelect(selected
);
372 if (_DisplayerProperties
) _DisplayerProperties
->onSelect(selected
);
373 _ToLua
.onSelect(selected
);
377 // *********************************************************************************************************
378 void CInstance::onAttrModified(const std::string
&attrName
, sint32 attrIndex
)
380 //H_AUTO(R2_CInstance_onAttrModified)
382 if (attrName
== "InstanceId")
384 nlwarning("InstanceId modification not allowed !! Please create a new object with a new id");
385 _Id
.clear(); // nevertheless invalidate the cache
387 if (_DisplayerVisual
) getDisplayerVisual()->onAttrModified(attrName
, attrIndex
);
388 if (_DisplayerUI
) _DisplayerUI
->onAttrModified(attrName
, attrIndex
);
389 if (_DisplayerProperties
) _DisplayerProperties
->onAttrModified(attrName
, attrIndex
);
390 _ToLua
.onAttrModified(attrName
, attrIndex
);
392 if (attrName
== "Name" || attrName
== "Title")
394 refreshDisplayNameHandle();
398 // *********************************************************************************************************
399 /*void CInstance::onTableModified(const std::string &tableName, const std::string &keyInTable, sint32 indexInTable)
401 if (_DisplayerVisual) getDisplayerVisual()->onTableModified(tableName, keyInTable, indexInTable);
402 if (_DisplayerUI) _DisplayerUI->onTableModified(tableName, keyInTable, indexInTable);
403 if (_DisplayerProperties) _DisplayerProperties->onTableModified(tableName, keyInTable, indexInTable);
406 // *********************************************************************************************************
407 void CInstance::onTargetInstanceCreated(const std::string
&refMakerAttr
, sint32 refMakerAttrIndex
)
409 //H_AUTO(R2_CInstance_onTargetInstanceCreated)
411 if (_DisplayerVisual
) getDisplayerVisual()->onTargetInstanceCreated(refMakerAttr
, refMakerAttrIndex
);
412 if (_DisplayerUI
) _DisplayerUI
->onTargetInstanceCreated(refMakerAttr
, refMakerAttrIndex
);
413 if (_DisplayerProperties
) _DisplayerProperties
->onTargetInstanceCreated(refMakerAttr
, refMakerAttrIndex
);
414 _ToLua
.onTargetInstanceCreated(refMakerAttr
, refMakerAttrIndex
);
418 // *********************************************************************************************************
419 void CInstance::onTargetInstanceErased(const std::string
&refMakerAttr
, sint32 refMakerAttrIndex
)
421 //H_AUTO(R2_CInstance_onTargetInstanceErased)
423 if (_DisplayerVisual
) getDisplayerVisual()->onTargetInstanceErased(refMakerAttr
, refMakerAttrIndex
);
424 if (_DisplayerUI
) _DisplayerUI
->onTargetInstanceErased(refMakerAttr
, refMakerAttrIndex
);
425 if (_DisplayerProperties
) _DisplayerProperties
->onTargetInstanceErased(refMakerAttr
, refMakerAttrIndex
);
426 _ToLua
.onTargetInstanceErased(refMakerAttr
, refMakerAttrIndex
);
430 // *********************************************************************************************************
431 void CInstance::onTargetInstancePreHrcMove(const std::string
&refMakerAttr
,sint32 refMakerAttrIndex
)
433 //H_AUTO(R2_CInstance_onTargetInstancePreHrcMove)
435 if (_DisplayerVisual
) getDisplayerVisual()->onTargetInstancePreHrcMove(refMakerAttr
, refMakerAttrIndex
);
436 if (_DisplayerUI
) _DisplayerUI
->onTargetInstancePreHrcMove(refMakerAttr
, refMakerAttrIndex
);
437 if (_DisplayerProperties
) _DisplayerProperties
->onTargetInstancePreHrcMove(refMakerAttr
, refMakerAttrIndex
);
438 _ToLua
.onTargetInstancePreHrcMove(refMakerAttr
, refMakerAttrIndex
);
442 // *********************************************************************************************************
443 void CInstance::onTargetInstancePostHrcMove(const std::string
&refMakerAttr
,sint32 refMakerAttrIndex
)
445 //H_AUTO(R2_CInstance_onTargetInstancePostHrcMove)
447 if (_DisplayerVisual
) getDisplayerVisual()->onTargetInstancePostHrcMove(refMakerAttr
, refMakerAttrIndex
);
448 if (_DisplayerUI
) _DisplayerUI
->onTargetInstancePostHrcMove(refMakerAttr
, refMakerAttrIndex
);
449 if (_DisplayerProperties
) _DisplayerProperties
->onTargetInstancePostHrcMove(refMakerAttr
, refMakerAttrIndex
);
450 _ToLua
.onTargetInstancePostHrcMove(refMakerAttr
, refMakerAttrIndex
);
454 // *********************************************************************************************************
455 void CInstance::onTargetInstanceEraseRequested(const std::string
&refMakerAttr
,sint32 refMakerAttrIndex
)
457 //H_AUTO(R2_CInstance_onTargetInstanceEraseRequested)
459 // forward to displayer for convenience & legacy code, but should not be handled by displayers ...
460 if (_DisplayerVisual
) getDisplayerVisual()->onTargetInstanceEraseRequested(refMakerAttr
, refMakerAttrIndex
);
461 if (_DisplayerUI
) _DisplayerUI
->onTargetInstanceEraseRequested(refMakerAttr
, refMakerAttrIndex
);
462 if (_DisplayerProperties
) _DisplayerProperties
->onTargetInstanceEraseRequested(refMakerAttr
, refMakerAttrIndex
);
464 _ToLua
.onTargetInstanceEraseRequested(refMakerAttr
, refMakerAttrIndex
);
468 // *********************************************************************************************************
469 void CInstance::onTargetInstanceAttrModified(const std::string
&refMakerAttr
, sint32 refMakerAttrIndex
, const std::string
&targetAttrName
, sint32 targetAttrIndex
)
471 //H_AUTO(R2_CInstance_onTargetInstanceAttrModified)
473 if (_DisplayerVisual
) getDisplayerVisual()->onTargetInstanceAttrModified(refMakerAttr
, refMakerAttrIndex
, targetAttrName
, targetAttrIndex
);
474 if (_DisplayerUI
) _DisplayerUI
->onTargetInstanceAttrModified(refMakerAttr
, refMakerAttrIndex
, targetAttrName
, targetAttrIndex
);
475 if (_DisplayerProperties
) _DisplayerProperties
->onTargetInstanceAttrModified(refMakerAttr
, refMakerAttrIndex
, targetAttrName
, targetAttrIndex
);
476 _ToLua
.onTargetInstanceAttrModified(refMakerAttr
, refMakerAttrIndex
, targetAttrName
, targetAttrIndex
);
480 // *********************************************************************************************************
481 void CInstance::onPreRender()
483 //H_AUTO(R2_CInstance_onPreRender)
485 if (_DisplayerVisual
) getDisplayerVisual()->onPreRender();
489 // *********************************************************************************************************
490 void CInstance::onPostRender()
492 //H_AUTO(R2_CInstance_onPostRender)
494 if (_DisplayerVisual
) getDisplayerVisual()->onPostRender();
498 // *********************************************************************************************************
499 CLuaObject
&CInstance::getLuaProjection()
501 //H_AUTO(R2_CInstance_getLuaProjection)
503 nlassert(_ToLua
._LuaProjection
.isValid());
505 return _ToLua
._LuaProjection
;
508 // *********************************************************************************************************
509 std::string
CInstance::getClassName() const
511 //H_AUTO(R2_CInstance_getClassName)
513 return getString(_ObjectTable
, "Class");
516 // *********************************************************************************************************
517 CLuaObject
&CInstance::getClass() const
519 //H_AUTO(R2_CInstance_getClass)
521 if (_ToLua
._Class
.isValid()) return _ToLua
._Class
;
522 _ToLua
._Class
= getEditor().getClasses()[getClassName()];
523 return _ToLua
._Class
;
526 // *********************************************************************************************************
527 TInstanceId
CInstance::getId() const
529 //H_AUTO(R2_CInstance_getId)
531 if (!_Id
.empty()) return _Id
;
532 nlassert(_ObjectTable
);
533 _Id
= getString(_ObjectTable
, "InstanceId");
538 // *********************************************************************************************************
539 CEntityCL
*CInstance::getEntity() const
541 //H_AUTO(R2_CInstance_getEntity)
543 CDisplayerVisualEntity
*dve
= dynamic_cast<CDisplayerVisualEntity
*>(getDisplayerVisual());
546 return dve
->getEntity();
551 // *********************************************************************************************************
552 std::string
CInstance::getSheet() const
554 CDisplayerVisualEntity
*dve
= dynamic_cast<CDisplayerVisualEntity
*>(getDisplayerVisual());
557 return dve
->getSheet();
562 // *********************************************************************************************************
563 CInstance
*CInstance::getParent() const
565 //H_AUTO(R2_CInstance_getParent)
567 static volatile bool cacheTest
= true;
575 CInstance
*result
= NULL
;
576 CObject
*currParent
= _ObjectTable
->getParent();
579 CInstance
*inst
= getEditor().getInstanceFromObject(currParent
);
585 currParent
= currParent
->getParent();
587 _LastParentOk
= true;
588 _LastParent
= result
;
592 // *********************************************************************************************************
593 bool CInstance::isSonOf(CInstance
*other
) const
595 //H_AUTO(R2_CInstance_isSonOf)
597 CInstance
*curr
=this->getParent();
600 if (curr
== other
) return true;
601 curr
= curr
->getParent();
606 // *********************************************************************************************************
607 bool CInstance::isKindOf(const std::string
&className
) const
609 //H_AUTO(R2_CInstance_isKindOf)
610 CEditor
&ed
= getEditor();
611 return ed
.isKindOf(_ClassIndex
, ed
.classToIndex(className
));
614 // *********************************************************************************************************
615 CInstance
*CInstance::getParentAct() const
617 //H_AUTO(R2_CInstance_getParentAct)
619 CInstance
*curr
= getParent();
622 if (curr
->isKindOf("Act")) return curr
;
623 curr
= curr
->getParent();
628 // *********************************************************************************************************
629 void CInstance::CToLua::executeHandler(const CLuaString
&name
, int numArgs
)
631 //H_AUTO(R2_CToLua_executeHandler)
632 CLuaState
&ls
= getEditor().getLua();
633 CLuaStackRestorer
lsr(&ls
, ls
.getTop() - numArgs
);
635 static volatile bool dumpStackWanted
= false;
636 if (dumpStackWanted
) ls
.dumpStack();
637 _Class
[ name
.getStr().c_str() ].push();
638 if (ls
.isNil(-1)) return; // not handled
639 if (dumpStackWanted
) ls
.dumpStack();
640 // put method before its args
641 ls
.insert(- numArgs
- 1);
642 if (dumpStackWanted
) ls
.dumpStack();
643 // Insert the 'this' as first parameter
644 _LuaProjection
.push();
645 ls
.insert(- numArgs
- 1);
647 if (dumpStackWanted
) ls
.dumpStack();
648 CLuaIHMRyzom::executeFunctionOnStack(ls
, numArgs
+ 1, 0);
649 if (dumpStackWanted
) ls
.dumpStack();
652 // *********************************************************************************************************
653 CLuaState
*CInstance::CToLua::getLua()
655 //H_AUTO(R2_CToLua_getLua)
656 return _LuaProjection
.getLuaState();
660 // *********************************************************************************************************
661 sint
CInstance::getSelectedSequence() const
663 //H_AUTO(R2_CInstance_getSelectedSequence)
664 CLuaObject selected
= const_cast<CInstance
*>(this)->getLuaProjection()["User"]["SelectedSequence"];
666 if (selected
.isInteger())
668 index
= (sint
) selected
.toInteger();
678 // *********************************************************************************************************
679 void CInstance::setSelectable(bool selectable
)
681 //H_AUTO(R2_CInstance_setSelectable)
683 if (selectable
== _Selectable
) return;
684 _Selectable
= selectable
;
685 CInstance
*selInstance
= getEditor().getSelectedInstance();
688 if (selInstance
&& (selInstance
== this || selInstance
->isSonOf(this)))
690 getEditor().setSelectedInstance(NULL
);
693 onAttrModified("Selectable");
696 // *********************************************************************************************************
697 bool CInstance::getSelectableFromRoot() const
699 //H_AUTO(R2_CInstance_getSelectableFromRoot)
701 const CInstance
*curr
= this;
704 if (!curr
->getSelectable()) return false;
705 curr
= curr
->getParent();
711 // *********************************************************************************************************
712 void CInstance::dummySetSelectableFromRoot(bool /* selectable */)
714 //H_AUTO(R2_CInstance_dummySetSelectableFromRoot)
715 nlwarning("SelectableFromRoot is a R/O property");
718 // *********************************************************************************************************
719 bool CInstance::getGhost() const
721 //H_AUTO(R2_CInstance_getGhost)
723 if (_ObjectTable
) return getObjectTable()->getGhost();
726 // *********************************************************************************************************
727 void CInstance::setGhost(bool ghost
)
729 //H_AUTO(R2_CInstance_setGhost)
731 if (_ObjectTable
) getObjectTable()->setGhost(ghost
);
734 // *********************************************************************************************************
735 CInstance
*CInstance::getParentGroup()
737 //H_AUTO(R2_CInstance_getParentGroup)
738 if (isKindOf("NpcGrpFeature")) return this;
739 if (getParent() && getParent()->isKindOf("NpcGrpFeature"))
746 // *********************************************************************************************************
747 const CInstance
*CInstance::getParentGroupLeader() const
749 //H_AUTO(R2_CInstance_getParentGroupLeader)
750 const CObjectTable
*props
= NULL
;
751 if (isKindOf("NpcGrpFeature"))
753 props
= getObjectTable();
755 else if (getParent() && getParent()->isKindOf("NpcGrpFeature"))
757 props
= getParent()->getObjectTable();
763 if (!props
) return NULL
;
765 const CObject
*components
= props
->findAttr("Components");
766 if (!components
|| components
->getSize() == 0)
770 return getEditor().getInstanceFromObject(components
->getValueAtPos(0));
773 // *********************************************************************************************************
774 CObject
*CInstance::getGroupSelectedSequence() const
776 //H_AUTO(R2_CInstance_getGroupSelectedSequence)
777 const CInstance
*leader
= getParentGroupLeader();
780 sint selectedSequence
= leader
->getSelectedSequence();
781 const CObject
*behav
= leader
->getObjectTable();
784 behav
= behav
->findAttr("Behavior");
787 const CObject
*activities
= behav
->findAttr("Activities");
790 if (selectedSequence
>= 0 && selectedSequence
< (sint
) activities
->getSize())
792 return activities
->getValueAtPos((sint32
) selectedSequence
);
802 // *********************************************************************************************************
803 bool CInstance::maxVisibleEntityExceeded() const
805 if (!_DisplayerVisual
) return false;
806 return _DisplayerVisual
->maxVisibleEntityExceeded();
809 // *********************************************************************************************************
810 std::string
CInstance::getPosInstanceId() const
812 //H_AUTO(R2_CInstance_getPosInstanceId)
813 CObject
*posObj
= getObjectTable()->getAttr("Position");
816 nlwarning("<CInstance::getPosInstanceId> can't retrieve position from object");
819 return posObj
->toString("InstanceId");
823 /////////////////////
824 // ACTION HANDLERS //
825 /////////////////////
827 // *********************************************************************************************************
828 // Select an instance from its id
829 class CAHSelectInstance
: public IActionHandler
831 virtual void execute(CCtrlBase
* /* pCaller */, const std::string
&sParams
)
833 // retrieve instance from its Id
834 CInstance
*instance
= getEditor().getInstanceFromId(sParams
);
837 getEditor().setSelectedInstance(instance
);
841 REGISTER_ACTION_HANDLER(CAHSelectInstance
, "r2ed_select_instance");
844 // *********************************************************************************************************
845 // Delete selected instance
846 class CAHDeleteSelectedInstance
: public IActionHandler
848 virtual void execute(CCtrlBase
* /* pCaller */, const std::string
&/* sParams */)
850 CInstance
*selectedInstance
= getEditor().getSelectedInstance();
851 if (selectedInstance
)
853 getEditor().getDMC().requestEraseNode(selectedInstance
->getId(), "", -1);
857 REGISTER_ACTION_HANDLER(CAHDeleteSelectedInstance
, "r2ed_delete_selected_instance");
859 // *********************************************************************************************************
860 // handler to pick an instance
861 class CAHPickerLua
: public IActionHandler
863 // TODO nico : replace this action handler by a CTool (in the same way that CToolChoosePosLua derives from CToolChoosePos)
864 virtual void execute(CCtrlBase
* /* pCaller */, const std::string
&sParams
)
866 // TODO : put this class in a separate file
867 class CToolPickLua
: public CToolPick
871 CToolPickLua(const std::string
&cursCanPickInstance
,
872 const std::string
&cursCannotPickInstance
,
873 const std::string
&cursCanPickPos
,
874 const std::string
&cursCannotPickPos
,
876 ) : CToolPick(cursCanPickInstance
,
877 cursCannotPickInstance
,
884 NLMISC_DECLARE_CLASS(CToolPickLua
);
885 void pick(CInstance
&instance
)
887 CTool::TSmartPtr
holdThis(this); // prevent 'setCurrentTool' from deleting 'this'
888 getEditor().setCurrentTool(NULL
);
889 if (!LuaPickFunc
.empty())
891 getEditor().getLua().executeScriptNoThrow(LuaPickFunc
+ "('" + instance
.getId() + "')");
894 void pick(const CVector
&pos
)
896 CTool::TSmartPtr
holdThis(this); // prevent 'setCurrentTool' from deleting 'this'
897 getEditor().setCurrentTool(NULL
);
898 if (!LuaPickPosFunc
.empty())
900 getEditor().getLua().executeScriptNoThrow(NLMISC::toString("%s(%f, %f, %f)", LuaPickPosFunc
.c_str(), pos
.x
, pos
.y
, pos
.z
));
903 bool canPick(const CInstance
&instance
) const
905 if (LuaPickFunc
.empty()) return true;
906 CLuaState
&lua
= getEditor().getLua();
907 int initialSize
= lua
.getTop();
908 std::string script
= "return " + LuaTestFunc
+ "('" + instance
.getId() + "')";
909 if (lua
.executeScriptNoThrow(script
, 1))
911 bool result
= lua
.toBoolean(initialSize
+ 1);
912 lua
.setTop(initialSize
);
915 lua
.setTop(initialSize
);
919 std::string LuaTestFunc
;
920 std::string LuaPickFunc
;
921 std::string LuaPickPosFunc
;
923 std::string cursCanPickInstance
= getParam(sParams
, "CursCanPickInstance");
924 std::string cursCannotPickInstance
= getParam(sParams
, "CursCannotPickInstance");
925 std::string cursCanPickPos
= getParam(sParams
, "CursCanPickPos");
926 std::string cursCannotPickPos
= getParam(sParams
, "CursCannotPickPos");
927 std::string wantMouseUp
= getParam(sParams
, "WantMouseUp");
928 std::string ignoreInstances
= getParam(sParams
, "IgnoreInstances");
930 if (cursCanPickInstance
.empty()) cursCanPickInstance
= "r2ed_tool_can_pick.tga";
931 if (cursCannotPickInstance
.empty()) cursCannotPickInstance
= "curs_stop.tga";
932 if (cursCanPickPos
.empty()) cursCanPickPos
= "r2ed_tool_pick.tga";
933 if (cursCannotPickPos
.empty()) cursCannotPickPos
= "r2ed_tool_pick.tga";
935 CToolPickLua
*picker
= new CToolPickLua(cursCanPickInstance
, cursCannotPickInstance
, cursCanPickPos
, cursCannotPickPos
, wantMouseUp
== "true");
936 picker
->LuaTestFunc
= getParam(sParams
, "TestFunc");
937 picker
->LuaPickFunc
= getParam(sParams
, "PickFunc");
938 picker
->LuaPickPosFunc
= getParam(sParams
, "PickPosFunc");
939 picker
->setIgnoreInstances(ignoreInstances
);
940 getEditor().setCurrentTool(picker
);
943 REGISTER_ACTION_HANDLER(CAHPickerLua
, "r2ed_picker_lua");
945 // *********************************************************************************************************
947 class CAHRotateInstance
: public IActionHandler
949 virtual void execute(CCtrlBase
* /* pCaller */, const std::string
&/* sParams */)
951 getEditor().setCurrentTool(new CToolSelectRotate
);
954 REGISTER_ACTION_HANDLER(CAHRotateInstance
, "r2ed_rotate");
956 // *********************************************************************************************************
958 class CAHMoveInstance
: public IActionHandler
960 virtual void execute(CCtrlBase
* /* pCaller */, const std::string
&/* sParams */)
962 getEditor().setCurrentTool(new CToolSelectMove
);
965 REGISTER_ACTION_HANDLER(CAHMoveInstance
, "r2ed_move");
969 // *********************************************************************************************************
970 // Debug : dump the lua table for current instance
971 class CAHDumpLuaTable
: public IActionHandler
973 virtual void execute(CCtrlBase
* /* pCaller */, const std::string
&sParams
)
975 if (!getEditor().getSelectedInstance()) return;
976 std::string maxDepthStr
= getParam(sParams
, "depth");
978 if (maxDepthStr
.empty())
981 fromString(maxDepthStr
, maxDepth
);
982 // don't want to display the parent
983 std::set
<const void *> negativeFilter
;
984 if (getEditor().getSelectedInstance()->getParent())
986 negativeFilter
.insert(getEditor().getSelectedInstance()->getParent()->getLuaProjection().toPointer());
988 getEditor().getSelectedInstance()->getLuaProjection().dump(30, &negativeFilter
);
991 REGISTER_ACTION_HANDLER(CAHDumpLuaTable
, "r2ed_dump_lua_table");