Worx14

modmarkers.ws

Jun 14th, 2022
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 86.06 KB | None | 0 0
  1. //---=== modFriendlyHUD ===---
  2. struct SMod3DMarker
  3. {
  4. var visibleType : name; //map pin visible type
  5. var isDiscovered : bool; //is discovered
  6. var isKnown : bool; //is known
  7. var isDisabled : bool; //is disabled
  8. var isHighlighted : bool; //is active quest objective
  9. var isActiveQuest : bool; //is active quest
  10. var lvlDiff : EQuestLevel; //player - quest lvl diff
  11. var description : string; //map pin short description (quest name, merchant type, etc)
  12. var position : Vector; //map pin world position
  13. var distance : float; //distance from player
  14. var text : string; //text/icon to display
  15. //three oneliners per marker seems excessive, but it's the only way to avoid flickering
  16. var onelinerID : int; //oneliner ID
  17. var distOnelinerID : int; //distance text oneliner ID
  18. var descrOnelinerID : int; //description text oneliner ID
  19. var screenPosition : Vector; //screen position
  20. var onScreen : bool; //is on screen
  21. var offscreenText : string; //text/icon to display if offscreen
  22. //display conditions
  23. var force : bool; //force show marker (respects max distance, ignores visibility)
  24. var pin : bool; //pin marker (ignores max distance, respects visibility)
  25. };
  26.  
  27. enum EMarkersDisplayMode
  28. {
  29. MDM_WS,
  30. MDM_Always,
  31. MDM_Never
  32. };
  33.  
  34. enum EMarkersIconType
  35. {
  36. MIT_Icon,
  37. MIT_Icon_bw,
  38. MIT_Text,
  39. MIT_Text_bw
  40. };
  41.  
  42. enum EMarkersVisibility
  43. {
  44. MV_Show,
  45. MV_Hide,
  46. MV_Pin,
  47. MV_Force
  48. };
  49.  
  50. enum EQuestLevel
  51. {
  52. QL_NORMAL,
  53. QL_HIGH,
  54. QL_LOW
  55. };
  56.  
  57. //this event triggers when map pin entity gets changed, like noticeboard changing from full
  58. //to empty; undiscovered pin changing to discovered, etc.
  59. //it's not triggered when quest is activated/deactivated or when user map pin is added
  60. class CModMarkersListener extends IGlobalEventScriptedListener
  61. {
  62. event OnGlobalEventName( eventCategory : EGlobalEventCategory, eventType : EGlobalEventType, eventParam : name )
  63. {
  64. if( eventCategory == GetGlobalEventCategory( SEC_OnMapPinChanged ) )
  65. {
  66. //theGame.witcherLog.AddMessage( "OnMapPinChanged" );
  67. Mod3DMarkersSignalCache3DMarkers( true );
  68. }
  69. }
  70. }
  71.  
  72. class CModMarkers
  73. {
  74. var config : CModFriendlyHUDConfig;
  75. var hud : CR4ScriptedHud;
  76. var module : CR4HudModuleOneliners;
  77. var isGeralt : bool;
  78.  
  79. var bIconCurrentlyShown : bool; default bIconCurrentlyShown = false;
  80. var bAltTextCurrentlyShown : bool; default bAltTextCurrentlyShown = false;
  81. var bDescriptionCurrentlyShown : bool; default bDescriptionCurrentlyShown = false;
  82. var bDistanceCurrentlyShown : bool; default bDistanceCurrentlyShown = false;
  83. var bCompassCurrentlyShown : bool; default bCompassCurrentlyShown = false;
  84.  
  85. var isIconFadingOut : bool; default isIconFadingOut = false;
  86. var isDescriptionFadingOut : bool; default isDescriptionFadingOut = false;
  87. var isDistanceFadingOut : bool; default isDistanceFadingOut = false;
  88. var isCompassFadingOut : bool; default isCompassFadingOut = false;
  89.  
  90. var iconFadeOutTime : float;
  91. var descriptionFadeOutTime : float;
  92. var distanceFadeOutTime : float;
  93. var compassFadeOutTime : float;
  94.  
  95. var marginCenter : Vector;
  96. var marginLeftTop : Vector;
  97. var marginRightBottom : Vector;
  98.  
  99. var timeDelta : float;
  100. var markersAlpha : float;
  101.  
  102. var onelinersMaxID : int; default onelinersMaxID = -1;
  103. var prevOnelinersMaxID : int; default prevOnelinersMaxID = -1;
  104.  
  105. const var MARKERS_START_ID : int; default MARKERS_START_ID = 100500;
  106. const var MARKERS_END_ID : int; default MARKERS_END_ID = 100899;
  107. const var COMPASS_START_ID : int; default COMPASS_START_ID = 100900;
  108. const var COMPASS_END_ID : int; default COMPASS_END_ID = 100909;
  109.  
  110. var projOffset, descrOffset, distOffset : float;
  111.  
  112. var cached3DMarkersStatic : array< SMod3DMarker >;
  113. var cached3DMarkersDynamic : array< SMod3DMarker >;
  114. var cached3DMarkersTracked : array< SMod3DMarker >;
  115. var cachedQuestPins : array< SCommonMapPinInstance >;
  116. var cachedQuestLevels : array< EQuestLevel >;
  117. var cachedWorldPath : string;
  118. var cachedNumPins : int;
  119. var isDirty : bool; default isDirty = false;
  120. var cacheQuestPins : bool; default cacheQuestPins = false;
  121. var delayedCacheTime : float;
  122. var compassLocs : array< Vector >;
  123.  
  124.  
  125. public function Init()
  126. {
  127. isGeralt = (thePlayer == GetWitcherPlayer());
  128. config = GetFHUDConfig();
  129. hud = (CR4ScriptedHud)theGame.GetHud();
  130. module = (CR4HudModuleOneliners)(hud.GetHudModule( "OnelinersModule" ));
  131. marginCenter = hud.GetScaleformPoint( 0.5, 0.5 );
  132. marginLeftTop = hud.GetScaleformPoint( 0.01, 0.025 );
  133. marginRightBottom = hud.GetScaleformPoint( 1 - 0.01, 1 - 0.01 );
  134. theGame.GetGlobalEventsManager().AddListener( GetGlobalEventCategory( SEC_OnMapPinChanged ), new CModMarkersListener in this );
  135. //cache all markers
  136. cacheQuestPins = true;
  137. Cache3DMarkers();
  138. Cache3DMarkersTracked();
  139. //init compass marks
  140. FillCompassLocs();
  141. }
  142.  
  143. public function Update( dt : float )
  144. {
  145. if( !config )
  146. {
  147. Init();
  148. }
  149. timeDelta = dt;
  150. markersAlpha = 100 - config.markersTransparency;
  151. //theGame.witcherLog.AddMessage( "timeDelta = " + timeDelta );
  152. if( !theGame.GetGuiManager().IsAnyMenu() )
  153. {
  154. if( config.compassMarkersEnabled )
  155. {
  156. UpdateCompass();
  157. }
  158. else if( bCompassCurrentlyShown )
  159. {
  160. CleanupCompassOneliners();
  161. bCompassCurrentlyShown = false;
  162. }
  163. if( config.b3DMarkersEnabled )
  164. {
  165. Update3DMarkers();
  166. }
  167. else if ( prevOnelinersMaxID > -1 )
  168. {
  169. CleanupOneliners();
  170. bIconCurrentlyShown = false;
  171. bAltTextCurrentlyShown = false;
  172. bDescriptionCurrentlyShown = false;
  173. bDistanceCurrentlyShown = false;
  174. prevOnelinersMaxID = -1;
  175. }
  176. }
  177. }
  178.  
  179. public function IsValidID( ID : int ) : bool
  180. {
  181. return IsMarkerID( ID ) || IsCompassID( ID );
  182. }
  183.  
  184. function IsMarkerID( ID : int ) : bool
  185. {
  186. return ( ID >= MARKERS_START_ID && ID <= MARKERS_END_ID );
  187. }
  188.  
  189. function IsCompassID( ID : int ) : bool
  190. {
  191. return ( ID >= COMPASS_START_ID && ID <= COMPASS_END_ID );
  192. }
  193.  
  194. function CleanupOneliners()
  195. {
  196. var i : int;
  197. for( i = MARKERS_START_ID; i < prevOnelinersMaxID; i += 1 )
  198. module.FXRemoveOneliner( i );
  199. }
  200.  
  201. function CleanupCompassOneliners()
  202. {
  203. module.FXRemoveOneliner( COMPASS_START_ID );
  204. module.FXRemoveOneliner( COMPASS_START_ID + 1 );
  205. module.FXRemoveOneliner( COMPASS_START_ID + 2 );
  206. module.FXRemoveOneliner( COMPASS_START_ID + 3 );
  207. module.FXRemoveOneliner( COMPASS_START_ID + 4 );
  208. module.FXRemoveOneliner( COMPASS_START_ID + 5 );
  209. module.FXRemoveOneliner( COMPASS_START_ID + 6 );
  210. module.FXRemoveOneliner( COMPASS_START_ID + 7 );
  211. module.FXRemoveOneliner( COMPASS_START_ID + 8 );
  212. module.FXRemoveOneliner( COMPASS_START_ID + 9 );
  213. }
  214.  
  215. function ShouldShowIcon() : bool
  216. {
  217. if( config.forceShowMarkers || config.markerIconDisplayMode == MDM_Always ||
  218. config.markerIconDisplayMode == MDM_WS && theGame.GetFocusModeController().IsActive() )
  219. {
  220. isIconFadingOut = false;
  221. return true;
  222. }
  223. if( isIconFadingOut && iconFadeOutTime > 0 )
  224. {
  225. iconFadeOutTime -= timeDelta;
  226. return true;
  227. }
  228. if( bIconCurrentlyShown && !isIconFadingOut )
  229. {
  230. isIconFadingOut = true;
  231. iconFadeOutTime = config.markersFadeOutDelay;
  232. return true;
  233. }
  234. isIconFadingOut = false;
  235. return false;
  236. }
  237.  
  238. function ShouldShowDescription() : bool
  239. {
  240. if( config.forceShowMarkers || config.markerDescriptionDisplayMode == MDM_Always ||
  241. config.markerDescriptionDisplayMode == MDM_WS && theGame.GetFocusModeController().IsActive() )
  242. {
  243. isDescriptionFadingOut = false;
  244. return true;
  245. }
  246. if( isDescriptionFadingOut && descriptionFadeOutTime > 0 )
  247. {
  248. descriptionFadeOutTime -= timeDelta;
  249. return true;
  250. }
  251. if( bDescriptionCurrentlyShown && !isDescriptionFadingOut )
  252. {
  253. isDescriptionFadingOut = true;
  254. descriptionFadeOutTime = config.markersFadeOutDelay;
  255. return true;
  256. }
  257. isDescriptionFadingOut = false;
  258. return false;
  259. }
  260.  
  261. function ShouldShowDistance() : bool
  262. {
  263. if( config.forceShowMarkers || config.markerDistanceDisplayMode == MDM_Always ||
  264. config.markerDistanceDisplayMode == MDM_WS && theGame.GetFocusModeController().IsActive() )
  265. {
  266. isDistanceFadingOut = false;
  267. return true;
  268. }
  269. if( isDistanceFadingOut && distanceFadeOutTime > 0 )
  270. {
  271. distanceFadeOutTime -= timeDelta;
  272. return true;
  273. }
  274. if( bDistanceCurrentlyShown && !isDistanceFadingOut )
  275. {
  276. isDistanceFadingOut = true;
  277. distanceFadeOutTime = config.markersFadeOutDelay;
  278. return true;
  279. }
  280. isDistanceFadingOut = false;
  281. return false;
  282. }
  283.  
  284. function ShouldShowCompass() : bool
  285. {
  286. if( config.forceShowMarkers || config.markerCompassDisplayMode == MDM_Always ||
  287. config.markerCompassDisplayMode == MDM_WS && theGame.GetFocusModeController().IsActive() )
  288. {
  289. isCompassFadingOut = false;
  290. return true;
  291. }
  292. if( isCompassFadingOut && compassFadeOutTime > 0 )
  293. {
  294. compassFadeOutTime -= timeDelta;
  295. return true;
  296. }
  297. if( bCompassCurrentlyShown && !isCompassFadingOut )
  298. {
  299. isCompassFadingOut = true;
  300. compassFadeOutTime = config.markersFadeOutDelay;
  301. return true;
  302. }
  303. isCompassFadingOut = false;
  304. return false;
  305. }
  306.  
  307. //======================= update compass ==========================
  308.  
  309. function UpdateCompass()
  310. {
  311. var i : int;
  312.  
  313. if( ShouldShowCompass() )
  314. {
  315. for( i = 0; i <= 7; i += 1 )
  316. {
  317. UpdateCompassScreenPosition( COMPASS_START_ID + i );
  318. }
  319. bCompassCurrentlyShown = true;
  320. }
  321. else
  322. {
  323. CleanupCompassOneliners();
  324. bCompassCurrentlyShown = false;
  325. }
  326. }
  327.  
  328. function FillCompassLocs()
  329. {
  330. compassLocs.Resize(8);
  331. compassLocs[0].X -= 100; compassLocs[0].Y += 100; // NW
  332. compassLocs[1].Y += 100; // N
  333. compassLocs[2].X += 100; compassLocs[2].Y += 100; // NE
  334. compassLocs[3].X -= 100; // W
  335. compassLocs[4].X += 100; // E
  336. compassLocs[5].X -= 100; compassLocs[5].Y -= 100; // SW
  337. compassLocs[6].Y -= 100; // S
  338. compassLocs[7].X += 100; compassLocs[7].Y -= 100; // SE
  339. }
  340.  
  341. function GetCompassLoc( ID : int ) : Vector
  342. {
  343. return compassLocs[ID - COMPASS_START_ID] + thePlayer.GetWorldPosition();
  344. }
  345.  
  346. function GetLocHeading( ID : int ) : float
  347. {
  348. return VecHeading( compassLocs[ID - COMPASS_START_ID] );
  349. }
  350.  
  351. function UpdateCompassScreenPosition( ID : int )
  352. {
  353. var oppositeCamera : bool;
  354. var screenPos : Vector;
  355. var mcOneliner : CScriptedFlashSprite;
  356. var text : string;
  357. var camHeading : float = VecHeading( theCamera.GetCameraDirection() );
  358. var loc : Vector;
  359.  
  360. loc = GetCompassLoc( ID );
  361. text = GetCompassText( ID );
  362. oppositeCamera = GetScreenPosOpposite( screenPos, loc );
  363. screenPos.Y = (marginRightBottom.Y - marginLeftTop.Y) * config.compassScreenPosY;
  364. //marker is not visible normally
  365. if( text != "" && ( oppositeCamera || !IsInsideMargins( screenPos ) ) )
  366. {
  367. //icons only
  368. if( ( config.markerIconType == MIT_Icon || config.markerIconType == MIT_Icon_bw ) && AbsF( AngleDistance( camHeading, GetLocHeading( ID ) ) ) < 130 )
  369. {
  370. if( screenPos.X <= marginLeftTop.X || oppositeCamera && screenPos.X <= marginCenter.X )
  371. {
  372. text = "<img src=\"img://icons/quests/arrow_left.png\" width=\"" + GetArrowSize() + "\" height=\"" + GetIconSize() + "\">" + GetCompassIcon60( ID );
  373. screenPos.X = marginLeftTop.X + (GetIconSize() + GetArrowSize() )/2;
  374. }
  375. else if( screenPos.X >= marginRightBottom.X || oppositeCamera && screenPos.X >= marginCenter.X )
  376. {
  377. text = GetCompassIcon60( ID ) + "<img src=\"img://icons/quests/arrow_right.png\" width=\"" + GetArrowSize() + "\" height=\"" + GetIconSize() + "\">";
  378. screenPos.X = marginRightBottom.X - (GetIconSize() + GetArrowSize() )/2;
  379. }
  380. screenPos.Y -= 0.7*GetIconSize()/2;
  381. }
  382. else
  383. {
  384. text = "";
  385. }
  386. }
  387. mcOneliner = module.FXGetOneliner( ID );
  388. //if has something to display
  389. if( text != "" )
  390. {
  391. if( !mcOneliner || module.FXGetOnelinerText( ID ).GetTextHtml() != text )
  392. {
  393. module.FXRemoveOneliner( ID );
  394. module.FXCreateOneliner( text, ID );
  395. mcOneliner = module.FXGetOneliner( ID );
  396. }
  397. mcOneliner.SetPosition( screenPos.X, screenPos.Y );
  398. mcOneliner.SetVisible( true );
  399. if( isCompassFadingOut )
  400. mcOneliner.SetAlpha( markersAlpha * MaxF( 0, compassFadeOutTime / config.markersFadeOutDelay ) );
  401. else
  402. mcOneliner.SetAlpha( markersAlpha );
  403. }
  404. else
  405. {
  406. if( mcOneliner )
  407. mcOneliner.SetVisible( false );
  408. }
  409. }
  410.  
  411. //=========================== update markers ==========================
  412.  
  413. function Cache3DMarkersIfNeeded()
  414. {
  415. var commonMapManager : CCommonMapManager = theGame.GetCommonMapManager();
  416. var currentWorldPath : string = theGame.GetWorld().GetDepotPath();
  417. var mapPinInstances : array< SCommonMapPinInstance >;
  418. var isGeraltNow : bool;
  419.  
  420. isGeraltNow = (thePlayer == GetWitcherPlayer());
  421.  
  422. //if the player has changed
  423. if( isGeraltNow != isGeralt )
  424. {
  425. //theGame.witcherLog.AddMessage( "Player has changed." );
  426. Init();
  427. }
  428. else if( isDirty && delayedCacheTime - theGame.GetEngineTimeAsSeconds() <= 0 )
  429. {
  430. Cache3DMarkers();
  431. }
  432. else
  433. {
  434. mapPinInstances = commonMapManager.GetMapPinInstances( currentWorldPath );
  435. //if world path has changed or markers have changed
  436. if( mapPinInstances.Size() != cachedNumPins || currentWorldPath != cachedWorldPath )
  437. {
  438. //theGame.witcherLog.AddMessage( "Map pins changed, caching markers." );
  439. //if world path has changed, cache everything, if not - only cache map pin entities
  440. if( currentWorldPath != cachedWorldPath )
  441. cacheQuestPins = true;
  442. Cache3DMarkers();
  443. }
  444. }
  445. Cache3DMarkersTracked(); //always re-cache tracked quest markers to properly track moving objectives
  446. }
  447.  
  448. function Update3DMarkers()
  449. {
  450. Cache3DMarkersIfNeeded();
  451.  
  452. prevOnelinersMaxID = onelinersMaxID;
  453. onelinersMaxID = MARKERS_START_ID;
  454.  
  455. UpdateShownVars();
  456. InitOnelinersOffsets();
  457.  
  458. ProcessMarkers( cached3DMarkersStatic );
  459. ProcessMarkers( cached3DMarkersDynamic );
  460. ProcessMarkers( cached3DMarkersTracked );
  461. ProcessMarkers( SU_fhudPatchAddCustomMarkers(this) );
  462.  
  463. CleanupUnusedOneliners();
  464. }
  465.  
  466. function ProcessMarkers( markers : array< SMod3DMarker > )
  467. {
  468. var playerPosition : Vector = thePlayer.GetWorldPosition();
  469. var markersCount : int;
  470. var i : int;
  471. var marker : SMod3DMarker;
  472.  
  473. markersCount = markers.Size();
  474. for( i = 0; i < markersCount; i += 1 )
  475. {
  476. marker = markers[i];
  477. marker.distance = VecDistanceSquared( playerPosition, marker.position );
  478.  
  479. if( marker.distance < config.markerMinDistanceSquared )
  480. continue;
  481.  
  482. //if marker isn't pinned, check for max dist
  483. if( !marker.pin && marker.distance > config.markerMaxDistanceSquared )
  484. continue;
  485.  
  486. //is inside quest zone
  487. /*if( marker.isHighlighted && marker.distance < mapPin.visibleRadius )
  488. {
  489. CleanupCurrentOneliners();
  490. break;
  491. }*/
  492.  
  493. AdjustZLevel( marker );
  494. UpdateMarker( marker );
  495. }
  496. }
  497.  
  498. function AdjustZLevel( out marker : SMod3DMarker )
  499. {
  500. var playerPosition : Vector;
  501. playerPosition = thePlayer.GetWorldPosition();
  502.  
  503. switch( marker.visibleType )
  504. {
  505. case 'User1':
  506. case 'User2':
  507. case 'User3':
  508. case 'User4':
  509. playerPosition = thePlayer.GetWorldPosition();
  510. marker.position.Z = playerPosition.Z + 0.5;
  511. return;
  512. case 'MagicLamp':
  513. case 'HorseRaceTarget':
  514. case 'EnemyDead':
  515. case 'GenericFocus':
  516. marker.position.Z += 0.5;
  517. return;
  518. }
  519. marker.position.Z += 2.5;
  520. }
  521.  
  522. function CleanupCurrentOneliners()
  523. {
  524. var i : int;
  525. for( i = MARKERS_START_ID; i < onelinersMaxID; i += 1 )
  526. module.FXRemoveOneliner( i );
  527. bIconCurrentlyShown = false;
  528. bAltTextCurrentlyShown = false;
  529. bDescriptionCurrentlyShown = false;
  530. bDistanceCurrentlyShown = false;
  531. }
  532.  
  533. function CleanupUnusedOneliners()
  534. {
  535. var i : int;
  536. for( i = onelinersMaxID; i < prevOnelinersMaxID; i += 1 )
  537. module.FXRemoveOneliner( i );
  538. }
  539.  
  540. function UpdateShownVars()
  541. {
  542. if( ShouldShowIcon() )
  543. {
  544. bIconCurrentlyShown = true;
  545. bAltTextCurrentlyShown = ( config.markerIconType == MIT_Text || config.markerIconType == MIT_Text_bw );
  546. }
  547. else
  548. {
  549. bIconCurrentlyShown = false;
  550. bAltTextCurrentlyShown = false;
  551. }
  552. if( ShouldShowDescription() )
  553. bDescriptionCurrentlyShown = true;
  554. else
  555. bDescriptionCurrentlyShown = false;
  556. if( ShouldShowDistance() )
  557. bDistanceCurrentlyShown = true;
  558. else
  559. bDistanceCurrentlyShown = false;
  560. }
  561.  
  562. function UpdateMarker( out marker : SMod3DMarker )
  563. {
  564. var markerText : string = "";
  565. var markerDescrText : string = "";
  566. var markerDistanceText : string = "";
  567. var onelinerTextFlash : CScriptedFlashTextField;
  568. var mcOneliner : CScriptedFlashSprite;
  569.  
  570. /*markerText = "id: " + pin.id
  571. + " tag: " + pin.tag
  572. + " customNameId: " + pin.customNameId
  573. + " extraTag: " + pin.extraTag
  574. + " type: " + pin.type
  575. + " visibleType: " + pin.visibleType
  576. + " alternateVersion: " + pin.alternateVersion;*/
  577. //theGame.witcherLog.AddMessage("size = " + GetIconSize());
  578.  
  579. SetMarkerScreenPosition( marker );
  580.  
  581. if( bIconCurrentlyShown || marker.force )
  582. {
  583. if( marker.onScreen )
  584. markerText = marker.text;
  585. else
  586. markerText = marker.offscreenText;
  587. marker.onelinerID = onelinersMaxID;
  588. onelinersMaxID += 1;
  589. mcOneliner = module.FXGetOneliner( marker.onelinerID );
  590. if( mcOneliner )
  591. module.FXRemoveOneliner( marker.onelinerID );
  592. module.FXCreateOneliner( markerText, marker.onelinerID );
  593. }
  594. else
  595. {
  596. marker.onelinerID = 0;
  597. }
  598.  
  599. if( bDescriptionCurrentlyShown && marker.onScreen )
  600. {
  601. markerDescrText = marker.description;
  602. marker.descrOnelinerID = onelinersMaxID;
  603. onelinersMaxID += 1;
  604. mcOneliner = module.FXGetOneliner( marker.descrOnelinerID );
  605. if( mcOneliner )
  606. module.FXRemoveOneliner( marker.descrOnelinerID );
  607. module.FXCreateOneliner( markerDescrText, marker.descrOnelinerID );
  608. }
  609. else
  610. {
  611. marker.descrOnelinerID = 0;
  612. }
  613.  
  614. if( bDistanceCurrentlyShown && marker.onScreen )
  615. {
  616. markerDistanceText = GetMarkerDistanceText( marker );
  617. marker.distOnelinerID = onelinersMaxID;
  618. onelinersMaxID += 1;
  619. mcOneliner = module.FXGetOneliner( marker.distOnelinerID );
  620. if( mcOneliner )
  621. module.FXRemoveOneliner( marker.distOnelinerID );
  622. module.FXCreateOneliner( markerDistanceText, marker.distOnelinerID );
  623. }
  624. else
  625. {
  626. marker.distOnelinerID = 0;
  627. }
  628.  
  629. UpdateMarkerOneliner( marker );
  630. }
  631.  
  632. function SetMarkerScreenPosition( out marker : SMod3DMarker )
  633. {
  634. var shouldProject : bool;
  635. var noOppositeCamera : bool;
  636. var onScreen : bool;
  637. var screenPos : Vector;
  638.  
  639. shouldProject = config.compassMarkersEnabled && config.project3DMarkersOnCompass;
  640. noOppositeCamera = ( shouldProject || config.markerOnScreenOnly );
  641. onScreen = GetScreenPos( screenPos, marker.position, noOppositeCamera );
  642. marker.offscreenText = "";
  643. if( !IsInsideMargins( screenPos ) )
  644. onScreen = false;
  645. if( onScreen )
  646. {
  647. if( shouldProject )
  648. screenPos.Y = (marginRightBottom.Y - marginLeftTop.Y) * config.compassScreenPosY + projOffset;
  649. }
  650. else if( !noOppositeCamera )
  651. {
  652. if( screenPos.X <= marginLeftTop.X )
  653. {
  654. if( config.markerIconType == MIT_Icon || config.markerIconType == MIT_Icon_bw )
  655. {
  656. marker.offscreenText = "<img src=\"img://icons/quests/arrow_left.png\" width=\"" + GetArrowSize() + "\" height=\"" + GetIconSize() + "\">" + marker.text;
  657. screenPos.X = marginLeftTop.X + (GetIconSize() + GetArrowSize() )/2;
  658. }
  659. else
  660. {
  661. marker.offscreenText = "<font size=\"" + config.markersAltTextSize + "\">&lt;</font>" + marker.text;
  662. screenPos.X = marginLeftTop.X + config.markersAltTextSize;
  663. }
  664. }
  665. else if( screenPos.X >= marginRightBottom.X )
  666. {
  667. if( config.markerIconType == MIT_Icon || config.markerIconType == MIT_Icon_bw )
  668. {
  669. marker.offscreenText = marker.text + "<img src=\"img://icons/quests/arrow_right.png\" width=\"" + GetArrowSize() + "\" height=\"" + GetIconSize() + "\">";
  670. screenPos.X = marginRightBottom.X - (GetIconSize() + GetArrowSize() )/2;
  671. }
  672. else
  673. {
  674. marker.offscreenText = marker.text + "<font size=\"" + config.markersAltTextSize + "\">></font>";
  675. screenPos.X = marginRightBottom.X - config.markersAltTextSize;
  676. }
  677. }
  678. else if( screenPos.Y <= marginLeftTop.Y )
  679. {
  680. if( config.markerIconType == MIT_Icon || config.markerIconType == MIT_Icon_bw )
  681. {
  682. marker.offscreenText = "<img src=\"img://icons/quests/arrow_up.png\" width=\"" + GetArrowSize() + "\" height=\"" + GetArrowSize() + "\">" + "<br>" + marker.text;
  683. screenPos.Y = marginLeftTop.Y + GetIconSize();
  684. }
  685. else
  686. {
  687. marker.offscreenText = "<font size=\"" + config.markersAltTextSize + "\">^</font><br>" + marker.text;
  688. screenPos.Y = marginLeftTop.Y + 1.5 * config.markersAltTextSize;
  689. }
  690. }
  691. else
  692. {
  693. if( config.markerIconType == MIT_Icon || config.markerIconType == MIT_Icon_bw )
  694. {
  695. marker.offscreenText = marker.text + "<br>" + "<img src=\"img://icons/quests/arrow_down.png\" width=\"" + GetArrowSize() + "\" height=\"" + GetArrowSize() + "\">";
  696. screenPos.Y = marginRightBottom.Y;
  697. }
  698. else
  699. {
  700. marker.offscreenText = marker.text + "<br><font size=\"" + config.markersAltTextSize + "\">v</font>";
  701. screenPos.Y = marginRightBottom.Y;
  702. }
  703. }
  704. }
  705. marker.onScreen = onScreen;
  706. marker.screenPosition = screenPos;
  707. }
  708.  
  709. function UpdateMarkerOneliner( out marker : SMod3DMarker )
  710. {
  711. var noOppositeCamera : bool;
  712. var mcOneliner : CScriptedFlashSprite;
  713.  
  714. noOppositeCamera = ( config.compassMarkersEnabled && config.project3DMarkersOnCompass || config.markerOnScreenOnly );
  715. if( marker.onelinerID )
  716. {
  717. mcOneliner = module.FXGetOneliner( marker.onelinerID );
  718. if( marker.onScreen || !noOppositeCamera )
  719. {
  720. mcOneliner.SetPosition( marker.screenPosition.X, marker.screenPosition.Y );
  721. mcOneliner.SetVisible( true );
  722. if( isIconFadingOut && !marker.force )
  723. mcOneliner.SetAlpha( markersAlpha * MaxF( 0, iconFadeOutTime / config.markersFadeOutDelay ) );
  724. else
  725. mcOneliner.SetAlpha( markersAlpha );
  726. }
  727. else
  728. mcOneliner.SetVisible( false );
  729. }
  730. if( marker.descrOnelinerID )
  731. {
  732. mcOneliner = module.FXGetOneliner( marker.descrOnelinerID );
  733. if( marker.onScreen )
  734. {
  735. mcOneliner.SetPosition( marker.screenPosition.X, marker.screenPosition.Y + descrOffset );
  736. mcOneliner.SetVisible( true );
  737. if( isDescriptionFadingOut )
  738. mcOneliner.SetAlpha( markersAlpha * MaxF( 0, descriptionFadeOutTime / config.markersFadeOutDelay ) );
  739. else
  740. mcOneliner.SetAlpha( markersAlpha );
  741. }
  742. else
  743. mcOneliner.SetVisible( false );
  744. }
  745. if( marker.distOnelinerID )
  746. {
  747. mcOneliner = module.FXGetOneliner( marker.distOnelinerID );
  748. if( marker.onScreen )
  749. {
  750. mcOneliner.SetPosition( marker.screenPosition.X, marker.screenPosition.Y - distOffset );
  751. mcOneliner.SetVisible( true );
  752. if( isDistanceFadingOut )
  753. mcOneliner.SetAlpha( markersAlpha * MaxF( 0, distanceFadeOutTime / config.markersFadeOutDelay ) );
  754. else
  755. mcOneliner.SetAlpha( markersAlpha );
  756. }
  757. else
  758. mcOneliner.SetVisible( false );
  759. }
  760. }
  761.  
  762. function IsInsideMargins( screenPos : Vector ) : bool
  763. {
  764. if( screenPos.X < marginLeftTop.X || screenPos.X > marginRightBottom.X ||
  765. screenPos.Y < marginLeftTop.Y || screenPos.Y > marginRightBottom.Y )
  766. return false;
  767. else
  768. return true;
  769. }
  770.  
  771. function GetScreenPos( out screenPos : Vector, worldPos : Vector, optional noOppositeCamera : bool ) : bool
  772. {
  773. if( !theCamera.WorldVectorToViewRatio( worldPos, screenPos.X, screenPos.Y ) )
  774. {
  775. if( noOppositeCamera )
  776. return false;
  777. GetOppositeCameraScreenPos( worldPos, screenPos.X, screenPos.Y );
  778. }
  779. screenPos.X = ( screenPos.X + 1 ) / 2;
  780. screenPos.Y = ( screenPos.Y + 1 ) / 2;
  781. screenPos = hud.GetScaleformPoint( screenPos.X, screenPos.Y );
  782. var camera_rotation: EulerAngles;
  783. var rotation: EulerAngles;
  784. var x: float;
  785. var y: float;
  786. var pitch: float;
  787.  
  788. // we get the normalized X coordinates [0;1] from the angle between the
  789. // camera heading and the heading toward the pin.
  790. x = AngleDistance(
  791. theCamera.GetCameraHeading(),
  792. VecHeading(worldPos - theCamera.GetCameraPosition())
  793. ) / 90 + 0.5;
  794.  
  795. camera_rotation = theCamera.GetCameraRotation();
  796.  
  797. rotation = VecToRotation(
  798. worldPos - theCamera.GetCameraPosition()
  799. );
  800.  
  801. y = AngleDistance(
  802. camera_rotation.Pitch,
  803. rotation.Pitch
  804. ) / 75 + 0.5;
  805.  
  806. screenPos = hud.GetScaleformPoint( x, y );
  807.  
  808. return true;
  809. }
  810.  
  811. function GetScreenPosOpposite( out screenPos : Vector, worldPos : Vector ) : bool
  812. {
  813. var oppositeCamera : bool = false;
  814.  
  815. if( !theCamera.WorldVectorToViewRatio( worldPos, screenPos.X, screenPos.Y ) )
  816. {
  817. oppositeCamera = true;
  818. GetOppositeCameraScreenPos( worldPos, screenPos.X, screenPos.Y );
  819. }
  820. screenPos.X = ( screenPos.X + 1 ) / 2;
  821. screenPos.Y = ( screenPos.Y + 1 ) / 2;
  822. screenPos = hud.GetScaleformPoint( screenPos.X, screenPos.Y );
  823. return oppositeCamera;
  824. }
  825.  
  826. //======================= positioning ======================
  827.  
  828. function InitOnelinersOffsets()
  829. {
  830. projOffset = GetProjOffsetY();
  831. descrOffset = GetDescrOnelinerOffset();
  832. distOffset = GetDistanceOnelinerOffset();
  833. }
  834.  
  835. function GetProjOffsetY() : float
  836. {
  837. var z : float = 0;
  838.  
  839. if( bAltTextCurrentlyShown )
  840. z = config.markersAltTextSize;
  841. else if( bIconCurrentlyShown )
  842. z = GetIconSize();
  843. else if( bDistanceCurrentlyShown )
  844. z = config.markersDistanceTextSize;
  845. else if( bDescriptionCurrentlyShown )
  846. z = config.markersDescriptionTextSize;
  847. if( config.markerIconType == MIT_Icon || config.markerIconType == MIT_Icon_bw )
  848. z = (z - GetCompassIconSize())/2;
  849. else
  850. z = (z - config.markersAltTextSize)/2;
  851.  
  852. return z;
  853. }
  854.  
  855. function GetDescrOnelinerOffset() : float
  856. {
  857. var z : float = 0;
  858.  
  859. z = config.markersDescriptionTextSize;
  860. if( bIconCurrentlyShown || bDistanceCurrentlyShown )
  861. z += 5;
  862.  
  863. return z;
  864. }
  865.  
  866. function GetDistanceOnelinerOffset() : float
  867. {
  868. var z : float = 0;
  869.  
  870. if( bAltTextCurrentlyShown )
  871. z += config.markersAltTextSize + 5;
  872. else if( bIconCurrentlyShown )
  873. z += GetIconSize() + 5;
  874.  
  875. return z;
  876. }
  877.  
  878. //========================= font/size ===========================
  879.  
  880. function GetCompassIconSize() : int
  881. {
  882. return 102 * config.markersIconSizePrc / 100;
  883. }
  884.  
  885. function GetArrowSize() : int
  886. {
  887. return 30 * config.markersIconSizePrc / 100;
  888. }
  889.  
  890. function GetIconSize() : int
  891. {
  892. return 60 * config.markersIconSizePrc / 100;
  893. }
  894.  
  895. function GetDistanceFont() : string
  896. {
  897. return " size=\"" + config.markersDistanceTextSize + "\" ";
  898. }
  899.  
  900. function GetDescriptionFont() : string
  901. {
  902. return " size=\"" + config.markersDescriptionTextSize + "\" ";
  903. }
  904.  
  905. function GetCompassFont() : string
  906. {
  907. return " face=\"$BoldFont\" color=\"#008000\" size=\"" + config.markersAltTextSize + "\" ";
  908. }
  909.  
  910. function GetMarkerDistanceText( marker : SMod3DMarker ) : string
  911. {
  912. return "<font" + GetDistanceFont() + ">" + FloatToStringPrec( FloorF( SqrtF( marker.distance ) ), 0 ) + "</font>";
  913. }
  914.  
  915. //===================== icon/alt text =========================
  916.  
  917. function GetCompassText( ID : int ) : string
  918. {
  919. switch( config.markerIconType )
  920. {
  921. case MIT_Icon:
  922. case MIT_Icon_bw:
  923. return GetCompassIcon( ID );
  924. case MIT_Text:
  925. case MIT_Text_bw:
  926. return GetCompassAltText( ID );
  927. }
  928. return "";
  929. }
  930.  
  931. function GetCompassIcon( ID : int ) : string
  932. {
  933. ID -= COMPASS_START_ID;
  934.  
  935. switch( ID )
  936. {
  937. case 0:
  938. return "";
  939. case 1:
  940. return "<img src=\"img://icons/quests/compass_N.png\" width=\"" + GetCompassIconSize() + "\" height=\"" + GetCompassIconSize() + "\">";
  941. case 2:
  942. return "";
  943. case 3:
  944. return "<img src=\"img://icons/quests/compass_W.png\" width=\"" + GetCompassIconSize() + "\" height=\"" + GetCompassIconSize() + "\">";
  945. case 4:
  946. return "<img src=\"img://icons/quests/compass_E.png\" width=\"" + GetCompassIconSize() + "\" height=\"" + GetCompassIconSize() + "\">";
  947. case 5:
  948. return "";
  949. case 6:
  950. return "<img src=\"img://icons/quests/compass_S.png\" width=\"" + GetCompassIconSize() + "\" height=\"" + GetCompassIconSize() + "\">";
  951. case 7:
  952. return "";
  953. }
  954. return "";
  955. }
  956.  
  957. function GetCompassIcon60( ID : int ) : string
  958. {
  959. ID -= COMPASS_START_ID;
  960.  
  961. switch( ID )
  962. {
  963. case 0:
  964. return "";
  965. case 1:
  966. return "<img src=\"img://icons/quests/compass_N_60.png\" width=\"" + GetIconSize() + "\" height=\"" + GetIconSize() + "\">";
  967. case 2:
  968. return "";
  969. case 3:
  970. return "<img src=\"img://icons/quests/compass_W_60.png\" width=\"" + GetIconSize() + "\" height=\"" + GetIconSize() + "\">";
  971. case 4:
  972. return "<img src=\"img://icons/quests/compass_E_60.png\" width=\"" + GetIconSize() + "\" height=\"" + GetIconSize() + "\">";
  973. case 5:
  974. return "";
  975. case 6:
  976. return "<img src=\"img://icons/quests/compass_S_60.png\" width=\"" + GetIconSize() + "\" height=\"" + GetIconSize() + "\">";
  977. case 7:
  978. return "";
  979. }
  980. return "";
  981. }
  982.  
  983. function GetCompassAltText( ID : int ) : string
  984. {
  985. ID -= COMPASS_START_ID;
  986.  
  987. switch( ID )
  988. {
  989. case 0:
  990. return "<font" + GetCompassFont() + ">NW</font>";
  991. case 1:
  992. return "<font" + GetCompassFont() + ">N</font>";
  993. case 2:
  994. return "<font" + GetCompassFont() + ">NE</font>";
  995. case 3:
  996. return "<font" + GetCompassFont() + ">W</font>";
  997. case 4:
  998. return "<font" + GetCompassFont() + ">E</font>";
  999. case 5:
  1000. return "<font" + GetCompassFont() + ">SW</font>";
  1001. case 6:
  1002. return "<font" + GetCompassFont() + ">S</font>";
  1003. case 7:
  1004. return "<font" + GetCompassFont() + ">SE</font>";
  1005. }
  1006. return "";
  1007. }
  1008.  
  1009. function GetMarkerIconByType( marker : SMod3DMarker ) : string
  1010. {
  1011. switch( config.markerIconType )
  1012. {
  1013. case MIT_Icon:
  1014. return GetMarkerIcon( marker );
  1015. case MIT_Icon_bw:
  1016. return GetMarkerIconBW( marker );
  1017. case MIT_Text:
  1018. return GetMarkerAltText( marker );
  1019. case MIT_Text_bw:
  1020. return GetMarkerAltTextBW( marker );
  1021. default:
  1022. return "";
  1023. }
  1024. }
  1025.  
  1026. function GetQuestIconByLevel( marker : SMod3DMarker ) : string
  1027. {
  1028. switch( marker.lvlDiff )
  1029. {
  1030. case QL_NORMAL:
  1031. return "\"img://icons/quests/quest_tracked_green.png\"";
  1032. case QL_HIGH:
  1033. return "\"img://icons/quests/quest_tracked_red.png\"";
  1034. case QL_LOW:
  1035. return "\"img://icons/quests/quest_tracked_gray.png\"";
  1036. }
  1037. return "\"img://icons/quests/quest_tracked_white.png\"";
  1038. }
  1039.  
  1040. function GetMarkerIcon( marker : SMod3DMarker ) : string
  1041. {
  1042. var iconPath : string;
  1043.  
  1044. if( marker.isActiveQuest )
  1045. {
  1046. if( marker.isHighlighted )
  1047. iconPath = "<img src=\"img://icons/quests/quest_tracked_orange.png\"";
  1048. else
  1049. iconPath = "<img src=\"img://icons/quests/quest_tracked_orange_sub.png\"";
  1050. }
  1051. else
  1052. {
  1053. switch( marker.visibleType )
  1054. {
  1055. //quests
  1056. case 'QuestReturn':
  1057. iconPath = "<img src=\"img://icons/quests/quest_question_yellow.png\"";
  1058. break;
  1059. case 'MonsterQuest':
  1060. iconPath = "<img src=\"img://icons/quests/quest_monsterhunt.png\"";
  1061. break;
  1062. case 'TreasureQuest':
  1063. iconPath = "<img src=\"img://icons/quests/quest_treasure.png\"";
  1064. break;
  1065. case 'StoryQuest':
  1066. case 'ChapterQuest':
  1067. case 'SideQuest':
  1068. iconPath = "<img src=" + GetQuestIconByLevel( marker );
  1069. break;
  1070. case 'QuestAvailable':
  1071. iconPath = "<img src=\"img://icons/quests/quest_exclamation_yellow.png\"";
  1072. break;
  1073. case 'QuestAvailableHoS':
  1074. iconPath = "<img src=\"img://icons/quests/quest_exclamation_blue.png\"";
  1075. break;
  1076. case 'QuestAvailableBaW':
  1077. case 'QuestBelgard':
  1078. case 'QuestCoronata':
  1079. case 'QuestVermentino':
  1080. iconPath = "<img src=\"img://icons/quests/quest_exclamation_orange.png\"";
  1081. break;
  1082. case 'HorseRace':
  1083. case 'BoatRace':
  1084. iconPath = "<img src=\"img://icons/quests/quest_horse_race.png\"";
  1085. break;
  1086. //utility signs
  1087. case 'User1':
  1088. iconPath = "<img src=\"img://icons/quests/user1.png\"";
  1089. break;
  1090. case 'User2':
  1091. iconPath = "<img src=\"img://icons/quests/user2.png\"";
  1092. break;
  1093. case 'User3':
  1094. iconPath = "<img src=\"img://icons/quests/user3.png\"";
  1095. break;
  1096. case 'User4':
  1097. iconPath = "<img src=\"img://icons/quests/user4.png\"";
  1098. break;
  1099. case 'Horse':
  1100. iconPath = "<img src=\"img://icons/quests/roach.png\"";
  1101. break;
  1102. case 'Boat':
  1103. iconPath = "<img src=\"img://icons/quests/boat.png\"";
  1104. break;
  1105. case 'RoadSign':
  1106. iconPath = "<img src=\"img://icons/quests/road_sign.png\"";
  1107. break;
  1108. case 'Harbor':
  1109. iconPath = "<img src=\"img://icons/quests/harbor.png\"";
  1110. break;
  1111. case 'Entrance':
  1112. iconPath = "<img src=\"img://icons/quests/cave_entrance.png\"";
  1113. break;
  1114. case 'NoticeBoard':
  1115. iconPath = "<img src=\"img://icons/quests/noticeboard_white.png\"";
  1116. break;
  1117. case 'NoticeBoardFull':
  1118. iconPath = "<img src=\"img://icons/quests/noticeboard_quest.png\"";
  1119. break;
  1120. case 'Whetstone':
  1121. iconPath = "<img src=\"img://icons/quests/whetstone.png\"";
  1122. break;
  1123. case 'ArmorRepairTable':
  1124. iconPath = "<img src=\"img://icons/quests/armor_repair_table.png\"";
  1125. break;
  1126. case 'WitcherHouse':
  1127. iconPath = "<img src=\"img://icons/quests/witcher_house.png\"";
  1128. break;
  1129. case 'AlchemyTable':
  1130. iconPath = "<img src=\"img://icons/quests/alchemy_table.png\"";
  1131. break;
  1132. case 'MutagenDismantle':
  1133. iconPath = "<img src=\"img://icons/quests/mutagen_dismantle.png\"";
  1134. break;
  1135. case 'Stables':
  1136. iconPath = "<img src=\"img://icons/quests/stables.png\"";
  1137. break;
  1138. case 'Bookshelf':
  1139. iconPath = "<img src=\"img://icons/quests/bookshelf.png\"";
  1140. break;
  1141. case 'Bed':
  1142. iconPath = "<img src=\"img://icons/quests/bed.png\"";
  1143. break;
  1144. case 'PlayerStash':
  1145. case 'PlayerStashDiscoverable':
  1146. iconPath = "<img src=\"img://icons/quests/player_stash.png\"";
  1147. break;
  1148. //NPCs
  1149. case 'Cammerlengo':
  1150. iconPath = "<img src=\"img://icons/quests/cammerlengo.png\"";
  1151. break;
  1152. case 'DyeMerchant':
  1153. iconPath = "<img src=\"img://icons/quests/dye_merchant.png\"";
  1154. break;
  1155. case 'WineMerchant':
  1156. iconPath = "<img src=\"img://icons/quests/wine_merchant.png\"";
  1157. break;
  1158. case 'Shopkeeper':
  1159. iconPath = "<img src=\"img://icons/quests/shopkeeper.png\"";
  1160. break;
  1161. case 'Blacksmith':
  1162. iconPath = "<img src=\"img://icons/quests/blacksmith.png\"";
  1163. break;
  1164. case 'Armorer':
  1165. iconPath = "<img src=\"img://icons/quests/armorer.png\"";
  1166. break;
  1167. case 'Archmaster':
  1168. iconPath = "<img src=\"img://icons/quests/archmaster.png\"";
  1169. break;
  1170. case 'Hairdresser':
  1171. iconPath = "<img src=\"img://icons/quests/hairdresser.png\"";
  1172. break;
  1173. case 'Alchemic':
  1174. iconPath = "<img src=\"img://icons/quests/alchemist.png\"";
  1175. break;
  1176. case 'Herbalist':
  1177. iconPath = "<img src=\"img://icons/quests/herbalist.png\"";
  1178. break;
  1179. case 'Innkeeper':
  1180. iconPath = "<img src=\"img://icons/quests/innkeeper.png\"";
  1181. break;
  1182. case 'Enchanter':
  1183. iconPath = "<img src=\"img://icons/quests/enchanter.png\"";
  1184. break;
  1185. case 'Torch':
  1186. iconPath = "<img src=\"img://icons/quests/torch.png\"";
  1187. break;
  1188. case 'Prostitute':
  1189. iconPath = "<img src=\"img://icons/quests/prostitute.png\"";
  1190. break;
  1191. //POIs
  1192. case 'NotDiscoveredPOI':
  1193. iconPath = "<img src=\"img://icons/quests/quest_question_white.png\"";
  1194. break;
  1195. case 'MonsterNest':
  1196. iconPath = "<img src=\"img://icons/quests/monster_nest.png\"";
  1197. break;
  1198. case 'MonsterNestDisabled':
  1199. iconPath = "<img src=\"img://icons/quests/monster_nest_disabled.png\"";
  1200. break;
  1201. case 'InfestedVineyard':
  1202. iconPath = "<img src=\"img://icons/quests/infested_vineyard.png\"";
  1203. break;
  1204. case 'InfestedVineyardDisabled':
  1205. iconPath = "<img src=\"img://icons/quests/infested_vineyard_disabled.png\"";
  1206. break;
  1207. case 'PlaceOfPower':
  1208. iconPath = "<img src=\"img://icons/quests/place_of_power.png\"";
  1209. break;
  1210. case 'PlaceOfPowerDisabled':
  1211. iconPath = "<img src=\"img://icons/quests/place_of_power_disabled.png\"";
  1212. break;
  1213. case 'TreasureHuntMappin':
  1214. iconPath = "<img src=\"img://icons/quests/quest_treasure.png\"";
  1215. break;
  1216. case 'TreasureHuntMappinDisabled':
  1217. iconPath = "<img src=\"img://icons/quests/quest_treasure_disabled.png\"";
  1218. break;
  1219. case 'SpoilsOfWar':
  1220. iconPath = "<img src=\"img://icons/quests/spoils_of_war.png\"";
  1221. break;
  1222. case 'SpoilsOfWarDisabled':
  1223. iconPath = "<img src=\"img://icons/quests/spoils_of_war_disabled.png\"";
  1224. break;
  1225. case 'BanditCamp':
  1226. iconPath = "<img src=\"img://icons/quests/person_in_distress.png\"";
  1227. break;
  1228. case 'BanditCampDisabled':
  1229. iconPath = "<img src=\"img://icons/quests/person_in_distress_disabled.png\"";
  1230. break;
  1231. case 'BanditCampfire':
  1232. iconPath = "<img src=\"img://icons/quests/bandit_camp.png\"";
  1233. break;
  1234. case 'BanditCampfireDisabled':
  1235. iconPath = "<img src=\"img://icons/quests/bandit_camp_disabled.png\"";
  1236. break;
  1237. case 'BossAndTreasure':
  1238. iconPath = "<img src=\"img://icons/quests/guarded_treasure.png\"";
  1239. break;
  1240. case 'BossAndTreasureDisabled':
  1241. iconPath = "<img src=\"img://icons/quests/guarded_treasure_disabled.png\"";
  1242. break;
  1243. case 'Contraband':
  1244. case 'ContrabandShip':
  1245. iconPath = "<img src=\"img://icons/quests/contraband.png\"";
  1246. break;
  1247. case 'ContrabandDisabled':
  1248. case 'ContrabandShipDisabled':
  1249. iconPath = "<img src=\"img://icons/quests/contraband_disabled.png\"";
  1250. break;
  1251. case 'RescuingTown':
  1252. iconPath = "<img src=\"img://icons/quests/rescuing_town.png\"";
  1253. break;
  1254. case 'RescuingTownDisabled':
  1255. iconPath = "<img src=\"img://icons/quests/rescuing_town_disabled.png\"";
  1256. break;
  1257. case 'DungeonCrawl':
  1258. iconPath = "<img src=\"img://icons/quests/dungeon_crawl.png\"";
  1259. break;
  1260. case 'DungeonCrawlDisabled':
  1261. iconPath = "<img src=\"img://icons/quests/dungeon_crawl_disabled.png\"";
  1262. break;
  1263. case 'Hideout':
  1264. iconPath = "<img src=\"img://icons/quests/hansa_hideout.png\"";
  1265. break;
  1266. case 'HideoutDisabled':
  1267. iconPath = "<img src=\"img://icons/quests/hansa_hideout_disabled.png\"";
  1268. break;
  1269. case 'Plegmund':
  1270. iconPath = "<img src=\"img://icons/quests/lebjoda_statue.png\"";
  1271. break;
  1272. case 'PlegmundDisabled':
  1273. iconPath = "<img src=\"img://icons/quests/lebjoda_statue_disabled.png\"";
  1274. break;
  1275. case 'KnightErrant':
  1276. iconPath = "<img src=\"img://icons/quests/knight_errand.png\"";
  1277. break;
  1278. case 'KnightErrantDisabled':
  1279. iconPath = "<img src=\"img://icons/quests/knight_errand_disabled.png\"";
  1280. break;
  1281. case 'WineContract':
  1282. iconPath = "<img src=\"img://icons/quests/wine_contract.png\"";
  1283. break;
  1284. case 'WineContractDisabled':
  1285. iconPath = "<img src=\"img://icons/quests/wine_contract_disabled.png\"";
  1286. break;
  1287. case 'SignalingStake':
  1288. iconPath = "<img src=\"img://icons/quests/bandit_campfire.png\"";
  1289. break;
  1290. case 'SignalingStakeDisabled':
  1291. iconPath = "<img src=\"img://icons/quests/bandit_campfire_disabled.png\"";
  1292. break;
  1293. //misc
  1294. case 'Rift':
  1295. case 'Teleport':
  1296. iconPath = "<img src=\"img://icons/quests/teleport.png\"";
  1297. break;
  1298. case 'MagicLamp':
  1299. iconPath = "<img src=\"img://icons/quests/magic_lamp.png\"";
  1300. break;
  1301. case 'HorseRaceTarget':
  1302. iconPath = "<img src=\"img://icons/quests/horse_race_target.png\"";
  1303. break;
  1304. case 'HorseRaceDummy':
  1305. iconPath = "<img src=\"img://icons/quests/horse_race_dummy.png\"";
  1306. break;
  1307. case 'Herb':
  1308. iconPath = "<img src=\"img://icons/quests/herb.png\"";
  1309. break;
  1310. case 'Enemy':
  1311. iconPath = "<img src=\"img://icons/quests/enemy.png\"";
  1312. break;
  1313. case 'EnemyDead':
  1314. iconPath = "<img src=\"img://icons/quests/dead_body.png\"";
  1315. break;
  1316. case 'GenericFocus':
  1317. iconPath = "<img src=\"img://icons/quests/ws_clue.png\"";
  1318. break;
  1319. default:
  1320. iconPath = "<img src=\"img://icons/quests/quest_question_white.png\"";
  1321. break;
  1322. }
  1323. }
  1324. iconPath += " width=\"" + GetIconSize() + "\" height=\"" + GetIconSize() + "\">";
  1325. return iconPath;
  1326. }
  1327.  
  1328. function GetMarkerIconBW( marker : SMod3DMarker ) : string
  1329. {
  1330. var iconPath : string;
  1331.  
  1332. if( marker.isActiveQuest )
  1333. {
  1334. //if( marker.isHighlighted )
  1335. iconPath = "<img src=\"img://icons/quests/quest_tracked_white.png\"";
  1336. //else
  1337. // iconPath = "<img src=\"img://icons/quests/quest_tracked_white.png\"";
  1338. }
  1339. else
  1340. {
  1341. switch( marker.visibleType )
  1342. {
  1343. //quests
  1344. case 'QuestReturn':
  1345. iconPath = "<img src=\"img://icons/quests/quest_tracked_white.png\"";
  1346. break;
  1347. case 'MonsterQuest':
  1348. iconPath = "<img src=\"img://icons/quests/quest_monsterhunt_white.png\"";
  1349. break;
  1350. case 'TreasureQuest':
  1351. iconPath = "<img src=\"img://icons/quests/quest_treasure_white.png\"";
  1352. break;
  1353. case 'StoryQuest':
  1354. case 'ChapterQuest':
  1355. case 'SideQuest':
  1356. iconPath = "<img src=\"img://icons/quests/quest_tracked_gray.png\"";
  1357. break;
  1358. case 'QuestAvailable':
  1359. case 'QuestAvailableHoS':
  1360. case 'QuestAvailableBaW':
  1361. case 'QuestBelgard':
  1362. case 'QuestCoronata':
  1363. case 'QuestVermentino':
  1364. iconPath = "<img src=\"img://icons/quests/quest_exclamation_white.png\"";
  1365. break;
  1366. case 'HorseRace':
  1367. case 'BoatRace':
  1368. iconPath = "<img src=\"img://icons/quests/quest_horse_race_white.png\"";
  1369. break;
  1370. //utility signs
  1371. case 'User1':
  1372. iconPath = "<img src=\"img://icons/quests/user1_white.png\"";
  1373. break;
  1374. case 'User2':
  1375. iconPath = "<img src=\"img://icons/quests/user2_white.png\"";
  1376. break;
  1377. case 'User3':
  1378. iconPath = "<img src=\"img://icons/quests/user3_white.png\"";
  1379. break;
  1380. case 'User4':
  1381. iconPath = "<img src=\"img://icons/quests/user4_white.png\"";
  1382. break;
  1383. case 'Horse':
  1384. iconPath = "<img src=\"img://icons/quests/roach_white.png\"";
  1385. break;
  1386. case 'Boat':
  1387. iconPath = "<img src=\"img://icons/quests/boat_white.png\"";
  1388. break;
  1389. case 'RoadSign':
  1390. iconPath = "<img src=\"img://icons/quests/road_sign_white.png\"";
  1391. break;
  1392. case 'Harbor':
  1393. iconPath = "<img src=\"img://icons/quests/harbor_white.png\"";
  1394. break;
  1395. case 'Entrance':
  1396. iconPath = "<img src=\"img://icons/quests/cave_entrance_white.png\"";
  1397. break;
  1398. case 'NoticeBoard':
  1399. iconPath = "<img src=\"img://icons/quests/noticeboard_white.png\"";
  1400. break;
  1401. case 'NoticeBoardFull':
  1402. iconPath = "<img src=\"img://icons/quests/noticeboard_quest_white.png\"";
  1403. break;
  1404. case 'Whetstone':
  1405. iconPath = "<img src=\"img://icons/quests/whetstone_white.png\"";
  1406. break;
  1407. case 'ArmorRepairTable':
  1408. iconPath = "<img src=\"img://icons/quests/armor_repair_table_white.png\"";
  1409. break;
  1410. case 'WitcherHouse':
  1411. iconPath = "<img src=\"img://icons/quests/witcher_house_white.png\"";
  1412. break;
  1413. case 'AlchemyTable':
  1414. iconPath = "<img src=\"img://icons/quests/alchemy_table_white.png\"";
  1415. break;
  1416. case 'MutagenDismantle':
  1417. iconPath = "<img src=\"img://icons/quests/mutagen_dismantle_white.png\"";
  1418. break;
  1419. case 'Stables':
  1420. iconPath = "<img src=\"img://icons/quests/stables_white.png\"";
  1421. break;
  1422. case 'Bookshelf':
  1423. iconPath = "<img src=\"img://icons/quests/bookshelf_white.png\"";
  1424. break;
  1425. case 'Bed':
  1426. iconPath = "<img src=\"img://icons/quests/bed_white.png\"";
  1427. break;
  1428. case 'PlayerStash':
  1429. case 'PlayerStashDiscoverable':
  1430. iconPath = "<img src=\"img://icons/quests/player_stash_white.png\"";
  1431. break;
  1432. //NPCs
  1433. case 'Cammerlengo':
  1434. iconPath = "<img src=\"img://icons/quests/cammerlengo_white.png\"";
  1435. break;
  1436. case 'DyeMerchant':
  1437. iconPath = "<img src=\"img://icons/quests/dye_merchant_white.png\"";
  1438. break;
  1439. case 'WineMerchant':
  1440. iconPath = "<img src=\"img://icons/quests/wine_merchant_white.png\"";
  1441. break;
  1442. case 'Shopkeeper':
  1443. iconPath = "<img src=\"img://icons/quests/shopkeeper_white.png\"";
  1444. break;
  1445. case 'Blacksmith':
  1446. iconPath = "<img src=\"img://icons/quests/blacksmith_white.png\"";
  1447. break;
  1448. case 'Armorer':
  1449. iconPath = "<img src=\"img://icons/quests/armorer_white.png\"";
  1450. break;
  1451. case 'Archmaster':
  1452. iconPath = "<img src=\"img://icons/quests/archmaster_white.png\"";
  1453. break;
  1454. case 'Hairdresser':
  1455. iconPath = "<img src=\"img://icons/quests/hairdresser_white.png\"";
  1456. break;
  1457. case 'Alchemic':
  1458. iconPath = "<img src=\"img://icons/quests/alchemist_white.png\"";
  1459. break;
  1460. case 'Herbalist':
  1461. iconPath = "<img src=\"img://icons/quests/herbalist_white.png\"";
  1462. break;
  1463. case 'Innkeeper':
  1464. iconPath = "<img src=\"img://icons/quests/innkeeper_white.png\"";
  1465. break;
  1466. case 'Enchanter':
  1467. iconPath = "<img src=\"img://icons/quests/enchanter_white.png\"";
  1468. break;
  1469. case 'Torch':
  1470. iconPath = "<img src=\"img://icons/quests/torch_white.png\"";
  1471. break;
  1472. case 'Prostitute':
  1473. iconPath = "<img src=\"img://icons/quests/prostitute_white.png\"";
  1474. break;
  1475. //POIs
  1476. case 'NotDiscoveredPOI':
  1477. iconPath = "<img src=\"img://icons/quests/quest_question_white.png\"";
  1478. break;
  1479. case 'MonsterNest':
  1480. iconPath = "<img src=\"img://icons/quests/monster_nest_white.png\"";
  1481. break;
  1482. case 'MonsterNestDisabled':
  1483. iconPath = "<img src=\"img://icons/quests/monster_nest_disabled.png\"";
  1484. break;
  1485. case 'InfestedVineyard':
  1486. iconPath = "<img src=\"img://icons/quests/infested_vineyard_white.png\"";
  1487. break;
  1488. case 'InfestedVineyardDisabled':
  1489. iconPath = "<img src=\"img://icons/quests/infested_vineyard_disabled.png\"";
  1490. break;
  1491. case 'PlaceOfPower':
  1492. iconPath = "<img src=\"img://icons/quests/place_of_power_white.png\"";
  1493. break;
  1494. case 'PlaceOfPowerDisabled':
  1495. iconPath = "<img src=\"img://icons/quests/place_of_power_disabled.png\"";
  1496. break;
  1497. case 'TreasureHuntMappin':
  1498. iconPath = "<img src=\"img://icons/quests/quest_treasure_white.png\"";
  1499. break;
  1500. case 'TreasureHuntMappinDisabled':
  1501. iconPath = "<img src=\"img://icons/quests/quest_treasure_disabled.png\"";
  1502. break;
  1503. case 'SpoilsOfWar':
  1504. iconPath = "<img src=\"img://icons/quests/spoils_of_war_white.png\"";
  1505. break;
  1506. case 'SpoilsOfWarDisabled':
  1507. iconPath = "<img src=\"img://icons/quests/spoils_of_war_disabled.png\"";
  1508. break;
  1509. case 'BanditCamp':
  1510. iconPath = "<img src=\"img://icons/quests/person_in_distress_white.png\"";
  1511. break;
  1512. case 'BanditCampDisabled':
  1513. iconPath = "<img src=\"img://icons/quests/person_in_distress_disabled.png\"";
  1514. break;
  1515. case 'BanditCampfire':
  1516. iconPath = "<img src=\"img://icons/quests/bandit_camp_white.png\"";
  1517. break;
  1518. case 'BanditCampfireDisabled':
  1519. iconPath = "<img src=\"img://icons/quests/bandit_camp_disabled.png\"";
  1520. break;
  1521. case 'BossAndTreasure':
  1522. iconPath = "<img src=\"img://icons/quests/guarded_treasure_white.png\"";
  1523. break;
  1524. case 'BossAndTreasureDisabled':
  1525. iconPath = "<img src=\"img://icons/quests/guarded_treasure_disabled.png\"";
  1526. break;
  1527. case 'Contraband':
  1528. case 'ContrabandShip':
  1529. iconPath = "<img src=\"img://icons/quests/contraband_white.png\"";
  1530. break;
  1531. case 'ContrabandDisabled':
  1532. case 'ContrabandShipDisabled':
  1533. iconPath = "<img src=\"img://icons/quests/contraband_disabled.png\"";
  1534. break;
  1535. case 'RescuingTown':
  1536. iconPath = "<img src=\"img://icons/quests/rescuing_town_white.png\"";
  1537. break;
  1538. case 'RescuingTownDisabled':
  1539. iconPath = "<img src=\"img://icons/quests/rescuing_town_disabled.png\"";
  1540. break;
  1541. case 'DungeonCrawl':
  1542. iconPath = "<img src=\"img://icons/quests/dungeon_crawl_white.png\"";
  1543. break;
  1544. case 'DungeonCrawlDisabled':
  1545. iconPath = "<img src=\"img://icons/quests/dungeon_crawl_disabled.png\"";
  1546. break;
  1547. case 'Hideout':
  1548. iconPath = "<img src=\"img://icons/quests/hansa_hideout_white.png\"";
  1549. break;
  1550. case 'HideoutDisabled':
  1551. iconPath = "<img src=\"img://icons/quests/hansa_hideout_disabled.png\"";
  1552. break;
  1553. case 'Plegmund':
  1554. iconPath = "<img src=\"img://icons/quests/lebjoda_statue_white.png\"";
  1555. break;
  1556. case 'PlegmundDisabled':
  1557. iconPath = "<img src=\"img://icons/quests/lebjoda_statue_disabled.png\"";
  1558. break;
  1559. case 'KnightErrant':
  1560. iconPath = "<img src=\"img://icons/quests/knight_errand_white.png\"";
  1561. break;
  1562. case 'KnightErrantDisabled':
  1563. iconPath = "<img src=\"img://icons/quests/knight_errand_disabled.png\"";
  1564. break;
  1565. case 'WineContract':
  1566. iconPath = "<img src=\"img://icons/quests/wine_contract_white.png\"";
  1567. break;
  1568. case 'WineContractDisabled':
  1569. iconPath = "<img src=\"img://icons/quests/wine_contract_disabled.png\"";
  1570. break;
  1571. case 'SignalingStake':
  1572. iconPath = "<img src=\"img://icons/quests/bandit_campfire_white.png\"";
  1573. break;
  1574. case 'SignalingStakeDisabled':
  1575. iconPath = "<img src=\"img://icons/quests/bandit_campfire_disabled.png\"";
  1576. break;
  1577. //misc
  1578. case 'Rift':
  1579. case 'Teleport':
  1580. iconPath = "<img src=\"img://icons/quests/teleport_white.png\"";
  1581. break;
  1582. case 'MagicLamp':
  1583. iconPath = "<img src=\"img://icons/quests/magic_lamp_white.png\"";
  1584. break;
  1585. case 'HorseRaceTarget':
  1586. iconPath = "<img src=\"img://icons/quests/horse_race_target_white.png\"";
  1587. break;
  1588. case 'HorseRaceDummy':
  1589. iconPath = "<img src=\"img://icons/quests/horse_race_dummy_white.png\"";
  1590. break;
  1591. case 'Herb':
  1592. iconPath = "<img src=\"img://icons/quests/herb_white.png\"";
  1593. break;
  1594. case 'Enemy':
  1595. iconPath = "<img src=\"img://icons/quests/enemy_white.png\"";
  1596. break;
  1597. case 'EnemyDead':
  1598. iconPath = "<img src=\"img://icons/quests/dead_body_white.png\"";
  1599. break;
  1600. case 'GenericFocus':
  1601. iconPath = "<img src=\"img://icons/quests/ws_clue_white.png\"";
  1602. break;
  1603. default:
  1604. iconPath = "<img src=\"img://icons/quests/quest_question_white.png\"";
  1605. break;
  1606. }
  1607. }
  1608. iconPath += " width=\"" + GetIconSize() + "\" height=\"" + GetIconSize() + "\">";
  1609. return iconPath;
  1610. }
  1611.  
  1612. function GetQuestAltTextByLevel( marker : SMod3DMarker ) : string
  1613. {
  1614. switch( marker.lvlDiff )
  1615. {
  1616. case QL_NORMAL:
  1617. return " color=\"#89d889\">*";
  1618. case QL_HIGH:
  1619. return " color=\"#ff6655\">*";
  1620. case QL_LOW:
  1621. return " color=\"#cccccc\">*";
  1622. }
  1623. return " >*";
  1624. }
  1625.  
  1626. function GetMarkerAltText( marker : SMod3DMarker ) : string
  1627. {
  1628. var altText : string;
  1629.  
  1630. if( marker.isActiveQuest )
  1631. {
  1632. if( marker.isHighlighted )
  1633. altText = " face=\"$BoldFont\" color=\"#ff9900\">*";
  1634. else
  1635. altText = " color=\"#ff9900\">*";
  1636. }
  1637. else
  1638. {
  1639. switch( marker.visibleType )
  1640. {
  1641. //quests
  1642. case 'QuestReturn':
  1643. altText = " face=\"$BoldFont\" color=\"#ff9900\">?";
  1644. break;
  1645. case 'MonsterQuest':
  1646. case 'TreasureQuest':
  1647. case 'StoryQuest':
  1648. case 'ChapterQuest':
  1649. case 'SideQuest':
  1650. altText = GetQuestAltTextByLevel( marker );
  1651. break;
  1652. case 'QuestAvailable':
  1653. altText = " color=\"#ffcc00\">!";
  1654. break;
  1655. case 'QuestAvailableHoS':
  1656. altText = " color=\"#55aae3\">!";
  1657. break;
  1658. case 'QuestAvailableBaW':
  1659. case 'QuestBelgard':
  1660. case 'QuestCoronata':
  1661. case 'QuestVermentino':
  1662. altText = " color=\"#fb712f\">!";
  1663. break;
  1664. case 'HorseRace':
  1665. case 'BoatRace':
  1666. altText = " color=\"#cd853f\">!";
  1667. break;
  1668. //utility signs
  1669. case 'User1':
  1670. altText = " color=\"#06b952\">x";
  1671. break;
  1672. case 'User2':
  1673. altText = " color=\"#ff6655\">x";
  1674. break;
  1675. case 'User3':
  1676. altText = " color=\"#67a9f8\">x";
  1677. break;
  1678. case 'User4':
  1679. altText = " color=\"#fb712f\">x";
  1680. break;
  1681. case 'Horse':
  1682. case 'Boat':
  1683. case 'RoadSign':
  1684. case 'Harbor':
  1685. case 'Entrance':
  1686. case 'Whetstone':
  1687. case 'ArmorRepairTable':
  1688. case 'WitcherHouse':
  1689. case 'PlayerStash':
  1690. case 'PlayerStashDiscoverable':
  1691. case 'AlchemyTable':
  1692. case 'MutagenDismantle':
  1693. case 'Stables':
  1694. case 'Bookshelf':
  1695. case 'Bed':
  1696. altText = " color=\"#89d889\">@";
  1697. break;
  1698. case 'NoticeBoard':
  1699. altText = " >!";
  1700. break;
  1701. case 'NoticeBoardFull':
  1702. altText = " color=\"#ffcc00\">!";
  1703. break;
  1704. //NPCs
  1705. case 'Cammerlengo':
  1706. case 'DyeMerchant':
  1707. case 'WineMerchant':
  1708. case 'Shopkeeper':
  1709. case 'Blacksmith':
  1710. case 'Armorer':
  1711. case 'Archmaster':
  1712. case 'Innkeeper':
  1713. case 'Enchanter':
  1714. altText = " color=\"#fff68f\">$";
  1715. break;
  1716. case 'Hairdresser':
  1717. altText = " color=\"#67a9f8\">$";
  1718. break;
  1719. case 'Alchemic':
  1720. case 'Herbalist':
  1721. altText = " color=\"#8ebd2f\">$";
  1722. break;
  1723. case 'Prostitute':
  1724. altText = " color=\"#991a1a\">$";
  1725. break;
  1726. case 'Torch':
  1727. altText = " color=\"#ff6655\">+";
  1728. break;
  1729. //POIs
  1730. case 'NotDiscoveredPOI':
  1731. altText = " >?";
  1732. break;
  1733. case 'MonsterNest':
  1734. case 'InfestedVineyard':
  1735. case 'PlaceOfPower':
  1736. case 'TreasureHuntMappin':
  1737. case 'SpoilsOfWar':
  1738. case 'BanditCamp':
  1739. case 'BanditCampfire':
  1740. case 'BossAndTreasure':
  1741. case 'Contraband':
  1742. case 'ContrabandShip':
  1743. case 'RescuingTown':
  1744. case 'DungeonCrawl':
  1745. case 'Hideout':
  1746. case 'Plegmund':
  1747. case 'KnightErrant':
  1748. case 'WineContract':
  1749. case 'SignalingStake':
  1750. altText = " >o";
  1751. break;
  1752. case 'MonsterNestDisabled':
  1753. case 'InfestedVineyardDisabled':
  1754. case 'PlaceOfPowerDisabled':
  1755. case 'TreasureHuntMappinDisabled':
  1756. case 'SpoilsOfWarDisabled':
  1757. case 'BanditCampDisabled':
  1758. case 'BanditCampfireDisabled':
  1759. case 'BossAndTreasureDisabled':
  1760. case 'ContrabandDisabled':
  1761. case 'ContrabandShipDisabled':
  1762. case 'RescuingTownDisabled':
  1763. case 'DungeonCrawlDisabled':
  1764. case 'HideoutDisabled':
  1765. case 'PlegmundDisabled':
  1766. case 'KnightErrantDisabled':
  1767. case 'WineContractDisabled':
  1768. case 'SignalingStakeDisabled':
  1769. altText = " color=\"#999999\">o";
  1770. break;
  1771. //misc
  1772. case 'Rift':
  1773. case 'Teleport':
  1774. altText = " color=\"#cc66ff\">#";
  1775. break;
  1776. case 'MagicLamp':
  1777. altText = " color=\"#00ee33\">#";
  1778. break;
  1779. case 'HorseRaceTarget':
  1780. altText = " color=\"#cc66ff\">x";
  1781. break;
  1782. case 'HorseRaceDummy':
  1783. altText = " color=\"#cc66ff\">x";
  1784. break;
  1785. case 'Herb':
  1786. altText = " color=\"#8ebd2f\">#";
  1787. break;
  1788. case 'Enemy':
  1789. altText = " color=\"#ff6655\">+";
  1790. break;
  1791. case 'EnemyDead':
  1792. altText = " color=\"#ff6655\">x";
  1793. break;
  1794. case 'GenericFocus':
  1795. altText = " color=\"#ff6655\">#";
  1796. break;
  1797. default:
  1798. altText = " >?";
  1799. break;
  1800. }
  1801. }
  1802. altText = "<font size=\"" + config.markersAltTextSize + "\" " + altText + "</font>";
  1803. return altText;
  1804. }
  1805.  
  1806. function GetMarkerAltTextBW( marker : SMod3DMarker ) : string
  1807. {
  1808. var altText : string;
  1809.  
  1810. if( marker.isActiveQuest )
  1811. {
  1812. if( marker.isHighlighted )
  1813. altText = " face=\"$BoldFont\">*";
  1814. else
  1815. altText = " >*";
  1816. }
  1817. else
  1818. {
  1819. switch( marker.visibleType )
  1820. {
  1821. //quests
  1822. case 'QuestReturn':
  1823. altText = " face=\"$BoldFont\">?";
  1824. break;
  1825. case 'MonsterQuest':
  1826. case 'TreasureQuest':
  1827. case 'StoryQuest':
  1828. case 'ChapterQuest':
  1829. case 'SideQuest':
  1830. altText = " >*";
  1831. break;
  1832. case 'QuestAvailable':
  1833. case 'QuestAvailableHoS':
  1834. case 'QuestAvailableBaW':
  1835. case 'QuestBelgard':
  1836. case 'QuestCoronata':
  1837. case 'QuestVermentino':
  1838. case 'HorseRace':
  1839. case 'BoatRace':
  1840. altText = " >!";
  1841. break;
  1842. //utility signs
  1843. case 'User1':
  1844. case 'User2':
  1845. case 'User3':
  1846. case 'User4':
  1847. altText = " >x";
  1848. break;
  1849. case 'Horse':
  1850. case 'Boat':
  1851. case 'RoadSign':
  1852. case 'Harbor':
  1853. case 'Entrance':
  1854. case 'Whetstone':
  1855. case 'ArmorRepairTable':
  1856. case 'WitcherHouse':
  1857. case 'PlayerStash':
  1858. case 'PlayerStashDiscoverable':
  1859. case 'AlchemyTable':
  1860. case 'MutagenDismantle':
  1861. case 'Stables':
  1862. case 'Bookshelf':
  1863. case 'Bed':
  1864. altText = " >@";
  1865. break;
  1866. case 'NoticeBoard':
  1867. case 'NoticeBoardFull':
  1868. altText = " >!";
  1869. break;
  1870. //NPCs
  1871. case 'Cammerlengo':
  1872. case 'DyeMerchant':
  1873. case 'WineMerchant':
  1874. case 'Shopkeeper':
  1875. case 'Blacksmith':
  1876. case 'Armorer':
  1877. case 'Archmaster':
  1878. case 'Innkeeper':
  1879. case 'Enchanter':
  1880. case 'Hairdresser':
  1881. case 'Alchemic':
  1882. case 'Herbalist':
  1883. case 'Prostitute':
  1884. altText = " >$";
  1885. break;
  1886. case 'Torch':
  1887. altText = " >+";
  1888. break;
  1889. //POIs
  1890. case 'NotDiscoveredPOI':
  1891. altText = " >?";
  1892. break;
  1893. case 'MonsterNest':
  1894. case 'InfestedVineyard':
  1895. case 'PlaceOfPower':
  1896. case 'TreasureHuntMappin':
  1897. case 'SpoilsOfWar':
  1898. case 'BanditCamp':
  1899. case 'BanditCampfire':
  1900. case 'BossAndTreasure':
  1901. case 'Contraband':
  1902. case 'ContrabandShip':
  1903. case 'RescuingTown':
  1904. case 'DungeonCrawl':
  1905. case 'Hideout':
  1906. case 'Plegmund':
  1907. case 'KnightErrant':
  1908. case 'WineContract':
  1909. case 'SignalingStake':
  1910. case 'MonsterNestDisabled':
  1911. case 'InfestedVineyardDisabled':
  1912. case 'PlaceOfPowerDisabled':
  1913. case 'TreasureHuntMappinDisabled':
  1914. case 'SpoilsOfWarDisabled':
  1915. case 'BanditCampDisabled':
  1916. case 'BanditCampfireDisabled':
  1917. case 'BossAndTreasureDisabled':
  1918. case 'ContrabandDisabled':
  1919. case 'ContrabandShipDisabled':
  1920. case 'RescuingTownDisabled':
  1921. case 'DungeonCrawlDisabled':
  1922. case 'HideoutDisabled':
  1923. case 'PlegmundDisabled':
  1924. case 'KnightErrantDisabled':
  1925. case 'WineContractDisabled':
  1926. case 'SignalingStakeDisabled':
  1927. altText = " >o";
  1928. break;
  1929. //misc
  1930. case 'Rift':
  1931. case 'Teleport':
  1932. case 'MagicLamp':
  1933. case 'Herb':
  1934. case 'GenericFocus':
  1935. altText = " >#";
  1936. break;
  1937. case 'HorseRaceTarget':
  1938. case 'HorseRaceDummy':
  1939. case 'EnemyDead':
  1940. altText = " >x";
  1941. break;
  1942. case 'Enemy':
  1943. altText = " >+";
  1944. break;
  1945. default:
  1946. altText = " >?";
  1947. break;
  1948. }
  1949. }
  1950. altText = "<font size=\"" + config.markersAltTextSize + "\" " + altText + "</font>";
  1951. return altText;
  1952. }
  1953.  
  1954. //================= on/off conditions ========================
  1955.  
  1956. function ShouldShowMarker( marker : SMod3DMarker ) : bool
  1957. {
  1958. if( marker.pin || marker.force )
  1959. return true;
  1960. if( IsActiveQuest( marker ) )
  1961. return config.markersShowQuests == MV_Show;
  1962. if( IsQuest( marker ) )
  1963. return config.markersShowQuestsAll == MV_Show;
  1964. if( IsUserMain( marker ) )
  1965. return config.markersShowUser == MV_Show;
  1966. if( IsUserAdditional( marker ) )
  1967. return config.markersShowUserAll == MV_Show;
  1968. if( IsMapLocation( marker ) )
  1969. return config.markersShowMapLoc == MV_Show;
  1970. if( IsNPC( marker ) )
  1971. return config.markersShowNPCs == MV_Show;
  1972. if( IsPOIUndiscovered( marker ) )
  1973. return config.markersShowUndiscovered == MV_Show;
  1974. if( IsPOI( marker ) )
  1975. return config.markersShowPOIs == MV_Show;
  1976. if( IsPOIDisabled( marker ) )
  1977. return config.markersShowDisabled == MV_Show;
  1978. if( IsMisc( marker ) )
  1979. return config.markersShowMisc == MV_Show;
  1980. if( IsHerb( marker ) )
  1981. return config.markersShowHerbs == MV_Show;
  1982. if( IsEnemy( marker ) )
  1983. return config.markersShowEnemies == MV_Show;
  1984. if( IsEnemyDead( marker ) )
  1985. return config.markersShowDeadEnemies == MV_Show;
  1986. if( IsWSClue( marker ) )
  1987. return config.markersShowWSClues == MV_Show;
  1988. /*if( pin.type == 'NPC' ||
  1989. pin.type == 'PointOfInterestMappin' )
  1990. continue;*/
  1991. //theGame.witcherLog.AddMessage( "marker: " + marker.visibleType );
  1992. return false;
  1993. }
  1994.  
  1995. function ShouldPinMarker( marker : SMod3DMarker ) : bool
  1996. {
  1997. if( IsActiveQuest( marker ) )
  1998. return config.markersShowQuests == MV_Pin;
  1999. if( IsQuest( marker ) )
  2000. return config.markersShowQuestsAll == MV_Pin;
  2001. if( IsUserMain( marker ) )
  2002. return config.markersShowUser == MV_Pin;
  2003. if( IsUserAdditional( marker ) )
  2004. return config.markersShowUserAll == MV_Pin;
  2005. if( IsMapLocation( marker ) )
  2006. return config.markersShowMapLoc == MV_Pin;
  2007. if( IsNPC( marker ) )
  2008. return config.markersShowNPCs == MV_Pin;
  2009. if( IsPOIUndiscovered( marker ) )
  2010. return config.markersShowUndiscovered == MV_Pin;
  2011. if( IsPOI( marker ) )
  2012. return config.markersShowPOIs == MV_Pin;
  2013. if( IsPOIDisabled( marker ) )
  2014. return config.markersShowDisabled == MV_Pin;
  2015. if( IsMisc( marker ) )
  2016. return config.markersShowMisc == MV_Pin;
  2017. if( IsHerb( marker ) )
  2018. return config.markersShowHerbs == MV_Pin;
  2019. if( IsEnemy( marker ) )
  2020. return config.markersShowEnemies == MV_Pin;
  2021. if( IsEnemyDead( marker ) )
  2022. return config.markersShowDeadEnemies == MV_Pin;
  2023. if( IsWSClue( marker ) )
  2024. return config.markersShowWSClues == MV_Pin;
  2025. return false;
  2026. }
  2027.  
  2028. function ShouldForceMarker( marker : SMod3DMarker ) : bool
  2029. {
  2030. if( IsActiveQuest( marker ) )
  2031. return config.markersShowQuests == MV_Force;
  2032. if( IsQuest( marker ) )
  2033. return config.markersShowQuestsAll == MV_Force;
  2034. if( IsUserMain( marker ) )
  2035. return config.markersShowUser == MV_Force;
  2036. if( IsUserAdditional( marker ) )
  2037. return config.markersShowUserAll == MV_Force;
  2038. if( IsMapLocation( marker ) )
  2039. return config.markersShowMapLoc == MV_Force;
  2040. if( IsNPC( marker ) )
  2041. return config.markersShowNPCs == MV_Force;
  2042. if( IsPOIUndiscovered( marker ) )
  2043. return config.markersShowUndiscovered == MV_Force;
  2044. if( IsPOI( marker ) )
  2045. return config.markersShowPOIs == MV_Force;
  2046. if( IsPOIDisabled( marker ) )
  2047. return config.markersShowDisabled == MV_Force;
  2048. if( IsMisc( marker ) )
  2049. return config.markersShowMisc == MV_Force;
  2050. if( IsHerb( marker ) )
  2051. return config.markersShowHerbs == MV_Force;
  2052. if( IsEnemy( marker ) )
  2053. return config.markersShowEnemies == MV_Force;
  2054. if( IsEnemyDead( marker ) )
  2055. return config.markersShowDeadEnemies == MV_Force;
  2056. if( IsWSClue( marker ) )
  2057. return config.markersShowWSClues == MV_Force;
  2058. return false;
  2059. }
  2060.  
  2061. function IsActiveQuest( marker : SMod3DMarker ) : bool
  2062. {
  2063. return marker.isActiveQuest;
  2064. }
  2065.  
  2066. function IsQuest( marker : SMod3DMarker ) : bool
  2067. {
  2068. switch( marker.visibleType )
  2069. {
  2070. case 'StoryQuest':
  2071. case 'ChapterQuest':
  2072. case 'SideQuest':
  2073. case 'QuestReturn':
  2074. case 'MonsterQuest':
  2075. case 'TreasureQuest':
  2076. case 'QuestAvailable':
  2077. case 'QuestAvailableHoS':
  2078. case 'QuestAvailableBaW':
  2079. case 'QuestBelgard':
  2080. case 'QuestCoronata':
  2081. case 'QuestVermentino':
  2082. case 'HorseRace':
  2083. case 'BoatRace':
  2084. return true;
  2085. }
  2086. return false;
  2087. }
  2088.  
  2089. function IsUserMain( marker : SMod3DMarker ) : bool
  2090. {
  2091. return ( marker.visibleType == 'User1' );
  2092. }
  2093.  
  2094. function IsUserAdditional( marker : SMod3DMarker ) : bool
  2095. {
  2096. switch( marker.visibleType )
  2097. {
  2098. case 'User2':
  2099. case 'User3':
  2100. case 'User4':
  2101. return true;
  2102. }
  2103. return false;
  2104. }
  2105.  
  2106. function IsRoadSign( marker : SMod3DMarker ) : bool
  2107. {
  2108. return ( marker.visibleType == 'RoadSign' );
  2109. }
  2110.  
  2111. function IsMapLocation( marker : SMod3DMarker ) : bool
  2112. {
  2113. switch( marker.visibleType )
  2114. {
  2115. case 'Horse':
  2116. case 'Boat':
  2117. case 'RoadSign':
  2118. case 'Harbor':
  2119. case 'Entrance':
  2120. case 'NoticeBoard':
  2121. case 'NoticeBoardFull':
  2122. case 'Whetstone':
  2123. case 'ArmorRepairTable':
  2124. case 'PlayerStash':
  2125. case 'PlayerStashDiscoverable':
  2126. case 'WitcherHouse':
  2127. case 'AlchemyTable':
  2128. case 'MutagenDismantle':
  2129. case 'Stables':
  2130. case 'Bookshelf':
  2131. case 'Bed':
  2132. return true;
  2133. }
  2134. return false;
  2135. }
  2136.  
  2137. function IsNPC( marker : SMod3DMarker ) : bool
  2138. {
  2139. switch( marker.visibleType )
  2140. {
  2141. case 'Cammerlengo':
  2142. case 'DyeMerchant':
  2143. case 'WineMerchant':
  2144. case 'Shopkeeper':
  2145. case 'Blacksmith':
  2146. case 'Armorer':
  2147. case 'Archmaster':
  2148. case 'Hairdresser':
  2149. case 'Alchemic':
  2150. case 'Herbalist':
  2151. case 'Innkeeper':
  2152. case 'Enchanter':
  2153. case 'Torch':
  2154. case 'Prostitute':
  2155. return true;
  2156. }
  2157. return false;
  2158. }
  2159.  
  2160. function IsPOIUndiscovered( marker : SMod3DMarker ) : bool
  2161. {
  2162. return ( marker.visibleType == 'NotDiscoveredPOI' );
  2163. }
  2164.  
  2165. function IsPOI( marker : SMod3DMarker ) : bool
  2166. {
  2167. switch( marker.visibleType )
  2168. {
  2169. case 'MonsterNest':
  2170. case 'InfestedVineyard':
  2171. case 'PlaceOfPower':
  2172. case 'TreasureHuntMappin':
  2173. case 'SpoilsOfWar':
  2174. case 'BanditCamp':
  2175. case 'BanditCampfire':
  2176. case 'BossAndTreasure':
  2177. case 'Contraband':
  2178. case 'ContrabandShip':
  2179. case 'RescuingTown':
  2180. case 'DungeonCrawl':
  2181. case 'Hideout':
  2182. case 'Plegmund':
  2183. case 'KnightErrant':
  2184. case 'WineContract':
  2185. case 'SignalingStake':
  2186. return true;
  2187. }
  2188. return false;
  2189. }
  2190.  
  2191. function IsPOIDisabled( marker : SMod3DMarker ) : bool
  2192. {
  2193. switch( marker.visibleType )
  2194. {
  2195. case 'MonsterNestDisabled':
  2196. case 'InfestedVineyardDisabled':
  2197. case 'PlaceOfPowerDisabled':
  2198. case 'TreasureHuntMappinDisabled':
  2199. case 'SpoilsOfWarDisabled':
  2200. case 'BanditCampDisabled':
  2201. case 'BanditCampfireDisabled':
  2202. case 'BossAndTreasureDisabled':
  2203. case 'ContrabandDisabled':
  2204. case 'ContrabandShipDisabled':
  2205. case 'RescuingTownDisabled':
  2206. case 'DungeonCrawlDisabled':
  2207. case 'HideoutDisabled':
  2208. case 'PlegmundDisabled':
  2209. case 'KnightErrantDisabled':
  2210. case 'WineContractDisabled':
  2211. case 'SignalingStakeDisabled':
  2212. return true;
  2213. }
  2214. return false;
  2215. }
  2216.  
  2217. function IsHerb( marker : SMod3DMarker ) : bool
  2218. {
  2219. return ( marker.visibleType == 'Herb' );
  2220. }
  2221.  
  2222. function IsEnemy( marker : SMod3DMarker ) : bool
  2223. {
  2224. return ( marker.visibleType == 'Enemy' );
  2225. }
  2226.  
  2227. function IsEnemyDead( marker : SMod3DMarker ) : bool
  2228. {
  2229. return ( marker.visibleType == 'EnemyDead' );
  2230. }
  2231.  
  2232. function IsWSClue( marker : SMod3DMarker ) : bool
  2233. {
  2234. return ( marker.visibleType == 'GenericFocus' );
  2235. }
  2236.  
  2237. function IsMisc( marker : SMod3DMarker ) : bool
  2238. {
  2239. switch( marker.visibleType )
  2240. {
  2241. case 'Rift':
  2242. case 'Teleport':
  2243. case 'MagicLamp':
  2244. case 'HorseRaceTarget':
  2245. case 'HorseRaceDummy':
  2246. return true;
  2247. }
  2248. return false;
  2249. }
  2250.  
  2251. function IsDynamic( marker : SMod3DMarker ) : bool
  2252. {
  2253. return IsNPC( marker ) || IsHerb( marker ) || IsEnemy( marker ) ||
  2254. IsEnemyDead( marker ) || IsWSClue( marker ) || IsMisc( marker );
  2255. }
  2256.  
  2257. //========================== cache markers =================================
  2258.  
  2259. public function SignalCache3DMarkers( questPins : bool )
  2260. {
  2261. if( !isDirty )
  2262. {
  2263. isDirty = true;
  2264. delayedCacheTime = theGame.GetEngineTimeAsSeconds() + 0.5f;
  2265. }
  2266. cacheQuestPins = questPins;
  2267. }
  2268.  
  2269. private function CacheQuestMapPins()
  2270. {
  2271. var mapManager : CCommonMapManager = theGame.GetCommonMapManager();
  2272. var currentWorldPath : string = theGame.GetWorld().GetDepotPath();
  2273. var journalManager : CWitcherJournalManager = theGame.GetJournalManager();
  2274. var trackedQuest : CJournalQuest;
  2275. var highlightedObjective : CJournalQuestObjective;
  2276. var activeQuests : array<CJournalBase>;
  2277. var currentQuest : CJournalQuest;
  2278. var currentPhase : CJournalQuestPhase;
  2279. var currentObjective : CJournalQuestObjective;
  2280. var mapPinInstances : array< SCommonMapPinInstance >;
  2281. var pin : SCommonMapPinInstance;
  2282. var i, j, k, m : int;
  2283. var lvlDiff : EQuestLevel;
  2284.  
  2285. //theGame.witcherLog.AddMessage( "CacheQuestMapPins" );
  2286.  
  2287. FactsAdd( "quest_map_pins_hack_disable_sound" );
  2288.  
  2289. journalManager.GetActivatedOfType( 'CJournalQuest', activeQuests );
  2290. trackedQuest = journalManager.GetTrackedQuest();
  2291. highlightedObjective = journalManager.GetHighlightedObjective();
  2292.  
  2293. cachedQuestPins.Clear();
  2294. cachedQuestLevels.Clear();
  2295.  
  2296. for( i = 0; i < activeQuests.Size(); i += 1 )
  2297. {
  2298. currentQuest = (CJournalQuest)activeQuests[i];
  2299. if( currentQuest == trackedQuest )
  2300. continue;
  2301. if( currentQuest && journalManager.GetEntryStatus( currentQuest ) == JS_Active && ( !config.markerHideActivities || !IsActivity( currentQuest ) ) )
  2302. {
  2303. journalManager.SetTrackedQuest( currentQuest );
  2304. lvlDiff = GetLevelDiff( currentQuest );
  2305. for( j = 0; j < currentQuest.GetNumChildren(); j += 1 )
  2306. {
  2307. currentPhase = (CJournalQuestPhase)currentQuest.GetChild(j);
  2308. if( currentPhase && journalManager.GetEntryStatus( currentPhase ) == JS_Active )
  2309. {
  2310. for( k = 0; k < currentPhase.GetNumChildren(); k += 1 )
  2311. {
  2312. currentObjective = (CJournalQuestObjective)currentPhase.GetChild(k);
  2313. if( currentObjective && journalManager.GetEntryStatus( currentObjective ) == JS_Active )
  2314. {
  2315. journalManager.SetHighlightedObjective( currentObjective );
  2316. //theGame.witcherLog.AddMessage( currentObjective.GetUniqueScriptTag() );
  2317. if( NormalizeArea( currentObjective.GetWorld() ) == NormalizeArea( mapManager.GetAreaFromWorldPath( currentWorldPath ) ) )
  2318. {
  2319. mapPinInstances = mapManager.GetMapPinInstances( currentWorldPath );
  2320. //theGame.witcherLog.AddMessage( mapPinInstances.Size() );
  2321. for( m = 0; m < mapPinInstances.Size(); m += 1 )
  2322. {
  2323. pin = mapPinInstances[m];
  2324. if( !pin.isDisabled && pin.guid == currentObjective.guid && ( pin.isDiscovered || pin.isKnown ) )
  2325. {
  2326. pin.isHighlighted = false;
  2327. cachedQuestPins.PushBack( pin );
  2328. cachedQuestLevels.PushBack( lvlDiff );
  2329. //theGame.witcherLog.AddMessage( GetMarkerDescription( pin ) );
  2330. }
  2331. }
  2332. }
  2333. }
  2334. }
  2335. }
  2336. }
  2337. }
  2338. }
  2339.  
  2340. journalManager.SetTrackedQuest( trackedQuest );
  2341. journalManager.SetHighlightedObjective( highlightedObjective );
  2342.  
  2343. FactsRemove( "quest_map_pins_hack_disable_sound" );
  2344. }
  2345.  
  2346. private function NormalizeArea( area : EAreaName ) : EAreaName
  2347. {
  2348. if( area == AN_Velen )
  2349. area = AN_NMLandNovigrad;
  2350.  
  2351. return area;
  2352. }
  2353.  
  2354. private function GetLevelDiff( targetQuest : CJournalQuest ) : EQuestLevel
  2355. {
  2356. var i, j : int;
  2357. var levels : C2dArray;
  2358. var qName : string;
  2359. var qLevel : int;
  2360. var lvlDiff : int;
  2361.  
  2362. for( i = 0; i < theGame.questLevelsContainer.Size(); i += 1 )
  2363. {
  2364. levels = theGame.questLevelsContainer[i];
  2365. for( j = 0; j < levels.GetNumRows(); j += 1 )
  2366. {
  2367. qName = levels.GetValueAtAsName(0, j);
  2368. if( qName == targetQuest.baseName )
  2369. {
  2370. qLevel = NameToInt( levels.GetValueAtAsName(1, j) );
  2371. if( qLevel > 1 )
  2372. {
  2373. if( FactsQuerySum( "NewGamePlus" ) > 0 )
  2374. qLevel += theGame.params.GetNewGamePlusLevel();
  2375. lvlDiff = qLevel - thePlayer.GetLevel();
  2376. if( lvlDiff <= -theGame.params.LEVEL_DIFF_HIGH )
  2377. return QL_LOW;
  2378. if( lvlDiff >= theGame.params.LEVEL_DIFF_HIGH )
  2379. return QL_HIGH;
  2380. }
  2381. return QL_NORMAL;
  2382. }
  2383. }
  2384. }
  2385.  
  2386. return QL_NORMAL;
  2387. }
  2388.  
  2389. private function IsActivity( targetQuest : CJournalQuest ) : bool
  2390. {
  2391. switch( NameToString(targetQuest.GetUniqueScriptTag()) )
  2392. {
  2393. case "NML: Fist Fighting BD0558AA-4C809220-048AB2BB-453FC15D":
  2394. case "NVG: Fist Fighting ADB63834-4EFADC15-0B036E9D-D61D4EDD":
  2395. case "SKG: Fist Fight Championship 3B9CD0F0-4CE07724-3F8C88BA-4B34E232":
  2396. case "NML Horse Race: Baron's Men 6E696C48-49E62FEA-947FC48E-AB746137":
  2397. case "MQ3026 Novigrad Horse Racing B3338F99-4362DADA-4BA1F9AD-95F10F44":
  2398. case "SKG Horse Race: Championship 020A073B-472AEE70-ABE51B81-90B67F37":
  2399. case "SKG Horse Race: Ferlund E6D3273C-48408AE2-334D1792-9E1250AA":
  2400. case "SKG Horse Race: Fejrlesdal 459A8157-4727C1B3-9C3A718F-C271FC41":
  2401. case "SKG Horse Race: Hindarsfjall A9CAEC8F-4FB88A21-24A21A94-3F615E3C":
  2402. case "Card Game Meta: Gather All 22A27919-4ECCF7E1-9F536F90-D140CB21":
  2403. case "CG : No Man's Land BECB3BA0-4C293A48-C3C229B6-31A1439A":
  2404. case "CG: Innkeepers 15BA81D3-4E85B6BD-DF83E995-5D7770CE":
  2405. case "CG: Novigrad 40B54F3B-48857011-9EC0B3BC-5A7537E2":
  2406. case "CG: Skellige 72BA3A67-4CFD722A-0A378284-F4E41BC2":
  2407. case "cammerlengo AFAD298F-47B94308-D6D65092-02F3FC2E":
  2408. case "cg700_all_cards 10792209-4257AE39-5B821199-2FFB20EC":
  2409. case "cg700_tournament DBBF356D-4FFC9CC0-29404AAF-D6208B48":
  2410. case "sq701_tournament":
  2411. case "ff701_fistfights AF499A50-4016055D-97A4A787-06336148":
  2412. case "ff701_master D3B2B89D-4E35CBA8-70F0B39C-46F2BF82":
  2413. return true;
  2414. }
  2415. return false;
  2416. }
  2417.  
  2418. //=============================================================================
  2419.  
  2420. function InitUserMarker( out userMarker : SMod3DMarker ) : bool
  2421. {
  2422. var mapManager : CCommonMapManager = theGame.GetCommonMapManager();
  2423. var area, numPins, id, type, i : int;
  2424. var pinX, pinY : float;
  2425.  
  2426. numPins = mapManager.GetUserMapPinCount();
  2427. for( i = 0; i < numPins; i += 1 )
  2428. {
  2429. mapManager.GetUserMapPinByIndex( i, id, area, pinX, pinY, type );
  2430. if( area == mapManager.GetCurrentArea() && type == 0 )
  2431. {
  2432. userMarker.visibleType = 'User1';
  2433. userMarker.position.X = pinX;
  2434. userMarker.position.Y = pinY;
  2435. return true;
  2436. }
  2437. }
  2438. return false;
  2439. }
  2440.  
  2441. function Cache3DMarkers()
  2442. {
  2443. var commonMapManager : CCommonMapManager = theGame.GetCommonMapManager();
  2444. var currentWorldPath : string = theGame.GetWorld().GetDepotPath();
  2445. var mapPinInstances : array< SCommonMapPinInstance >;
  2446. var mapPinInstancesCount : int;
  2447. var i : int;
  2448. var mapPin : SCommonMapPinInstance;
  2449. var marker : SMod3DMarker;
  2450. var questsStartingIdx : int = 0;
  2451. //var mStatic, mDynamic : array< SMod3DMarker >;
  2452. var userMarker : SMod3DMarker;
  2453. var hasUserMarker, userMarkerSubstituted : bool;
  2454. var disabledPins : array< string > = theGame.GetCommonMapManager().GetDisabledMapPins();
  2455. var journalManager : CWitcherJournalManager = theGame.GetJournalManager();
  2456. var highlightedObjective : CJournalQuestObjective;
  2457.  
  2458. /*theGame.witcherLog.AddMessage( "Disabled Pins:" );
  2459. for( i = 0; i < disabledPins.Size(); i += 1 )
  2460. {
  2461. theGame.witcherLog.AddMessage( disabledPins[i] );
  2462. }*/
  2463.  
  2464. cached3DMarkersStatic.Clear();
  2465. cached3DMarkersDynamic.Clear();
  2466.  
  2467. //cache all quest map pins (all but tracked quest)
  2468. if( cacheQuestPins )
  2469. CacheQuestMapPins();
  2470.  
  2471. //get map pins (all but non-tracked quests)
  2472. mapPinInstances = commonMapManager.GetMapPinInstances( currentWorldPath );
  2473.  
  2474. cachedWorldPath = currentWorldPath;
  2475. cachedNumPins = mapPinInstances.Size();
  2476. questsStartingIdx = cachedNumPins;
  2477.  
  2478. //append cached map pins for non-tracked quests
  2479. for( i = 0; i < cachedQuestPins.Size(); i += 1 )
  2480. mapPinInstances.PushBack( cachedQuestPins[i] );
  2481.  
  2482. mapPinInstancesCount = mapPinInstances.Size();
  2483.  
  2484. hasUserMarker = InitUserMarker( userMarker );
  2485. userMarkerSubstituted = false;
  2486.  
  2487. highlightedObjective = journalManager.GetHighlightedObjective();
  2488.  
  2489. for( i = 0; i < mapPinInstancesCount; i += 1 )
  2490. {
  2491. mapPin = mapPinInstances[i];
  2492. //skip highlighted objective markers (updated separately)
  2493. if( highlightedObjective && mapPin.guid == highlightedObjective.guid )
  2494. continue;
  2495. marker.visibleType = mapPin.visibleType;
  2496. marker.isDiscovered = mapPin.isDiscovered;
  2497. marker.isKnown = mapPin.isKnown;
  2498. marker.isDisabled = mapPin.isDisabled;
  2499. marker.position = mapPin.position;
  2500. ResetQuestMarkerStatus( marker );
  2501. //skip disabled markers
  2502. if( config.markersSyncWithMap && disabledPins.Contains( mapPin.visibleType ) )
  2503. continue;
  2504. //skip unknown markers
  2505. if( !marker.isDiscovered && !marker.isKnown )
  2506. {
  2507. if( !IsRoadSign( marker ) || !config.markerShowUndiscoveredRoadsigns )
  2508. continue;
  2509. }
  2510. //always skip disabled quest map pins
  2511. if( marker.isDisabled && IsQuest( marker ) )
  2512. continue;
  2513. //other disabled pins use menu setting
  2514. if( marker.isDisabled && !config.markersShowDisabled )
  2515. continue;
  2516. if( i >= questsStartingIdx )
  2517. marker.lvlDiff = cachedQuestLevels[i - questsStartingIdx];
  2518. else if( commonMapManager.IsQuestPinType( mapPin.type ) )
  2519. SetQuestMarkerStatus( marker, mapPin );
  2520. marker.force = ShouldForceMarker( marker );
  2521. marker.pin = ShouldPinMarker( marker );
  2522. if( hasUserMarker && config.markerPinWithUserMarker )
  2523. {
  2524. if( IsUserMain( marker ) )
  2525. {
  2526. marker.description = GetMarkerDescription( mapPin );
  2527. marker.text = GetMarkerIconByType( marker );
  2528. userMarker = marker;
  2529. continue;
  2530. }
  2531. //user pinned markers ignore both visibility and max distance settings
  2532. else if( !userMarkerSubstituted && VecDistanceSquared2D( marker.position, userMarker.position ) <= 16.f )
  2533. {
  2534. userMarkerSubstituted = true;
  2535. marker.force = true;
  2536. marker.pin = true;
  2537. }
  2538. }
  2539. //cached3DMarkers.PushBack( marker );
  2540. //Dynamic markers like herbs and especially WS clues lead to rearranging
  2541. //of array elements and redrawing of oneliners - i.e. they cause flickering
  2542. //when enabled. Without proper map/dictionary proper caching is PITA and
  2543. //this is just a hacky workaround, but oh well.
  2544. if( ShouldShowMarker( marker ) )
  2545. {
  2546. marker.description = GetMarkerDescription( mapPin );
  2547. marker.text = GetMarkerIconByType( marker );
  2548. if( IsDynamic( marker ) )
  2549. cached3DMarkersDynamic.PushBack( marker );
  2550. else
  2551. cached3DMarkersStatic.PushBack( marker );
  2552. }
  2553. //theGame.witcherLog.AddMessage( "MAPPIN " + mapPin.id + ": " + mapPin.tag + " : " + mapPin.visibleType );
  2554. }
  2555.  
  2556. //for( i = 0; i < mStatic.Size(); i += 1 )
  2557. // cached3DMarkers.PushBack( mStatic[i] );
  2558. //for( i = 0; i < mDynamic.Size(); i += 1 )
  2559. // cached3DMarkers.PushBack( mDynamic[i] );
  2560.  
  2561. if( !userMarkerSubstituted && ShouldShowMarker( userMarker ) )
  2562. {
  2563. cached3DMarkersStatic.PushBack( userMarker );
  2564. }
  2565.  
  2566. isDirty = false;
  2567. cacheQuestPins = false;
  2568. }
  2569.  
  2570. function Cache3DMarkersTracked()
  2571. {
  2572. var commonMapManager : CCommonMapManager = theGame.GetCommonMapManager();
  2573. var currentWorldPath : string = theGame.GetWorld().GetDepotPath();
  2574. var mapPinInstances : array< SCommonMapPinInstance >;
  2575. var mapPinInstancesCount : int;
  2576. var i : int;
  2577. var mapPin : SCommonMapPinInstance;
  2578. var marker : SMod3DMarker;
  2579. var userMarker : SMod3DMarker;
  2580. var hasUserMarker, userMarkerSubstituted : bool;
  2581. var disabledPins : array< string > = theGame.GetCommonMapManager().GetDisabledMapPins();
  2582. var journalManager : CWitcherJournalManager = theGame.GetJournalManager();
  2583. var highlightedObjective : CJournalQuestObjective;
  2584.  
  2585. cached3DMarkersTracked.Clear();
  2586.  
  2587. mapPinInstances = commonMapManager.GetMapPinInstances( currentWorldPath );
  2588. mapPinInstancesCount = mapPinInstances.Size();
  2589.  
  2590. hasUserMarker = InitUserMarker( userMarker );
  2591. userMarkerSubstituted = false;
  2592.  
  2593. highlightedObjective = journalManager.GetHighlightedObjective();
  2594.  
  2595. if( !highlightedObjective )
  2596. return;
  2597.  
  2598. for( i = 0; i < mapPinInstancesCount; i += 1 )
  2599. {
  2600. mapPin = mapPinInstances[i];
  2601. //skip all, but tracked objective markers
  2602. if(mapPin.guid != highlightedObjective.guid)
  2603. continue;
  2604. marker.visibleType = mapPin.visibleType;
  2605. marker.isDiscovered = mapPin.isDiscovered;
  2606. marker.isKnown = mapPin.isKnown;
  2607. marker.isDisabled = mapPin.isDisabled;
  2608. marker.position = mapPin.position;
  2609. marker.isHighlighted = true;
  2610. marker.isActiveQuest = true;
  2611. //skip disabled markers
  2612. if( config.markersSyncWithMap && disabledPins.Contains( mapPin.visibleType ) )
  2613. continue;
  2614. //skip unknown markers
  2615. if( !marker.isDiscovered && !marker.isKnown )
  2616. {
  2617. if( !IsRoadSign( marker ) || !config.markerShowUndiscoveredRoadsigns )
  2618. continue;
  2619. }
  2620. //always skip disabled quest map pins
  2621. if( marker.isDisabled )
  2622. continue;
  2623. marker.force = ShouldForceMarker( marker );
  2624. marker.pin = ShouldPinMarker( marker );
  2625. if( hasUserMarker && config.markerPinWithUserMarker )
  2626. {
  2627. if( !userMarkerSubstituted && VecDistanceSquared2D( marker.position, userMarker.position ) <= 16.f )
  2628. {
  2629. userMarkerSubstituted = true;
  2630. marker.force = true;
  2631. marker.pin = true;
  2632. }
  2633. }
  2634. if( ShouldShowMarker( marker ) )
  2635. {
  2636. marker.description = GetMarkerDescription( mapPin );
  2637. marker.text = GetMarkerIconByType( marker );
  2638. cached3DMarkersTracked.PushBack( marker );
  2639. }
  2640. }
  2641. }
  2642.  
  2643. function ResetQuestMarkerStatus( out marker : SMod3DMarker )
  2644. {
  2645. marker.isHighlighted = false;
  2646. marker.isActiveQuest = false;
  2647. }
  2648.  
  2649. function SetQuestMarkerStatus( out marker : SMod3DMarker, pin : SCommonMapPinInstance )
  2650. {
  2651. var journalManager : CWitcherJournalManager = theGame.GetJournalManager();
  2652. var curObjective : CJournalQuestObjective;
  2653. var highlightedObjective : CJournalQuestObjective;
  2654. var curQuest : CJournalQuest;
  2655. var highlightedQuest : CJournalQuest;
  2656.  
  2657. highlightedObjective = journalManager.GetHighlightedObjective();
  2658. curObjective = (CJournalQuestObjective)journalManager.GetEntryByGuid( pin.guid );
  2659. if( curObjective && curObjective == highlightedObjective )
  2660. marker.isHighlighted = true;
  2661. else
  2662. marker.isHighlighted = false;
  2663. highlightedQuest = journalManager.GetHighlightedQuest();
  2664. if( curObjective )
  2665. curQuest = curObjective.GetParentQuest();
  2666. if( curQuest && curQuest == highlightedQuest )
  2667. marker.isActiveQuest = true;
  2668. else
  2669. marker.isActiveQuest = false;
  2670. }
  2671.  
  2672. function GetMarkerDescription( targetPin: SCommonMapPinInstance ) : string
  2673. {
  2674. var definitionManager : CDefinitionsManagerAccessor = theGame.GetDefinitionsManager();
  2675. var journalManager : CWitcherJournalManager = theGame.GetJournalManager();
  2676. var curObjective : CJournalQuestObjective;
  2677. var curQuest : CJournalQuest;
  2678. var label : string;
  2679.  
  2680. switch( targetPin.visibleType )
  2681. {
  2682. case 'StoryQuest':
  2683. case 'ChapterQuest':
  2684. case 'SideQuest':
  2685. case 'MonsterQuest':
  2686. case 'TreasureQuest':
  2687. case 'QuestReturn':
  2688. case 'HorseRace':
  2689. case 'BoatRace':
  2690. case 'QuestBelgard':
  2691. case 'QuestCoronata':
  2692. case 'QuestVermentino':
  2693. curObjective = (CJournalQuestObjective)journalManager.GetEntryByGuid( targetPin.guid );
  2694. if( curObjective )
  2695. {
  2696. curQuest = curObjective.GetParentQuest();
  2697. label = GetLocStringById( curQuest.GetTitleStringId() );
  2698. }
  2699. break;
  2700. case 'Horse':
  2701. case 'Rift':
  2702. case 'Teleport':
  2703. case 'QuestAvailable':
  2704. case 'QuestAvailableHoS':
  2705. case 'QuestAvailableBaW':
  2706. case 'MagicLamp':
  2707. case 'HorseRaceTarget':
  2708. case 'HorseRaceDummy':
  2709. case 'Whetstone':
  2710. case 'Entrance':
  2711. case 'NotDiscoveredPOI':
  2712. label = GetLocStringByKeyExt( StrLower( "map_location_" + targetPin.visibleType ) );
  2713. break;
  2714. case 'MonsterNest':
  2715. case 'MonsterNestDisabled':
  2716. case 'InfestedVineyard':
  2717. case 'InfestedVineyardDisabled':
  2718. case 'PlaceOfPower':
  2719. case 'PlaceOfPowerDisabled':
  2720. case 'TreasureHuntMappin':
  2721. case 'TreasureHuntMappinDisabled':
  2722. case 'SpoilsOfWar':
  2723. case 'SpoilsOfWarDisabled':
  2724. case 'BanditCamp':
  2725. case 'BanditCampDisabled':
  2726. case 'BanditCampfire':
  2727. case 'BanditCampfireDisabled':
  2728. case 'BossAndTreasure':
  2729. case 'BossAndTreasureDisabled':
  2730. case 'Contraband':
  2731. case 'ContrabandDisabled':
  2732. case 'ContrabandShip':
  2733. case 'ContrabandShipDisabled':
  2734. case 'RescuingTown':
  2735. case 'RescuingTownDisabled':
  2736. case 'DungeonCrawl':
  2737. case 'DungeonCrawlDisabled':
  2738. case 'Hideout':
  2739. case 'HideoutDisabled':
  2740. case 'Plegmund':
  2741. case 'PlegmundDisabled':
  2742. case 'KnightErrant':
  2743. case 'KnightErrantDisabled':
  2744. case 'WineContract':
  2745. case 'WineContractDisabled':
  2746. case 'SignalingStake':
  2747. case 'SignalingStakeDisabled':
  2748. case 'AlchemyTable':
  2749. case 'WitcherHouse':
  2750. case 'MutagenDismantle':
  2751. case 'Stables':
  2752. case 'Bookshelf':
  2753. case 'Bed':
  2754. label = GetLocStringByKeyExt( StrLower( "map_location_" + targetPin.type ) );
  2755. break;
  2756. case 'PlayerStash':
  2757. case 'PlayerStashDiscoverable':
  2758. label = GetLocStringByKeyExt( "map_location_playerstash" );
  2759. break;
  2760. case 'Cammerlengo':
  2761. case 'DyeMerchant':
  2762. case 'WineMerchant':
  2763. case 'Shopkeeper':
  2764. case 'Blacksmith':
  2765. case 'Armorer':
  2766. case 'Archmaster':
  2767. case 'Hairdresser':
  2768. label = GetLocStringByKeyExt( StrLower( "map_location_" + targetPin.type ) );
  2769. break;
  2770. case 'Alchemic':
  2771. label = GetLocStringByKeyExt( StrLower( "map_location_alchemic" ) );
  2772. break;
  2773. case 'Herbalist':
  2774. label = GetLocStringByKeyExt( StrLower( "herbalist" ) );
  2775. break;
  2776. case 'Innkeeper':
  2777. label = GetLocStringById( 175619 );
  2778. break;
  2779. case 'Enchanter':
  2780. label = GetLocStringByKeyExt( "panel_map_enchanter_pin_name" );
  2781. break;
  2782. case 'Torch':
  2783. label = GetLocStringByKeyExt( "map_location_torch" );
  2784. break;
  2785. case 'Prostitute':
  2786. label = GetLocStringByKeyExt( "novigrad_courtisan" );
  2787. break;
  2788. case 'ArmorRepairTable':
  2789. label = GetLocStringByKeyExt( "map_location_armor_repair_table" );
  2790. break;
  2791. case 'Herb':
  2792. label= GetLocStringByKeyExt( definitionManager.GetItemLocalisationKeyName( targetPin.tag ) );
  2793. break;
  2794. case 'RoadSign':
  2795. label = GetLocStringByKeyExt( StrLower( "map_location_" + targetPin.tag ) );
  2796. break;
  2797. case 'NoticeBoard':
  2798. case 'NoticeBoardFull':
  2799. label = GetLocStringByKeyExt( StrLower( "map_location_noticeboard" ) );
  2800. break;
  2801. case 'Boat':
  2802. label = GetLocStringByKeyExt( StrLower( "panel_hud_boat" ) );
  2803. break;
  2804. case 'User1':
  2805. case 'User2':
  2806. case 'User3':
  2807. case 'User4':
  2808. label = GetLocStringByKeyExt( StrLower( "map_location_user" ) );
  2809. break;
  2810. default:
  2811. if ( targetPin.customNameId != 0 )
  2812. label = GetLocStringById( targetPin.customNameId );
  2813. else
  2814. label = GetLocStringByKeyExt( StrLower( "map_location_" + targetPin.visibleType ) );
  2815. break;
  2816. }
  2817. label = "<font" + GetDescriptionFont() + ">" + label + "</font>";
  2818. return label;
  2819. }
  2820. }
  2821.  
  2822. function Mod3DMarkersSignalCache3DMarkers( questPins : bool )
  2823. {
  2824. //theGame.witcherLog.AddMessage( "Mod3DMarkersSignalCache3DMarkers" );
  2825. ((CR4HudModuleOneliners)((CR4ScriptedHud)theGame.GetHud()).GetHudModule( "OnelinersModule" )).SignalCache3DMarkers( questPins );
  2826. }
  2827. //---=== modFriendlyHUD ===---
Add Comment
Please, Sign In to add comment