diff --git a/ryzom/client/data/gamedev/interfaces_v3/actions.xml b/ryzom/client/data/gamedev/interfaces_v3/actions.xml
index d8bb033b4..de2df5798 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/actions.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/actions.xml
@@ -31,6 +31,8 @@
+
+
@@ -78,10 +80,113 @@
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -134,7 +239,11 @@
+
+
+
+
@@ -229,6 +338,9 @@
+
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/appzone.lua b/ryzom/client/data/gamedev/interfaces_v3/appzone.lua
new file mode 100644
index 000000000..af9f584cd
--- /dev/null
+++ b/ryzom/client/data/gamedev/interfaces_v3/appzone.lua
@@ -0,0 +1,192 @@
+
+-- global
+AppZone = {
+ id = "ui:interface:appzone",
+ homeuri = "?action=appzone_toolbar",
+ launchuri = "?action=launch_app",
+ addappuri = "?action=list_user_apps",
+ mode = "h_bar",
+ imagesize = 26
+}
+
+-- use client.cfg value when available
+local uri = getClientCfg("AppZoneUrl")
+if uri == nil or uri == '' then
+ uri = 'http://app.ryzom.com/'
+end
+
+AppZone.homeuri = uri .. AppZone.homeuri
+AppZone.launchuri = uri .. AppZone.launchuri
+AppZone.addappuri = uri .. AppZone.addappuri
+
+function AppZone:getRoot()
+ return getUI(self.id)
+end
+
+function AppZone:onButtonHome()
+ local webig = getUI("ui:interface:webig")
+ webig:find("html").url = self.addappuri
+ webig.active = true
+end
+
+function AppZone:calculateSize(count, spacer, mode)
+ local w, h
+ if mode == "h_bar" then
+ -- icon=32, space=2+2
+ w = count * self.imagesize + spacer * 15
+ w = w + 55 + 10 + 20
+ h = self.imagesize + 2
+ elseif mode == "h_box" then
+ w = count * self.imagesize
+ w = w + 20
+ h = self.imagesize + 2
+ h = h * spacer
+ h = h + 15
+ elseif mode == "v_bar" then
+ -- icon=32, space=2+2
+ h = count * self.imagesize + spacer * 15
+ h = h + 20 + 20 + 12
+ w = self.imagesize + 2 + 18
+ else
+ h = count * self.imagesize
+ h = h + 20 + 25
+ w = self.imagesize + 2
+ w = w * spacer
+ w = w + 16
+ end
+
+ local ui = getUI("ui:interface")
+ if w > ui.w then
+ w = ui.w
+ end
+ if h > ui.h then
+ h = ui.h
+ end
+
+ return w, h
+end
+
+function AppZone:setElementCount(count,spacer,m)
+ self.mode = m
+
+ local root = self:getRoot()
+ local content = root:find("content")
+ local html = root:find("html")
+
+ local button_toggle = root:find("toggle_mode")
+ local button_reload = root:find("browse_reload")
+ local button_home = root:find("browse_home")
+
+ local w, h = self:calculateSize(count, spacer, self.mode)
+ root.h = h
+ root.w = w
+ content.w = w
+ content.h = h
+
+ -- set position of buttons
+ if self.mode == "h_bar" then
+ -- button_toggle.posref = "BL BL"
+ button_toggle.x = 2
+ button_toggle.y = 0
+ -- button_reload.posref = "TL BL"
+ html.x = 15
+ html.y = 0
+ button_reload.x = -25
+ button_reload.y = -25
+ -- button_home.posref = "BR BR"
+ button_home.x = 0
+ button_home.y = -3 + 5
+ elseif self.mode == "h_box" then
+ -- button_toggle.posref = "TL TL"
+ button_toggle.x = 2
+ button_toggle.y = h - 15
+ -- button_reload.posref = "TL BL"
+ html.x = 0
+ html.y = -20
+ button_reload.x = -25
+ button_reload.y = -4 - 20
+ -- button_home.posref = "BR BR"
+ button_home.x = 0
+ button_home.y = -3 + h - 18
+ elseif self.mode == "v_bar" then
+ -- button_toggle.posref = "TL TL"
+ button_toggle.x = 2
+ button_toggle.y = h - 15
+ -- button_reload.posref = "TL BL"
+ html.x = 0
+ html.y = -20
+ button_reload.x = 0
+ button_reload.y = -4
+ -- button_home.posref = "BR BR"
+ button_home.x = 4 - 7
+ button_home.y = -3
+ else
+ -- button_toggle.posref = "TL TL"
+ button_toggle.x = 2
+ button_toggle.y = h - 15
+ -- button_reload.posref = "TL BL"
+ html.x = 0
+ html.y = -20
+ button_reload.x = -25
+ button_reload.y = -4 - 20
+ -- button_home.posref = "BR BR"
+ button_home.x = 0 - w + 54 + 12
+ button_home.y = -3
+ end
+end
+
+function AppZone:setMode(m)
+ self.mode = m
+
+ self:reload()
+end
+
+function AppZone:setActive(s)
+ self:getRoot().active = s
+end
+
+function AppZone:launchApp(appid, appwin, appurl)
+ if not appwin then
+ if string.match(appid, "^[0-9]+$") then
+ appwin = "app" .. tostring(appid)
+ else
+ appwin = "webig"
+ end
+ end
+
+ if not appurl then
+ appurl = self.launchuri .. "&appid=" .. tostring(appid)
+ end
+
+ if WebBrowser then
+ WebBrowser:openWindow(appwin, appurl)
+ else
+ -- fallback if WebBrowser not present
+ local webig = getUI("ui:interface:webig")
+ webig:find("html").url = appurl;
+ webig.active = true
+ end
+end
+
+function AppZone:reload()
+ local url = self.homeuri
+ url = url .. "&mode=" .. tostring(self.mode)
+
+ local html = self:getRoot():find("html")
+ html.url = url
+end
+
+-- slash command: /appzone
+function AppZone:handle(cmd)
+ if cmd == 'show' then
+ self:setActive(true)
+ elseif cmd == 'hide' then
+ self:setActive(false)
+ elseif cmd == 'reload' then
+ self:reload()
+ elseif cmd == 'list' then
+ self:onButtonHome()
+ else
+ self:launchApp(cmd)
+ end
+end
diff --git a/ryzom/client/data/gamedev/interfaces_v3/appzone.xml b/ryzom/client/data/gamedev/interfaces_v3/appzone.xml
new file mode 100644
index 000000000..79595ffe1
--- /dev/null
+++ b/ryzom/client/data/gamedev/interfaces_v3/appzone.xml
@@ -0,0 +1,260 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/ark.lua b/ryzom/client/data/gamedev/interfaces_v3/ark.lua
new file mode 100644
index 000000000..8666be557
--- /dev/null
+++ b/ryzom/client/data/gamedev/interfaces_v3/ark.lua
@@ -0,0 +1,540 @@
+if Ark == nil then
+ Ark = {
+ }
+end
+
+function broadcast(text, t)
+ if t == nil then
+ t = "AMB"
+ end
+ local message = ucstring()
+ text = message:fromUtf8(tostring(text))
+ displaySystemInfo(message, t)
+end
+
+--------------------------------------------------------------------------------
+--- ARK MISSION CATALOG ---
+--------------------------------------------------------------------------------
+if ArkMissionCatalog == nil then
+ ArkMissionCatalog = {
+ window = nil,
+ window_id = "ui:interface:ark_mission_catalog"
+ }
+end
+
+function ArkMissionCatalog:OpenWindow(urlA, urlB)
+ local winframe = WebBrowser:addWindow("ark_mission_catalog", "Mission Catalog", getUI(ArkMissionCatalog.window_id))
+ winframe.opened=true
+ winframe.active=true
+ winframe.w = 950
+
+ ArkMissionCatalog.window = winframe
+
+ getUI(ArkMissionCatalog.window_id..":content:htmlA"):browse(urlA)
+
+ local htmlb = getUI(ArkMissionCatalog.window_id..":content:htmlB")
+ if htmlb.home == "" then
+ htmlb.home = urlB
+ end
+ htmlb:browse("home")
+
+end
+
+
+function ArkMissionCatalog:OpenCat(url)
+ local htmlb = getUI(ArkMissionCatalog.window_id..":content:htmlB")
+ htmlb.home = url+"&continent="+getContinentSheet()
+ htmlb:browse("home")
+end
+
+function ArkMissionCatalog:UpdateMissionTexts(win, id, text1, text2)
+ local w = win:find("ark_mission_"..id)
+ local text = ucstring()
+ text:fromUtf8(text1)
+ w:find("text1").uc_hardtext = text
+ text:fromUtf8(text2)
+ w:find("text2").uc_hardtext = text
+end
+
+function ArkMissionCatalog:startResize()
+ local ency = getUI("ui:interface:encyclopedia")
+ ency.w = 950
+ ency.h = 700
+ setOnDraw(ency, "ArkMissionCatalog:autoResize()")
+end
+
+function ArkMissionCatalog:autoResize()
+ if ArkMissionCatalog.bypass_resize then
+ ArkMissionCatalog.bypass_resize = false
+ return
+ end
+
+ local ui = getUI(ArkMissionCatalog.window_id)
+ local htmlA = getUI(ArkMissionCatalog.window_id..":content:htmlA")
+ local htmlB = getUI(ArkMissionCatalog.window_id..":content:htmlB")
+
+ if ArkMissionCatalog.cat == "storyline" then
+ if ui.w < 784 then
+ if ArkMissionCatalog.cat == "storyline" then
+ local td30 = htmlB:find("storyline_content")
+ if td30 ~= nil then
+ td30.x = math.max(0, 200-784+ui.w)
+ ArkMissionCatalog.need_restore_td30 = true
+ end
+ end
+ else
+ if ArkMissionCatalog.need_restore_td30 then
+ local td30 = htmlB:find("storyline_content")
+ if td30 ~= nil then
+ td30.x = 200
+ ArkMissionCatalog.need_restore_td30 = false
+ end
+ end
+ end
+ end
+
+ if ui.w < 950 then
+ htmlA.w = math.max(60, 220-950+ui.w)
+ htmlB.x = math.max(35, 190-950+ui.w)
+ ArkMissionCatalog.need_restore = true
+ else
+ if ArkMissionCatalog.need_restore then
+ htmlA.w = 220
+ htmlB.x = 190
+ ArkMissionCatalog.need_restore = false
+ end
+ end
+end
+
+function ArkMissionCatalog:showLegacyEncyclopedia(state)
+ if state == 1 then
+ getUI("ui:interface:legacy_encyclopedia").active=1
+ else
+ getUI("ui:interface:legacy_encyclopedia").active=0
+ end
+end
+
+
+
+
+
+if S2E1 == nil then
+ S2E1 = {}
+end
+
+runAH(nil, "stop_event_music", "")
+
+S2E1.WindowOpened = false
+S2E1.texts = {}
+S2E1.texts["de"] = {}
+S2E1.texts["en"] = {}
+S2E1.texts["es"] = {}
+S2E1.texts["fr"] = {}
+S2E1.texts["ru"] = {}
+
+
+S2E1.texts["de"][1] = {"Aus der Rinde kommt ein leichtes Knirschen.",
+"Die leisen Knirsch-Geräusche fangen an dich zu nerven.",
+"Die Rinde scheint sich unter deinen Füßen zu winden...",
+"Du hast Schwierigkeiten geradeaus zu gehen; vielleicht war die Shooki nicht sehr frisch.",
+"Ein Rindenbeben muss irgendwo weit weg von hier passiert sein...."}
+S2E1.texts["de"][2] = {"Ein dumpfes Schlaggeräusch kommt von der Rinde.",
+"Plötzliche Beben erschüttern die Rinde und die Vegetation um dich herum.",
+"Sie bringen dich aus dem Gleichgewicht...",
+"Man muss aufpassen, dass man nicht hinfällt.",
+"Das Beben lässt nach, die Rinde kommt wieder zur Ruhe."}
+S2E1.texts["de"][3] = {"Aus der Rinde steigt ein dumpfes Rumoren auf.",
+"Eine erste Erschütterung bringt dich ins Wanken.",
+"Die, die folgen, sind heftig...",
+"Es fällt dir schwer aufzustehen.",
+"Die Erschütterungen werden schwächer, die Rinde kommt wieder zur Ruhe."}
+S2E1.texts["de"][4] = {"Aus der Rinde steigt ein Grollen auf.",
+"Plötzlich gibt die Rinde unter deinen Füßen nach und du fällst zu Boden.",
+"Du stehst auf und versuchst zu fliehen...",
+"aber fällst gleich wieder hin.",
+"Die Erschütterungen werden schwächer..."}
+S2E1.texts["de"][5] = {"Aus der Rinde dringt ein rumpelndes Geräusch empor.",
+"Plötzlich gibt sie unter deinen Füßen nach und du fällst hin.",
+"Du stehst wieder auf."}
+
+
+S2E1.texts["en"][1] = {"A slight squeak raise from the Bark.",
+"The little squeals begin to irk you.",
+"The Bark seems to wriggle under your feet…",
+"You have trouble walking straight; maybe the Shooki wasn't very fresh.",
+"A barkquake must have happened somewhere far from here…"}
+S2E1.texts["en"][2] = {"A thumping sound rises from the Bark.",
+"Jolts suddenly shake the Bark and the vegetation around you.",
+"They throw you off balance…",
+"You have to pay attention not to fall down.",
+"The shaking subsides, the Bark reverts to a stable state."}
+S2E1.texts["en"][3] = {"A thudding murmur raises from the Bark.",
+"A first jolt makes you waver.",
+"Those following are violent…",
+"You're having a hard time standing up.",
+"The jolts become weaker, the Bark becomes stable again."}
+S2E1.texts["en"][4] = {"A rumble comes out of the Bark.",
+"The Bark suddenly gives way under your feet and you fall to the ground.",
+"You get up, trying to get away…",
+"But fall back immediately.",
+"The jolts are beginning to weaken…"}
+S2E1.texts["en"][5] = {"Out of the Bark comes a rumbling sound.",
+"Suddenly it gives way under your feet and you fall to the ground.",
+"You get up again."}
+
+
+S2E1.texts["es"][1] = {"Un ligero chirrido de la corteza.",
+"Los pequeños chillidos comienzan a molestarte.",
+"La corteza parece retorcerse bajo tus pies...",
+"Tienes problemas para caminar recto; tal vez el Shooki no era muy fresco.",
+"Un terremoto debe haber ocurrido en algún lugar lejos de aquí..."}
+S2E1.texts["es"][2] = {"Un sonido de golpeteo se eleva desde la corteza.",
+"Las sacudidas repentinamente sacuden la corteza y la vegetación a su alrededor.",
+"Te desequilibran...",
+"Tienes que prestar atención para no caerte.",
+"El temblor disminuye, la corteza vuelve a un estado estable."}
+S2E1.texts["es"][3] = {"Un estruendoso murmullo se eleva desde la corteza.",
+"La primera sacudida te hace temblar.",
+"Los siguientes son violentos...",
+"Te cuesta mucho trabajo estar de pie.",
+"Las sacudidas se debilitan, la corteza se vuelve estable de nuevo."}
+S2E1.texts["es"][4] = {"Un estruendo sale de la corteza.",
+"La corteza de repente cede bajo tus pies y caes al suelo.",
+"Te levantas, tratando de escapar...",
+"Pero retroceda inmediatamente.",
+"Las sacudidas están empezando a debilitarse..."}
+S2E1.texts["es"][5] = {"De la Corteza sale un sonido estruendoso.",
+"De repente cede bajo tus pies y caes al suelo.",
+"Te levantas de nuevo."}
+
+
+S2E1.texts["fr"][1] = {"Un léger grincement s'échappe de l'Écorce.",
+"Les petits crissements commencent à vous agacer.",
+"L'Écorce semble frétiller sous vos pieds…",
+"Vous avez du mal à marcher droit ; peut-être la Shooki n'était-elle pas très fraîche.",
+"Un tremblement d'écorce a dû se produire quelque part, loin d'ici…"}
+S2E1.texts["fr"][2] = {"Un bruit sourd monte de l'Écorce.",
+"Des secousses agitent soudain l'Écorce et la végétation autour de vous.",
+"Elles vous déséquilibrent…",
+"Vous devez faire attention pour ne pas tomber.",
+"Le tremblement s'apaise, l'Écorce redevient stable."}
+S2E1.texts["fr"][3] = {"Une sourde rumeur monte de l'Écorce.",
+"Une première secousse vous fait vaciller.",
+"Celles qui suivent sont violentes…",
+"Vous avez beaucoup de mal à tenir debout.",
+"Les secousses deviennent plus faibles, l'Écorce redevient stable."}
+S2E1.texts["fr"][4] = {"Un grondement monte de l'Écorce.",
+"L'Écorce se dérobe soudain sous vos pieds et vous tombez sur le sol.",
+"Vous vous relevez, cherchant à vous éloigner…",
+"Mais retombez aussitôt.",
+"Les secousses commencent à s'affaiblir…"}
+S2E1.texts["fr"][5] = {"De l'Écorce s'élève un grondement.",
+"Elle se dérobe soudain sous vos pieds et vous tombez sur le sol.",
+"Vous vous relevez."}
+
+S2E1.texts["ru"][1] = {"Легкий скрип коры.",
+"Эти тихие скрипы начинают тебя раздражать.",
+"Кора, похоже, виляет у тебя под ногами...",
+"Тебе трудно шагать прямо, может быть, Шуки был не очень свежим.",
+"Наверное, где-то произошло трясение коры..."}
+S2E1.texts["ru"][2] = {"Из коры поднимается стук.",
+"Толчки внезапно трясут Кору и растительность вокруг тебя.",
+"Они сбивают тебя с пути...",
+"Тебе нужно сосредоточиться, чтобы не упасть.",
+"Тряска утихает, кора возвращается в стабильное состояние."}
+S2E1.texts["ru"][3] = {"Громкий шум поднимается из коры.",
+"Первый толчок заставляет тебя колебаться.",
+"Следующие жестокие...",
+"Тебе тяжело стоять.",
+"Толчки слабеют, кора снова становится стабильной."}
+S2E1.texts["ru"][4] = {"Грохот исходит из коры.",
+"Кора внезапно поддается под ногами, и ты падаешь на поверхность.",
+"Ты встаешь, пытаешься убежать...",
+"Но немедленно опять падаешь.",
+"Толчки начинают ослабляться..."}
+S2E1.texts["ru"][5] = {"Из коры доносится грохот.",
+"Кора внезапно поддается под ногами, и ты падаешь на поверхность.",
+"Ты снова встаешь."}
+
+function utf8decode(text)
+ local utext = ucstring()
+ utext:fromUtf8(text)
+ return utext
+end
+
+function point_inside_poly(x,y,poly)
+ local inside = false
+ local p1x = poly[1][1]
+ local p1y = poly[1][2]
+
+ for i=0,#poly do
+
+ local p2x = poly[((i)%#poly)+1][1]
+ local p2y = poly[((i)%#poly)+1][2]
+
+ if y > math.min(p1y,p2y) then
+ if y <= math.max(p1y,p2y) then
+ if x <= math.max(p1x,p2x) then
+ if p1y ~= p2y then
+ xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
+ end
+ if p1x == p2x or x <= xinters then
+ inside = not inside
+ end
+ end
+ end
+ end
+ p1x,p1y = p2x,p2y
+ end
+ return inside
+end
+
+function S2E1:loopActions()
+ local action_params = S2E1.AutoActions[S2E1.AutoActionId]
+ if action_params ~= nil then
+ local action = action_params[1]
+ local param = action_params[2]
+ local ttime = action_params[3]
+ S2E1.crazy_time = nltime.getLocalTime()
+ if action == "broadcast" then
+ displaySystemInfo(utf8decode("@{9E9F}"..param), "BC")
+ action = "wait"
+ elseif action == "crunsh" then
+ runAH(nil, "run_action", "forward")
+ runAH(nil, "force_sit", "")
+ action = "wait"
+ elseif action == "open_window" then
+ S2E1:openWindow(param)
+ action = "wait"
+ elseif action ~= "Cam" then
+ runAH(nil, action, param)
+ action = "wait"
+ end
+ S2E1.camPosX = 0
+ S2E1.camPosY = 0
+ getUI("ui:interface:storyline_window").active=1
+ setOnDraw(getUI("ui:interface:storyline_window"), "S2E1:loopAction("..tostring(ttime)..", [["..action.."]], [["..param.."]])")
+ end
+end
+
+function S2E1:loopAction(ttime, action, param)
+ if action == "Cam" then
+ local params = {}
+ for p in string.gmatch(param, "([^:]+)") do
+ table.insert(params, p)
+ end
+ paramX = tonumber(params[1]) / 100
+ paramY = tonumber(params[2]) / 100
+ S2E1.camPosX = S2E1.camPosX + paramX
+ S2E1.camPosY = S2E1.camPosY + paramY
+ moveCam(S2E1.camPosY, 0, S2E1.camPosX)
+ end
+
+ local tick = nltime.getLocalTime()
+ if tick > S2E1.crazy_time + ttime then
+ setOnDraw(getUI("ui:interface:storyline_window"), "")
+ S2E1.AutoActionId = S2E1.AutoActionId + 1
+ S2E1.camPosX = 0
+ S2E1.camPosY = 0
+ if action == "Cam" then
+ moveCam(0, 0, 0)
+ end
+ S2E1:loopActions()
+ end
+end
+
+
+
+function S2E1:AddQuake(force)
+ for n=1,force*10 do
+ posX = force * 4 * (math.random() - 0.5)
+ posY = force * 0.1 * (math.random() - 0.5)
+ timer = 50+(40*math.random())
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"Cam", tostring(posX)..":"..tostring(posY), timer}
+ end
+end
+
+function S2E1:getText(size, id)
+ local lang = getClientCfg("LanguageCode")
+ return S2E1.texts[lang][size][id]
+end
+
+function S2E1:StartQuake(size)
+ local delays = {}
+ delays[1] = {3000, 4000, 300, 1000, 7700}
+ delays[2] = {3000, 4000, 300, 1000, 7700, 4000, 1000}
+ delays[3] = {3000, 4000, 300, 1000, 200, 4000, 5000}
+ delays[4] = {5000, 1000, 500, 3000, 700, 500}
+ delays[5] = {300, 300}
+
+ local first_delay = 3000
+ if size == 5 then
+ first_delay = 1000
+ end
+
+ S2E1.AutoActions = {
+ {"stop_event_music", "", 10},
+ {"broadcast", S2E1:getText(size, 1), 10},
+ {"play_event_music", "music=bg_quake"..tostring(size)..".ogg", first_delay}
+ }
+
+ if size == 1 then
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][1]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 2), delays[size][2]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 3), delays[size][3]}
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][4]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 4), delays[size][5]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 5), 10}
+ end
+
+ if size == 2 then
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][1]}
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 2), delays[size][2]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 3), delays[size][3]}
+ S2E1:AddQuake(2)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][4]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 4), delays[size][5]}
+
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][6]}
+
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][7]}
+
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 5), 10}
+ end
+
+ if size == 3 then
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][1]}
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 2), delays[size][1]}
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][4]}
+ S2E1:AddQuake(2)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 3), delays[size][2]}
+ S2E1:AddQuake(3)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 4), delays[size][3]}
+
+ S2E1:AddQuake(2)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][6]}
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][7]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 5), 10}
+
+ end
+
+ if size == 4 then
+ S2E1:AddQuake(1)
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][1]}
+ S2E1:AddQuake(2)
+ S2E1:AddQuake(3)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", delays[size][2]}
+ S2E1:AddQuake(4)
+ S2E1:AddQuake(3)
+
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 2), delays[size][3]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"crunsh", "", 10}
+
+ S2E1:AddQuake(2)
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 3), delays[size][4]}
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"crunsh", "", 10}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 4), delays[size][5]}
+
+ S2E1:AddQuake(1)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"run_action", "forward", 300}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"stop_action", "forward", 300}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 5), delays[size][6]}
+ end
+
+ if size == 5 then
+ S2E1:AddQuake(2)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 2), delays[size][1]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"crunsh", "", 10}
+ S2E1:AddQuake(2)
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"broadcast", S2E1:getText(size, 3), delays[size][2]}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"run_action", "forward", 300}
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"stop_action", "forward", 300}
+ end
+
+
+ S2E1.AutoActions[#S2E1.AutoActions+1] = {"", "", 5000}
+
+ S2E1.AutoActionId = 1
+ S2E1:loopActions()
+end
+
+
+function S2E1:newQuake(timer)
+ local nbr_p = 0
+ local polygons = {}
+ local zones = {}
+
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{7846,-6097}, {9754,-6093}, {9778,-8349}, {7844,-8321}}
+ zones[nbr_p] = "nexus"
+
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{8128,-10208}, {11368,-10208}, {11392,-12392}, {8096,-12368}}
+ zones[nbr_p] = "silan"
+
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{3716,-4726}, {5228,-5118}, {5468,-5478}, {5596,-5894}, {5604,-6302}, {5524,-6958}, {5220,-7310}, {4692,-7582}, {3588,-7550}, {3060,-6681}, {3076,-5630}}
+ zones[nbr_p] = "surround"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{13764,-29482}, {19540,-29434}, {19156,-30090}, {18836,-30330}, {17732,-30506}, {17060,-30458}, {16484,-31049}, {15820,-31538}, {15650,-31590}, {15496,-31578}, {14436,-30890}}
+ zones[nbr_p] = "surround"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{6684,-14990}, {6431,-14820}, {6292,-14726}, {6221,-14689}, {6236,-14606}, {5972,-14414}, {5580,-12246}, {5692,-11230}, {5860,-11054}, {6164,-10854}, {7404,-11166}, {7380,-14382}}
+ zones[nbr_p] = "surround"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{432,-9729}, {1644,-9693}, {1672,-11433}, {452,-11397}}
+ zones[nbr_p] = "surround"
+
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{308,-350}, {4004,-318}, {5428,-1918}, {6116,-3086}, {6308,-7982}, {3588,-7710}, {308,-2606}}
+ zones[nbr_p] = "far"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{20064,-29262}, {19972,-34986}, {13652,-34954}, {13548,-29330}}
+ zones[nbr_p] = "far"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{5300,-9485}, {7524,-9445}, {7556,-17189}, {5280,-17106}}
+ zones[nbr_p] = "far"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{191,-13148}, {119,-15892}, {3103,-15868}, {3055,-13100}}
+ zones[nbr_p] = "far"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{9990,-1580}, {10046,-2300}, {10246,-2676}, {10510,-2884}, {10990,-3212}, {11646,-3428}, {12486,-3124}, {12522,-712}}
+ zones[nbr_p] = "far"
+ nbr_p = nbr_p + 1
+ polygons[nbr_p] = {{16578,-27080}, {17290,-26192}, {17638,-25860}, {17714,-25613}, {17870,-25436}, {18790,-24648}, {19534,-24168}, {20374,-23800}, {20394,-27100}}
+ zones[nbr_p] = "far"
+
+
+ local x,y=getPlayerPos()
+ local zone = "farfar"
+ for i=1,nbr_p do
+ z = point_inside_poly(x, y, polygons[i])
+ if z == true then
+ zone = zones[i]
+ break
+ end
+ end
+
+ if zone == "farfar" and (timer % 6) == 0 then
+ S2E1:StartQuake(1)
+ elseif zone == "far" and (timer % 4) == 0 then
+ S2E1:StartQuake(2)
+ elseif zone == "surround" and (timer % 2) == 0 then
+ S2E1:StartQuake(3)
+ elseif zone == "nexus" then
+ S2E1:StartQuake(4)
+ end
+
+
+end
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/base64.lua b/ryzom/client/data/gamedev/interfaces_v3/base64.lua
new file mode 100644
index 000000000..203d0aa52
--- /dev/null
+++ b/ryzom/client/data/gamedev/interfaces_v3/base64.lua
@@ -0,0 +1,202 @@
+--[[
+
+ base64 -- v1.5.1 public domain Lua base64 encoder/decoder
+ no warranty implied; use at your own risk
+
+ Needs bit32.extract function. If not present it's implemented using BitOp
+ or Lua 5.3 native bit operators. For Lua 5.1 fallbacks to pure Lua
+ implementation inspired by Rici Lake's post:
+ http://ricilake.blogspot.co.uk/2007/10/iterating-bits-in-lua.html
+
+ author: Ilya Kolbin (iskolbin@gmail.com)
+ url: github.com/iskolbin/lbase64
+
+ COMPATIBILITY
+
+ Lua 5.1, 5.2, 5.3, LuaJIT
+
+ LICENSE
+
+ See end of file for license information.
+
+--]]
+
+
+base64 = {}
+
+local extract = _G.bit32 and _G.bit32.extract
+if not extract then
+ if _G.bit then
+ local shl, shr, band = _G.bit.lshift, _G.bit.rshift, _G.bit.band
+ extract = function( v, from, width )
+ return band( shr( v, from ), shl( 1, width ) - 1 )
+ end
+ elseif _G._VERSION >= "Lua 5.3" then
+ extract = load[[return function( v, from, width )
+ return ( v >> from ) & ((1 << width) - 1)
+ end]]()
+ else
+ extract = function( v, from, width )
+ local w = 0
+ local flag = 2^from
+ for i = 0, width-1 do
+ local flag2 = flag + flag
+ if v % flag2 >= flag then
+ w = w + 2^i
+ end
+ flag = flag2
+ end
+ return w
+ end
+ end
+end
+
+
+function base64.makeencoder( s62, s63, spad )
+ local encoder = {}
+ for b64code, char in pairs{[0]='A','B','C','D','E','F','G','H','I','J',
+ 'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',
+ 'Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
+ 'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2',
+ '3','4','5','6','7','8','9',s62 or '+',s63 or'/',spad or'='} do
+ encoder[b64code] = char:byte()
+ end
+ return encoder
+end
+
+function base64.makedecoder( s62, s63, spad )
+ local decoder = {}
+ for b64code, charcode in pairs( base64.makeencoder( s62, s63, spad )) do
+ decoder[charcode] = b64code
+ end
+ return decoder
+end
+
+local DEFAULT_ENCODER = base64.makeencoder()
+local DEFAULT_DECODER = base64.makedecoder()
+
+local char, concat = string.char, table.concat
+
+function base64.encode( str, encoder, usecaching )
+ encoder = encoder or DEFAULT_ENCODER
+ local t, k, n = {}, 1, #str
+ local lastn = n % 3
+ local cache = {}
+ for i = 1, n-lastn, 3 do
+ local a, b, c = str:byte( i, i+2 )
+ local v = a*0x10000 + b*0x100 + c
+ local s
+ if usecaching then
+ s = cache[v]
+ if not s then
+ s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
+ cache[v] = s
+ end
+ else
+ s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
+ end
+ t[k] = s
+ k = k + 1
+ end
+ if lastn == 2 then
+ local a, b = str:byte( n-1, n )
+ local v = a*0x10000 + b*0x100
+ t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[64])
+ elseif lastn == 1 then
+ local v = str:byte( n )*0x10000
+ t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[64], encoder[64])
+ end
+ return concat( t )
+end
+
+function base64.decode( b64, decoder, usecaching )
+ decoder = decoder or DEFAULT_DECODER
+ local pattern = '[^%w%+%/%=]'
+ if decoder then
+ local s62, s63
+ for charcode, b64code in pairs( decoder ) do
+ if b64code == 62 then s62 = charcode
+ elseif b64code == 63 then s63 = charcode
+ end
+ end
+ pattern = ('[^%%w%%%s%%%s%%=]'):format( char(s62), char(s63) )
+ end
+ b64 = b64:gsub( pattern, '' )
+ local cache = usecaching and {}
+ local t, k = {}, 1
+ local n = #b64
+ local padding = b64:sub(-2) == '==' and 2 or b64:sub(-1) == '=' and 1 or 0
+ for i = 1, padding > 0 and n-4 or n, 4 do
+ local a, b, c, d = b64:byte( i, i+3 )
+ local s
+ if usecaching then
+ local v0 = a*0x1000000 + b*0x10000 + c*0x100 + d
+ s = cache[v0]
+ if not s then
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
+ s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
+ cache[v0] = s
+ end
+ else
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
+ s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
+ end
+ t[k] = s
+ k = k + 1
+ end
+ if padding == 1 then
+ local a, b, c = b64:byte( n-3, n-1 )
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40
+ t[k] = char( extract(v,16,8), extract(v,8,8))
+ elseif padding == 2 then
+ local a, b = b64:byte( n-3, n-2 )
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000
+ t[k] = char( extract(v,16,8))
+ end
+ return concat( t )
+end
+
+return base64
+
+--[[
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2018 Ilya Kolbin
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+--]]
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml b/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml
index 38e6b147b..69cf329f4 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/bot_chat_v4.xml
@@ -432,7 +432,6 @@
-
@@ -450,7 +449,6 @@
-
@@ -518,7 +516,7 @@
-
+
@@ -530,13 +528,13 @@
-
+
-
-
-
-
+
+
@@ -625,8 +623,8 @@
-
@@ -725,7 +723,7 @@
-
+
@@ -757,7 +755,6 @@
-
@@ -765,7 +762,6 @@
-
@@ -831,11 +827,11 @@
-->
-
+
+
+
@@ -100,7 +103,8 @@
-
+
+
@@ -121,4 +125,8 @@
+
+
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/compass.lua b/ryzom/client/data/gamedev/interfaces_v3/compass.lua
new file mode 100644
index 000000000..4f765b45a
--- /dev/null
+++ b/ryzom/client/data/gamedev/interfaces_v3/compass.lua
@@ -0,0 +1,50 @@
+-- In this file we define functions that serves for compass window
+
+if (game==nil) then
+ game= {};
+end
+
+
+function game:areInSilan()
+ polygons = {{8128,-10208}, {11368,-10208}, {11392,-12392}, {8096,-12368}}
+ local x,y = getPlayerPos()
+ for i = 1, 4 do
+ local z = point_inside_poly(x, y, polygons)
+ if z == true then
+ return true
+ end
+ end
+ return false
+end
+
+function game:updateCompass()
+ if game.InGameDbInitialized == false then
+ return
+ end
+
+ local calendar_win = getUI("ui:interface:compass:calendar")
+ local format_date = "%d %m %Y %H:%M"
+ format_date = findReplaceAll(format_date, "%m", i18n.get("uiMonth"..getTimestampHuman("%m")):toUtf8())
+ calendar_win.tooltip = getTimestampHuman(format_date)
+end
+
+
+function game:displayDynE()
+ local win = getUI("ui:interface:app2453")
+ if win ~= nil and win.active == true then
+ win.active = false
+ else
+ AppZone:launchApp(2453)
+ end
+end
+
+function game:displayCalendar()
+ local win = getUI("ui:interface:webig")
+ if win ~= nil and win.active == true then
+ win.active = false
+ else
+ win.active = true
+ end
+end
+
+setOnDraw(getUI("ui:interface:compass"), "game:updateCompass()")
diff --git a/ryzom/client/data/gamedev/interfaces_v3/compass.xml b/ryzom/client/data/gamedev/interfaces_v3/compass.xml
index 71ddb2308..a593bfb5a 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/compass.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/compass.xml
@@ -190,11 +190,11 @@
-
+
-
+
@@ -204,123 +204,124 @@
params="target_property=ui:interface:compass:visuel:radar:world_size|value=switch(@0, 50.0, 100.0, 250.0, 500.0)" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/help.xml b/ryzom/client/data/gamedev/interfaces_v3/help.xml
index d7043da83..0c2ce606e 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/help.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/help.xml
@@ -61,7 +61,7 @@
-
+
@@ -71,9 +71,10 @@
+
@@ -223,7 +224,7 @@
-
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml b/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml
index 737db5c59..f694b2136 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/hierarchy.xml
@@ -111,6 +111,7 @@
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/info_player.lua b/ryzom/client/data/gamedev/interfaces_v3/info_player.lua
index 9ee0416ed..93cf7b159 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/info_player.lua
+++ b/ryzom/client/data/gamedev/interfaces_v3/info_player.lua
@@ -15,6 +15,14 @@ game.PrevSessionMission = - 1
-- flag set to true when the in game db has been initialized
game.InGameDbInitialized = false
+game.WebMissionLastDesc = {}
+
+game.CapTitle = ""
+game.CapDesc = ""
+game.CapChannel = ""
+game.CapInfosUrl = nil
+game.CapNextUrl = ""
+
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
@@ -243,6 +251,7 @@ function game:initNpcWebPageData()
self.NpcWebPage= {};
self.NpcWebPage.UrlTextId= 0;
self.NpcWebPage.BrowseDone= false;
+ self.NpcWebPage.WaitingDynStr = false
end
end
@@ -283,17 +292,14 @@ function game:onDrawNpcWebPage()
local utf8Url = ucUrl
local isRing = string.find(utf8Url, "ring_access_point=1") ~= nil
if isRing then
- -- when in ring mode, add the parameters ourselves. 60 sec timeout because of zope...
- -- browseNpcWebPage(uiStr, utf8Url .. game.RingAccessPointFilter:getURLParameters(), false, 60)
- -- Use new window after revamp
- --RingAccessPoint:getWindow().active = 1
- --RingAccessPoint:getWindow():center()
- --RingAccessPoint:getWindow():blink(1)
- --RingAccessPoint:show()
getUI("ui:interface:npc_web_browser").active = false
runAH(nil, "context_ring_sessions", "")
return
else
+ local hideWindow = string.find(utf8Url, "_hideWindow=1") ~= nil
+ if hideWindow then
+ getUI("ui:interface:npc_web_browser").active = false
+ end
self.NpcWebPage.BrowseDone= true;
browseNpcWebPage(uiStr, utf8Url, true, 10); -- 'true' is for 'add parameters' here. 10 is standard timeout
end
@@ -302,14 +308,15 @@ function game:onDrawNpcWebPage()
-- if this is a ring window, then only the refresh button to access to filter will be available
local isRing = string.find(utf8Url, "ring_access_point=1") ~= nil
local browser = getUI("ui:interface:npc_web_browser")
- browser:find("browse_redo").active = not isRing
- browser:find("browse_undo").active = not isRing
- browser:find("browse_refresh").active = isRing
+ browser:find("browse_redo").active = true
+ browser:find("browse_undo").active = true
+ browser:find("browse_refresh").active = true
end
end
end
------------------------------------------------------------------------------------------------------------
+-- UNUSED???
function game:initNpcWebPage()
local ui= getUICaller();
if(ui~=nil) then
@@ -318,24 +325,81 @@ function game:initNpcWebPage()
end
------------------------------------------------------------------------------------------------------------
+function string:split(Pattern)
+ local Results = {}
+ local Start = 1
+ local SplitStart, SplitEnd = string.find(self, Pattern, Start)
+ while(SplitStart)do
+ table.insert(Results, string.sub(self, Start, SplitStart-1))
+ Start = SplitEnd+1
+ SplitStart, SplitEnd = string.find(self, Pattern, Start)
+ end
+ table.insert(Results, string.sub(self, Start))
+ return Results
+end
+
+function game:getOpenAppPageMessage()
+ local ucUrl = getDynString(self.NpcWebPage.UrlTextId)
+ local url = ucUrl
+ surl = url:split("&")
+ for i=1,#surl do
+ if surl[i]:sub(1, 12) == "open_message" then
+ return base64.decode(surl[i]:sub(14))
+ end
+ end
+ return ""
+end
+
+function game:onDbChangeAppPage()
+ if getDbProp("UI:VARIABLES:CURRENT_SERVER_TICK") > self.NpcWebPage.Timeout then
+ local npcName = getTargetName()
+ local text = game:getOpenAppPageMessage()
+ displaySystemInfo(text, "AMB")
+ removeOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK")
+ end
+end
+
function game:startNpcWebPage()
self:initNpcWebPageData();
-- set the new page to explore.
-- NB: must backup the Database, because don't want that the page change when clicking an other NPC
- self.NpcWebPage.UrlTextId= getDbProp('LOCAL:TARGET:CONTEXT_MENU:WEB_PAGE_URL');
- self.NpcWebPage.BrowseDone= false;
+ if not self.NpcWebPage.WaitingDynStr then
+ self.NpcWebPage.UrlTextId = getDbProp("LOCAL:TARGET:CONTEXT_MENU:WEB_PAGE_URL");
+ end
+ self.NpcWebPage.BrowseDone = false;
- -- reset the page (empty url) and undo / redo
- runAH(nil, "browse", "name=ui:interface:npc_web_browser:content:html|url=release_wk.html|localize=1");
- clearHtmlUndoRedo("ui:interface:npc_web_browser:content:html");
- local ui= getUI("ui:interface:npc_web_browser");
- if(ui~=nil) then
- ui.active= true;
+ available = isDynStringAvailable(self.NpcWebPage.UrlTextId)
+ if available then
+ if self.NpcWebPage.WaitingDynStr then
+ self.NpcWebPage.WaitingDynStr = false
+ removeOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK")
+ end
+ local ucUrl = getDynString(self.NpcWebPage.UrlTextId)
+ local utf8Url = ucUrl
+
+ if utf8Url:sub(1, 4) == "http" then
+ runAH(nil, "browse", "name=ui:interface:npc_web_browser:content:html|url=release_wk.html|localize=1");
+ clearHtmlUndoRedo("ui:interface:npc_web_browser:content:html");
+ local ui= getUI("ui:interface:npc_web_browser");
+ if(ui~=nil) then
+ ui.active= true;
+ end
+ ui:find("browse_redo").active = false
+ ui:find("browse_undo").active = false
+ ui:find("browse_refresh").active = false
+ else
+ setTargetAsInterlocutor()
+ self.NpcWebPage.Timeout = getDbProp("UI:VARIABLES:CURRENT_SERVER_TICK")+7
+ addOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK", "game:onDbChangeAppPage()")
+
+ -- App url, need sign it with server
+ runCommand("a", "openTargetApp", utf8Url)
+ end
+ else
+ self.NpcWebPage.WaitingDynStr = true
+ addOnDbChange(getUI("ui:interface:npc_web_browser"),"@UI:VARIABLES:CURRENT_SERVER_TICK", "game:startNpcWebPage()")
end
- ui:find("browse_redo").active = false
- ui:find("browse_undo").active = false
- ui:find("browse_refresh").active = false
end
------------------------------------------------------------------------------------------------------------
@@ -377,29 +441,6 @@ end
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
-function game:initFamePos()
- local ui = getUICaller();
-
- -- assign good bar with good text
-
- local uiList = { 'fyros', 'matis', 'tryker', 'zorai', 'kami', 'karavan' };
-
- for k,v in pairs(uiList) do
- -- get ui text
- local uiTextRef = getUI(getUIId(ui) .. ':' .. v);
- local fameIdx = getFameDBIndex(getFameIndex(v));
- -- put bar in front of it
- if (fameIdx >= 0) and (fameIdx <= 5) then
- local uiBar = getUI(getUIId(ui) .. ':fb' .. fameIdx);
- uiBar.y = uiTextRef.y - uiTextRef.h / 2 + uiBar.h / 2;
- else
- debugInfo('Error init fame bar pos for ' .. v);
- end
- end
-
-end
-
------------------------------------------------------------------------------------------------------------
function game:initFameTribe()
local ui = getUICaller();
@@ -418,11 +459,29 @@ end
------------------------------------------------------------------------------------------------------------
function game:updateFameBar(path)
+ local ui = getUICaller();
local thresholdKOS = getDbProp('SERVER:FAME:THRESHOLD_KOS');
local thresholdTrade = getDbProp('SERVER:FAME:THRESHOLD_TRADE');
local fameValue = getDbProp(path .. ':VALUE');
local fameMax = getDbProp(path .. ':THRESHOLD');
+ -- known/unknown fame
+ local fameVisible = fameValue ~= -128
+ if fameVisible then
+ -- show unmodified value stored in #path:VALUE
+ ui.t.hardtext = fameValue
+ else
+ ui.t.hardtext = "?"
+ end
+ -- show/hide fame bar components
+ ui.m.active = fameVisible
+ ui.p0.active = fameVisible
+ ui.p1.active = fameVisible
+ ui.p2.active = fameVisible
+ ui.p3.active = fameVisible
+ ui.p4.active = fameVisible
+ ui.bar3d.active = fameVisible
+
if (thresholdKOS < -100) then thresholdKOS = -100; end
if (thresholdKOS > 100) then thresholdKOS = 100; end
if (thresholdTrade < -100) then thresholdTrade = -100; end
@@ -435,7 +494,6 @@ function game:updateFameBar(path)
if (thresholdKOS > thresholdTrade) then thresholdKOS = thresholdTrade; end
if (fameValue > fameMax) then fameValue = fameMax; end
- local ui = getUICaller();
local uiPart0 = ui.p0;
local uiPart1 = ui.p1;
local uiPart2 = ui.p2;
@@ -909,18 +967,18 @@ function RingPlayerInfo:fill(ringPoints)
-- tooltipUI.tooltip = self:tooltipRingRating(level, progress, "uiR2EDMasterlessRingRatingTooltip")
-- ecosystem Points
--- local ecosystems = {"Basic", "Desert", "Subtropic", "Forest", "Jungle", "PrimeRoot"}
--- for k, eco in pairs(ecosystems) do
--- local ecoVal = tostring(ringPoints[eco.."RingPoints"])
--- local ecoValMax = tostring(ringPoints["Max" .. eco.."RingPoints"])
--- local ecoUI = ui:find(string.lower(eco))
--- local maxUI = ecoUI:find("max")
--- local valUI = ecoUI:find("val")
--- tooltipUI = ecoUI:find("tt")
--- maxUI.hardtext = ecoValMax
--- valUI.hardtext = ecoVal
--- tooltipUI.tooltip = self:tooltipEcosystemPoints(ecoVal, ecoValMax, "uiR2ED" .. eco .. "PointsTooltip")
--- end
+ local ecosystems = {"Basic", "Desert", "Subtropic", "Forest", "Jungle", "PrimeRoot"}
+ for k, eco in pairs(ecosystems) do
+ local ecoVal = tostring(ringPoints[eco.."RingPoints"])
+ local ecoValMax = tostring(ringPoints["Max" .. eco.."RingPoints"])
+ local ecoUI = ui:find(string.lower(eco))
+ local maxUI = ecoUI:find("max")
+ local valUI = ecoUI:find("val")
+ tooltipUI = ecoUI:find("tt")
+ maxUI.hardtext = ecoValMax
+ valUI.hardtext = ecoVal
+ tooltipUI.tooltip = self:tooltipEcosystemPoints(ecoVal, ecoValMax, "uiR2ED" .. eco .. "PointsTooltip")
+ end
end
--------------------------------------------------------------------------------------------------------------
@@ -1013,6 +1071,27 @@ function RingPlayerInfo:getLevelRatingAndImprovementRate(val)
return level, progress
end
+--------------------------------------------------------------------------------------------------------------
+--
+function game:updateOrganization(path, uiOrgText, uiStatusText, uiPointsText)
+
+ local org = getDbProp(path.."1:VALUE")
+ getUICaller()[uiOrgText].hardtext = i18n.get('uiOrganization_' .. org)
+
+ local status = getDbProp(path.."2:VALUE")
+ getUICaller()[uiStatusText].hardtext= status
+
+ local points = getDbProp(path.."3:VALUE")
+ getUICaller()[uiPointsText].hardtext= points
+
+end
+
+------------------------------------------------------------------------------------------------------------
+function game:organizationTooltip()
+ -- set the tooltip in InterfaceManager
+ setContextHelpText( i18n.get('uittOrganization') );
+end
+
--------------------------------------------------------------------------------------------------------------
function game:popMissionList()
diff --git a/ryzom/client/data/gamedev/interfaces_v3/info_player.xml b/ryzom/client/data/gamedev/interfaces_v3/info_player.xml
index 4e4ba4a53..7edb0beb2 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/info_player.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/info_player.xml
@@ -31,9 +31,9 @@
-
-
-
+
+
+
-
-
+
+
@@ -58,8 +58,8 @@
-
-
+
+
@@ -67,8 +67,8 @@
-
-
+
+
@@ -80,8 +80,8 @@
-
-
+
+
@@ -93,8 +93,8 @@
-
-
+
+
@@ -108,10 +108,10 @@
text="" >
-
-
-
-
+
+
+
+
@@ -125,7 +125,7 @@
-
+
@@ -141,7 +141,7 @@
-
+
-
+
@@ -571,8 +584,8 @@
@@ -593,9 +606,9 @@
@@ -637,6 +650,7 @@
-
-
-
+
-
+ onclick_l="map_back" params_l="map=ui:interface:map:content:map_content:actual_map" tooltip="uittBack" />
+
-
+ onclick_l="map_zoom_in" params_l="map=ui:interface:map:content:map_content:actual_map" tooltip="uittZoomIn" />
+
-
+ onclick_l="map_zoom_out" params_l="map=ui:interface:map:content:map_content:actual_map" tooltip="uittZoomOut" />
+
+ onclick_l="map_center" params_l="map=ui:interface:map:content:map_content:actual_map" tooltip="uittCenter" />
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
@@ -469,8 +536,8 @@
-
-
diff --git a/ryzom/client/data/gamedev/interfaces_v3/misc.lua b/ryzom/client/data/gamedev/interfaces_v3/misc.lua
new file mode 100644
index 000000000..3e27a7cf9
--- /dev/null
+++ b/ryzom/client/data/gamedev/interfaces_v3/misc.lua
@@ -0,0 +1,128 @@
+-- misc
+--
+if misc == nil then
+ misc = {}
+end
+
+-- convert CRGBA to hexadecimal 6-digits
+function misc:toHexRGBA(rgba)
+ return string.format("%.2x%.2x%.2x%.2x", rgba.R, rgba.G, rgba.B, rgba.A)
+end
+
+-- convert hexadecimal to its short-hand version
+function misc:toHexShort(hex)
+ local s = ''
+ for i = 1, #str, 2 do s = s..string.sub(hex:lower(), i, i) end
+ return s
+end
+
+-- ready to use colored chat string
+function misc:encodeColorTag(hex, str)
+ return "@{"..self:toHexShort(hex).."}"..str
+end
+
+--
+-- inventories observer
+function misc:initInvObserver(
+ inventory,
+ func_add,
+ func_del,
+ func_change,
+ item_filter
+)
+ if self.invObserver == nil then
+ self.invObserver = {
+ maxSlots = 499, obs = {}
+ }
+ function self.invObserver:__remove(n)
+ if #self.obs > 0 then
+ self.obs[n] = nil
+ end
+ end
+ function self.invObserver:__update(n)
+ self.obs[n].cache = nil
+ self:__observ(n)
+ end
+ function self.invObserver:__observ(n)
+ local t = {}
+ local n = n or 1
+ if #self.obs <= 0 then
+ return
+ end
+ for i = 0, self.maxSlots do
+ local sheet = getDbProp(self.obs[n].inv..":"..i..":SHEET")
+ if sheet > 0 then
+ t[sheet] = getDbProp(self.obs[n].inv..":"..i..":QUANTITY")
+ if self.obs[n].filter then
+ local name = getSheetName(sheet)
+ if not name:match(self.obs[n].filter) then
+ t[sheet] = nil
+ end
+ end
+ end
+ end
+ if not self.obs[n].cache then
+ self.obs[n].cache = t
+ t = {}
+ return
+ end
+ local lenT = function(t)
+ local i = 0
+ for _ in pairs(t) do i = i + 1 end return i
+ end
+ local t_len, b_len = lenT(t), lenT(self.obs[n].cache)
+ if t_len ~= b_len then
+ if t_len > b_len then
+ self.obs[n].onAdd(n)
+ else
+ self.obs[n].onDel(n)
+ end
+ self:__update(n)
+ return
+ end
+ for k, v in pairs(self.obs[n].cache) do
+ local found = false
+ for k1, v1 in pairs(t) do
+ if k == k1 then found = true
+ break
+ end
+ end
+ if found then
+ for k1, v1 in pairs(t) do
+ if k == k1 then
+ if v == v1 then break end
+ self.obs[n].onChange(n)
+ self:__update(n)
+ end
+ end
+ else
+ self:__update(n)
+ end
+ end
+ end
+ function self.invObserver:add(uiWindow, n)
+ if uiWindow then
+ setOnDraw(uiWindow, formatUI("misc.invObserver:__observ(#1)", n))
+ end
+ end
+ function self.invObserver:remove(uiWindow, n)
+ if uiWindow then
+ setOnDraw(uiWindow, "")
+ self:__remove(n)
+ end
+ end
+ self.invObserver.__index = self.invObserver
+ end
+ if inventory then
+ self.invObserver.obs[#self.invObserver.obs+1] =
+ {
+ inv = inventory,
+ onAdd = func_add,
+ onDel = func_del,
+ onChange = func_change,
+ filter = item_filter,
+ cache = nil
+ }
+ end
+ return setmetatable(misc, self.invObserver)
+end
\ No newline at end of file
diff --git a/ryzom/client/data/gamedev/interfaces_v3/out_v2_appear.xml b/ryzom/client/data/gamedev/interfaces_v3/out_v2_appear.xml
index d009d9c62..a7bb3429d 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/out_v2_appear.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/out_v2_appear.xml
@@ -353,12 +353,12 @@
+
- -->
diff --git a/ryzom/client/data/gamedev/interfaces_v3/out_v2_config.xml b/ryzom/client/data/gamedev/interfaces_v3/out_v2_config.xml
index 9dd1b9a4e..4f761ff8b 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/out_v2_config.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/out_v2_config.xml
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/out_v2_connect.xml b/ryzom/client/data/gamedev/interfaces_v3/out_v2_connect.xml
index 0651d4872..8acbe7d4e 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/out_v2_connect.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/out_v2_connect.xml
@@ -37,15 +37,15 @@
+ global_color="false" color="255 255 255 255" posref="TL TL" x="0" y="0" texture="new_launcher_bg.tga" />
-
-
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/out_v2_crash.xml b/ryzom/client/data/gamedev/interfaces_v3/out_v2_crash.xml
index b4f3e017c..b69a5286f 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/out_v2_crash.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/out_v2_crash.xml
@@ -10,17 +10,17 @@
+ global_color="false" color="255 255 255 255" posref="TL TL" x="0" y="0" texture="new_launcher_bg.tga" />
-
-
-
-
+
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/out_v2_select.xml b/ryzom/client/data/gamedev/interfaces_v3/out_v2_select.xml
index acef29020..7e49ffe40 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/out_v2_select.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/out_v2_select.xml
@@ -591,12 +591,14 @@
onclick_l="proc" params_l="proc_charsel_play"/>
-->
-
+
-
-
+
+
@@ -696,7 +698,6 @@
onclick_l="leave_modal" />
-
diff --git a/ryzom/client/data/gamedev/interfaces_v3/out_v2_widgets.xml b/ryzom/client/data/gamedev/interfaces_v3/out_v2_widgets.xml
index 4bae3a8cb..99794e094 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/out_v2_widgets.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/out_v2_widgets.xml
@@ -83,7 +83,7 @@
tx_normal="qh_off" tx_pushed="qh_on" tx_over="qh_off" wmin="80" wmargin="40"
global_color_normal="false" global_color_over="false" global_color_pushed="false"
color="255 255 255 255" col_over="255 255 255 0" col_pushed="255 255 255 255"
- text_y="2" fontsize="13" shadow="true"
+ text_y="2" fontsize="14" shadow="true"
text_color_normal="222 201 182 255"
text_color_pushed="222 201 182 255"
text_color_over="255 255 255 255"
diff --git a/ryzom/client/data/gamedev/interfaces_v3/outgame_config.xml b/ryzom/client/data/gamedev/interfaces_v3/outgame_config.xml
index cabc9e02c..53188529d 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/outgame_config.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/outgame_config.xml
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/outpost.xml b/ryzom/client/data/gamedev/interfaces_v3/outpost.xml
index 0e0d0c155..ea6bf35bb 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/outpost.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/outpost.xml
@@ -1085,6 +1085,7 @@
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/phrase.xml b/ryzom/client/data/gamedev/interfaces_v3/phrase.xml
index 355d3abaa..6f6714b3b 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/phrase.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/phrase.xml
@@ -255,7 +255,7 @@
-->
-
+
@@ -266,7 +266,7 @@
y="-4"
xitem="2" yitem="-2"
xtext="32" ytext="-2"
- xcost="230" ycost="-8"
+ xcost="235" ycost="-8"
hspace="4"
array="false"
value="UI:PHRASE:SELECT"
@@ -287,7 +287,7 @@
shadow="true"
multi_line="true"
multi_line_space="0"
- line_maxw="180"
+ line_maxw="210"
>
@@ -501,7 +501,6 @@
-
@@ -509,7 +508,6 @@
-
@@ -523,7 +521,6 @@
-
@@ -533,7 +530,6 @@
-
@@ -596,10 +592,10 @@
-
+
-
@@ -621,9 +617,9 @@
-
-
-
+
+
+
@@ -643,7 +639,7 @@
-
-
-
+
+
@@ -670,6 +666,11 @@
multi_line="true" line_maxw="250" multi_line_space="0" hardtext="uiTextHelpSelectFaberPlanSlot" />
+
+
+
+
+
@@ -686,17 +687,20 @@
-
+
-
+
-
+
+
+
+
-
+
diff --git a/ryzom/client/data/gamedev/interfaces_v3/player.lua b/ryzom/client/data/gamedev/interfaces_v3/player.lua
index a72c35852..96dc81962 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/player.lua
+++ b/ryzom/client/data/gamedev/interfaces_v3/player.lua
@@ -952,12 +952,23 @@ end
-- called by C++ code when the tooltip of a buff item is about to be displayed
function game:updateBuffItemTooltip(buffItem)
local ttWin = getUI("ui:interface:buff_item_context_help")
+ local item = buffItem:getItemInfo()
local text = buffItem:getName()
- self:setPhraseTooltipCarac(ttWin, "hp_buff", buffItem:getHpBuff())
- self:setPhraseTooltipCarac(ttWin, "sta_buff", buffItem:getStaBuff())
- self:setPhraseTooltipCarac(ttWin, "sap_buff", buffItem:getSapBuff())
- self:setPhraseTooltipCarac(ttWin, "focus_buff", buffItem:getFocusBuff())
+ self:setPhraseTooltipCarac(ttWin, "hp_buff", item.HpBuff)
+ self:setPhraseTooltipCarac(ttWin, "sta_buff", item.StaBuff)
+ self:setPhraseTooltipCarac(ttWin, "sap_buff", item.SapBuff)
+ self:setPhraseTooltipCarac(ttWin, "focus_buff", item.FocusBuff)
+ self:setPhraseTooltipCarac(ttWin, "durability", item.Hp)
+ -- / max
+ if item.HpMax == 0 then
+ ttWin:find("durability_sep").active = false
+ ttWin:find("durability_max").active = false
+ else
+ ttWin:find("durability_sep").active = true
+ ttWin:find("durability_max").active = true
+ ttWin:find("durability_max").hardtext = item.HpMax
+ end
updateTooltipCoords()
return text
diff --git a/ryzom/client/data/gamedev/interfaces_v3/player.xml b/ryzom/client/data/gamedev/interfaces_v3/player.xml
index b85b63af1..8a6455e8d 100644
--- a/ryzom/client/data/gamedev/interfaces_v3/player.xml
+++ b/ryzom/client/data/gamedev/interfaces_v3/player.xml
@@ -39,8 +39,8 @@
-
-
+
+
@@ -52,9 +52,9 @@
@@ -164,9 +164,11 @@
+
+
@@ -185,9 +187,9 @@
-
+
-