Merge branch '164-crash-on-patching-and-possibly-right-after-login' into main/gingo...
[ryzomcore.git] / ryzom / client / src / cursor_functions.cpp
blobcf471df79f7a797e776980bf1628d4c9a5b916ff
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2018 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
6 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /////////////
26 // INCLUDE //
27 /////////////
28 #include "stdpch.h"
29 // Client.
30 #include "cursor_functions.h"
31 #include "user_entity.h"
32 #include "entities.h"
33 #include "net_manager.h"
34 #include "interface_v3/interface_manager.h"
35 #include "interface_v3/interface_3d_scene.h"
36 #include "nel/gui/group_container.h"
37 #include "sheet_manager.h"
38 #include "interface_v3/inventory_manager.h"
39 #include "interface_v3/guild_manager.h"
40 #include "nel/3d/u_instance.h"
41 #include "main_loop.h"
42 // GAME SHARE
43 #include "game_share/bot_chat_types.h"
44 // r2
45 #include "r2/editor.h"
48 ///////////
49 // USING //
50 ///////////
51 using namespace NLMISC;
52 using namespace NL3D;
54 #ifdef DEBUG_NEW
55 #define new DEBUG_NEW
56 #endif
59 ////////////
60 // GLOBAL //
61 ////////////
62 // Contextual Cursor.
63 CContextualCursor ContextCur;
64 CLFECOMMON::TCLEntityId SlotUnderCursor;
65 uint32 MissionId = 0;
66 uint32 MissionRingId = 0;
67 sint32 InstanceId = 0;
68 sint32 selectedInstance = -1;
69 string selectedInstanceURL;
70 static NLMISC::CRefPtr<NLMISC::CCDBNodeLeaf> s_UserCharFade;
73 ///////////////
74 // FUNCTIONS //
75 ///////////////
76 void checkUnderCursor();
77 void contextSelect (bool rightClick, bool dblClick);
78 void contextAttack (bool rightClick, bool dblClick);
79 void contextQuarter (bool rightClick, bool dblClick);
80 void contextLoot (bool rightClick, bool dblClick);
81 void contextPickUp (bool rightClick, bool dblClick);
82 void contextTradeItem (bool rightClick, bool dblClick);
83 void contextTradePhrase (bool rightClick, bool dblClick);
84 void contextDynamicMission (bool rightClick, bool dblClick);
85 void contextStaticMission (bool rightClick, bool dblClick);
86 void contextTradePact (bool rightClick, bool dblClick);
87 void contextCreateGuild (bool rightClick, bool dblClick);
88 void contextNews (bool rightClick, bool dblClick);
89 void contextTeleport (bool rightClick, bool dblClick);
90 void contextFaction (bool rightClick, bool dblClick);
91 void contextCosmetic (bool rightClick, bool dblClick);
92 void contextTalk (bool rightClick, bool dblClick);
93 void contextExtractRM (bool rightClick, bool dblClick);
94 void contextMission (bool rightClick, bool dblClick);
95 void contextWebPage (bool rightClick, bool dblClick);
96 void contextWebIG (bool rightClick, bool dblClick);
97 void contextARKitect (bool rightClick, bool dblClick);
98 void contextRingMission (bool rightClick, bool dblClick);
99 void contextOutpost (bool rightClick, bool dblClick);
100 void contextBuildTotem (bool rightClick, bool dblClick);
101 //-----------------------------------------------
102 // initContextualCursor :
103 // Initialize Contextual Cursor.
104 //-----------------------------------------------
105 void initContextualCursor()
107 // Create states of the Contextual Cursor.
108 ContextCur.add(false, "STAND BY", string("curs_default.tga"), 0.0f, checkUnderCursor, 0);
109 ContextCur.add(false, "SELECTABLE", string("curs_pick.tga"), 0.0f, checkUnderCursor, contextSelect);
110 // ContextCur.add(false, "ATTACK", string("hand_attack.TGA"), 0.0f, checkUnderCursor, contextAttack);
111 // ContextCur.add(false, "QUARTER", string("hand_harvest.TGA"), 0.0f, checkUnderCursor, contextQuarter);
112 // ContextCur.add(false, "LOOT", string("hand_loot.TGA"), 0.0f, checkUnderCursor, contextLoot);
113 // ContextCur.add(false, "PICKUP", string("hand_loot.TGA"), 0.0f, checkUnderCursor, contextPickUp);
114 // ContextCur.add(false, "TALK", string("hand_speak.TGA"), 0.0f, checkUnderCursor, contextTalk);
116 // String Cursors
117 ContextCur.add(true, "ATTACK", string("uimGcmAttack"), 0.0f, checkUnderCursor, contextAttack);
118 ContextCur.add(true, "QUARTER", string("uimGcmQuartering"), 0.0f, checkUnderCursor, contextQuarter);
119 ContextCur.add(true, "LOOT", string("uimGcmLoot"), 0.0f, checkUnderCursor, contextLoot);
120 ContextCur.add(true, "PICKUP", string("uimGcmPickUp"), 0.0f, checkUnderCursor, contextPickUp);
121 ContextCur.add(true, "TRADE ITEM", string("uimGcmTrade"), 0.0f, checkUnderCursor, contextTradeItem);
122 ContextCur.add(true, "TRADE PHRASE", string("uimGcmTradePhase"), 0.0f, checkUnderCursor, contextTradePhrase);
123 ContextCur.add(true, "DYNAMIC MISSION", string("uimGcmDynamicMission"), 0.0f, checkUnderCursor, contextDynamicMission);
124 ContextCur.add(true, "STATIC MISSION", string("uimGcmMissions"), 0.0f, checkUnderCursor, contextStaticMission);
125 ContextCur.add(true, "TRADE PACT", string("uimGcmTradePact"), 0.0f, checkUnderCursor, contextTradePact);
126 ContextCur.add(true, "CREATE GUILD", string("uimGcmCreateGuild"), 0.0f, checkUnderCursor, contextCreateGuild);
127 ContextCur.add(true, "NEWS", string("uimGcmNews"), 0.0f, checkUnderCursor, contextNews);
128 ContextCur.add(true, "TELEPORT", string("uimGcmTeleport"), 0.0f, checkUnderCursor, contextTeleport);
129 ContextCur.add(true, "FACTION", string("uimGcmFaction"), 0.0f, checkUnderCursor, contextFaction);
130 ContextCur.add(true, "COSMETIC", string("uimGcmCosmetic"), 0.0f, checkUnderCursor, contextCosmetic);
131 // ContextCur.add(true, "TALK", string("uimGcmTalk"), 0.0f, checkUnderCursor, contextTalk);
132 ContextCur.add(true, "EXTRACT_RM", string("uimGcmExtractRM"), 0.0f, checkUnderCursor, contextExtractRM);
133 ContextCur.add(true, "MISSION", string(""), 0.0f, checkUnderCursor, contextMission);
134 ContextCur.add(true, "WEB PAGE", string(""), 0.0f, checkUnderCursor, contextWebPage);
135 ContextCur.add(true, "WEBIG", string(""), 0.0f, checkUnderCursor, contextWebIG);
136 ContextCur.add(false, "ARKITECT", string("curs_create.tga"), 0.0f, checkUnderCursor, contextARKitect);
137 ContextCur.add(true, "OUTPOST", string(""), 0.0f, checkUnderCursor, contextOutpost);
138 ContextCur.add(true, "RING MISSION", string(""), 0.0f, checkUnderCursor, contextRingMission);
139 ContextCur.add(true, "BUILD_TOTEM", string("uimGcmChooseBuilding"), 0.0f, checkUnderCursor, contextBuildTotem);
140 }// initContextualCursor //
142 //-----------------------------------------------
143 // releaseContextualCursor :
144 // Release cursors.
145 //-----------------------------------------------
146 void releaseContextualCursor()
148 ContextCur.release();
149 }// releaseContextualCursor //
152 //-----------------------------------------------
153 // testMissionOption
154 //-----------------------------------------------
155 static bool testMissionOption(sint32 priorityWanted)
157 CInterfaceManager *pIM= CInterfaceManager::getInstance();
159 uint32 textID = 0;
160 sint32 bestPriority = 0;
161 for(uint k = 0; k < NUM_MISSION_OPTIONS; ++k)
163 std::string nodeName = toString("LOCAL:TARGET:CONTEXT_MENU:MISSIONS_OPTIONS:%d:PRIORITY", (int) k);
164 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(nodeName, false);
165 if(pNL)
167 sint32 priority = pNL->getValue32();
168 if(priority == priorityWanted)
170 // Special for priority 2 (yoyo: don't know why...). fail if more than one choice
171 if(priorityWanted != 2 || textID==0)
173 nodeName = toString("LOCAL:TARGET:CONTEXT_MENU:MISSIONS_OPTIONS:%d:TITLE", (int) k);
174 pNL = NLGUI::CDBManager::getInstance()->getDbProp(nodeName, false);
175 if(pNL && pNL->getValue32())
177 textID = pNL->getValue32();
178 MissionId = k;
179 bestPriority = priority;
180 // general case: found so stop. priority==2: must check all options
181 if(priorityWanted!=2)
182 break;
185 // here means that priorityWanted==2 and textId!=0
186 else
188 // More than a choice for priorityWanted=2 mission options so nothing to show.
189 textID=0;
190 break;
194 else
195 nlwarning("checkUnderCursor: entry '%s' dose not exist.", nodeName.c_str());
197 // Get the Text for the cursor
198 if(textID)
200 string result;
201 bool res = STRING_MANAGER::CStringManagerClient::instance()->getDynString(textID, result);
202 if (!res)
203 result = NLMISC::CI18N::get("uiMissionOptionNotReceived");
204 if(ContextCur.context("MISSION", 0.0, result))
205 return true;
208 return false;
211 //-----------------------------------------------
212 // testMissionRing
213 //-----------------------------------------------
214 static bool testMissionRing()
216 CInterfaceManager *pIM= CInterfaceManager::getInstance();
218 for(uint i=0;i<BOTCHATTYPE::MaxR2MissionEntryDatabase;i++)
220 // get the ring mission title textID
221 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp(toString("LOCAL:TARGET:CONTEXT_MENU:MISSION_RING:%d:TITLE", i), false);
222 if(pNL && pNL->getValue32())
224 uint32 textID = pNL->getValue32();
226 // if the string is not received display a temp string
227 string missionRingText;
228 if(!STRING_MANAGER::CStringManagerClient::instance()->getDynString(textID, missionRingText))
229 missionRingText = NLMISC::CI18N::get("uiMissionRingNameNotReceived");
231 // display the cursor
232 MissionRingId= i;
233 if(ContextCur.context("RING MISSION", 0.f, missionRingText))
234 return true;
238 return false;
242 //-----------------------------------------------
243 // checkUnderCursor :
244 // Select the right context according to what is under the cursor.
245 //-----------------------------------------------
246 void checkUnderCursor()
248 // Get the interface instance.
249 CInterfaceManager *IM = CInterfaceManager::getInstance();
250 if(IM == 0)
251 return;
253 // Get the cursor instance
254 CViewPointer *cursor = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() );
255 if(cursor == 0)
256 return;
258 // No Op if screen minimized
259 if(CViewRenderer::getInstance()->isMinimized())
260 return;
262 // Get the pointer position (in pixel)
263 sint32 x, y;
264 cursor->getPointerPos(x, y);
266 // Over the interface ?
267 if (CWidgetManager::getInstance()->getWindowUnder(x, y) == NULL)
269 // Is the pointer in the window ?
270 if(x < 0 || y <0)
271 return;
272 uint32 w, h;
273 CViewRenderer &viewRender = *CViewRenderer::getInstance();
274 viewRender.getScreenSize(w, h);
275 if(x>=(sint32)w || y>=(sint32)h)
276 return;
277 // Get the pointer position (in float)
278 float cursX, cursY;
279 cursX = (float)x/(float)w;
280 cursY = (float)y/(float)h;
282 // Get the entities under position
283 bool isPlayerUnderCursor;
284 CEntityCL *entity;
285 entity= EntitiesMngr.getEntityUnderPos(cursX, cursY, ClientCfg.SelectionDist, isPlayerUnderCursor);
287 // If the mouse is over the player make the player transparent
288 CCDBNodeLeaf *pNL = s_UserCharFade ? &*s_UserCharFade
289 : &*(s_UserCharFade = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:USER_CHAR_FADE", false));
290 if ((pNL != NULL) && (pNL->getValue32() == 1) && UserEntity->selectable())
292 // If the nearest entity is the player, hide!
293 if (isPlayerUnderCursor)
294 UserEntity->makeTransparent(true);
295 else
296 UserEntity->makeTransparent(false);
298 else
299 UserEntity->makeTransparent(false);
301 // make transparent the entity under cursor?
302 if (ClientCfg.TransparentUnderCursor)
304 for (uint32 i = 1; i < 255; ++i)
306 CEntityCL *pE = EntitiesMngr.entity(i);
307 if (pE != NULL)
309 if (pE == entity)
310 pE->makeTransparent(true);
311 else
312 pE->makeTransparent(false);
317 // If there is an entity selected -> Set as the Target.
318 if(entity)
320 // Get the distance between the user and the entity.
321 float dist = (float)(entity->pos() - UserEntity->pos()).norm()-entity->box().getRadius();
322 // Entity Slot under the cursor.
323 SlotUnderCursor = entity->slot();
324 uint32 availablePrograms = (uint32)NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:TARGET:CONTEXT_MENU:PROGRAMMES")->getValue32();
325 bool entityAttackable = (availablePrograms&(1<<BOTCHATTYPE::Attackable)) || entity->properties().attackable();
326 if (ClientCfg.R2EDEnabled)
328 if (R2::getEditor().isDMing())
330 availablePrograms = 0;
331 entityAttackable = false;
334 // If the selection is not the entity under the cursor.
335 if(SlotUnderCursor != UserEntity->selection())
337 // If the user is fighting, clicking automatically attacks the new target
338 if( ClientCfg.AtkOnSelect && UserEntity->isFighting() && entityAttackable)
340 if(ContextCur.context("ATTACK"))
341 return;
343 // If the Entity is selectable -> select it.
344 else if(entity->properties().selectable())
346 if(ContextCur.context("SELECTABLE", dist))
347 return;
350 // Entity Under the cursor is the entity selected.
351 else
353 // Wait for the target is up to date. Do not display context cursor if the user is mounted.
354 if( (UserEntity->selection() == UserEntity->targetSlot()) &&
355 (! UserEntity->isRiding()) )
357 // Forage source
358 if ( entity->isForageSource() )
360 if( !UserEntity->isFighting() )
362 if(ContextCur.context("EXTRACT_RM"))
363 return;
366 // Alive
367 else if(entity->isDead()==false)
369 // Talk/Trade
370 // Mission Option of priority 3
371 if(testMissionOption(3))
372 return;
374 // other
375 if(availablePrograms)
377 // Static Mission
378 if(availablePrograms & (1 << BOTCHATTYPE::ChooseMissionFlag))
380 if(ContextCur.context("STATIC MISSION"))
381 return;
383 // Trade Item
384 else if (availablePrograms & (1 << BOTCHATTYPE::TradeItemFlag))
386 if(ContextCur.context("TRADE ITEM"))
387 return;
389 // Trade Phrase
390 else if(availablePrograms & (1 << BOTCHATTYPE::TradePhraseFlag))
392 if(ContextCur.context("TRADE PHRASE"))
393 return;
395 // Dynamic Mission
396 // else if(availablePrograms & (1 << BOTCHATTYPE::DynamicMissionFlag))
397 // {
398 // if(ContextCur.context("DYNAMIC MISSION"))
399 // return;
400 // }
401 // Trade Pact
402 else if(availablePrograms & (1 << BOTCHATTYPE::TradePactFlag))
404 if(ContextCur.context("TRADE PACT"))
405 return;
407 // Create Guild
408 else if(availablePrograms & (1 << BOTCHATTYPE::CreateGuildFlag))
410 if (!CGuildManager::getInstance()->isInGuild())
411 if(ContextCur.context("CREATE GUILD"))
412 return;
414 // News
415 else if(availablePrograms & (1 << BOTCHATTYPE::NewsFlag))
417 if(ContextCur.context("NEWS"))
418 return;
420 // Teleport
421 else if(availablePrograms & (1 << BOTCHATTYPE::TradeTeleportFlag))
423 if(ContextCur.context("TELEPORT"))
424 return;
426 // Faction Items
427 else if(availablePrograms & (1 << BOTCHATTYPE::TradeFactionFlag))
429 if(ContextCur.context("FACTION"))
430 return;
432 // Cosmetic
433 else if(availablePrograms & (1 << BOTCHATTYPE::TradeCosmeticFlag))
435 if(ContextCur.context("COSMETIC"))
436 return;
438 // WebPage
439 else if(availablePrograms & (1 << BOTCHATTYPE::WebPageFlag))
441 // get the web page title textID
442 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:TARGET:CONTEXT_MENU:WEB_PAGE_TITLE", false);
443 if(pNL && pNL->getValue32())
445 uint32 textID = pNL->getValue32();
447 // if the string is not received display a temp string
448 string webPageText;
449 if(!STRING_MANAGER::CStringManagerClient::instance()->getDynString(textID, webPageText))
450 webPageText = NLMISC::CI18N::get("uiWebPageNameNotReceived");
452 // display the cursor
453 if(ContextCur.context("WEB PAGE", 0.f, webPageText))
454 return;
457 // OutpostFlag
458 else if(availablePrograms & (1 << BOTCHATTYPE::OutpostFlag))
460 // get the outpost sheet
461 CCDBNodeLeaf *pNL = NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:TARGET:CONTEXT_MENU:OUTPOST", false);
462 if(pNL && pNL->getValue32())
464 // get the outpost name
465 CSheetId outpostSheet(pNL->getValue32());
466 string outpostName;
467 outpostName= STRING_MANAGER::CStringManagerClient::getOutpostLocalizedName(outpostSheet);
469 // display the cursor
470 if(ContextCur.context("OUTPOST", 0.f, outpostName))
471 return;
474 // Spire Totem
475 else if(availablePrograms & (1 << BOTCHATTYPE::Totem))
477 if(ContextCur.context("BUILD_TOTEM"))
478 return;
483 // test mission options of lesser priorities
484 if(testMissionOption(2))
485 return;
486 if(testMissionOption(1))
487 return;
489 // test ring mission
490 if(testMissionRing())
491 return;
493 // Attack
494 if (entityAttackable)
496 if(ContextCur.context("ATTACK"))
497 return;
500 if(testMissionOption(0))
501 return;
503 // Dead
504 else
506 if (!R2::getEditor().isDMing())
508 // Quartering
509 if((entity->properties()).harvestable())
511 if(ContextCur.context("QUARTER"))
512 return;
514 // Loot
515 else if((entity->properties()).lootable())
517 if(ContextCur.context("LOOT"))
518 return;
520 // Pick Up
521 else if((entity->properties()).liftable())
523 if(ContextCur.context("PICKUP"))
524 return;
529 if(entity->properties().selectable())
531 if(ContextCur.context("SELECTABLE", dist))
532 return;
537 else
539 sint32 instance_idx;
540 CShapeInstanceReference instref = EntitiesMngr.getShapeInstanceUnderPos(cursX, cursY, instance_idx);
542 std::vector<string> keys;
543 keys.push_back("colorize");
545 if (instance_idx != selectedInstance && selectedInstance != -1) {
546 std::vector<string> values;
547 values.push_back("0");
548 EntitiesMngr.setupInstance((uint32)selectedInstance, keys, values);
551 UInstance instance = instref.Instance;
552 if (!instance.empty() && !instref.ContextURL.empty())
555 selectedInstanceURL = instref.ContextURL;
556 if (instref.ContextText.empty())
558 if (instance_idx != -1) {
559 std::vector<string> values;
560 values.push_back("#FF0000FF");
561 EntitiesMngr.setupInstance((uint32)instance_idx, keys, values);
562 selectedInstance = instance_idx;
565 cursor->setCursor("r2ed_tool_select_move_over.tga");
566 InstanceId = instance_idx;
567 if (ContextCur.context("ARKITECT", 0.f, "Edit"))
568 return;
570 else
572 cursor->setCursor("curs_pick.tga");
573 string contextText = instref.ContextText;
574 if (ContextCur.context("WEBIG", 0.f, contextText))
575 return;
577 } else {
578 if (!selectedInstanceURL.empty()) {
579 cursor->setCursor("curs_default.tga");
580 selectedInstanceURL.clear();
584 SlotUnderCursor = CLFECOMMON::INVALID_SLOT;
587 else
589 if(UserEntity)
590 UserEntity->makeTransparent(false);
592 // Default Context.
593 ContextCur.context("STAND BY");
594 }// checkUnderCursor //
597 //-----------------------------------------------
598 // contextSelect :
599 // Select what is under the cursor.
600 // \Warning Be sure the checkUnderCursor and contextSelect are done after entites removed.
601 //-----------------------------------------------
602 void contextSelect(bool /* rightClick */, bool /* dblClick */)
604 // Push a message with the entity target (in slot).
605 if(SlotUnderCursor != CLFECOMMON::INVALID_SLOT)
607 // Select the entity
608 UserEntity->selection(SlotUnderCursor);
610 }// contextSelect //
612 //-----------------------------------------------
613 // contextAttack :
614 //-----------------------------------------------
615 void contextAttack(bool rightClick, bool dblClick)
617 if(rightClick)
618 return;
619 if( ClientCfg.DblClickMode && !dblClick)
620 return;
621 // Select the entity to target.
622 UserEntity->selection(SlotUnderCursor);
624 if( UserEntity->canEngageCombat() )
626 // Move to the current selection and attack.
627 UserEntity->moveToAttack();
629 }// contextAttack //
631 //-----------------------------------------------
632 // contextQuarter :
633 //-----------------------------------------------
634 void contextQuarter(bool rightClick, bool dblClick)
636 if(rightClick)
637 return;
638 if( ClientCfg.DblClickMode && !dblClick)
639 return;
640 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::Quarter);
641 }// contextQuarter //
643 //-----------------------------------------------
644 // contextLoot :
645 //-----------------------------------------------
646 void contextLoot(bool rightClick, bool dblClick)
648 if(rightClick)
649 return;
650 if( ClientCfg.DblClickMode && !dblClick)
651 return;
652 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::Loot);
653 }// contextLoot //
655 //-----------------------------------------------
656 // contextPickUp :
657 //-----------------------------------------------
658 void contextPickUp(bool rightClick, bool dblClick)
660 if(rightClick)
661 return;
662 if( ClientCfg.DblClickMode && !dblClick)
663 return;
664 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::PickUp);
665 }// contextPickUp //
667 //-----------------------------------------------
668 // contextTradeItem :
669 //-----------------------------------------------
670 void contextTradeItem(bool rightClick, bool dblClick)
672 if(rightClick)
673 return;
674 if( ClientCfg.DblClickMode && !dblClick)
675 return;
676 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::TradeItem);
677 }// contextTradeItem //
679 //-----------------------------------------------
680 // contextTradePhrase :
681 //-----------------------------------------------
682 void contextTradePhrase(bool rightClick, bool dblClick)
684 if(rightClick)
685 return;
686 if( ClientCfg.DblClickMode && !dblClick)
687 return;
688 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::TradePhrase);
689 }// contextTradePhrase //
691 //-----------------------------------------------
692 // contextDynamicMission :
693 //-----------------------------------------------
694 void contextDynamicMission(bool rightClick, bool dblClick)
696 if(rightClick)
697 return;
698 if( ClientCfg.DblClickMode && !dblClick)
699 return;
700 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::DynamicMission);
701 }// contextDynamicMission //
703 //-----------------------------------------------
704 // contextStaticMission :
705 //-----------------------------------------------
706 void contextStaticMission(bool rightClick, bool dblClick)
708 if(rightClick)
709 return;
710 if( ClientCfg.DblClickMode && !dblClick)
711 return;
712 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::StaticMission);
713 }// contextStaticMission //
715 //-----------------------------------------------
716 // contextTradePact :
717 //-----------------------------------------------
718 void contextTradePact(bool rightClick, bool dblClick)
720 if(rightClick)
721 return;
722 if( ClientCfg.DblClickMode && !dblClick)
723 return;
724 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::TradePact);
725 }// contextTradePact //
727 //-----------------------------------------------
728 // contextCreateGuild :
729 //-----------------------------------------------
730 void contextCreateGuild(bool rightClick, bool dblClick)
732 if(rightClick)
733 return;
734 if( ClientCfg.DblClickMode && !dblClick)
735 return;
736 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::CreateGuild);
737 }// contextCreateGuild //
739 //-----------------------------------------------
740 // contextNews :
741 //-----------------------------------------------
742 void contextNews(bool rightClick, bool dblClick)
744 if(rightClick)
745 return;
746 if( ClientCfg.DblClickMode && !dblClick)
747 return;
748 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::News);
749 }// contextNews //
751 //-----------------------------------------------
752 // contextTeleport :
753 //-----------------------------------------------
754 void contextTeleport(bool rightClick, bool dblClick)
756 if(rightClick)
757 return;
758 if( ClientCfg.DblClickMode && !dblClick)
759 return;
760 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::TradeTeleport);
761 }// contextTeleport //
763 //-----------------------------------------------
764 // contextFaction :
765 //-----------------------------------------------
766 void contextFaction(bool rightClick, bool dblClick)
768 if(rightClick)
769 return;
770 if( ClientCfg.DblClickMode && !dblClick)
771 return;
772 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::TradeFaction);
773 }// contextFaction //
775 //-----------------------------------------------
776 // contextCosmetic :
777 //-----------------------------------------------
778 void contextCosmetic(bool rightClick, bool dblClick)
780 if(rightClick)
781 return;
782 if( ClientCfg.DblClickMode && !dblClick)
783 return;
784 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::TradeCosmetic);
785 }// contextCosmetic //
787 //-----------------------------------------------
788 // contextTalk :
789 //-----------------------------------------------
790 void contextTalk(bool rightClick, bool dblClick)
792 if(rightClick)
793 return;
794 if( ClientCfg.DblClickMode && !dblClick)
795 return;
796 // Get the interface instace.
797 CInterfaceManager *IM = CInterfaceManager::getInstance();
798 if(IM == 0)
799 return;
800 // Get Entity Program
801 uint32 availablePrograms = (uint32)NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:TARGET:CONTEXT_MENU:PROGRAMMES")->getValue32();
802 // Static Mission
803 if(availablePrograms & (1 << BOTCHATTYPE::ChooseMissionFlag))
804 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::StaticMission);
805 // Trade Item
806 else if (availablePrograms & (1 << BOTCHATTYPE::TradeItemFlag))
807 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::TradeItem);
808 // Trade Phrase
809 else if(availablePrograms & (1 << BOTCHATTYPE::TradePhraseFlag))
810 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::TradePhrase);
811 // Dynamic Mission DEPRECATED
812 /* else if(availablePrograms & (1 << BOTCHATTYPE::DynamicMissionFlag))
813 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::DynamicMission);*/
815 // Trade Pact
816 else if(availablePrograms & (1 << BOTCHATTYPE::TradePactFlag))
817 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::TradePact);
818 // Create Guild
819 else if(availablePrograms & (1 << BOTCHATTYPE::CreateGuildFlag))
821 if (!CGuildManager::getInstance()->isInGuild())
822 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::CreateGuild);
824 // News
825 else if(availablePrograms & (1 << BOTCHATTYPE::NewsFlag))
826 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::Talk);
827 // Teleport
828 else if(availablePrograms & (1 << BOTCHATTYPE::TradeTeleportFlag))
829 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::TradeTeleport);
830 // Faction
831 else if(availablePrograms & (1 << BOTCHATTYPE::TradeFactionFlag))
832 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::TradeFaction);
833 // WebPage
834 else if(availablePrograms & (1 << BOTCHATTYPE::WebPageFlag))
835 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::WebPage);
836 // Outpost
837 else if(availablePrograms & (1 << BOTCHATTYPE::OutpostFlag))
838 UserEntity->moveTo(SlotUnderCursor, 2.0, CUserEntity::Outpost);
839 }// contextTalk //
842 //-----------------------------------------------
843 // contextExtractRM :
844 //-----------------------------------------------
845 void contextExtractRM(bool rightClick, bool dblClick)
847 if(rightClick)
848 return;
849 if( ClientCfg.DblClickMode && !dblClick)
850 return;
851 UserEntity->moveToExtractionPhrase(SlotUnderCursor, MaxExtractionDistance, std::numeric_limits<uint>::max(), std::numeric_limits<uint>::max(), true );
854 //-----------------------------------------------
855 // contextMission :
856 // Callback for dynamic missions
857 //-----------------------------------------------
858 void contextMission(bool rightClick, bool dblClick)
860 if(rightClick)
861 return;
862 if( ClientCfg.DblClickMode && !dblClick)
863 return;
864 UserEntity->moveToMission(SlotUnderCursor, 3.0, MissionId);
865 }// contextMission //
867 //-----------------------------------------------
868 // contextWebPage :
869 //-----------------------------------------------
870 void contextWebPage(bool rightClick, bool dblClick)
872 if(rightClick)
873 return;
874 if( ClientCfg.DblClickMode && !dblClick)
875 return;
876 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::WebPage);
877 }// contextWebPage //
879 //-----------------------------------------------
880 // contextWebIG :
881 //-----------------------------------------------
882 void contextWebIG(bool rightClick, bool dblClick)
884 CInterfaceManager *IM = CInterfaceManager::getInstance();
885 CInterfaceElement *pGC = CWidgetManager::getInstance()->getElementFromId("ui:interface:bot_chat_object");
886 CInterface3DShape *el= dynamic_cast<CInterface3DShape*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:bot_chat_object:scene3d:object_1"));
887 if (el != NULL)
889 //TODO: Fix that
890 //el->setName(selectedInstance.getShapeName());
891 el->setPosX(0.0f);
893 if (selectedInstanceURL.empty())
895 if (pGC != NULL)
896 pGC->setActive(true);
898 else
900 if (pGC != NULL)
901 pGC->setActive(false);
903 if (selectedInstanceURL.substr(0, 5) == "@LUA ")
905 string header = toString("doubleClick = %s\nrightClick = %s\nSelectedInstanceId = %u\n", dblClick?"true":"false", rightClick?"true":"false", InstanceId);
906 CLuaManager::getInstance().executeLuaScript(header+selectedInstanceURL.substr(5), true);
908 else
910 CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:webig:content:html|url="+selectedInstanceURL);
914 }// contextWebIG //
916 //-----------------------------------------------
917 // contextARKitect :
918 //-----------------------------------------------
919 void contextARKitect(bool rightClick, bool dblClick)
921 string header = toString("doubleClick = %s\nrightClick = %s\nSelectedInstanceId = %u\n", dblClick?"true":"false", rightClick?"true":"false", InstanceId);
923 CLuaManager::getInstance().executeLuaScript(header+selectedInstanceURL, true);
925 }// contextARKitect //
928 //-----------------------------------------------
929 // contextOutpost
930 //-----------------------------------------------
931 void contextOutpost(bool rightClick, bool dblClick)
933 if(rightClick)
934 return;
935 if( ClientCfg.DblClickMode && !dblClick)
936 return;
937 UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::Outpost);
938 }// contextOutpost //
940 //-----------------------------------------------
941 // contextRingMission
942 //-----------------------------------------------
943 void contextRingMission(bool rightClick, bool dblClick)
945 if(rightClick)
946 return;
947 if( ClientCfg.DblClickMode && !dblClick)
948 return;
949 UserEntity->moveToMissionRing(SlotUnderCursor, 3.0, MissionRingId);
950 }// contextRingMission //
952 //-----------------------------------------------
953 // contextBuildTotem :
954 //-----------------------------------------------
955 void contextBuildTotem(bool rightClick, bool dblClick)
957 if(rightClick)
958 return;
959 if( ClientCfg.DblClickMode && !dblClick)
960 return;
961 UserEntity->moveToTotemBuildingPhrase(SlotUnderCursor,MaxExtractionDistance, std::numeric_limits<uint>::max(), std::numeric_limits<uint>::max(), true );
962 }// contextBuildTotem //