Add motd & featured tab + fixes
This commit is contained in:
parent
8404feba32
commit
6023e619b9
@ -1,2 +1 @@
|
||||
require("credits")
|
||||
require("mainmenu")
|
||||
|
@ -1,4 +0,0 @@
|
||||
LUI.onmenuopen("main_campaign", function(menu)
|
||||
local headertext = menu:getFirstDescendentById("header_text")
|
||||
headertext:setText("H2-MOD")
|
||||
end)
|
2
data/cdata/ui_scripts/motd/__init__.lua
Normal file
2
data/cdata/ui_scripts/motd/__init__.lua
Normal file
@ -0,0 +1,2 @@
|
||||
require("motd")
|
||||
require("featured")
|
493
data/cdata/ui_scripts/motd/featured.lua
Normal file
493
data/cdata/ui_scripts/motd/featured.lua
Normal file
@ -0,0 +1,493 @@
|
||||
motd.getfeaturedtabtitle = function(index)
|
||||
return motd.getfeaturedtab(index).tab_title or ""
|
||||
end
|
||||
|
||||
local animmsfull = 150
|
||||
local animms = animmsfull / 2
|
||||
|
||||
LUI.onmenuopen("main_campaign", function(menu)
|
||||
if (mods.getloaded() ~= nil or motd.getnumfeaturedtabs() <= 0) then
|
||||
return
|
||||
end
|
||||
|
||||
local left = 866
|
||||
local featuredcontainer = LUI.UIElement.new({
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
left = left,
|
||||
top = 420,
|
||||
})
|
||||
|
||||
featuredcontainer:registerAnimationState("hide", {
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
left = left,
|
||||
top = 570,
|
||||
})
|
||||
|
||||
featuredcontainer:registerAnimationState("show", {
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
left = left,
|
||||
top = 420,
|
||||
})
|
||||
|
||||
local featuredstencil = LUI.UIStencilText.new({
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
height = 200,
|
||||
width = GenericMenuDims.menu_width_standard + (10 + 12) * 2,
|
||||
})
|
||||
|
||||
local featured = LUI.UIElement.new({
|
||||
left = 20,
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
bottomAnchor = true,
|
||||
rightAnchor = true
|
||||
})
|
||||
|
||||
local arrowcontainer = LUI.UIElement.new({
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
bottomAnchor = true,
|
||||
rightAnchor = true
|
||||
})
|
||||
|
||||
arrowcontainer:registerAnimationState("hide", {
|
||||
alpha = 0
|
||||
})
|
||||
|
||||
arrowcontainer:registerAnimationState("show", {
|
||||
alpha = 1
|
||||
})
|
||||
|
||||
featured:addElement(arrowcontainer)
|
||||
|
||||
featuredstencil:registerAnimationState("hide", {
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
height = GenericButtonSettings.Styles.FlatButton.height + 2,
|
||||
width = GenericMenuDims.menu_width_standard + (10 + 12) * 2,
|
||||
})
|
||||
|
||||
local istopmost = function()
|
||||
return LUI.FlowManager.IsMenuTopmost(Engine.GetLuiRoot(), "main_campaign")
|
||||
end
|
||||
|
||||
featuredstencil:registerAnimationState("show", {
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
height = 200,
|
||||
width = GenericMenuDims.menu_width_standard + (10 + 12) * 2,
|
||||
})
|
||||
|
||||
local hoverelem = LUI.UIElement.new({
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
top = -10,
|
||||
height = 150 + GenericButtonSettings.Styles.FlatButton.height + 2 + 10,
|
||||
width = GenericMenuDims.menu_width_standard + 50,
|
||||
left = -25
|
||||
})
|
||||
|
||||
local header = LUI.UIElement.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
width = GenericMenuDims.menu_width_standard,
|
||||
height = GenericButtonSettings.Styles.FlatButton.height,
|
||||
})
|
||||
|
||||
local headerbg = LUI.UIImage.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
bottomAnchor = true,
|
||||
rightAnchor = true,
|
||||
alpha = 0.55,
|
||||
color = Colors.grey_14,
|
||||
material = RegisterMaterial("white")
|
||||
})
|
||||
|
||||
local headerbutton = LUI.UIImage.new({
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
height = 10,
|
||||
width = 10,
|
||||
top = 10.5,
|
||||
left = 10,
|
||||
zRot = -90,
|
||||
color = {
|
||||
r = 0.6,
|
||||
g = 0.6,
|
||||
b = 0.6,
|
||||
},
|
||||
material = RegisterMaterial("widg_lobby_arrow")
|
||||
})
|
||||
|
||||
headerbutton:registerEventHandler("mouseenter", function()
|
||||
if (not istopmost()) then
|
||||
return
|
||||
end
|
||||
|
||||
Engine.PlaySound(CoD.SFX.MouseOver)
|
||||
headerbutton:animateToState("focused")
|
||||
end)
|
||||
|
||||
headerbutton:registerEventHandler("mouseleave", function()
|
||||
headerbutton:animateToState("unfocused")
|
||||
end)
|
||||
|
||||
headerbutton:registerAnimationState("down", {
|
||||
zRot = -90
|
||||
})
|
||||
|
||||
headerbutton:registerAnimationState("right", {
|
||||
zRot = 0
|
||||
})
|
||||
|
||||
headerbutton:registerAnimationState("focused", {
|
||||
color = Colors.h2.yellow
|
||||
})
|
||||
|
||||
headerbutton:registerAnimationState("unfocused", {
|
||||
color = {
|
||||
r = 0.6,
|
||||
g = 0.6,
|
||||
b = 0.6,
|
||||
}
|
||||
})
|
||||
|
||||
local tabcount = motd.getnumfeaturedtabs()
|
||||
|
||||
headerbutton:setHandleMouse(true)
|
||||
local minimized = false
|
||||
headerbutton:registerEventHandler("leftmousedown", function()
|
||||
minimized = not minimized
|
||||
|
||||
if (minimized) then
|
||||
featuredstencil:animateToState("hide", animms)
|
||||
featuredcontainer:animateToState("hide", animms)
|
||||
headerbutton:animateToState("right", animms)
|
||||
arrowcontainer:animateToState("hide", animms)
|
||||
else
|
||||
featuredstencil:animateToState("show", animms)
|
||||
featuredcontainer:animateToState("show", animms)
|
||||
headerbutton:animateToState("down", animms)
|
||||
|
||||
if (tabcount > 1) then
|
||||
arrowcontainer:animateToState("show", animms)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
header:addElement(headerbg)
|
||||
header:addElement(headerbutton)
|
||||
|
||||
local headertext = LUI.UIText.new({
|
||||
leftAnchor = true,
|
||||
left = GenericButtonSettings.Styles.FlatButton.text_padding_with_content + 10,
|
||||
top = -CoD.TextSettings.Font19.Height / 2 + 1.5,
|
||||
font = CoD.TextSettings.Font19.Font,
|
||||
height = CoD.TextSettings.Font19.Height
|
||||
})
|
||||
|
||||
local rightoffset = -15
|
||||
local pips = {}
|
||||
|
||||
for i = 1, tabcount do
|
||||
local pipmat = RegisterMaterial("h1_ui_featured_pip_unfocused")
|
||||
local ratio = Engine.GetMaterialAspectRatio(pipmat)
|
||||
local height = 14
|
||||
|
||||
local pip = LUI.UIImage.new({
|
||||
topAnchor = true,
|
||||
rightAnchor = true,
|
||||
top = GenericButtonSettings.Styles.FlatButton.height / 2 - height / 2,
|
||||
width = ratio * height,
|
||||
height = height,
|
||||
material = RegisterMaterial("h1_ui_featured_pip_unfocused"),
|
||||
right = rightoffset
|
||||
})
|
||||
|
||||
pip:setHandleMouse(true)
|
||||
pip:registerEventHandler("mouseenter", function()
|
||||
if (not istopmost()) then
|
||||
return
|
||||
end
|
||||
|
||||
Engine.PlaySound(CoD.SFX.MouseOver)
|
||||
end)
|
||||
|
||||
pip:registerAnimationState("focused", {
|
||||
material = RegisterMaterial("h2_ui_featured_pip_focused"),
|
||||
})
|
||||
|
||||
pip:registerAnimationState("unfocused", {
|
||||
material = RegisterMaterial("h1_ui_featured_pip_unfocused"),
|
||||
})
|
||||
|
||||
table.insert(pips, pip)
|
||||
header:addElement(pip)
|
||||
rightoffset = rightoffset - height
|
||||
end
|
||||
|
||||
pips[#pips]:animateToState("focused")
|
||||
|
||||
headertext:setText(Engine.ToUpperCase(Engine.Localize("@LUA_MENU_FEATURED")))
|
||||
|
||||
local content = LUI.UIElement.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
top = GenericButtonSettings.Styles.FlatButton.height + 3,
|
||||
width = GenericMenuDims.menu_width_standard,
|
||||
height = 150,
|
||||
})
|
||||
|
||||
local stencil = LUI.UIStencilText.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
bottomAnchor = true,
|
||||
rightAnchor = true,
|
||||
left = 1,
|
||||
})
|
||||
|
||||
local imagelist = LUI.UIHorizontalList.new( {
|
||||
left = 0,
|
||||
leftAnchor = true,
|
||||
width = (GenericMenuDims.menu_width_standard) * tabcount,
|
||||
height = 150,
|
||||
spacing = 0
|
||||
} )
|
||||
|
||||
stencil:addElement(imagelist)
|
||||
|
||||
local contentborder = LUI.UIImage.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
bottomAnchor = true,
|
||||
rightAnchor = true,
|
||||
alpha = 0,
|
||||
material = RegisterMaterial("h2_ui_btn_focused_stroke_square")
|
||||
})
|
||||
|
||||
contentborder:registerAnimationState("unfocused", {
|
||||
alpha = 0
|
||||
})
|
||||
|
||||
contentborder:registerAnimationState("focused", {
|
||||
alpha = 1
|
||||
})
|
||||
|
||||
contentborder:setup9SliceImage()
|
||||
|
||||
for i = 1, tabcount do
|
||||
local panel = LUI.UIElement.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
bottomAnchor = true,
|
||||
width = GenericMenuDims.menu_width_standard,
|
||||
})
|
||||
|
||||
local text = LUI.UIText.new({
|
||||
bottomAnchor = true,
|
||||
leftAnchor = true,
|
||||
rightAnchor = true,
|
||||
alignment = LUI.Alignment.Center,
|
||||
bottom = (-CoD.TextSettings.Font21.Height / 2) + 2,
|
||||
height = CoD.TextSettings.Font21.Height,
|
||||
font = CoD.TextSettings.Font21.Font,
|
||||
})
|
||||
|
||||
local textbg = LUI.UIImage.new({
|
||||
bottomAnchor = true,
|
||||
leftAnchor = true,
|
||||
rightAnchor = true,
|
||||
height = CoD.TextSettings.Font21.Height * 2,
|
||||
alpha = 0.75,
|
||||
material = RegisterMaterial("black")
|
||||
})
|
||||
|
||||
text:setText(motd.getfeaturedtabtitle(i - 1))
|
||||
|
||||
local material = RegisterMaterial("featured_panel_thumbnail_" .. i)
|
||||
local ratio = Engine.GetMaterialAspectRatio(material)
|
||||
local width = GenericMenuDims.menu_width_standard
|
||||
local height = width / ratio
|
||||
|
||||
local contentimage = LUI.UIImage.new({
|
||||
topAnchor = true,
|
||||
leftAnchor = true,
|
||||
width = width,
|
||||
height = height,
|
||||
material = material,
|
||||
})
|
||||
|
||||
panel:addElement(contentimage)
|
||||
panel:addElement(textbg)
|
||||
panel:addElement(text)
|
||||
imagelist:addElement(panel)
|
||||
end
|
||||
|
||||
local focusindex = 0
|
||||
local shiftright = function()
|
||||
local prevfocus = focusindex
|
||||
focusindex = (focusindex + 1) % tabcount
|
||||
|
||||
pips[#pips - (prevfocus)]:animateToState("unfocused")
|
||||
pips[#pips - (focusindex)]:animateToState("focused")
|
||||
|
||||
imagelist:registerAnimationState("move", {
|
||||
leftAnchor = true,
|
||||
left = (focusindex) * -GenericMenuDims.menu_width_standard
|
||||
})
|
||||
|
||||
imagelist:animateToState("move", animmsfull)
|
||||
end
|
||||
|
||||
local shiftleft = function()
|
||||
local prevfocus = focusindex
|
||||
focusindex = (focusindex - 1) % tabcount
|
||||
|
||||
pips[#pips - (prevfocus)]:animateToState("unfocused")
|
||||
pips[#pips - (focusindex)]:animateToState("focused")
|
||||
|
||||
imagelist:registerAnimationState("move", {
|
||||
leftAnchor = true,
|
||||
left = (focusindex) * -GenericMenuDims.menu_width_standard
|
||||
})
|
||||
|
||||
imagelist:animateToState("move", animmsfull)
|
||||
end
|
||||
|
||||
local autoscrolltimer = LUI.UITimer.new(3000, "autoscroll")
|
||||
featured:addElement(autoscrolltimer)
|
||||
featured:registerEventHandler("autoscroll", function()
|
||||
if (not minimized) then
|
||||
shiftright()
|
||||
end
|
||||
end)
|
||||
|
||||
local addarrows = function()
|
||||
local arrowmat = RegisterMaterial("h1_prestige_leftright_arrow")
|
||||
local arrowratio = Engine.GetMaterialAspectRatio(arrowmat)
|
||||
local height = 20
|
||||
local width = arrowratio * height
|
||||
|
||||
local arrowleft = LUI.UIImage.new({
|
||||
leftAnchor = true,
|
||||
left = -width - 10,
|
||||
top = -10,
|
||||
height = height,
|
||||
width = width,
|
||||
alpha = 0,
|
||||
material = RegisterMaterial("h1_prestige_leftright_arrow")
|
||||
})
|
||||
|
||||
local arrowright = LUI.UIImage.new({
|
||||
rightAnchor = true,
|
||||
right = 0,
|
||||
top = -10,
|
||||
height = height,
|
||||
width = width,
|
||||
zRot = 180,
|
||||
alpha = 0,
|
||||
material = RegisterMaterial("h1_prestige_leftright_arrow")
|
||||
})
|
||||
|
||||
arrowleft:registerAnimationState("focused", {
|
||||
alpha = 1
|
||||
})
|
||||
|
||||
arrowleft:registerAnimationState("unfocused", {
|
||||
alpha = 0
|
||||
})
|
||||
|
||||
arrowright:registerAnimationState("focused", {
|
||||
alpha = 1
|
||||
})
|
||||
|
||||
arrowright:registerAnimationState("unfocused", {
|
||||
alpha = 0
|
||||
})
|
||||
|
||||
arrowleft:setHandleMouse(true)
|
||||
arrowright:setHandleMouse(true)
|
||||
|
||||
arrowleft:registerEventHandler("leftmousedown", shiftleft)
|
||||
arrowright:registerEventHandler("leftmousedown", shiftright)
|
||||
|
||||
arrowcontainer:addElement(arrowleft)
|
||||
arrowcontainer:addElement(arrowright)
|
||||
|
||||
featured.arrowleft = arrowleft
|
||||
featured.arrowright = arrowright
|
||||
end
|
||||
|
||||
addarrows()
|
||||
|
||||
if (tabcount <= 1) then
|
||||
arrowcontainer:animateToState("hide")
|
||||
end
|
||||
|
||||
featured:registerEventHandler("focused", function()
|
||||
contentborder:animateToState("focused", animms)
|
||||
featured.arrowleft:animateToState("focused", animms)
|
||||
featured.arrowright:animateToState("focused", animms)
|
||||
LUI.UITimer.Stop(autoscrolltimer)
|
||||
end)
|
||||
|
||||
|
||||
featured:registerEventHandler("unfocused", function()
|
||||
contentborder:animateToState("unfocused", animms)
|
||||
featured.arrowleft:animateToState("unfocused", animms)
|
||||
featured.arrowright:animateToState("unfocused", animms)
|
||||
LUI.UITimer.Reset(autoscrolltimer)
|
||||
end)
|
||||
|
||||
hoverelem:setHandleMouseMove(true)
|
||||
|
||||
hoverelem:registerEventHandler("mouseenter", function()
|
||||
if (not istopmost()) then
|
||||
return
|
||||
end
|
||||
|
||||
featured:processEvent({
|
||||
name = "focused",
|
||||
dispatchChildren = true
|
||||
})
|
||||
end)
|
||||
|
||||
hoverelem:registerEventHandler("mouseleave", function()
|
||||
featured:processEvent({
|
||||
name = "unfocused",
|
||||
dispatchChildren = true
|
||||
})
|
||||
end)
|
||||
|
||||
header:addElement(headertext)
|
||||
header:addElement(LUI.DecoFrame.new(nil, LUI.DecoFrame.Grey))
|
||||
|
||||
featured:addElement(header)
|
||||
|
||||
content:addElement(stencil)
|
||||
content:addElement(LUI.DecoFrame.new(nil, LUI.DecoFrame.Grey))
|
||||
content:addElement(contentborder)
|
||||
|
||||
content:setHandleMouse(true)
|
||||
content:registerEventHandler("leftmousedown", function()
|
||||
local data = motd.getfeaturedtab(focusindex)
|
||||
data.popup_image = "featured_panel_" .. (focusindex + 1)
|
||||
LUI.FlowManager.RequestPopupMenu( nil, "motd_main", true, nil, false, {
|
||||
popupDataQueue = {data}
|
||||
})
|
||||
end)
|
||||
|
||||
featured:addElement(content)
|
||||
featured:addElement(hoverelem)
|
||||
|
||||
featuredstencil:addElement(featured)
|
||||
featuredcontainer:addElement(featuredstencil)
|
||||
|
||||
menu:addElement(featuredcontainer)
|
||||
end)
|
||||
|
76
data/cdata/ui_scripts/motd/motd.lua
Normal file
76
data/cdata/ui_scripts/motd/motd.lua
Normal file
@ -0,0 +1,76 @@
|
||||
require("LUI.common_menus.MarketingComms")
|
||||
require("LUI.common_menus.MarketingPopup")
|
||||
LUI.CustomMarketingPopups = {ShowDepotOnboardingPopupIfPossible = function() end}
|
||||
|
||||
LUI.onmenuopen("main_campaign", function(menu)
|
||||
if (not motd.hasseentoday()) then
|
||||
motd.sethasseentoday()
|
||||
local data = motd.getmotd()
|
||||
LUI.FlowManager.RequestPopupMenu( self, "motd_main", true, nil, false, {
|
||||
popupDataQueue = {data}
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
local function makelink(element, link)
|
||||
element:setHandleMouseMove(true)
|
||||
element:setHandleMouseButton(true)
|
||||
element:registerAnimationState("focused", {
|
||||
color = {
|
||||
r = 1,
|
||||
g = 1,
|
||||
b = 1
|
||||
}
|
||||
})
|
||||
|
||||
local entered = false
|
||||
element:registerEventHandler("mouseenter", function()
|
||||
if (not entered) then
|
||||
Engine.PlaySound(CoD.SFX.MouseOver)
|
||||
entered = true
|
||||
end
|
||||
|
||||
element:animateToState("focused")
|
||||
end)
|
||||
|
||||
element:registerEventHandler("mouseleave", function()
|
||||
entered = false
|
||||
element:animateToState("default")
|
||||
end)
|
||||
|
||||
element:registerEventHandler("leftmousedown", function()
|
||||
Engine.PlaySound(CoD.SFX.MouseClick)
|
||||
game:openlink(link)
|
||||
end)
|
||||
end
|
||||
|
||||
local marketingbase = LUI.MarketingPopup.Base
|
||||
LUI.MarketingPopup.Base = function(a1, data, a3)
|
||||
local element = marketingbase(a1, data, a3)
|
||||
|
||||
local blur = element:getFirstDescendentById("generic_popup_screen_overlay_blur"):getNextSibling()
|
||||
local parent = blur:getFirstChild():getNextSibling():getNextSibling():getNextSibling()
|
||||
local image = parent:getFirstChild()
|
||||
image:close()
|
||||
|
||||
local state = LUI.DeepCopy(image:getAnimationStateInC("default"))
|
||||
local imagecontainer = LUI.UIStencilText.new(state)
|
||||
local material = RegisterMaterial(data.image)
|
||||
|
||||
local ratio = Engine.GetMaterialAspectRatio(material)
|
||||
local width = 525
|
||||
local height = width / ratio
|
||||
|
||||
local image = LUI.UIImage.new({
|
||||
leftAnchor = true,
|
||||
topAnchor = true,
|
||||
width = width,
|
||||
height = height,
|
||||
material = material
|
||||
})
|
||||
|
||||
imagecontainer:addElement(image)
|
||||
parent:addElement(imagecontainer)
|
||||
|
||||
return element
|
||||
end
|
@ -4,12 +4,14 @@ eng_h2_mod_common
|
||||
eng_h2_mod_patch_af_caves
|
||||
ens_h2_mod_common
|
||||
ens_h2_mod_patch_af_caves
|
||||
cze_h2_mod_common
|
||||
fra_h2_mod_common
|
||||
h2_mod_common
|
||||
h2_mod_patch_af_caves
|
||||
h2_mod_patch_dc_whitehouse
|
||||
h2_mod_patch_ending
|
||||
h2_mod_pre_gfx
|
||||
h2_mod_ui
|
||||
ita_h2_mod_common
|
||||
jpf_h2_mod_common
|
||||
jpp_h2_mod_common
|
||||
|
21
data/zone_source/h2_mod_ui.csv
Normal file
21
data/zone_source/h2_mod_ui.csv
Normal file
@ -0,0 +1,21 @@
|
||||
material,h2_ui_featured_pip_focused
|
||||
material,h1_ui_featured_pip_unfocused
|
||||
material,h2_ui_btn_focused_stroke_square
|
||||
material,h1_prestige_leftright_arrow
|
||||
material,featured_panel_1
|
||||
material,featured_panel_2
|
||||
material,featured_panel_3
|
||||
material,featured_panel_4
|
||||
material,featured_panel_5
|
||||
material,featured_panel_6
|
||||
material,featured_panel_7
|
||||
material,featured_panel_8
|
||||
material,featured_panel_thumbnail_1
|
||||
material,featured_panel_thumbnail_2
|
||||
material,featured_panel_thumbnail_3
|
||||
material,featured_panel_thumbnail_4
|
||||
material,featured_panel_thumbnail_5
|
||||
material,featured_panel_thumbnail_6
|
||||
material,featured_panel_thumbnail_7
|
||||
material,featured_panel_thumbnail_8
|
||||
material,motd_image
|
|
BIN
data/zonetool/h2_mod_ui/images/featured_panel_1.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_1.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_2.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_2.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_3.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_3.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_4.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_4.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_5.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_5.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_6.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_6.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_7.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_7.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_8.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_8.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_1.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_1.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_2.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_2.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_3.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_3.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_4.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_4.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_5.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_5.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_6.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_6.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_7.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_7.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_8.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/featured_panel_thumbnail_8.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/h1_btn_focused_rect_stroke.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/h1_btn_focused_rect_stroke.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/h1_prestige_leftright-arrow.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/h1_prestige_leftright-arrow.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/h1_ui_featured_pip_unfocused.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/h1_ui_featured_pip_unfocused.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/h2_btn_focused_rect_stroke.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/h2_btn_focused_rect_stroke.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/h2_ui_featured_pip_focused.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/h2_ui_featured_pip_focused.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/motd_image.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/motd_image.dds
Normal file
Binary file not shown.
26
data/zonetool/h2_mod_ui/materials/featured_panel_1.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_1.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_1",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_1",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_2.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_2.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_2",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_2",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_3.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_3.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_3",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_3",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_4.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_4.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_4",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_4",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_5.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_5.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_5",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_5",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_6.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_6.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_6",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_6",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_7.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_7.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_7",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_7",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/featured_panel_8.json
Normal file
26
data/zonetool/h2_mod_ui/materials/featured_panel_8.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_8",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_8",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_1",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_1",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_2",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_2",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_3",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_3",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_4",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_4",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_5",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_5",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_6",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_6",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_7",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_7",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "featured_panel_thumbnail_8",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "featured_panel_thumbnail_8",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "h1_prestige_leftright_arrow",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "h1_prestige_leftright-arrow",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "h1_ui_featured_pip_unfocused",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "h1_ui_featured_pip_unfocused",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "h2_ui_btn_focused_stroke_square",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "h2_btn_focused_rect_stroke",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "h2_ui_featured_pip_focused",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "h2_ui_featured_pip_focused",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
26
data/zonetool/h2_mod_ui/materials/motd_image.json
Normal file
26
data/zonetool/h2_mod_ui/materials/motd_image.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "motd_image",
|
||||
"techniqueSet->name": "2d",
|
||||
"gameFlags": 0,
|
||||
"sortKey": 60,
|
||||
"renderFlags": 0,
|
||||
"textureAtlasRowCount": 1,
|
||||
"textureAtlasColumnCount": 1,
|
||||
"textureAtlasFrameBlend": 0,
|
||||
"textureAtlasAsArray": 0,
|
||||
"surfaceTypeBits": 0,
|
||||
"cameraRegion": 12,
|
||||
"materialType": 0,
|
||||
"assetFlags": 0,
|
||||
"constantTable": null,
|
||||
"textureTable": [
|
||||
{
|
||||
"image": "motd_image",
|
||||
"semantic": 0,
|
||||
"samplerState": 226,
|
||||
"lastCharacter": 112,
|
||||
"firstCharacter": 99,
|
||||
"typeHash": 2695565377
|
||||
}
|
||||
]
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
"MENU_SP_CAMPAIGN": "H2-MOD",
|
||||
|
||||
"LOCALE_0": "English",
|
||||
"LOCALE_1": "French",
|
||||
"LOCALE_2": "German",
|
||||
|
@ -34,6 +34,7 @@ namespace config
|
||||
{
|
||||
{define_field("disable_custom_fonts", field_type::boolean, false)},
|
||||
{define_field("language", field_type::string, language::get_default_language(), language::is_valid_language)},
|
||||
{define_field("motd_last_seen", field_type::number_unsigned, 0)},
|
||||
};
|
||||
|
||||
std::string get_config_file_path()
|
||||
|
@ -125,6 +125,29 @@ namespace fastfiles
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_add_zone(std::vector<game::XZoneInfo>& zones,
|
||||
utils::memory::allocator& allocator, const std::string& name,
|
||||
bool localized, bool game = false)
|
||||
{
|
||||
if (localized)
|
||||
{
|
||||
const auto language = game::SEH_GetCurrentLanguageCode();
|
||||
try_add_zone(zones, allocator, language + "_"s + name, false);
|
||||
}
|
||||
|
||||
if (!fastfiles::exists(name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
game::XZoneInfo info{};
|
||||
info.name = allocator.duplicate_string(name);
|
||||
info.allocFlags = (game ? game::DB_ZONE_GAME : game::DB_ZONE_COMMON) | game::DB_ZONE_CUSTOM;
|
||||
info.freeFlags = 0;
|
||||
zones.push_back(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void load_mod_zones()
|
||||
{
|
||||
try_load_zone("mod", true);
|
||||
@ -138,28 +161,65 @@ namespace fastfiles
|
||||
}
|
||||
}
|
||||
|
||||
void load_pre_gfx_zones(game::XZoneInfo* zoneInfo,
|
||||
unsigned int zoneCount, game::DBSyncMode syncMode)
|
||||
void add_mod_zones(std::vector<game::XZoneInfo>& zones, utils::memory::allocator& allocator)
|
||||
{
|
||||
try_add_zone(zones, allocator, "mod", true);
|
||||
const auto mod_zones = mods::get_mod_zones();
|
||||
for (const auto& zone : mod_zones)
|
||||
{
|
||||
if (zone.alloc_flags & game::DB_ZONE_COMMON)
|
||||
{
|
||||
try_add_zone(zones, allocator, zone.name, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_zones(std::vector<game::XZoneInfo>& zones,
|
||||
game::XZoneInfo* source, const size_t count)
|
||||
{
|
||||
for (auto i = 0; i < count; ++i)
|
||||
{
|
||||
zones.push_back(source[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void load_pre_gfx_zones(game::XZoneInfo* zone_info,
|
||||
unsigned int zone_count, game::DBSyncMode sync_mode)
|
||||
{
|
||||
// code_pre_gfx
|
||||
|
||||
try_load_zone("h2_mod_pre_gfx", true);
|
||||
utils::memory::allocator allocator;
|
||||
std::vector<game::XZoneInfo> zones;
|
||||
try_add_zone(zones, allocator, "h2_mod_pre_gfx", true);
|
||||
push_zones(zones, zone_info, zone_count);
|
||||
|
||||
game::DB_LoadXAssets(zoneInfo, zoneCount, syncMode);
|
||||
game::DB_LoadXAssets(zones.data(), static_cast<int>(zones.size()), sync_mode);
|
||||
}
|
||||
|
||||
void load_post_gfx_and_ui_and_common_zones(game::XZoneInfo* zoneInfo,
|
||||
unsigned int zoneCount, game::DBSyncMode syncMode)
|
||||
void load_post_gfx_and_ui_and_common_zones(game::XZoneInfo* zone_info,
|
||||
unsigned int zone_count, game::DBSyncMode sync_mode)
|
||||
{
|
||||
// code_post_gfx_mp
|
||||
// ui_mp
|
||||
// common_mp
|
||||
|
||||
try_load_zone("h2_mod_common", true);
|
||||
utils::memory::allocator allocator;
|
||||
std::vector<game::XZoneInfo> zones;
|
||||
|
||||
game::DB_LoadXAssets(zoneInfo, zoneCount, syncMode);
|
||||
try_add_zone(zones, allocator, "h2_mod_common", true);
|
||||
for (auto i = 0u; i < zone_count; i++)
|
||||
{
|
||||
zones.push_back(zone_info[i]);
|
||||
|
||||
load_mod_zones();
|
||||
if (zone_info[i].name == "code_post_gfx"s)
|
||||
{
|
||||
try_add_zone(zones, allocator, "h2_mod_ui", true);
|
||||
}
|
||||
}
|
||||
|
||||
add_mod_zones(zones, allocator);
|
||||
|
||||
game::DB_LoadXAssets(zones.data(), static_cast<int>(zones.size()), sync_mode);
|
||||
}
|
||||
|
||||
constexpr unsigned int get_asset_type_size(const game::XAssetType type)
|
||||
@ -432,7 +492,7 @@ namespace fastfiles
|
||||
add_custom_level_load_zone(load, name, size_est);
|
||||
}
|
||||
|
||||
void add_mod_zones(game::LevelLoad* load)
|
||||
void add_mod_zones_to_load(game::LevelLoad* load)
|
||||
{
|
||||
const auto mod_zones = mods::get_mod_zones();
|
||||
for (const auto& zone : mod_zones)
|
||||
@ -450,7 +510,7 @@ namespace fastfiles
|
||||
|
||||
a.pushad64();
|
||||
a.mov(rcx, rbx);
|
||||
a.call_aligned(add_mod_zones);
|
||||
a.call_aligned(add_mod_zones_to_load);
|
||||
a.popad64();
|
||||
|
||||
a.mov(rcx, rdi);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <utils/image.hpp>
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/concurrency.hpp>
|
||||
#include <utils/http.hpp>
|
||||
|
||||
namespace images
|
||||
{
|
||||
@ -73,7 +74,7 @@ namespace images
|
||||
return true;
|
||||
}
|
||||
|
||||
void load_texture_stub(game::GfxImage* image, void* a2, int* a3)
|
||||
void load_texture_stub(void* a1, game::GfxImage* image)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -87,7 +88,7 @@ namespace images
|
||||
console::error("Failed to load image %s: %s\n", image->name, e.what());
|
||||
}
|
||||
|
||||
load_texture_hook.invoke<void>(image, a2, a3);
|
||||
load_texture_hook.invoke<void>(a1, image);
|
||||
}
|
||||
|
||||
int setup_texture_stub(game::GfxImage* image, void* a2, void* a3)
|
||||
@ -115,7 +116,7 @@ namespace images
|
||||
void post_unpack() override
|
||||
{
|
||||
setup_texture_hook.create(0x1402A7940, setup_texture_stub);
|
||||
load_texture_hook.create(0x1402A6690, load_texture_stub);
|
||||
load_texture_hook.create(0x14074A390, load_texture_stub);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
203
src/client/component/motd.cpp
Normal file
203
src/client/component/motd.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "motd.hpp"
|
||||
#include "console.hpp"
|
||||
#include "images.hpp"
|
||||
#include "command.hpp"
|
||||
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/http.hpp>
|
||||
#include <utils/concurrency.hpp>
|
||||
|
||||
#define MAX_FEATURED_TABS 8
|
||||
|
||||
namespace motd
|
||||
{
|
||||
namespace
|
||||
{
|
||||
utils::concurrency::container<nlohmann::json, std::recursive_mutex> marketing;
|
||||
|
||||
std::unordered_map<std::string, std::string> image_cache;
|
||||
|
||||
std::optional<std::string> download_image(const std::string& url)
|
||||
{
|
||||
if (image_cache.contains(url))
|
||||
{
|
||||
return {image_cache.at(url)};
|
||||
}
|
||||
|
||||
const auto res = utils::http::get_data(url);
|
||||
if (res.has_value())
|
||||
{
|
||||
image_cache[url] = res.value();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void download_motd_image(nlohmann::json& data)
|
||||
{
|
||||
if (!data["motd"].is_object() || !data["motd"]["image_url"].is_string())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto url = data["motd"]["image_url"].get<std::string>();
|
||||
const auto image_data = download_image(url);
|
||||
if (image_data.has_value())
|
||||
{
|
||||
const auto& image = image_data.value();
|
||||
console::debug("Downloaded motd image\n");
|
||||
images::override_texture("motd_image", image);
|
||||
}
|
||||
}
|
||||
|
||||
void download_featured_tabs_images(nlohmann::json& data)
|
||||
{
|
||||
if (!data["featured"].is_array())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto index = 0;
|
||||
for (const auto& [key, tab] : data["featured"].items())
|
||||
{
|
||||
index++;
|
||||
if (index >= MAX_FEATURED_TABS + 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tab.is_object() || !tab["image_url"].is_string())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto download_image_ = [&](const std::string& field, const std::string& image_name)
|
||||
{
|
||||
const auto url = tab[field].get<std::string>();
|
||||
const auto image_data = download_image(url);
|
||||
if (image_data.has_value())
|
||||
{
|
||||
const auto& image = image_data.value();
|
||||
console::debug("Downloaded featured tab image %i\n", index);
|
||||
images::override_texture(image_name + std::format("_{}", index), image);
|
||||
}
|
||||
};
|
||||
|
||||
download_image_("image_url", "featured_panel");
|
||||
download_image_("thumbnail_url", "featured_panel_thumbnail");
|
||||
}
|
||||
}
|
||||
|
||||
void download_images()
|
||||
{
|
||||
marketing.access([&](nlohmann::json& data)
|
||||
{
|
||||
if (!data.is_object())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
download_motd_image(data);
|
||||
download_featured_tabs_images(data);
|
||||
});
|
||||
}
|
||||
|
||||
void init(bool load_images = true)
|
||||
{
|
||||
marketing.access([&](nlohmann::json& data)
|
||||
{
|
||||
image_cache.clear();
|
||||
data.clear();
|
||||
|
||||
const auto marketing_data = utils::http::get_data("https://master.fed0001.xyz/h2-mod/marketing.json");
|
||||
if (marketing_data.has_value())
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto& value = marketing_data.value();
|
||||
data = nlohmann::json::parse(value);
|
||||
if (load_images)
|
||||
{
|
||||
download_images();
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
console::error("Failed to load marketing.json: %s\n", e.what());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int get_num_featured_tabs()
|
||||
{
|
||||
return marketing.access<nlohmann::json>([&](nlohmann::json& data)
|
||||
-> nlohmann::json
|
||||
{
|
||||
if (!data.is_object() || !data["featured"].is_array())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std::min(MAX_FEATURED_TABS, static_cast<int>(data["featured"].size()));
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json get_featured_tab(const int index)
|
||||
{
|
||||
return marketing.access<nlohmann::json>([&](nlohmann::json& data)
|
||||
-> nlohmann::json
|
||||
{
|
||||
if (!data.is_object() || !data["featured"].is_array())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (index >= data["featured"].size())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return data["featured"][index];
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json get_motd()
|
||||
{
|
||||
return marketing.access<nlohmann::json>([](nlohmann::json& data)
|
||||
-> nlohmann::json
|
||||
{
|
||||
if (!data.is_object() || !data["motd"].is_object())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return data["motd"];
|
||||
});
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
init();
|
||||
|
||||
command::add("reloadmotd", []()
|
||||
{
|
||||
init(true);
|
||||
});
|
||||
|
||||
command::add("reloadmotd_noimages", []()
|
||||
{
|
||||
init(false);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(motd::component)
|
8
src/client/component/motd.hpp
Normal file
8
src/client/component/motd.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
namespace motd
|
||||
{
|
||||
int get_num_featured_tabs();
|
||||
nlohmann::json get_motd();
|
||||
nlohmann::json get_featured_tab(const int index);
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
#include "console.hpp"
|
||||
#include "language.hpp"
|
||||
#include "config.hpp"
|
||||
#include "motd.hpp"
|
||||
|
||||
#include "game/ui_scripting/execution.hpp"
|
||||
#include "game/scripting/execution.hpp"
|
||||
@ -151,6 +152,7 @@ namespace ui_scripting
|
||||
{
|
||||
object[key] = json_to_lua(value);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
if (json.is_array())
|
||||
@ -161,6 +163,7 @@ namespace ui_scripting
|
||||
{
|
||||
array[index++] = json_to_lua(value);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
if (json.is_boolean())
|
||||
@ -604,6 +607,41 @@ namespace ui_scripting
|
||||
{
|
||||
config::set(key, lua_to_json(value));
|
||||
};
|
||||
|
||||
auto motd_table = table();
|
||||
lua["motd"] = motd_table;
|
||||
|
||||
motd_table["getnumfeaturedtabs"] = motd::get_num_featured_tabs;
|
||||
motd_table["getmotd"] = []()
|
||||
{
|
||||
return json_to_lua(motd::get_motd());
|
||||
};
|
||||
|
||||
motd_table["getfeaturedtab"] = [](const int index)
|
||||
{
|
||||
return json_to_lua(motd::get_featured_tab(index));
|
||||
};
|
||||
|
||||
motd_table["hasseentoday"] = []()
|
||||
{
|
||||
const auto last_seen = config::get<uint64_t>("motd_last_seen");
|
||||
if (!last_seen.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto value = static_cast<time_t>(last_seen.value());
|
||||
const auto before = std::chrono::floor<std::chrono::days>(std::chrono::system_clock::from_time_t(value));
|
||||
const auto now = std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now());
|
||||
const auto diff = std::chrono::sys_days{now} - std::chrono::sys_days{before};
|
||||
return diff.count() < 1;
|
||||
};
|
||||
|
||||
motd_table["sethasseentoday"] = []()
|
||||
{
|
||||
const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
config::set<uint64_t>("motd_last_seen", static_cast<uint64_t>(now));
|
||||
};
|
||||
}
|
||||
|
||||
void start()
|
||||
|
Loading…
Reference in New Issue
Block a user