2733 lines
126 KiB
Plaintext
2733 lines
126 KiB
Plaintext
|
|
--[[
|
|
|
|
Tronex
|
|
2019/10/12
|
|
Anomlous Options Menu
|
|
|
|
Features:
|
|
- %100 customizable, support for all kind of xml elements
|
|
- Highlight pending changes
|
|
- Option description support
|
|
- Option presets support
|
|
- Reset button to clear pending changes
|
|
- Script callback on option changes
|
|
- Functors capability to excute on apply or init
|
|
- Precoditions capability to hide/show/execute functors
|
|
|
|
To get an option value inside other scripts, use: ui_options.get(parameter)
|
|
Check the options table here to see the values used
|
|
|
|
See the tutorial at the bottom for adding or modifying options table
|
|
|
|
--]]
|
|
|
|
local enable_debug = false
|
|
------------------------------------------------------------
|
|
-- Strings and LTX management
|
|
------------------------------------------------------------
|
|
local ini_pres = ini_file("presets\\includes.ltx")
|
|
local ini_loc = ini_file_ex("localization.ltx",true)
|
|
local _opt_ = "/" -- For axr_options.ltx, don't touch!
|
|
local opt_section = "options" -- For axr_options.ltx, don't touch!
|
|
local opt_str = "ui_mm_" -- Option name: "ui_mm_(option ID)" -- Option description: "ui_mm_(option ID)_desc"
|
|
local opt_str_menu = "ui_mm_menu_" -- Option menu: "ui_mm_menu_(option menu ID)"
|
|
local opt_str_prst = "ui_mm_prst_" -- Option preset: "ui_mm_prst_(option preset ID)"
|
|
local opt_str_lst = "ui_mm_lst_" -- List/Radio keys: "ui_mm_lst_(key)"
|
|
function cc(path,opt) return (path .. _opt_ .. opt) end
|
|
|
|
------------------------------------------------------------
|
|
-- Utilities
|
|
------------------------------------------------------------
|
|
|
|
local m_floor, m_ceil, s_find, s_gsub = math.floor, math.ceil, string.find, string.gsub
|
|
local clr, clamp, round_idp, str_explode = utils_xml.get_color, clamp, round_idp, str_explode
|
|
local precision = 6 -- allowed number of zeros
|
|
local width_factor = utils_xml.is_widescreen() and 0.8 or 1
|
|
local clr_o = GetARGB(255, 250, 150, 75)
|
|
local clr_g1 = GetARGB(255, 170, 170, 170)
|
|
local clr_g2 = GetARGB(255, 200, 200, 200)
|
|
local clr_w = GetARGB(255, 255, 255, 255)
|
|
local clr_tree = {
|
|
[1] = GetARGB(255, 180, 180, 180),
|
|
[2] = GetARGB(255, 180, 180, 180),
|
|
[3] = GetARGB(255, 180, 180, 180),
|
|
}
|
|
|
|
function print_dbg(...)
|
|
if enable_debug then
|
|
printf(...)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Options
|
|
------------------------------------------------------------
|
|
options = {}
|
|
local opt_temp = {} -- stores pending changes
|
|
local opt_backup = {} -- do a backup of original changes for comparison with pendings
|
|
local opt_index = {} -- option index by path, so we can locate an option fast without iterating throw the whole options table
|
|
local opt_val = {} -- option value type by path, to execute proper functions on different type without iterating throw the whole options table
|
|
local allowed_type = { -- ignore tables from these types in temp tables
|
|
["check"] = true,
|
|
["list"] = true,
|
|
["input"] = true,
|
|
["radio_h"] = true,
|
|
["radio_v"] = true,
|
|
["track"] = true,
|
|
}
|
|
function init_opt_base()
|
|
|
|
options = {
|
|
|
|
{ id= "video" ,gr={
|
|
{ id= "basic" ,sh=true ,gr={
|
|
{ id= "slide_vid" ,type= "slide" ,link= "ui_options_slider_video" ,text= "ui_mm_title_video_basic" ,size= {512,50} },
|
|
|
|
{ id= "renderer" ,type= "list" ,val= 0 ,cmd= "renderer" ,curr= {curr_renderer} ,content= {cont_renderer} ,restart= true ,vid= true },
|
|
-- { id= "preset" ,type= "list" ,val= 0 ,cmd= "_preset" ,content= {{"Minimum","pres_minimum"} , {"Low","pres_low"} , {"Default","pres_default"} , {"High","pres_high"} , {"Extreme","pres_extreme"}} ,restart= true},
|
|
{ id= "resolution" ,type= "list" ,val= 0 ,cmd= "vid_mode" ,content= {cont_vid_mode} ,no_str= true ,restart= true ,vid= true },
|
|
{ id= "gamma" ,type= "track" ,val= 2 ,cmd= "rs_c_gamma" ,min= 0.5 ,max= 1.5 ,step= 0.1 ,precondition= {for_renderer,"renderer_r1"} },
|
|
{ id= "contrast" ,type= "track" ,val= 2 ,cmd= "rs_c_contrast" ,min= 0.5 ,max= 1.5 ,step= 0.1 ,precondition= {for_renderer,"renderer_r1"} },
|
|
{ id= "brightness" ,type= "track" ,val= 2 ,cmd= "rs_c_brightness" ,min= 0.5 ,max= 1.5 ,step= 0.1 ,precondition= {for_renderer,"renderer_r1"} },
|
|
{ id= "fov" ,type= "track" ,val= 2 ,cmd= "fov" ,min= 5 ,max= 180 ,step= 1 },
|
|
{ id= "hud_fov" ,type= "track" ,val= 2 ,cmd= "hud_fov" ,min= 0.1 ,max= 1 ,step= 0.01 },
|
|
{ id= "screen_mode" ,type= "radio_h" ,val= 2 ,curr= {curr_screen_mode} ,content= {{1,"fullscreen"} , {2,"borderless"} , {3,"windowed"}} ,functor = {func_screen_mode} },
|
|
{ id= "lighting" ,type= "button" ,functor_ui= {start_lighting_ui} ,precondition= {level_present} ,precondition_1= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
},},
|
|
{ id= "advanced" ,presets= {"video_extreme","video_high","video_default","video_low","video_minimum"} ,sh=true ,gr={
|
|
{ id= "slide_vid_adv" ,type= "slide" ,link= "ui_options_slider_video_advanced" ,text= "ui_mm_title_video_advanced" ,size= {512,50} },
|
|
|
|
{ id= "ai_torch" ,type= "check" ,val= 1 ,cmd= "ai_use_torch_dynamic_lights" },
|
|
{ id= "v_sync" ,type= "check" ,val= 1 ,cmd= "rs_v_sync" },
|
|
{ id= "framelimit" ,type= "track" ,val= 2 ,cmd= "r__framelimit" ,min= 0 ,max= 500 ,step= 2 },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "title" ,type= "title" ,text= "ui_mm_header_rendering_dist" ,align= "l" ,clr= {255,200,200,200} },
|
|
{ id= "vis_distance" ,type= "track" ,val= 2 ,cmd= "rs_vis_distance" ,min= 0.4 ,max= 1.5 ,step= 0.1 ,no_str= true },
|
|
{ id= "optimize_static_geom" ,type= "track" ,val= 2 ,cmd= "r__optimize_static_geom" ,min= 0 ,max= 4 ,step= 1 ,no_str= true ,invert= true },
|
|
{ id= "optimize_dynamic_geom" ,type= "track" ,val= 2 ,cmd= "r__optimize_dynamic_geom" ,min= 0 ,max= 4 ,step= 1 ,no_str= true ,invert= true },
|
|
{ id= "optimize_shadow_geom" ,type= "check" ,val= 1 ,cmd= "r__optimize_shadow_geom" },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "title" ,type= "title" ,text= "ui_mm_header_rendering_quality" ,align= "l" ,clr= {255,200,200,200} },
|
|
{ id= "texture_lod" ,type= "track" ,val= 2 ,cmd= "texture_lod" ,min= 0 ,max= 4 ,step= 1 ,no_str= true ,invert= true ,vid= true ,restart= true },
|
|
{ id= "geometry_lod" ,type= "track" ,val= 2 ,cmd= "r__geometry_lod" ,min= 0.1 ,max= 1.5 ,step= 0.1 },
|
|
{ id= "mipbias" ,type= "track" ,val= 2 ,cmd= "r__tf_mipbias" ,min= -0.5 ,max= 0.5 ,step= 0.1 ,no_str= true ,invert= true },
|
|
{ id= "tf_aniso" ,type= "list" ,val= 0 ,cmd= "r__tf_aniso" ,content={ {"0","0"},{"4","4"},{"8","8"},{"16","16"} } ,vid= true, no_str= true },
|
|
{ id= "ssample" ,type= "track" ,val= 2 ,cmd= "r__supersample" ,min= 1 ,max= 8 ,step= 1 ,vid= true ,precondition= {for_renderer,"renderer_r1","renderer_r2a","renderer_r2","renderer_r2.5"} },
|
|
{ id= "ssample_list" ,type= "list" ,val= 0 ,cmd= "r3_msaa" ,content={ {"st_opt_off","st_opt_off"},{"2x","x2"},{"4x","x4"},{"8x","x8"} } ,vid= true ,precondition= {for_renderer,"renderer_r3","renderer_r4"} , no_str= true },
|
|
{ id= "smaa" ,type= "list" ,val= 0 ,cmd= "r2_smaa" ,content={ {"off","st_opt_off"},{"low","st_opt_low"},{"medium","st_opt_medium"},{"high","st_opt_high"},{"ultra","st_opt_ultra"} } ,precondition= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"}, no_str= true },
|
|
{ id= "detail_textures" ,type= "check" ,val= 1 ,cmd= "r1_detail_textures" ,vid= true ,precondition= {for_renderer,"renderer_r1"} },
|
|
{ id= "detail_bump" ,type= "check" ,val= 1 ,cmd= "r2_detail_bump" ,vid= true ,precondition= {for_renderer,"renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "steep_parallax" ,type= "check" ,val= 1 ,cmd= "r2_steep_parallax" ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "enable_tessellation" ,type= "check" ,val= 1 ,cmd= "r4_enable_tessellation" ,vid= true ,precondition= {for_renderer,"renderer_r4"} },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "title" ,type= "title" ,text= "ui_mm_header_grass" ,align= "l" ,clr= {255,200,200,200} },
|
|
{ id= "detail_density" ,type= "track" ,val= 2 ,cmd= "r__detail_density" ,min= 0.04 ,max= 1 ,step= 0.02 ,prec = 2 ,invert= true ,vid= true ,restart= true ,no_str= true },
|
|
{ id= "detail_radius" ,type= "track" ,val= 2 ,cmd= "r__detail_radius" ,min= 50 ,max= 250 ,step= 20 ,restart= true ,vid= true },
|
|
{ id= "detail_height" ,type= "track" ,val= 2 ,cmd= "r__detail_height" ,min= 0.5 ,max= 2 ,step= 0.1 ,restart= true ,vid= true },
|
|
{ id= "grass_shadow" ,type= "check" ,val= 1 ,cmd= "r__enable_grass_shadow" ,vid= true ,precondition= {for_renderer,"renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
|
|
{ id= "line" ,type= "line" ,precondition= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "title" ,type= "title" ,text= "ui_mm_header_lighting" ,align= "l" ,clr= {255,200,200,200} ,precondition= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"}},
|
|
{ id= "slight_fade" ,type= "track" ,val= 2 ,cmd= "r2_slight_fade" ,min= 0.2 ,max= 1 ,step= 0.1 ,vid= true ,precondition= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "ls_squality" ,type= "track" ,val= 2 ,cmd= "r2_ls_squality" ,min= 0.5 ,max= 1 ,step= 0.5 ,vid= true ,precondition= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "actor_shadow" ,type= "check" ,val= 1 ,cmd= "r__actor_shadow" ,precondition= {for_renderer,"renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "gloss_factor" ,type= "track" ,val= 2 ,cmd= "r2_gloss_factor" ,min= 0 ,max= 10 ,step= 0.5 ,precondition= {for_renderer,"renderer_r2a","renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "sun" ,type= "check" ,val= 1 ,cmd= "r2_sun" ,vid= true ,precondition= {for_renderer,"renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "sun_quality" ,type= "list" ,val= 0 ,cmd= "r2_sun_quality" ,content={cont_sun_quality} ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
-- { id= "sun_details" ,type= "check" ,val= 1 ,cmd= "r2_sun_details" ,vid= true ,precondition= {for_renderer,"renderer_r2","renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "sunshafts_mode" ,type= "radio_v" ,val= 0 ,cmd= "r2_sunshafts_mode" ,content={ {"off"},{"volumetric"},{"screen_space"},{"combined"} } ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "sunshafts_quality" ,type= "list" ,val= 0 ,cmd= "r2_sunshafts_quality" ,content={ {"st_opt_low","low"},{"st_opt_medium","medium"},{"st_opt_high","high"} } ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "sunshafts_value" ,type= "track" ,val= 2 ,cmd= "r2_sunshafts_value" ,min= 0.5 ,max= 2 ,step= 0.1 ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "sunshafts_min" ,type= "track" ,val= 2 ,cmd= "r2_sunshafts_min" ,min= 0 ,max= 0.5 ,step= 0.05 ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "ssao_mode" ,type= "radio_v" ,val= 0 ,cmd= "r2_ssao_mode" ,content={ {"disabled","st_opt_off"},{"default","SSDO"},{"hbao","HBAO"},{"hdao","HDAO"}} ,vid= true , no_str = true ,restart= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "ssao" ,type= "list" ,val= 0 ,cmd= "r2_ssao" ,content={ {"st_opt_off","off"},{"st_opt_low","low"},{"st_opt_medium","medium"},{"st_opt_high","high"} } ,vid= true ,restart= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "volumetric_lights" ,type= "check" ,val= 1 ,cmd= "r2_volumetric_lights" ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
|
|
{ id= "line" ,type= "line" ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"}},
|
|
{ id= "title" ,type= "title" ,text= "ui_mm_header_effects" ,align= "l" ,clr= {255,200,200,200} ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"}},
|
|
{ id= "soft_water" ,type= "check" ,val= 1 ,cmd= "r2_soft_water" ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "soft_particles" ,type= "check" ,val= 1 ,cmd= "r2_soft_particles" ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "dof_enable" ,type= "check" ,val= 1 ,cmd= "r2_dof_enable" ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "mblur_enable" ,type= "check" ,val= 1 ,cmd= "r2_mblur_enabled" ,vid= true ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "mblur" ,type= "track" ,val= 2 ,def= 0.4 ,cmd= "r2_mblur" ,min= 0 ,max= 1 ,step= 0.05 ,precondition= {for_renderer,"renderer_r2.5","renderer_r3","renderer_r4"} },
|
|
{ id= "dynamic_wet_surfaces" ,type= "check" ,val= 1 ,cmd= "r3_dynamic_wet_surfaces" ,vid= true ,precondition= {for_renderer,"renderer_r3","renderer_r4"} },
|
|
{ id= "volumetric_smoke" ,type= "check" ,val= 1 ,cmd= "r3_volumetric_smoke" ,vid= true ,precondition= {for_renderer,"renderer_r3","renderer_r4"} },
|
|
-- { id= "msaa_alphatest" ,type= "list" ,val= 0 ,cmd= "r3_msaa_alphatest" ,content={ {"st_opt_off","off"},{"st_atest_msaa_dx10_0","atest_msaa_dx10_0"},{"st_atest_msaa_dx10_1","atest_msaa_dx10_1"} } ,vid= true ,precondition= {for_renderer,"renderer_r3","renderer_r4"} },
|
|
-- { id= "msaa_opt" ,type= "check" ,val= 1 ,cmd= "r3_msaa_opt" ,vid= true ,precondition= {for_renderer,"renderer_r3","renderer_r4"} },
|
|
|
|
},},
|
|
{ id= "hud" ,sh=true ,gr={
|
|
{ id= "slide_hud" ,type= "slide" ,link= "ui_options_slider_hud" ,text= "ui_mm_title_hud" ,size= {512,50} ,spacing= 20 },
|
|
|
|
{ id= "show_crosshair" ,type= "check" ,val= 1 ,def= false ,cmd= "hud_crosshair" },
|
|
{ id= "crosshair_dist" ,type= "check" ,val= 1 ,def= false ,cmd= "hud_crosshair_dist" },
|
|
{ id= "crosshair_clr_a" ,type= "track" ,val= 2 ,min= 0 ,max= 255 ,step= 1 ,curr= {curr_crosshair_clr,"a"} ,functor= {func_crosshair_clr,"a"} },
|
|
{ id= "crosshair_clr_r" ,type= "track" ,val= 2 ,min= 0 ,max= 255 ,step= 1 ,curr= {curr_crosshair_clr,"r"} ,functor= {func_crosshair_clr,"r"} },
|
|
{ id= "crosshair_clr_g" ,type= "track" ,val= 2 ,min= 0 ,max= 255 ,step= 1 ,curr= {curr_crosshair_clr,"g"} ,functor= {func_crosshair_clr,"g"} },
|
|
{ id= "crosshair_clr_b" ,type= "track" ,val= 2 ,min= 0 ,max= 255 ,step= 1 ,curr= {curr_crosshair_clr,"b"} ,functor= {func_crosshair_clr,"b"} },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "show_hud" ,type= "check" ,val= 1 ,def= true ,cmd= "hud_draw" },
|
|
-- { id= "dynamic_crosshair" ,type= "check" ,val= 1 ,def= false ,cmd= "cl_dynamiccrosshair" },
|
|
{ id= "show_slots" ,type= "check" ,val= 1 ,def= true ,functor= {func_slot_hud} },
|
|
{ id= "show_wpn" ,type= "check" ,val= 1 ,def= true ,cmd= "hud_weapon" },
|
|
{ id= "show_tracers" ,type= "check" ,val= 1 ,def= true ,cmd= "g_use_tracers" },
|
|
{ id= "show_minimap" ,type= "check" ,val= 1 ,def= false ,functor= {func_hud_minimap} },
|
|
{ id= "show_enemy_health" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "show_identity" ,type= "check" ,val= 1 ,def= false ,cmd= "hud_info" },
|
|
{ id= "autohide_stamina_bar" ,type= "check" ,val= 1 ,def= true ,functor= {func_hud_autohide_bar} },
|
|
{ id= "3d_pda" ,type= "check" ,val= 1 ,def= true ,cmd= "g_3d_pda" },
|
|
{ id= "ironsights_zoom_factor" ,type= "track" ,val= 2 ,min= 1 ,max= 2 ,step= 0.1 ,cmd= "g_ironsights_zoom_factor" },
|
|
{ id= "head_bob_factor" ,type= "track" ,val= 2 ,min= 0 ,max= 2 ,step= 0.1 ,cmd= "head_bob_factor" },
|
|
|
|
},},
|
|
{ id= "player" ,sh=true ,gr={
|
|
{ id= "slide_player" ,type= "slide" ,link= "ui_options_slider_player" ,text= "ui_mm_title_effects" ,size= {512,50} },
|
|
|
|
{ id= "animations" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "item_swap_animation" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "shoot_effects" ,type= "check" ,val= 1 ,def= false },
|
|
|
|
{ id= "radiation_effect" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "blood_splash" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "bleed_effect" ,type= "check" ,val= 1 ,def= true },
|
|
--{ id="tiny_pfx" ,type= "check" ,val= 1 ,def= true },
|
|
|
|
{ id= "slide_mask" ,type= "slide" ,link= "ui_options_slider_mask" ,text= "ui_mm_title_mask" ,size= {512,50} ,spacing= 20 },
|
|
{ id= "mask_hud" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "breathing_fog" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "rain_droplets" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "visor_reflection" ,type= "check" ,val= 1 ,def= true },
|
|
},},
|
|
{ id= "weather" ,sh=true ,gr={
|
|
{ id= "clear_slide" ,type= "slide" ,link= "ui_options_slider_weather_clear" ,text= "st_wthr_clear" ,size= {512,50} },
|
|
{ id= "clear_period" ,type= "radio_h" ,val= 2 ,def= random_choice(4,6) ,content={ {3,"3h"},{4,"4h"},{5,"5h"},{6,"6h"},{7,"7h"},{8,"8h"},{9,"9h"},{10,"10h"},{11,"11h"},{12,"12h"} } ,hint= "video_weather_period" ,force_horz = true },
|
|
{ id= "clear_occurrence" ,type= "radio_v" ,val= 2 ,def= random_choice(2,3) ,content={ {1,"none"},{2,"rare"},{3,"regular"} } ,hint= "video_weather_occurrence" },
|
|
|
|
{ id= "partly_slide" ,type= "slide" ,link= "ui_options_slider_weather_partly" ,text= "st_wthr_partly" ,size= {512,50} },
|
|
{ id= "partly_period" ,type= "radio_h" ,val= 2 ,def= random_choice(4,6) ,content={ {3,"3h"},{4,"4h"},{5,"5h"},{6,"6h"},{7,"7h"},{8,"8h"},{9,"9h"},{10,"10h"},{11,"11h"},{12,"12h"} } ,hint= "video_weather_period" ,force_horz = true },
|
|
{ id= "partly_occurrence" ,type= "radio_v" ,val= 2 ,def= random_choice(2,3) ,content={ {1,"none"},{2,"rare"},{3,"regular"} } ,hint= "video_weather_occurrence" },
|
|
|
|
{ id= "cloudy_slide" ,type= "slide" ,link= "ui_options_slider_weather_cloudy" ,text= "st_wthr_cloudy" ,size= {512,50} },
|
|
{ id= "cloudy_period" ,type= "radio_h" ,val= 2 ,def= random_choice(4,6) ,content={ {3,"3h"},{4,"4h"},{5,"5h"},{6,"6h"},{7,"7h"},{8,"8h"},{9,"9h"},{10,"10h"},{11,"11h"},{12,"12h"} } ,hint= "video_weather_period" ,force_horz = true },
|
|
{ id= "cloudy_occurrence" ,type= "radio_v" ,val= 2 ,def= random_choice(2,3) ,content={ {1,"none"},{2,"rare"},{3,"regular"} } ,hint= "video_weather_occurrence" },
|
|
|
|
{ id= "rain_slide" ,type= "slide" ,link= "ui_options_slider_weather_rain" ,text= "st_wthr_rain" ,size= {512,50} },
|
|
{ id= "rain_period" ,type= "radio_h" ,val= 2 ,def= random_choice(4,6) ,content={ {3,"3h"},{4,"4h"},{5,"5h"},{6,"6h"},{7,"7h"},{8,"8h"},{9,"9h"},{10,"10h"},{11,"11h"},{12,"12h"} } ,hint= "video_weather_period" ,force_horz = true },
|
|
{ id= "rain_occurrence" ,type= "radio_v" ,val= 2 ,def= random_choice(2,3) ,content={ {1,"none"},{2,"rare"},{3,"regular"} } ,hint= "video_weather_occurrence" },
|
|
|
|
{ id= "storm_slide" ,type= "slide" ,link= "ui_options_slider_weather_storm" ,text= "st_wthr_storm" ,size= {512,50} },
|
|
{ id= "storm_period" ,type= "radio_h" ,val= 2 ,def= random_choice(4,6) ,content={ {3,"3h"},{4,"4h"},{5,"5h"},{6,"6h"},{7,"7h"},{8,"8h"},{9,"9h"},{10,"10h"},{11,"11h"},{12,"12h"} } ,hint= "video_weather_period" ,force_horz = true },
|
|
{ id= "storm_occurrence" ,type= "radio_v" ,val= 2 ,def= random_choice(2,3) ,content={ {1,"none"},{2,"rare"},{3,"regular"} } ,hint= "video_weather_occurrence" },
|
|
|
|
{ id= "foggy_slide" ,type= "slide" ,link= "ui_options_slider_weather_foggy" ,text= "st_wthr_foggy" ,size= {512,50} },
|
|
{ id= "foggy_period" ,type= "radio_h" ,val= 2 ,def= random_choice(4,6) ,content={ {3,"3h"},{4,"4h"},{5,"5h"},{6,"6h"},{7,"7h"},{8,"8h"},{9,"9h"},{10,"10h"},{11,"11h"},{12,"12h"} } ,hint= "video_weather_period" ,force_horz = true },
|
|
{ id= "foggy_occurrence" ,type= "radio_v" ,val= 2 ,def= random_choice(2,3) ,content={ {1,"none"},{2,"rare"},{3,"regular"} } ,hint= "video_weather_occurrence" },
|
|
|
|
},},
|
|
{ id= "night" ,sh=true ,gr={
|
|
{ id= "slide_night" ,type= "slide" ,link= "ui_options_slider_night" ,text= "ui_mm_title_night" ,size= {512,50} },
|
|
|
|
{ id= "brightness" ,type= "list" ,val= 0 ,def= "slight" ,content= {{"dark","dark_night"} , {"slight","slight_night"} , {"medium","medium_night"} , {"bright","bright_night"}} },
|
|
{ id= "moon_cycle" ,type= "radio_h" ,val= 2 ,def= 8 ,content= {{8,"8days"} , {28,"28days"}} },
|
|
{ id= "moon_phase_state" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "moon_phase" ,type= "radio_v" ,val= 2 ,def= 8 ,content= {{0,"moon_phase_0"} , {1,"moon_phase_1"} , {2,"moon_phase_2"} , {3,"moon_phase_3"} , {4,"moon_phase_4"} , {5,"moon_phase_5"} , {6,"moon_phase_6"} , {7,"moon_phase_7"}} },
|
|
},},
|
|
},},
|
|
{ id= "sound" ,gr={
|
|
{ id= "general" ,sh=true ,gr={
|
|
{ id= "slide_sound" ,type= "slide" ,link= "ui_options_slider_sound" ,text= "ui_mm_title_sound" ,size= {512,50} },
|
|
|
|
{ id= "master_volume" ,type= "track" ,val= 2 ,cmd= "snd_volume_eff" ,min= 0 ,max= 1 ,step= 0.1 },
|
|
{ id= "music_volume" ,type= "track" ,val= 2 ,cmd= "snd_volume_music" ,min= 0 ,max= 1 ,step= 0.1 },
|
|
{ id= "sound_device" ,type= "list" ,val= 0 ,cmd= "snd_device" ,no_str= true ,restart= true },
|
|
{ id= "eax" ,type= "check" ,val= 1 ,cmd= "snd_efx" },
|
|
{ id= "dynamic_music" ,type= "check" ,val= 1 ,cmd= "g_dynamic_music" },
|
|
{ id= "caption" ,type= "radio_v" ,val= 0 ,def= "none" ,content={ {"none"},{"storyonly"},{"all"} } },
|
|
},},
|
|
{ id= "environment" ,sh=true ,gr={
|
|
{ id= "slide_sound" ,type= "slide" ,link= "ui_options_slider_sound_environment" ,text= "ui_mm_title_sound_environment" ,size= {512,50} },
|
|
|
|
{ id= "ambient_volume" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 1 ,step= 0.1 },
|
|
{ id= "wind_sound" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "breathing_sound" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "helmet_rain_sound" ,type= "check" ,val= 1 ,def= true },
|
|
},},
|
|
{ id= "radio" ,sh=true ,gr={
|
|
{ id= "slide_radio" ,type= "slide" ,link= "ui_options_slider_radio" ,text= "ui_mm_title_sound_radio" ,size= {512,50} },
|
|
|
|
{ id= "zone" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "emission_intereferences" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "underground_intereferences" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "display_tracks" ,type= "check" ,val= 1 ,def= false },
|
|
-- playlist names
|
|
},},
|
|
},},
|
|
{ id= "control" ,gr={
|
|
{ id= "general" ,sh=true ,gr={
|
|
{ id= "slide_control" ,type= "slide" ,link= "ui_options_slider_control" ,text= "ui_mm_title_control" ,size= {512,50} },
|
|
|
|
{ id= "mouse_sens" ,type= "track" ,val= 2 ,cmd= "mouse_sens" ,min= 0.001 ,max= 0.6 ,step= 0.01 },
|
|
{ id= "mouse_sens_aim" ,type= "track" ,val= 2 ,cmd= "mouse_sens_aim" ,min= 0.5 ,max= 2 ,step= 0.05, def= 1 },
|
|
{ id= "mouse_invert" ,type= "check" ,val= 1 ,cmd= "mouse_invert" ,def= false },
|
|
{ id= "crouch_toggle" ,type= "check" ,val= 1 ,cmd= "g_crouch_toggle" ,def= false },
|
|
{ id= "walk_toggle" ,type= "check" ,val= 1 ,cmd= "g_walk_toggle" ,def= false },
|
|
{ id= "sprint_toggle" ,type= "check" ,val= 1 ,cmd= "g_sprint_toggle" ,def= true },
|
|
{ id= "lookout_toggle" ,type= "check" ,val= 1 ,cmd= "g_lookout_toggle" ,def= false },
|
|
{ id= "aim_toggle" ,type= "check" ,val= 1 ,cmd= "wpn_aim_toggle" ,def= false ,bool_to_num= true },
|
|
{ id= "pickup_mode" ,type= "check" ,val= 1 ,cmd= "g_multi_item_pickup" ,def= true },
|
|
{ id= "simple_pda_mode" ,type= "check" ,val= 1 ,cmd= "g_simple_pda" ,def= true },
|
|
{ id= "disassembly_warning" ,type= "check" ,val= 1 ,def= true },
|
|
},},
|
|
{ id= "keybind" ,sh=true ,gr={},}, -- ENGINE!
|
|
},},
|
|
{ id= "gameplay" ,gr={
|
|
{ id= "general" ,sh=true ,gr={
|
|
{ id= "slide_player" ,type= "slide" ,link= "ui_options_slider_player" ,text= "ui_mm_title_gameplay" ,size= {512,50} },
|
|
|
|
{ id= "player_name" ,type= "input" ,val= 0 ,curr= {curr_player_name} ,functor= {func_player_name} ,precondition= {level_present} },
|
|
{ id= "outfit_portrait" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "hardcore_ai_aim" ,type= "check" ,val= 1 ,def= false ,functor= {func_hardcore_ai_aim} },
|
|
{ id= "show_tip_reputation" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "mechanic_feature" ,type= "check" ,val= 1 ,def= false },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "release_dropped_items" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "corpse_max_count" ,type= "track" ,val= 2 ,def= 5 ,min= 5 ,max= 30 ,step= 1 },
|
|
{ id= "corpse_min_dist" ,type= "track" ,val= 2 ,def= 75 ,min= 75 ,max= 200 ,step= 5 },
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "npc_loot_distance" ,type= "track" ,val= 2 ,def= 5 ,min= 0 ,max= 25 ,step= 1 },
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "max_tasks" ,type= "track" ,val= 2 , def= 2 ,min= 1 ,max= 10 ,step= 1 },
|
|
{ id= "line" ,type= "line" },
|
|
{ id= "need_equipped_hkit" ,type= "check" ,val= 1 ,def= true },
|
|
},},
|
|
{ id= "silent_kills" ,sh=true ,gr={
|
|
{ id= "sk_desc" ,type= "desc" ,text= "st_sk_desc" ,clr= {255,125,175,200} },
|
|
{ id= "sk_enabled" ,type= "check" ,val= 1 ,def= false},
|
|
{ id= "sk_melee_enabled" ,type= "check" ,val= 1 ,def= true},
|
|
{ id= "sk_all_melee_ok" ,type= "check" ,val= 1 ,def= false},
|
|
{ id= "sk_gun_enabled" ,type= "check" ,val= 1 ,def= true},
|
|
{ id= "sk_headshot_only" ,type= "check" ,val= 1 ,def= true},
|
|
{ id= "sk_fresh_time" ,type= "input" ,val= 0 ,def= 300},
|
|
{ id= "sk_suspect_dist" ,type= "input" ,val= 0 ,def= 10},
|
|
{ id= "sk_melee_hear_dist" ,type= "input" ,val= 0 ,def= 5},
|
|
{ id= "sk_gun_hear_dist" ,type= "input" ,val= 0 ,def= 10},
|
|
},},
|
|
{ id= "economy_diff" ,sh=true ,precondition = {level_present} ,output = "ui_mm_warning_economy_diff_not_level_present" ,presets= {"economy_easy","economy_medium","economy_hard"} ,gr={
|
|
{ id= "slide_economy_diff" ,type= "slide" ,link= "ui_options_slider_economy_diff" ,text= "ui_mm_title_economy_diff" ,size= {512,50} },
|
|
{ id= "desc_ingame_only" ,type= "desc" ,text= "ui_mm_desc_economy_diff" ,clr= {255,200,75,75} },
|
|
|
|
{ id= "condition_buy_override" ,type= "track" ,val= 2 , curr = {trader_cond,'get'}, functor= {trader_cond,"set"} ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "goodwill" ,type= "track" ,val= 2 ,curr= {curr_economy,"goodwill"} ,functor= {func_economy_diff,"goodwill"} ,min= 0.5 ,max= 3 ,step= 0.1 },
|
|
{ id= "rewards" ,type= "track" ,val= 2 ,curr= {curr_economy,"rewards"} ,functor= {func_economy_diff,"rewards"} ,min= 0.5 ,max= 3 ,step= 0.1 },
|
|
{ id= "repair" ,type= "track" ,val= 2 ,curr= {curr_economy,"repair"} ,functor= {func_economy_diff,"repair"} ,min= 1 ,max= 2 ,step= 0.1 },
|
|
{ id= "upgrade" ,type= "track" ,val= 2 ,curr= {curr_economy,"upgrade"} ,functor= {func_economy_diff,"upgrade"} ,min= 1 ,max= 3 ,step= 0.1 },
|
|
{ id= "buy" ,type= "track" ,val= 2 ,curr= {curr_economy,"buy"} ,functor= {func_economy_diff,"buy"} ,min= 0.5 ,max= 2 ,step= 0.1 },
|
|
{ id= "sell" ,type= "track" ,val= 2 ,curr= {curr_economy,"sell"} ,functor= {func_economy_diff,"sell"} ,min= 0.5 ,max= 2 ,step= 0.1 },
|
|
{ id= "loots" ,type= "track" ,val= 2 ,curr= {curr_economy,"loots"} ,functor= {func_economy_diff,"loots"} ,min= 0.5 ,max= 3 ,step= 0.1 },
|
|
{ id= "money_loots" ,type= "track" ,val= 2 ,curr= {curr_economy,"money_loots"} ,functor= {func_economy_diff,"money_loots"} ,min= 0.5 ,max= 3 ,step= 0.1 },
|
|
{ id= "stash_chance" ,type= "track" ,val= 2 ,curr= {curr_economy,"stash_chance"} ,functor= {func_economy_diff,"stash_chance"} ,min= 0.1 ,max= 1 ,step= 0.05 },
|
|
{ id= "weapon_degradation" ,type= "track" ,val= 2 ,curr= {curr_economy,"weapon_degradation"} ,functor= {func_economy_diff,"weapon_degradation"} ,min= 0.5 ,max= 1 ,step= 0.05 },
|
|
{ id= "battery_consumption" ,type= "track" ,val= 2 ,curr= {curr_economy,"battery_consumption"} ,functor= {func_economy_diff,"battery_consumption"} ,min= 0.5 ,max= 3 ,step= 0.1 },
|
|
{ id= "restock" ,type= "track" ,val= 2 ,curr= {curr_economy,"restock"} ,functor= {func_economy_diff,"restock"} ,min= 12 ,max= 168 ,step= 1 },
|
|
{ id= "arty_chance" ,type= "track" ,val= 2 ,curr= {curr_economy,"arty_chance"} ,functor= {func_economy_diff,"arty_chance"} ,min= 0.1 ,max= 1 ,step= 0.05 },
|
|
{ id= "percentage_parts" ,type= "check" ,val= 1 ,curr= {curr_economy,"percentage_parts"} ,functor= {func_economy_diff,"percentage_parts"} },
|
|
{ id= "limited_bolts" ,type= "check" ,val= 1 ,curr= {curr_economy,"limited_bolts"} ,functor= {func_economy_diff,"limited_bolts"} },
|
|
{ id= "outfit_drops" ,type= "list" ,val= 2 ,curr= {curr_economy,"outfit_drops"} ,functor= {func_economy_diff,"outfit_drops"} ,content= {{1,"off"} , {2,"progressive"} , {3,"full"}} },
|
|
|
|
},},
|
|
{ id= "gameplay_diff" ,sh=true ,precondition = {level_present} ,output = "ui_mm_warning_gameplay_diff_not_level_present" ,presets= {"gameplay_easy","gameplay_medium","gameplay_hard"} ,gr={
|
|
{ id= "slide_gameplay_diff" ,type= "slide" ,link= "ui_options_slider_gameplay_diff" ,text= "ui_mm_title_gameplay_diff" ,size= {512,50} },
|
|
{ id= "desc_ingame_only" ,type= "desc" ,text= "ui_mm_desc_gameplay_diff" ,clr= {255,200,75,75} },
|
|
|
|
{ id= "actor_immunities" ,type= "list" ,val= 2 ,curr= {curr_gameplay,"actor_immunities"} ,functor= {func_gameplay_diff,"actor_immunities"} ,content= {{1,"great"} , {2,"good"} , {3,"average"} , {4,"poor"}} },
|
|
{ id= "hit_power" ,type= "track" ,val= 2 ,curr= {curr_gameplay,"hit_power"} ,functor= {func_gameplay_diff,"hit_power"} ,min= 0.5 ,max= 3 ,step= 0.1 },
|
|
{ id= "dispersion_base" ,type= "track" ,val= 2 ,curr= {curr_gameplay,"dispersion_base"} ,functor= {func_gameplay_diff,"dispersion_base"} ,min= 1 ,max= 3 ,step= 0.1 },
|
|
{ id= "dispersion_factor" ,type= "track" ,val= 2 ,curr= {curr_gameplay,"dispersion_factor"} ,functor= {func_gameplay_diff,"dispersion_factor"} ,min= 1 ,max= 5 ,step= 0.1 },
|
|
{ id= "power_loss_bias" ,type= "track" ,val= 2 ,curr= {curr_gameplay,"power_loss_bias"} ,functor= {func_gameplay_diff,"power_loss_bias"} ,min= 0.0 ,max= 1 ,step= 0.05 },
|
|
{ id= "weight" ,type= "track" ,val= 2 ,curr= {curr_gameplay,"weight"} ,functor= {func_gameplay_diff,"weight"} ,min= 10 ,max= 50 ,step= 1 },
|
|
{ id= "thirst" ,type= "check" ,val= 1 ,curr= {curr_gameplay,"thirst"} ,functor= {func_gameplay_diff,"thirst"} },
|
|
{ id= "sleep" ,type= "check" ,val= 1 ,curr= {curr_gameplay,"sleep"} ,functor= {func_gameplay_diff,"sleep"} },
|
|
{ id= "radiation_day" ,type= "check" ,val= 1 ,curr= {curr_gameplay,"radiation_day"} ,functor= {func_gameplay_diff,"radiation_day"} },
|
|
{ id= "notify_geiger" ,type= "check" ,val= 1 ,curr= {curr_gameplay,"notify_geiger"} ,functor= {func_gameplay_diff,"notify_geiger"} },
|
|
{ id= "notify_anomaly" ,type= "check" ,val= 1 ,curr= {curr_gameplay,"notify_anomaly"} ,functor= {func_gameplay_diff,"notify_anomaly"} },
|
|
},},
|
|
{ id= "disguise" ,sh=true ,gr={
|
|
{ id= "slide_disguise" ,type= "slide" ,link= "ui_options_slider_disguise" ,text= "ui_mm_menu_disguise" ,size= {512,50} },
|
|
{ id= "desc_disguise" ,type= "desc" ,text= "ui_mm_desc_disguise" ,clr= {255,125,175,200} },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "state" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "active_item" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "active_item_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "weapon" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "weapon_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "outfit" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "outfit_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "helmet" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "helmet_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "backpack" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "backpack_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "inventory" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "inventory_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "speed" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "speed_factor" ,type= "track" ,val= 2 ,def= 1 ,min= 0.1 ,max= 2 ,step= 0.1 },
|
|
{ id= "distance" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "distance_factor" ,type= "track" ,val= 2 ,def= 5 ,min= 1 ,max= 100 ,step= 1 },
|
|
{ id= "stay_time" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "stay_time_factor" ,type= "track" ,val= 2 ,def= 20 ,min= 1 ,max= 100 ,step= 1 },
|
|
},},
|
|
{ id= "fast_travel" ,sh=true ,gr={
|
|
{ id= "slide_fast_travel" ,type= "slide" ,link= "ui_options_slider_fast_travel" ,text= "ui_mm_menu_fast_travel" ,size= {512,50} },
|
|
{ id= "desc_fast_travel" ,type= "desc" ,text= "ui_mm_desc_fast_travel" ,clr= {255,125,175,200} },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "state" ,type= "list" ,val= 2 ,def= 0 ,content= {{0,"disabled"} , {1,"visit_only"} , {2,"show_all"}} },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "on_combat" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "on_overweight" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "on_damage" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "on_emission" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "long_names" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "visit_message" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "time" ,type= "check" ,val= 1 ,def= false },
|
|
},},
|
|
{ id= "backpack_travel" ,sh=true ,gr={
|
|
{ id= "slide_backpack_travel" ,type= "slide" ,link= "ui_options_slider_fast_travel" ,text= "ui_mm_menu_backpack_travel" ,size= {512,50} },
|
|
{ id= "desc_backpack_travel" ,type= "desc" ,text= "ui_mm_desc_backpack_travel" ,clr= {255,125,175,200} },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "state" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id= "on_combat" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "on_overweight" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "on_damage" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "on_emission" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "time" ,type= "check" ,val= 1 ,def= false },
|
|
},},
|
|
},},
|
|
{ id= "alife" ,gr={
|
|
{ id= "general" ,sh=true ,gr={
|
|
{ id= "slide_alife" ,type= "slide" ,link= "ui_options_slider_alife" ,text= "ui_mm_title_alife" ,size= {512,50} },
|
|
|
|
{ id= "alife_mutant_pop" ,type= "list" ,val= 2 ,def= 0.75 ,content= {{0.25} , {0.5} , {0.75} , {1}} ,no_str= true },
|
|
{ id= "alife_stalker_pop" ,type= "list" ,val= 2 ,def= 0.5 ,content= {{0.25} , {0.5} , {0.75} , {1}} ,no_str= true },
|
|
{ id= "offline_combat" ,type= "list" ,val= 0 ,def= "full" ,content= {{"full","full"} , {"on_smarts_only","on_smarts_only"}, {"off","off"}} },
|
|
{ id= "excl_dist" ,type= "list" ,val= 2 ,def= 75 ,content= {{0} , {25} , {50} , {75} , {100}} ,no_str= true },
|
|
{ id= "dynamic_anomalies" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "dynamic_relations" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "war_goodwill_reset" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "heli_engine_sound" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "heli_spawn" ,type= "check" ,val= 1 ,def= false },
|
|
|
|
},},
|
|
{ id= "event" ,sh=true ,gr={
|
|
{ id= "slide_emission" ,type= "slide" ,link= "ui_options_slider_emission" ,text= "ui_mm_title_emission" ,size= {512,50} },
|
|
{ id= "emission_state" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "emission_frequency" ,type= "list" ,val= 2 ,def= 24 ,content= {{12,"every_12h"} , {24,"every_24h"} , {48,"every_2d"} , {96,"every_4d"}} },
|
|
{ id= "emission_fate" ,type= "list" ,val= 0 ,def= "kill_at_wave" ,content= {{"kill_at_end"} , {"kill_at_wave"} , {"turn_to_zombie"} , {"explode"}} },
|
|
{ id= "emission_warning" ,type= "list" ,val= 0 ,def= "siren_radio" ,content= {{"siren_radio"} , {"siren"} , {"radio"} , {"no_warning"}} },
|
|
{ id= "emission_task" ,type= "check" ,val= 1 ,def= true },
|
|
|
|
{ id= "slide_psi_storm" ,type= "slide" ,link= "ui_options_slider_psi_storm" ,text= "ui_mm_title_psi_storm" ,size= {512,50} ,spacing= 20 },
|
|
{ id= "psi_storm_state" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "psi_storm_frequency" ,type= "list" ,val= 2 ,def= 24 ,content= {{12,"every_12h"} , {24,"every_24h"} , {48,"every_2d"} , {96,"every_4d"}} },
|
|
{ id= "psi_storm_fate" ,type= "list" ,val= 0 ,def= "kill_at_vortex" ,content= {{"kill_at_vortex"} , {"turn_to_zombie"} , {"unhurt"}} },
|
|
{ id= "psi_storm_warning" ,type= "list" ,val= 0 ,def= "siren" ,content= {{"siren"} , {"no_warning"}} },
|
|
{ id= "psi_storm_task" ,type= "check" ,val= 1 ,def= true },
|
|
|
|
},},
|
|
{ id= "warfare" ,presets= {"warfare_default","warfare_slow","warfare_slower"} ,gr={
|
|
{ id= "general" ,sh=true ,presets= {"warfare_default","warfare_yoko"} ,gr={
|
|
{ id= "slide_warfare" ,type= "slide" ,link= "ui_options_slider_warfare" ,text= "ui_mm_title_warfare" ,size= {512,50} },
|
|
|
|
{ id= "all_out_war" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "random_starting_locations" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "random_starting_character" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "random_stalker_chance" ,type= "track" ,val= 2 ,def= 50 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "random_monster_chance" ,type= "track" ,val= 2 ,def= 50 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "auto_capture" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "auto_capture_max_distance" ,type= "track" ,val= 2 ,def= 50 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "auto_capture_wait_time" ,type= "track" ,val= 2 ,def= 15 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "fog_of_war" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "fog_of_war_distance" ,type= "track" ,val= 2 ,def= 100 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "hide_unfriendly_squads" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "hide_smarts" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "hide_underground_smarts" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "enemy_new_game_bonus" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "enemy_resource_boost" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id= "enemy_base_boost" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
|
|
{ id= "actor_influence_weight" ,type= "track" ,val= 2 ,def= 250 ,min= 0 ,max= 10000 ,step= 50 },
|
|
{ id= "novice_squad_price" ,type= "track" ,val= 2 ,def= 1000 ,min= 0 ,max= 100000 ,step= 1000 },
|
|
{ id= "advanced_squad_price" ,type= "track" ,val= 2 ,def= 10000 ,min= 0 ,max= 100000 ,step= 1000 },
|
|
{ id= "veteran_squad_price" ,type= "track" ,val= 2 ,def= 50000 ,min= 0 ,max= 100000 ,step= 1000 },
|
|
{ id= "heli_price" ,type= "track" ,val= 2 ,def= 75000 ,min= 0 ,max= 100000 ,step= 1000 },
|
|
{ id= "actor_support_enemy_rank_weight" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 50 ,step= 1 },
|
|
{ id= "actor_support_reward_money" ,type= "track" ,val= 2 ,def= 500 ,min= 0 ,max= 10000 ,step= 50 },
|
|
{ id= "actor_support_reward_influence" ,type= "track" ,val= 2 ,def= 0.2 ,min= 0 ,max= 2 ,step= 0.1 },
|
|
|
|
{ id= "monster_max_squads_per_level" ,type= "track" ,val= 2 ,def= 5 ,min= 1 ,max= 200 ,step= 1 },
|
|
{ id= "monster_min_faction_respawn" ,type= "track" ,val= 2 ,def= 5 ,min= 1 ,max= 200 ,step= 1 },
|
|
{ id= "monster_max_faction_respawn" ,type= "track" ,val= 2 ,def= 30 ,min= 1 ,max= 200 ,step= 1 },
|
|
|
|
{ id= "zombies_act_as_faction" ,type= "check" ,val= 1 ,def= false },
|
|
--{ id= "offline_combat_distance" ,type= "track" ,val= 2 ,def= 100 ,min= 1 ,max= 200 ,step= 1 },
|
|
{ id= "enable_mutant_offline_combat" ,type= "check" ,val= 1 ,def= true },
|
|
{ id= "disable_smart_pop_cap" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "purge_zone_on_emission" ,type= "check" ,val= 1 ,def= false },
|
|
{ id= "purge_zone_percentage" ,type= "track" ,val= 2 ,def= 50 ,min= 1 ,max= 100 ,step= 1 },
|
|
{ id= "debug_logging" ,type= "check" ,val= 1 ,def= false },
|
|
},},
|
|
{ id= "azazel" ,sh=true ,presets= {"warfare_default","warfare_yoko"} ,gr={
|
|
{ id= "slide_warfare" ,type= "slide" ,link= "ui_options_slider_warfare" ,text= "ui_mm_title_warfare_azazel" ,size= {512,50} },
|
|
|
|
{ id="state" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="respawn_as_companions" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="respawn_as_actor_faction" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="respawn_as_allies" ,type= "check" ,val= 1 ,def= false },
|
|
{ id="respawn_as_neutrals" ,type= "check" ,val= 1 ,def= false },
|
|
{ id="respawn_as_enemies" ,type= "check" ,val= 1 ,def= false },
|
|
{ id="respawn_as_nearest" ,type= "check" ,val= 1 ,def= true },
|
|
|
|
{ id="companion_dist_mult" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="actor_faction_dist_mult" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="friend_dist_mult" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="ally_dist_mult" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="neutral_dist_mult" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="enemy_dist_mult" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 },
|
|
|
|
{ id="companion_min_respawn_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="companion_max_respawn_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="actor_faction_min_respawn_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="actor_faction_max_respawn_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="ally_min_respawn_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="ally_max_respawn_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="neutral_respawn_min_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="neutral_respawn_max_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="enemy_respawn_min_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
{ id="enemy_respawn_max_dist" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 100 ,step= 1 },
|
|
},},
|
|
{ id= "stalker" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction" ,apply_to_all=true ,gr={
|
|
{ id= "slide_warfare" ,type= "slide" ,link= "ui_options_slider_warfare" ,text= "ui_mm_title_warfare_faction" ,size= {512,50} },
|
|
|
|
{ id="participate_in_warfare" ,type= "check" ,val= 1 ,def= true ,hint="alife_warfare_faction_participate_in_warfare" },
|
|
{ id="spawn_on_new_game" ,type= "check" ,val= 1 ,def= true ,hint="alife_warfare_faction_spawn_on_new_game" },
|
|
{ id="random_spawn_entries" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_random_spawn_entries" },
|
|
{ id="linked_level_targeting" ,type= "check" ,val= 1 ,def= true ,hint="alife_warfare_faction_linked_level_targeting" },
|
|
{ id="ignore_empty_targets" ,type= "check" ,val= 1 ,def= false ,hint="alife_warfare_faction_ignore_empty_targets" },
|
|
{ id="expansion_aggression" ,type= "track" ,val= 2 ,def= 50 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_expansion_aggression" },
|
|
{ id="offline_power_multiplier" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_offline_power_multiplier" },
|
|
{ id="night_activity_chance" ,type= "track" ,val= 2 ,def= 50 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_night_activity_chance" },
|
|
|
|
{ id="keep_last_base" ,type= "check" ,val= 1 ,def= false ,hint="alife_warfare_faction_keep_last_base" },
|
|
{ id="min_faction_respawn" ,type= "track" ,val= 2 ,def= 15 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_min_faction_respawn" },
|
|
{ id="max_faction_respawn" ,type= "track" ,val= 2 ,def= 90 ,min= 0 ,max= 200 ,step= 1 ,hint="alife_warfare_faction_max_faction_respawn" },
|
|
|
|
{ id="min_invasion_size" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 10 ,step= 0.1 ,hint="alife_warfare_faction_min_invasion_size" },
|
|
{ id="max_invasion_size" ,type= "track" ,val= 2 ,def= 2.5 ,min= 0 ,max= 10 ,step= 0.1 ,hint="alife_warfare_faction_max_invasion_size" },
|
|
{ id="min_invasion_depart_time" ,type= "track" ,val= 2 ,def= 5 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_min_invasion_depart_time" },
|
|
{ id="max_invasion_depart_time" ,type= "track" ,val= 2 ,def= 30 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_max_invasion_depart_time" },
|
|
|
|
{ id="min_patrol_time" ,type= "track" ,val= 2 ,def= 60 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_min_patrol_time" },
|
|
{ id="max_patrol_time" ,type= "track" ,val= 2 ,def= 240 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_max_patrol_time" },
|
|
{ id="min_patrol_squads" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 10 ,step= 1 ,hint="alife_warfare_faction_min_patrol_squads" },
|
|
{ id="max_patrol_squads" ,type= "track" ,val= 2 ,def= 2 ,min= 0 ,max= 10 ,step= 1 ,hint="alife_warfare_faction_max_patrol_squads" },
|
|
{ id="patrol_hunt_chance" ,type= "track" ,val= 2 ,def= 50 ,min= 0 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_patrol_hunt_chance" },
|
|
{ id="min_patrol_rest_time" ,type= "track" ,val= 2 ,def= 60 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_min_patrol_rest_time" },
|
|
{ id="max_patrol_rest_time" ,type= "track" ,val= 2 ,def= 240 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_max_patrol_rest_time" },
|
|
|
|
{ id="min_resurgence_wait_time" ,type= "track" ,val= 2 ,def= 30 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_min_resurgence_wait_time" },
|
|
{ id="max_resurgence_wait_time" ,type= "track" ,val= 2 ,def= 120 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_max_resurgence_wait_time" },
|
|
|
|
{ id="random_squad_count" ,type= "check" ,val= 1 ,def= false ,hint="alife_warfare_faction_random_squad_count" },
|
|
{ id="min_random_squad_count" ,type= "track" ,val= 2 ,def= 1 ,min= 0 ,max= 20 ,step= 1 ,hint="alife_warfare_faction_min_random_squad_count" },
|
|
{ id="max_random_squad_count" ,type= "track" ,val= 2 ,def= 3 ,min= 0 ,max= 20 ,step= 1 ,hint="alife_warfare_faction_max_random_squad_count" },
|
|
|
|
{ id="random_patrols" ,type= "check" ,val= 1 ,def= false ,hint="alife_warfare_faction_random_patrols" },
|
|
{ id="max_random_patrols" ,type= "track" ,val= 2 ,def= 15 ,min= 0 ,max= 20 ,step= 1 ,hint="alife_warfare_faction_max_random_patrols" },
|
|
{ id="min_random_patrol_time" ,type= "track" ,val= 2 ,def= 30 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_min_random_patrol_time" },
|
|
{ id="max_random_patrol_time" ,type= "track" ,val= 2 ,def= 180 ,min= 0 ,max= 1000 ,step= 10 ,hint="alife_warfare_faction_max_random_patrol_time" },
|
|
|
|
{ id="base_priority" ,type= "track" ,val= 2 ,def= 10 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_base_priority" },
|
|
{ id="resource_priority" ,type= "track" ,val= 2 ,def= 5 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_resource_priority" },
|
|
{ id="territory_priority" ,type= "track" ,val= 2 ,def= -5 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_territory_priority" },
|
|
{ id="flag_priority" ,type= "track" ,val= 2 ,def= 1 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_flag_priority" },
|
|
{ id="is_being_targeted_priority" ,type= "track" ,val= 2 ,def= 2 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_is_being_targeted_priority" },
|
|
{ id="target_weaker_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_target_weaker_priority" },
|
|
{ id="target_stronger_priority" ,type= "track" ,val= 2 ,def= 1 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_target_stronger_priority" },
|
|
{ id="target_faction_stronger_priority" ,type= "track" ,val= 2 ,def= 1 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_target_faction_stronger_priority" },
|
|
{ id="target_faction_weaker_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_target_faction_weaker_priority" },
|
|
{ id="target_resource_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_target_resource_priority" },
|
|
{ id="target_on_same_level_priority" ,type= "track" ,val= 2 ,def= 100 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_target_on_same_level_priority" },
|
|
|
|
{ id="max_smart_targets_per_base" ,type= "track" ,val= 2 ,def= 2 ,min= 0 ,max= 10 ,step= 1 ,hint="alife_warfare_faction_max_smart_targets_per_base" },
|
|
|
|
{ id="resource_count_modifier" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 1 ,step= 0.01 ,hint="alife_warfare_faction_resource_count_modifier" },
|
|
{ id="base_count_modifier" ,type= "track" ,val= 2 ,def= 0 ,min= 0 ,max= 1 ,step= 0.01 ,hint="alife_warfare_faction_base_count_modifier" },
|
|
|
|
{ id="lvl_k00_marsh_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_k00_marsh_priority" },
|
|
{ id="lvl_k01_darkscape_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_k01_darkscape_priority" },
|
|
{ id="lvl_l01_escape_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l01_escape_priority" },
|
|
{ id="lvl_l02_garbage_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l02_garbage_priority" },
|
|
{ id="lvl_l03_agroprom_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l03_agroprom_priority" },
|
|
{ id="lvl_l04_darkvalley_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l04_darkvalley_priority" },
|
|
{ id="lvl_l05_bar_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l05_bar_priority" },
|
|
{ id="lvl_l06_rostok_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l06_rostok_priority" },
|
|
{ id="lvl_l07_military_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l07_military_priority" },
|
|
{ id="lvl_l08_yantar_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l08_yantar_priority" },
|
|
{ id="lvl_l09_deadcity_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l09_deadcity_priority" },
|
|
{ id="lvl_l10_limansk_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l10_limansk_priority" },
|
|
{ id="lvl_l10_radar_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l10_radar_priority" },
|
|
{ id="lvl_l10_red_forest_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l10_red_forest_priority" },
|
|
{ id="lvl_l11_hospital_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l11_hospital_priority" },
|
|
{ id="lvl_l11_pripyat_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l11_pripyat_priority" },
|
|
{ id="lvl_l12_stancia_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l12_stancia_priority" },
|
|
{ id="lvl_l12u_sarcofag_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l12u_sarcofag_priority" },
|
|
{ id="lvl_l12u_control_monolith_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l12u_control_monolith_priority" },
|
|
{ id="lvl_l12_stancia_2_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l12_stancia_2_priority" },
|
|
{ id="lvl_l13_generators_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_l13_generators_priority" },
|
|
{ id="lvl_zaton_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_zaton_priority" },
|
|
{ id="lvl_jupiter_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_jupiter_priority" },
|
|
{ id="lvl_pripyat_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_pripyat_priority" },
|
|
{ id="lvl_jupiter_underground_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_jupiter_underground_priority" },
|
|
{ id="lvl_k02_trucks_cemetery_priority" ,type= "track" ,val= 2 ,def= 0 ,min= -100 ,max= 100 ,step= 1 ,hint="alife_warfare_faction_lvl_k02_trucks_cemetery_priority" },
|
|
},},
|
|
},},
|
|
{ id= "dynamic_news" ,sh=true ,gr={
|
|
{ id= "slide_dynamic_news" ,type= "slide" ,link= "ui_options_slider_news" ,text= "ui_mm_menu_dynamic_news" ,size= {512,50} },
|
|
{ id= "desc_dynamic_news" ,type= "desc" ,text= "ui_mm_desc_dynamic_news" ,clr= {255,125,175,200} },
|
|
{ id= "line" ,type= "line" },
|
|
|
|
{ id="message_duration" ,type= "track" ,val= 2 ,def= 10 ,min= 5 ,max= 30 ,step= 1 },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id="death_stalker_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="death_mutant_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="generic_death_news" ,type= "check" ,val= 1 ,def= false },
|
|
{ id="death_report_news" ,type= "check" ,val= 1 ,def= false },
|
|
{ id="kill_wounded_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="found_artifact_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="heli_call_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="loot_news" ,type= "check" ,val= 1 ,def= true },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id="reaction_news" ,type= "check" ,val= 1 ,def= true },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id="weather_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="time_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="nearby_activity_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="dumb_zombie_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="cycle_of_special_news" ,type= "track" ,val= 2 ,def= 240 ,min= 60 ,max= 1800 ,step= 60 },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id="bounty_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="cycle_of_task_news" ,type= "track" ,val= 2 ,def= 300 ,min= 60 ,max= 1800 ,step= 60 },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id="random_msg_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="factions_report_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="zone_activity_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="found_dead_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="surge_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="cycle_of_random_news" ,type= "track" ,val= 2 ,def= 240 ,min= 60 ,max= 1800 ,step= 60 },
|
|
|
|
{ id= "line" ,type= "line" },
|
|
{ id="companions_news" ,type= "check" ,val= 1 ,def= true },
|
|
{ id="cycle_of_companions_news" ,type= "track" ,val= 2 ,def= 240 ,min= 60 ,max= 1800 ,step= 60 },
|
|
},},
|
|
},},
|
|
{ id= "other" ,sh=true ,gr={
|
|
{ id= "slide_other" ,type= "slide" ,link= "ui_options_slider_other" ,text= "ui_mm_title_other" ,size= {512,50} },
|
|
|
|
{ id= "localization" ,type= "list" ,val= 0 ,def= "eng" ,curr= {curr_localization} ,content= {{"eng"} , {"rus"}} ,no_str= true ,functor= {func_localization} },
|
|
{ id= "discord" ,type= "check" ,val= 1 ,def= true ,cmd= "discord_status" },
|
|
|
|
{ id= "line" ,type= "line" ,precondition = {debug_only} },
|
|
{ id= "important_save" ,type= "check" ,val= 1 ,def= true ,cmd= "g_important_save" },
|
|
-- { id= "autosave_timer" ,type= "check" ,val= 1 ,def= false ,functor= {func_autosave_timer} }, -- removed for custom value box below
|
|
{ id= "autosave_timer_new" ,type= "input" ,val= 0 ,def= 0, functor ={func_autosave_timer_new}},
|
|
{ id= "quicksave_cnt" ,type= "list" ,val= 2 ,def= 5 ,content= {{1} , {5} , {10} , {15} , {20}} ,no_str= true },
|
|
|
|
{ id= "line" ,type= "line" ,precondition = {debug_only} },
|
|
{ id= "debug_hud" ,type= "check" ,val= 1 ,def= false ,precondition = {debug_only} ,functor= {func_debug_hud} },
|
|
{ id= "debug_map_hud" ,type= "check" ,val= 1 ,def= false ,precondition = {debug_only} ,functor= {func_debug_map_hud} },
|
|
{ id= "debug_error" ,type= "check" ,val= 1 ,def= false ,precondition = {debug_only} },
|
|
},},
|
|
}
|
|
|
|
init_opt_coder()
|
|
end
|
|
function init_opt_coder()
|
|
------------------------------------------------------------------------
|
|
-- Auto-complete factions options for warfare
|
|
local t = {}
|
|
copy_table(t, options[5].gr[3].gr[3].gr)
|
|
options[5].gr[3].gr[4] = { id= "bandit" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[5] = { id= "csky" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[6] = { id= "army" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[7] = { id= "freedom" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[8] = { id= "dolg" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[9] = { id= "ecolog" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[10] = { id= "killer" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[11] = { id= "monolith" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[12] = { id= "renegade" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[13] = { id= "greh" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[14] = { id= "isg" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
options[5].gr[3].gr[15] = { id= "zombied" ,sh=true ,presets= {"warfare_default","warfare_yoko"}, id_gr= "warfare_faction", apply_to_all=true ,gr=t }
|
|
|
|
------------------------------------------------------------------------
|
|
-- Auto-complete options for radio music
|
|
local ltx = ini_file("plugins\\radio_zone_fm.ltx") -- File control: reading the ltx file that controls the hotkeys
|
|
local num_of_plyr = ltx:r_float_ex("trx_radio_plyr","number_of_playlists") or 2 -- Number of Music Player plylists
|
|
local radio_size = #options[2].gr[3].gr
|
|
for i=1,num_of_plyr do
|
|
radio_size = radio_size + 1
|
|
options[2].gr[3].gr[radio_size] = { id= ("playlist_name_"..i) ,type= "input" ,val= 0 ,def= {def_radio_playlist, i} }
|
|
end
|
|
|
|
------------------------------------------------------------------------
|
|
-- Coding options
|
|
local function code_option(gr, id, num)
|
|
local path
|
|
for i=1,#gr do
|
|
if allowed_type[gr[i].type] then
|
|
path = cc(id , gr[i].id)
|
|
opt_index[path] = cc(num , i)
|
|
opt_val[path] = gr[i].val
|
|
--printf("-[%s] | index: %s - type: %s", path, opt_index[path], opt_val[path])
|
|
end
|
|
end
|
|
end
|
|
|
|
local id_1, id_2, id_3
|
|
-- Level 1
|
|
for i=1,#options do
|
|
id_1 = options[i].id
|
|
if options[i].sh then
|
|
code_option(options[i].gr, id_1, i)
|
|
else
|
|
-- Level 2
|
|
for ii=1,#options[i].gr do
|
|
id_2 = options[i].gr[ii].id
|
|
if options[i].gr[ii].sh then
|
|
code_option( (options[i].gr[ii].gr), (id_1 .._opt_.. id_2), (i .._opt_.. ii) )
|
|
else
|
|
-- Level 3
|
|
for iii=1,#options[i].gr[ii].gr do
|
|
id_3 = options[i].gr[ii].gr[iii].id
|
|
if options[i].gr[ii].gr[iii].sh then
|
|
code_option( (options[i].gr[ii].gr[iii].gr), (id_1 .._opt_.. id_2 .._opt_.. id_3), (i .._opt_.. ii .._opt_.. iii) )
|
|
else
|
|
----
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Functors
|
|
------------------------------------------------------------
|
|
|
|
-- Special
|
|
function start_lighting_ui(self)
|
|
self:On_Cancel()
|
|
ui_ctrl_lighting.start()
|
|
end
|
|
|
|
-- Preconditions
|
|
function level_present()
|
|
return level.present()
|
|
end
|
|
function debug_only()
|
|
return DEV_DEBUG
|
|
end
|
|
function for_renderer(...)
|
|
local rend = {...}
|
|
local curr_rend = get_console_cmd(0, "renderer")
|
|
local result = false
|
|
for i=1,#rend do
|
|
result = result or curr_rend == rend[i]
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- Default values
|
|
function def_radio_playlist(i)
|
|
if (i == 1) then return "OST"
|
|
elseif (i == 2) then return "TRX_Special"
|
|
else return "Playlist_" .. tostring(i)
|
|
end
|
|
end
|
|
|
|
-- Contents
|
|
function cont_vid_mode()
|
|
local ratio = {
|
|
[round_idp(5/4, 1)] = "(5:4)",
|
|
[round_idp(4/3, 1)] = "(4:3)",
|
|
[round_idp(16/9, 1)] = "(16:9)",
|
|
[round_idp(16/10, 1)] = "(16:10)",
|
|
[round_idp(21/9, 1)] = "(21:9)",
|
|
[round_idp(32/9, 1)] = "(32:9)",
|
|
}
|
|
|
|
local ress = game.get_resolutions() -- get all res list from engine in one string
|
|
ress = str_explode(ress,",")
|
|
|
|
local cont = {}
|
|
for i=1,#ress do
|
|
local res = str_explode(ress[i],"x")
|
|
local w = tonumber(res[1])
|
|
local h = tonumber(res[2])
|
|
local rat = ratio[round_idp(w/h , 1)] or ""
|
|
cont[#cont + 1] = { (w.."x"..h) , (w.." x "..h.." "..rat) }
|
|
end
|
|
|
|
return cont
|
|
end
|
|
function cont_renderer()
|
|
if for_renderer("renderer_r2a","renderer_r2","renderer_r2.5") then
|
|
return {{"renderer_r2a"},{"renderer_r2"},{"renderer_r2.5"}}
|
|
else
|
|
local curr = get_console_cmd(0, "renderer")
|
|
return {{curr}}
|
|
end
|
|
end
|
|
function cont_sun_quality()
|
|
local cont = { {"st_opt_low","low"},{"st_opt_medium","medium"},{"st_opt_high","high"} }
|
|
if for_renderer("renderer_r3","renderer_r4") then
|
|
cont[#cont + 1] = {"st_opt_ultra","ultra"}
|
|
cont[#cont + 1] = {"st_opt_extreme","extreme"}
|
|
end
|
|
return cont
|
|
end
|
|
|
|
-- Functor to execute on apply
|
|
function func_screen_mode()
|
|
local val = opt_temp["video/basic/screen_mode"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "video/basic/screen_mode", 2)
|
|
end
|
|
|
|
if (val == 1) then
|
|
exec_console_cmd("rs_screenmode fullscreen")
|
|
elseif (val == 2) then
|
|
exec_console_cmd("rs_screenmode borderless")
|
|
else
|
|
exec_console_cmd("rs_screenmode windowed")
|
|
end
|
|
--[[
|
|
if val == 1 then
|
|
exec_console_cmd("rs_fullscreen on")
|
|
exec_console_cmd("rs_borderless 0")
|
|
else
|
|
exec_console_cmd("rs_fullscreen off")
|
|
exec_console_cmd("rs_borderless 1")
|
|
end
|
|
--]]
|
|
end
|
|
function func_localization()
|
|
local val = opt_temp["other/localization"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "other/localization", 0)
|
|
end
|
|
|
|
if (ini_loc:r_value("string_table","language") ~= val) then
|
|
ini_loc:w_value("string_table","language",val)
|
|
ini_loc:save()
|
|
reload_ini_sys()
|
|
game.reload_language()
|
|
|
|
if level.present() then
|
|
SendScriptCallback("on_localization_change")
|
|
end
|
|
end
|
|
end
|
|
function func_slot_hud()
|
|
if level.present() then
|
|
local val = opt_temp["video/hud/show_slots"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "video/hud/show_slots", 1)
|
|
end
|
|
|
|
if val then
|
|
item_artefact.activate_hud()
|
|
else
|
|
item_artefact.deactivate_hud()
|
|
end
|
|
end
|
|
end
|
|
function func_hardcore_ai_aim()
|
|
if level.present() then
|
|
local val = opt_temp["gameplay/general/hardcore_ai_aim"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "gameplay/general/hardcore_ai_aim", 1)
|
|
end
|
|
|
|
if val then
|
|
exec_console_cmd("ai_aim_max_angle 20.0")
|
|
exec_console_cmd("ai_aim_min_angle 17.0")
|
|
exec_console_cmd("ai_aim_min_speed 2.5")
|
|
exec_console_cmd("ai_aim_predict_time 0.28")
|
|
else
|
|
exec_console_cmd("ai_aim_max_angle 0.7854")
|
|
exec_console_cmd("ai_aim_min_angle 0.19635")
|
|
exec_console_cmd("ai_aim_min_speed 0.24")
|
|
exec_console_cmd("ai_aim_predict_time 0.40")
|
|
end
|
|
end
|
|
end
|
|
|
|
-- unused
|
|
-- function func_autosave_timer()
|
|
-- if (level.present() and game_autosave) then
|
|
-- local val = opt_temp["other/autosave_timer"]
|
|
-- if (val == nil) then
|
|
-- val = axr_main.config:r_value(opt_section, "other/autosave_timer", 1)
|
|
-- end
|
|
|
|
-- if val then
|
|
-- game_autosave.activate_feature()
|
|
-- else
|
|
-- game_autosave.deactivate_feature()
|
|
-- end
|
|
-- end
|
|
-- end
|
|
|
|
function func_autosave_timer_new()
|
|
game_autosave_new.option_updated()
|
|
end
|
|
|
|
function func_hud_minimap()
|
|
if (level.present()) then
|
|
local val = opt_temp["video/hud/show_minimap"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "video/hud/show_minimap", 0)
|
|
end
|
|
|
|
local maingameui = ActorMenu.get_maingame()
|
|
if (maingameui and maingameui.UIZoneMap) then
|
|
maingameui.UIZoneMap.disabled = not val
|
|
maingameui.UIMotionIcon:Show(maingameui.UIZoneMap.disabled == false)
|
|
end
|
|
end
|
|
end
|
|
function func_hud_autohide_bar()
|
|
if (level.present()) then
|
|
local val = opt_temp["video/hud/autohide_stamina_bar"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "video/hud/autohide_stamina_bar", 1)
|
|
end
|
|
|
|
actor_effects.toggle_hud_autohide(val)
|
|
end
|
|
end
|
|
function func_player_name()
|
|
local se_actor = alife():actor()
|
|
if se_actor then
|
|
local curr_name = se_actor:character_name()
|
|
local new_name = opt_temp["gameplay/general/player_name"] or axr_main.config:r_value(opt_section, "gameplay/general/player_name", 0)
|
|
if new_name and (new_name ~= "") and (new_name ~= curr_name) then
|
|
se_actor:set_character_name(new_name)
|
|
printf("- Changed player name from (%s) to (%s)", curr_name, new_name)
|
|
end
|
|
end
|
|
end
|
|
function func_gameplay_diff(fac)
|
|
if (opt_temp["gameplay/gameplay_diff/"..fac] ~= nil) then
|
|
game_difficulties.set_game_factor(fac, opt_temp["gameplay/gameplay_diff/"..fac])
|
|
end
|
|
end
|
|
function func_economy_diff(fac)
|
|
if (opt_temp["gameplay/economy_diff/"..fac] ~= nil) then
|
|
game_difficulties.set_eco_factor(fac, opt_temp["gameplay/economy_diff/"..fac])
|
|
end
|
|
end
|
|
function func_debug_hud()
|
|
if (level.present() and xrs_debug_tools) then
|
|
local val = opt_temp["other/debug_hud"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "other/debug_hud", 1)
|
|
end
|
|
|
|
if val then
|
|
xrs_debug_tools.activate_feature()
|
|
else
|
|
xrs_debug_tools.deactivate_feature()
|
|
end
|
|
end
|
|
end
|
|
function func_debug_map_hud()
|
|
if (level.present() and ui_map_debug_ex) then
|
|
local val = opt_temp["other/debug_map_hud"]
|
|
if (val == nil) then
|
|
val = axr_main.config:r_value(opt_section, "other/debug_map_hud", 1)
|
|
end
|
|
|
|
if val then
|
|
ui_map_debug_ex.activate_feature()
|
|
else
|
|
ui_map_debug_ex.deactivate_feature()
|
|
end
|
|
end
|
|
end
|
|
function func_crosshair_clr(n)
|
|
local val = opt_temp["video/hud/crosshair_clr_" .. n]
|
|
if (val == nil) then
|
|
return
|
|
end
|
|
|
|
local curr = get_console_cmd(nil, "g_crosshair_color")
|
|
curr = tostring(curr)
|
|
local r,g,b,a = string.match(curr,"(%d+), (%d+), (%d+), (%d+)")
|
|
if n == "a" then
|
|
a = val
|
|
elseif n == "r" then
|
|
r = val
|
|
elseif n == "g" then
|
|
g = val
|
|
elseif n == "b" then
|
|
b = val
|
|
end
|
|
exec_console_cmd( strformat("g_crosshair_color (%s, %s, %s, %s)",r,g,b,a) )
|
|
end
|
|
|
|
-- Current value override
|
|
function curr_renderer()
|
|
return get_console_cmd(0, "renderer")
|
|
end
|
|
function curr_screen_mode()
|
|
local sm = get_console_cmd(0, "rs_screenmode")
|
|
if (sm == "fullscreen") then
|
|
return 1
|
|
elseif (sm == "borderless") then
|
|
return 2
|
|
end
|
|
return 3
|
|
end
|
|
function curr_player_name()
|
|
return alife():actor():character_name()
|
|
end
|
|
function curr_economy(fact)
|
|
local value = game_difficulties.get_eco_factor(fact)
|
|
return value
|
|
end
|
|
function curr_gameplay(fact)
|
|
local value = game_difficulties.get_game_factor(fact)
|
|
return value
|
|
end
|
|
function curr_localization()
|
|
local val = ini_loc:r_value("string_table","language") or axr_main.config:r_value(opt_section, "other/localization", 0)
|
|
return val
|
|
end
|
|
function curr_crosshair_clr(n)
|
|
local curr = get_console_cmd(nil, "g_crosshair_color")
|
|
curr = tostring(curr)
|
|
local r,g,b,a = string.match(curr,"(%d+), (%d+), (%d+), (%d+)")
|
|
if n == "a" then
|
|
return tonumber(a)
|
|
elseif n == "r" then
|
|
return tonumber(r)
|
|
elseif n == "g" then
|
|
return tonumber(g)
|
|
elseif n == "b" then
|
|
return tonumber(b)
|
|
end
|
|
return 255
|
|
end
|
|
|
|
-- Utilities
|
|
function is_int(num)
|
|
return (m_floor(num) == num)
|
|
end
|
|
function exec(func,...)
|
|
if (not func) then
|
|
return false
|
|
end
|
|
return func(...)
|
|
end
|
|
function str_opt_explode(id, by_num)
|
|
local nums = by_num and opt_index[id] or id
|
|
local t = nums and str_explode(nums, _opt_) or {}
|
|
if by_num then
|
|
for i=1,#t do
|
|
t[i] = tonumber(t[i])
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
function get_opt_table(id)
|
|
local t = str_opt_explode(id, true)
|
|
if #t == 0 then
|
|
return {}
|
|
end
|
|
|
|
if #t == 1 then
|
|
return options[t[1]]
|
|
elseif #t == 2 then
|
|
return options[t[1]].gr[t[2]]
|
|
elseif #t == 3 then
|
|
return options[t[1]].gr[t[2]].gr[t[3]]
|
|
elseif #t == 4 then
|
|
return options[t[1]].gr[t[2]].gr[t[3]].gr[t[4]]
|
|
end
|
|
end
|
|
function check_opt_table(id)
|
|
local t = str_opt_explode(id, true)
|
|
return #t > 0
|
|
end
|
|
|
|
--------------------
|
|
function get(id)
|
|
if (#options == 0) then
|
|
init_opt_base()
|
|
end
|
|
|
|
local value = axr_main.config:r_value(opt_section, id, opt_val[id])
|
|
if (value ~= nil) then
|
|
--print_dbg("/Got axr_option [%s] = %s", id, value)
|
|
return value
|
|
end
|
|
|
|
-- Write in axr_main if it doesn't exist
|
|
local v = get_opt_table(id)
|
|
if v.cmd then
|
|
if v.val == 0 then
|
|
value = get_console_cmd(0, v.cmd)
|
|
elseif v.val == 1 then
|
|
value = get_console_cmd(1, v.cmd)
|
|
elseif v.val == 2 then
|
|
value = get_console_cmd(0, v.cmd) --get_console_cmd(2, v.cmd)
|
|
value = tonumber(value)
|
|
if v.min and v.max then
|
|
value = clamp(value, v.min, v.max)
|
|
end
|
|
value = round_idp(value, v.prec or precision)
|
|
end
|
|
elseif (type(v.def) == "table") then
|
|
value = exec(unpack(v.def))
|
|
axr_main.config:w_value(opt_section, id, value)
|
|
axr_main.config:save()
|
|
else
|
|
value = v.def
|
|
axr_main.config:w_value(opt_section, id, value)
|
|
axr_main.config:save()
|
|
end
|
|
|
|
--print_dbg("/Got option [%s] = %s", id, value)
|
|
if (value == nil) then
|
|
printe("!Found nil option value [%s]", id)
|
|
end
|
|
|
|
return value
|
|
end
|
|
|
|
function set(id, value)
|
|
axr_main.config:w_value(opt_section, id, value)
|
|
axr_main.config:save()
|
|
end
|
|
--------------------
|
|
|
|
|
|
--===========================================================
|
|
--//////////////////////// OPTIONS //////////////////////////
|
|
--===========================================================
|
|
|
|
class "UIOptions" (CUIScriptWnd)
|
|
|
|
function UIOptions:__init() super()
|
|
self.last_tree = {}
|
|
self.last_path = nil
|
|
self.last_curr_tree = nil
|
|
|
|
self._Cap = {}
|
|
self._Check = {}
|
|
self._List = {}
|
|
self._Input = {}
|
|
self._Track = {}
|
|
self._Radio = {}
|
|
|
|
-- Prepare the options table
|
|
if (#options == 0) then
|
|
init_opt_base()
|
|
end
|
|
|
|
self:InitControls()
|
|
self:InitCallBacks()
|
|
|
|
self:Reset()
|
|
end
|
|
|
|
function UIOptions:__finalize()
|
|
end
|
|
|
|
function UIOptions:InitControls()
|
|
self:SetWndRect (Frect():set(0,0,1024,768))
|
|
self:Enable (true)
|
|
|
|
self.xml = CScriptXmlInit()
|
|
local xml = self.xml
|
|
xml:ParseFile ("ui_options.xml")
|
|
|
|
self.background = xml:InitStatic("background", self)
|
|
self.dialog = xml:InitStatic("main", self)
|
|
|
|
xml:InitStatic("main:frame", self.dialog)
|
|
|
|
-- Buttons
|
|
self.btn_accept = xml:Init3tButton("main:btn_accept", self.dialog)
|
|
self:Register(self.btn_accept, "btn_accept")
|
|
|
|
self.btn_reset = xml:Init3tButton("main:btn_reset", self.dialog)
|
|
self:Register(self.btn_reset, "btn_reset")
|
|
|
|
self.btn_default = xml:Init3tButton("main:btn_default", self.dialog)
|
|
self:Register(self.btn_default, "btn_default")
|
|
|
|
self.btn_cancel = xml:Init3tButton("main:btn_cancel", self.dialog)
|
|
self:Register(self.btn_cancel, "btn_cancel")
|
|
|
|
-- Pending text
|
|
--xml:InitFrame("main:notify_frame", self.dialog)
|
|
self.pending = xml:InitTextWnd("main:notify", self.dialog)
|
|
|
|
-- Options lists
|
|
self.tree = {}
|
|
self.bl = {}
|
|
|
|
-- Options showcase
|
|
self.scroll_opt = xml:InitScrollView("main:scroll", self.dialog)
|
|
|
|
-- Presets
|
|
self.preset_cap = xml:InitStatic("main:cap_preset", self.dialog)
|
|
self.preset = xml:InitComboBox("main:preset",self.dialog)
|
|
self:Register(self.preset, "preset")
|
|
self.preset:Show(false)
|
|
self.preset_cap:Show(false)
|
|
|
|
-- Message box
|
|
self.message_box = CUIMessageBoxEx()
|
|
self:Register (self.message_box, "mb")
|
|
|
|
-- Hint Window
|
|
self.hint_wnd = utils_ui.UIHint(self)
|
|
end
|
|
|
|
function UIOptions:InitCallBacks()
|
|
self:AddCallback("btn_accept", ui_events.BUTTON_CLICKED, self.OnButton_Accept, self)
|
|
self:AddCallback("btn_reset", ui_events.BUTTON_CLICKED, self.OnButton_Reset, self)
|
|
self:AddCallback("btn_default", ui_events.BUTTON_CLICKED, self.OnButton_Default, self)
|
|
self:AddCallback("btn_cancel", ui_events.BUTTON_CLICKED, self.OnButton_Cancel, self)
|
|
|
|
self:AddCallback("preset", ui_events.LIST_ITEM_SELECT, self.Callback_Preset, self)
|
|
|
|
self:AddCallback("mb", ui_events.MESSAGE_BOX_YES_CLICKED, self.On_Discard, self)
|
|
--self:AddCallback("mb", ui_events.MESSAGE_BOX_NO_CLICKED, self.On_Discard,self)
|
|
end
|
|
|
|
function UIOptions:Update()
|
|
CUIScriptWnd.Update(self)
|
|
|
|
-- Show hint on hover
|
|
for id,ctrl in pairs(self._Cap) do
|
|
if ctrl:IsCursorOverWindow() then
|
|
local str = opt_str .. id .. "_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. TODO: add callback support for CUITrackBar in engine, this is just silly
|
|
for id,e in pairs(self._Track) do
|
|
if e.ctrl:IsCursorOverWindow() then
|
|
local v = self:GetOption(id)
|
|
local value = round_idp(e.ctrl:GetFValue(), v.prec or precision)
|
|
if (value ~= e.value) then
|
|
e.value = value
|
|
self:Callback_Track(e.txt, e.path, e.opt, v, value)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function UIOptions:Reset()
|
|
-- Clear all trees
|
|
for i=1,3 do
|
|
if self.tree[i] then
|
|
if type(self.tree[i]) == table then
|
|
for j=1,#self.tree[i] do
|
|
self.tree[i][j]:Clear()
|
|
end
|
|
else
|
|
self.tree[i]:Clear()
|
|
end
|
|
end
|
|
end
|
|
|
|
self:Register_Tree(1, "", options, 1)
|
|
end
|
|
|
|
function UIOptions:Reset_opt(curr_tree, path, flags)
|
|
flags = flags or {}
|
|
local xml = self.xml
|
|
self.scroll_opt:Clear()
|
|
|
|
-- If options tree has a precondition that must be met, don't show it if it returns false
|
|
if curr_tree.precondition and (not exec(unpack(curr_tree.precondition))) then
|
|
if curr_tree.output then
|
|
local _txt = xml:InitTextWnd("elements:block", nil)
|
|
_txt:SetText( game.translate_string(curr_tree.output) )
|
|
|
|
self.scroll_opt:AddWindow(_txt, true)
|
|
_txt:SetAutoDelete(false)
|
|
end
|
|
else
|
|
|
|
-- Keybinds
|
|
if (self.dlg_controls == nil) then
|
|
self.dlg_controls = opt_controls()
|
|
self.dlg_controls:InitControls(0,0, xml, self)
|
|
self.dlg_controls:Show (false)
|
|
self.dialog:AttachChild (self.dlg_controls)
|
|
xml:InitWindow ("tab_size", 0, self.dlg_controls)
|
|
|
|
local opt = COptionsManager()
|
|
|
|
opt:SetCurrentValues("key_binding")
|
|
opt:SaveBackupValues("key_binding")
|
|
end
|
|
if (path == "control/keybind") then
|
|
self.dlg_controls:Show(true)
|
|
self.Keybinds_Shown = true
|
|
else
|
|
self.dlg_controls:Show(false)
|
|
end
|
|
|
|
-- Presets
|
|
self:Register_Preset(curr_tree)
|
|
|
|
if curr_tree.apply_to_all and curr_tree.id_gr then
|
|
flags.apply_to_all = true
|
|
flags.group = curr_tree.id_gr
|
|
else
|
|
flags.apply_to_all = nil
|
|
end
|
|
|
|
empty_table(self._Cap)
|
|
empty_table(self._Check)
|
|
empty_table(self._List)
|
|
empty_table(self._Input)
|
|
empty_table(self._Track)
|
|
empty_table(self._Radio)
|
|
|
|
for i=1,#curr_tree.gr do
|
|
-- Check preconditions
|
|
local to_hide = curr_tree.gr[i].precondition and (not exec(unpack(curr_tree.gr[i].precondition)))
|
|
for j=1,10 do -- support for 10 preconditions
|
|
if (not curr_tree.gr[i]["precondition_" .. j]) then
|
|
break
|
|
elseif (not exec(unpack(curr_tree.gr[i]["precondition_" .. j]))) then
|
|
to_hide = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if (not to_hide) then
|
|
local opt = curr_tree.gr[i].id
|
|
local v = curr_tree.gr[i]
|
|
|
|
local _st = xml:InitStatic("main:st", nil)
|
|
local _h = 0
|
|
|
|
----------- Support
|
|
if (v.type == "line") then
|
|
_h = self:Register_Line(xml, _st)
|
|
|
|
elseif (v.type == "image") then
|
|
_h = self:Register_Image(xml, _st, v)
|
|
|
|
elseif (v.type == "slide") then
|
|
_h = self:Register_Slide(xml, _st, v)
|
|
|
|
elseif (v.type == "title") then
|
|
_h = self:Register_Title(xml, _st, v)
|
|
|
|
elseif (v.type == "desc") then
|
|
_h = self:Register_Desc(xml, _st, v)
|
|
|
|
----------- Option
|
|
elseif (v.type == "check") then
|
|
_h = self:Register_Check(xml, _st, path, opt, v, flags)
|
|
|
|
elseif (v.type == "button") then
|
|
_h = self:Register_Button(xml, _st, path, opt, v, flags)
|
|
|
|
elseif (v.type == "list") then
|
|
_h = self:Register_List(xml, _st, path, opt, v, flags)
|
|
|
|
elseif (v.type == "input") then
|
|
_h = self:Register_Input(xml, _st, path, opt, v, flags)
|
|
|
|
elseif (v.type == "track") then
|
|
_h = self:Register_Track(xml, _st, path, opt, v, flags)
|
|
|
|
elseif (v.type == "radio_h") then
|
|
_h = self:Register_Radio(xml, _st, path, opt, v, true, flags)
|
|
|
|
elseif (v.type == "radio_v") then
|
|
_h = self:Register_Radio(xml, _st, path, opt, v, false, flags)
|
|
|
|
end
|
|
|
|
_st:SetWndSize(vector2():set(_st:GetWidth(), _h + 10))
|
|
self.scroll_opt:AddWindow(_st, true)
|
|
_st:SetAutoDelete(true)
|
|
end
|
|
end
|
|
if self.Save_AXR then
|
|
self.Save_AXR = false
|
|
axr_main.config:save()
|
|
end
|
|
end
|
|
end
|
|
|
|
function UIOptions:Reset_last_opt()
|
|
Register_UI("UIOptions")
|
|
|
|
if self.last_curr_tree and self.last_path then
|
|
self:Reset_opt(self.last_curr_tree, self.last_path)
|
|
self:UpdatePending()
|
|
end
|
|
end
|
|
|
|
------------------------------------------------------------
|
|
-- Elements
|
|
------------------------------------------------------------
|
|
function UIOptions:Register_Cap(xml, handler, id, hint)
|
|
id = s_gsub(id, _opt_, "_")
|
|
self._Cap[id] = xml:InitStatic("elements:cap",handler)
|
|
self._Cap[id]:TextControl():SetText( game.translate_string(opt_str .. (hint or id)) )
|
|
return self._Cap[id]:GetHeight()
|
|
end
|
|
|
|
function UIOptions:Register_Line(xml, handler)
|
|
local line = xml:InitStatic("elements:line",handler)
|
|
return (line:GetHeight() + 10)
|
|
end
|
|
|
|
function UIOptions:Register_Image(xml, handler, v)
|
|
local pic = xml:InitStatic("elements:image",handler)
|
|
if v.link then
|
|
if (v.pos) then
|
|
local pos = pic:GetWndPos()
|
|
pic:SetWndPos(vector2():set( pos.x + v.pos[1] , pos.y + v.pos[2] ))
|
|
end
|
|
if (v.size) then
|
|
pic:SetWndSize(vector2():set( v.size[1] , v.size[2] ))
|
|
end
|
|
pic:InitTexture(v.link)
|
|
pic:SetStretchTexture(v.stretch and true or false)
|
|
end
|
|
return pic:GetHeight()
|
|
end
|
|
|
|
function UIOptions:Register_Slide(xml, handler, v)
|
|
local frame = xml:InitStatic("elements:slide", handler)
|
|
local _pos = frame:GetWndPos()
|
|
frame:SetWndPos(vector2():set( _pos.x , _pos.y + (v.spacing or 20) ))
|
|
|
|
local pic = xml:InitStatic("elements:slide:pic", frame)
|
|
if v.link then
|
|
pic:InitTexture(v.link)
|
|
pic:SetStretchTexture(true)
|
|
if (v.pos) then
|
|
local pos = pic:GetWndPos()
|
|
pic:SetWndPos(vector2():set( pos.x + v.pos[1] , pos.y + v.pos[2] ))
|
|
end
|
|
if (v.size) then
|
|
pic:SetWndSize(vector2():set( v.size[1] * width_factor , v.size[2] ))
|
|
end
|
|
pic:InitTexture(v.link)
|
|
end
|
|
|
|
local txt = xml:InitTextWnd("elements:slide:txt", frame)
|
|
if v.text then
|
|
txt:SetText( game.translate_string(v.text) )
|
|
end
|
|
|
|
xml:InitStatic("elements:slide:line_1", frame)
|
|
xml:InitStatic("elements:slide:line_2", frame)
|
|
|
|
return (pic:GetHeight() + 20)
|
|
end
|
|
|
|
function UIOptions:Register_Title(xml, handler, v)
|
|
local title = xml:InitTextWnd("elements:title_" .. (v.align or "l"), handler)
|
|
title:SetText( game.translate_string(v.text) )
|
|
title:AdjustHeightToText()
|
|
title:SetWndSize(vector2():set(title:GetWidth(), title:GetHeight() + 20))
|
|
if v.clr and v.clr[4] then
|
|
title:SetTextColor( GetARGB(v.clr[1], v.clr[2], v.clr[3], v.clr[4]) )
|
|
end
|
|
return title:GetHeight()
|
|
end
|
|
|
|
function UIOptions:Register_Desc(xml, handler, v)
|
|
local desc = xml:InitTextWnd("elements:desc", handler)
|
|
desc:SetText( game.translate_string(v.text) )
|
|
desc:AdjustHeightToText()
|
|
desc:SetWndSize(vector2():set(desc:GetWidth(), desc:GetHeight() + 20))
|
|
if v.clr and v.clr[4] then
|
|
desc:SetTextColor( GetARGB(v.clr[1], v.clr[2], v.clr[3], v.clr[4]) )
|
|
end
|
|
return desc:GetHeight()
|
|
end
|
|
|
|
function UIOptions:Register_Check(xml, handler, path, opt, v, flags)
|
|
local id = cc(path , opt)
|
|
|
|
-- Caption
|
|
local h = self:Register_Cap(xml, handler, id, v.hint)
|
|
|
|
-- Apply to all button
|
|
if flags.apply_to_all and flags.group then
|
|
self:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
end
|
|
|
|
-- Create control
|
|
local ctrl = xml:InitCheck("elements:check",handler)
|
|
if (ctrl:GetHeight() > h) then
|
|
h = ctrl:GetHeight()
|
|
end
|
|
|
|
-- Get values
|
|
local value = self:GetValue(path, opt, v, flags)
|
|
ctrl:SetCheck(value)
|
|
|
|
-- Register
|
|
local id_ctrl = self:Stacker(path, opt, v)
|
|
|
|
self:Register(ctrl, id_ctrl)
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_Check(ctrl, path, opt, v)
|
|
end
|
|
self:AddCallback(id_ctrl, ui_events.BUTTON_CLICKED, _wrapper, self)
|
|
|
|
return h
|
|
end
|
|
function UIOptions:Callback_Check(ctrl, path, opt, v)
|
|
local value = ctrl:GetCheck()
|
|
self:CacheValue(path, opt, value, v)
|
|
end
|
|
|
|
function UIOptions:Register_Button(xml, handler, path, opt, v, flags)
|
|
local id = cc(path , opt)
|
|
|
|
|
|
|
|
--[[ Apply to all button
|
|
if flags.apply_to_all and flags.group then
|
|
self:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
end
|
|
--]]
|
|
|
|
xml:InitFrame("elements:frame_button", handler)
|
|
|
|
-- Create control
|
|
local ctrl = xml:Init3tButton("elements:btn_button", handler)
|
|
local h = ctrl:GetHeight()
|
|
|
|
-- Caption
|
|
local id_cap = s_gsub(id, _opt_, "_")
|
|
self._Cap[id_cap] = xml:InitStatic("elements:cap_button",handler)
|
|
self._Cap[id_cap]:TextControl():SetText( game.translate_string(opt_str .. (v.hint or id_cap)) )
|
|
if (self._Cap[id_cap]:GetHeight() > h) then
|
|
h = self._Cap[id_cap]:GetHeight()
|
|
end
|
|
|
|
-- Register
|
|
local id_ctrl = self:Stacker(path, opt, v)
|
|
|
|
self:Register(ctrl, id_ctrl)
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_Button(ctrl, path, opt, v)
|
|
end
|
|
self:AddCallback(id_ctrl, ui_events.BUTTON_CLICKED, _wrapper, self)
|
|
|
|
return h
|
|
end
|
|
function UIOptions:Callback_Button(ctrl, path, opt, v)
|
|
if v.functor_ui then
|
|
local id = cc(path , opt)
|
|
print_dbg("- Executing functor_ui of [%s]",id)
|
|
exec(unpack(v.functor_ui),self)
|
|
end
|
|
if v.functor then
|
|
local id = cc(path , opt)
|
|
print_dbg("- Executing functor of [%s]",id)
|
|
exec(unpack(v.functor))
|
|
end
|
|
end
|
|
|
|
function UIOptions:Register_List(xml, handler, path, opt, v, flags)
|
|
local id = cc(path , opt)
|
|
|
|
-- Caption
|
|
local h = self:Register_Cap(xml, handler, id, v.hint)
|
|
|
|
-- Apply to all button
|
|
if flags.apply_to_all and flags.group then
|
|
self:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
end
|
|
|
|
-- Create control
|
|
local ctrl = xml:InitComboBox("elements:list",handler)
|
|
if (ctrl:GetHeight() > h) then
|
|
--h = ctrl:GetHeight()
|
|
end
|
|
|
|
-- Get values
|
|
local idx
|
|
local value = self:GetValue(path, opt, v, flags)
|
|
local content = self:GetContent(path, opt, v)
|
|
|
|
-- Setup
|
|
for i=1,#content do
|
|
local str_2 = content[i][2] or tostring(content[i][1])
|
|
local str = v.no_str and str_2 or game.translate_string(opt_str_lst .. str_2)
|
|
ctrl:AddItem( game.translate_string(str), i)
|
|
|
|
if content[i][1] == value then
|
|
idx = i
|
|
end
|
|
end
|
|
idx = idx or 1
|
|
|
|
local str_2 = content[idx][2] or tostring(content[idx][1])
|
|
local str = v.no_str and str_2 or game.translate_string(opt_str_lst .. str_2)
|
|
ctrl:enable_id( idx )
|
|
ctrl:SetText( game.translate_string(str) )
|
|
|
|
-- Register
|
|
local id_ctrl = self:Stacker(path, opt, v)
|
|
|
|
self:Register(ctrl, id_ctrl)
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_List(ctrl, path, opt, v)
|
|
end
|
|
self:AddCallback(id_ctrl, ui_events.LIST_ITEM_SELECT, _wrapper, self)
|
|
|
|
return h
|
|
end
|
|
function UIOptions:Callback_List(ctrl, path, opt, v)
|
|
local i = ctrl:CurrentID()
|
|
local content = self:GetContent(path, opt, v)
|
|
self:CacheValue(path, opt, content[i][1], v)
|
|
end
|
|
|
|
function UIOptions:Register_Input(xml, handler, path, opt, v, flags)
|
|
local id = cc(path , opt)
|
|
|
|
-- Caption
|
|
local h = self:Register_Cap(xml, handler, id, v.hint)
|
|
|
|
-- Apply to all button
|
|
if flags.apply_to_all and flags.group then
|
|
self:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
end
|
|
|
|
-- Create control
|
|
local ctrl = xml:InitEditBox("elements:input",handler)
|
|
if (ctrl:GetHeight() > h) then
|
|
h = ctrl:GetHeight()
|
|
end
|
|
|
|
-- Get values
|
|
local value = self:GetValue(path, opt, v, flags)
|
|
ctrl:SetText(value)
|
|
|
|
-- Register
|
|
local id_ctrl = self:Stacker(path, opt, v)
|
|
|
|
self:Register(ctrl, id_ctrl)
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_Input(ctrl, path, opt, v)
|
|
end
|
|
self:AddCallback(id_ctrl, ui_events.EDIT_TEXT_COMMIT, _wrapper, self)
|
|
|
|
return h
|
|
end
|
|
function UIOptions:Callback_Input(ctrl, path, opt, v)
|
|
local value = ctrl:GetText()
|
|
if not (value and value ~= "") then
|
|
ctrl:SetText( self:GetCurrentValue(path, opt, v) or self:GetDefaultValue(path, opt, v) )
|
|
return
|
|
end
|
|
|
|
if (v.val == 1) then
|
|
value = tonumber(value)
|
|
if (not value) then
|
|
ctrl:SetText( self:GetCurrentValue(path, opt, v) or self:GetDefaultValue(path, opt, v) )
|
|
return
|
|
end
|
|
value = clamp(value, v.min, v.max)
|
|
end
|
|
|
|
self:CacheValue(path, opt, value, v)
|
|
ctrl:SetText(value)
|
|
end
|
|
|
|
function UIOptions:Register_Track(xml, handler, path, opt, v, flags)
|
|
local id = cc(path , opt)
|
|
|
|
-- Caption
|
|
local h = self:Register_Cap(xml, handler, id, v.hint)
|
|
|
|
-- Apply to all button
|
|
if flags.apply_to_all and flags.group then
|
|
self:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
end
|
|
|
|
-- Create control
|
|
self._Track[id] = {}
|
|
self._Track[id].ctrl = xml:InitTrackBar("elements:track",handler)
|
|
self._Track[id].path = path
|
|
self._Track[id].opt = opt
|
|
if (self._Track[id].ctrl:GetHeight() > h) then
|
|
h = self._Track[id].ctrl:GetHeight()
|
|
end
|
|
|
|
self._Track[id].txt = xml:InitTextWnd("elements:track_value",handler)
|
|
|
|
-- Get values
|
|
local value = self:GetValue(path, opt, v, flags)
|
|
value = clamp(value, v.min, v.max)
|
|
value = round_idp(value, v.prec or precision)
|
|
|
|
local int = false --is_int(value) and is_int(v.step) and is_int(v.min) and is_int(v.max)
|
|
self._Track[id].value = value -- temp
|
|
self._Track[id].ctrl:SetInvert(v.invert and true or false)
|
|
self._Track[id].ctrl:SetStep(v.step)
|
|
if int then
|
|
self._Track[id].ctrl:SetOptIBounds(v.min, v.max)
|
|
self._Track[id].ctrl:SetIValue(value)
|
|
else
|
|
self._Track[id].ctrl:SetOptFBounds(v.min, v.max)
|
|
self._Track[id].ctrl:SetFValue(value)
|
|
end
|
|
if (not v.no_str) then
|
|
self._Track[id].txt:SetText(value)
|
|
end
|
|
|
|
return h
|
|
end
|
|
function UIOptions:Callback_Track(ctrl, path, opt, v, value)
|
|
if (not v.no_str) then
|
|
ctrl:SetText(value)
|
|
end
|
|
self:CacheValue(path, opt, value, v)
|
|
end
|
|
|
|
function UIOptions:Register_Radio(xml, handler, path, opt, v, typ, flags)
|
|
local id = cc(path , opt)
|
|
|
|
-- Caption
|
|
local h = self:Register_Cap(xml, handler, id, v.hint)
|
|
|
|
-- Apply to all button
|
|
if flags.apply_to_all and flags.group then
|
|
self:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
end
|
|
|
|
-- Determine type
|
|
local str = typ and "horz" or "vert"
|
|
local content = self:GetContent(path, opt, v)
|
|
local num = #content
|
|
if num > 8 and (not v.force_horz) then
|
|
typ = false
|
|
str = "vert"
|
|
end
|
|
|
|
-- Create control
|
|
local frame = xml:InitStatic("elements:radio_" .. str, handler)
|
|
local ctrl = {}
|
|
local txt
|
|
local offset = typ and m_floor(frame:GetWidth()/num) or 30
|
|
local h_factor = typ and 1 or 0
|
|
local v_factor = typ and 0 or 1
|
|
local h1, h2 = 0, 0
|
|
--printf("offset: %s - h_factor: %s - v_factor: %s - num: %s", offset, h_factor, v_factor, num)
|
|
for i=1,num do
|
|
|
|
-- Buttons
|
|
ctrl[i] = xml:InitCheck("elements:radio_" .. str .. ":btn", frame)
|
|
local pos = ctrl[i]:GetWndPos()
|
|
h1 = (h1 * v_factor) + ctrl[i]:GetHeight()
|
|
ctrl[i]:SetWndPos(vector2():set( pos.x + ((i-1) * offset * h_factor) , pos.y + ((i-1) * offset * v_factor) ))
|
|
|
|
-- Text
|
|
txt = xml:InitTextWnd("elements:radio_" .. str .. ":txt", frame)
|
|
local pos2 = txt:GetWndPos()
|
|
h2 = h_factor * txt:GetHeight()
|
|
txt:SetWndPos(vector2():set( pos2.x + ((i-1) * offset * h_factor) , pos2.y - (v_factor * 30) + ((i-1) * offset * v_factor) ))
|
|
local str_2 = content[i][2] or tostring(content[i][1])
|
|
local str = v.no_str and game.translate_string(str_2) or game.translate_string(opt_str_lst .. str_2)
|
|
txt:SetText( str )
|
|
|
|
if (h1 + h2 > h) then
|
|
h = h1 + h2
|
|
end
|
|
end
|
|
|
|
-- Get values
|
|
local value = self:GetValue(path, opt, v, flags)
|
|
|
|
local id_ctrl = self:Stacker(path, opt, v)
|
|
for i=1,num do
|
|
if (content[i][1] == value) then
|
|
ctrl[i]:SetCheck(true)
|
|
else
|
|
ctrl[i]:SetCheck(false)
|
|
end
|
|
|
|
-- Register
|
|
self:Register(ctrl[i], id_ctrl .. i)
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_Radio(ctrl, path, opt, v, i)
|
|
end
|
|
self:AddCallback(id_ctrl .. i, ui_events.BUTTON_CLICKED, _wrapper, self)
|
|
end
|
|
|
|
return h
|
|
end
|
|
function UIOptions:Callback_Radio(ctrl, path, opt, v, n)
|
|
local value = ctrl[n]:GetCheck()
|
|
--printf("n = %s", n)
|
|
if value then
|
|
for i=1,#ctrl do
|
|
if i ~= n then
|
|
ctrl[i]:SetCheck(false)
|
|
end
|
|
end
|
|
|
|
local content = self:GetContent(path, opt, v)
|
|
self:CacheValue(path, opt, content[n][1], v)
|
|
else
|
|
ctrl[n]:SetCheck(true)
|
|
end
|
|
end
|
|
|
|
function UIOptions:Register_BtnAll(xml, handler, path, opt, v, flags)
|
|
local ctrl = xml:Init3tButton("elements:btn_all",handler)
|
|
xml:InitStatic("elements:cap_all",handler)
|
|
|
|
local id_ctrl = self:Stacker(path, opt, v)
|
|
|
|
self:Register(ctrl, id_ctrl)
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_BtnAll(ctrl, path, opt, v, flags)
|
|
end
|
|
self:AddCallback(id_ctrl, ui_events.BUTTON_CLICKED, _wrapper, self)
|
|
end
|
|
function UIOptions:Callback_BtnAll(ctrl, path, opt, v, flags)
|
|
local id = cc(path , opt)
|
|
local group = flags.group
|
|
local value = self:GetValue(path, opt, v, flags)
|
|
|
|
-- Set same value for identical options of same group
|
|
local function set_in_group(p, group, path, opt, value)
|
|
print_dbg("~set_in_group | current path: %s - target opt: %s", path, opt)
|
|
for i=1,#p do
|
|
local path_ext = path and (path ~= "") and cc(path , p[i].id) or p[i].id
|
|
if p[i].sh then
|
|
print_dbg("~set_in_group | current path: %s - target opt: %s", path_ext, opt)
|
|
if (p[i].id_gr == group) then
|
|
local gr = p[i].gr
|
|
for j=1,#gr do
|
|
if gr[j].id == opt then
|
|
local id_ext = cc(path_ext , opt)
|
|
if check_opt_table(id_ext) then
|
|
print_dbg("-set_in_group | Found match: %s", id_ext)
|
|
self:CacheValue(path_ext, opt, value, gr[j])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
set_in_group(p[i].gr, group, path_ext, opt, value)
|
|
end
|
|
end
|
|
end
|
|
set_in_group(options, group, "", opt, value)
|
|
end
|
|
|
|
function UIOptions:Register_Preset(ct)
|
|
if ct.presets then
|
|
self.preset:ClearList()
|
|
--
|
|
for i=1,#ct.presets do
|
|
self.preset:AddItem( game.translate_string(opt_str_prst .. ct.presets[i]), i)
|
|
end
|
|
if (ct.curr_preset) then
|
|
self.preset:SetText( game.translate_string(opt_str_prst .. ct.curr_preset) )
|
|
end
|
|
self.preset:Show(true)
|
|
self.preset_cap:Show(true)
|
|
else
|
|
self.preset:ClearList()
|
|
self.preset:Show(false)
|
|
self.preset_cap:Show(false)
|
|
end
|
|
end
|
|
function UIOptions:Callback_Preset()
|
|
if not (self.last_curr_tree and self.last_path) then
|
|
return
|
|
end
|
|
|
|
local txt = self.preset:GetText()
|
|
if not (txt and txt ~= "") then
|
|
return
|
|
end
|
|
|
|
-- Retrieve the preset section
|
|
local pres
|
|
local presets = self.last_curr_tree.presets
|
|
for i=1,#presets do
|
|
if game.translate_string(opt_str_prst .. presets[i]) == txt then
|
|
pres = presets[i]
|
|
break
|
|
end
|
|
end
|
|
|
|
if pres and ini_pres:section_exist(pres) then
|
|
self.last_curr_tree.curr_preset = pres
|
|
--self:Reset_opt(self.last_curr_tree, self.last_path, { preset = pres })
|
|
|
|
local n = ini_pres:line_count(pres)
|
|
local result, id, value
|
|
for i=0,n-1 do
|
|
result, id, value = ini_pres:r_line_ex(pres,i,"","")
|
|
|
|
-- Validate option
|
|
local v = get_opt_table(id)
|
|
if v and v.type then
|
|
|
|
-- No need to modify options that can't be seen
|
|
local to_hide = v.precondition and (not exec(unpack(v.precondition)))
|
|
if (not to_hide) then
|
|
|
|
-- Get proper value
|
|
if v.val == 0 then
|
|
|
|
elseif v.val == 1 then
|
|
value = (value == "true") and true or false
|
|
elseif v.val == 2 then
|
|
value = tonumber(value)
|
|
end
|
|
|
|
-- Extract path and opt
|
|
local t = str_opt_explode(id)
|
|
local opt = t[#t]
|
|
local path = t[1]
|
|
for i=2,#t-1 do
|
|
path = cc(path , t[i])
|
|
end
|
|
|
|
-- Cache changes
|
|
self:CacheValue(path, opt, value, v)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Update XML elements
|
|
self:Reset_opt(self.last_curr_tree, self.last_path)
|
|
|
|
-- Update state
|
|
self:UpdatePending()
|
|
end
|
|
end
|
|
|
|
function UIOptions:Register_Tree(tr, path, group, idx)
|
|
print_dbg("-Register_Tree | tr: %s - path: %s", tr, path)
|
|
local xml = self.xml
|
|
|
|
if (not self.tree[tr]) then
|
|
self.tree[tr] = {}
|
|
end
|
|
|
|
if (not self.tree[tr][path]) then
|
|
self.tree[tr][path] = xml:InitScrollView("main:tree_" .. tr, self.dialog)
|
|
|
|
--[[
|
|
local pos = self.tree[tr][path]:GetWndPos()
|
|
if tr == 3 then idx = 1 end
|
|
self.tree[tr][path]:SetWndPos(vector2():set( pos.x , pos.y + (25*(idx-1)) ))
|
|
--]]
|
|
|
|
if (not self.bl[tr]) then
|
|
self.bl[tr] = {}
|
|
end
|
|
|
|
self.bl[tr][path] = {}
|
|
|
|
-- Fill tree
|
|
for i=1,#group do
|
|
local _st = xml:InitStatic("main:st_tree", nil)
|
|
|
|
self.bl[tr][path][i] = xml:InitCheck("elements:btn_list", _st)
|
|
self.bl[tr][path][i]:SetCheck(false)
|
|
|
|
local txt = xml:InitTextWnd("elements:txt_list", _st)
|
|
txt:SetText( game.translate_string(opt_str_menu .. group[i].id) )
|
|
txt:SetTextColor( clr_tree[tr] )
|
|
|
|
self.tree[tr][path]:AddWindow(_st, true)
|
|
_st:SetAutoDelete(false)
|
|
end
|
|
|
|
-- Set Callback for tree buttons
|
|
for i=1,#self.bl[tr][path] do
|
|
local path_i = (path ~= "") and cc(path , group[i].id) or group[i].id
|
|
|
|
self:Register(self.bl[tr][path][i], ("tree_"..path_i))
|
|
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
|
|
self:Callback_Tree(tr, path_i, group[i], self.bl[tr][path], i)
|
|
end
|
|
self:AddCallback(("tree_"..path_i), ui_events.BUTTON_CLICKED, _wrapper, self)
|
|
end
|
|
end
|
|
|
|
self.tree[tr][path]:Show(true)
|
|
|
|
self.bl[tr][path][1]:SetCheck(true)
|
|
local path_1 = (path ~= "") and cc(path , group[1].id) or group[1].id
|
|
self:Callback_Tree(tr, path_1, group[1], self.bl[tr][path], 1)
|
|
end
|
|
function UIOptions:Callback_Tree(tr, path, group, ctrl, i)
|
|
print_dbg("-Callback_Tree | tr: %s - path: %s - index: %s", tr, path, i)
|
|
|
|
-- Radio buttons behavior
|
|
if (ctrl[i]:GetCheck() == false) then
|
|
ctrl[i]:SetCheck(true)
|
|
return
|
|
end
|
|
for k=1,#ctrl do
|
|
if k ~= i then
|
|
ctrl[k]:SetCheck(false)
|
|
end
|
|
end
|
|
|
|
-- Hide all sub trees
|
|
for k=tr+1,#self.tree do
|
|
for _,v in pairs(self.tree[k]) do
|
|
v:Show(false)
|
|
end
|
|
end
|
|
|
|
-- If its an option list, show it
|
|
if group.sh then
|
|
self:Reset_opt(group, path)
|
|
|
|
-- Caching current options
|
|
self.last_path = path
|
|
if (not self.last_curr_tree) then
|
|
self.last_curr_tree = {}
|
|
end
|
|
empty_table(self.last_curr_tree)
|
|
copy_table(self.last_curr_tree, group)
|
|
|
|
else
|
|
self:Register_Tree(tr+1, path, group.gr, i)
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Utilities
|
|
------------------------------------------------------------
|
|
function UIOptions:GetValue(path, opt, v, flags)
|
|
-- NOTE: make sure to check for nil values only, since false exists as legit value for commands and check boxes
|
|
|
|
local value
|
|
|
|
if flags and flags.def then
|
|
value = self:GetDefaultValue(path, opt, v)
|
|
|
|
elseif flags and flags.preset then
|
|
local pres = flags.preset
|
|
local id = cc(path , opt)
|
|
|
|
if v.val == 0 then
|
|
value = ini_pres:r_string_ex(pres, id)
|
|
elseif v.val == 1 then
|
|
value = ini_pres:r_bool_ex(pres, id)
|
|
elseif v.val == 2 then
|
|
value = ini_pres:r_float_ex(pres, id)
|
|
end
|
|
end
|
|
|
|
if (value ~= nil) or (flags and flags.def) then
|
|
if (value ~= nil) and (v.type == "track") then
|
|
value = clamp(value, v.min, v.max)
|
|
end
|
|
self:CacheValue(path, opt, value, v)
|
|
end
|
|
if (value == nil) then
|
|
value = self:GetCurrentValue(path, opt, v)
|
|
end
|
|
if (value == nil) then
|
|
value = self:GetDefaultValue(path, opt, v)
|
|
end
|
|
|
|
if (value ~= nil) and (v.type == "track") then
|
|
value = clamp(value, v.min, v.max)
|
|
end
|
|
|
|
return value
|
|
end
|
|
|
|
function UIOptions:GetDefaultValue(path, opt, v)
|
|
local id = cc(path , opt)
|
|
local value
|
|
|
|
if (type(v.def) == "table") then
|
|
value = exec(unpack(v.def))
|
|
else
|
|
value = v.def
|
|
end
|
|
|
|
-- We cache default values for the first time, so current values rely on them up later
|
|
-- because some default values are randomized and player might not touch them, thus causing randomized effects where they are used in-game
|
|
if (axr_main.config:r_value(opt_section, id, v.val) == nil) and (value ~= nil) then
|
|
axr_main.config:w_value(opt_section, id, value)
|
|
self.Save_AXR = true
|
|
end
|
|
|
|
return value
|
|
end
|
|
|
|
function UIOptions:GetCurrentValue(path, opt, v)
|
|
local id = cc(path , opt)
|
|
|
|
if (opt_temp[id] ~= nil) then
|
|
local _id = s_gsub(id, _opt_, "_")
|
|
if self._Cap[_id] and self._Cap[_id]:IsShown() then
|
|
self._Cap[_id]:TextControl():SetTextColor( clr_o )
|
|
end
|
|
|
|
return opt_temp[id]
|
|
end
|
|
|
|
local value
|
|
if v.curr then
|
|
value = exec(unpack(v.curr))
|
|
elseif v.cmd then
|
|
if v.val == 0 then
|
|
value = get_console_cmd(0, v.cmd)
|
|
elseif v.val == 1 then
|
|
value = get_console_cmd(1, v.cmd)
|
|
elseif v.val == 2 then
|
|
value = get_console_cmd(0, v.cmd) --get_console_cmd(2, v.cmd) -- some commands are integers, using get_float will return 0. This is a walkaround
|
|
value = tonumber(value)
|
|
if v.min and v.max then
|
|
value = clamp(value, v.min, v.max)
|
|
end
|
|
value = round_idp(value, v.prec or precision)
|
|
end
|
|
|
|
else
|
|
value = axr_main.config:r_value(opt_section, id, v.val)
|
|
end
|
|
|
|
return value
|
|
end
|
|
|
|
function UIOptions:GetContent(path, opt, v)
|
|
if v.cmd and (not v.content) then
|
|
local value
|
|
if v.val == 0 then
|
|
value = get_console_cmd(0, v.cmd)
|
|
elseif v.val == 1 then
|
|
value = get_console_cmd(1, v.cmd)
|
|
elseif v.val == 2 then
|
|
value = get_console_cmd(0, v.cmd) --get_console_cmd(2, v.cmd)
|
|
value = tonumber(value)
|
|
if v.min and v.max then
|
|
value = clamp(value, v.min, v.max)
|
|
end
|
|
value = round_idp(value, v.prec or precision)
|
|
end
|
|
return {{value,tostring(value)}}
|
|
|
|
elseif (type(v.content[1]) == "function") then
|
|
return exec(unpack(v.content))
|
|
else
|
|
return v.content
|
|
end
|
|
end
|
|
|
|
function UIOptions:GetOption(id)
|
|
|
|
local t = str_explode(id,_opt_ )
|
|
local v = options
|
|
for i=1,#t do
|
|
for j=1,#v do
|
|
if v[j].id == t[i] then
|
|
if i == #t then
|
|
v = v[j]
|
|
else
|
|
v = v[j].gr
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
return v
|
|
end
|
|
|
|
function UIOptions:CacheValue(path, opt, value, v)
|
|
local id = cc(path , opt)
|
|
|
|
-- Do a backup of current values first
|
|
if (opt_backup[id] == nil) then
|
|
opt_backup[id] = self:GetValue(path, opt, v)
|
|
print_dbg("# Backup [%s] = %s", id, opt_backup[id])
|
|
end
|
|
|
|
-- Cache changed values
|
|
if (value ~= nil) and (value ~= opt_backup[id]) then
|
|
opt_temp[id] = value
|
|
print_dbg("/ Cached [%s] = %s", id, value)
|
|
else
|
|
opt_temp[id] = nil -- no need to cache current values
|
|
print_dbg("~ Cleared cache [%s]", id)
|
|
end
|
|
|
|
-- Change text color
|
|
local _id = s_gsub(id, _opt_, "_")
|
|
if self._Cap[_id] and self._Cap[_id]:IsShown() then
|
|
if (opt_temp[id] ~= nil) and (opt_temp[id] ~= opt_backup[id]) then
|
|
self._Cap[_id]:TextControl():SetTextColor( clr_o )
|
|
else
|
|
self._Cap[_id]:TextControl():SetTextColor( clr_g1 )
|
|
end
|
|
end
|
|
|
|
-- Update state
|
|
self:UpdatePending()
|
|
end
|
|
|
|
function UIOptions:Stacker(path, opt, v)
|
|
-- This assure that each time a control is created, an unique callback id is given to it
|
|
-- Why? because in normal case, jumping between options removes the previous ones constantly, getting back to them will create new controls and assign them to the old ids
|
|
-- This is bad because callbacks are still attached to the old controls, any fresh controls that get assigned to those ids will be inactive as a result
|
|
-- My solution is this function to generate unique id each time a control is created
|
|
|
|
if (not v.stack) then v.stack = 0 end
|
|
v.stack = v.stack + 1
|
|
|
|
return cc( cc(path , opt) , v.stack)
|
|
end
|
|
|
|
function UIOptions:UpdatePending()
|
|
local size = size_table(opt_temp)
|
|
if size > 0 then
|
|
self.pending:SetText( strformat( game.translate_string("ui_mm_warning_pending"), size) )
|
|
else
|
|
self.pending:SetText("")
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Callbacks
|
|
------------------------------------------------------------
|
|
function UIOptions:OnButton_Accept()
|
|
--if self.Need_VidRestart then
|
|
-- self.message_box:InitMessageBox("message_box_yes_no")
|
|
-- self.message_box:SetText(string.format("%s %d% s", game.translate_string("ui_mm_confirm_changes"), 15, game.translate_string("mp_si_sec")))
|
|
-- self.message_box:ShowDialog(true)
|
|
--else
|
|
self:On_Accept()
|
|
--end
|
|
end
|
|
|
|
function UIOptions:OnButton_Reset()
|
|
if self.last_path and self.last_curr_tree and is_not_empty(opt_temp) then
|
|
local to_reset
|
|
for id, val in pairs(opt_temp) do
|
|
if s_find(id,self.last_path) then
|
|
to_reset = true
|
|
opt_temp[id] = nil
|
|
|
|
local _id = s_gsub(id, _opt_, "_")
|
|
if self._Cap[_id] and self._Cap[_id]:IsShown() then
|
|
self._Cap[_id]:TextControl():SetTextColor( clr_g1 )
|
|
end
|
|
end
|
|
end
|
|
|
|
if (to_reset) then
|
|
self:UpdatePending()
|
|
self:Reset_opt(self.last_curr_tree, self.last_path)
|
|
end
|
|
end
|
|
|
|
if self.dlg_controls and self.dlg_controls:IsShown() then
|
|
local opt = COptionsManager()
|
|
opt:SetCurrentValues ("key_binding")
|
|
end
|
|
end
|
|
|
|
function UIOptions:OnButton_Default()
|
|
if self.last_path and self.last_curr_tree then
|
|
self:Reset_opt(self.last_curr_tree, self.last_path, { def = true })
|
|
end
|
|
|
|
if self.dlg_controls and self.dlg_controls:IsShown() then
|
|
exec_console_cmd("default_controls")
|
|
|
|
local opt = COptionsManager()
|
|
opt:SetCurrentValues ("key_binding")
|
|
end
|
|
end
|
|
|
|
function UIOptions:OnButton_Cancel()
|
|
if is_not_empty(opt_temp) then
|
|
self.message_box:InitMessageBox("message_box_yes_no")
|
|
self.message_box:SetText(game.translate_string("ui_mm_discard_changes"))
|
|
self.message_box:ShowDialog(true)
|
|
else
|
|
self:On_Cancel()
|
|
end
|
|
end
|
|
|
|
function UIOptions:On_Accept()
|
|
for id, val in pairs(opt_temp) do
|
|
|
|
local v = self:GetOption(id)
|
|
|
|
-- Cache the changes
|
|
if (not v.curr) then
|
|
print_dbg("- Saved [%s] := %s", id, val)
|
|
axr_main.config:w_value(opt_section, id, val)
|
|
self.Save_AXR = true
|
|
end
|
|
|
|
self.Change_Done = true
|
|
|
|
-- Execute functors if found
|
|
if v.functor then
|
|
if v.postcondition then
|
|
if exec(unpack(v.postcondition))then
|
|
print_dbg("- Executing postcondition functor of [%s]",id)
|
|
exec(unpack(v.functor))
|
|
end
|
|
else
|
|
print_dbg("- Executing functor of [%s]",id)
|
|
exec(unpack(v.functor))
|
|
end
|
|
end
|
|
|
|
-- See if it needs restart
|
|
if v.restart then
|
|
self.Need_Restart = true
|
|
end
|
|
if v.vid then
|
|
self.Need_VidRestart = true
|
|
end
|
|
|
|
-- Send callback and apply changes
|
|
if v.cmd then
|
|
local cmd_value = val
|
|
if type(cmd_value) == "boolean" then
|
|
if v.bool_to_num then
|
|
cmd_value = cmd_value and "1" or "0"
|
|
else
|
|
cmd_value = cmd_value and "on" or "off"
|
|
end
|
|
end
|
|
|
|
print_dbg("- Saved CMD [%s] := %s", id, cmd_value)
|
|
exec_console_cmd(v.cmd .. " " .. cmd_value)
|
|
self.Save_CFG = true
|
|
end
|
|
end
|
|
|
|
-- Save axr_options
|
|
if self.Save_AXR then
|
|
axr_main.config:save()
|
|
self.Save_AXR = false
|
|
end
|
|
|
|
-- Save keybinds
|
|
if self.Keybinds_Shown then
|
|
local opt = COptionsManager()
|
|
opt:SaveValues("key_binding")
|
|
opt:OptionsPostAccept()
|
|
self.Save_CFG = true
|
|
end
|
|
|
|
print_dbg("~ Change done: %s | Game restart: %s | Vid restart: %s | Save AXR: %s | Save CFG: %s | Keybinds: %s", self.Change_Done, self.Need_Restart, self.Need_VidRestart, self.Save_AXR, self.Save_CFG, self.Keybinds_Shown)
|
|
|
|
-- appdata
|
|
if self.Save_CFG then
|
|
print_dbg("- Saved CFG")
|
|
exec_console_cmd("cfg_save")
|
|
--exec_console_cmd("cfg_save tmp")
|
|
end
|
|
|
|
if level.present() and self.Change_Done then
|
|
print_dbg("% Sent callback (on_option_change)")
|
|
SendScriptCallback("on_option_change")
|
|
end
|
|
|
|
-- Clear cache
|
|
empty_table(opt_temp)
|
|
empty_table(opt_backup)
|
|
|
|
-- Exit
|
|
self:On_Cancel()
|
|
end
|
|
|
|
function UIOptions:On_Cancel()
|
|
|
|
self.owner:ShowDialog(true)
|
|
self:HideDialog()
|
|
self.owner:Show(true)
|
|
|
|
-- Restart vid
|
|
if self.Need_VidRestart then
|
|
exec_console_cmd("vid_restart")
|
|
end
|
|
|
|
if self.Need_Restart then
|
|
self.owner:SetMsg( game.translate_string("ui_mm_change_done_restart") , 7 )
|
|
self.message_box:InitMessageBox("message_box_restart_game")
|
|
self.message_box:ShowDialog(true)
|
|
|
|
elseif self.Change_Done then
|
|
self.owner:SetMsg( game.translate_string("ui_mm_change_done") , 5 )
|
|
end
|
|
|
|
self.Change_Done = false
|
|
self.Need_VidRestart = false
|
|
self.Need_Restart = false
|
|
self.Save_CFG = false
|
|
self.Keybinds_Shown = false
|
|
|
|
Unregister_UI("UIOptions")
|
|
end
|
|
|
|
function UIOptions:On_Discard()
|
|
empty_table(opt_temp)
|
|
if (self.last_path and self.last_curr_tree) then
|
|
self:UpdatePending()
|
|
self:Reset_opt(self.last_curr_tree, self.last_path)
|
|
end
|
|
self:On_Cancel()
|
|
end
|
|
|
|
function UIOptions:OnKeyboard(dik, keyboard_action)
|
|
local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
|
|
if (res == false) then
|
|
local bind = dik_to_bind(dik)
|
|
if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
|
|
|
|
if dik == DIK_keys.DIK_ESCAPE then
|
|
self:OnButton_Cancel()
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
return res
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Keybinds
|
|
------------------------------------------------------------
|
|
class "opt_controls" (CUIWindow)
|
|
|
|
function opt_controls:__init() super()
|
|
end
|
|
|
|
function opt_controls:__finalize()
|
|
|
|
end
|
|
|
|
function opt_controls:InitControls(x, y, xml, handler)
|
|
|
|
self:SetWndPos(vector2():set(x,y))
|
|
self:SetWndSize(vector2():set(738,416))
|
|
|
|
self:SetAutoDelete(true)
|
|
|
|
-- self.bk = xml:InitFrame("frame", self)
|
|
|
|
xml:InitFrameLine ("tab_controls:cap_keyboardsetup", self)
|
|
xml:InitFrameLine ("tab_controls:cap_keyboardsetup", self)
|
|
xml:InitKeyBinding ("tab_controls:key_binding", self)
|
|
end
|
|
|
|
function trader_cond(x)
|
|
if x == 'get' then
|
|
-- printf('@@@ returning %s', alife_storage_manager.get_state().trader_buy_condition_override or "0 (DEFAULT)")
|
|
return alife_storage_manager.get_state().trader_buy_condition_override or 0
|
|
else
|
|
-- printf('@@@ setting %s', opt_temp["gameplay/economy_diff/condition_buy_override"] or '0 (DEFAULT)')
|
|
alife_storage_manager.get_state().trader_buy_condition_override = opt_temp["gameplay/economy_diff/condition_buy_override"] or 0
|
|
end
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Tutorial: How to add new options:
|
|
------------------------------------------------------------
|
|
--[[
|
|
------------------------------------------------------------------------------------------------
|
|
Option name:
|
|
script will read option name (id) and show it automatically, naming should be like this: "ui_mm_[tree_1]_[tree_2]_[tree_...]_[option]"
|
|
[tree_n] and [option] are detemined from option path inside the table
|
|
Example: options["video"]["general"]["renderer"] name will come from "ui_mm_video_general_renderer" string
|
|
|
|
------------------------------------------------------------------------------------------------
|
|
Option description:
|
|
option description can show up in the hint window if its defined by its name followed by "_desc"
|
|
Example: option with a name of "ui_mm_video_general_renderer" will show its hint if "ui_mm_video_general_renderer_desc" exists
|
|
|
|
|
|
------------------------------------------------------------------------------------------------
|
|
Parameters of option Tree:
|
|
------------------------------------------------------------------------------------------------
|
|
|
|
- [id]
|
|
- Define: (string)
|
|
To give a tree its own identity
|
|
|
|
- [sh]
|
|
- Define: (boolean)
|
|
used to detemine that the sub-tree tables are actual list of options to set and show
|
|
|
|
- [precondition]
|
|
- Define: ( table {function, parameters} )
|
|
don't show tree options if its precondition return false
|
|
|
|
- [output]
|
|
- Define: (string)
|
|
Text to show when precondition fails
|
|
|
|
- [gr]
|
|
- Define: ( table { ... } )
|
|
Table of a sub-tree or options list
|
|
|
|
- [apply_to_all]
|
|
- Define: (boolean)
|
|
when you have options trees with similar options and group, you can use this to add "Apply to All" button to each option
|
|
clicking it will apply option changes to this option in all other trees from same group
|
|
you must give these a tree a group id
|
|
|
|
- [id_gr]
|
|
- Define: (string)
|
|
allows you to give options tree a group id, to connect them when you want to use "Apply to all" button for options
|
|
|
|
------------------------------------------------------------------------------------------------
|
|
Parameters of options:
|
|
------------------------------------------------------------------------------------------------
|
|
|
|
----------------------
|
|
Critical parameters:
|
|
--------------------
|
|
These parameters must be declared for elements
|
|
|
|
[id]
|
|
- Define: (string)
|
|
Option identity/name.
|
|
Option get stored in axr_main or called in other sripts by its path (IDs of sub trees and option):
|
|
Example: ( tree_1_id/tree_2_id/.../option_id )
|
|
|
|
[type]
|
|
- Define: (string)
|
|
- Possible values:
|
|
- Option elements:
|
|
"check" : Option, check box, either ON or OFF
|
|
"list" : Option, list of strings, useful for options with too many selections
|
|
"input" : Option, input box, you can type a value of your choice
|
|
"radio_h" : Option, radio box, select one out of many choices. Can fit up to 8 selections (Horizental layout)
|
|
"radio_v" : Option, radio box, select one out of many choices. Can fit up any number of selections (Vertical layout)
|
|
"track" : Option, track bar, easy way to control numric options with min/max values (can be used only if [val] = 2)
|
|
- Support elements:
|
|
"line" : Support element, a simple line to separate things around
|
|
"image" : Support element, 563x50 px image box, full-area coverage
|
|
"slide" : Support element, image box on left, text on right
|
|
"title" : Support element, title (left/right/center alignment)
|
|
"desc" : Support element, description (left alignment)
|
|
|
|
|
|
----------------------
|
|
Dependable parameters:
|
|
----------------------
|
|
These parameters must be declared when other specific parameters are declared already. They work along with them
|
|
|
|
[val]
|
|
- Define: (number)
|
|
- Used by: option elements: ALL
|
|
Option's value type: 0. string | 1. boolean | 2. float
|
|
It tells the script what kind of value the option is storing / dealing with
|
|
|
|
[cmd]:
|
|
- Define: (string)
|
|
- Used by: option elements: ALL (needed if you want to control a console command)
|
|
Tie an option to a console command, so when the option value get changed, it get applied directly to the command
|
|
The option will show command's current value
|
|
NOTE:
|
|
cmd options don't get cached in axr_options, instead they get stored in appdata/user.ltx
|
|
[def] parameter is not needed here since we engine applies default values to commands if they don't exist in user.ltx automatically
|
|
|
|
[def]
|
|
- Define: (boolean) / (number) / (string) / ( table {function, parameters} )
|
|
- Used by: option elements: ALL (not needed if [cmd] is used)
|
|
Default value of an option
|
|
when no cached values are found in axr_options, the default value will be used
|
|
|
|
[min]
|
|
- Define: (number)
|
|
- Used by: option elements: "input" / "track": (only if [val] = 2)
|
|
Minimum viable value for an option, to make sure a value stays in range
|
|
|
|
[max]
|
|
- Define: (number)
|
|
- Used by: option elements: "input" / "track": (only if [val] = 2)
|
|
Maximum viable value for an option, to make sure a value stays in range
|
|
|
|
[step]
|
|
- Define: (number)
|
|
- Used by: option elements: "track": (only if [val] = 2)
|
|
How much a value can be increased/decreased in one step
|
|
|
|
[content]
|
|
- Define: ( table {double pairs} ) / ( table {function, parameters} )
|
|
- Used by: option elements: "list" / "radio_h" / "radio_v":
|
|
Delcares option's selection list
|
|
Pairs: { value of the selection, string to show on UI }
|
|
Example: content= { {0,"off"} , {1,"half"} , {2,"full"}}
|
|
So the list or radio option will show 3 selections (translated strings): (ui_mm_lst_off) and (ui_mm_lst_half) and (ui_mm_lst_full)
|
|
When you select one and it get applied, the assosiated value will get applied
|
|
So picking the first one will pass ( 0 )
|
|
|
|
|
|
[link]
|
|
- Define: (string)
|
|
- Used by: support elements: "image" / "slide"
|
|
Link to texture you want to show
|
|
|
|
[text]
|
|
- Define: (string)
|
|
- Used by: support elements: "slide" / "title" / "desc"
|
|
String to show near the image, it will be translated
|
|
|
|
----------------------
|
|
Optional parameters:
|
|
----------------------
|
|
These parameters are completely optionals, and can be used for custom stuff
|
|
|
|
[force_horz]
|
|
- Define: (boolean)
|
|
- Used by: option elements: "radio_h"
|
|
Force the radio buttons into horizental layout, despite their number
|
|
|
|
[no_str]
|
|
- Define: (boolean)
|
|
- Used by: option elements: "list" / "radio_h" / "radio_v" / "track"
|
|
Usually, the 2nd key of pairs in content table are strings to show on the UI, by translating "opt_str_lst_(string)"
|
|
when we set [no_str] to true, it will show the string fromm table as it is without translations or "opt_str_lst_"
|
|
For TrackBars: no_str won't show value next to the slider
|
|
|
|
[prec]
|
|
- Define: (number)
|
|
- Used by: option elements: "track"
|
|
allowed number of zeros in a number
|
|
|
|
[precondition]
|
|
- Define: ( table {function, parameters} )
|
|
- Used by: option elements: ALL
|
|
Show the option on UI if the precondition function returns true
|
|
|
|
[functor]
|
|
- Define: ( table {function, parameters} )
|
|
- Used by: option elements: ALL
|
|
Execute a function when option's changes get applied
|
|
|
|
[postcondition]
|
|
- Define: ( table {function, parameters} )
|
|
- Used by: option elements: ALL, with defined [functor]
|
|
Option won't execute its functor when changes are applied, unless if the postcondition function returns true
|
|
|
|
[curr]
|
|
- Define: ( table {function, parameters} )
|
|
- Used by: option elements: ALL
|
|
get current value of an option by executing the declared function, instead of reading it from axr_options.ltx
|
|
|
|
[hint]
|
|
- Define: (string)
|
|
- Used by: option elements: ALL
|
|
Override default name / desc rule to replace the translation of an option with a custom one, should be set without "ui_mm_" and "_desc"
|
|
Example: { hint = "alife_warfare_capture"} will force the script to use "ui_mm_alife_warfare_capture" and "ui_mm_alife_warfare_capture_desc" for name and desc of the option
|
|
|
|
[clr]
|
|
- Define: ( table {a,r,b,g} )
|
|
- Used by: support elements: "title" / "desc"
|
|
determines the color of the text
|
|
|
|
[stretch]
|
|
- Define: (boolean)
|
|
- Used by: support elements: "slide"
|
|
force the texture to stretch or not
|
|
|
|
[pos]
|
|
- Define: ( table {x,y} )
|
|
- Used by: support elements: "slide"
|
|
custom pos for the texture
|
|
|
|
[size]
|
|
- Define: ( table {w,z} )
|
|
- Used by: support elements: "slide"
|
|
custom size for the texture
|
|
|
|
[align]
|
|
- Define: (string) "l" "r" "c"
|
|
- Used by: support elements: "title"
|
|
determines the alignment of the title
|
|
|
|
[spacing]
|
|
- Define: (number)
|
|
- Used by: support elements: "slide"
|
|
hight offset to add extra space
|
|
--]] |