951 lines
29 KiB
Plaintext
951 lines
29 KiB
Plaintext
|
--========================================================
|
||
|
--
|
||
|
-- Shader 3D Scopes Editor Script by Private Pirate v1.1.0
|
||
|
--
|
||
|
--========================================================
|
||
|
|
||
|
|
||
|
function on_game_start()
|
||
|
RegisterScriptCallback("on_key_press", on_key_press)
|
||
|
RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
|
||
|
RegisterScriptCallback("on_option_change", on_option_change)
|
||
|
RegisterScriptCallback("save_state", save_state)
|
||
|
RegisterScriptCallback("load_state", load_state)
|
||
|
end
|
||
|
|
||
|
|
||
|
--;-- VARIABLES AND TABLES ---------------------------------------------------------------------------------------
|
||
|
|
||
|
local shader_parameters = {
|
||
|
["s3ds_reticle_size"] = {text = "sse_reticle_size", def = 4, typ = "track", index = 1, min = 0.5, max = 10, step = 0.1},
|
||
|
["s3ds_eye_relief"] = {text = "sse_eye_relief", def = 4, typ = "track", index = 2, min = 1, max = 10, step = 0.01},
|
||
|
["s3ds_exit_pupil"] = {text = "sse_exit_pupil", def = 0.3, typ = "track", index = 3, min = 0.1, max = 5, step = 0.01},
|
||
|
["s3ds_ffp"] = {text = "sse_ffp", def = 0, typ = "check", index = 4},
|
||
|
["s3ds_reflection_hue"] = {text = "sse_refl_hue", def = 0.65, typ = "track", index = 5, min = 0, max = 1, step = 0.01},
|
||
|
["s3ds_min_zoom_1x"] = {text = "sse_min_zoom", def = 0, typ = "check", index = 6},
|
||
|
["s3ds_image_type"] = {text = "sse_image_type", def = 0, typ = "radio", index = 7, content = {{"image_type_1",0}, {"image_type_2",1}, {"image_type_3",2}}},
|
||
|
["s3ds_reticle_type"] = {text = "sse_reticle_type", def = 0, typ = "track", index = 8, min = 0, max = 7, step = 1},
|
||
|
["s3ds_dirt_intensity"] = {text = "sse_lens_dirt", def = 0, typ = "track", index = 9, min = 0, max = 10, step = 0.1},
|
||
|
["s3ds_chroma_power"] = {text = "sse_chroma_power", def = 0, typ = "track", index = 10, min = 0, max = 0.2, step = 0.01},
|
||
|
["s3ds_lens_color"] = {text = "sse_lens_color", def = "1,1,1", typ = "radio", index = 11, content = {{"lens_none","1,1,1"}, {"lens_old_yellow","0.95,0.91,0.83"}, {"lens_russian_blue","0.93,0.96,1"}, {"lens_contrast_yellow","1,0.95,0.3"}}},
|
||
|
["ms_count"] = {text = "sse_reticle_count", def = 1, typ = "radio", index = 12, content = {{"ms_count_1",1}, {"ms_count_2",2}, {"ms_count_3",3}, {"ms_count_4",4}}},
|
||
|
["ms_colors"] = {text = "sse_ret_colors", def = "0,0,0,0", typ = "radio", index = 13, content = {{"no_clr","0,0,0,0"}, {"scope_black","0,0,0,1"}, {"scope_red","1,0.2,0.2,1"}, {"scope_red_dim","0.4,0.05,0.05,1"}}},
|
||
|
}
|
||
|
|
||
|
|
||
|
local data -- sorted shader_parameters table
|
||
|
local ext_val -- S3DS shader param preset of current weapon (only those who are actually in use, NOT IN CORRECT ORDER)
|
||
|
local ext_val_ms -- mark switch shader param preset of current weapon (only those who are actually in use, NOT IN CORRECT ORDER)
|
||
|
local curr_val = {} -- sorted version of ext_val
|
||
|
local cache = {} -- cache weapon specific Shader Parameter values
|
||
|
|
||
|
--general
|
||
|
local debug_mode = DEV_DEBUG or DEV_DEBUG_DEV
|
||
|
local keybind = shader_scopes_editor_mcm.get_config("keybind")
|
||
|
local copy_mode = shader_scopes_editor_mcm.get_config("copy_mode")
|
||
|
local ZOOM_FACTOR = z_3d_scopes_mcm.get_config("zoom_factor")
|
||
|
local NVG_BLUR = z_3d_scopes_mcm.get_config("nvg_blur")
|
||
|
local show_help_wnd = false
|
||
|
|
||
|
-- weapon related variables
|
||
|
local active_item
|
||
|
local is_wpn
|
||
|
local wpn
|
||
|
local section
|
||
|
local last_wpn
|
||
|
|
||
|
-- Utilities
|
||
|
local precision = 2 -- allowed numbers of zeroes
|
||
|
local functor = function(t,a,b) return t[a].index < t[b].index end
|
||
|
local m_floor = math.floor
|
||
|
local str_format = string.format
|
||
|
local lens_clr_index = shader_parameters["s3ds_lens_color"].index -- better than calling in functions
|
||
|
local ms_cnt_index = shader_parameters["ms_count"].index -- better than calling in functions
|
||
|
local ms_clr_index = shader_parameters["ms_colors"].index -- better than calling in functions
|
||
|
|
||
|
function shallow_copy(src) -- retains independence when passing values between arrays, otherwise changing src array changes dst array when src = dst
|
||
|
local dst = {}
|
||
|
for k, v in pairs(src) do
|
||
|
dst[k] = v
|
||
|
end
|
||
|
return dst
|
||
|
end
|
||
|
|
||
|
function conv_to_arr(str)
|
||
|
local arr = {}
|
||
|
for val in string.gmatch(str, "[^,]+") do
|
||
|
arr[#arr + 1] = tonumber(val)
|
||
|
end
|
||
|
return arr
|
||
|
end
|
||
|
|
||
|
|
||
|
--;-- MAIN FUNCTIONS ---------------------------------------------------------------------------------------------
|
||
|
|
||
|
function on_option_change()
|
||
|
keybind = shader_scopes_editor_mcm.get_config("keybind")
|
||
|
copy_mode = shader_scopes_editor_mcm.get_config("copy_mode")
|
||
|
ZOOM_FACTOR = z_3d_scopes_mcm.get_config("zoom_factor")
|
||
|
NVG_BLUR = z_3d_scopes_mcm.get_config("nvg_blur")
|
||
|
end
|
||
|
|
||
|
|
||
|
function save_state(m_data)
|
||
|
m_data.cache = cache
|
||
|
end
|
||
|
|
||
|
|
||
|
function load_state(m_data)
|
||
|
if (m_data.cache) then
|
||
|
cache = m_data.cache
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function on_key_press(key)
|
||
|
if (not debug_mode) then
|
||
|
if (key == keybind) then
|
||
|
actor_menu.set_msg(1, game.translate_string("sse_no_dbg_msg"), 5)
|
||
|
end
|
||
|
return
|
||
|
end
|
||
|
|
||
|
active_item = db.actor:active_item()
|
||
|
is_wpn = IsWeapon(active_item)
|
||
|
wpn = is_wpn and active_item
|
||
|
if (wpn) then
|
||
|
wpn_section = wpn:section()
|
||
|
end
|
||
|
|
||
|
if (key == keybind) then
|
||
|
if (wpn) then
|
||
|
get_params(wpn)
|
||
|
show_ui()
|
||
|
actor_menu.set_msg(1, game.translate_string("sse_help_msg"), 2)
|
||
|
else
|
||
|
actor_menu.set_msg(1, game.translate_string("sse_no_wpn_msg"),5)
|
||
|
end
|
||
|
|
||
|
elseif (key == DIK_keys.DIK_K) then
|
||
|
printf("lens_clr_index = "..lens_clr_index)
|
||
|
printf("ms_cnt_index = "..ms_cnt_index)
|
||
|
printf("ms_clr_index = "..ms_clr_index)
|
||
|
|
||
|
printe("cache[wpn_section]")
|
||
|
for i, v in ipairs(cache[wpn_section]) do
|
||
|
printf(i.." : "..tostring(v))
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
-- sort shader_parameters table by index when read by game and write into new table "data"
|
||
|
function actor_on_first_update()
|
||
|
|
||
|
data = {
|
||
|
param = {},
|
||
|
text = {},
|
||
|
def = {},
|
||
|
typ = {},
|
||
|
index = {},
|
||
|
min = {},
|
||
|
max = {},
|
||
|
step = {},
|
||
|
content = {},
|
||
|
}
|
||
|
|
||
|
for key, v in spairs(shader_parameters, functor) do
|
||
|
data.param[#data.param + 1] = key
|
||
|
data.text[#data.text + 1] = v.text
|
||
|
data.def[#data.def + 1] = v.def
|
||
|
data.typ[#data.typ + 1] = v.typ
|
||
|
data.index[#data.index + 1] = v.index
|
||
|
data.min[#data.min + 1] = v.min or "nil" -- has to be filled otherwise order is not given anymore, nil doesn't work but "nil" does
|
||
|
data.max[#data.max + 1] = v.max or "nil"
|
||
|
data.step[#data.step + 1] = v.step or "nil"
|
||
|
data.content[#data.content + 1] = v.content or "nil"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
-- get Shader Parameter preset values of active weapon, write into new array along with default values, called when UI opens
|
||
|
function get_params(wpn)
|
||
|
ext_val = z_3d_scopes.parse_parameters(wpn) --> NOT IN ORDER
|
||
|
ext_val_ms = z_mark_switch.parse_parameters(wpn) --> NOT IN ORDER
|
||
|
|
||
|
-- replace curr_val[i] with curr_val[key] to get array with preset + default param values
|
||
|
for i, key in ipairs(data.param) do
|
||
|
curr_val[i] = (ext_val[key] or ext_val_ms[key]) or data.def[i] --> COMPLETE AND IN CORRECT ORDER
|
||
|
end
|
||
|
|
||
|
cache_values()
|
||
|
end
|
||
|
|
||
|
|
||
|
-- cache (default) values of currently active weapon
|
||
|
function cache_values()
|
||
|
|
||
|
-- create new key with name of weapon section
|
||
|
if (not cache[wpn_section]) then
|
||
|
cache[wpn_section] = {}
|
||
|
end
|
||
|
|
||
|
-- check whether cache[wpn_section] contains values, if not fill with preset values
|
||
|
for i = 1, #curr_val do
|
||
|
if (not cache[wpn_section][i]) then
|
||
|
cache[wpn_section][i] = curr_val[i]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
update_shader_on_open_ui()
|
||
|
end
|
||
|
|
||
|
-- update Shader Parameters when switching weapons and then reopening UI or when pasting copied values
|
||
|
function update_shader_on_open_ui()
|
||
|
|
||
|
-- Shader Parameter 1
|
||
|
if (cache[wpn_section][1] ~= curr_val[1] or
|
||
|
cache[wpn_section][2] ~= curr_val[2] or
|
||
|
cache[wpn_section][3] ~= curr_val[3] or
|
||
|
cache[wpn_section][4] ~= curr_val[4]) then
|
||
|
get_console():execute("s3ds_param_1 "..cache[wpn_section][1]..", "..cache[wpn_section][2]..", "..cache[wpn_section][3]..", "..cache[wpn_section][4])
|
||
|
end
|
||
|
|
||
|
-- Shader Parameter 2
|
||
|
if (cache[wpn_section][5] ~= curr_val[5] or
|
||
|
cache[wpn_section][6] ~= curr_val[6]) then
|
||
|
get_console():execute("s3ds_param_2 "..cache[wpn_section][5]..", 0, "..cache[wpn_section][6]..", "..(ZOOM_FACTOR or 1.5))
|
||
|
end
|
||
|
|
||
|
-- Shader Parameter 3
|
||
|
if (cache[wpn_section][7] ~= curr_val[7] or
|
||
|
cache[wpn_section][8] ~= curr_val[8] or
|
||
|
cache[wpn_section][9] ~= curr_val[9] or
|
||
|
cache[wpn_section][10] ~= curr_val[10]) then
|
||
|
get_console():execute("s3ds_param_3 "..cache[wpn_section][7]..", "..cache[wpn_section][8]..", "..cache[wpn_section][9]..", "..cache[wpn_section][10])
|
||
|
end
|
||
|
|
||
|
-- Shader Parameter 4
|
||
|
if (cache[wpn_section][11] ~= curr_val[11]) then
|
||
|
get_console():execute("s3ds_param_4 "..cache[wpn_section][11]..", "..(NVG_BLUR and 1 or 0))
|
||
|
end
|
||
|
|
||
|
-- Marks Switch Parameter 1
|
||
|
if (cache[wpn_section][12] ~= curr_val[12]) then
|
||
|
get_console():execute("markswitch_count "..cache[wpn_section][12])
|
||
|
end
|
||
|
|
||
|
-- Mark Switch Parameter 2
|
||
|
if (cache[wpn_section][13] ~= curr_val[13]) then
|
||
|
get_console():execute("markswitch_color "..cache[wpn_section][13])
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--;-- EDITOR MENU UI ---------------------------------------------------------------------------------------------
|
||
|
|
||
|
GUI = nil -- instance, don't touch!
|
||
|
|
||
|
-- open UI Window
|
||
|
function show_ui()
|
||
|
if (not GUI) then
|
||
|
GUI = ShaderScopesEditor()
|
||
|
end
|
||
|
|
||
|
if (GUI and (not GUI:IsShown())) then
|
||
|
GUI:ShowDialog(true)
|
||
|
Register_UI("ShaderScopesEditor", "shader_scopes_editor", GUI)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
class "ShaderScopesEditor" (CUIScriptWnd)
|
||
|
|
||
|
function ShaderScopesEditor:__init() super()
|
||
|
self:InitControls()
|
||
|
self:InitCallBacks()
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:__finalize()
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:InitControls()
|
||
|
self:SetWndRect(Frect():set(0,0,1024,768))
|
||
|
self:SetAutoDelete(true)
|
||
|
|
||
|
self.xml = CScriptXmlInit()
|
||
|
local xml = self.xml
|
||
|
xml:ParseFile("ui_shader_scopes_editor_16.xml")
|
||
|
|
||
|
-- UI Window
|
||
|
self.dialog = xml:InitStatic("SSE", self)
|
||
|
self.background = xml:InitStatic("SSE:background", self.dialog)
|
||
|
self.line_1_1 = xml:InitStatic("SSE:background:line_1_1", self.background)
|
||
|
self.line_1_2 = xml:InitStatic("SSE:background:line_1_2", self.background)
|
||
|
self.title = xml:InitTextWnd("SSE:background:title", self.background)
|
||
|
self.title:SetText(game.translate_string("sse_menu_title"))
|
||
|
self.line_2_1 = xml:InitStatic("SSE:background:line_2_1", self.background)
|
||
|
self.line_2_2 = xml:InitStatic("SSE:background:line_2_2", self.background)
|
||
|
|
||
|
|
||
|
-- Shader Parameter Description
|
||
|
self.desc = xml:InitTextWnd("SSE:desc", self.dialog)
|
||
|
self.desc:SetText(game.translate_string("sse_desc"))
|
||
|
|
||
|
|
||
|
self.main_wnd = xml:InitStatic("SSE:main_wnd", self.dialog)
|
||
|
|
||
|
-- tab selection and buttons
|
||
|
self.tab_select = xml:InitStatic("SSE:tab_select", self.dialog)
|
||
|
|
||
|
self.tab_1_bg = xml:InitStatic("SSE:tab_select:background_1", self.tab_select)
|
||
|
self.tab_1 = xml:Init3tButton("SSE:tab_select:tab_1", self.tab_select)
|
||
|
self.tab_1:TextControl():SetText(game.translate_string("sse_tab_1"))
|
||
|
self:Register(self.tab_1, "tab_1")
|
||
|
|
||
|
self.tab_2_bg = xml:InitStatic("SSE:tab_select:background_2", self.tab_select)
|
||
|
self.tab_2_bg:Show(false)
|
||
|
self.tab_2 = xml:Init3tButton("SSE:tab_select:tab_2", self.tab_select)
|
||
|
self.tab_2:TextControl():SetText(game.translate_string("sse_tab_2"))
|
||
|
self:Register(self.tab_2, "tab_2")
|
||
|
|
||
|
-- bottom line
|
||
|
self.line_3 = xml:InitStatic("SSE:line_3", self.dialog)
|
||
|
|
||
|
|
||
|
-- S3DS param windows (scroll view) ---------------------------------------
|
||
|
self.s3ds_wnd = xml:InitScrollView("SSE:scroll_view", self.dialog)
|
||
|
self.s3ds_wnd:Clear()
|
||
|
|
||
|
-- parameter windows
|
||
|
self.wnd = {}
|
||
|
self.value = {}
|
||
|
|
||
|
for i = 1, lens_clr_index do
|
||
|
local _st = xml:InitStatic("SSE:window", nil)
|
||
|
self.wnd[i] = {}
|
||
|
self.wnd[i].window = _st
|
||
|
|
||
|
-- Shader Parameter name, reference images
|
||
|
self.wnd[i].title = xml:InitTextWnd("SSE:window:title", _st)
|
||
|
self.wnd[i].title:SetText(game.translate_string(data.text[i]))
|
||
|
-- self.wnd[i].tex_1 = xml:InitStatic("SSE:window:texture_1", _st)
|
||
|
-- self.wnd[i].tex_2 = xml:InitStatic("SSE:window:texture_2", _st)
|
||
|
|
||
|
self:Register_Btn_Reset(i, xml, _st)
|
||
|
|
||
|
self.value[i] = cache[wpn_section][i]
|
||
|
|
||
|
-- trackbars
|
||
|
if (data.typ[i] == "track") then
|
||
|
self:Register_Trackbar(i, xml, _st)
|
||
|
|
||
|
-- checkboxes
|
||
|
elseif (data.typ[i] == "check") then
|
||
|
self:Register_Check(i, xml, _st)
|
||
|
|
||
|
-- multiple checkboxes
|
||
|
elseif (data.typ[i] == "radio") then
|
||
|
self:Register_Radio_Check(i, xml, _st)
|
||
|
end
|
||
|
|
||
|
self.wnd[i].devider = xml:InitStatic("SSE:window:devider", _st)
|
||
|
|
||
|
if (data.param[i] == "s3ds_lens_color") then
|
||
|
self:Add_Color_Sliders(i, xml, _st)
|
||
|
end
|
||
|
|
||
|
self.s3ds_wnd:AddWindow(_st, true)
|
||
|
_st:SetAutoDelete(true)
|
||
|
end
|
||
|
|
||
|
-- Mark Switch param window -----------------------------------------------
|
||
|
self.ms_wnd = xml:InitStatic("SSE:ms_wnd", self.dialog)
|
||
|
|
||
|
for i = ms_cnt_index, (#data.param) do
|
||
|
local _st = xml:InitStatic("SSE:window", nil)
|
||
|
self.wnd[i] = {}
|
||
|
self.wnd[i].window = _st
|
||
|
|
||
|
local pos = self.wnd[i].window:GetWndPos()
|
||
|
local offset = self.wnd[1].window:GetHeight()
|
||
|
self.wnd[i].window:SetWndPos(vector2():set(pos.x, pos.y + (i - ms_cnt_index) * offset))
|
||
|
|
||
|
self.wnd[i].title = xml:InitTextWnd("SSE:window:title", _st)
|
||
|
self.wnd[i].title:SetText(game.translate_string(data.text[i]))
|
||
|
|
||
|
self:Register_Btn_Reset(i, xml, _st)
|
||
|
|
||
|
self.value[i] = cache[wpn_section][i]
|
||
|
|
||
|
self:Register_Radio_Check(i, xml, _st)
|
||
|
|
||
|
if (data.param[i] == "ms_colors") then
|
||
|
self:Add_Color_Sliders(i, xml, _st)
|
||
|
end
|
||
|
|
||
|
self.wnd[i].devider = xml:InitStatic("SSE:window:devider", _st)
|
||
|
|
||
|
_st:SetAutoDelete(true)
|
||
|
self.ms_wnd:AttachChild(_st)
|
||
|
end
|
||
|
|
||
|
self.ms_wnd:Show(false)
|
||
|
|
||
|
|
||
|
-- hint window on hover over window title
|
||
|
self.hint_wnd = utils_ui.UIHint(self)
|
||
|
|
||
|
-- help window with instructions and info
|
||
|
self.help_wnd = xml:InitStatic("help_wnd", self)
|
||
|
self.help_wnd:SetAutoDelete(false)
|
||
|
self.help_text = xml:InitTextWnd("help_wnd:text_wnd", self.help_wnd)
|
||
|
self.help_text:SetText(game.translate_string("sse_help_text"))
|
||
|
self.help_text:AdjustHeightToText()
|
||
|
self.help_wnd:Show(false)
|
||
|
|
||
|
-- Buttons
|
||
|
self.copy_cache = {} -- saves copied values
|
||
|
|
||
|
self.btn_reset_all = xml:Init3tButton("SSE:btn_reset_all", self.dialog)
|
||
|
self:Register(self.btn_reset_all, "btn_reset_all")
|
||
|
self.btn_reset_all:TextControl():SetText(game.translate_string("sse_btn_reset_all"))
|
||
|
|
||
|
self.btn_resume = xml:Init3tButton("SSE:btn_resume", self.dialog)
|
||
|
self:Register(self.btn_resume, "btn_resume")
|
||
|
self.btn_resume:TextControl():SetText(game.translate_string("sse_btn_resume"))
|
||
|
|
||
|
self.btn_copy = xml:Init3tButton("SSE:btn_copy", self.dialog)
|
||
|
self:Register(self.btn_copy, "btn_copy")
|
||
|
self.btn_copy:TextControl():SetText(game.translate_string("sse_btn_copy"))
|
||
|
|
||
|
self.btn_paste = xml:Init3tButton("SSE:btn_paste", self.dialog)
|
||
|
self:Register(self.btn_paste, "btn_paste")
|
||
|
self.btn_paste:TextControl():SetText(game.translate_string("sse_btn_paste"))
|
||
|
|
||
|
self.btn_apply = xml:Init3tButton("SSE:btn_apply", self.dialog)
|
||
|
self:Register(self.btn_apply, "btn_apply")
|
||
|
self.btn_apply:TextControl():SetText(game.translate_string("sse_btn_apply"))
|
||
|
end
|
||
|
|
||
|
|
||
|
-----------------------
|
||
|
-- Ctrl Init Functions
|
||
|
-----------------------
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:Register_Btn_Reset(i, xml, handler)
|
||
|
|
||
|
local btn_reset_id = "btn_reset_"..i
|
||
|
self.wnd[i][btn_reset_id] = xml:Init3tButton("SSE:window:btn_reset", handler)
|
||
|
self:Register(self.wnd[i][btn_reset_id], btn_reset_id)
|
||
|
self.wnd[i][btn_reset_id]:TextControl():SetText(game.translate_string("sse_btn_reset"))
|
||
|
|
||
|
local _wrapper = function(handler)
|
||
|
self:OnButton_Reset(i)
|
||
|
end
|
||
|
self:AddCallback(btn_reset_id, ui_events.BUTTON_CLICKED, _wrapper, self)
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:Register_Trackbar(i, xml, handler)
|
||
|
|
||
|
self.wnd[i].trackbar = xml:InitTrackBar("SSE:window:trackbar", handler)
|
||
|
|
||
|
-- assign current Shader Parameter values to trackbars when initiating UI
|
||
|
self.value[i] = clamp(self.value[i], data.min[i], data.max[i])
|
||
|
self.wnd[i].trackbar:SetOptFBounds(data.min[i], data.max[i])
|
||
|
self.wnd[i].trackbar:SetFValue(self.value[i])
|
||
|
self.wnd[i].trackbar:SetStep(data.step[i])
|
||
|
|
||
|
-- number display next to trackbar
|
||
|
self.wnd[i].value = xml:InitTextWnd("SSE:window:track_value", handler)
|
||
|
self.wnd[i].value:SetText(self.value[i])
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:Register_Check(i, xml, handler)
|
||
|
|
||
|
local check_id = "checkbox_"..i
|
||
|
self.wnd[i][check_id] = xml:InitCheck("SSE:window:checkbox", handler)
|
||
|
if (self.value[i] == 1) then
|
||
|
self.wnd[i][check_id]:SetCheck(true)
|
||
|
else
|
||
|
self.wnd[i][check_id]:SetCheck(false)
|
||
|
end
|
||
|
self:Register(self.wnd[i][check_id], check_id)
|
||
|
|
||
|
local _wrapper = function(handler)
|
||
|
self:OnButton_Check(i, check_id)
|
||
|
end
|
||
|
self:AddCallback(check_id, ui_events.BUTTON_CLICKED, _wrapper, self)
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:Register_Radio_Check(i, xml, handler)
|
||
|
|
||
|
local count = #data.content[i] -- count entries
|
||
|
local offset = m_floor(self.wnd[i].window:GetWidth()/count)
|
||
|
for j = 1, count do
|
||
|
|
||
|
-- checkboxes
|
||
|
local radio_check_id = "radio_check_"..i.."_"..j
|
||
|
self.wnd[i][radio_check_id] = xml:InitCheck("SSE:window:radio_check", handler)
|
||
|
|
||
|
local pos = self.wnd[i][radio_check_id]:GetWndPos()
|
||
|
self.wnd[i][radio_check_id]:SetWndPos(vector2():set(pos.x + offset*(j-1 + 0.5) - 17, pos.y))
|
||
|
|
||
|
-- compare values set initial states of radio check buttons
|
||
|
local set_check
|
||
|
if (self.value[i] ~= data.content[i][j][2]) then
|
||
|
set_check = false
|
||
|
else
|
||
|
set_check = true
|
||
|
end
|
||
|
self.wnd[i][radio_check_id]:SetCheck(set_check)
|
||
|
|
||
|
-- text windows
|
||
|
local radio_text_id = "radio_text_"..i.."_"..j
|
||
|
self.wnd[i][radio_text_id] = xml:InitTextWnd("SSE:window:radio_text", handler)
|
||
|
self.wnd[i][radio_text_id]:SetText(game.translate_string("sse_lst_"..data.content[i][j][1]))
|
||
|
|
||
|
pos = self.wnd[i][radio_text_id]:GetWndPos()
|
||
|
self.wnd[i][radio_text_id]:SetWndPos(vector2():set(pos.x + offset*(j-1 + 0.5) - 17, pos.y))
|
||
|
|
||
|
self:Register(self.wnd[i][radio_check_id], radio_check_id)
|
||
|
|
||
|
local _wrapper = function(_st)
|
||
|
self:OnRadio_Check(radio_check_id, i, j)
|
||
|
end
|
||
|
self:AddCallback(radio_check_id, ui_events.BUTTON_CLICKED, _wrapper, self)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:Add_Color_Sliders(i, xml, handler)
|
||
|
|
||
|
local size = {}
|
||
|
size.w = self.wnd[i].window:GetWidth()
|
||
|
size.h = self.wnd[i].window:GetHeight()
|
||
|
self.wnd[i].window:SetWndSize(vector2():set(size.w, 2*size.h))
|
||
|
|
||
|
-- convert color value string to array to assign values
|
||
|
self.value[i] = conv_to_arr(self.value[i])
|
||
|
|
||
|
-- init custom trackbars
|
||
|
self.wnd[i].trackbar = {}
|
||
|
self.wnd[i].color = {}
|
||
|
self.wnd[i].value = {}
|
||
|
local colors = {"R", "G", "B"}
|
||
|
for j = 1, 3 do
|
||
|
self.wnd[i].trackbar[j] = xml:InitTrackBar("SSE:ms_wnd:trackbar", handler)
|
||
|
|
||
|
-- assign current Shader Parameter values to trackbars when initiating UI
|
||
|
self.value[i][j] = clamp(self.value[i][j], 0, 1)
|
||
|
self.wnd[i].trackbar[j]:SetOptFBounds(0, 1)
|
||
|
self.wnd[i].trackbar[j]:SetFValue(self.value[i][j])
|
||
|
self.wnd[i].trackbar[j]:SetStep(0.01)
|
||
|
|
||
|
-- color letter and number display next to trackbar
|
||
|
self.wnd[i].color[j] = xml:InitTextWnd("SSE:window:track_value", handler)
|
||
|
self.wnd[i].color[j]:SetText(colors[j])
|
||
|
self.wnd[i].value[j] = xml:InitTextWnd("SSE:window:track_value", handler)
|
||
|
self.wnd[i].value[j]:SetText(self.value[i][j])
|
||
|
|
||
|
local track_pos = self.wnd[i].trackbar[j]:GetWndPos()
|
||
|
local value_pos = self.wnd[i].value[j]:GetWndPos()
|
||
|
|
||
|
self.wnd[i].color[j]:SetWndPos(vector2():set(value_pos.x - 250, value_pos.y + 25*(j-1) + 40))
|
||
|
self.wnd[i].trackbar[j]:SetWndPos(vector2():set(track_pos.x, track_pos.y + 25*(j-1) + 40))
|
||
|
self.wnd[i].value[j]:SetWndPos(vector2():set(value_pos.x, value_pos.y + 25*(j-1) + 40))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
--------------------
|
||
|
-- Button Callbacks
|
||
|
--------------------
|
||
|
|
||
|
function ShaderScopesEditor:InitCallBacks()
|
||
|
self:AddCallback("tab_1", ui_events.BUTTON_CLICKED, self.OnTab_S3DS, self)
|
||
|
self:AddCallback("tab_2", ui_events.BUTTON_CLICKED, self.OnTab_MS, self)
|
||
|
self:AddCallback("btn_reset_all", ui_events.BUTTON_CLICKED, self.OnButton_Reset_All, self)
|
||
|
self:AddCallback("btn_resume", ui_events.BUTTON_CLICKED, self.OnButton_Resume, self)
|
||
|
self:AddCallback("btn_copy", ui_events.BUTTON_CLICKED, self.OnButton_Copy, self)
|
||
|
self:AddCallback("btn_paste", ui_events.BUTTON_CLICKED, self.OnButton_Paste, self)
|
||
|
self:AddCallback("btn_apply", ui_events.BUTTON_CLICKED, self.Save_Params, self)
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:OnButton_Reset(i)
|
||
|
self.value[i] = curr_val[i]
|
||
|
self:Update_Ctrl(self.value)
|
||
|
self:Update_Shader(i)
|
||
|
self:Send_Msg(game.translate_string("sse_btn_reset_msg"), 2)
|
||
|
end
|
||
|
|
||
|
-- show S3DS window
|
||
|
function ShaderScopesEditor:OnTab_S3DS()
|
||
|
if (not self.s3ds_wnd:IsShown()) then
|
||
|
self.s3ds_wnd:Show(true)
|
||
|
self.tab_1_bg:Show(true)
|
||
|
self.ms_wnd:Show(false)
|
||
|
self.tab_2_bg:Show(false)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
-- show Mark Switch window
|
||
|
function ShaderScopesEditor:OnTab_MS()
|
||
|
if (not self.ms_wnd:IsShown()) then
|
||
|
self.s3ds_wnd:Show(false)
|
||
|
self.tab_1_bg:Show(false)
|
||
|
self.ms_wnd:Show(true)
|
||
|
self.tab_2_bg:Show(true)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:OnButton_Check(i, check_id)
|
||
|
|
||
|
local val = self.wnd[i][check_id]:GetCheck()
|
||
|
if (val) then
|
||
|
val = 1
|
||
|
else
|
||
|
val = 0
|
||
|
end
|
||
|
|
||
|
if (val ~= self.value[i]) then
|
||
|
self.value[i] = val
|
||
|
self:Update_Shader(i)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:OnRadio_Check(radio_check_id, i, j)
|
||
|
|
||
|
-- turn other check buttons off when pressing a button
|
||
|
local val = self.wnd[i][radio_check_id]:GetCheck()
|
||
|
if (val) then
|
||
|
for n = 1, #data.content[i] do
|
||
|
local id = "radio_check_"..i.."_"..n
|
||
|
if (n ~= j) then
|
||
|
self.wnd[i][id]:SetCheck(false)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
self.value[i] = data.content[i][j][2]
|
||
|
self:Update_Shader(i)
|
||
|
else
|
||
|
self.wnd[i][radio_check_id]:SetCheck(true)
|
||
|
end
|
||
|
|
||
|
-- update custom color sliders
|
||
|
if (i == lens_clr_index or i == ms_clr_index) then
|
||
|
data.content[i][j][2] = conv_to_arr(data.content[i][j][2])
|
||
|
|
||
|
for k = 1, 3 do
|
||
|
self.wnd[i].trackbar[k]:SetFValue(data.content[i][j][2][k])
|
||
|
self.wnd[i].value[k]:SetText(data.content[i][j][2][k])
|
||
|
end
|
||
|
|
||
|
data.content[i][j][2] = table.concat(data.content[i][j][2], ",")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
-- discard all changes and apply Shader Parameter preset values to active weapon
|
||
|
function ShaderScopesEditor:OnButton_Reset_All()
|
||
|
|
||
|
cache[wpn_section] = {}
|
||
|
|
||
|
self:Update_Ctrl(curr_val)
|
||
|
|
||
|
-- reinitiate cache values of active weapon
|
||
|
cache[wpn_section] = shallow_copy(curr_val)
|
||
|
|
||
|
z_3d_scopes.update_shader(wpn)
|
||
|
z_mark_switch.update_shader(wpn, z_mark_switch.parse_parameters(wpn))
|
||
|
self:Send_Msg(game.translate_string("sse_btn_reset_all_msg"), 2)
|
||
|
end
|
||
|
|
||
|
|
||
|
-- discard all changes and close UI (reopening UI brings back changed values)
|
||
|
function ShaderScopesEditor:OnButton_Resume()
|
||
|
z_3d_scopes.update_shader(wpn)
|
||
|
z_mark_switch.update_shader(wpn, z_mark_switch.parse_parameters(wpn))
|
||
|
GUI:HideDialog()
|
||
|
GUI:Show(false)
|
||
|
Unregister_UI("ShaderScopesEditor")
|
||
|
self:Send_Msg(game.translate_string("sse_btn_resume_msg"), 5)
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:OnButton_Copy()
|
||
|
self.copy_cache = {} -- empty cache
|
||
|
|
||
|
if (copy_mode == 1) then
|
||
|
for i, v in pairs(cache[wpn_section]) do
|
||
|
if (v ~= curr_val[i]) then
|
||
|
self.copy_cache[i] = v
|
||
|
end
|
||
|
end
|
||
|
self:Send_Msg(game.translate_string("sse_btn_copy_msg_1"), 2)
|
||
|
else
|
||
|
self.copy_cache = cache[wpn_section]
|
||
|
self:Send_Msg(game.translate_string("sse_btn_copy_msg_2"), 2)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:OnButton_Paste()
|
||
|
if (not next(self.copy_cache)) then
|
||
|
self:Send_Msg(game.translate_string("sse_btn_paste_msg_1"), 2)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- shallow_copy() is necessary, otherwise changing values in copied section changes values in pasted section
|
||
|
if (copy_mode == 1) then
|
||
|
for i, v in pairs(shallow_copy(self.copy_cache)) do
|
||
|
cache[wpn_section][i] = v
|
||
|
end
|
||
|
else
|
||
|
cache[wpn_section] = shallow_copy(self.copy_cache)
|
||
|
end
|
||
|
|
||
|
self:Update_Ctrl(cache[wpn_section])
|
||
|
update_shader_on_open_ui()
|
||
|
self:Send_Msg(game.translate_string("sse_btn_paste_msg_2"), 2)
|
||
|
end
|
||
|
|
||
|
|
||
|
-- Show hint message on button press
|
||
|
function ShaderScopesEditor:Send_Msg(str, dur)
|
||
|
printf("3D Shader Scopes Editor: "..str)
|
||
|
actor_menu.set_msg(1, str, dur)
|
||
|
end
|
||
|
|
||
|
|
||
|
---------------------------------
|
||
|
-- Update UI and 3D Scope Shader
|
||
|
---------------------------------
|
||
|
|
||
|
function ShaderScopesEditor:Update_Ctrl(arr)
|
||
|
for i, val in ipairs(arr) do
|
||
|
if (data.typ[i] == "track") then
|
||
|
self.value[i] = clamp(val, data.min[i], data.max[i])
|
||
|
self.wnd[i].trackbar:SetFValue(val)
|
||
|
self.wnd[i].value:SetText(val)
|
||
|
|
||
|
elseif (data.typ[i] == "check") then
|
||
|
local check_id = "checkbox".."_"..i
|
||
|
self.value[i] = val
|
||
|
|
||
|
if (val == 1) then
|
||
|
self.wnd[i][check_id]:SetCheck(true)
|
||
|
else
|
||
|
self.wnd[i][check_id]:SetCheck(false)
|
||
|
end
|
||
|
|
||
|
elseif (data.typ[i] == "radio") then
|
||
|
self.value[i] = val
|
||
|
for n = 1, #data.content[i] do
|
||
|
local id = "radio_check_"..i.."_"..n
|
||
|
if (data.content[i][n][2] == self.value[i]) then
|
||
|
self.wnd[i][id]:SetCheck(true)
|
||
|
else
|
||
|
self.wnd[i][id]:SetCheck(false)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- custom color sliders
|
||
|
if (i == lens_clr_index or i == ms_clr_index) then
|
||
|
for j = 1, 3 do
|
||
|
if (type(self.value[i]) == "string") then
|
||
|
self.value[i] = conv_to_arr(self.value[i])
|
||
|
end
|
||
|
if (type(val) == "string") then
|
||
|
val = conv_to_arr(val)
|
||
|
end
|
||
|
|
||
|
self.value[i][j] = clamp(val[j], 0, 1)
|
||
|
self.wnd[i].trackbar[j]:SetFValue(val[j])
|
||
|
self.wnd[i].value[j]:SetText(val[j])
|
||
|
end
|
||
|
val = table.concat(val, ",")
|
||
|
self.value[i] = table.concat(self.value[i], ",")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function ShaderScopesEditor:Update()
|
||
|
CUIScriptWnd.Update(self)
|
||
|
|
||
|
-- check active weapon to update values in UI on weapon switch
|
||
|
if (not last_wpn or last_wpn ~= wpn_section) then
|
||
|
last_wpn = wpn_section
|
||
|
|
||
|
self:Update_Ctrl(cache[wpn_section])
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- show hint on hover (from ui_options.script)
|
||
|
for i,ctrl in ipairs(self.wnd) do
|
||
|
if ctrl.title:IsCursorOverWindow() then
|
||
|
local str = data.text[i].."_desc"
|
||
|
local str_t = game.translate_string(str)
|
||
|
if (str ~= str_t) then
|
||
|
self.hint_wnd:Update(str_t)
|
||
|
end
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
self.hint_wnd:Update()
|
||
|
|
||
|
-- hack to simulate tracing method for trackbar value changes (from ui_ctrl_lighting.script)
|
||
|
for i,ctrl in ipairs(self.wnd) do
|
||
|
if (data.typ[i] == "track") then
|
||
|
if ctrl.trackbar:IsCursorOverWindow() then
|
||
|
local val = round_idp(ctrl.trackbar:GetFValue(), precision) -- round value from UI controls
|
||
|
if (val ~= self.value[i]) then
|
||
|
self.value[i] = val
|
||
|
self.wnd[i].value:SetText(val)
|
||
|
self:Update_Shader(i)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- custom color sliders
|
||
|
for i = lens_clr_index, ms_clr_index do
|
||
|
if (i ~= ms_cnt_index) then
|
||
|
for j = 1, 3 do
|
||
|
if (self.wnd[i].trackbar[j]:IsCursorOverWindow()) then
|
||
|
local val = round_idp(self.wnd[i].trackbar[j]:GetFValue(), precision) -- round value from UI controls
|
||
|
|
||
|
if (type(self.value[i]) == "string") then
|
||
|
self.value[i] = conv_to_arr(self.value[i])
|
||
|
end
|
||
|
|
||
|
if (val ~= self.value[i][j]) then
|
||
|
self.value[i][j] = val
|
||
|
self.wnd[i].value[j]:SetText(val)
|
||
|
self.value[i] = table.concat(self.value[i], ",")
|
||
|
self:Update_Shader(i)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- toggle help window
|
||
|
if (self.show_help_wnd) then
|
||
|
self.help_wnd:Show(true)
|
||
|
else
|
||
|
self.help_wnd:Show(false)
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
|
||
|
-- apply Shader Parameter values and update cache
|
||
|
function ShaderScopesEditor:Update_Shader(i)
|
||
|
|
||
|
if (self.value[i] ~= cache[wpn_section][i]) then
|
||
|
-- Shader Parameter 1
|
||
|
if (i <= 4) then
|
||
|
get_console():execute("s3ds_param_1 "..self.value[1]..", "..self.value[2]..", "..self.value[3]..", "..self.value[4])
|
||
|
|
||
|
-- Shader Parameter 2
|
||
|
elseif (i == 5 or i == 6) then
|
||
|
get_console():execute("s3ds_param_2 "..self.value[5]..", 0, "..self.value[6]..", "..(ZOOM_FACTOR or 1.5))
|
||
|
|
||
|
-- Shader Parameter 3
|
||
|
elseif (i >= 7 and i <= 10) then
|
||
|
get_console():execute("s3ds_param_3 "..self.value[7]..", "..self.value[8]..", "..self.value[9]..", "..self.value[10])
|
||
|
|
||
|
-- Shader Parameter 4
|
||
|
elseif (i == 11) then
|
||
|
get_console():execute("s3ds_param_4 "..self.value[11]..", "..(NVG_BLUR and 1 or 0))
|
||
|
|
||
|
-- Marks Switch Parameter 1
|
||
|
elseif (i == 12) then
|
||
|
get_console():execute("markswitch_count "..self.value[12])
|
||
|
|
||
|
-- Mark Switch Parameter 2
|
||
|
elseif (i == 13) then
|
||
|
get_console():execute("markswitch_color "..self.value[13])
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- update cache
|
||
|
cache[wpn_section][i] = self.value[i]
|
||
|
end
|
||
|
|
||
|
|
||
|
-- close UI
|
||
|
function ShaderScopesEditor:OnKeyboard(dik, keyboard_action)
|
||
|
|
||
|
-- close UI Window
|
||
|
if (keyboard_action == ui_events.WINDOW_KEY_PRESSED) then
|
||
|
if (dik == DIK_keys.DIK_ESCAPE) then
|
||
|
GUI:HideDialog()
|
||
|
GUI:Show(false)
|
||
|
Unregister_UI("ShaderScopesEditor")
|
||
|
actor_menu.set_msg(1, game.translate_string("sse_escape_msg"),5)
|
||
|
|
||
|
elseif (dik == DIK_keys.DIK_H) then
|
||
|
show_help_wnd = not show_help_wnd
|
||
|
self.show_help_wnd = show_help_wnd
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
-- save changed Shader Parameter values to cache_dbg.ltx
|
||
|
function ShaderScopesEditor:Save_Params()
|
||
|
|
||
|
local ini_cc = ui_debug_launcher.ini_cc
|
||
|
self.save_cache = {}
|
||
|
self.save_cache[wpn_section] = {}
|
||
|
|
||
|
for i = 1, #data.param do
|
||
|
if (cache[wpn_section][i] ~= curr_val[i]) then
|
||
|
self.save_cache[wpn_section][i] = {}
|
||
|
self.save_cache[wpn_section][i][1] = data.param[i]
|
||
|
|
||
|
if (type(cache[wpn_section][i]) == "string") then
|
||
|
for j, cont in ipairs(data.content[i]) do
|
||
|
if (cache[wpn_section][i] == tostring(cont[2])) then
|
||
|
self.save_cache[wpn_section][i][2] = data.content[i][j][1]
|
||
|
break
|
||
|
else
|
||
|
self.save_cache[wpn_section][i][2] = tostring(cache[wpn_section][i].."(custom_color, set_custom_name)")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
self.save_cache[wpn_section][i][2] = cache[wpn_section][i]
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if (not next(self.save_cache[wpn_section])) then
|
||
|
self:Send_Msg(str_format(game.translate_string("sse_btn_apply_msg_1"), wpn_section), 2)
|
||
|
else
|
||
|
local par, val -- parameter name, parameter value
|
||
|
for sec,v in pairs(self.save_cache) do
|
||
|
for i,w in pairs(v) do
|
||
|
if (w) then
|
||
|
par = w[1]
|
||
|
val = w[2]
|
||
|
ini_cc:w_value(sec, par, val)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
ini_cc:save()
|
||
|
self:Send_Msg(str_format(game.translate_string("sse_btn_apply_msg_2"), wpn_section), 2)
|
||
|
end
|
||
|
end
|