Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / ryzom / client / mods / syui_v3 / syui / syui.lua
blobbfa8f8b3b3f2266681c618e77346e6874dc19337
1 -- written by Syphox
2 local M = {}
4 function M.exist()
5 return true
6 end
8 local bit32 = {}
9 local logic_and = {
10 [0] = { [0] = 0, 0, 0, 0},
11 [1] = { [0] = 0, 1, 0, 1},
12 [2] = { [0] = 0, 0, 2, 2},
13 [3] = { [0] = 0, 1, 2, 3},
16 local function checkint32( name, argidx, x, level )
17 local n = tonumber( x )
18 if not n then
19 error( string.format(
20 "bad argument #%d to '%s' (number expected, got %s)",
21 argidx, name, type( x )
22 ), level + 1 )
23 end
24 return math.floor( n ) % 0x100000000
25 end
27 local function comb( name, args, nargs, s, t )
28 for i = 1, nargs do
29 args[i] = checkint32( name, i, args[i], 3 )
30 end
31 local pow = 1
32 local ret = 0
33 for b = 0, 31, 2 do
34 local c = s
35 for i = 1, nargs do
36 c = t[c][args[i] % 4]
37 args[i] = math.floor( args[i] / 4 )
38 end
39 ret = ret + c * pow
40 pow = pow * 4
41 end
42 return ret
43 end
44 function bit32.btest( ... )
45 return comb( 'btest', { ... }, select( '#', ... ), 3, logic_and ) ~= 0
46 end
49 local function targetIsInSameTeam()
50 if(getDbProp('UI:VARIABLES:IS_TEAM_PRESENT')~=0)then
51 for i=0,7 do
52 local groupEntityUID = getDbProp('SERVER:GROUP:' .. tostring(i) ..':UID')
53 if(groupEntityUID == getDbProp('UI:VARIABLES:TARGET:UID'))then
54 return true
55 end
56 end
57 return false
58 end
59 end
61 local function targetIsInSameGuild()
62 if(getDbProp('SERVER:GUILD:NAME')~=0)then
63 local nbMember = getNbGuildMembers();
64 for i=0,(nbMember-1) do
65 if(getGuildMemberName(i) == getTargetName())then
66 return true
67 end
68 end
69 return false
70 end
71 end
73 local function targetIsInSameLeague()
74 local targetLeague = getDbProp('SERVER:Entities:E' .. getTargetSlot() .. ':P25')
75 local playerLeague = getDbProp('SERVER:Entities:E0:P25')
76 if(targetLeague == playerLeague and playerLeague ~= 0)then
77 return true
78 end
79 return false
80 end
82 -- no way found yet
83 local function targetIsInSameOpFight()
85 end
87 -- 1=duel, 2=unk, 3=arena, 4=unk, 5=gvg (pr), 6=unk, 7=tagged(mara), 8=unk, 9=tp safezone, 10=safe zone related
88 function M.checkPvPMode()
89 local targetProp = getDbProp('SERVER:Entities:E' .. getTargetSlot() .. ':P23')
90 local playerProp = getDbProp('SERVER:Entities:E0:P23')
91 local pvp_mode = {1,3,5,7}
92 for i=1,8 do
93 if(bit32.btest(targetProp, 2^(i-1)) and bit32.btest(playerProp, 2^(i-1)))then
94 return true
95 end
96 end
97 return false
98 end
100 function M.PvPLogo()
101 local targetProp = getDbProp('SERVER:Entities:E' .. getTargetSlot() .. ':P23')
102 for i=1,8 do
103 if(bit32.btest(targetProp, 2^(i-1)))then
104 return true
107 return false
110 function M.isEnemy()
111 if(isTargetPlayer() and M.checkPvPMode())then
112 if(targetIsInSameGuild())then
113 return false
115 if(targetIsInSameTeam())then
116 return false
118 if(targetIsInSameLeague())then
119 return false
121 return true
123 return false
126 local function TJauge(val)
127 local jvalue = getDbProp("UI:VARIABLES:BARS:TARGET:" .. val) / 1.27
128 if(jvalue < 0)then
129 jvalue = 0
131 setDbProp("UI:VARIABLES:BARS:TARGET:" .. val .. "_PERCENT", math.floor(jvalue))
134 function M.UpdateJauge()
135 local bars = {"HP", "SAP", "STA"}
136 for k,v in pairs(bars) do
137 TJauge(v)
141 function M.teamInvite(uiID)
142 runAH(nil, 'talk', 'mode=0|text=/invite '.. getUI('ui:interface:' .. uiID).title)
145 function M.updateFLinvB(uiID)
146 if(uiID==nil)then
147 return
149 local tUI = getUI('ui:interface:' .. uiID .. ':header_closed:invite_button')
150 if(getUI('ui:interface:' .. uiID .. ':header_closed:online').texture ~= 'w_online.tga')then
151 if(tUI.texture == 'invt.tga')then
152 tUI.texture = ''
154 else
155 if(tUI.texture == '')then
156 tUI.texture = 'invt.tga'
157 tUI.x = -52
158 tUI.y = 0
160 end
163 function M.invToGuild(ply)
164 ply = getUI('ui:interface:add_guild'):find('edit_text').hardtext:split(">")[2]
165 if(ply ~= '')then
166 runAH(nil, 'talk', 'mode=0|text=/guildinvite ' .. ply)
168 runAH(nil, 'leave_modal', '')
171 function M.teamInviteFromGuild(uiID)
172 runAH(nil, 'talk', 'mode=0|text=/invite ' .. getGuildMemberName(tonumber(uiID:split(":m")[2])))
175 local tGuild = 'ui:interface:guild:content:tab_guild:list_member:guild_members'
176 function M.updateGLinvB()
177 if(getUI('ui:interface:guild').active)then
178 -- if get #id from member template, it creates too many instances and game will crash. bad coded from ryzom dev
179 for v = 0, (getNbGuildMembers()-1) do
180 local uiTexture = getUI(tGuild .. ":" .. tGuild .. ":m" .. v .. ':online')
181 local tUI = getUI(tGuild .. ":" .. tGuild .. ":m" .. v .. ':invite_button')
182 if(getUI("ui:interface:player").title ~= getUI(tGuild .. ":" .. tGuild .. ":m" .. v .. ":name").hardtext)then
183 if(uiTexture.texture ~= 'w_online.tga')then
184 if(tUI.texture == 'invt.tga')then
185 tUI.texture = ''
187 else
188 if(tUI.texture == '')then
189 tUI.texture = 'invt.tga'
190 tUI.x = -22
191 tUI.y = 0
194 else
195 -- fix the invite button in guild tab, because it sometimes disappear
196 -- the button appear for the player with higher grade than member
197 local invB = getUI('ui:interface:guild:content:tab_guild_i:invite')
198 if(getGuildMemberGrade(v) ~= 'Member')then
199 if(invB.active == false)then
200 invB.active = true
202 else
203 invB.active = false
210 function M.updateMemberCount()
211 -- fix the new guild tab
212 local mcount = getUI('ui:interface:guild:content:tab_guild_i:member_count')
213 if(getUI('ui:interface:guild').active)then
214 if(tonumber(mcount.hardtext) ~= getNbGuildMembers())then
215 mcount.hardtext = getNbGuildMembers()
220 function M.updateFPS()
221 local fpsUI = getUI('ui:interface:compass:frame:fps')
222 if(fpsUI==nil)then return end;
223 local fps = getDbProp('UI:VARIABLES:FPS')
224 fpsUI.hardtext = fps;
225 local colRGB = '255 81 81 255'
226 if(fps >= 30)then
227 colRGB = '155 255 81 255'
228 elseif(fps >= 20)then
229 colRGB = '249 255 81 255'
231 fpsUI.color = colRGB
234 function string:split(Pattern)
235 local Results = {}
236 local Start = 1
237 local SplitStart, SplitEnd = string.find(self, Pattern, Start)
238 while(SplitStart)do
239 table.insert(Results, string.sub(self, Start, SplitStart-1))
240 Start = SplitEnd+1
241 SplitStart, SplitEnd = string.find(self, Pattern, Start)
243 table.insert(Results, string.sub(self, Start))
244 return Results
247 function M.sysinfo(txt, mtd)
248 if(mtd==nil)then mtd='SYS' end;
249 displaySystemInfo(ucstring(tostring(txt)), mtd);
252 function M.showTargetPercent()
253 local targetUI = getUI('ui:interface:target')
254 local playerUI = getUI('ui:interface:player')
255 local contentUI = targetUI:find("content")
256 local clawImg = targetUI:find("slot_claw")
257 local targetTitle = targetUI:find("target_title")
258 local playerTitle = playerUI:find("player_title")
259 local wgTargetConside = targetUI:find("conside")
260 local wgTargetLevel = targetUI:find("target_level")
261 targetTitle.color = "255 255 255 255"
262 playerTitle.color = targetTitle.color
264 if (isTargetUser() or
265 (isTargetPlayer() and
266 not M.isEnemy()))then
267 wgTargetConside.active = false
268 contentUI.h = 55
269 contentUI.y = -24
270 clawImg.active = false
271 else
272 if(not isTargetPlayer() and
273 not M.checkPvPMode() and
274 getTargetLevel() > 0)then
275 if(clawImg.texture ~= "claw.tga")then
276 clawImg.texture = "claw.tga"
277 clawImg.x = 7
278 clawImg.y = -6
281 if(targetUI.title == "")then
282 wgTargetConside.active = false
283 clawImg.active = false
285 contentUI.h = 18
286 contentUI.y = -26
289 if(getTargetLevelForce() > 0 and
290 not isTargetPlayer())then
291 if(getTargetLevel() > 0)then
292 --fix campfire, do not show claw
293 if(tostring(getTargetSheet())~="object_campfire_28_b.creature")then
294 wgTargetConside.active = true
295 clawImg.active = true
300 if(getTargetLevel() <= 0 or isTargetNPC())then
301 wgTargetConside.active = false
302 wgTargetLevel.active = false
303 wgTargetLevel.hardtext = ""
304 clawImg.active = false
305 wgTargetConside.texture = "blank_n.tga"
308 if((isTargetUser() or isTargetPlayer()) and M.PvPLogo())then
309 if(clawImg.texture ~= "pvp.tga")then
310 clawImg.texture = "pvp.tga"
311 clawImg.x = 0
312 clawImg.y = 5
314 clawImg.active = true
315 wgTargetConside.active = false
319 function M.newConsider()
320 local targetWindow = getUI("ui:interface:target")
321 local clawImg = targetWindow:find("slot_claw")
322 local targetTitle = targetWindow:find("target_title")
323 local wgTargetLevel = targetWindow:find("target_level")
324 local wgTargetConside = targetWindow:find("conside")
325 local wgImpossible = targetWindow:find("impossible")
326 local wgSlotRing = targetWindow:find("slot_ring")
327 local wgToolTip = targetWindow:find("target_tooltip")
328 local pvpMode = false
330 local maxDiffLevel = 10
331 if not pvpMode then
332 for gm = 0, 7 do
333 if getDbProp("SERVER:GROUP:" .. tostring(gm) .. ":PRESENT") ~= 0 then
334 maxDiffLevel = maxDiffLevel + 10
339 local impossible = (getTargetLevel() - getPlayerLevel() > maxDiffLevel)
341 wgSlotRing.active = false
342 wgTargetConside.active = false
343 wgImpossible.active = false
344 wgTargetConside.texture = "blank_n.tga"
346 if impossible then
347 -- targeted object is too hard too beat, display a skull
348 wgTargetLevel.active = false
349 wgTargetConside.active = false
350 wgImpossible.texture = "skull_imp.tga"
351 clawImg.active = false
352 wgImpossible.active = true
353 wgImpossible.color = "255 255 255 255"
354 --wgImpossible.color = "255 50 50 255"
355 wgTargetLevel.hardtext = ""
356 else
357 --fix campfire, do not show, claw, lvl and consider
358 if(tostring(getTargetSheet())=="object_campfire_28_b.creature")then
359 wgTargetConside.active = false
360 wgTargetLevel.active = false
361 wgTargetLevel.hardtext = ""
362 clawImg.active = false
363 wgTargetConside.texture = "blank_n.tga"
364 return
366 -- player can see the level of the targeted creature, but not from NPC's
367 if(not isTargetNPC())then
368 wgTargetLevel.active = true
369 wgTargetConside.active = true
370 wgImpossible.active = false
371 wgImpossible.texture = "blank_n.tga"
373 wgTargetLevel.hardtext = tostring(getTargetLevel())
374 wgTargetLevel.color = "255 255 255 255"
375 wgImpossible.color = "255 255 255 255"
378 local image={ 'b1', 'b2', 'b3', 'b4', 'b5', 'g1', 'g2', 'g3', 'g4', 'g5', 'ge1', 'ge2', 'ge3', 'ge4', 'ge5', 'r1', 'r2', 'r3', 'r4', 'r5', 'l1', 'l2', 'l3', 'l4', 'l5', 'l5', 'l5' }
380 if(getTargetLevel()<10)then
381 wgTargetConside.texture = 'consider_gr.tga'
384 for k,v in pairs(image) do
385 if(getTargetLevel()>=tonumber(k .. 0))then
386 wgTargetConside.texture = 'consider_' .. v .. '.tga'
391 -- based on the 'level force', set a colored ring around the level
392 local levelForce = getTargetLevelForce()
394 wgImpossible.active = true
395 if levelForce < 6 then
396 wgToolTip.tooltip = i18n.get("uittConsiderTargetLevel")
397 elseif levelForce == 6 then
398 -- Named creature
399 wgImpossible.color = "255 255 255 255"
400 --wgImpossible.color = "191 225 254 255"
401 wgImpossible.texture = "skull_imp.tga"
402 wgImpossible.active = true
403 wgToolTip.tooltip = i18n.get("uittConsiderNamedOrMiniBoss")
404 wgTargetLevel.hardtext = ""
405 elseif levelForce == 7 then
406 -- Boss
407 wgImpossible.color = "255 255 255 255"
408 --wgImpossible.color = "222 191 254 255"
409 wgImpossible.texture = "skull_imp.tga"
410 wgImpossible.active = true
411 wgToolTip.tooltip = i18n.get("uittConsiderNamedOrMiniBoss")
412 wgTargetLevel.hardtext = ""
413 elseif levelForce == 8 then
414 -- Mini-Boss
415 wgImpossible.color = "255 255 255 255"
416 --wgImpossible.color = "254 191 191 255"
417 wgImpossible.texture = "skull_imp.tga"
418 wgImpossible.active = true
419 wgTargetLevel.hardtext = ""
420 wgTargetConside.active = false
421 if isTargetNPC() then
422 wgToolTip.tooltip = i18n.get("uittConsiderBossNpc")
423 else
424 wgToolTip.tooltip = i18n.get("uittConsiderBoss")
428 if impossible then
429 wgToolTip.tooltip = concatUCString(wgToolTip.tooltip, ucstring("\n"), i18n.get("uittConsiderUnknownLevel"))
433 return M