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/>.
23 #include "tool_create_entity.h"
25 #include "nel/misc/vectord.h"
26 #include "nel/misc/i18n.h"
28 #include "../client_sheets/character_sheet.h"
30 #include "../entity_cl.h"
31 #include "../player_r2_cl.h"
32 #include "../sheet_manager.h"
33 #include "nel/gui/lua_ihm.h"
34 #include "nel/misc/cdb_leaf.h"
35 #include "../interface_v3/interface_manager.h"
36 #include "dmc/palette.h"
37 #include "displayer_visual.h"
38 #include "r2_config.h"
39 #include "verbose_clock.h"
40 #include "entity_sorter.h"
42 #include "nel/gui/ctrl_base_button.h"
44 #include "game_share/player_visual_properties.h"
45 #include "game_share/visual_slot_manager.h"
51 using namespace NLPACS
;
52 using namespace NLMISC
;
58 // ***************************************************************
59 CToolCreateEntity::~CToolCreateEntity()
64 // ***************************************************************
65 void CToolCreateEntity::cancel()
67 CToolChoosePos::cancel();
71 // ***************************************************************
72 CToolCreateEntity::CToolCreateEntity(uint ghostSlot
, const std::string
&paletteId
, bool arrayMode
) : CToolChoosePos(ghostSlot
)
74 _PaletteId
= paletteId
;
79 _CreateState
= CreateSingle
;
80 _ArrayOrigin
.set(0.f
, 0.f
, 0.f
);
81 _ArrayEnd
.set(0.f
, 0.f
, 0.f
);
82 _ArrayDefaultAngle
= 0.f
;
85 CObject
*paletteNode
= getEditor().getDMC().getPaletteElement(paletteId
);
88 std::string sheetClient
= getString(paletteNode
, "SheetClient");
89 if (isBotObjectSheet(CSheetId(sheetClient
)))
91 _CreateState
= ChooseArrayOrigin
;
95 _ArrayWantedAction
= ArrayActionNone
;
98 // ***************************************************************
99 void CToolCreateEntity::updateInvalidCursorOnUI()
101 //H_AUTO(R2_CToolCreateEntity_updateInvalidCursorOnUI)
102 // set the default cursor unless the mouse is on the palette
103 const std::vector
<CInterfaceGroup
*> &groups
= CWidgetManager::getInstance()->getGroupsUnderPointer();
104 for(uint k
= 0; k
< groups
.size(); ++k
)
106 if (groups
[k
]->getId() == "ui:interface:r2ed_palette") // hardcoded for now ...
108 setMouseCursor(_CursValid
);
112 setMouseCursor(DEFAULT_CURSOR
);
115 // ***************************************************************
116 void CToolCreateEntity::commit(const NLMISC::CVector
&createPosition
, float createAngle
)
118 //H_AUTO(R2_CToolCreateEntity_commit)
119 if (_CreateState
== ChooseArrayOrigin
)
121 if (!getEditor().verifyRoomLeft(0, 1))
124 CLuaManager::getInstance().executeLuaScript("r2:checkStaticQuota(1)");
127 setContextHelp(CI18N::get("uiR2EDDrawArrayContextHelp"));
128 _CreateState
= DrawArray
;
129 _ArrayDefaultAngle
= createAngle
;
130 _ArrayOrigin
= createPosition
;
131 _ArrayEnd
= createPosition
;
132 updateArray(getGhost());
137 CEntityCL
*ghost
= getGhost();
140 cloneEntityIntoScenario(ghost
,
143 true, /* new action */
144 false /* create ghost */);
146 if (isMultiPos() && isShiftDown())
148 // prevent newly created ghost to be removed twice ...
150 // re set this tool to generate a new entity look
151 CAHManager::getInstance()->runActionHandler("r2ed_create_entity", NULL
, "PaletteId=" + _PaletteId
);
155 // ***************************************************************
156 bool CToolCreateEntity::isBotObjectSheet(const NLMISC::CSheetId
&sheetId
) const
158 //H_AUTO(R2_CToolCreateEntity_isBotObjectSheet)
159 const CCharacterSheet
*charSheet
= dynamic_cast<const CCharacterSheet
*>(SheetMngr
.get(sheetId
));
162 std::string botobjectsPaletteRoot
= "palette.entities.botobjects";
163 return (_PaletteId
.substr(0, botobjectsPaletteRoot
.size()) == botobjectsPaletteRoot
);
169 // ***************************************************************
170 std::string
CToolCreateEntity::cloneEntityIntoScenario(CEntityCL
*clonee
,
171 const NLMISC::CVector
&createPosition
,
177 //H_AUTO(R2_CToolCreateEntity_cloneEntityIntoScenario)
178 if (!clonee
) return "";
179 std::string instanceId
;
180 bool isBotObject
= isBotObjectSheet(clonee
->sheetId());
182 if (!getEditor().verifyRoomLeft(isBotObject
? 0 : 1, isBotObject
? 1 : 0)) { return ""; }
184 std::string className
;
185 // if class is given in the palette node, then use it. Default to 'Npc' else
186 CObject
*paletteNode
= getDMC().getPaletteElement(_PaletteId
);
187 if (paletteNode
&& paletteNode
->findIndex("Class") != -1)
189 className
= getString(paletteNode
, "Class");
191 if (className
.empty())
196 ucstring readableName
;
197 // retrieve name from the palette id
198 CLuaState
&ls
= getEditor().getLua();
199 getEditor().getEnv()["PaletteIdToTranslation"][_PaletteId
].push();
202 readableName
.fromUtf8(ls
.toString(-1));
204 if (readableName
.empty())
206 // if no name found then give a default one
207 readableName
= CI18N::get(isBotObject
? "uiR2EDNameBotObject" : "uiR2EDNameNPC");
210 // except for creatures, posfix the name with a number
211 std::string creaturePaletteRoot
= "palette.entities.creatures";
212 if (_PaletteId
.substr(0, creaturePaletteRoot
.size()) != creaturePaletteRoot
)
214 readableName
= getEditor().genInstanceName(readableName
);
218 className
= "NpcCreature";
221 std::string sheetClient
= getString(paletteNode
, "SheetClient");
222 getEditor().getLua().push(sheetClient
);
223 if (getEditor().getEnv().callMethodByNameNoThrow("isNPCPlant", 1, 1))
225 CLuaObject
result(getEditor().getLua());
226 bool isPlant
= result
.toBoolean();
228 className
= "NpcPlant";
234 getDMC().newAction(NLMISC::CI18N::get("uiR2EDCreateAction") + readableName
);
236 // send network commands to create entity on server
237 CUniquePtr
<CObject
> desc(getDMC().newComponent(className
));
241 // TMP FIX : if the created entity is a custom npc, then retrieve look from the clonee visual properties
242 if (className
== "NpcCustom")
247 const string propNameA
= toString("SERVER:Entities:E%d:P%d", clonee
->slot(), CLFECOMMON::PROPERTY_VPA
);
248 const string propNameB
= toString("SERVER:Entities:E%d:P%d", clonee
->slot(), CLFECOMMON::PROPERTY_VPB
);
249 const string propNameC
= toString("SERVER:Entities:E%d:P%d", clonee
->slot(), CLFECOMMON::PROPERTY_VPC
);
250 CCDBNodeLeaf
*leafA
= NLGUI::CDBManager::getInstance()->getDbProp(propNameA
);
251 CCDBNodeLeaf
*leafB
= NLGUI::CDBManager::getInstance()->getDbProp(propNameB
);
252 CCDBNodeLeaf
*leafC
= NLGUI::CDBManager::getInstance()->getDbProp(propNameC
);
255 nlwarning("Can't find DB leaf %s", propNameA
.c_str());
260 nlwarning("Can't find DB leaf %s", propNameB
.c_str());
265 nlwarning("Can't find DB leaf %s", propNameC
.c_str());
269 vA
.PropertyA
= leafA
->getValue64();
270 vB
.PropertyB
= leafB
->getValue64();
271 vC
.PropertyC
= leafC
->getValue64();
272 nlassert(desc
->isTable());
273 CObjectTable
*props
= (CObjectTable
*) desc
.get();
275 props
->set("GabaritHeight", (double)vC
.PropertySubData
.CharacterHeight
);
276 props
->set("GabaritTorsoWidth", (double)vC
.PropertySubData
.TorsoWidth
);
277 props
->set("GabaritArmsWidth", (double)vC
.PropertySubData
.ArmsWidth
);
278 props
->set("GabaritLegsWidth", (double)vC
.PropertySubData
.LegsWidth
);
279 props
->set("GabaritBreastSize", (double)vC
.PropertySubData
.BreastSize
);
281 props
->set("HairColor", (double)vA
.PropertySubData
.HatColor
);
282 props
->set("Tattoo", (double)vC
.PropertySubData
.Tattoo
);
283 props
->set("EyesColor", (double)vC
.PropertySubData
.EyesColor
);
285 props
->set("MorphTarget1", (double)vC
.PropertySubData
.MorphTarget1
);
286 props
->set("MorphTarget2", (double)vC
.PropertySubData
.MorphTarget2
);
287 props
->set("MorphTarget3", (double)vC
.PropertySubData
.MorphTarget3
);
288 props
->set("MorphTarget4", (double)vC
.PropertySubData
.MorphTarget4
);
289 props
->set("MorphTarget5", (double)vC
.PropertySubData
.MorphTarget5
);
290 props
->set("MorphTarget6", (double)vC
.PropertySubData
.MorphTarget6
);
291 props
->set("MorphTarget7", (double)vC
.PropertySubData
.MorphTarget7
);
292 props
->set("MorphTarget8", (double)vC
.PropertySubData
.MorphTarget8
);
294 props
->set("Sex", (double)vA
.PropertySubData
.Sex
);
296 CVisualSlotManager
* vsManager
= CVisualSlotManager::getInstance();
297 NLMISC::CSheetId
* sheetId
= NULL
;
299 if(vA
.PropertySubData
.HatModel
== 0)
301 props
->set("HatModel", 0);
305 sheetId
= vsManager
->index2Sheet((uint32
)vA
.PropertySubData
.HatModel
, SLOTTYPE::HEAD_SLOT
);
308 props
->set("HairType", (double)sheetId
->asInt());
312 if(vA
.PropertySubData
.JacketModel
== 0)
314 props
->set("JacketModel", 0);
318 sheetId
= vsManager
->index2Sheet((uint32
)vA
.PropertySubData
.JacketModel
, SLOTTYPE::CHEST_SLOT
);
321 props
->set("JacketModel", (double)sheetId
->asInt());
325 if(vA
.PropertySubData
.TrouserModel
== 0)
327 props
->set("TrouserModel", 0);
331 sheetId
= vsManager
->index2Sheet((uint32
)vA
.PropertySubData
.TrouserModel
, SLOTTYPE::LEGS_SLOT
);
334 props
->set("TrouserModel", (double)sheetId
->asInt());
338 if(vB
.PropertySubData
.FeetModel
== 0)
340 props
->set("FeetModel", 0);
344 sheetId
= vsManager
->index2Sheet((uint32
)vB
.PropertySubData
.FeetModel
, SLOTTYPE::FEET_SLOT
);
347 props
->set("FeetModel", (double)sheetId
->asInt());
351 if(vB
.PropertySubData
.HandsModel
== 0)
353 props
->set("HandsModel", 0);
357 sheetId
= vsManager
->index2Sheet((uint32
)vB
.PropertySubData
.HandsModel
, SLOTTYPE::HANDS_SLOT
);
360 props
->set("HandsModel", (double)sheetId
->asInt());
364 if(vA
.PropertySubData
.ArmModel
== 0)
366 props
->set("ArmModel", 0);
370 sheetId
= vsManager
->index2Sheet((uint32
)vA
.PropertySubData
.ArmModel
, SLOTTYPE::ARMS_SLOT
);
373 props
->set("ArmModel", (double)sheetId
->asInt());
377 double weaponRH
=0, weaponLH
=0;
378 if(vA
.PropertySubData
.WeaponRightHand
== 0)
380 props
->set("WeaponRightHand", 0);
384 sheetId
= vsManager
->index2Sheet((uint32
)vA
.PropertySubData
.WeaponRightHand
, SLOTTYPE::RIGHT_HAND_SLOT
);
387 weaponRH
= (double)sheetId
->asInt();
389 props
->set("WeaponRightHand", weaponRH
);
392 if(vA
.PropertySubData
.WeaponLeftHand
== 0)
394 props
->set("WeaponLeftHand", 0);
398 sheetId
= vsManager
->index2Sheet((uint32
)vA
.PropertySubData
.WeaponLeftHand
, SLOTTYPE::LEFT_HAND_SLOT
);
401 weaponLH
= (double)sheetId
->asInt();
403 props
->set("WeaponLeftHand", weaponLH
);
406 props
->set("JacketColor", (double)vA
.PropertySubData
.JacketColor
);
407 props
->set("TrouserColor", (double)vA
.PropertySubData
.TrouserColor
);
408 props
->set("FeetColor", (double)vB
.PropertySubData
.FeetColor
);
409 props
->set("HandsColor", (double)vB
.PropertySubData
.HandsColor
);
410 props
->set("ArmColor", (double)vA
.PropertySubData
.ArmColor
);
412 CPlayerR2CL
* player
= (CPlayerR2CL
*)dynamic_cast<CPlayerR2CL
*>(clonee
);
415 std::string race
, gender
, sheetClient
;
416 switch(player
->people())
418 case EGSPD::CPeople::Fyros
:
419 sheetClient
= "basic_fyros_";
423 case EGSPD::CPeople::Matis
:
424 sheetClient
= "basic_matis_";
428 case EGSPD::CPeople::Tryker
:
429 sheetClient
= "basic_tryker_";
433 case EGSPD::CPeople::Zorai
:
434 sheetClient
= "basic_zorai_";
439 nlwarning("CToolCreateEntity::commit unknown people");
441 switch(player
->getGender())
443 case GSGENDER::female
:
444 sheetClient
= sheetClient
+"female.creature";
449 sheetClient
= sheetClient
+"male.creature";
454 nlwarning("CToolCreateEntity::commit unknown gender");
457 props
->set("SheetClient", sheetClient
);
460 getEditor().getLua().push(race
);
461 getEditor().getLua().push(gender
);
462 if (getEditor().getEnv().callMethodByNameNoThrow("randomNPCName", 2, 1))
464 CLuaObject
result(getEditor().getLua());
465 std::string name
= result
.toString();
466 props
->set("Name", name
);
470 getEditor().getLua().push(getString(paletteNode
, "Equipment"));
471 getEditor().getLua().push(weaponRH
);
472 getEditor().getLua().push(weaponLH
);
473 getEditor().getLua().push(getString(paletteNode
, "Sheet"));
474 getEditor().getLua().push(getString(paletteNode
, "SheetModel"));
475 if (getEditor().getEnv().callMethodByNameNoThrow("searchSheet", 5, 1))
477 CLuaObject
result(getEditor().getLua());
478 std::string sheet
= result
.toString();
479 props
->set("Sheet", sheet
);
483 nlwarning("SearchSheet failed : Palette Id = %s", _PaletteId
.c_str());
489 desc
->set("Name", readableName
.toUtf8());
492 desc
->set("Base", _PaletteId
);
493 desc
->setObject("Position", buildVector(CVectorD(createPosition
)));
494 desc
->set("Angle", createAngle
);
495 //desc->set("Name", readableName.toUtf8());
497 instanceId
= getString(desc
.get(), "InstanceId");
498 if (!instanceId
.empty())
502 // selection asked when instance is created
503 getEditor().setCookie(instanceId
, "Select", true);
507 getEditor().setCookie(instanceId
, "GhostDuplicate", true);
511 // send creation command
512 // tmp : static npc counter
513 // add in component list of default feature
514 if (getEditor().getDefaultFeature())
516 std::string targetInstanceId
;
517 // if object is a bot object, it is considered to be permanent content
518 // and should be created in the base act
519 CInstance
*targetAct
= isBotObject
? getEditor().getBaseAct() : getEditor().getCurrentAct();
522 nlwarning("Can't find act when creating an entity");
526 if (_AutoGroup
.getGroupingCandidate())
528 nlassert(!createGhost
); // either autogroup or arraymode, both at the same time not supported
529 _AutoGroup
.group(desc
.get(), createPosition
);
534 desc
->setGhost(createGhost
);
535 getDMC().requestInsertNode(getEditor().getDefaultFeature(targetAct
)->getId(),
547 // ***************************************************************
548 void CToolCreateEntity::onActivate()
550 //H_AUTO(R2_CToolCreateEntity_onActivate)
551 setContextHelp(CI18N::get("uiR2EDToolCreateEntity"));
554 // ***************************************************************
555 void CToolCreateEntity::updateBeforeRender()
557 //H_AUTO(R2_CToolCreateEntity_updateBeforeRender)
558 if (_CreateState
!= DrawArray
)
560 CToolChoosePos::updateBeforeRender();
561 _AutoGroup
.update(_CreatePosition
, _PaletteId
, _Valid
&& !isCtrlDown());
562 setContextHelp(CI18N::get(_AutoGroup
.getGroupingCandidate() ? "uiR2EDToolCreateEntityAutoGroup" : "uiR2EDToolCreateEntity"));
565 setContextHelp(CI18N::get("uiR2EDDrawArrayContextHelp"));
566 // update for array mode
568 sint32 mouseX
, mouseY
;
569 getMousePos(mouseX
, mouseY
);
570 if (!isInScreen(mouseX
, mouseY
) || (isMouseOnUI() && !isMouseOnWorldMap()))
573 _ArrayEnd
= _ArrayOrigin
;
576 CTool::CWorldViewRay worldViewRay
;
577 computeWorldViewRay(mouseX
, mouseY
, worldViewRay
);
579 CVector entityPos
; // the pos where the ghost will be shown
580 CVector inter
; // intersection of view ray with landscape
582 TRayIntersectionType rayIntersectionType
= computeLandscapeRayIntersection(worldViewRay
, inter
);
583 switch(rayIntersectionType
)
587 _ArrayEnd
= _ArrayOrigin
;
594 for (uint k
= 0; valid
&& k
< _ArrayElements
.size(); ++k
)
596 if (_ArrayElements
[k
])
598 if (_ArrayElements
[k
]->getDisplayFlag(CDisplayerVisual::FlagBadPos
))
604 CGroupMap
*worldMap
= getWorldMap();
605 if (worldMap
) worldMap
->setSelectionAxis(_ValidArray
);
606 setMouseCursor(_ValidArray
? _CursValid
: _CursInvalid
);
609 // ***************************************************************
610 void CToolCreateEntity::updateAfterRender()
612 //H_AUTO(R2_CToolCreateEntity_updateAfterRender)
613 if (_CreateState
!= DrawArray
)
615 CToolChoosePos::updateAfterRender();
618 switch(_ArrayWantedAction
)
620 case ArrayActionNone
:
622 case ArrayActionValidate
:
625 CTool::TSmartPtr
hold(this);
626 CAHManager::getInstance()->runActionHandler("r2ed_create_entity", NULL
, "PaletteId="+_PaletteId
);
630 case ArrayActionCancel
:
632 CTool::TSmartPtr
hold(this);
634 getEditor().setCurrentTool(NULL
);
643 // ***************************************************************
644 bool CToolCreateEntity::onMouseLeftButtonClicked()
646 //H_AUTO(R2_CToolCreateEntity_onMouseLeftButtonClicked)
647 if (_CreateState
!= DrawArray
)
649 return CToolChoosePos::onMouseLeftButtonClicked();
653 _ArrayWantedAction
= ArrayActionValidate
;
658 // ***************************************************************
659 bool CToolCreateEntity::onMouseRightButtonClicked()
661 //H_AUTO(R2_CToolCreateEntity_onMouseRightButtonClicked)
662 if (_CreateState
!= DrawArray
)
664 return CToolChoosePos::onMouseRightButtonClicked();
666 _ArrayWantedAction
= ArrayActionCancel
;
670 // ***************************************************************
671 void CToolCreateEntity::clearArray()
673 //H_AUTO(R2_CToolCreateEntity_clearArray)
674 for (uint k
= 0; k
< _ArrayElements
.size(); ++k
)
676 if (_ArrayElements
[k
])
678 getEditor().getDMC().requestEraseNode(_ArrayElements
[k
]->getDisplayedInstance()->getId(), "", -1);
683 // ***************************************************************
684 void CToolCreateEntity::updateArray(CEntityCL
*clonee
)
686 //H_AUTO(R2_CToolCreateEntity_updateArray)
689 nlassert(!_ArrayElements
.empty());
690 nlassert(_ArrayElements
[0] != NULL
);
691 clonee
= _ArrayElements
[0]->getEntity();
698 CVector extent
= _ArrayEnd
- _ArrayOrigin
;
700 float arrayStepLength
= 1.f
;
701 if (!_ArrayElements
.empty() && _ArrayElements
[0])
703 arrayStepLength
= 2.f
* _ArrayElements
[0]->getSelectionDecalRadius();
704 arraySize
= (uint
) floorf(extent
.norm() / arrayStepLength
) + 1;
705 arraySize
= std::min(arraySize
, (uint
) 16);
707 while (!getEditor().verifyRoomLeft(0, arraySize
))
712 TSmartPtr
hold(this);
717 _ArrayElements
.resize(std::max(arraySize
, uint(_ArrayElements
.size())));
718 CVector delta
= arrayStepLength
* extent
.normed();
719 float angle
= _ArrayDefaultAngle
;
722 angle
= - (float) atan2(extent
.x
, extent
.y
);
724 bool newEntityCreated
= false;
725 uint numCreatedEntity
= 0;
726 for (uint k
= 0; k
< _ArrayElements
.size(); ++k
)
728 CVector pos
= _ArrayOrigin
+ (float) k
* delta
;
729 if (!_ArrayElements
[k
])
733 nlwarning("NEW ENTITY");
734 // create new element
735 std::string instanceId
= cloneEntityIntoScenario(clonee
,
738 false, /*new action*/
739 true /*create ghost*/);
740 CInstance
*inst
= getEditor().getInstanceFromId(instanceId
);
743 _ArrayElements
[k
] = dynamic_cast<CDisplayerVisualEntity
*>(inst
->getDisplayerVisual());
744 if (_ArrayElements
[k
])
746 _ArrayElements
[k
]->setDisplayMode(CDisplayerVisual::DisplayModeArray
);
749 newEntityCreated
= true;
754 if (_ArrayElements
[k
])
756 bool active
= k
< arraySize
;
757 // do a kind of 'reserve' on the list of entities : don't delete entities in excess, but hide them instead
758 if (active
!= _ArrayElements
[k
]->getActive())
760 _ArrayElements
[k
]->setActive(active
);
763 newEntityCreated
= true;
764 _ArrayElements
[k
]->setDisplayMode(CDisplayerVisual::DisplayModeArray
);
769 // update pos & angle
770 TInstanceId instanceId
= _ArrayElements
[k
]->getDisplayedInstance()->getId();
771 CVector worldPos
= _ArrayElements
[k
]->getWorldPos();
774 CObject
*newPos
= buildVector(pos
, _ArrayElements
[k
]->getDisplayedInstance()->getPosInstanceId());
775 getEditor().getDMC().requestSetNode(instanceId
, "Position", newPos
);
778 if (angle
!= _ArrayElements
[k
]->getAngle())
780 CObjectNumber
*angleObject
= new CObjectNumber(angle
);
781 getEditor().getDMC().requestSetNode(instanceId
, "Angle", angleObject
);
787 if (newEntityCreated
)
789 nlwarning("Num created entity = %d", numCreatedEntity
);
790 getEditor().getEntitySorter()->clipEntitiesByDist();
794 // ***************************************************************
795 void CToolCreateEntity::commitArray()
797 //H_AUTO(R2_CToolCreateEntity_commitArray)
798 for (uint k
= 0; k
< _ArrayElements
.size(); ++k
)
800 if (_ArrayElements
[k
])
802 cloneEntityIntoScenario(_ArrayElements
[k
]->getEntity(),
803 _ArrayElements
[k
]->getWorldPos(),
804 _ArrayElements
[k
]->getAngle(),
805 k
== 0, /*new action*/
806 false /*create ghost*/);
810 getEditor().getDMC().flushActions();
813 // ***************************************************************
814 bool CToolCreateEntity::stopAfterCommit() const
816 //H_AUTO(R2_CToolCreateEntity_stopAfterCommit)
817 return _CreateState
== CreateSingle
;
822 // ***************************************************************
823 class CAHR2EDToggleDrawArray
: public IActionHandler
825 virtual void execute(CCtrlBase
*pCaller
, const std::string
&/* sParams */)
827 CInterfaceManager
*im
= CInterfaceManager::getInstance();
828 CCtrlBaseButton
*but
= dynamic_cast<CCtrlBaseButton
*>(pCaller
);
831 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:R2_DRAW_ARRAY")->setValueBool(but
->getPushed());
832 CToolCreateEntity
*tce
= dynamic_cast<CToolCreateEntity
*>(getEditor().getCurrentTool());
835 CAHManager::getInstance()->runActionHandler("r2ed_create_entity", NULL
, "PaletteId=" + tce
->getPaletteId());
840 REGISTER_ACTION_HANDLER(CAHR2EDToggleDrawArray
, "r2ed_toggle_draw_array");