1 -- In this file we define functions that serves for player windows
3 function getDbPropU(dbEntry
)
4 value
= getDbProp(dbEntry
)
6 value
= 4294967296+value
11 if string.find(_VERSION
, "Lua 5.0") then
12 function math
.fmod(a
, b
)
17 ------------------------------------------------------------------------------------------------------------
18 -- create the game namespace without reseting if already created in an other file.
23 if (game
.PVP
== nil) then
25 game
.PVP
.tagStartTimer
= 0;
26 game
.PVP
.flagStartTimer
= 0;
27 game
.PVP
.tagTimerStarted
= false;
28 game
.PVP
.flagTimerStarted
= false;
31 if (game
.BonusMalus
== nil) then
33 game
.BonusMalus
.DeathPenaltyBefore
= -1;
34 game
.BonusMalus
.DeathPenaltyAfter
= -1;
35 game
.BonusMalus
.XPCatSlotBefore
= -1;
36 game
.BonusMalus
.XPCatSlotAfter
= -1;
37 game
.BonusMalus
.RingXPCatSlotBefore
= -1;
38 game
.BonusMalus
.RingXPCatSlotAfter
= -1;
39 game
.BonusMalus
.OutpostSlotBefore
= -1;
40 game
.BonusMalus
.OutpostSlotAfter
= -1;
41 game
.BonusMalus
.BonusAHList
= {};
42 game
.BonusMalus
.MalusAHList
= {};
45 game
.wantedScriptPlaces
= {}
46 game
.latestValidScriptPlace
= ""
48 function game
:addScriptPlace(modname
, place
, id
)
49 if game
.wantedScriptPlaces
[modname
] == nil then
50 game
.wantedScriptPlaces
[modname
] = {}
52 game
.wantedScriptPlaces
[modname
][place
] = id
56 function game
:checkScriptPlace(place
)
57 for modname
, vals
in pairs(game
.wantedScriptPlaces
) do
58 if vals
[place
] ~= nil and game
.latestValidScriptPlace
~= place
then
59 game
.latestValidScriptPlace
= place
60 openArkScript(vals
[place
], nil, "place="..place
)
66 function game
:CheckPosition()
67 local x
,y
,z
= getPlayerPos()
68 local sx
= tostring(math
.floor(x
/10))
69 local sy
= tostring(math
.floor(y
/10))
70 game
:checkRpItemsPosition(sx
, sy
)
71 local cont
, region
, places
= getPositionInfos()
72 game
:checkScriptPlace(cont
)
73 game
:checkScriptPlace(region
)
74 for place
, typ
in pairs(places
) do
75 game
:checkScriptPlace(place
)
79 ------------------------------------------------------------------------------------------------------------
80 -- Update player bars in function of what we wants to display (we can hide each one of the 3 bars : sap,stamina and focus)
81 function game
:updatePlayerBars()
83 local dispSap
= getDbProp('UI:SAVE:PLAYER:DISP_SAP');
84 local dispSta
= getDbProp('UI:SAVE:PLAYER:DISP_STA');
85 local dispFoc
= getDbProp('UI:SAVE:PLAYER:DISP_FOC');
87 local ui
= getUI('ui:interface:player:content');
89 -- active ui in function of what is displayed
91 ui
.b_sap
.active
= (dispSap
== 1);
92 ui
.jsap
.active
= (dispSap
== 1);
94 ui
.b_sta
.active
= (dispSta
== 1);
95 ui
.jsta
.active
= (dispSta
== 1);
97 ui
.b_foc
.active
= (dispFoc
== 1);
98 ui
.jfoc
.active
= (dispFoc
== 1);
100 -- choose good y-position
102 local totalBarDisp
= dispSap
+ dispSta
+ dispFoc
;
103 if (totalBarDisp
== 3) then
108 ui
.current_action
.y
= -65;
110 elseif (totalBarDisp
== 2) then
112 if (dispSap
== 0) then
117 if (dispSta
== 0) then
122 if (dispFoc
== 0) then
127 ui
.current_action
.y
= -50;
129 elseif (totalBarDisp
== 1) then
135 ui
.current_action
.y
= -35;
138 ui
.current_action
.y
= -20;
145 ------------------------------------------------------------------------------------------------------------
146 -- convert a boolean to a number 0 or 1
147 function booleanToNumber(thebool
)
155 ------------------------------------------------------------------------------------------------------------
156 -- Update player pvp tag
157 function game
:pvpTagUpdateDisplay()
158 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
159 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
160 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
161 local uiPlayer
= getUI('ui:interface:player:header_opened');
163 -- get the current state
164 local pvpServerFlag
= pvpServerFlagTimer
> currentServerTick
;
165 local pvpLocalTag
= (getDbProp('UI:TEMP:PVP_FACTION:TAG_PVP') == 1);
166 local pvpServerTag
= (getDbProp('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:TAG_PVP') == 1);
167 local pvpServerActivateTimerOn
= pvpServerTagTimer
> currentServerTick
;
169 -- deduce the display state according to the current state
173 local buttonMode
= GREEN
;
174 local buttonPushed
= false;
175 local buttonTimer
= false;
176 -- if the flag is activated, then must display PVP flag button and timer
177 if (pvpServerFlag
) then
182 -- else must display correct mode according to the TAG state
184 -- There are 8 possibilities according to the combination of the 3 flags
185 -- Here: TL= pvpLocalTag, TS= pvpServerTag, AS= pvpServerActivateTimerOn)
188 -- 0 0 0 -> Standard disabled PVP
189 -- 1 0 0 -> The user pressed the button but still no response from server
190 -- 1 1 1 -> The user pressed the button and got response from server. => GREEN icon with timer
191 -- 0 1 1 -> The user canceled the activation (server not acked yet the cancel). => default display
193 -- 1 1 0 -> Standard enabled PVP
194 -- 0 1 0 -> The user pressed the button but still no response from server
195 -- 0 0 1 -> The user pressed the button and got response from server. => ORANGE icon with timer
196 -- 1 0 1 -> The user canceled the activation (server not acked yet the cancel). => default display
198 -- From this table, we can deduce the following rules
200 -- buttonMode is GREEN when TS==AS
201 if( pvpServerTag
== pvpServerActivateTimerOn
) then
207 -- the button is pushed if (there is a timer and TL==TS), or (no timer and TL!=TS)
208 if( pvpServerActivateTimerOn
== (pvpLocalTag
== pvpServerTag
) ) then
214 -- display a timer only if the timer is activated and server and local tag are equals
215 if( pvpServerActivateTimerOn
and pvpLocalTag
== pvpServerTag
) then
223 -- setup the local display
224 setDbProp("UI:TEMP:PVP_FACTION:DSP_MODE", buttonMode
);
225 setDbProp("UI:TEMP:PVP_FACTION:DSP_PUSHED", booleanToNumber(buttonPushed
));
226 setDbProp("UI:TEMP:PVP_FACTION:DSP_TIMER", booleanToNumber(buttonTimer
));
228 -- setup the timer bar
230 local uiBar
= uiPlayer
.pvp_timer
;
231 local uiBarBg
= uiPlayer
.pvp_timer_bg
;
233 if(buttonMode
==RED
) then
234 -- display a reverse timer
235 uiBar
.w
= uiBarBg
.w
* (pvpServerFlagTimer
- currentServerTick
) / (pvpServerFlagTimer
- game
.PVP
.flagStartTimer
);
237 -- display a forward timer
238 uiBar
.w
= uiBarBg
.w
* (currentServerTick
- game
.PVP
.tagStartTimer
) / (pvpServerTagTimer
- game
.PVP
.tagStartTimer
);
242 -- force update of the tooltip for any button (by disabling then reenabling)
243 disableContextHelpForControl(uiPlayer
.pvp_tag_button_0
);
244 disableContextHelpForControl(uiPlayer
.pvp_tag_button_1
);
245 disableContextHelpForControl(uiPlayer
.pvp_tag_button_2
);
248 ------------------------------------------------------------------------------------------------------------
249 -- Update player pvp tag
250 function game
:pvpTag()
251 local buttonStat
= getDbProp('UI:TEMP:PVP_FACTION:TAG_PVP');
252 if (buttonStat
== 0) then
253 setDbProp('UI:TEMP:PVP_FACTION:TAG_PVP',1);
255 setDbProp('UI:TEMP:PVP_FACTION:TAG_PVP',0);
257 sendMsgToServerPvpTag(buttonStat
== 0);
260 self
:pvpTagUpdateDisplay();
263 ------------------------------------------------------------------------------------------------------------
264 -- Update button due to server validation
265 function game
:updatePvpTag()
266 -- force copy to temp of Server tag
267 local pvpServerTag
= (getDbProp('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:TAG_PVP') == 1);
268 setDbProp('UI:TEMP:PVP_FACTION:TAG_PVP', booleanToNumber(pvpServerTag
));
270 -- launch timer DB if necessary
271 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
272 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
273 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
275 if(pvpServerTagTimer
> currentServerTick
) or (pvpServerFlagTimer
> currentServerTick
) then
276 local ui
= getUI('ui:interface:player');
277 addOnDbChange(ui
,'@UI:VARIABLES:CURRENT_SERVER_TICK', 'game:updatePvpTimer()');
279 if(pvpServerTagTimer
> currentServerTick
and game
.PVP
.tagTimerStarted
== false) then
280 game
.PVP
.tagStartTimer
= currentServerTick
;
281 game
.PVP
.tagTimerStarted
= true;
283 if(pvpServerFlagTimer
> currentServerTick
and game
.PVP
.flagTimerStarted
== false) then
284 game
.PVP
.flagStartTimer
= currentServerTick
;
285 game
.PVP
.flagTimerStarted
= true;
289 -- update display (after start timer reseted)
290 self
:pvpTagUpdateDisplay();
293 ------------------------------------------------------------------------------------------------------------
295 function game
:updatePvpTimer()
298 self
:pvpTagUpdateDisplay();
301 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
302 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
303 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
305 -- Manage Tag Timer display
306 if(pvpServerTagTimer
<= currentServerTick
) then
307 game
.PVP
.tagTimerStarted
= false;
310 -- Manage Flag Timer display
311 if(pvpServerFlagTimer
<= currentServerTick
) then
312 game
.PVP
.flagTimerStarted
= false;
315 -- if both off, stop the db update
316 if(game
.PVP
.tagTimerStarted
== false) and (game
.PVP
.flagTimerStarted
== false) then
317 removeOnDbChange(getUI('ui:interface:player'),'@UI:VARIABLES:CURRENT_SERVER_TICK');
321 ------------------------------------------------------------------------------------------------------------
323 function game
:formatTime(temps
)
325 local hours
= math
.floor(temps
/(10*60*60));
326 local minutes
= math
.floor((temps
- (hours
*10*60*60)) / (10*60));
327 local seconds
= math
.floor((temps
- (hours
*10*60*60) - (minutes
*10*60)) / 10);
329 local fmt
= i18n
.get('uittPvPTime');
330 fmt
= findReplaceAll(fmt
, '%h', tostring(hours
));
331 fmt
= findReplaceAll(fmt
, '%m', tostring(minutes
));
332 fmt
= findReplaceAll(fmt
, '%s', tostring(seconds
));
336 ------------------------------------------------------------------------------------------------------------
338 function game
:playerTTPvp()
340 -- The tooltip to display depends on the current display state
341 local buttonMode
= getDbProp("UI:TEMP:PVP_FACTION:DSP_MODE");
342 local buttonPushed
= (getDbProp("UI:TEMP:PVP_FACTION:DSP_PUSHED")==1);
343 local buttonTimer
= (getDbProp("UI:TEMP:PVP_FACTION:DSP_TIMER")==1);
347 if(buttonMode
==2) then
348 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
349 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
350 local tempsString
= game
:formatTime( pvpServerFlagTimer
- currentServerTick
);
351 text
= i18n
.get('uittPvPModeFlag');
352 text
= findReplaceAll(text
, '%temps', tempsString
);
356 if(buttonMode
==0 and not(buttonPushed
)) then
357 text
= i18n
.get('uittPvPModeTagOff');
358 elseif(buttonMode
==0 and buttonPushed
) then
359 text
= i18n
.get('uittPvPModeTagOffChange');
360 elseif(buttonMode
==1 and not(buttonPushed
)) then
361 text
= i18n
.get('uittPvPModeTagOn');
362 elseif(buttonMode
==1 and buttonPushed
) then
363 text
= i18n
.get('uittPvPModeTagOnChange');
369 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
370 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
371 local tempsString
= game
:formatTime( pvpServerTagTimer
- currentServerTick
);
372 local timeFmt
= i18n
.get('uittPvPTagTimer');
373 timeFmt
= findReplaceAll(timeFmt
, '%temps', tempsString
);
374 text
= concatUCString(text
, timeFmt
);
379 setContextHelpText(text
);
384 -- ***************************************************************************
385 -- ***************************************************************************
387 -- ***************************************************************************
388 -- ***************************************************************************
391 ------------------------------------------------------------------------------------------------------------
392 function game
:bonusMalusActiveText(ui
, slot
, state
)
393 local uiTextGroup
= ui
["text" .. tostring(slot
) ];
395 uiTextGroup
.active
= state
;
399 ------------------------------------------------------------------------------------------------------------
400 function game
:bonusMalusSetText(ui
, slot
, fmt
)
401 local uiTextGroup
= ui
["text" .. tostring(slot
) ];
403 uiTextGroup
.shade0
.uc_hardtext_format
= fmt
;
404 uiTextGroup
.shade1
.uc_hardtext_format
= fmt
;
405 uiTextGroup
.shade2
.uc_hardtext_format
= fmt
;
406 uiTextGroup
.shade3
.uc_hardtext_format
= fmt
;
407 uiTextGroup
.text
.uc_hardtext_format
= fmt
;
408 uiTextGroup
.text2
.uc_hardtext_format
= fmt
;
412 ------------------------------------------------------------------------------------------------------------
413 -- Called from c++ to format icon regen timer text
414 -- timer: number, ie 123, -123
415 -- dbPath: UI:VARIABLES:BONUS:0
417 -- Activate it in "bonuses" and/or "maluses" xml group.
418 -- If using color tags, then also set both colors to white
419 -- regen_text_fct="lua:game:formatRegenTimer"
420 -- regen_text_color="255 255 255"
421 -- regen_text_disabled_color="255 255 255"
422 function game
:formatRegenTimer(timer
, dbPath
)
424 return string.format("%dm", timer
/ 60);
426 return string.format("%ds", timer
);
430 ------------------------------------------------------------------------------------------------------------
431 -- From given DB vals, compute the 'Xp Bonus' text info
432 function game
:updateXpCatQuantity(textSlot
, ui
)
433 -- get the ui text to fill
439 local fmt
= "x@{FF6F}" .. tostring( getDbProp("SERVER:CHARACTER_INFO:XP_CATALYSER:Count") );
441 self
:bonusMalusSetText(ui
, textSlot
, fmt
);
445 ------------------------------------------------------------------------------------------------------------
446 -- From given DB vals, compute the 'Ring Xp Bonus' text info
447 function game
:updateRingXpCatQuantity(textSlot
, ui
)
448 -- get the ui text to fill
454 local fmt
= "x@{FF6F}" .. tostring( getDbProp("SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Count") );
456 self
:bonusMalusSetText(ui
, textSlot
, fmt
);
460 ------------------------------------------------------------------------------------------------------------
461 function game
:outpostUpdatePVPTimer(textSlot
, ui
)
462 -- get the ui text to fill
467 -- Get the timer of interest (priority to player leaving the zone)
469 local endOfPvpTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_OUTPOST:FLAG_PVP_TIME_END');
470 if( endOfPvpTimer
>0 ) then
471 endTimer
= endOfPvpTimer
;
473 local endOfRound
= getDbProp('SERVER:CHARACTER_INFO:PVP_OUTPOST:ROUND_END_DATE');
474 if( endOfRound
>0 ) then
475 endTimer
= endOfRound
;
479 -- Use a text with a timer?
480 if( endTimer
>0 ) then
481 -- compute the time that lefts in sec (suppose a smooth server tick is 1 ms)
482 local curTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
483 local timeSec
= (endTimer
- curTick
)/10;
485 local text
= "@{FF6F}" .. runFct('secondsToTimeStringShort', timeSec
);
486 self
:bonusMalusSetText(ui
, textSlot
, text
);
487 -- else Default display
489 self
:bonusMalusSetText(ui
, textSlot
, "@{FF6F}on");
495 ------------------------------------------------------------------------------------------------------------
496 function game
:deathPenaltyUpdateXPMalus()
500 ------------------------------------------------------------------------------------------------------------
501 -- called when someone click on a bonus malus icon. redirect to correct action handler if any
502 function game
:onLeftClickBonus()
503 local ui
= getUICaller();
504 local id
= getIndexInDB(ui
);
505 local ah
= self
.BonusMalus
.BonusAHList
[id
];
511 function game
:onLeftClickMalus()
512 local ui
= getUICaller();
513 local id
= getIndexInDB(ui
);
514 local ah
= self
.BonusMalus
.MalusAHList
[id
];
520 ------------------------------------------------------------------------------------------------------------
521 -- update if needed the ActionHandler and text update from DB
522 function game
:updateBonusMalusTextSetup()
523 local numLocalBonusMalus
= tonumber(getDefine("num_local_bonus_malus"));
524 local uiBonus
= getUI('ui:interface:bonus_malus:header_opened:bonus');
525 local uiMalus
= getUI('ui:interface:bonus_malus:header_opened:malus');
526 local dbXpCat
= "@SERVER:CHARACTER_INFO:XP_CATALYSER:Count";
527 local dbRingXpCat
= "@SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Count";
528 local dbOutpost
= "@SERVER:CHARACTER_INFO:PVP_OUTPOST, @UI:VARIABLES:CURRENT_SERVER_TICK";
529 local dbDeathPenalty
= "@SERVER:USER:DEATH_XP_MALUS";
533 self
.BonusMalus
.DeathPenaltyBefore
= self
.BonusMalus
.DeathPenaltyAfter
;
534 self
.BonusMalus
.XPCatSlotBefore
= self
.BonusMalus
.XPCatSlotAfter
;
535 self
.BonusMalus
.RingXPCatSlotBefore
= self
.BonusMalus
.RingXPCatSlotAfter
;
536 self
.BonusMalus
.OutpostSlotBefore
= self
.BonusMalus
.OutpostSlotAfter
;
539 -- *** remove and hide any preceding
540 for i
= 0,numLocalBonusMalus
-1 do
542 self
.BonusMalus
.BonusAHList
[i
]= nil;
543 self
.BonusMalus
.MalusAHList
[i
]= nil;
545 self
:bonusMalusActiveText(uiBonus
, i
, false);
546 -- reset special tooltip
547 setDbProp( formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', i
), game
.TBonusMalusSpecialTT
.None
);
549 removeOnDbChange(uiBonus
, dbXpCat
);
550 removeOnDbChange(uiBonus
, dbRingXpCat
);
551 removeOnDbChange(uiBonus
, dbOutpost
);
554 -- *** set new XPCat setup
555 local slot
= self
.BonusMalus
.XPCatSlotAfter
;
557 -- set AH to use for this slot
558 self
.BonusMalus
.BonusAHList
[slot
]= "xp_catalyser_stop_use";
559 -- add DB change, and call now! else not updated
560 addOnDbChange(uiBonus
, dbXpCat
, formatUI("game:updateXpCatQuantity(#1, nil)", slot
) );
561 self
:updateXpCatQuantity(slot
, uiBonus
);
563 self
:bonusMalusActiveText(uiBonus
, slot
, true);
564 -- set special tooltip (id==1 for xpcat)
565 setDbProp( formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', slot
), game
.TBonusMalusSpecialTT
.XpCatalyser
);
568 -- *** set new RingXPCat setup
569 local slot
= self
.BonusMalus
.RingXPCatSlotAfter
;
571 -- set AH to use for this slot
572 self
.BonusMalus
.BonusAHList
[slot
]= "ring_xp_catalyser_stop_use";
573 -- add DB change, and call now! else not updated
574 addOnDbChange(uiBonus
, dbRingXpCat
, formatUI("game:updateRingXpCatQuantity(#1, nil)", slot
) );
575 self
:updateRingXpCatQuantity(slot
, uiBonus
);
577 self
:bonusMalusActiveText(uiBonus
, slot
, true);
578 -- set special tooltip (id==1 for ringxpcat)
579 setDbProp( formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', slot
), game
.TBonusMalusSpecialTT
.XpCatalyser
);
583 -- *** set new Outpost setup
584 local slot
= self
.BonusMalus
.OutpostSlotAfter
;
587 -- add DB change, and call now! else not updated
588 addOnDbChange(uiBonus
, dbOutpost
, formatUI("game:outpostUpdatePVPTimer(#1, nil)", slot
) );
589 self
:outpostUpdatePVPTimer(slot
, uiBonus
);
591 self
:bonusMalusActiveText(uiBonus
, slot
, true);
592 -- don't set the tooltip here, because redone after return
596 -- *** set new DeathPenalty setup
597 local slot
= self
.BonusMalus
.DeathPenaltyAfter
;
600 -- add DB change, and call now! else not updated
601 addOnDbChange(uiMalus
, dbDeathPenalty
, formatUI("game:deathPenaltyUpdateXPMalus(#1, nil)", slot
) );
602 self
:deathPenaltyUpdateXPMalus(slot
, uiMalus
);
604 self
:bonusMalusActiveText(uiMalus
, slot
, true);
605 -- set special tooltip (id==1 for death penalty)
606 setDbProp( formatUI('UI:VARIABLES:MALUS:#1:SPECIAL_TOOLTIP', slot
), game
.TBonusMalusSpecialTT
.DeathPenalty
);
611 ------------------------------------------------------------------------------------------------------------
612 -- Update Bonus malus local DB according to server DB
613 function game
:updatePlayerBonusMalus()
614 local numServerBonusMalus
= tonumber(getDefine("num_server_bonus_malus"));
615 local numLocalBonusMalus
= tonumber(getDefine("num_local_bonus_malus"));
616 local dbServerBonusBase
= getDefine("bonus") .. ":" ;
617 local dbServerMalusBase
= getDefine("malus") .. ":" ;
618 local dbLocalBonusBase
= "UI:VARIABLES:BONUS:";
619 local dbLocalMalusBase
= "UI:VARIABLES:MALUS:";
622 local mustUpdateTextSetup
= false;
625 -- ***********************
627 -- ***********************
629 local mustShowBonus
= false;
631 -- *** Insert XPCatalyzer first
632 local xpcatCount
= getDbProp("SERVER:CHARACTER_INFO:XP_CATALYSER:Count");
633 if(xpcatCount
~=0) then
634 local xpcatLevel
= getDbProp("SERVER:CHARACTER_INFO:XP_CATALYSER:Level");
635 -- Get the most appropriate icon
638 if(i
<=xpcatLevel
) then
642 -- Set the DB for this brick
644 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('big_xpcat_' .. tostring(iconLevel
) .. '.sbrick' ) );
645 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
646 self
.BonusMalus
.XPCatSlotAfter
= destIndex
;
647 destIndex
= destIndex
+1;
649 self
.BonusMalus
.XPCatSlotAfter
= -1;
651 if(self
.BonusMalus
.XPCatSlotAfter
~= self
.BonusMalus
.XPCatSlotBefore
) then
652 mustUpdateTextSetup
= true;
655 -- *** Then insert RingXPCatalyzer
656 local ringxpcatCount
= getDbProp("SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Count");
657 if(ringxpcatCount
~=0) then
658 local ringxpcatLevel
= getDbProp("SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Level");
659 -- Get the most appropriate icon
662 if(i
<=ringxpcatLevel
) then
666 -- Set the DB for this brick
668 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('big_ring_xpcat_' .. tostring(iconLevel
) .. '.sbrick' ) );
669 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
670 self
.BonusMalus
.RingXPCatSlotAfter
= destIndex
;
671 destIndex
= destIndex
+1;
673 self
.BonusMalus
.RingXPCatSlotAfter
= -1;
675 if(self
.BonusMalus
.RingXPCatSlotAfter
~= self
.BonusMalus
.RingXPCatSlotBefore
) then
676 mustUpdateTextSetup
= true;
680 -- *** Insert PVPOutpost
681 local pvpOutpostPresent
= getDbProp("SERVER:CHARACTER_INFO:PVP_OUTPOST:FLAG_PVP");
682 local pvpOutpostEndOfPVPFlag
= 0;
683 local pvpOutpostEndOfRound
= 0;
684 if(pvpOutpostPresent
~=0) then
685 local pvpOutpostLevel
= 0;
686 pvpOutpostEndOfPVPFlag
= getDbPropU('SERVER:CHARACTER_INFO:PVP_OUTPOST:FLAG_PVP_TIME_END');
687 pvpOutpostEndOfRound
= getDbPropU('SERVER:CHARACTER_INFO:PVP_OUTPOST:ROUND_END_DATE');
688 -- set a level only if we have some round, and if the out timer is not set
689 if(pvpOutpostEndOfRound
~=0 and pvpOutpostEndOfPVPFlag
==0) then
690 pvpOutpostLevel
= 1 + getDbProp('SERVER:CHARACTER_INFO:PVP_OUTPOST:ROUND_LVL_CUR');
693 -- Set the DB for this brick
695 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('big_outpost_pvp_' .. tostring(pvpOutpostLevel
) .. '.sbrick' ) );
696 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
697 self
.BonusMalus
.OutpostSlotAfter
= destIndex
;
698 destIndex
= destIndex
+1;
700 self
.BonusMalus
.OutpostSlotAfter
= -1;
702 if(self
.BonusMalus
.OutpostSlotAfter
~= self
.BonusMalus
.OutpostSlotBefore
) then
703 mustUpdateTextSetup
= true;
707 -- *** Insert standard Bonus
708 for i
=0,numServerBonusMalus
-1 do
710 local sheet
= getDbProp(dbServerBonusBase
.. tostring(i
) .. ":SHEET" );
711 local disabled
= getDbProp(dbServerBonusBase
.. tostring(i
) .. ":DISABLED" );
712 local timer
= getDbProp(dbServerBonusBase
.. tostring(i
) .. ":DISABLED_TIME" );
716 -- copy (to index shifted if needed)
717 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", sheet
);
718 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", disabled
);
719 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED_TIME", timer
);
720 destIndex
= destIndex
+1;
722 if(mustShowBonus
) then
723 setDbProp("UI:VARIABLES:SHOW_BONUS", 1);
725 setDbProp("UI:VARIABLES:SHOW_BONUS", 0);
729 -- *** erase any remaining bonus
730 while destIndex
<numLocalBonusMalus
do
731 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", 0 );
732 destIndex
= destIndex
+ 1;
737 -- ***********************
739 -- ***********************
740 local mustShowMalus
= false;
743 -- *** Insert Death Penalty first
744 local deathPenalty
= getDbProp("SERVER:USER:DEATH_XP_MALUS");
745 if(deathPenalty
~=255 and deathPenalty
~=0) then
746 -- Set the DB for this brick
748 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('death_penalty.sbrick' ) );
749 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
750 self
.BonusMalus
.DeathPenaltyAfter
= destIndex
;
751 destIndex
= destIndex
+1;
753 self
.BonusMalus
.DeathPenaltyAfter
= -1;
755 if(self
.BonusMalus
.DeathPenaltyAfter
~= self
.BonusMalus
.DeathPenaltyBefore
) then
756 mustUpdateTextSetup
= true;
759 -- *** insert standard malus
760 for i
=0,numServerBonusMalus
-1 do
762 local sheet
= getDbProp(dbServerMalusBase
.. tostring(i
) .. ":SHEET" );
763 local disabled
= getDbProp(dbServerMalusBase
.. tostring(i
) .. ":DISABLED" );
764 local timer
= getDbProp(dbServerMalusBase
.. tostring(i
) .. ":DISABLED_TIME" );
769 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":SHEET", sheet
);
770 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":DISABLED", disabled
);
771 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":DISABLED_TIME", timer
);
772 destIndex
= destIndex
+1;
774 if(mustShowMalus
) then
775 setDbProp("UI:VARIABLES:SHOW_MALUS", 1);
777 setDbProp("UI:VARIABLES:SHOW_MALUS", 0);
781 -- *** erase any remaining malus
782 while destIndex
<numLocalBonusMalus
do
783 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":SHEET", 0 );
784 destIndex
= destIndex
+ 1;
789 -- ***********************
790 -- *** update Text setup
791 -- ***********************
792 if(mustUpdateTextSetup
) then
793 game
:updateBonusMalusTextSetup();
796 -- set special tooltip for outpost (id==2,3,4 for outpost)
797 if(self
.BonusMalus
.OutpostSlotAfter
~= -1) then
798 local dbFmt
= formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', self
.BonusMalus
.OutpostSlotAfter
);
799 if(pvpOutpostEndOfPVPFlag
~= 0) then
800 setDbProp(dbFmt
, game
.TBonusMalusSpecialTT
.OutpostPVPOutOfZone
);
801 elseif(pvpOutpostEndOfRound
~= 0) then
802 setDbProp(dbFmt
, game
.TBonusMalusSpecialTT
.OutpostPVPInRound
);
804 setDbProp(dbFmt
, game
.TBonusMalusSpecialTT
.OutpostPVPOn
);
812 -- ***************************************************************************
813 -- ***************************************************************************
815 -- ***************************************************************************
816 -- ***************************************************************************
819 ------------------------------------------------------------------------------------------------------------
820 function game
:updateCurrentActionPosition()
821 local uiMemory
= getUI("ui:interface:gestionsets");
822 local uiAction
= getUI("ui:interface:current_action");
823 local uiMain
= getUI("ui:interface");
824 if(uiAction
and uiMain
and uiMemory
and uiMemory
.active
) then
826 -- NB: must use harcoded 182 and 40 size for the window, because may not be active at this time
828 -- refresh the x position
829 uiAction
.x
= uiMemory
.x_real
+ uiMemory
.w_real
/2 - 182/2;
831 -- setup the y position according to position of the memory bar
832 local distBelow
= uiMemory
.y_real
;
833 local distAbove
= uiMain
.h
- (uiMemory
.y_real
+ uiMemory
.h_real
);
834 if(distBelow
< distAbove
) then
835 uiAction
.y
= uiMemory
.y_real
+ uiMemory
.h_real
+ 40;
837 uiAction
.y
= uiMemory
.y_real
;
844 LastTooltipPhrase
= nil
846 ------------------------------------------------------------------------------------------------------------
847 -- tool function used by game:updatePhraseTooltip
848 function game
:setPhraseTooltipCarac(ttWin
, name
, value
, textValue
)
849 local icon
= ttWin
:find(name
)
850 local text
= ttWin
:find(name
.. "_text")
857 if textValue
~= nil then
858 text
.uc_hardtext
= textValue
860 text
.hardtext
= tostring(value
)
866 function game
:timeInSecondsToReadableTime(regenTime
)
867 local seconds
= math
.fmod(regenTime
, 60)
868 local minutes
= math
.fmod(math
.floor(regenTime
/ 60), 60)
869 local hours
= math
.floor(regenTime
/ 3600)
871 if seconds
> 0 then result
= concatUCString(tostring(seconds
), i18n
.get("uittSecondsShort")) end
872 if minutes
> 0 then result
= concatUCString(tostring(minutes
), i18n
.get("uittMinutesShort"), result
) end
873 if hours
> 0 then result
= concatUCString(tostring(hours
), i18n
.get("uittHoursShort"), result
) end
877 ------------------------------------------------------------------------------------------------------------
878 -- display the time left for a power / auras in its tooltip
879 function game
:setPhraseTooltipPowerRegenTime(ttWin
, regenTimeInTicks
)
880 local text
= ttWin
:find("regen_time")
881 if regenTimeInTicks
== 0 then
885 text
.uc_hardtext_single_line_format
= concatUCString(i18n
.get("uittRegenTime"), game
:timeInSecondsToReadableTime(math
.floor((regenTimeInTicks
+ 9) * 0.1)))
886 text
:invalidateCoords()
887 ttWin
:invalidateCoords()
892 local EmptyUCString
= ucstring()
894 ------------------------------------------------------------------------------------------------------------
895 -- called by C++ code when the tooltip of a phrase is about to be displayed
896 function game
:updatePhraseTooltip(phrase
)
897 LastTooltipPhrase
= phrase
898 local ttWin
= getUI("ui:interface:action_context_help")
899 local text
= phrase
:getName()
901 if not text
or text
== EmptyUCString
then
905 local desc
= phrase
:getDesc()
906 if desc
and desc
~= EmptyUCString
then
907 local str
= tostring(desc
)
908 local charFound
= false
909 for k
= 1, string.len(str
) do
910 if string.byte(str
, k
) ~= 32 then
916 text
= concatUCString(text
, "\n@{CCCF}", desc
)
919 text
= concatUCString(text
, "@{CCCF}")
921 -- IMPORTANT : the following getters on 'phrase' take in account the 'total action malus' for the timebeing
922 self
:setPhraseTooltipCarac(ttWin
, "hp_cost", phrase
:getHpCost())
923 self
:setPhraseTooltipCarac(ttWin
, "sta_cost", phrase
:getStaCost())
924 self
:setPhraseTooltipCarac(ttWin
, "sap_cost", phrase
:getSapCost())
925 self
:setPhraseTooltipCarac(ttWin
, "focus_cost", phrase
:getFocusCost())
926 self
:setPhraseTooltipCarac(ttWin
, "cast_time", phrase
:getCastTime(), concatUCString(string.format("%.1f", phrase
:getCastTime()), i18n
.get("uittSeconds")))
927 local castRange
= phrase
:getCastRange()
928 if not phrase
:isMagicPhrase() then
931 self
:setPhraseTooltipCarac(ttWin
, "cast_range", castRange
, concatUCString(tostring(castRange
), i18n
.get("uittMeters")))
932 -- if the phrase is a power / aura, then we may want to display its regen time in the tooltip
933 if phrase
:isPowerPhrase() then
934 setOnDraw(ttWin
, "game:updatePowerPhraseTooltip()")
939 local successRateText
= ttWin
:find("success_rate")
940 local successRate
= phrase
:getSuccessRate()
941 if successRate
== 0 then
942 successRateText
.active
= false
944 successRateText
.active
= true
945 successRateText
.uc_hardtext_single_line_format
= concatUCString(i18n
.get("uittSuccessRate"), tostring(successRate
), " %")
948 local disableTimeText
= ttWin
:find("disable_time")
949 if phrase
:isPowerPhrase() then
950 local disableTime
= phrase
:getPowerDisableTime()
951 if disableTime
== 0 then
952 disableTimeText
.active
= false
954 disableTimeText
.active
= true
955 disableTimeText
.uc_hardtext_single_line_format
= concatUCString(i18n
.get("uittDisableTime"), game
:timeInSecondsToReadableTime(disableTime
/ 10))
958 disableTimeText
.active
= false
960 game
:updatePowerPhraseTooltip()
961 updateTooltipCoords()
965 ------------------------------------------------------------------------------------------------------------
966 -- called at each frame when a power/aura tooltip is displayed,in order to update the regen countdown
967 function game
:updatePowerPhraseTooltip()
968 local ttWin
= getUI("ui:interface:action_context_help")
969 local leftRegenTime
= 0
970 if LastTooltipPhrase
:isPowerPhrase() then
971 leftRegenTime
= LastTooltipPhrase
:getTotalRegenTime() - LastTooltipPhrase
:getRegenTime()
973 if leftRegenTime
< 0 then
976 self
:setPhraseTooltipPowerRegenTime(ttWin
, leftRegenTime
)
977 updateTooltipCoords()
981 -- ***************************************************************************
982 -- ***************************************************************************
984 -- ***************************************************************************
985 -- ***************************************************************************
987 ------------------------------------------------------------------------------------------------------------
988 -- called by C++ code when the tooltip of a buff item is about to be displayed
989 function game
:updateBuffItemTooltip(buffItem
)
990 local ttWin
= getUI("ui:interface:buff_item_context_help")
991 local item
= buffItem
:getItemInfo()
992 local text
= buffItem
:getName()
994 self
:setPhraseTooltipCarac(ttWin
, "hp_buff", item
.HpBuff
)
995 self
:setPhraseTooltipCarac(ttWin
, "sta_buff", item
.StaBuff
)
996 self
:setPhraseTooltipCarac(ttWin
, "sap_buff", item
.SapBuff
)
997 self
:setPhraseTooltipCarac(ttWin
, "focus_buff", item
.FocusBuff
)
998 self
:setPhraseTooltipCarac(ttWin
, "durability", item
.Hp
)
1000 if item
.HpMax
== 0 then
1001 ttWin
:find("durability_sep").active
= false
1002 ttWin
:find("durability_max").active
= false
1004 ttWin
:find("durability_sep").active
= true
1005 ttWin
:find("durability_max").active
= true
1006 ttWin
:find("durability_max").hardtext
= item
.HpMax
1009 updateTooltipCoords()
1014 -- ***************************************************************************
1015 -- ***************************************************************************
1016 -- CURRENT CRYSTALLIZED SPELL
1017 -- ***************************************************************************
1018 -- ***************************************************************************
1020 ------------------------------------------------------------------------------------------------------------
1021 -- called by C++ code when the tooltip of a cristallized spell is about to be displayed
1022 function game
:updateCrystallizedSpellTooltip(crystallizedSpell
)
1023 local ttWin
= getUI("ui:interface:crystallized_spell_context_help")
1024 local text
= crystallizedSpell
:getName()
1026 crystallizedSpell
:buildCrystallizedSpellListBrick()
1028 updateTooltipCoords()
1032 ------------------------------------------------------------------------------------------------------------
1033 -- update craft window craftplan or item name and description
1035 -- uiCaller == ui:interface:phrase_faber_execution:header_opened
1036 -- dbPath == UI:PHRASE:FABER:FABER_PLAN:SHEET
1038 -- uiCaller == ui:interface:phrase_faber_execution:header_opened:item_result
1039 -- dbPath == UI:PHRASE:FABER:RESULT_ITEM:SHEET
1040 function game
:updatePhraseFaberPreview(dbPath
)
1041 local ui
= getUICaller();
1042 local sheet
= getSheetName(getDbProp(dbPath
))
1044 local name
= ui
:find("name")
1045 if (name
~= nil) then
1046 ui
:find("name").uc_hardtext
= getSheetLocalizedName(sheet
)
1049 local desc
= ui
:find("desc")
1050 if (desc
~= nil) then
1051 ui
:find("desc").uc_hardtext
= getSheetLocalizedDesc(sheet
)
1056 function game
:fixVpx(vpx
)
1057 while string.len(vpx
) < 16 do
1061 local vpx1
= string.format("%06d", tonumber(vpx
:sub(1, string.len(vpx
)-2), 16)*256)
1062 local vpx2
= string.format("%06d", tonumber(vpx
:sub(string.len(vpx
)-1, string.len(vpx
)), 16)+tonumber(vpx1
:sub(string.len(vpx1
)-5, string.len(vpx1
))))
1063 local nvpx
= vpx1
:sub(1, string.len(vpx1
)-6)..vpx2
:sub(string.len(vpx2
)-5, string.len(vpx2
))
1068 RYZOM_PLAYER_VERSION
= 324