Fix classique titles display
[ryzomcore.git] / ryzom / client / data / gamedev / interfaces_v3 / info_player.lua
blob54b2414080777b3fcb260517200d65a4e0625526
1 -- In this file we define functions that serves for info player windows
4 ------------------------------------------------------------------------------------------------------------
5 -- create the game namespace without reseting if already created in an other file.
6 if (game==nil) then
7 game= {};
8 end
11 -- Index of the mission slected during the last session (read from the config file)
12 game.PrevSessionMission = - 1
15 -- flag set to true when the in game db has been initialized
16 game.InGameDbInitialized = false
18 game.WebMissionLastDesc = {}
20 ------------------------------------------------------------------------------------------------------------
21 -- CAP
22 ------------------------------------------------------------------------------------------------------------
23 -- Define the default url listing all caps
24 game.CapUrl = nil
26 game.CapTitle = ""
27 game.CapDesc = ""
28 game.CapInfosUrl = nil
29 game.CapNextUrl = nil
30 game.capExpanded = false
31 game.CapInfos = ""
32 game.keepExpandStatus = false
34 function debug(text, type)
35 end
37 function p(text, type)
38 end
41 ------------------------------------------------------------------------------------------------------------
42 ------------------------------------------------------------------------------------------------------------
43 ------------------------------------------------------------------------------------------------------------
44 -- MAGIC DAMAGE PROTECTIONS
45 ------------------------------------------------------------------------------------------------------------
46 ------------------------------------------------------------------------------------------------------------
47 ------------------------------------------------------------------------------------------------------------
50 ------------------------------------------------------------------------------------------------------------
51 -- From DB, compute the Total Max Magic Absorption, and store in local DB
52 function game:computeMagicProtectTotalAbsorb()
54 -- *** pre compute the table of DB props (if not done)
55 if (self.JewelDBs == nil) then
56 local defList= {
57 'headdress',
58 'earl',
59 'earr',
60 'necklace',
61 'wristl',
62 'wristr',
63 'fingerl',
64 'fingerr',
65 'anklel',
66 'ankler',
69 self.JewelDBs= {};
70 for k,v in pairs(defList) do
71 self.JewelDBs[k]= getDefine(v) .. ':INDEX_IN_BAG';
72 end
73 end
75 -- *** for each jewel, add the magic protection
76 local protectFactor= getDbProp(formatUI('%player_protect_absorbfactor'));
77 local totalProtect= 0;
78 for k,dbJewel in pairs(self.JewelDBs) do
79 -- if the index in bag is not null (ie something present)
80 local indexInBag= getDbProp(dbJewel);
81 if (indexInBag>0) then
82 -- real index in bag is -1
83 indexInBag= indexInBag-1;
84 -- check the sheetId is correct
85 local dbSheet= formatUI('%bag:#1:SHEET', indexInBag);
86 if (getDbProp(dbSheet)~=0) then
87 local protect= getDbProp(formatUI('%bag:#1:QUALITY', indexInBag));
88 -- mul by factor, and add to total protection
89 protect= math.floor(protect * protectFactor / 100);
90 totalProtect= totalProtect + protect;
91 end
92 end
93 end
95 -- *** additionaly, must add the max skill of player (mul by factor)
96 local protect= 0;
97 protect= math.max(protect, getBaseSkillValueMaxChildren(getSkillIdFromName('SF')) );
98 protect= math.max(protect, getBaseSkillValueMaxChildren(getSkillIdFromName('SM')) );
99 protect= math.max(protect, getBaseSkillValueMaxChildren(getSkillIdFromName('SC')) );
100 protect= math.max(protect, getBaseSkillValueMaxChildren(getSkillIdFromName('SH')) );
101 protect= math.floor(protect * protectFactor / 100);
102 totalProtect= totalProtect + protect;
105 -- *** store result
106 setDbProp('UI:VARIABLES:TOTAL_MAGIC_ABSORB', totalProtect);
110 ------------------------------------------------------------------------------------------------------------
111 -- From given DBs, compute the 'Magic protection' tooltip to display
112 function game:tooltipMagicProtect(dbVal, ttFormat)
113 local fmt= i18n.get(ttFormat);
115 -- get the current and max value. minimize the value displayed
116 local val= getDbProp(dbVal);
117 local vMax= getDbProp(formatUI('%player_protect_maxratio'));
118 val= math.min(val, vMax);
120 -- replace value
121 fmt= findReplaceAll(fmt, "%v", tostring(val) );
123 -- replace max text
124 if (val>=vMax) then
125 fmt= findReplaceAll(fmt, "%max", i18n.get('uittProtect_MaxReached') );
126 else
127 fmt= findReplaceAll(fmt, "%max", "" );
130 -- set the tooltip in InterfaceManager
131 setContextHelpText(fmt);
135 ------------------------------------------------------------------------------------------------------------
136 function game:displayMagicProtect(dbVal)
137 -- get values. minimize the value displayed
138 local val= getDbProp(dbVal);
139 local vMax= getDbProp(formatUI('%player_protect_maxratio'));
140 val= math.min(val, vMax);
142 -- get the ui text
143 local ui= getUICaller();
144 local uiText= ui.val;
146 -- set the text (percentage)
147 uiText.uc_hardtext= tostring(val) .. "%";
149 -- set color and global color according to maximum reached or not
150 if(val >= vMax) then
151 uiText.color= '255 240 130 255';
152 uiText.global_color= false;
153 else
154 uiText.color= '255 255 255 255';
155 uiText.global_color= true;
160 ------------------------------------------------------------------------------------------------------------
161 ------------------------------------------------------------------------------------------------------------
162 ------------------------------------------------------------------------------------------------------------
163 -- MAGIC RESISTANCES
164 ------------------------------------------------------------------------------------------------------------
165 ------------------------------------------------------------------------------------------------------------
166 ------------------------------------------------------------------------------------------------------------
169 ------------------------------------------------------------------------------------------------------------
170 -- Compute the current Base Resist (nb maybe negative)
171 function game:getMagicResistBaseLevel()
172 -- its just the max beetween SF, SM and SH/2
173 local vSF= getBaseSkillValueMaxChildren(getSkillIdFromName('SF'));
174 local vSM= getBaseSkillValueMaxChildren(getSkillIdFromName('SM'));
175 local vSH= getBaseSkillValueMaxChildren(getSkillIdFromName('SH'));
176 local val= math.max(vSF, vSM);
177 val= math.max(val, math.floor(vSH/2));
178 -- Yoyo: -25 is an EGS variable. Hardcoded for now
179 val= val-25;
180 return val;
184 ------------------------------------------------------------------------------------------------------------
185 -- Compute the current Max Resist
186 function game:getMagicResistMaxLevel()
187 local mlvl= 25 + self:getMagicResistBaseLevel() + getDbProp(formatUI('%player_resist_maxratio'));
188 return math.max(0,mlvl);
192 ------------------------------------------------------------------------------------------------------------
193 -- From given DBs, compute the 'Magic Resistance' tooltip to display
194 function game:tooltipMagicResist(dbVal, ttFormat)
195 local fmt= i18n.get(ttFormat);
197 -- get the current and max value. minimize the value displayed
198 local val= getDbProp(dbVal);
199 local vMax= self:getMagicResistMaxLevel();
200 val= math.min(val, vMax);
202 -- replace value
203 fmt= findReplaceAll(fmt, "%v", tostring(val) );
205 -- replace max text
206 if (val>=vMax) then
207 fmt= findReplaceAll(fmt, "%max", i18n.get('uittResist_MaxReached') );
208 else
209 fmt= findReplaceAll(fmt, "%max", "" );
212 -- Print Chances to resist agst Elemental spells
213 local casterSpellLvl= self:getMagicResistBaseLevel(); -- choose the skill base level for reference, +25
214 casterSpellLvl= casterSpellLvl+25;
215 casterSpellLvl= math.max(casterSpellLvl, 0);
216 fmt= findReplaceAll(fmt, "%eml", tostring(casterSpellLvl));
217 fmt= findReplaceAll(fmt, "%emr", tostring(getMagicResistChance(true, casterSpellLvl, val)));
219 -- Print Chances to resist against Afflliction spells
220 fmt= findReplaceAll(fmt, "%aml", tostring(casterSpellLvl));
221 fmt= findReplaceAll(fmt, "%amr", tostring(getMagicResistChance(false, casterSpellLvl, val)));
224 -- set the tooltip in InterfaceManager
225 setContextHelpText(fmt);
229 ------------------------------------------------------------------------------------------------------------
230 function game:displayMagicResist(dbVal)
231 -- get values. minimize the value displayed
232 local val= getDbProp(dbVal);
233 local vMax= self:getMagicResistMaxLevel();
234 val= math.min(val, vMax);
236 -- get the ui text
237 local ui= getUICaller();
238 local uiText= ui.val;
240 -- set the text (final value)
241 uiText.uc_hardtext= tostring(val);
243 -- set color and global color according to maximum reached or not
244 if(val >= vMax) then
245 uiText.color= '255 240 130 255';
246 uiText.global_color= false;
247 else
248 uiText.color= '255 255 255 255';
249 uiText.global_color= true;
254 ------------------------------------------------------------------------------------------------------------
255 ------------------------------------------------------------------------------------------------------------
256 ------------------------------------------------------------------------------------------------------------
257 -- NPC WEB BROWSER
258 ------------------------------------------------------------------------------------------------------------
259 ------------------------------------------------------------------------------------------------------------
260 ------------------------------------------------------------------------------------------------------------
263 ------------------------------------------------------------------------------------------------------------
264 function game:initNpcWebPageData()
265 if(self.NpcWebPage==nil) then
266 self.NpcWebPage= {};
267 self.NpcWebPage.UrlTextId= 0;
268 self.NpcWebPage.BrowseDone= false;
269 self.NpcWebPage.WaitingDynStr = false
273 -- TMP TMP for test
274 NicoMagicURL = ""
275 --function nicoTest()
276 -- runCommand("db", "LOCAL:TARGET:CONTEXT_MENU:WEB_PAGE_URL", 45678)
277 -- end
279 ------------------------------------------------------------------------------------------------------------
280 function game:onDrawNpcWebPage()
282 self:initNpcWebPageData();
284 -- if the browse has already been done
285 if(self.NpcWebPage.BrowseDone) then
286 return;
289 -- browse when the url string id is ready
290 if(self.NpcWebPage.UrlTextId ~=0) then
291 local available
292 if config.Local == 1 then
293 available = (NicoMagicURL ~= "")
294 else
295 available = isDynStringAvailable(self.NpcWebPage.UrlTextId)
297 if(available) then
298 local ucUrl
299 if config.Local == 1 then
300 ucUrl = ucstring(NicoMagicURL) -- for test in local mode
301 else
302 ucUrl = getDynString(self.NpcWebPage.UrlTextId);
304 -- browse
305 local uiStr= getUIId(getUICaller());
306 -- if the url
307 local utf8Url = ucUrl:toUtf8()
308 local isRing = string.find(utf8Url, "ring_access_point=1") ~= nil
309 if isRing then
310 getUI("ui:interface:npc_web_browser").active = false
311 runAH(nil, "context_ring_sessions", "")
312 return
313 else
314 local hideWindow = string.find(utf8Url, "_hideWindow=1") ~= nil
315 if hideWindow then
316 getUI("ui:interface:npc_web_browser").active = false
318 self.NpcWebPage.BrowseDone= true;
319 browseNpcWebPage(uiStr, utf8Url, true, 10); -- 'true' is for 'add parameters' here. 10 is standard timeout
321 -- clear undo/redo, to cannot undo to the "please wait" page :)
322 clearHtmlUndoRedo(uiStr);
323 -- if this is a ring window, then only the refresh button to access to filter will be available
324 local isRing = string.find(utf8Url, "ring_access_point=1") ~= nil
325 local browser = getUI("ui:interface:npc_web_browser")
326 browser:find("browse_redo").active = true
327 browser:find("browse_undo").active = true
328 browser:find("browse_refresh").active = true
333 ------------------------------------------------------------------------------------------------------------
334 -- UNUSED???
335 function game:initNpcWebPage()
336 local ui= getUICaller();
337 if(ui~=nil) then
338 setOnDraw(ui, "game:onDrawNpcWebPage()");
342 ------------------------------------------------------------------------------------------------------------
343 function string:split(Pattern)
344 local Results = {}
345 local Start = 1
346 local SplitStart, SplitEnd = string.find(self, Pattern, Start)
347 while(SplitStart)do
348 table.insert(Results, string.sub(self, Start, SplitStart-1))
349 Start = SplitEnd+1
350 SplitStart, SplitEnd = string.find(self, Pattern, Start)
352 table.insert(Results, string.sub(self, Start))
353 return Results
356 function game:getOpenAppPageMessage()
357 local ucUrl = getDynString(self.NpcWebPage.UrlTextId)
358 local url = ucUrl:toUtf8()
359 surl = url:split("&")
360 for i=1,#surl do
361 if surl[i]:sub(1, 12) == "open_message" then
362 return base64.decode(surl[i]:sub(14))
365 return ""
368 function game:onDbChangeAppPage()
369 if getDbProp("UI:VARIABLES:CURRENT_SERVER_TICK") > self.NpcWebPage.Timeout then
370 local npcName = getTargetName()
372 local message = ucstring()
374 local text = game:getOpenAppPageMessage()
375 message:fromUtf8(text)
376 displaySystemInfo(message, "AMB")
377 removeOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK")
381 function game:startNpcWebPage()
382 self:initNpcWebPageData();
384 -- set the new page to explore.
385 -- NB: must backup the Database, because don't want that the page change when clicking an other NPC
386 if not self.NpcWebPage.WaitingDynStr then
387 self.NpcWebPage.UrlTextId = getDbProp("LOCAL:TARGET:CONTEXT_MENU:WEB_PAGE_URL");
389 self.NpcWebPage.BrowseDone = false;
391 available = isDynStringAvailable(self.NpcWebPage.UrlTextId)
392 if available then
393 if self.NpcWebPage.WaitingDynStr then
394 self.NpcWebPage.WaitingDynStr = false
395 removeOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK")
397 local ucUrl = getDynString(self.NpcWebPage.UrlTextId)
398 local utf8Url = ucUrl:toUtf8()
400 if utf8Url:sub(1, 4) == "http" then
401 runAH(nil, "browse", "name=ui:interface:npc_web_browser:content:html|url=release_wk.html|localize=1");
402 clearHtmlUndoRedo("ui:interface:npc_web_browser:content:html");
403 local ui= getUI("ui:interface:npc_web_browser");
404 if(ui~=nil) then
405 ui.active= true;
407 ui:find("browse_redo").active = false
408 ui:find("browse_undo").active = false
409 ui:find("browse_refresh").active = false
410 else
411 setTargetAsInterlocutor()
412 self.NpcWebPage.Timeout = getDbProp("UI:VARIABLES:CURRENT_SERVER_TICK")+7
413 addOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK", "game:onDbChangeAppPage()")
415 -- App url, need sign it with server
416 runCommand("a", "openTargetApp", utf8Url)
418 else
419 self.NpcWebPage.WaitingDynStr = true
420 addOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK", "game:startNpcWebPage()")
424 ------------------------------------------------------------------------------------------------------------
426 function game:closeNpcWebBrowserHeader()
427 local ui = getUI('ui:interface:npc_web_browser');
429 -- save size
430 ui_npc_web_browser_h = ui.h;
431 ui_npc_web_browser_w = ui.w;
433 -- reduce window size
434 ui.pop_min_h = 32;
435 ui.h = 0;
436 ui.w = 150;
439 ------------------------------------------------------------------------------------------------------------
441 function game:openNpcWebBrowserHeader()
442 local ui = getUI('ui:interface:npc_web_browser');
443 ui.pop_min_h = 96;
445 -- set size from saved values
446 if (ui_npc_web_browser_h ~= nil) then
447 ui.h = ui_npc_web_browser_h;
450 if (ui_npc_web_browser_w ~= nil) then
451 ui.w = ui_npc_web_browser_w;
456 ------------------------------------------------------------------------------------------------------------
457 ------------------------------------------------------------------------------------------------------------
458 -- FAME
459 ------------------------------------------------------------------------------------------------------------
460 ------------------------------------------------------------------------------------------------------------
461 ------------------------------------------------------------------------------------------------------------
463 ------------------------------------------------------------------------------------------------------------
464 function game:initFameTribe()
465 local ui = getUICaller();
467 local firstIdx = getFirstTribeFameIndex();
468 local firstDBIdx = getFameDBIndex(firstIdx);
469 local nbFame = getNbTribeFameIndex();
471 for c = 1,nbFame do
472 local lineIdx = getFameDBIndex(firstIdx+c-1) - firstDBIdx;
473 local uiLine = getUI(getUIId(ui) .. ':list:line' .. lineIdx);
474 uiLine.t.hardtext = 'uiFame_' .. getFameName(firstIdx+c-1);
479 ------------------------------------------------------------------------------------------------------------
480 function game:updateFameBar(path)
481 local ui = getUICaller();
482 local thresholdKOS = getDbProp('SERVER:FAME:THRESHOLD_KOS');
483 local thresholdTrade = getDbProp('SERVER:FAME:THRESHOLD_TRADE');
484 local fameValue = getDbProp(path .. ':VALUE');
485 local fameMax = getDbProp(path .. ':THRESHOLD');
487 -- known/unknown fame
488 local fameVisible = fameValue ~= -128
489 if fameVisible then
490 -- show unmodified value stored in #path:VALUE
491 ui.t.hardtext = fameValue
492 else
493 ui.t.hardtext = "?"
495 -- show/hide fame bar components
496 ui.m.active = fameVisible
497 ui.p0.active = fameVisible
498 ui.p1.active = fameVisible
499 ui.p2.active = fameVisible
500 ui.p3.active = fameVisible
501 ui.p4.active = fameVisible
502 ui.bar3d.active = fameVisible
504 if (thresholdKOS < -100) then thresholdKOS = -100; end
505 if (thresholdKOS > 100) then thresholdKOS = 100; end
506 if (thresholdTrade < -100) then thresholdTrade = -100; end
507 if (thresholdTrade > 100) then thresholdTrade = 100; end
508 if (fameValue < -100) then fameValue = -100; end
509 if (fameValue > 100) then fameValue = 100; end
510 if (fameMax < -100) then fameMax = -100; end
511 if (fameMax > 100) then fameMax = 100; end
513 if (thresholdKOS > thresholdTrade) then thresholdKOS = thresholdTrade; end
514 if (fameValue > fameMax) then fameValue = fameMax; end
516 local uiPart0 = ui.p0;
517 local uiPart1 = ui.p1;
518 local uiPart2 = ui.p2;
519 local uiPart3 = ui.p3;
520 local uiPart4 = ui.p4;
521 local uiBar3d = ui.bar3d;
522 -- part 4 is there to fill in the hole
524 local barW = ui.w - 4;
525 local barX = 2;
527 local bar3dStart= barX + barW/2;
528 local bar3dLimit= bar3dStart;
530 -- init part 0 of the bar
531 uiPart0.x = barX;
532 ui.ttp0.x = barX;
533 ui.ttp0.w = barW * (thresholdKOS + 100) / 200;
534 if (fameValue >= -100) and (fameValue <= thresholdKOS) then
535 uiPart0.color = '80 0 0 255';
536 uiPart0.w = barW * (fameValue + 100) / 200;
538 uiPart4.color = '255 0 0 255';
539 uiPart4.x = uiPart0.x + uiPart0.w;
540 uiPart4.w = barW * (thresholdKOS - fameValue) / 200;
542 bar3dLimit= uiPart4.x;
543 else
544 uiPart0.color= '80 0 0 255';
545 uiPart0.w = barW * (thresholdKOS + 100) / 200;
548 -- init part 1 of the bar
549 local part1X= barX + barW * (thresholdKOS + 100) / 200;
550 local part1TotalW= barW * (thresholdTrade - thresholdKOS) / 200;
551 uiPart1.x = part1X;
552 ui.ttp1.x = part1X;
553 ui.ttp1.w = part1TotalW;
554 if (fameValue >= thresholdKOS) and (fameValue <= thresholdTrade) then
555 uiPart1.color = '80 40 0 255';
556 uiPart1.w = barW * (fameValue - thresholdKOS) / 200;
558 uiPart4.color = '255 127 0 255';
559 uiPart4.x = uiPart1.x + uiPart1.w;
560 uiPart4.w = barW * (thresholdTrade - fameValue) / 200;
562 bar3dLimit= uiPart4.x;
563 else
564 if (fameValue < thresholdKOS) then
565 uiPart1.color = '255 127 0 255';
566 else
567 uiPart1.color = '80 40 0 255';
569 uiPart1.w = part1TotalW;
572 -- init part 2 of the bar
573 local part2X= barX + barW * (thresholdTrade + 100) / 200;
574 local part2TotalW= barW * (0 - thresholdTrade) / 200;
575 uiPart2.x = part2X;
576 ui.ttp2.x = part2X;
577 ui.ttp2.w = part2TotalW;
578 if (fameValue >= thresholdTrade) and (fameValue <= 0) then
579 uiPart2.color = '80 80 0 255';
580 uiPart2.w = barW * (fameValue - thresholdTrade) / 200;
582 uiPart4.color = '255 255 0 255';
583 uiPart4.x = uiPart2.x + uiPart2.w;
584 uiPart4.w = barW * (0 - fameValue) / 200;
586 bar3dLimit= uiPart4.x;
587 else
588 if (fameValue < thresholdTrade) then
589 uiPart2.color = '255 255 0 255';
590 else
591 uiPart2.color = '80 80 0 255';
593 uiPart2.w = part2TotalW;
596 -- init part 3 of the bar
597 local part3X= barX + barW * (0 + 100) / 200;
598 local part3TotalW= barW * (100 - 0) / 200;
599 uiPart3.x = part3X;
600 ui.ttp3.x = part3X;
601 ui.ttp3.w = part3TotalW;
602 if (fameValue >= 0) and (fameValue <= 100) then
603 uiPart3.color = '0 255 0 255';
604 uiPart3.w = barW * (fameValue - 0) / 200;
606 uiPart4.color = '0 80 0 255';
607 uiPart4.x = uiPart3.x + uiPart3.w;
608 uiPart4.w = barW * (100 - fameValue) / 200;
610 bar3dLimit= uiPart4.x;
611 else
612 uiPart3.color = '0 80 0 255';
613 uiPart3.w = part3TotalW;
616 -- init max limit
617 local uiMaxLimit = ui.m;
618 uiMaxLimit.x = barX + barW * (fameMax + 100) / 200;
620 -- init bar3d
621 if (bar3dStart < bar3dLimit) then
622 uiBar3d.x= bar3dStart;
623 uiBar3d.w= bar3dLimit-bar3dStart;
624 else
625 uiBar3d.x= bar3dLimit;
626 uiBar3d.w= bar3dStart - bar3dLimit;
631 ------------------------------------------------------------------------------------------------------------
632 function game:updateFameBarTT(path)
633 local fameMax = getDbProp(path .. ':THRESHOLD');
635 local text = i18n.get('uittFameMaxPossible');
636 text = findReplaceAll(text, '%famemax', tostring(fameMax));
637 setContextHelpText(text);
640 ------------------------------------------------------------------------------------------------------------
641 function game:getPvpEffects()
642 local uiGroup= getUICaller();
643 local n = 59-1;
644 local i;
645 local hasBonus = false;
646 local hasMalus = false;
648 local text = ''
649 local textBonus = '';
650 local textMalus = '';
651 local fmt;
653 -- check every malus and bonus
654 for i=0, n do
655 local path = formatUI('SERVER:PVP_EFFECTS:#1', i);
656 local id = getDbProp(path .. ':ID');
657 if (id ~= 0) then
658 local isBonus = getDbProp(path .. ':ISBONUS');
659 local param = getDbProp(path .. ':PARAM');
660 if (isBonus == 1) then
661 hasBonus = true;
662 fmt = i18n.get('uiPvPEffect_' .. getRegionByAlias(id) .. '_Bonus');
663 fmt = replacePvpEffectParam(fmt, param);
664 if (textBonus ~= '') then
665 textBonus = concatUCString(textBonus, '\n\n');
667 textBonus = concatUCString(textBonus, fmt);
668 else
669 hasMalus = true;
670 fmt = i18n.get('uiPvPEffect_' .. getRegionByAlias(id) .. '_Malus');
671 fmt = replacePvpEffectParam(fmt, param);
672 if (textMalus ~= '') then
673 textMalus = concatUCString(textMalus, '\n\n');
675 textMalus = concatUCString(textMalus, fmt);
676 end;
680 if (hasBonus) then
681 uiGroup.pvpEffectsBonusMalusInfo.uc_hardtext_format = i18n.get('uiPvpEffectBonus');
682 uiGroup.pvpEffectsBonusMalus.uc_hardtext_format = textBonus;
683 elseif (hasMalus) then
684 uiGroup.pvpEffectsBonusMalusInfo.uc_hardtext_format = i18n.get('uiPvpEffectMalus');
685 uiGroup.pvpEffectsBonusMalus.uc_hardtext_format = textMalus;
686 else
687 uiGroup.pvpEffectsBonusMalusInfo.uc_hardtext_format = '';
688 uiGroup.pvpEffectsBonusMalus.uc_hardtext_format = '';
693 ------------------------------------------------------------------------------------------------------------
694 function game:getFactionName(id)
695 if (id == self.TPVPClan.Kami) then
696 return i18n.get('uiFameKami');
697 elseif (id == self.TPVPClan.Karavan) then
698 return i18n.get('uiFameKaravan');
699 elseif (id == self.TPVPClan.Fyros) then
700 return i18n.get('uiFameFyros');
701 elseif (id == self.TPVPClan.Matis) then
702 return i18n.get('uiFameMatis');
703 elseif (id == self.TPVPClan.Tryker) then
704 return i18n.get('uiFameTryker');
705 elseif (id == self.TPVPClan.Zorai) then
706 return i18n.get('uiFameZorai');
707 else
708 return i18n.get('Unknown');
712 ------------------------------------------------------------------------------------------------------------
713 function game:getAllegiancePoints()
714 local path = 'SERVER:PVP_EFFECTS:PVP_FACTION_POINTS';
715 local civ = getDbProp(path .. ':CIV');
716 local civPoints = getDbProp(path .. ':CIV_POINTS');
717 local cult = getDbProp(path .. ':CULT');
718 local cultPoints = getDbProp(path .. ':CULT_POINTS');
720 local text;
721 local uiGroup= getUICaller();
723 -- civ allegiance
724 if (civ == self.TPVPClan.None or civ == self.TPVPClan.Neutral) then
725 text = i18n.get('uiPvpFameNoCivAllegiance');
726 else
727 text = i18n.get('uiPvpFameAllegiancePoints');
728 text = findReplaceAll(text, '%faction', self:getFactionName(civ));
729 text = findReplaceAll(text, '%points', tostring(civPoints));
731 uiGroup.civ_allegiance_pts.uc_hardtext_format = text;
733 -- cult allegiance
734 if (cult == self.TPVPClan.None or cult == self.TPVPClan.Neutral) then
735 text = i18n.get('uiPvpFameNoCultAllegiance');
736 else
737 text = i18n.get('uiPvpFameAllegiancePoints');
738 text = findReplaceAll(text, '%faction', self:getFactionName(cult));
739 text = findReplaceAll(text, '%points', tostring(cultPoints));
741 uiGroup.cult_allegiance_pts.uc_hardtext_format = text;
744 ------------------------------------------------------------------------------------------------------------
745 function game:updateAllegiance(path, uiText)
746 local alleg = getDbProp(path);
748 local text = i18n.get('uiFameAllegiance' .. tostring(alleg) );
749 getUICaller()[uiText].uc_hardtext= text;
752 ------------------------------------------------------------------------------------------------------------
753 function game:fameAllegianceTooltipCiv()
754 local enum= getDbProp('SERVER:FAME:CIV_ALLEGIANCE');
755 -- set the tooltip in InterfaceManager
756 setContextHelpText( i18n.get('uittFameAllegianceCiv' .. tostring(enum)) );
759 ------------------------------------------------------------------------------------------------------------
760 function game:fameAllegianceTooltipCult()
761 local enum= getDbProp('SERVER:FAME:CULT_ALLEGIANCE');
762 -- set the tooltip in InterfaceManager
763 setContextHelpText( i18n.get('uittFameAllegianceCult' .. tostring(enum)) );
766 ------------------------------------------------------------------------------------------------------------
767 function game:fameAllegianceTooltipCivGuild()
768 local enum= getDbProp('SERVER:GUILD:FAME:CIV_ALLEGIANCE');
769 -- set the tooltip in InterfaceManager
770 setContextHelpText( i18n.get('uittFameAllegianceCivGuild' .. tostring(enum)) );
773 ------------------------------------------------------------------------------------------------------------
774 function game:fameAllegianceTooltipCultGuild()
775 local enum= getDbProp('SERVER:GUILD:FAME:CULT_ALLEGIANCE');
776 -- set the tooltip in InterfaceManager
777 setContextHelpText( i18n.get('uittFameAllegianceCultGuild' .. tostring(enum)) );
780 ------------------------------------------------------------------------------------------------------------
782 function game:tooltipDeltaValue(base, max)
783 -- Calculate delta
784 local val = max - base;
786 local text;
787 if (val == 0) then
788 text = concatUCString('@{FFFF}', tostring(max));
789 else
790 if (val > 0) then
791 -- bonus
792 text = concatUCString('@{FFFF}', tostring(max));
793 text = concatUCString(text, ' (');
794 text = concatUCString(text, tostring(base));
795 text = concatUCString(text, '@{0F0F}');
796 text = concatUCString(text, ' + ');
797 text = concatUCString(text, tostring(val));
798 text = concatUCString(text, '@{FFFF}');
799 text = concatUCString(text, ')');
800 else
801 -- malus
802 text = concatUCString('@{FFFF}', tostring(max));
803 text = concatUCString(text, ' (');
804 text = concatUCString(text, tostring(base));
805 text = concatUCString(text, '@{E42F}');
806 text = concatUCString(text, ' - ');
807 text = concatUCString(text, tostring(math.abs(val)));
808 text = concatUCString(text, '@{FFFF}');
809 text = concatUCString(text, ')');
813 return text;
817 ------------------------------------------------------------------------------------------------------------
819 function game:tooltipScore(dbBase, dbMax, ttFormat)
820 -- Get DB values
821 local base = getDbProp(dbBase);
822 local max = getDbProp(dbMax);
824 -- Tooltip text
825 local fmt = i18n.get(ttFormat);
826 local text = self:tooltipDeltaValue(base, max);
827 fmt = findReplaceAll(fmt, "%n", text );
829 -- Set tooltip
830 setContextHelpText(fmt);
833 ------------------------------------------------------------------------------------------------------------
835 function game:tooltipScoreEP(dbBase, dbMax, ttFormat, dbLvl, dbMod)
836 -- Defender level
837 local defLvl= getDbProp(formatUI(dbLvl));
838 defLvl = math.max(0, defLvl);
840 -- Attacker level
841 local attLvl = getBaseSkillValueMaxChildren(getSkillIdFromName('SF'));
843 -- Get DB values
844 local base = getDbProp(dbBase);
845 local max = getDbProp(dbMax);
846 local chance = getDodgeParryChance(attLvl, defLvl);
847 local mod = getDbProp(dbMod);
848 local maxChance = chance + mod;
850 -- Tooltip text
851 local fmt = i18n.get(ttFormat);
852 local text = self:tooltipDeltaValue(base, max);
853 local textChance = self:tooltipDeltaValue(chance, maxChance);
854 fmt = findReplaceAll(fmt, "%n", text );
855 fmt = findReplaceAll(fmt, "%l", tostring(attLvl));
856 fmt = findReplaceAll(fmt, "%p", textChance);
858 -- Set tooltip
859 setContextHelpText(fmt);
865 -------------------------------------------------------------------------------------------------------------
866 ---------------------------------- RING STATS ---------------------------------------------------
867 -------------------------------------------------------------------------------------------------------------
869 RingPlayerInfo =
871 WaitingInfo = false,
872 LastRefreshTime = 0,
873 InfoReceived = false,
874 PendingRefresh = false,
875 WaitingPeriod = 15,
876 RefreshPeriod = 10,
877 MinRefreshPeriod = 4,
878 LastRefreshQuerryTime = 0,
881 --------------------------------------------------------------------------------------------------------------
883 function RingPlayerInfo:getWindow()
884 local ui = getUI("ui:interface:info_player_skills")
885 assert(ui)
886 return ui
889 --------------------------------------------------------------------------------------------------------------
891 function RingPlayerInfo:initRingStatPlayer()
893 setOnDraw(self:getWindow(), "RingPlayerInfo:onRingRatingPlayerDraw()")
896 --------------------------------------------------------------------------------------------------------------
898 function RingPlayerInfo:onRingRatingPlayerDraw()
900 local timeInSec = nltime.getLocalTime() / 1000
901 if self.WaitingInfo then
902 if timeInSec - self.LastRefreshTime > self.WaitingPeriod then
903 self.WaitingInfo = false
904 self.LastRefreshTime = nltime.getLocalTime() / 1000
905 else
906 if not self.InfoReceived then
907 --debugInfo("No received info")
910 else
911 if timeInSec - self.LastRefreshTime > self.RefreshPeriod then
912 self:refresh()
913 else
914 --debugInfo("pas de refresh")
917 self:updatePendingRefresh()
921 --------------------------------------------------------------------------------------------------------------
923 function RingPlayerInfo:updatePendingRefresh()
925 if self.PendingRefresh then
926 local currTime = nltime.getLocalTime() / 1000
927 if currTime - self.LastRefreshQuerryTime > self.MinRefreshPeriod and game.getRingStats then
928 self.LastRefreshQuerryTime = currTime
929 self.PendingRefresh = false
930 game.getRingStats()
935 --------------------------------------------------------------------------------------------------------------
937 function RingPlayerInfo:onRingStatsPlayerReceving(ringPoints)
939 self.WaitingInfo = false
940 self.LastRefreshTime = nltime.getLocalTime() / 1000
941 self.InfoReceived = true
943 self:fill(ringPoints)
946 function RingPlayerInfo:fill(ringPoints)
948 self.InfoReceived = false
950 local ui = self:getWindow()
952 -- author Rating
953 -- local authorRR = ui:find("author_ring_rating")
954 -- local jaugeUI = authorRR:find("jauge_bar")
955 -- local levelUI = authorRR:find("level_rating")
956 -- local tooltipUI = authorRR:find("tt")
957 -- local level, progress = self:getLevelRatingAndImprovementRate(ringPoints.AuthorRating)
958 -- jaugeUI.w = progress*156
959 -- local texturename = ""
960 -- if level~=0 then texturename = "r2ed_ring_rating_" .. level .. ".tga" end
961 -- levelUI.texture = texturename
962 -- tooltipUI.tooltip = self:tooltipRingRating(level, progress, "uiR2EDAuthorRingRatingTooltip")
964 -- AM Rating
965 -- local AMRR = ui:find("am_ring_rating")
966 -- jaugeUI = AMRR:find("jauge_bar")
967 -- levelUI = AMRR:find("level_rating")
968 -- tooltipUI = AMRR:find("tt")
969 -- level, progress = self:getLevelRatingAndImprovementRate(ringPoints.AMRating)
970 -- jaugeUI.w = progress*156
971 -- texturename = ""
972 -- if level~=0 then texturename = "r2ed_ring_rating_" .. level .. ".tga" end
973 -- levelUI.texture = texturename
974 -- tooltipUI.tooltip = self:tooltipRingRating(level, progress, "uiR2EDAMRingRatingTooltip")
976 -- masterless Rating
977 -- local masterlessRR = ui:find("masterless_ring_rating")
978 -- jaugeUI = masterlessRR:find("jauge_bar")
979 -- levelUI = masterlessRR:find("level_rating")
980 -- tooltipUI = masterlessRR:find("tt")
981 -- level, progress = self:getLevelRatingAndImprovementRate(ringPoints.MasterlessRating)
982 -- jaugeUI.w = progress*156
983 -- texturename = ""
984 -- if level~=0 then texturename = "r2ed_ring_rating_" .. level .. ".tga" end
985 -- levelUI.texture = texturename
986 -- tooltipUI.tooltip = self:tooltipRingRating(level, progress, "uiR2EDMasterlessRingRatingTooltip")
988 -- ecosystem Points
989 local ecosystems = {"Basic", "Desert", "Subtropic", "Forest", "Jungle", "PrimeRoot"}
990 for k, eco in pairs(ecosystems) do
991 local ecoVal = tostring(ringPoints[eco.."RingPoints"])
992 local ecoValMax = tostring(ringPoints["Max" .. eco.."RingPoints"])
993 local ecoUI = ui:find(string.lower(eco))
994 local maxUI = ecoUI:find("max")
995 local valUI = ecoUI:find("val")
996 tooltipUI = ecoUI:find("tt")
997 maxUI.hardtext = ecoValMax
998 valUI.hardtext = ecoVal
999 tooltipUI.tooltip = self:tooltipEcosystemPoints(ecoVal, ecoValMax, "uiR2ED" .. eco .. "PointsTooltip")
1003 --------------------------------------------------------------------------------------------------------------
1005 function RingPlayerInfo:refresh()
1007 self.PendingRefresh = true
1008 self.LastRefreshTime = nltime.getLocalTime() / 1000
1009 self.WaitingInfo = true
1012 --------------------------------------------------------------------------------------------------------------
1014 function RingPlayerInfo:tooltipEcosystemPoints(rp, maxRp, ttFormat)
1016 -- Tooltip text
1017 local fmt = i18n.get(ttFormat);
1018 fmt = findReplaceAll(fmt, "%n", rp );
1019 fmt = findReplaceAll(fmt, "%p", maxRp );
1021 -- Set tooltip
1022 return fmt;
1026 ------------------------------------------------------------------------------------------------------------
1027 function RingPlayerInfo:updateRRPSLevel(dbVal, tooltip)
1030 -- get values. minimize the value displayed
1031 local val= getDbProp(dbVal);
1033 -- get the ui text
1034 local ui= getUICaller();
1035 local uiText= ui.val;
1037 -- set the text
1038 uiText.uc_hardtext= tostring(val)
1040 self:tooltipRRPs(dbVal, tooltip)
1043 --------------------------------------------------------------------------------------------------------------
1045 function RingPlayerInfo:tooltipRRPs(dbBase, ttFormat)
1047 local val = getDbProp(dbBase);
1049 -- Tooltip text
1050 local fmt = i18n.get(ttFormat);
1051 local text = tostring(val)
1052 fmt = findReplaceAll(fmt, "%n", text );
1054 -- Set tooltip
1055 setContextHelpText(fmt);
1059 --------------------------------------------------------------------------------------------------------------
1061 function RingPlayerInfo:tooltipRingRating(level, progress, ttFormat)
1063 -- Tooltip text
1064 local fmt = i18n.get(ttFormat);
1065 progress = math.floor(progress*100)
1066 fmt = findReplaceAll(fmt, "%n", tostring(level));
1067 fmt = findReplaceAll(fmt, "%p", tostring(progress));
1068 -- Set tooltip
1069 return fmt;
1072 --------------------------------------------------------------------------------------------------------------
1074 function RingPlayerInfo:getLevelRatingAndImprovementRate(val)
1076 val = val / 100
1077 local level = 0
1078 local maxRatingInLevel = 0
1079 local minRatingInLevel = 0
1081 for i=0,9 do
1082 level = i
1083 minRatingInLevel = maxRatingInLevel
1084 maxRatingInLevel = maxRatingInLevel + math.pow(4, i+1)
1085 if maxRatingInLevel>val then break end
1088 local progress = (val-minRatingInLevel)/(maxRatingInLevel-minRatingInLevel)
1090 return level, progress
1093 --------------------------------------------------------------------------------------------------------------
1095 function game:updateOrganization(path, uiOrgText, uiStatusText, uiPointsText)
1097 local org = getDbProp(path.."1:VALUE")
1098 getUICaller()[uiOrgText].uc_hardtext = i18n.get('uiOrganization_' .. org)
1100 local status = getDbProp(path.."2:VALUE")
1101 getUICaller()[uiStatusText].uc_hardtext= status
1103 local points = getDbProp(path.."3:VALUE")
1104 getUICaller()[uiPointsText].uc_hardtext= points
1108 ------------------------------------------------------------------------------------------------------------
1109 function game:organizationTooltip()
1110 -- set the tooltip in InterfaceManager
1111 setContextHelpText( i18n.get('uittOrganization') );
1115 --------------------------------------------------------------------------------------------------------------
1116 function game:popMissionList()
1117 local menu = getUI("ui:interface:mission_cb_menu")
1118 enableModalWindow(getUICaller(), "ui:interface:mission_cb_menu")
1119 self:updateMissionMenuSize()
1124 --------------------------------------------------------------------------------------------------------------
1125 function game:getGroupMissionFirstIndex()
1126 return tonumber(getDefine("ipj_nb_mission"))
1129 --------------------------------------------------------------------------------------------------------------
1130 function game:getMissionDbPath(missionIndex)
1131 local numMissions = game:getGroupMissionFirstIndex()
1132 if missionIndex >= numMissions then -- group mission ?
1133 return "SERVER:GROUP:MISSIONS:" .. tostring(missionIndex - numMissions)
1134 else
1135 return "SERVER:MISSIONS:" .. tostring(missionIndex)
1139 --------------------------------------------------------------------------------------------------------------
1140 function game:getCurrMissionIndex()
1141 local result = getDbProp("UI:SAVE:MISSION_SELECTED")
1142 return result
1145 function game:getCurrGroupMissionIndex()
1146 return getDbProp("UI:SAVE:MISSION_SELECTED") - tonumber(getDefine("ipj_nb_mission"))
1150 --------------------------------------------------------------------------------------------------------------
1151 function game:updateCurrMissionComboBox()
1152 local numMissions = tonumber(getDefine("ipj_nb_mission"))
1153 local missionFound = false
1154 local cb = getUI("ui:interface:info_player_journal:content:mission_combo")
1155 local missionList = getUI("ui:interface:info_player_journal:content:mission_list")
1156 for i = 0, numMissions - 1 do
1157 if getDbProp("SERVER:MISSIONS:" .. i .. ":TITLE") ~= 0
1158 or getDbProp("SERVER:GROUP:MISSIONS:" .. i .. ":TITLE") ~= 0 then
1159 missionFound = true
1160 break
1163 if not missionFound then
1164 cb.arrow.active = false
1165 cb.mission_ico.active = false
1166 cb.mission_title.active = false
1167 cb.select.active = false
1168 cb.no_selected_mission.active = false
1169 cb.no_available_mission.active = true
1170 missionList.no_selected_mission.active = false
1171 missionList.no_available_mission.active = true
1172 return
1174 cb.no_available_mission.active = false
1175 missionList.no_available_mission.active = false
1176 cb.arrow.active = true
1177 cb.select.active = true
1178 local currMission = self:getCurrMissionIndex()
1180 local dbPath = self:getMissionDbPath(currMission)
1182 local selected = (currMission ~= -1)
1183 if selected then
1184 cb.mission_title.textid_dblink = dbPath .. ":TITLE"
1185 selected = (tile ~= 0)
1187 cb.mission_ico.active = selected
1188 cb.mission_title.active = selected
1189 cb.no_selected_mission.active = not selected
1190 missionList.no_selected_mission.active = not selected
1191 if selected then
1192 if getDbProp(dbPath .. ":FINISHED") == 0 then
1193 cb.mission_ico.texture = runExpr("getMissionSmallIcon(" .. tostring(getDbProp(dbPath .. ":ICON") .. ")"))
1194 elseif getDbProp(dbPath .. ":FINISHED") == 1 then
1195 cb.mission_ico.texture = "Small_Task_Done.tga"
1196 else
1197 cb.mission_ico.texture = "Small_Task_Failed.tga"
1202 --------------------------------------------------------------------------------------------------------------
1203 function game:onMissionSelected(index)
1204 disableModalWindow()
1205 self:updateCurrMissionComboBox()
1206 game.WebMissionLastDesc = {}
1207 setOnDraw(getMissionWindow(), "game:ensureWebMissionVisibility()")
1210 --------------------------------------------------------------------------------------------------------------
1211 function game:onGroupMissionSelected(index)
1212 disableModalWindow()
1213 self:updateCurrMissionComboBox()
1216 --------------------------------------------------------------------------------------------------------------
1217 function game:onMissionDBIndexChanged()
1218 local missionIndex = self:getCurrMissionIndex()
1219 if missionIndex < 0 then return end
1220 -- if selection was made from the list, update the other list
1221 if missionIndex >= self:getGroupMissionFirstIndex() then
1222 local groupMissionIndex = missionIndex - self:getGroupMissionFirstIndex()
1223 getUI("ui:interface:info_player_journal:content:mission_list:b_group_title" .. tostring(groupMissionIndex)).pushed = true
1224 getUI("ui:interface:mission_cb_menu:mission_list:b_group_title" .. tostring(groupMissionIndex)).pushed = true
1225 else
1226 getUI("ui:interface:info_player_journal:content:mission_list:b_title" .. tostring(missionIndex)).pushed = true
1227 getUI("ui:interface:mission_cb_menu:mission_list:b_title" .. tostring(missionIndex)).pushed = true
1229 game:updateMissionWindowLayout()
1232 --------------------------------------------------------------------------------------------------------------
1233 function game:onMissionTitleChanged(index)
1234 -- if title is not nil then a new mission has been added -> if db initilization is over, then selected this new mission
1235 if getDbProp(self:getMissionDbPath(index) .. ":TITLE") ~= 0 then
1236 if game.InGameDbInitialized or config.Local then
1237 self:setCurrentMission(index)
1239 else
1240 self:updateCurrMissionComboBox()
1241 self:updateMissionMenuSize()
1244 --------------------------------------------------------------------------------------------------------------
1245 function game:onGroupMissionTitleChanged(index)
1246 if getDbProp(self:getMissionDbPath(index + 15) .. ":TITLE") ~= 0 then
1247 if game.InGameDbInitialized or config.Local then
1248 self:setCurrentMission(index + 15)
1250 else
1251 self:updateCurrMissionComboBox()
1252 self:updateMissionMenuSize()
1256 --------------------------------------------------------------------------------------------------------------
1257 function game:updateMissionMenuSize()
1258 local parentCB = getUI("ui:interface:info_player_journal:content:mission_combo")
1259 local menu = getUI("ui:interface:mission_cb_menu")
1261 if not menu.active then
1262 return
1265 local maxNumMissions = 2 * self:getGroupMissionFirstIndex()
1266 local missionCount = 0
1267 for k = 0, maxNumMissions - 1 do
1268 if getDbProp(self:getMissionDbPath(k) .. ":TITLE") ~= 0 then
1269 missionCount = missionCount + 1
1272 menu.h = 8 + missionCount * 18
1273 menu.y = 0
1274 menu:updateCoords()
1275 local y = parentCB.y_real - menu.h_real - 1
1276 if y < 0 then
1277 y = parentCB.y_real + parentCB.h_real + 1
1279 local scrW
1280 local scrH
1281 scrW, scrH = getWindowSize()
1282 if y + menu.h > scrH then
1283 y = scrH - menu.h
1285 menu.w = parentCB.w_real
1286 menu.y = y
1287 menu.x = parentCB.x_real
1288 menu.h = 8 + missionCount * 18
1289 menu:invalidateCoords()
1292 function game:parseLangText(text)
1293 if text == nil then
1294 return ""
1296 local final = ""
1297 local work = ""
1298 local translated = ""
1299 local stext = text:split("[[]")
1300 for k, v in pairs(stext) do
1301 if string.sub(v, 3, 3) == "]" then
1302 if string.sub(v, 1, 2):upper() == getClientCfg("LanguageCode"):upper() then
1303 work = ""
1304 translated = string.sub(v, 4)
1305 elseif string.sub(v, 1, 2):upper() == "WK" and translated == "" then
1306 work = string.sub(v, 4)
1308 else
1309 if k > 1 then
1310 final = final .. "["
1312 final = final .. v
1315 return final .. work .. translated
1318 function game:onOverCap()
1319 local ui = getUI("ui:interface:cap")
1320 mx, my = getMousePos()
1321 -- Inside
1322 if mx > ui.x and mx < ui.x + ui.w and my < ui.y and my > ui.y - ui.h then
1323 if getCurrentWindowUnder() == ui then
1324 if game.keepExpandStatus or ui.opened == false then return end
1325 if game.capExpanded == false then
1326 game:expandCapWeb(true)
1329 else
1330 -- Outside
1331 if game.keepExpandStatus or ui.opened == false then return end
1332 if mx < ui.x or mx > ui.x + ui.w or my > ui.y or my < ui.y - ui.h then
1333 if game.capExpanded then
1334 game:expandCapWeb(false)
1340 function game:expandCapWeb(expand)
1341 local ui = getUI("ui:interface:cap")
1342 if expand then
1343 setTopWindow(ui)
1344 game.capExpanded = true
1345 ui.pop_min_h = game.ui_cap_expanded_h
1346 ui.pop_max_h = game.ui_cap_expanded_h + 1
1347 ui:find("header_opened").h = game.ui_cap_expanded_h - 16
1348 else
1349 game.capExpanded = false
1350 ui.pop_min_h = game.ui_cap_collapsed_h
1351 ui.pop_max_h = game.ui_cap_collapsed_h+1
1352 ui:find("header_opened").h = game.ui_cap_collapsed_h - 16
1356 function game:keepExpandCapWeb(force)
1357 local ui = getUI("ui:interface:cap")
1358 if force ~= nil then
1359 game.keepExpandStatus = not force
1362 if game.keepExpandStatus == false then
1363 game.keepExpandStatus = true
1364 ui:find("right").texture = "w_win_lock.tga"
1365 else
1366 game.keepExpandStatus = false
1367 ui:find("right").texture = "grey_0.tga"
1372 function game:onCapResize()
1373 local ui = getUI("ui:interface:cap")
1374 local web = ui:find("html")
1375 web.w = ui.w - 18
1378 game.ui_cap_collapsed_h = 65
1379 game.ui_cap_expanded_h = 280
1380 game.ui_cap_w = 292
1382 function game:closeCapHeader()
1383 local ui = getUI("ui:interface:cap")
1385 -- save size
1386 game.ui_cap_h = ui.h
1387 game.ui_cap_w = ui.w
1389 -- reduce window size
1390 ui.pop_min_w = 292
1391 ui.pop_min_h = 50
1392 ui.pop_max_w = 292
1393 ui.pop_max_h = 50
1394 ui.h = 50
1395 ui.w = 280
1396 getUI("ui:interface:cap:header_closed").h = 34
1399 function game:openCapHeader()
1400 local ui = getUI("ui:interface:cap")
1401 ui.pop_min_w = 292
1402 ui.pop_max_w = 800
1404 game:expandCapWeb(true)
1406 if (game.ui_cap_w ~= nil) then
1407 ui.w = game.ui_cap_w;
1411 function game:openFullCap()
1412 game.ui_cap_collapsed_h = 65
1413 getUI("ui:interface:cap").opened = true
1414 game:openCapHeader()
1417 function game:resizeCap(value)
1418 local ui = getUI("ui:interface:cap")
1419 game.ui_cap_expanded_h = value
1420 if game.capExpanded and getUI("ui:interface:cap").opened then
1421 ui.pop_min_h = game.ui_cap_expanded_h
1422 ui.pop_max_h = game.ui_cap_expanded_h+1
1423 ui.h = game.ui_cap_expanded_h
1424 getUI("ui:interface:cap:header_opened").h = ui.h-16
1428 function game:updateCapTooltip()
1429 local real_tooltip = game:parseLangText(mission_real_tooltip)
1430 getUI("ui:interface:cap:header_opened:cap_group:cap_ctrl").tooltip = getUCtf8("@{FB0F}"..game.CapTitle.."\n@{FFFF}"..game.CapDesc..real_tooltip)
1431 getUI("ui:interface:cap:header_closed:cap_group:cap_ctrl").tooltip = getUCtf8("@{FB0F}"..game.CapTitle.."\n@{FFFF}"..game.CapDesc..real_tooltip)
1434 function game:setCapTitle(text)
1435 game.CapTitle = game:parseLangText(text)
1436 getUI("ui:interface:cap:header_opened:cap_group:cap_title").hardtext = game.CapTitle
1437 game:updateCapTooltip()
1440 function game:setCapDesc(text)
1441 game.CapDesc = game:parseLangText(text)
1442 getUI("ui:interface:cap:header_opened:cap_group:cap_desc").hardtext = game.CapDesc
1443 getUI("ui:interface:cap:header_closed:cap_group:cap_desc").hardtext = game.CapDesc
1444 game:updateCapTooltip()
1447 function game:setCapIcon(icon)
1448 getUI("ui:interface:cap:header_opened:cap_group:cap_icon").texture = icon
1449 getUI("ui:interface:cap:header_closed:cap_group:cap_icon").texture = icon
1452 function game:setCapInfos(infos)
1453 getUI("ui:interface:cap:header_opened:cap_group:infos").uc_hardtext_format=getUCtf8(infos)
1454 game.CapInfos = infos
1457 function game:informNewCap()
1458 local resize = 70
1459 if getUI("ui:interface:cap:header_closed").active then
1460 getUI("ui:interface:cap:header_closed:cap_group:infos").uc_hardtext_format=getUCtf8("@{0AFF}Nouveau cap disponible")
1461 getUI("ui:interface:cap:header_closed").h = 70
1462 game.ui_cap_closed_h = 70
1463 else
1464 getUI("ui:interface:cap:header_opened:cap_group:infos").uc_hardtext_format=getUCtf8("@{0AFF}Nouveau cap disponible")
1465 if game.keepExpandStatus then
1466 return
1468 getUI("ui:interface:cap:header_opened").h = 70
1469 resize = 84
1471 local ui = getUI("ui:interface:cap")
1472 ui.pop_min_h = resize
1473 ui.pop_max_h = resize+1
1477 function game:capOpenUrl(url)
1478 if url == nil then
1479 local ui = getUI("ui:interface:cap:header_opened:cap_group:html")
1480 if ui then
1481 ui:browse(game.CapUrl)
1483 else
1484 webig:openUrlInBg(url)
1489 function game:setCapProgress(value, text)
1490 if value == nil then
1491 getUI("ui:interface:cap:header_opened:cap_group:cap_progress").active = false
1492 getUI("ui:interface:cap:header_closed:cap_group:cap_progress").active = false
1493 else
1494 getUI("ui:interface:cap:header_opened:cap_group:cap_progress").active = true
1495 getUI("ui:interface:cap:header_closed:cap_group:cap_progress").active = true
1496 if value >= 0 then
1497 if value > 100 then
1498 game:capOpenUrl(game.CapNextUrl)
1499 else
1500 setDbProp("UI:TEMP:CAP_PROGRESS", value)
1505 if text ~= nil then
1506 getUI("ui:interface:cap:header_opened:cap_group:cap_infos").hardtext = text
1507 getUI("ui:interface:cap:header_closed:cap_group:cap_infos").hardtext = text
1511 function game:autoHideCapPopup()
1513 if game.autoHideCapTimer == 0 then
1514 alpha = nltime.getLocalTime() - game.autoHideCapStartTime
1515 if alpha >= 254*5 then
1516 setOnDraw(getUI("ui:interface:cap_popup"), "")
1517 getUI("ui:interface:cap_popup").active=false
1518 else
1519 getUI("ui:interface:cap_popup").alpha=255-math.floor(alpha/5)
1521 else
1522 if game.autoHideCapStartTime + game.autoHideCapTimer < nltime.getLocalTime() then
1523 game.autoHideCapStartTime = nltime.getLocalTime()
1524 game.autoHideCapTimer = 0
1529 function game:displayRpMessage(message, icon)
1530 if icon == nil then
1531 icon = "rpjob_roleplay.tga"
1534 local htmlcode = [[
1535 <body style="font-style: italic; font-weight: bold; color: white; background-position: center; background-image: url(pretty_notif.tga)">
1536 <table width="100%" cellspacing="0" cellpadding="0">
1537 <tr>
1538 <td id="icon" align="center" width="750" valign="middle" height="30px"><img width="32px" src="]]..icon..[["/></td>
1539 </tr><tr>
1540 <tr>
1541 <td align="center">]]..message..[[</td>
1542 </tr>
1543 </table>
1544 </body>
1547 getUI("ui:interface:cap_popup:html"):renderHtml(htmlcode)
1548 setTopWindow(getUI("ui:interface:cap_popup"))
1549 getUI("ui:interface:cap_popup").alpha=255
1550 getUI("ui:interface:cap_popup").y = getUI("ui:interface").h-170
1551 getUI("ui:interface:cap_popup").x = math.floor(getUI("ui:interface").w / 2) - 400
1552 getUI("ui:interface:cap_popup").active = true
1553 game.autoHideCapStartTime = nltime.getLocalTime()
1554 game.autoHideCapTimer = 3000
1555 setOnDraw(getUI("ui:interface:cap_popup"), "game:autoHideCapPopup()")
1558 function game:openInfosUrl()
1559 if game.CapInfosUrl == nil then
1560 game:openMissionsCatalog()
1561 elseif game.CapInfosUrl:sub(1, 1) == "#" then
1562 local infos = {}
1563 for info in string.gmatch(game.CapInfosUrl, "[^%s]+") do
1564 table.insert(infos, info)
1566 if infos[1] == "#lesson" then
1567 openLesson(infos[2], infos[3], true)
1569 elseif game.CapInfosUrl ~= "" then
1570 getUI("ui:interface:web_transactions_lessons"):find("html"):browse(game.CapInfosUrl)
1574 function game:setInfosUrl(url)
1575 game.CapInfosUrl = url
1578 function game:setNextUrl(url)
1579 game.CapNextUrl = url
1582 function setCap(id, element, a, b)
1583 if element == nil then
1584 game.CapId = id
1585 game:setInfosUrl(a)
1586 game:setNextUrl(b)
1587 return
1590 if id ~= game.CapId then
1591 return
1594 if element == "t" then
1595 game:setCapTitle(a)
1596 elseif element == "d" then
1597 game:setCapDesc(a)
1598 elseif element == "i" then
1599 game:setCapIcon(a)
1600 elseif element == "p" then
1601 game:setCapProgress(a, b)
1602 elseif element == "u" then
1603 game:setInfosUrl(a)
1604 game:setNextUrl(b)
1605 elseif element == "n" then
1606 game:setNextUrl(a)
1607 elseif element == "o" then
1608 game:setInfosUrl(a)
1609 elseif element == "r" then
1610 game:displayRpMessage(a, b)
1611 elseif element == "b" then
1612 broadcast(a, b)
1613 elseif element == "f" then
1614 getUI("ui:interface:cap"):blink(1)
1619 function game:openMissionsCatalog()
1620 -- Setup this function in webig
1624 --------------------------------------------------------------------------------------------------------------
1625 function game:onMissionFinished(index)
1626 self:updateCurrMissionComboBox()
1627 --self:updateMissionDescCloseButton(index)
1630 --------------------------------------------------------------------------------------------------------------
1631 function game:onGroupMissionFinished(index)
1632 self:updateCurrMissionComboBox()
1633 --self:updateMissionDescCloseButton(index + game:getGroupMissionFirstIndex())
1636 --------------------------------------------------------------------------------------------------------------
1637 function game:expandMissionList()
1638 local missionCB = getUI("ui:interface:info_player_journal:content:mission_combo")
1639 missionCB.active = not missionCB.active
1640 self:updateMissionWindowLayout()
1643 --------------------------------------------------------------------------------------------------------------
1644 function game:updateMissionWindowLayout()
1645 if not isInRingMode() then
1646 local base = "ui:interface:info_player_journal:content:"
1647 local missionCB = getUI(base.."mission_combo")
1648 local missionList = getUI(base.."mission_list")
1649 local fake = getUI(base.."fake")
1650 local desc = getUI(base.."desc")
1651 local separator = getUI(base.."separator")
1652 local expanded
1653 local win = getUI("ui:interface:info_player_journal")
1655 if missionCB.active then
1656 missionList.active = false
1657 separator.active = true
1658 expanded = 0
1659 win.pop_min_h = 165 - win.content_y_offset
1660 desc.max_h = 0
1661 else
1662 missionList.active = true
1663 separator.active = true
1664 expanded = 1
1665 win.pop_min_h = 200 - win.content_y_offset
1666 desc.max_h = 27
1669 setDbProp("UI:SAVE:EXPAND_MISSION_LIST", expanded)
1670 win:invalidateCoords()
1673 --------------------------------------------------------------------------------------------------------------
1674 function game:onMissionJournalOpened()
1675 local missionDesc = getUI("ui:interface:info_player_journal:content:desc")
1676 missionDesc.active = getDbProp("UI:SAVE:MISSION_SELECTED") ~= -1
1678 local expandList = getDbProp("UI:SAVE:EXPAND_MISSION_LIST")
1679 self:updateMissionJournalMode()
1681 if not isInRingMode() then
1682 local missionCB = getUI("ui:interface:info_player_journal:content:mission_combo")
1683 if expandList == 1 then
1684 missionCB.active = false
1685 else
1686 missionCB.active = true
1690 self:updateMissionJournalHeader()
1691 self:updateMissionJournalFixedEntry()
1694 --------------------------------------------------------------------------------------------------------------
1695 function game:updateMissionJournalHeader()
1696 local win = getUI("ui:interface:info_player_journal")
1697 local headerActive = getDbProp("UI:SAVE:MISSION_JOURNAL_HEADER_ACTIVE") ~= 0
1698 win.header_active = headerActive
1699 win.right_button_enabled = headerActive
1700 if headerActive then
1701 win.uc_title_opened = i18n.get("uiJournalTitle")
1702 win.content_y_offset = 0
1703 else
1704 win.uc_title_opened = ucstring("")
1705 win.content_y_offset = win.header_opened.h_real + 3
1710 --------------------------------------------------------------------------------------------------------------
1711 function game:updateMissionJournalFixedEntry()
1712 -- update fixed entry text
1713 self:updateMissionWindowLayout()
1716 --------------------------------------------------------------------------------------------------------------
1717 function game:setCurrentMission(index)
1718 mw = getMissionWindow()
1719 mw.active = game.InGameDbInitialized
1720 if index < self:getGroupMissionFirstIndex() then
1721 runAH(nil, "proc", "mission_proc_title|" .. tostring(index))
1722 else
1723 runAH(nil, "proc", "group_mission_proc_title|" .. tostring(index - self:getGroupMissionFirstIndex()))
1727 --------------------------------------------------------------------------------------------------------------
1728 function game:onMissionComboWheelUp()
1729 local currMissionIndex = self:getCurrMissionIndex()
1730 while currMissionIndex > 0 do
1731 currMissionIndex = currMissionIndex - 1
1732 if getDbProp(self:getMissionDbPath(currMissionIndex) .. ":TITLE") ~= 0 then
1733 self:setCurrentMission(currMissionIndex)
1734 return
1739 --------------------------------------------------------------------------------------------------------------
1740 function game:onMissionComboWheelDown()
1741 local currMissionIndex = self:getCurrMissionIndex()
1742 local maxNumMission = 2 * self:getGroupMissionFirstIndex()
1743 while currMissionIndex < (maxNumMission - 1) do
1744 currMissionIndex = currMissionIndex + 1
1745 if getDbProp(self:getMissionDbPath(currMissionIndex) .. ":TITLE") ~= 0 then
1746 self:setCurrentMission(currMissionIndex)
1747 return
1754 --------------------------------------------------------------------------------------------------------------
1755 function game:toggleMissionJournalCaption()
1756 local dbPath = "UI:SAVE:MISSION_JOURNAL_HEADER_ACTIVE"
1757 setDbProp(dbPath, 1 - getDbProp(dbPath))
1758 local win = getUI("ui:interface:info_player_journal")
1759 self:updateMissionJournalHeader()
1760 self:updateMissionWindowLayout()
1763 --------------------------------------------------------------------------------------------------------------
1764 -- handler called by C++ to tell that the main loop is about to begin
1765 function game:onMainLoopBegin()
1766 --getUI("ui:interface:db_loading").active=true
1767 game.InGameDbInitialized = false
1768 game.setupWebigWithDBInitialized = false
1769 game.webigInitialized = false
1770 game.PrevSessionMission = getDbProp("UI:VARIABLES:MISSION_SELECTED_PREV_SESSION")
1772 debug("MainLoop")
1776 --------------------------------------------------------------------------------------------------------------
1777 -- handler called by C++ to tell that all initial value have been set in the db
1778 function game:onInGameDbInitialized()
1779 --getUI("ui:interface:db_loading").active=false
1780 game.InGameDbInitialized = true
1781 debug("IG DB initialized")
1782 -- if the journal is opened, force an update for the fixed entry text
1783 -- (says if we're in start island, paying account ...) need DB flags like
1784 -- IS_NEWBIE & IS_TRIAL to be received
1785 game:updateMissionJournalFixedEntry()
1786 -- If a mission was previously selected, restore it
1787 if game.PrevSessionMission ~= -1 then
1788 self:setCurrentMission(game.PrevSessionMission)
1791 game:setInfoPlayerCharacterRace()
1793 game:openChannels()
1795 runAH(nil, "proc", "init_3d_preview")
1796 runAH(nil, "sort_tribefame", "")
1798 if getDbProp("UI:SAVE:AUTO_LIGHT") == 1 then
1799 runAH(nil, "light_on", "")
1803 function game:onWebIgReady()
1804 -- Call init webig
1805 debug("Webig ready")
1806 game.webigInitialized = true
1807 setOnDraw(getUI("ui:interface:encyclopedia"), "ArkMissionCatalog:startResize()")
1808 getUI("ui:interface:webig:content:html"):browse("home")
1809 if getDbProp("UI:SAVE:SKIP_TUTORIAL") == 0 then
1810 addOnDbChange(getUI("ui:interface"), "@UI:SAVE:MK_MODE", "game:resizeMilkoPad()")
1811 help:initWelcome()
1814 game.setupWebigWithDBInitialized = true
1815 help:displayWelcome()
1816 game:onCapResize()
1817 local cap = getUI("ui:interface:cap")
1818 setOnDraw(cap, "game:onOverCap()")
1819 ArkLessons:init()
1823 --------------------------------------------------------------------------------------------------------------
1824 -- handler called by C++ at the start of a far TP (log to char selection or far tp)
1825 function game:onFarTpStart()
1826 debugInfo("game:onFarTpStart()")
1827 --game:deinitWebIgApps()
1829 if getDbProp("UI:SAVE:CHAT:SAVE_CHANNEL") > 0 then
1830 game:saveChannel()
1833 artefact:onClose()
1836 --------------------------------------------------------------------------------------------------------------
1837 -- handler called by C++ after characer reselection or the end of a far TP
1838 function game:onFarTpEnd()
1839 debugInfo("game:onFarTpEnd()")
1840 --game:preInitWebIgApps()
1843 --------------------------------------------------------------------------------------------------------------
1844 -- handler called by C++ at the end of the main loop
1845 function game:onMainLoopEnd()
1846 game.InGameDbInitialized = false
1847 game:updateMissionJournalFixedEntry()
1849 if getDbProp("UI:SAVE:CHAT:SAVE_CHANNEL") > 0 then
1850 game:saveChannel()
1853 artefact:onClose()
1856 --------------------------------------------------------------------------------------------------------------
1857 -- ring journal on / off
1858 function game:setMissionJournalRingMode(isRing)
1859 local journal = getUI("ui:interface:info_player_journal")
1860 if isRing then
1861 journal.content.expand_mission_list.active = false
1862 journal.content.mission_combo.active = false
1863 journal.content.active = true
1864 journal.content.mission_list.active = false
1865 journal.content.sv.active = false
1866 journal.content.fake.active = false
1867 journal.content.separator.active = false
1868 journal.content.separator_bis.active = false
1869 journal.content.desc.active = false
1870 journal.content.sv_desc.active = false
1871 journal.no_available_missions.active = true
1872 else
1873 journal.content.expand_mission_list.active = true
1874 journal.no_available_missions.active = false;
1875 journal.content.active = true;
1876 --journal.content.mission_list.active = true;
1877 journal.content.sv.active = true;
1878 journal.content.fake.active = true;
1879 journal.content.separator.active = true;
1880 journal.content.desc.active = getDbProp("UI:SAVE:MISSION_SELECTED") ~= -1;
1881 journal.content.sv_desc.active = true
1885 --------------------------------------------------------------------------------------------------------------
1886 -- update mission journal depending on wether we're in the ring or not
1887 function game:updateMissionJournalMode()
1888 --local isRing = r2~=nil and r2.Mode~=nil and r2.Mode=='r2ed_anim_test'
1889 game:setMissionJournalRingMode(isInRingMode())
1894 local remainingMissionTextIDs = {}
1898 function getMissionWindow()
1899 return getUI("ui:interface:info_player_journal")
1902 --------------------------------------------------------------------------------------------------------------
1903 -- This is called when a new step is added to the current mission. If so, make sure that the step
1904 -- is visible in the listbox
1905 function game:onNewMissionStepAdded(stepIndex)
1906 local missionWnd = getMissionWindow()
1907 local missionIndex = getDbProp("UI:SAVE:MISSION_SELECTED")
1908 local dbPath
1910 if missionIndex < 0 then
1911 return
1914 -- debugInfo("New Step")
1915 if missionIndex < 15 then
1916 dbPath = "SERVER:MISSIONS:" .. tostring(missionIndex) .. ":GOALS:" .. tostring(stepIndex) .. ":TEXT"
1917 else
1918 dbPath = "SERVER:GROUP:MISSIONS:" .. tostring(missionIndex - 15) .. ":GOALS:" .. tostring(stepIndex) .. ":TEXT"
1920 local stringID = getDbProp(dbPath)
1921 if stringID ~= 0 then
1922 -- debugInfo(tostring(stringID))
1923 table.insert(remainingMissionTextIDs, stringID)
1924 setOnDraw(missionWnd, "game:ensureLastMissionStepVisibility0()")
1925 else
1927 game.WebMissionLastDesc = {}
1930 function game:ensureLastMissionStepVisibility0()
1932 local missing = false
1933 for k, v in pairs(remainingMissionTextIDs) do
1934 if not isDynStringAvailable(v) then
1935 missing = true
1936 break
1939 local missionWnd = getMissionWindow()
1940 if not missing then
1941 remainingMissionTextIDs = {}
1942 -- delay real update to newt frame
1943 setOnDraw(missionWnd, "game:ensureLastMissionStepVisibility1()")
1944 else
1945 -- for debug : dump the list of remaining "dyn string"
1946 --local stringList = "{"
1947 --for k, v in remainingMissionTextIDs do
1948 -- if not isDynStringAvailable(v) then
1949 -- stringList = stringList .. " " .. tostring(v)
1950 -- end
1951 --end
1952 --stringList = stringList .. "}"
1956 function game:ensureLastMissionStepVisibility1()
1957 local missionWnd = getMissionWindow()
1958 local missionIndex = getDbProp("UI:SAVE:MISSION_SELECTED")
1959 local scrollBar = missionWnd:find("sv_desc")
1960 --scrollBar.trackPos = 20000 -- move upward
1961 --scrollBar:updateCoords()
1962 --setOnDraw(missionWnd, "")
1963 local descWnd = missionWnd:find("desc")
1964 local maxNumSteps = getDefine("ipj_nb_goal")
1965 local topStep
1966 for stepIndex = 0, maxNumSteps -1 do
1967 local currStep = descWnd["step" .. tostring(stepIndex)]
1968 if currStep.active then
1969 topStep = currStep
1973 if topStep == nil then
1974 return
1977 scrollBar:ensureVisible(topStep, "M", "M")
1979 --local wantedY = topStep.h_real / 2 - (descWnd.y_real - topStep.y_real)
1980 --local wantedY = descWnd.y_real + descWnd.h_real - topStep.y_real
1981 --local offsetY = wantedY - descWnd.max_h_real / 2
1982 --if offsetY < 0 then offsetY = 0 end
1983 --descWnd.ofsy = offsetY
1984 --descWnd:invalidateCoords()
1985 --descWnd:updateCoords()
1987 game.WebMissionLastDesc = {}
1988 setOnDraw(missionWnd, "game:ensureWebMissionVisibility()")
1992 function game:ensureWebMissionVisibility()
1993 local missionWnd = getMissionWindow()
1994 local missionIndex = getDbProp("UI:SAVE:MISSION_SELECTED")
1995 local scrollBar = missionWnd:find("sv_desc")
1996 local descWnd = missionWnd:find("desc")
1997 local maxNumSteps = getDefine("ipj_nb_goal")
1998 local topStep
1999 local haveWeb = false
2000 for stepIndex = 0, maxNumSteps -1 do
2001 local currStep = descWnd["step" .. tostring(stepIndex)]
2002 if missionIndex < 15 then
2003 dbPath = "SERVER:MISSIONS:" .. tostring(missionIndex) .. ":GOALS:" .. tostring(stepIndex) .. ":TEXT"
2004 local stringID = getDbProp(dbPath)
2005 local uctext = getDynString(stringID)
2006 local text = uctext:toUtf8()
2007 if text ~= "" and game.WebMissionLastDesc[stepIndex] ~= text then
2008 game.WebMissionLastDesc[stepIndex] = text
2009 if string.sub(text, 1, 4) == "@WEB" then
2010 text = string.sub(text, 6)
2011 haveWeb = true
2012 local win = getUI(descWnd.id..":web:html")
2013 for web, final_text in string.gmatch(text, "(.*)\n@@@\n(.*)") do
2014 win:renderHtml(web)
2015 currStep.hardtext = final_text
2016 break
2018 else
2019 currStep.uc_hardtext = uctext
2024 if (game.WebMissionLastDesc[stepIndex] ~= nil) and (string.sub(game.WebMissionLastDesc[stepIndex], 1, 4) == "@WEB") then
2025 haveWeb = true
2029 if haveWeb then
2030 getUI(descWnd.id..":web").h = 56
2031 else
2032 getUI(descWnd.id..":web").h = 0
2035 local base = "ui:interface:info_player_journal:content:"
2036 local fake = getUI(base.."fake")
2037 local missionCB = getUI(base.."mission_combo")
2038 local missionL = getUI(base.."mission_list")
2039 local desc = getUI(base.."desc")
2040 local win = getUI("ui:interface:info_player_journal")
2041 win.pop_min_h = 200 - win.content_y_offset
2043 local missionsH = 24
2044 local maxNumMissions = 2 * self:getGroupMissionFirstIndex()
2045 for k = 0, maxNumMissions - 1 do
2046 if getDbProp(self:getMissionDbPath(k) .. ":TITLE") ~= 0 then
2047 missionsH = missionsH + 17
2051 if missionCB.active then
2052 fake.h = 24
2053 win.pop_min_h = 224 + getUI(descWnd.id..":web").h
2054 else
2055 fake.h = missionL.h
2056 win.pop_min_h = missionsH + 200 + getUI(descWnd.id..":web").h
2060 --------------------------------------------------------------------------------------------------------------
2061 -- This handler is triggered when a new mission has been added. In this case, we select the mission automatically
2062 function game:onNewMissionAdded(missionIndex)
2063 setOnDraw(missionWnd, "game:ensureWebMissionVisibility()")
2064 debugInfo("Mission " .. missionIndex .. " has been added")
2065 game.WebMissionLastDesc = {}
2068 --------------------------------------------------------------------------------------------------------------
2069 -- RPJOBS
2071 function game:addRpJob(jobtype, id, value, rpjobs)
2072 local base_path = "ui:interface:info_player_skills:content:rpjobs:rpjob_"..jobtype.."_"..id..":rpjob_"..jobtype.."_infos_"..id
2074 local group = getUI("ui:interface:info_player_skills:content:rpjobs:rpjob_"..jobtype.."_"..id)
2076 if (value == nil) then
2077 group.active = false
2078 else
2079 local name = "rpjob_" .. string.format("%03d", value)
2080 local sitem = name..".sitem"
2081 if (rpjobs[sitem] == nil) then
2082 group.active = false
2083 else
2084 group.active = true
2086 local echelon_value = rpjobs[sitem][1]
2087 local quantity = rpjobs[sitem][2]
2089 local maxlevel = (echelon_value*6)-30
2091 if (quantity > maxlevel) then
2092 quantity = maxlevel
2095 local base = getUI(base_path..":t")
2096 base.hardtext = i18n.get(name):toUtf8()
2097 local ui = getUI(base_path..":icon")
2098 ui.texture = name..".tga"
2099 local echelon = getUI(base_path..":echelon_value")
2100 echelon.hardtext = tostring(echelon_value/10)
2101 local bar = getUI(base_path..":bar3d:level")
2102 local t = getUI(base_path..":bar3d:t")
2103 if (echelon_value >= 60) then
2104 bar.color = "255 0 0 255"
2105 bar.w = "368"
2106 t.hardtext = i18n.get("uiRpjobMaxLevel"):toUtf8()
2107 t.color = "255 255 0 255"
2108 else
2109 bar.color = tostring(math.floor((105*quantity)/maxlevel)).." "..tostring(100+math.floor((155*quantity)/maxlevel)).." "..tostring(math.floor((105*quantity)/maxlevel)).." 255"
2110 bar.w = tostring((368*quantity)/maxlevel)
2111 t.hardtext = tostring(quantity).." / "..tostring(maxlevel)
2112 t.color = tostring(255*math.floor(3*(maxlevel-quantity)/maxlevel)).." "..tostring(255*math.floor(3*(maxlevel-quantity)/maxlevel)).." "..tostring(255*math.floor(3*(maxlevel-quantity)/maxlevel)).." 255"
2119 function game:getRPJobs()
2120 rpjobs_advanced = {}
2121 rpjobs_elementary = {}
2122 rpjobs_roleplay = {}
2123 rpjobs = {}
2125 for i = 0, 499, 1 do
2126 local sheet = getDbProp("SERVER:INVENTORY:BAG:"..tostring(i)..":SHEET")
2127 if (sheet ~= 0) then
2128 local name = getSheetName(sheet)
2129 if (string.sub(name, 0, 6) == "rpjob_") then
2130 local quality = getDbProp("SERVER:INVENTORY:BAG:"..tostring(i)..":QUALITY")
2131 local quantity = getDbProp("SERVER:INVENTORY:BAG:"..tostring(i)..":QUANTITY")
2133 if (name == "rpjob_advanced.sitem") then
2134 table.insert(rpjobs_advanced, quality)
2135 else
2136 if (name == "rpjob_elementary.sitem") then
2137 table.insert(rpjobs_elementary, quality)
2138 else
2139 if (name == "rpjob_roleplay.sitem") then
2140 table.insert(rpjobs_roleplay, quality)
2141 else
2142 if rpjobs[name] == nil then
2143 rpjobs[name] = {quality, quantity}
2144 else
2145 if rpjobs[name][1] < quality then
2146 rpjobs[name] = {quality, quantity}
2156 for id=1,2,1 do
2157 game:addRpJob("advanced", id, rpjobs_advanced[id], rpjobs)
2160 for id=1,3,1 do
2161 game:addRpJob("elementary", id, rpjobs_elementary[id], rpjobs)
2167 --------------------------------------------------------------------------------------------------------------
2168 function game:setInfoPlayerCharacterRace()
2169 getUI("ui:interface:info_player_skills:content:basics_skills:character_race_name").uc_hardtext = i18n.get("io"..getUserRace())
2172 function game:arkTitlesAddClassics()
2173 local current_title = getUI("ui:interface:player:header_opened:player_title").uc_hardtext
2174 runAH(nil, "title_init_combobox", "")
2175 local cb = getUI("ui:interface:info_player_skills:content:webinfos:title:player_title")
2176 local ui = getUI("ui:interface:encyclopedia:content:htmlC")
2177 local html = [[<body style="background-color: #0009">]]
2179 local titles = {}
2180 for i=0,cb:getNumTexts()-1 do
2181 table.insert(titles, tostring(cb:getText(i)))
2183 table.sort(titles)
2184 for i,title in ipairs(titles) do
2185 local current = "_blue"
2186 if tostring(current_title) == tostring(title) then
2187 current = ""
2190 html = html .. [[<div class="ryzom-ui-grouptemplate" id="div_ark_title" style="template:title_template;id:div_ark_title:display_title;icon:ico_amber_ball]]..current..[[.tga;text:]]
2191 html = html .. title .. [[;titleid:]] .. title
2192 html = html .. [[;color:255 255 255 255;enable:50;tooltip:"></div>]]
2194 html = html .. [[<br/><br/><br/></body>]]
2195 ui:renderHtml(html)