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
= {};
46 ------------------------------------------------------------------------------------------------------------
47 -- Update player bars in function of what we wants to display (we can hide each one of the 3 bars : sap,stamina and focus)
48 function game
:updatePlayerBars()
50 local dispSap
= getDbProp('UI:SAVE:PLAYER:DISP_SAP');
51 local dispSta
= getDbProp('UI:SAVE:PLAYER:DISP_STA');
52 local dispFoc
= getDbProp('UI:SAVE:PLAYER:DISP_FOC');
54 local ui
= getUI('ui:interface:player:content');
56 -- active ui in function of what is displayed
58 ui
.b_sap
.active
= (dispSap
== 1);
59 ui
.jsap
.active
= (dispSap
== 1);
61 ui
.b_sta
.active
= (dispSta
== 1);
62 ui
.jsta
.active
= (dispSta
== 1);
64 ui
.b_foc
.active
= (dispFoc
== 1);
65 ui
.jfoc
.active
= (dispFoc
== 1);
67 -- choose good y-position
69 local totalBarDisp
= dispSap
+ dispSta
+ dispFoc
;
70 if (totalBarDisp
== 3) then
75 ui
.current_action
.y
= -65;
77 elseif (totalBarDisp
== 2) then
79 if (dispSap
== 0) then
84 if (dispSta
== 0) then
89 if (dispFoc
== 0) then
94 ui
.current_action
.y
= -50;
96 elseif (totalBarDisp
== 1) then
102 ui
.current_action
.y
= -35;
105 ui
.current_action
.y
= -20;
112 ------------------------------------------------------------------------------------------------------------
113 -- convert a boolean to a number 0 or 1
114 function booleanToNumber(thebool
)
122 ------------------------------------------------------------------------------------------------------------
123 -- Update player pvp tag
124 function game
:pvpTagUpdateDisplay()
125 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
126 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
127 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
128 local uiPlayer
= getUI('ui:interface:player:header_opened');
130 -- get the current state
131 local pvpServerFlag
= pvpServerFlagTimer
> currentServerTick
;
132 local pvpLocalTag
= (getDbProp('UI:TEMP:PVP_FACTION:TAG_PVP') == 1);
133 local pvpServerTag
= (getDbProp('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:TAG_PVP') == 1);
134 local pvpServerActivateTimerOn
= pvpServerTagTimer
> currentServerTick
;
136 -- deduce the display state according to the current state
140 local buttonMode
= GREEN
;
141 local buttonPushed
= false;
142 local buttonTimer
= false;
143 -- if the flag is activated, then must display PVP flag button and timer
144 if (pvpServerFlag
) then
149 -- else must display correct mode according to the TAG state
151 -- There are 8 possibilities according to the combination of the 3 flags
152 -- Here: TL= pvpLocalTag, TS= pvpServerTag, AS= pvpServerActivateTimerOn)
155 -- 0 0 0 -> Standard disabled PVP
156 -- 1 0 0 -> The user pressed the button but still no response from server
157 -- 1 1 1 -> The user pressed the button and got response from server. => GREEN icon with timer
158 -- 0 1 1 -> The user canceled the activation (server not acked yet the cancel). => default display
160 -- 1 1 0 -> Standard enabled PVP
161 -- 0 1 0 -> The user pressed the button but still no response from server
162 -- 0 0 1 -> The user pressed the button and got response from server. => ORANGE icon with timer
163 -- 1 0 1 -> The user canceled the activation (server not acked yet the cancel). => default display
165 -- From this table, we can deduce the following rules
167 -- buttonMode is GREEN when TS==AS
168 if( pvpServerTag
== pvpServerActivateTimerOn
) then
174 -- the button is pushed if (there is a timer and TL==TS), or (no timer and TL!=TS)
175 if( pvpServerActivateTimerOn
== (pvpLocalTag
== pvpServerTag
) ) then
181 -- display a timer only if the timer is activated and server and local tag are equals
182 if( pvpServerActivateTimerOn
and pvpLocalTag
== pvpServerTag
) then
190 -- setup the local display
191 setDbProp("UI:TEMP:PVP_FACTION:DSP_MODE", buttonMode
);
192 setDbProp("UI:TEMP:PVP_FACTION:DSP_PUSHED", booleanToNumber(buttonPushed
));
193 setDbProp("UI:TEMP:PVP_FACTION:DSP_TIMER", booleanToNumber(buttonTimer
));
195 -- setup the timer bar
197 local uiBar
= uiPlayer
.pvp_timer
;
198 local uiBarBg
= uiPlayer
.pvp_timer_bg
;
200 if(buttonMode
==RED
) then
201 -- display a reverse timer
202 uiBar
.w
= uiBarBg
.w
* (pvpServerFlagTimer
- currentServerTick
) / (pvpServerFlagTimer
- game
.PVP
.flagStartTimer
);
204 -- display a forward timer
205 uiBar
.w
= uiBarBg
.w
* (currentServerTick
- game
.PVP
.tagStartTimer
) / (pvpServerTagTimer
- game
.PVP
.tagStartTimer
);
209 -- force update of the tooltip for any button (by disabling then reenabling)
210 disableContextHelpForControl(uiPlayer
.pvp_tag_button_0
);
211 disableContextHelpForControl(uiPlayer
.pvp_tag_button_1
);
212 disableContextHelpForControl(uiPlayer
.pvp_tag_button_2
);
215 ------------------------------------------------------------------------------------------------------------
216 -- Update player pvp tag
217 function game
:pvpTag()
218 local buttonStat
= getDbProp('UI:TEMP:PVP_FACTION:TAG_PVP');
219 if (buttonStat
== 0) then
220 setDbProp('UI:TEMP:PVP_FACTION:TAG_PVP',1);
222 setDbProp('UI:TEMP:PVP_FACTION:TAG_PVP',0);
224 sendMsgToServerPvpTag(buttonStat
== 0);
227 self
:pvpTagUpdateDisplay();
230 ------------------------------------------------------------------------------------------------------------
231 -- Update button due to server validation
232 function game
:updatePvpTag()
233 -- force copy to temp of Server tag
234 local pvpServerTag
= (getDbProp('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:TAG_PVP') == 1);
235 setDbProp('UI:TEMP:PVP_FACTION:TAG_PVP', booleanToNumber(pvpServerTag
));
237 -- launch timer DB if necessary
238 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
239 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
240 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
242 if(pvpServerTagTimer
> currentServerTick
) or (pvpServerFlagTimer
> currentServerTick
) then
243 local ui
= getUI('ui:interface:player');
244 addOnDbChange(ui
,'@UI:VARIABLES:CURRENT_SERVER_TICK', 'game:updatePvpTimer()');
246 if(pvpServerTagTimer
> currentServerTick
and game
.PVP
.tagTimerStarted
== false) then
247 game
.PVP
.tagStartTimer
= currentServerTick
;
248 game
.PVP
.tagTimerStarted
= true;
250 if(pvpServerFlagTimer
> currentServerTick
and game
.PVP
.flagTimerStarted
== false) then
251 game
.PVP
.flagStartTimer
= currentServerTick
;
252 game
.PVP
.flagTimerStarted
= true;
256 -- update display (after start timer reseted)
257 self
:pvpTagUpdateDisplay();
260 ------------------------------------------------------------------------------------------------------------
262 function game
:updatePvpTimer()
265 self
:pvpTagUpdateDisplay();
268 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
269 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
270 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
272 -- Manage Tag Timer display
273 if(pvpServerTagTimer
<= currentServerTick
) then
274 game
.PVP
.tagTimerStarted
= false;
277 -- Manage Flag Timer display
278 if(pvpServerFlagTimer
<= currentServerTick
) then
279 game
.PVP
.flagTimerStarted
= false;
282 -- if both off, stop the db update
283 if(game
.PVP
.tagTimerStarted
== false) and (game
.PVP
.flagTimerStarted
== false) then
284 removeOnDbChange(getUI('ui:interface:player'),'@UI:VARIABLES:CURRENT_SERVER_TICK');
288 ------------------------------------------------------------------------------------------------------------
290 function game
:formatTime(temps
)
292 local hours
= math
.floor(temps
/(10*60*60));
293 local minutes
= math
.floor((temps
- (hours
*10*60*60)) / (10*60));
294 local seconds
= math
.floor((temps
- (hours
*10*60*60) - (minutes
*10*60)) / 10);
296 local fmt
= i18n
.get('uittPvPTime');
297 fmt
= findReplaceAll(fmt
, '%h', tostring(hours
));
298 fmt
= findReplaceAll(fmt
, '%m', tostring(minutes
));
299 fmt
= findReplaceAll(fmt
, '%s', tostring(seconds
));
303 ------------------------------------------------------------------------------------------------------------
305 function game
:playerTTPvp()
307 -- The tooltip to display depends on the current display state
308 local buttonMode
= getDbProp("UI:TEMP:PVP_FACTION:DSP_MODE");
309 local buttonPushed
= (getDbProp("UI:TEMP:PVP_FACTION:DSP_PUSHED")==1);
310 local buttonTimer
= (getDbProp("UI:TEMP:PVP_FACTION:DSP_TIMER")==1);
314 if(buttonMode
==2) then
315 local pvpServerFlagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT');
316 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
317 local tempsString
= game
:formatTime( pvpServerFlagTimer
- currentServerTick
);
318 text
= i18n
.get('uittPvPModeFlag');
319 text
= findReplaceAll(text
, '%temps', tempsString
);
323 if(buttonMode
==0 and not(buttonPushed
)) then
324 text
= i18n
.get('uittPvPModeTagOff');
325 elseif(buttonMode
==0 and buttonPushed
) then
326 text
= i18n
.get('uittPvPModeTagOffChange');
327 elseif(buttonMode
==1 and not(buttonPushed
)) then
328 text
= i18n
.get('uittPvPModeTagOn');
329 elseif(buttonMode
==1 and buttonPushed
) then
330 text
= i18n
.get('uittPvPModeTagOnChange');
336 local pvpServerTagTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_FACTION_TAG:ACTIVATION_TIME');
337 local currentServerTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
338 local tempsString
= game
:formatTime( pvpServerTagTimer
- currentServerTick
);
339 local timeFmt
= i18n
.get('uittPvPTagTimer');
340 timeFmt
= findReplaceAll(timeFmt
, '%temps', tempsString
);
341 text
= concatUCString(text
, timeFmt
);
346 setContextHelpText(text
);
351 -- ***************************************************************************
352 -- ***************************************************************************
354 -- ***************************************************************************
355 -- ***************************************************************************
358 ------------------------------------------------------------------------------------------------------------
359 function game
:bonusMalusActiveText(ui
, slot
, state
)
360 local uiTextGroup
= ui
["text" .. tostring(slot
) ];
362 uiTextGroup
.active
= state
;
366 ------------------------------------------------------------------------------------------------------------
367 function game
:bonusMalusSetText(ui
, slot
, fmt
)
368 local uiTextGroup
= ui
["text" .. tostring(slot
) ];
370 uiTextGroup
.shade0
.uc_hardtext_format
= fmt
;
371 uiTextGroup
.shade1
.uc_hardtext_format
= fmt
;
372 uiTextGroup
.shade2
.uc_hardtext_format
= fmt
;
373 uiTextGroup
.shade3
.uc_hardtext_format
= fmt
;
374 uiTextGroup
.text
.uc_hardtext_format
= fmt
;
375 uiTextGroup
.text2
.uc_hardtext_format
= fmt
;
379 ------------------------------------------------------------------------------------------------------------
380 -- Called from c++ to format icon regen timer text
381 -- timer: number, ie 123, -123
382 -- dbPath: UI:VARIABLES:BONUS:0
384 -- Activate it in "bonuses" and/or "maluses" xml group.
385 -- If using color tags, then also set both colors to white
386 -- regen_text_fct="lua:game:formatRegenTimer"
387 -- regen_text_color="255 255 255"
388 -- regen_text_disabled_color="255 255 255"
389 function game
:formatRegenTimer(timer
, dbPath
)
391 return string.format("%dm", timer
/ 60);
393 return string.format("%ds", timer
);
397 ------------------------------------------------------------------------------------------------------------
398 -- From given DB vals, compute the 'Xp Bonus' text info
399 function game
:updateXpCatQuantity(textSlot
, ui
)
400 -- get the ui text to fill
406 local fmt
= "x@{FF6F}" .. tostring( getDbProp("SERVER:CHARACTER_INFO:XP_CATALYSER:Count") );
408 self
:bonusMalusSetText(ui
, textSlot
, fmt
);
412 ------------------------------------------------------------------------------------------------------------
413 -- From given DB vals, compute the 'Ring Xp Bonus' text info
414 function game
:updateRingXpCatQuantity(textSlot
, ui
)
415 -- get the ui text to fill
421 local fmt
= "x@{FF6F}" .. tostring( getDbProp("SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Count") );
423 self
:bonusMalusSetText(ui
, textSlot
, fmt
);
427 ------------------------------------------------------------------------------------------------------------
428 function game
:outpostUpdatePVPTimer(textSlot
, ui
)
429 -- get the ui text to fill
434 -- Get the timer of interest (priority to player leaving the zone)
436 local endOfPvpTimer
= getDbPropU('SERVER:CHARACTER_INFO:PVP_OUTPOST:FLAG_PVP_TIME_END');
437 if( endOfPvpTimer
>0 ) then
438 endTimer
= endOfPvpTimer
;
440 local endOfRound
= getDbProp('SERVER:CHARACTER_INFO:PVP_OUTPOST:ROUND_END_DATE');
441 if( endOfRound
>0 ) then
442 endTimer
= endOfRound
;
446 -- Use a text with a timer?
447 if( endTimer
>0 ) then
448 -- compute the time that lefts in sec (suppose a smooth server tick is 1 ms)
449 local curTick
= getDbPropU('UI:VARIABLES:CURRENT_SERVER_TICK');
450 local timeSec
= (endTimer
- curTick
)/10;
452 local text
= "@{FF6F}" .. runFct('secondsToTimeStringShort', timeSec
);
453 self
:bonusMalusSetText(ui
, textSlot
, text
);
454 -- else Default display
456 self
:bonusMalusSetText(ui
, textSlot
, "@{FF6F}on");
462 ------------------------------------------------------------------------------------------------------------
463 function game
:deathPenaltyUpdateXPMalus()
467 ------------------------------------------------------------------------------------------------------------
468 -- called when someone click on a bonus malus icon. redirect to correct action handler if any
469 function game
:onLeftClickBonus()
470 local ui
= getUICaller();
471 local id
= getIndexInDB(ui
);
472 local ah
= self
.BonusMalus
.BonusAHList
[id
];
478 function game
:onLeftClickMalus()
479 local ui
= getUICaller();
480 local id
= getIndexInDB(ui
);
481 local ah
= self
.BonusMalus
.MalusAHList
[id
];
487 ------------------------------------------------------------------------------------------------------------
488 -- update if needed the ActionHandler and text update from DB
489 function game
:updateBonusMalusTextSetup()
490 local numLocalBonusMalus
= tonumber(getDefine("num_local_bonus_malus"));
491 local uiBonus
= getUI('ui:interface:bonus_malus:header_opened:bonus');
492 local uiMalus
= getUI('ui:interface:bonus_malus:header_opened:malus');
493 local dbXpCat
= "@SERVER:CHARACTER_INFO:XP_CATALYSER:Count";
494 local dbRingXpCat
= "@SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Count";
495 local dbOutpost
= "@SERVER:CHARACTER_INFO:PVP_OUTPOST, @UI:VARIABLES:CURRENT_SERVER_TICK";
496 local dbDeathPenalty
= "@SERVER:USER:DEATH_XP_MALUS";
500 self
.BonusMalus
.DeathPenaltyBefore
= self
.BonusMalus
.DeathPenaltyAfter
;
501 self
.BonusMalus
.XPCatSlotBefore
= self
.BonusMalus
.XPCatSlotAfter
;
502 self
.BonusMalus
.RingXPCatSlotBefore
= self
.BonusMalus
.RingXPCatSlotAfter
;
503 self
.BonusMalus
.OutpostSlotBefore
= self
.BonusMalus
.OutpostSlotAfter
;
506 -- *** remove and hide any preceding
507 for i
= 0,numLocalBonusMalus
-1 do
509 self
.BonusMalus
.BonusAHList
[i
]= nil;
510 self
.BonusMalus
.MalusAHList
[i
]= nil;
512 self
:bonusMalusActiveText(uiBonus
, i
, false);
513 -- reset special tooltip
514 setDbProp( formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', i
), game
.TBonusMalusSpecialTT
.None
);
516 removeOnDbChange(uiBonus
, dbXpCat
);
517 removeOnDbChange(uiBonus
, dbRingXpCat
);
518 removeOnDbChange(uiBonus
, dbOutpost
);
521 -- *** set new XPCat setup
522 local slot
= self
.BonusMalus
.XPCatSlotAfter
;
524 -- set AH to use for this slot
525 self
.BonusMalus
.BonusAHList
[slot
]= "xp_catalyser_stop_use";
526 -- add DB change, and call now! else not updated
527 addOnDbChange(uiBonus
, dbXpCat
, formatUI("game:updateXpCatQuantity(#1, nil)", slot
) );
528 self
:updateXpCatQuantity(slot
, uiBonus
);
530 self
:bonusMalusActiveText(uiBonus
, slot
, true);
531 -- set special tooltip (id==1 for xpcat)
532 setDbProp( formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', slot
), game
.TBonusMalusSpecialTT
.XpCatalyser
);
535 -- *** set new RingXPCat setup
536 local slot
= self
.BonusMalus
.RingXPCatSlotAfter
;
538 -- set AH to use for this slot
539 self
.BonusMalus
.BonusAHList
[slot
]= "ring_xp_catalyser_stop_use";
540 -- add DB change, and call now! else not updated
541 addOnDbChange(uiBonus
, dbRingXpCat
, formatUI("game:updateRingXpCatQuantity(#1, nil)", slot
) );
542 self
:updateRingXpCatQuantity(slot
, uiBonus
);
544 self
:bonusMalusActiveText(uiBonus
, slot
, true);
545 -- set special tooltip (id==1 for ringxpcat)
546 setDbProp( formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', slot
), game
.TBonusMalusSpecialTT
.XpCatalyser
);
550 -- *** set new Outpost setup
551 local slot
= self
.BonusMalus
.OutpostSlotAfter
;
554 -- add DB change, and call now! else not updated
555 addOnDbChange(uiBonus
, dbOutpost
, formatUI("game:outpostUpdatePVPTimer(#1, nil)", slot
) );
556 self
:outpostUpdatePVPTimer(slot
, uiBonus
);
558 self
:bonusMalusActiveText(uiBonus
, slot
, true);
559 -- don't set the tooltip here, because redone after return
563 -- *** set new DeathPenalty setup
564 local slot
= self
.BonusMalus
.DeathPenaltyAfter
;
567 -- add DB change, and call now! else not updated
568 addOnDbChange(uiMalus
, dbDeathPenalty
, formatUI("game:deathPenaltyUpdateXPMalus(#1, nil)", slot
) );
569 self
:deathPenaltyUpdateXPMalus(slot
, uiMalus
);
571 self
:bonusMalusActiveText(uiMalus
, slot
, true);
572 -- set special tooltip (id==1 for death penalty)
573 setDbProp( formatUI('UI:VARIABLES:MALUS:#1:SPECIAL_TOOLTIP', slot
), game
.TBonusMalusSpecialTT
.DeathPenalty
);
578 ------------------------------------------------------------------------------------------------------------
579 -- Update Bonus malus local DB according to server DB
580 function game
:updatePlayerBonusMalus()
581 local numServerBonusMalus
= tonumber(getDefine("num_server_bonus_malus"));
582 local numLocalBonusMalus
= tonumber(getDefine("num_local_bonus_malus"));
583 local dbServerBonusBase
= getDefine("bonus") .. ":" ;
584 local dbServerMalusBase
= getDefine("malus") .. ":" ;
585 local dbLocalBonusBase
= "UI:VARIABLES:BONUS:";
586 local dbLocalMalusBase
= "UI:VARIABLES:MALUS:";
589 local mustUpdateTextSetup
= false;
592 -- ***********************
594 -- ***********************
596 local mustShowBonus
= false;
598 -- *** Insert XPCatalyzer first
599 local xpcatCount
= getDbProp("SERVER:CHARACTER_INFO:XP_CATALYSER:Count");
600 if(xpcatCount
~=0) then
601 local xpcatLevel
= getDbProp("SERVER:CHARACTER_INFO:XP_CATALYSER:Level");
602 -- Get the most appropriate icon
605 if(i
<=xpcatLevel
) then
609 -- Set the DB for this brick
611 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('big_xpcat_' .. tostring(iconLevel
) .. '.sbrick' ) );
612 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
613 self
.BonusMalus
.XPCatSlotAfter
= destIndex
;
614 destIndex
= destIndex
+1;
616 self
.BonusMalus
.XPCatSlotAfter
= -1;
618 if(self
.BonusMalus
.XPCatSlotAfter
~= self
.BonusMalus
.XPCatSlotBefore
) then
619 mustUpdateTextSetup
= true;
622 -- *** Then insert RingXPCatalyzer
623 local ringxpcatCount
= getDbProp("SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Count");
624 if(ringxpcatCount
~=0) then
625 local ringxpcatLevel
= getDbProp("SERVER:CHARACTER_INFO:RING_XP_CATALYSER:Level");
626 -- Get the most appropriate icon
629 if(i
<=ringxpcatLevel
) then
633 -- Set the DB for this brick
635 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('big_ring_xpcat_' .. tostring(iconLevel
) .. '.sbrick' ) );
636 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
637 self
.BonusMalus
.RingXPCatSlotAfter
= destIndex
;
638 destIndex
= destIndex
+1;
640 self
.BonusMalus
.RingXPCatSlotAfter
= -1;
642 if(self
.BonusMalus
.RingXPCatSlotAfter
~= self
.BonusMalus
.RingXPCatSlotBefore
) then
643 mustUpdateTextSetup
= true;
647 -- *** Insert PVPOutpost
648 local pvpOutpostPresent
= getDbProp("SERVER:CHARACTER_INFO:PVP_OUTPOST:FLAG_PVP");
649 local pvpOutpostEndOfPVPFlag
= 0;
650 local pvpOutpostEndOfRound
= 0;
651 if(pvpOutpostPresent
~=0) then
652 local pvpOutpostLevel
= 0;
653 pvpOutpostEndOfPVPFlag
= getDbPropU('SERVER:CHARACTER_INFO:PVP_OUTPOST:FLAG_PVP_TIME_END');
654 pvpOutpostEndOfRound
= getDbPropU('SERVER:CHARACTER_INFO:PVP_OUTPOST:ROUND_END_DATE');
655 -- set a level only if we have some round, and if the out timer is not set
656 if(pvpOutpostEndOfRound
~=0 and pvpOutpostEndOfPVPFlag
==0) then
657 pvpOutpostLevel
= 1 + getDbProp('SERVER:CHARACTER_INFO:PVP_OUTPOST:ROUND_LVL_CUR');
660 -- Set the DB for this brick
662 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('big_outpost_pvp_' .. tostring(pvpOutpostLevel
) .. '.sbrick' ) );
663 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
664 self
.BonusMalus
.OutpostSlotAfter
= destIndex
;
665 destIndex
= destIndex
+1;
667 self
.BonusMalus
.OutpostSlotAfter
= -1;
669 if(self
.BonusMalus
.OutpostSlotAfter
~= self
.BonusMalus
.OutpostSlotBefore
) then
670 mustUpdateTextSetup
= true;
674 -- *** Insert standard Bonus
675 for i
=0,numServerBonusMalus
-1 do
677 local sheet
= getDbProp(dbServerBonusBase
.. tostring(i
) .. ":SHEET" );
678 local disabled
= getDbProp(dbServerBonusBase
.. tostring(i
) .. ":DISABLED" );
679 local timer
= getDbProp(dbServerBonusBase
.. tostring(i
) .. ":DISABLED_TIME" );
683 -- copy (to index shifted if needed)
684 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", sheet
);
685 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED", disabled
);
686 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":DISABLED_TIME", timer
);
687 destIndex
= destIndex
+1;
689 if(mustShowBonus
) then
690 setDbProp("UI:VARIABLES:SHOW_BONUS", 1);
692 setDbProp("UI:VARIABLES:SHOW_BONUS", 0);
696 -- *** erase any remaining bonus
697 while destIndex
<numLocalBonusMalus
do
698 setDbProp(dbLocalBonusBase
.. tostring(destIndex
) .. ":SHEET", 0 );
699 destIndex
= destIndex
+ 1;
704 -- ***********************
706 -- ***********************
707 local mustShowMalus
= false;
710 -- *** Insert Death Penalty first
711 local deathPenalty
= getDbProp("SERVER:USER:DEATH_XP_MALUS");
712 if(deathPenalty
~=255 and deathPenalty
~=0) then
713 -- Set the DB for this brick
715 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":SHEET", getSheetId('death_penalty.sbrick' ) );
716 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":DISABLED", 0 );
717 self
.BonusMalus
.DeathPenaltyAfter
= destIndex
;
718 destIndex
= destIndex
+1;
720 self
.BonusMalus
.DeathPenaltyAfter
= -1;
722 if(self
.BonusMalus
.DeathPenaltyAfter
~= self
.BonusMalus
.DeathPenaltyBefore
) then
723 mustUpdateTextSetup
= true;
726 -- *** insert standard malus
727 for i
=0,numServerBonusMalus
-1 do
729 local sheet
= getDbProp(dbServerMalusBase
.. tostring(i
) .. ":SHEET" );
730 local disabled
= getDbProp(dbServerMalusBase
.. tostring(i
) .. ":DISABLED" );
731 local timer
= getDbProp(dbServerMalusBase
.. tostring(i
) .. ":DISABLED_TIME" );
736 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":SHEET", sheet
);
737 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":DISABLED", disabled
);
738 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":DISABLED_TIME", timer
);
739 destIndex
= destIndex
+1;
741 if(mustShowMalus
) then
742 setDbProp("UI:VARIABLES:SHOW_MALUS", 1);
744 setDbProp("UI:VARIABLES:SHOW_MALUS", 0);
748 -- *** erase any remaining malus
749 while destIndex
<numLocalBonusMalus
do
750 setDbProp(dbLocalMalusBase
.. tostring(destIndex
) .. ":SHEET", 0 );
751 destIndex
= destIndex
+ 1;
756 -- ***********************
757 -- *** update Text setup
758 -- ***********************
759 if(mustUpdateTextSetup
) then
760 game
:updateBonusMalusTextSetup();
763 -- set special tooltip for outpost (id==2,3,4 for outpost)
764 if(self
.BonusMalus
.OutpostSlotAfter
~= -1) then
765 local dbFmt
= formatUI('UI:VARIABLES:BONUS:#1:SPECIAL_TOOLTIP', self
.BonusMalus
.OutpostSlotAfter
);
766 if(pvpOutpostEndOfPVPFlag
~= 0) then
767 setDbProp(dbFmt
, game
.TBonusMalusSpecialTT
.OutpostPVPOutOfZone
);
768 elseif(pvpOutpostEndOfRound
~= 0) then
769 setDbProp(dbFmt
, game
.TBonusMalusSpecialTT
.OutpostPVPInRound
);
771 setDbProp(dbFmt
, game
.TBonusMalusSpecialTT
.OutpostPVPOn
);
779 -- ***************************************************************************
780 -- ***************************************************************************
782 -- ***************************************************************************
783 -- ***************************************************************************
786 ------------------------------------------------------------------------------------------------------------
787 function game
:updateCurrentActionPosition()
788 local uiMemory
= getUI("ui:interface:gestionsets");
789 local uiAction
= getUI("ui:interface:current_action");
790 local uiMain
= getUI("ui:interface");
791 if(uiAction
and uiMain
and uiMemory
and uiMemory
.active
) then
793 -- NB: must use harcoded 182 and 40 size for the window, because may not be active at this time
795 -- refresh the x position
796 uiAction
.x
= uiMemory
.x_real
+ uiMemory
.w_real
/2 - 182/2;
798 -- setup the y position according to position of the memory bar
799 local distBelow
= uiMemory
.y_real
;
800 local distAbove
= uiMain
.h
- (uiMemory
.y_real
+ uiMemory
.h_real
);
801 if(distBelow
< distAbove
) then
802 uiAction
.y
= uiMemory
.y_real
+ uiMemory
.h_real
+ 40;
804 uiAction
.y
= uiMemory
.y_real
;
811 LastTooltipPhrase
= nil
813 ------------------------------------------------------------------------------------------------------------
814 -- tool function used by game:updatePhraseTooltip
815 function game
:setPhraseTooltipCarac(ttWin
, name
, value
, textValue
)
816 local icon
= ttWin
:find(name
)
817 local text
= ttWin
:find(name
.. "_text")
824 if textValue
~= nil then
825 text
.uc_hardtext
= textValue
827 text
.hardtext
= tostring(value
)
833 function game
:timeInSecondsToReadableTime(regenTime
)
834 local seconds
= math
.fmod(regenTime
, 60)
835 local minutes
= math
.fmod(math
.floor(regenTime
/ 60), 60)
836 local hours
= math
.floor(regenTime
/ 3600)
838 if seconds
> 0 then result
= concatUCString(tostring(seconds
), i18n
.get("uittSecondsShort")) end
839 if minutes
> 0 then result
= concatUCString(tostring(minutes
), i18n
.get("uittMinutesShort"), result
) end
840 if hours
> 0 then result
= concatUCString(tostring(hours
), i18n
.get("uittHoursShort"), result
) end
844 ------------------------------------------------------------------------------------------------------------
845 -- display the time left for a power / auras in its tooltip
846 function game
:setPhraseTooltipPowerRegenTime(ttWin
, regenTimeInTicks
)
847 local text
= ttWin
:find("regen_time")
848 if regenTimeInTicks
== 0 then
852 text
.uc_hardtext_single_line_format
= concatUCString(i18n
.get("uittRegenTime"), game
:timeInSecondsToReadableTime(math
.floor((regenTimeInTicks
+ 9) * 0.1)))
853 text
:invalidateCoords()
854 ttWin
:invalidateCoords()
859 local EmptyUCString
= ucstring()
861 ------------------------------------------------------------------------------------------------------------
862 -- called by C++ code when the tooltip of a phrase is about to be displayed
863 function game
:updatePhraseTooltip(phrase
)
864 LastTooltipPhrase
= phrase
865 local ttWin
= getUI("ui:interface:action_context_help")
866 local text
= phrase
:getName()
868 if not text
or text
== EmptyUCString
then
872 local desc
= phrase
:getDesc()
873 if desc
and desc
~= EmptyUCString
then
874 local str
= tostring(desc
)
875 local charFound
= false
876 for k
= 1, string.len(str
) do
877 if string.byte(str
, k
) ~= 32 then
883 text
= concatUCString(text
, "\n@{CCCF}", desc
)
886 text
= concatUCString(text
, "@{CCCF}")
888 -- IMPORTANT : the following getters on 'phrase' take in account the 'total action malus' for the timebeing
889 self
:setPhraseTooltipCarac(ttWin
, "hp_cost", phrase
:getHpCost())
890 self
:setPhraseTooltipCarac(ttWin
, "sta_cost", phrase
:getStaCost())
891 self
:setPhraseTooltipCarac(ttWin
, "sap_cost", phrase
:getSapCost())
892 self
:setPhraseTooltipCarac(ttWin
, "focus_cost", phrase
:getFocusCost())
893 self
:setPhraseTooltipCarac(ttWin
, "cast_time", phrase
:getCastTime(), concatUCString(string.format("%.1f", phrase
:getCastTime()), i18n
.get("uittSeconds")))
894 local castRange
= phrase
:getCastRange()
895 if not phrase
:isMagicPhrase() then
898 self
:setPhraseTooltipCarac(ttWin
, "cast_range", castRange
, concatUCString(tostring(castRange
), i18n
.get("uittMeters")))
899 -- if the phrase is a power / aura, then we may want to display its regen time in the tooltip
900 if phrase
:isPowerPhrase() then
901 setOnDraw(ttWin
, "game:updatePowerPhraseTooltip()")
906 local successRateText
= ttWin
:find("success_rate")
907 local successRate
= phrase
:getSuccessRate()
908 if successRate
== 0 then
909 successRateText
.active
= false
911 successRateText
.active
= true
912 successRateText
.uc_hardtext_single_line_format
= concatUCString(i18n
.get("uittSuccessRate"), tostring(successRate
), " %")
915 local disableTimeText
= ttWin
:find("disable_time")
916 if phrase
:isPowerPhrase() then
917 local disableTime
= phrase
:getPowerDisableTime()
918 if disableTime
== 0 then
919 disableTimeText
.active
= false
921 disableTimeText
.active
= true
922 disableTimeText
.uc_hardtext_single_line_format
= concatUCString(i18n
.get("uittDisableTime"), game
:timeInSecondsToReadableTime(disableTime
/ 10))
925 disableTimeText
.active
= false
927 game
:updatePowerPhraseTooltip()
928 updateTooltipCoords()
932 ------------------------------------------------------------------------------------------------------------
933 -- called at each frame when a power/aura tooltip is displayed,in order to update the regen countdown
934 function game
:updatePowerPhraseTooltip()
935 local ttWin
= getUI("ui:interface:action_context_help")
936 local leftRegenTime
= 0
937 if LastTooltipPhrase
:isPowerPhrase() then
938 leftRegenTime
= LastTooltipPhrase
:getTotalRegenTime() - LastTooltipPhrase
:getRegenTime()
940 if leftRegenTime
< 0 then
943 self
:setPhraseTooltipPowerRegenTime(ttWin
, leftRegenTime
)
944 updateTooltipCoords()
948 -- ***************************************************************************
949 -- ***************************************************************************
951 -- ***************************************************************************
952 -- ***************************************************************************
954 ------------------------------------------------------------------------------------------------------------
955 -- called by C++ code when the tooltip of a buff item is about to be displayed
956 function game
:updateBuffItemTooltip(buffItem
)
957 local ttWin
= getUI("ui:interface:buff_item_context_help")
958 local item
= buffItem
:getItemInfo()
959 local text
= buffItem
:getName()
961 self
:setPhraseTooltipCarac(ttWin
, "hp_buff", item
.HpBuff
)
962 self
:setPhraseTooltipCarac(ttWin
, "sta_buff", item
.StaBuff
)
963 self
:setPhraseTooltipCarac(ttWin
, "sap_buff", item
.SapBuff
)
964 self
:setPhraseTooltipCarac(ttWin
, "focus_buff", item
.FocusBuff
)
965 self
:setPhraseTooltipCarac(ttWin
, "durability", item
.Hp
)
967 if item
.HpMax
== 0 then
968 ttWin
:find("durability_sep").active
= false
969 ttWin
:find("durability_max").active
= false
971 ttWin
:find("durability_sep").active
= true
972 ttWin
:find("durability_max").active
= true
973 ttWin
:find("durability_max").hardtext
= item
.HpMax
976 updateTooltipCoords()
981 -- ***************************************************************************
982 -- ***************************************************************************
983 -- CURRENT CRYSTALLIZED SPELL
984 -- ***************************************************************************
985 -- ***************************************************************************
987 ------------------------------------------------------------------------------------------------------------
988 -- called by C++ code when the tooltip of a cristallized spell is about to be displayed
989 function game
:updateCrystallizedSpellTooltip(crystallizedSpell
)
990 local ttWin
= getUI("ui:interface:crystallized_spell_context_help")
991 local text
= crystallizedSpell
:getName()
993 crystallizedSpell
:buildCrystallizedSpellListBrick()
995 updateTooltipCoords()
999 ------------------------------------------------------------------------------------------------------------
1000 -- update craft window craftplan or item name and description
1002 -- uiCaller == ui:interface:phrase_faber_execution:header_opened
1003 -- dbPath == UI:PHRASE:FABER:FABER_PLAN:SHEET
1005 -- uiCaller == ui:interface:phrase_faber_execution:header_opened:item_result
1006 -- dbPath == UI:PHRASE:FABER:RESULT_ITEM:SHEET
1007 function game
:updatePhraseFaberPreview(dbPath
)
1008 local ui
= getUICaller();
1009 local sheet
= getSheetName(getDbProp(dbPath
))
1011 local name
= ui
:find("name")
1012 if (name
~= nil) then
1013 ui
:find("name").uc_hardtext
= getSheetLocalizedName(sheet
)
1016 local desc
= ui
:find("desc")
1017 if (desc
~= nil) then
1018 ui
:find("desc").uc_hardtext
= getSheetLocalizedDesc(sheet
)
1023 function game
:fixVpx(vpx
)
1024 while string.len(vpx
) < 16 do
1028 local vpx1
= string.format("%06d", tonumber(vpx
:sub(1, string.len(vpx
)-2), 16)*256)
1029 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
))))
1030 local nvpx
= vpx1
:sub(1, string.len(vpx1
)-6)..vpx2
:sub(string.len(vpx2
)-5, string.len(vpx2
))
1035 RYZOM_PLAYER_VERSION
= 10469