Divergent/mods/HUD Offsets Editor/gamedata/scripts/ui_debug_wpn_hud.script

2117 lines
70 KiB
Plaintext

-- Draggable Hud Editor by demonized
-- Possibility to set hud values by mouse dragging
-- Adjusting world model position and orientation for strapped/unstrapped poses
-- 2023
--[[
Script by Tronex
Engine edits by Rezy
2019/9/15
Weapon HUD editor
Weapon HUD editor allows you to change Weapon HUD position and orientation in real-time.
The GUI is interactive and easy to use, with ability to save adjusted pos in a temp file "temp_hud.ltx".
Edited values are temporarly cached for the weapons you worked on. You can return to them in case you turned off the editor (Avoid exiting or reloading when you have unsaved values).
Keybinds:
• Up Arrow: select previous parameter.
• Down Arrow: select next parameter.
• Left Arrow: reduce\rotate value of selected parameter.
• Right Arrow: increase\rotate value of selected parameter.
• LShift (hold): x10 value step.
• LAlt (hold): x50 value step.
• C: copy current section settings.
• V: paste/apply current section settings.
• Delete: clean temp cache.
• H: toggle hint window.
• Esc or Home: turn off editor.
--]]
local EPS = 0.0000100
local function fsimilar(value, to, eps)
return math.abs(value - to) < eps
end
local function generate_orthonormal_basis_normalized(d)
local dir = vector():set(d):normalize()
local up = vector():set(0,0,0)
local right = vector():set(0,0,0)
local fInvLength
if (fsimilar(dir.y, 1.0, EPS)) then
up:set(0, 0, 1)
fInvLength = 1 / math.sqrt(dir.x * dir.x + dir.y * dir.y)
right.x = -dir.y * fInvLength
right.y = dir.x * fInvLength
right.z = 0
up.x = -dir.z * right.y
up.y = dir.z * right.x
up.z = dir.x * right.y - dir.y * right.x
else
up:set(0, 1, 0)
fInvLength = 1 / math.sqrt(dir.x * dir.x + dir.z * dir.z)
right.x = dir.z * fInvLength
right.y = 0
right.z = -dir.x * fInvLength
up.x = dir.y * right.z
up.y = dir.z * right.x - dir.x * right.z
up.z = -dir.y * right.x
end
return dir, up, right
end
local precision = 6 -- allowed number of zeros
local t_dir = "items\\weapons\\"
local parameters = {
-- Type: 0 = string | 1 = number | 2 = 3d vector | 3 = 4d vector |
["hands_position"] = { name = "Hands Position", typ = 2, def = {0,0,0}, indx = 1, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 0, hud = true },
["hands_orientation"] = { name = "Hands Orientation", typ = 2, def = {0,0,0}, indx = 2, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 0, hud = true },
["base_hud_offset_pos"] = { name = "Base Position", typ = 2, def = {0,0,0}, indx = 3, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 5, hud = true },
["base_hud_offset_rot"] = { name = "Base Orientation", typ = 2, def = {0,0,0}, indx = 4, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 5, hud = true },
["aim_hud_offset_pos"] = { name = "Aim Position", typ = 2, def = {0,0,0}, indx = 5, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 1, hud = true },
["aim_hud_offset_rot"] = { name = "Aim Orientation", typ = 2, def = {0,0,0}, indx = 6, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 1, hud = true },
["gl_hud_offset_pos"] = { name = "GL Position", typ = 2, def = {0,0,0}, indx = 7, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 2, hud = true },
["gl_hud_offset_rot"] = { name = "GL Orientation", typ = 2, def = {0,0,0}, indx = 8, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 2, hud = true },
["aim_hud_offset_alt_pos"] = { name = "Alt Position", typ = 2, def = {0,0,0}, indx = 9, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 3, hud = true },
["aim_hud_offset_alt_rot"] = { name = "Alt Orientation", typ = 2, def = {0,0,0}, indx = 10, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 3, hud = true },
["lowered_hud_offset_pos"] = { name = "Lowered Position", typ = 2, def = {0,0,0}, indx = 11, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 4, hud = true },
["lowered_hud_offset_rot"] = { name = "Lowered Orientation", typ = 2, def = {0,0,0}, indx = 12, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 4, hud = true },
["fire_point"] = { name = "Fire Point", typ = 2, def = {0,0,0}, indx = 13, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 10, hud = true, no_16x9 = true },
["fire_point2"] = { name = "Fire Point 2 (GL)", typ = 2, def = {0,0,0}, indx = 14, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 11, hud = true, no_16x9 = true },
["fire_direction"] = { name = "Fire Direction", typ = 2, def = {0,0,1}, indx = 15, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 10, hud = true, no_16x9 = true },
["shell_point"] = { name = "Shell Point", typ = 2, def = {0,0,0}, indx = 16, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 11, hud = true, no_16x9 = true },
["custom_ui_pos"] = { name = "UI Position", typ = 2, def = {0,0,0}, indx = 17, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 20 }, --idxb 20 is reserved for device ui
["custom_ui_rot"] = { name = "UI Orientation", typ = 2, def = {0,0,0}, indx = 18, min = -180, max = 180, step = 1, idxa = 1, idxb = 20 },
["item_position"] = { name = "Item Position", typ = 2, def = {0,0,0}, indx = 19, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 12, hud = true, no_16x9 = true },
["item_orientation"] = { name = "Item Orientation", typ = 2, def = {0,0,0}, indx = 20, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 12, hud = true, no_16x9 = true },
["scope_zoom_factor"] = { name = "Zoom Factor", typ = 1, def = 0, indx = 21, min = 0, max = 120, step = 0.1 },
["gl_zoom_factor"] = { name = "GL Zoom Factor", typ = 1, def = 0, indx = 22, min = 0, max = 120, step = 0.1 },
["scope_zoom_factor_alt"] = { name = "Alt Zoom Factor", typ = 1, def = 0, indx = 23, min = 0, max = 120, step = 0.1 },
}
local third_person_parameters = {
["position"] = { name = "Position", typ = 2, def = {0,0,0}, indx = 1, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 0, hud = false, no_16x9 = true },
["orientation"] = { name = "Orientation", typ = 2, def = {0,0,0}, indx = 2, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 0, hud = false, no_16x9 = true },
["strap_position"] = { name = "Strap Position", typ = 2, def = {0,0,0}, indx = 3, min = -180, max = 180, step = 0.0001, idxa = 0, idxb = 1, hud = false, no_16x9 = true },
["strap_orientation"] = { name = "Strap Orientation", typ = 2, def = {0,0,0}, indx = 4, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 1, hud = false, no_16x9 = true },
["fire_point"] = { name = "Fire Point", typ = 2, def = {0,0,0}, indx = 5, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 1, hud = false, no_16x9 = true },
["fire_point2"] = { name = "Fire Point 2 (GL)", typ = 2, def = {0,0,0}, indx = 6, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 1, hud = false, no_16x9 = true },
["shell_point"] = { name = "Shell Point", typ = 2, def = {0,0,0}, indx = 7, min = -180, max = 180, step = 0.0001, idxa = 1, idxb = 1, hud = false, no_16x9 = true },
}
local adjust_active = nil
local is_wide = utils_xml.is_widescreen()
local _width = (device().width)-400
local _hight = (device().height)
local msg_width = is_wide and (_width*0.8) or _width
-- general values cache
local _memo = {} -- _memo[section] = {...}
local _memo_i = {} -- _memo_i[section] = {...}
-- cache current values
local _cache = {}
local _cache_i = {}
local _selected = {}
local _selected_group = {}
local key_timer = 0
local jump_1 = 1
local jump_2 = 10
local jump_3 = 50
local jump = jump_1
local dummy_npc
local enable_debug = false
function print_dbg(...)
if enable_debug then
printf(...)
end
end
-------------------------------------------------------------------
GUI = nil -- instance, don't touch
function start(owner)
-- Hide the owner
if owner then
if (owner:IsShown()) then
print_dbg("~ hide owner: %s", owner.name or "?")
owner:HideDialog()
owner:Show(false)
end
else
hide_hud_inventory()
end
local wpn = db.actor:active_item()
local det = db.actor:active_detector()
if wpn or det then
if (not GUI) then
GUI = WpnHudEditor(owner, wpn and wpn:section() or det:section())
end
if (GUI) and (not GUI:IsShown()) then
-- Enable hud adjust mode
if (not adjust_active) then
adjust_active = true
hud_adjust.enabled(true)
print_dbg("~ Enabled hud adjust mode")
end
GUI:ShowDialog(true)
GUI.section = wpn and wpn:section() or det:section()
GUI:Reset()
GUI:Send_MSG("Press H for info")
RegisterScriptCallback("on_key_release",on_key_release)
RegisterScriptCallback("on_key_hold",on_key_hold)
Register_UI("WpnHudEditor","ui_debug_wpn_hud")
else
ui_debug_launcher.resume()
printe("! Ok... Something is fucked...")
end
else
ui_debug_launcher.resume()
actor_menu.set_msg(1, "Hold the weapon you want to edit in your hands first!",5)
end
end
function on_key_release(key)
-- jump = jump_1
end
function on_key_hold(key)
-- if GUI then
-- if (key == DIK_keys["DIK_LSHIFT"]) then
-- jump = jump_2
-- key_timer = time_global() + 200
-- elseif (key == DIK_keys["DIK_LMENU"]) then
-- jump = jump_3
-- key_timer = time_global() + 200
-- end
-- end
end
-------------------------------------------------------------------
class "WpnHudEditor" (CUIScriptWnd)
function WpnHudEditor:__init(owner,section) super()
self.owner = owner
self.section = section
self.data = {}
self.tables = {parameters, third_person_parameters}
for i, v in ipairs(self.tables) do
_selected[v] = _selected[v] or 1
_selected_group[v] = _selected_group[v] or 1
self.data[v] = {}
self.data[v].selected = _selected[v]
self.data[v].selected_group = _selected_group[v]
self.data[v].cnt = 0 -- parameters counter / index
self.data[v].cnt_group = {} -- parameters counter / index per parent parameter
self.data[v].cnt_to_group = {} -- parameters counter to group relation
self.data[v].name = {} -- parameters name (by index)
self.data[v].typ = {} -- parameter type (by index)
self.data[v].value = {} -- parameter value (by index)
self.data[v].value_i = {} -- parameter value (by parent)
self.data[v].parent = {} -- parameter parent, useful for dealing with vector values (by index)
self.data[v].index = {} -- list parameter index, to trace list value
self.data[v].par = {} -- parameter element (by index)
self.data[v].par_cap = {} -- parameter cap (by index)
self.data[v].par_hl = {} -- parameter hightlighting (by index)
self.data[v].par_list = {} -- parameter list for lists (by index)
self.data[v].par_list_n = {} -- parameter numbered list for lists (by index)
end
self.active_table = parameters
self.third_person_mode = false
self:ResetNpcCam()
self:InitControls()
self:InitCallBacks()
self:Reset(true)
self:Send_MSG("Press H for info")
end
function WpnHudEditor:__finalize()
end
function WpnHudEditor:InitControls()
self:SetWndRect (Frect():set(0,0,1024,768))
self:SetAutoDelete(true)
if self.owner then
self.xml = self.owner.xml
else
self.xml = CScriptXmlInit()
end
local xml = self.xml
if (not self.owner) then
xml:ParseFile ("ui_debug_launcher.xml")
end
-- Guides
local width = device().width
local hight = device().height
local w_fac = (1024/width)
local h_fac = (768/hight)
local thic = 2
self._w = xml:InitStatic("dbg_wpn_hud_editor:align", self)
--self._w:SetWndPos(vector2():set( 0 , ((hight/2 * h_fac) - (thic/2)) ))
--self._w:SetWndSize(vector2():set( (width * w_fac) , (thic * h_fac) ))
self._w:Show(false)
self._h = xml:InitStatic("dbg_wpn_hud_editor:align", self)
--self._h:SetWndPos(vector2():set( ((width/2 * w_fac) - (thic/2)) , 0 ))
--self._h:SetWndSize(vector2():set( (thic * w_fac) , (hight * h_fac) ))
self._h:Show(false)
local pos_w = self._w:GetWndPos()
--printf("_W | x=%s y=%s w=%s h=%s", pos_w.x, pos_w.y, self._w:GetWidth(), self._w:GetHeight())
local pos_h = self._h:GetWndPos()
--printf("_H | x=%s y=%s w=%s h=%s", pos_h.x, pos_h.y, self._h:GetWidth(), self._h:GetHeight())
-- Dialog
self.dialog = xml:InitStatic("dbg_wpn_hud_editor", self)
xml:InitFrame("dbg_wpn_hud_editor:frame", self.dialog)
xml:InitStatic("dbg_wpn_hud_editor:cap",self.dialog)
self.txt_section = xml:InitTextWnd("dbg_wpn_hud_editor:section",self.dialog)
-- Ratio saving
xml:InitStatic("dbg_wpn_hud_editor:cap_ratio", self.dialog)
self.btn_ratio = xml:InitCheck("dbg_wpn_hud_editor:check_ratio", self.dialog)
self:Register(self.btn_ratio, "btn_ratio")
self.btn_ratio:SetCheck(true)
-- Show alignment
self.btn_align = xml:Init3tButton("dbg_wpn_hud_editor:btn_alignment", self.dialog)
self:Register(self.btn_align, "btn_align")
-- Third person switch
self.btn_third_person = xml:Init3tButton("dbg_wpn_hud_editor:btn_third_person", self.dialog)
self:Register(self.btn_third_person, "btn_third_person")
-- Copy section settings
self.btn_ini_copy = xml:Init3tButton("dbg_wpn_hud_editor:btn_ini_copy", self.dialog)
self:Register(self.btn_ini_copy, "btn_copy")
-- Paste section settings
self.btn_ini_paste = xml:Init3tButton("dbg_wpn_hud_editor:btn_ini_paste", self.dialog)
self:Register(self.btn_ini_paste, "btn_paste")
-- Save file
self.btn_save = xml:Init3tButton("dbg_wpn_hud_editor:btn_save", self.dialog)
self:Register(self.btn_save, "btn_save")
-- Reload hud values
self.btn_reload = xml:Init3tButton("dbg_wpn_hud_editor:btn_reload", self.dialog)
self:Register(self.btn_reload, "btn_reload")
self:ResetSelects()
-- Parameters
for i, v in ipairs(self.tables) do
self.data[v].scroll_par = xml:InitScrollView("dbg_wpn_hud_editor:scroll_par", self.dialog)
self.data[v].scroll_par:Clear()
local functor = function(t,a,b) return t[a].indx < t[b].indx end
local v1 = v
for par,v in spairs(v,functor) do
local _st = xml:InitStatic("dbg_wpn_hud_editor:tmp_par", nil)
-- Parameter cap
local n = #self.data[v1].par_cap + 1
self.data[v1].par_cap[n] = xml:InitTextWnd("dbg_wpn_hud_editor:op_par:cap", _st)
self.data[v1].par_cap[n]:SetText(v.name)
-- Multi boxes for vectors
local par_i = ((v.typ == 2) and 3) or ((v.typ == 3) and 4) or 1
for i=1,par_i do
-- Tracers
local ext = self:GetStringByType(i,v.typ)
local str = par .. ext
self.data[v1].cnt = self.data[v1].cnt + 1
self.data[v1].name[self.data[v1].cnt] = str
self.data[v1].typ[self.data[v1].cnt] = v.typ
self.data[v1].parent[self.data[v1].cnt] = par
self.data[v1].cnt_group[n] = self.data[v1].cnt_group[n] or {}
local size_cg = #self.data[v1].cnt_group[n] + 1
self.data[v1].cnt_group[n][size_cg] = self.data[v1].cnt
self.data[v1].cnt_to_group[self.data[v1].cnt] = n
-- Parameter element and hightlight texture
if v.typ == 0 then
self.data[v1].par[self.data[v1].cnt] = xml:InitComboBox("dbg_wpn_hud_editor:op_par:list", _st)
self:Register(self.data[v1].par[self.data[v1].cnt],tostring(v1) .. "par_" .. self.data[v1].cnt)
self.data[v1].par_hl[self.data[v1].cnt] = xml:InitStatic("dbg_wpn_hud_editor:op_par:hl_list", _st)
else
self.data[v1].par[self.data[v1].cnt] = xml:InitEditBox("dbg_wpn_hud_editor:op_par:input" .. ext, _st)
self:Register(self.data[v1].par[self.data[v1].cnt],tostring(v1) .. "par_" .. self.data[v1].cnt)
if v.typ == 1 then
self.data[v1].par[self.data[v1].cnt]:SetText(v.def)
else
self.data[v1].par[self.data[v1].cnt]:SetText(v.def[i])
end
self.data[v1].par_hl[self.data[v1].cnt] = xml:InitStatic("dbg_wpn_hud_editor:op_par:hl" .. ext, _st)
end
-- Hightlight last selected parameter
if (self.data[v1].cnt ~= _selected[v1]) then
self.data[v1].par_hl[self.data[v1].cnt]:Show(false)
end
end
self.data[v1].scroll_par:AddWindow(_st, true)
_st:SetAutoDelete(false)
end
if i > 1 then
self.data[v].scroll_par:Show(false)
end
end
-- Lines
xml:InitStatic("dbg_wpn_hud_editor:line_1",self.dialog)
xml:InitStatic("dbg_wpn_hud_editor:line_2",self.dialog)
-- Message Window
self.msg_wnd = xml:InitFrame("hint_wnd:background",self)
self.msg_wnd:SetAutoDelete(false)
self.msg_wnd_text = xml:InitTextWnd("hint_wnd:text",self.msg_wnd)
self.msg_wnd_text:SetTextAlignment(2)
self.msg_wnd:Show(false)
self.msg_wnd:SetColor(GetARGB(255,0,0,0))
-- Hint Window
self.hint_wnd = xml:InitFrame("help_wnd:background",self)
self.hint_wnd:SetAutoDelete(false)
self.hint_wnd_text = xml:InitTextWnd("help_wnd:text",self.hint_wnd)
--self.hint_wnd_text:SetTextAlignment(2)
self.hint_wnd_text:SetText(game.translate_string("st_ui_dbg_hud_about"))
self.hint_wnd_text:AdjustHeightToText()
self.hint_wnd_text:SetWndSize(vector2():set(msg_width, self.hint_wnd_text:GetHeight()+10))
self.hint_wnd_text:SetWndPos(vector2():set(20,10))
self.hint_wnd:Show(false)
self.hint_wnd:SetWndSize(vector2():set(msg_width, 700))
self.hint_wnd:SetWndPos(vector2():set( self.dialog:GetWidth() , 1 ))
self.hint_wnd:SetColor(GetARGB(255,0,0,0))
self.disable_drag = true
self.pos = nil
self.mouse_hold = nil
self.save_mode = true
end
function WpnHudEditor:ResetSelects(state_only)
local xml = self.xml
-- State Select
self.dummy_npc_states = {
{"Unstrapped", "guard_na"},
{"Strapped", "wait_na"},
{"Threat", "threat"},
{"Fire", "threat_fire"},
}
self.list_dummy_npc_state = self.list_dummy_npc_state or xml:InitComboBox("dbg_wpn_hud_editor:list_dummy_npc_state", self.dialog)
self.list_dummy_npc_state:ClearList()
for i = 1, #self.dummy_npc_states do
self.list_dummy_npc_state:AddItem(self.dummy_npc_states[i][1], i)
end
self.list_dummy_npc_state:enable_id(1)
self.list_dummy_npc_state:SetText(self.dummy_npc_states[1][1])
self.dummy_npc_state = self.dummy_npc_states[1][2]
if dummy_npc then
db.storage[dummy_npc.id].ui_debug_wpn_hud_dummy.state = self.dummy_npc_state
end
if state_only then return end
-- Time Factor Select
self.tf = {
{"TF Normal (1)", 1},
{"TF Slow-mo (0.1)", 0.1},
{"TF Freeze (0.01)", 0.01},
}
self.tf_select = self.tf_select or xml:InitComboBox("dbg_wpn_hud_editor:list_tf", self.dialog)
self.tf_select:ClearList()
for i = 1, #self.tf do
self.tf_select:AddItem(self.tf[i][1], i)
end
self.tf_select:enable_id(1)
self.tf_select:SetText(self.tf[1][1])
exec_console_cmd("time_factor " .. 1)
-- Drag Mode Select (Persistent)
if not self.select_registered then
self.drag_modes = {
{"Drag per-group", true},
{"Drag per-value", false},
}
self.list_drag_mode = self.list_drag_mode or xml:InitComboBox("dbg_wpn_hud_editor:list_drag_mode", self.dialog)
self.list_drag_mode:ClearList()
for i = 1, #self.drag_modes do
self.list_drag_mode:AddItem(self.drag_modes[i][1], i)
end
self.list_drag_mode:enable_id(1)
self.list_drag_mode:SetText(self.drag_modes[1][1])
self.drag_mode = self.drag_modes[1][2]
end
if not self.select_registered then
self.select_registered = true
self:Register(self.tf_select, "tf_select")
self:Register(self.list_dummy_npc_state, "list_dummy_npc_state")
self:Register(self.list_drag_mode, "list_drag_mode")
end
end
function WpnHudEditor:InitCallBacks()
self:AddCallback("btn_copy", ui_events.BUTTON_CLICKED, self.OnButtonCopy, self)
self:AddCallback("btn_paste", ui_events.BUTTON_CLICKED, self.OnButtonPaste, self)
self:AddCallback("btn_save", ui_events.BUTTON_CLICKED, self.OnButtonSave, self)
self:AddCallback("btn_reload", ui_events.BUTTON_CLICKED, self.OnButtonResume, self)
self:AddCallback("btn_align", ui_events.BUTTON_CLICKED, self.OnButtonAlign, self)
self:AddCallback("btn_third_person", ui_events.BUTTON_CLICKED, self.OnButtonThirdPerson, self)
self:AddCallback("tf_select", ui_events.LIST_ITEM_SELECT, self.OnTfSelect, self)
self:AddCallback("list_dummy_npc_state", ui_events.LIST_ITEM_SELECT, self.OnDummyNpcStateChange, self)
self:AddCallback("list_drag_mode", ui_events.LIST_ITEM_SELECT, self.OnDragModeChange, self)
--self:AddCallback("btn_ratio", ui_events.BUTTON_CLICKED, self.OnButtonRatio, self)
for i, v in ipairs(self.tables) do
for i=1,self.data[v].cnt do
local f = tostring(v).."OnInput_" .. i
self[f] = function(self)
self:OnInput(i)
local group = self.data[v].cnt_to_group[i]
self:SwitchParamByIndex(group, i)
end
self:AddCallback(tostring(v) .. "par_" .. i, ui_events.EDIT_TEXT_COMMIT, self[f], self)
end
end
end
function WpnHudEditor:OnTfSelect()
local id = self.tf_select:CurrentID()
local tf = self.tf[id][2]
exec_console_cmd("time_factor " .. tf)
end
function WpnHudEditor:OnDummyNpcStateChange()
local id = self.list_dummy_npc_state:CurrentID()
local state = self.dummy_npc_states[id][2]
self.dummy_npc_state = state
if dummy_npc then
db.storage[dummy_npc.id].ui_debug_wpn_hud_dummy.state = self.dummy_npc_state
end
end
function WpnHudEditor:OnDragModeChange()
local id = self.list_drag_mode:CurrentID()
local state = self.drag_modes[id][2]
self.drag_mode = state
end
function WpnHudEditor:ResetNpcCam()
self.dummy_npc_cam_offset = {
heading = 0,
pitch = 0,
height = 1.2,
zoom = 1.5,
move = -0.2,
}
self:SetCam()
end
function WpnHudEditor:SetCam()
if dummy_npc then
local obj = level.object_by_id(dummy_npc.id)
if obj then
local pos = obj:position():add(vector():set(0, self.dummy_npc_cam_offset.height, 0))
local obj_pos = vector():set(pos)
local dir = vector():setHP(utils_data.deg2rad(self.dummy_npc_cam_offset.heading), self.dummy_npc_cam_offset.pitch):normalize()
pos = pos:mad(dir, self.dummy_npc_cam_offset.zoom)
dir = vector():set(obj_pos):sub(pos):normalize()
-- dir = vector_rotate_y(dir, 15)
local d, u, r = generate_orthonormal_basis_normalized(dir)
pos:mad(r, self.dummy_npc_cam_offset.move)
dir = vector():set(
dir:getH(),
dir:getP(),
0
)
level.set_cam_custom_position_direction(pos, dir)
end
end
end
function WpnHudEditor:ChangeNpcCam(heading, height, zoom, move, pitch)
if heading then
self.dummy_npc_cam_offset.heading = self.dummy_npc_cam_offset.heading + heading
end
if pitch then
self.dummy_npc_cam_offset.pitch = clamp(self.dummy_npc_cam_offset.pitch + pitch,
-math.pi / 2.6, math.pi / 2.05)
end
if height then
self.dummy_npc_cam_offset.height = clamp(self.dummy_npc_cam_offset.height + height, 0.2, 2)
end
if zoom then
self.dummy_npc_cam_offset.zoom = clamp(self.dummy_npc_cam_offset.zoom + zoom, 0.2, 2.5)
end
if move then
self.dummy_npc_cam_offset.move = clamp(self.dummy_npc_cam_offset.move + move, -1.5, 1.5)
end
self:SetCam()
end
function WpnHudEditor:StopCam()
if dummy_npc then
alife():release(dummy_npc)
dummy_npc = nil
end
if level.remove_cam_custom_position_direction then level.remove_cam_custom_position_direction() end
RemoveTimeEvent("ui_debug_wpn_hud_dummy", "ui_debug_wpn_hud_dummy_npc")
RemoveTimeEvent("ui_debug_wpn_hud_dummy", "ui_debug_wpn_hud_dummy_weapon")
self.dummy_npc_state = self.dummy_npc_states[1][2]
end
function WpnHudEditor:DisableWCT(v)
if weapon_cover_tilt and weapon_cover_tilt.set_force_disabled then
weapon_cover_tilt.set_force_disabled(v)
end
end
function WpnHudEditor:Reset(force,use_cache)
local _use_cache = use_cache and is_not_empty(_cache) and is_not_empty(_cache_i) and true
self:DisableWCT(true)
local section = self.section
local hud_section = ini_sys:r_string_ex(section,"hud")
local str = utils_xml.is_widescreen() and "_16x9" or ""
local ltx = ini_file("temp_hud.ltx")
local section_found = ltx and ltx:section_exist(hud_section)
self.txt_section:SetText(section)
for i, v in ipairs(self.tables) do
empty_table(self.data[v].index)
local _use_cache = use_cache and is_not_empty(_cache) and is_not_empty(_cache[v]) and is_not_empty(_cache_i) and is_not_empty(_cache_i[v]) and true
-- Read values and convert to numbers if needed
if _use_cache then
--print_dbg("/ WpnHudEditor:Reset | use cache")
copy_table(self.data[v].value_i, _cache_i[v])
if not _memo_i[v] then _memo_i[v] = {} end
if (not _memo_i[v][section]) then _memo_i[v][section] = {} end
copy_table(_memo_i[v][section], _cache_i[v])
elseif _memo_i[v] and _memo_i[v][section] then
--print_dbg("/ WpnHudEditor:Reset | use memo | file: %s - hour: %s", file, hour)
copy_table(self.data[v].value_i, _memo_i[v][section])
else
local v1 = v
for par,v in pairs(v1) do
local t = {}
if (v.hud) then
local par_str = v.no_16x9 and par or (par..str)
if section_found and ltx:r_string_ex(hud_section,(par_str)) then
t = parse_list(ltx, hud_section, (par_str))
else
t = parse_list(ini_sys, hud_section, (par_str))
end
else
if ltx:r_string_ex(section, par) then
t = parse_list(ltx, section, par)
else
t = parse_list(ini_sys, section, par)
end
end
self.data[v1].value_i[par] = {}
for i=1,#t do
if (v.typ ~= 0) then
self.data[v1].value_i[par][i] = tonumber(t[i])
end
end
-- use default values if nothing is found
if (#self.data[v1].value_i[par] == 0) then
if (v.typ == 1) then
self.data[v1].value_i[par][1] = v.def
else
copy_table(self.data[v1].value_i[par], v.def)
end
end
end
end
-- Fill current values
for i=1,self.data[v].cnt do
local value
if _use_cache then
value = _cache[v][i]
if (not _memo[v]) then _memo[v] = {} end
if (not _memo[v][section]) then _memo[v][section] = {} end
_memo[v][section][i] = _cache[v][i]
elseif _memo[v] and _memo[v][section] then
value = _memo[v][section][i]
else
value = self:GetParameterValue(i, v)
end
-- print_dbg("/ WpnHudEditor:Reset | Filler | self.value[%s] (%s) = %s", i, self.parent[i], value)
self.data[v].value[i] = value
self.data[v].par[i]:SetText(value)
end
end
-- Apply values in-game
for i, t in ipairs(self.tables) do
if t == third_person_parameters then
self:ApplyThirdPersonParameterValue()
else
for par,v in pairs(t) do
self:ApplyParameterValue(v.typ, par, t)
end
end
end
-- Crosshair state
self.crosshair = get_console_cmd(1,"hud_crosshair")
if self._w:IsShown() then
exec_console_cmd("hud_crosshair on")
end
self.disable_drag = true
self.pos = nil
self.mouse_hold = nil
-- self.drag_mode = true
end
---------------< Utility >---------------
local indx_str = {
[1] = "_x",
[2] = "_y",
[3] = "_z",
[4] = "_a",
}
function WpnHudEditor:GetStringByType(indx,typ)
if (typ == 0) or (typ == 1) then
return ""
else
return indx_str[indx]
end
end
function WpnHudEditor:GetParameterValue(cnt, v)
local str = self.data[v].name[cnt]
local parent = self.data[v].parent[cnt]
local typ = self.data[v].typ[cnt]
print_dbg("/ WpnHudEditor:GetParameterValue | str: %s - parent: %s - typ: %s", str, parent, typ)
if (typ == 0) or (typ == 1) then
return self.data[v].value_i[parent][1]
end
if (string.sub(str,-2) == "_x") then return self.data[v].value_i[parent][1]
elseif (string.sub(str,-2) == "_y") then return self.data[v].value_i[parent][2]
elseif (string.sub(str,-2) == "_z") then return self.data[v].value_i[parent][3]
elseif (string.sub(str,-2) == "_a") then return self.data[v].value_i[parent][4]
end
printe("!ERROR no returned value for %s!", parent)
end
function WpnHudEditor:SetParameterValue(cnt,value)
local v = self.active_table
local str = self.data[v].name[cnt]
local parent = self.data[v].parent[cnt]
local typ = self.data[v].typ[cnt]
if self:IsInvalidValue(cnt,typ,value) then
self:Send_MSG("!ERROR nil value found for parameter [%s]", str)
return
end
if (typ == 1) then
self.data[v].value_i[parent][1] = value
elseif (string.sub(str,-2) == "_x") then self.data[v].value_i[parent][1] = value
elseif (string.sub(str,-2) == "_y") then self.data[v].value_i[parent][2] = value
elseif (string.sub(str,-2) == "_z") then self.data[v].value_i[parent][3] = value
elseif (string.sub(str,-2) == "_a") then self.data[v].value_i[parent][4] = value
end
local section = self.section
if not _memo[v] then _memo[v] = {} end
if not _memo_i[v] then _memo_i[v] = {} end
if (not _memo[v][section]) then _memo[v][section] = {} end
copy_table(_memo[v][section], self.data[v].value)
if (not _memo_i[v][section]) then _memo_i[v][section] = {} end
copy_table(_memo_i[v][section], self.data[v].value_i)
end
function WpnHudEditor:ApplyParameterValue(typ, parent, v)
v = v or self.active_table
print_dbg("# Setting now: %s",parent)
if v == third_person_parameters then
self:ApplyThirdPersonParameterValue()
else
if (typ == 1) then
local value = self.data[v].value_i[parent][1]
if value and (type(value) == "number") then
hud_adjust.set_value(parent, value)
print_dbg("-hud_adjust.set_value(%s,%s)",parent,value)
else
printe("! MISSING VALUE: WpnHudEditor:ApplyParameterValue(%s, %s)", typ ,parent)
end
elseif (typ == 2) then
local value_1 = self.data[v].value_i[parent][1]
local value_2 = self.data[v].value_i[parent][2]
local value_3 = self.data[v].value_i[parent][3]
if value_1 and (type(value_1) == "number")
and value_2 and (type(value_2) == "number")
and value_3 and (type(value_3) == "number")
then
hud_adjust.set_vector(v[parent].idxa, v[parent].idxb, value_1, value_2, value_3)
print_dbg("-hud_adjust.set_vector[%s]([%s][%s]: %s,%s,%s)", parent, v[parent].idxa, v[parent].idxb, value_1, value_2, value_3)
else
printe("! MISSING VALUE: WpnHudEditor:ApplyParameterValue(%s, %s)", typ ,parent)
end
elseif (typ == 3) then
local value_1 = self.data[v].value_i[parent][1]
local value_2 = self.data[v].value_i[parent][2]
local value_3 = self.data[v].value_i[parent][3]
local value_4 = self.data[v].value_i[parent][4]
if value_1 and (type(value_1) == "number")
and value_2 and (type(value_2) == "number")
and value_3 and (type(value_3) == "number")
and value_4 and (type(value_4) == "number")
then
--weather.set_value_vector(parent,value_1,value_2,value_3,value_4)
print_dbg("-weather.set_value_vector2(%s,%s,%s,%s,%s)",parent,value_1,value_2,value_3,value_4)
else
printe("! MISSING VALUE: WpnHudEditor:ApplyParameterValue(%s, %s)", typ ,parent)
end
end
end
end
function WpnHudEditor:ApplyThirdPersonParameterValue()
if not self.weapon_cobj then
print_dbg("no active weapon to set")
return
end
if not (
self.weapon_cobj.Set_mOffset
and self.weapon_cobj.Set_mStrapOffset
and self.weapon_cobj.Set_mFirePoint
and self.weapon_cobj.Set_mFirePoint2
and self.weapon_cobj.Set_mShellPoint
) then
self:Print(nil, "Modded exes not installed, third person editor is unavailable")
return
end
local params = {}
for par,v in pairs(third_person_parameters) do
local typ = v.typ
local parent = par
if (typ == 1) then
local value = self.data[third_person_parameters].value_i[parent][1]
if value and (type(value) == "number") then
params[parent] = value
print_dbg("-third_person_value(%s,%s)",parent,value)
else
printe("! MISSING VALUE: third_person_value(%s,%s)", typ ,parent)
end
elseif (typ == 2) then
local value_1 = self.data[third_person_parameters].value_i[parent][1]
local value_2 = self.data[third_person_parameters].value_i[parent][2]
local value_3 = self.data[third_person_parameters].value_i[parent][3]
if value_1 and (type(value_1) == "number")
and value_2 and (type(value_2) == "number")
and value_3 and (type(value_3) == "number")
then
params[parent] = vector():set(value_1, value_2, value_3)
print_dbg("-third_person_value(%s,%s,%s,%s)",parent,value_1, value_2, value_3)
else
printe("! MISSING VALUE: third_person_value(%s, %s)", typ ,parent)
end
end
end
if params.position and params.orientation then
self.weapon_cobj:Set_mOffset(params.position, params.orientation)
end
if params.strap_position and params.strap_orientation then
self.weapon_cobj:Set_mStrapOffset(params.strap_position, params.strap_orientation)
end
if params.fire_point then
self.weapon_cobj:Set_mFirePoint(params.fire_point)
end
if params.fire_point2 then
self.weapon_cobj:Set_mFirePoint2(params.fire_point2)
end
if params.shell_point then
self.weapon_cobj:Set_mShellPoint(params.shell_point)
end
end
function WpnHudEditor:IsInvalidValue(cnt,typ,value)
-- Numbers
if not (value and value ~= "" and tonumber(value)) then
return true
end
return false
end
function WpnHudEditor:Send_MSG(text,...)
printf(text, ...)
self:Print(nil, strformat(text,...))
-- local str = strformat(text,...)
-- self.msg_wnd:Show(true)
-- self.msg_wnd_text:SetText(str)
-- self.msg_wnd_text:AdjustHeightToText()
-- self.msg_wnd_text:SetWndSize(vector2():set(msg_width, self.msg_wnd_text:GetHeight()+10))
-- self.msg_wnd_text:SetWndPos(vector2():set(0,20))
-- self.msg_wnd:SetWndSize(vector2():set(msg_width, self.msg_wnd_text:GetHeight()+44))
-- self.msg_wnd:SetWndPos(vector2():set( self.dialog:GetWidth() , (_hight - self.msg_wnd:GetHeight()) ))
-- self.msg_wnd_timer = time_global() + 4000
end
local toggle_hint = false
function WpnHudEditor:ShowHint()
toggle_hint = not toggle_hint
self.hint_wnd_show = toggle_hint
end
function WpnHudEditor:Update()
CUIScriptWnd.Update(self)
if key_state(DIK_keys.DIK_LSHIFT) == 1 then
jump = jump_2
elseif key_state(DIK_keys.DIK_LMENU) == 1 then
jump = jump_3
else
jump = jump_1
end
self:SetCam()
self:On_Drag()
if self.third_person_mode then
if key_state(bind_to_dik(key_bindings.kFWD)) == 1 then
self:ChangeNpcCam(nil, nil, -0.003)
elseif key_state(bind_to_dik(key_bindings.kBACK)) == 1 then
self:ChangeNpcCam(nil, nil, 0.003)
end
if key_state(bind_to_dik(key_bindings.kL_STRAFE)) == 1 then
self:ChangeNpcCam(nil, nil, nil, -0.003)
elseif key_state(bind_to_dik(key_bindings.kR_STRAFE)) == 1 then
self:ChangeNpcCam(nil, nil, nil, 0.003)
end
-- Lock condition and ammo count in TP
if self.weapon_cobj then
self.weapon_cobj:SetAmmoElapsed(30)
self.weapon:set_condition(1)
end
end
if (self.msg_wnd_timer and time_global() > self.msg_wnd_timer) then
self.msg_wnd_timer = nil
self.msg_wnd:Show(false)
end
if (self.hint_wnd_show) then
self.hint_wnd:Show(true)
else
self.hint_wnd:Show(false)
end
end
function WpnHudEditor:Print(s, str, ...)
actor_menu.set_msg(1, string.format(str, ...), 2)
end
local tg = 0
local tg_interval = 20
local tg_print = 0
function WpnHudEditor:On_Drag()
if (self.disable_drag) then
return
end
-- local t = time_global()
-- if t < tg then return end
-- tg = t + tg_interval
if not self.pos then self.pos = GetCursorPosition() end
local pos = GetCursorPosition()
local diff_y = pos.y - self.pos.y
local diff_x = pos.x - self.pos.x
local rounded_diff_y = math.abs(round_idp(diff_y, 4)) * device().width / 1920
local rounded_diff_x = math.abs(round_idp(diff_x, 4)) * device().width / 1920
-- if time_global() - tg_print > 100 then
-- printf("ratio %s", device().width / 1920)
-- printf("%s, %s", rounded_diff_x, rounded_diff_y)
-- self:Print(nil, rounded_diff_x .. ", " .. rounded_diff_y)
-- tg_print = time_global()
-- end
if self.mouse_hold and self.mouse_hold == DIK_keys.MOUSE_3 and self.third_person_mode then
if key_state(DIK_keys.DIK_LCONTROL) == 1 then
if diff_y < 0 then
self:ChangeNpcCam(nil, nil, 0.003 * -rounded_diff_y)
elseif diff_y > 0 then
self:ChangeNpcCam(nil, nil, 0.003 * rounded_diff_y)
end
elseif key_state(DIK_keys.DIK_LSHIFT) == 1 then
if diff_x < 0 then
self:ChangeNpcCam(nil, nil, nil, 0.0015 * rounded_diff_x)
elseif diff_x > 0 then
self:ChangeNpcCam(nil, nil, nil, 0.0015 * -rounded_diff_x)
end
if diff_y < 0 then
self:ChangeNpcCam(nil, 0.0015 * -rounded_diff_y)
elseif diff_y > 0 then
self:ChangeNpcCam(nil, 0.0015 * rounded_diff_y)
end
else
if diff_x < 0 then
self:ChangeNpcCam(0.15 * rounded_diff_x)
elseif diff_x > 0 then
self:ChangeNpcCam(0.15 * -rounded_diff_x)
end
if diff_y < 0 then
self:ChangeNpcCam(nil, nil, nil, nil, 0.0015 * -rounded_diff_y)
elseif diff_y > 0 then
self:ChangeNpcCam(nil, nil, nil, nil, 0.0015 * rounded_diff_y)
end
end
end
local v = self.active_table
if self.drag_mode == true then
local group = self.data[v].cnt_group[self.data[v].selected_group]
if self.mouse_hold and self.mouse_hold == DIK_keys.MOUSE_1 then
if self.data[v].selected_group == 2 then -- Hands orientation
if diff_y < 0 then
self:SwitchValue(true, group[2], 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[2], 8 * rounded_diff_y)
end
if diff_x < 0 then
self:SwitchValue(true, group[1], 8 * rounded_diff_x)
elseif diff_x > 0 then
self:SwitchValue(false, group[1], 8 * rounded_diff_x)
end
elseif self.data[v].selected_group == 6 and v == third_person_parameters then -- TP Strapped Orientation
if diff_y > 0 then
self:SwitchValue(true, group[1], 8 * rounded_diff_y)
elseif diff_y < 0 then
self:SwitchValue(false, group[1], 8 * rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[2], 8 * rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[2], 8 * rounded_diff_x)
end
elseif self.data[v].selected_group == 6 then -- Aim orientation
if diff_y > 0 then
self:SwitchValue(true, group[1], 1 * rounded_diff_y)
elseif diff_y < 0 then
self:SwitchValue(false, group[1], 1 * rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[2], 1 * rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[2], 1 * rounded_diff_x)
end
elseif self.data[v].selected_group == 8 and v ~= third_person_parameters then -- GL orientation
if diff_y > 0 then
self:SwitchValue(true, group[1], 1 * rounded_diff_y)
elseif diff_y < 0 then
self:SwitchValue(false, group[1], 1 * rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[2], 1 * rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[2], 1 * rounded_diff_x)
end
elseif self.data[v].selected_group == 8 then -- Alt orientation
if diff_y > 0 then
self:SwitchValue(true, group[1], 1 * rounded_diff_y)
elseif diff_y < 0 then
self:SwitchValue(false, group[1], 1 * rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[2], 1 * rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[2], 1 * rounded_diff_x)
end
elseif self.data[v].selected_group == 19 then -- Item Position
if diff_y < 0 then
self:SwitchValue(true, group[2], rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[2], rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[1], rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[1], rounded_diff_x)
end
elseif self.data[v].selected_group == 20 then -- Item Orientation
if diff_y < 0 then
self:SwitchValue(true, group[2], 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[2], 8 * rounded_diff_y)
end
if diff_x < 0 then
self:SwitchValue(true, group[1], 8 * rounded_diff_x)
elseif diff_x > 0 then
self:SwitchValue(false, group[1], 8 * rounded_diff_x)
end
elseif self.data[v].selected_group == 18 then -- UI orientation
if diff_y > 0 then
self:SwitchValue(true, group[1], round_idp(0.02 * rounded_diff_y, 4))
elseif diff_y < 0 then
self:SwitchValue(false, group[1], round_idp(0.02 * rounded_diff_y, 4))
end
if diff_x > 0 then
self:SwitchValue(true, group[2], round_idp(0.02 * rounded_diff_x, 4))
elseif diff_x < 0 then
self:SwitchValue(false, group[2], round_idp(0.02 * rounded_diff_x, 4))
end
elseif self.data[v].selected_group == 12 then -- Lowered orientation
if diff_y > 0 then
self:SwitchValue(true, group[1], 1 * rounded_diff_y)
elseif diff_y < 0 then
self:SwitchValue(false, group[1], 1 * rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[2], 1 * rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[2], 1 * rounded_diff_x)
end
elseif self.data[v].selected_group == 23 or
self.data[v].selected_group == 22 or
self.data[v].selected_group == 21 then -- Last 3 groups with single value
if diff_y < 0 then
self:SwitchValue(true, group[1], round_idp(0.2 * rounded_diff_y, 4))
elseif diff_y > 0 then
self:SwitchValue(false, group[1], round_idp(0.2 * rounded_diff_y, 4))
end
else -- Everything else
if diff_y < 0 then
self:SwitchValue(true, group[2], 1 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[2], 1 * rounded_diff_y)
end
if diff_x > 0 then
self:SwitchValue(true, group[1], 1 * rounded_diff_x)
elseif diff_x < 0 then
self:SwitchValue(false, group[1], 1 * rounded_diff_x)
end
end
elseif self.mouse_hold and self.mouse_hold == DIK_keys.MOUSE_2 then
if self.data[v].selected_group == 2 then -- Hands orientation
if diff_y < 0 then
self:SwitchValue(true, group[3], 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[3], 8 * rounded_diff_y)
end
elseif self.data[v].selected_group == 6 and v == third_person_parameters then -- TP Strapped Orientation
if diff_y < 0 then
self:SwitchValue(true, group[3], 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[3], 8 * rounded_diff_y)
end
elseif self.data[v].selected_group == 18 then -- UI orientation
if diff_y < 0 then
self:SwitchValue(true, group[3], round_idp(0.02 * rounded_diff_y, 4))
elseif diff_y > 0 then
self:SwitchValue(false, group[3], round_idp(0.02 * rounded_diff_y, 4))
end
elseif self.data[v].selected_group == 19 then -- Item Position
if diff_y < 0 then
self:SwitchValue(true, group[3], 2 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[3], 2 * rounded_diff_y)
end
elseif self.data[v].selected_group == 20 then -- Item Orientation
if diff_y < 0 then
self:SwitchValue(true, group[3], 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[3], 8 * rounded_diff_y)
end
elseif self.data[v].selected_group == 23 or
self.data[v].selected_group == 22 or
self.data[v].selected_group == 21 then -- Last 3 groups with single value
if diff_y < 0 then
self:SwitchValue(true, group[1], round_idp(0.2 * rounded_diff_y, 4))
elseif diff_y > 0 then
self:SwitchValue(false, group[1], round_idp(0.2 * rounded_diff_y, 4))
end
else -- Everything else
if diff_y < 0 then
self:SwitchValue(true, group[3], 1 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, group[3], 1 * rounded_diff_y)
end
end
end
elseif self.drag_mode == false then
if self.mouse_hold and (self.mouse_hold == DIK_keys.MOUSE_1 or self.mouse_hold == DIK_keys.MOUSE_2) then
if self.data[v].selected_group == 2 then -- Hands orientation
if diff_y < 0 then
self:SwitchValue(true, self.data[v].selected, 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, self.data[v].selected, 8 * rounded_diff_y)
end
elseif self.data[v].selected_group == 6 and v == third_person_parameters then -- TP Strapped Orientation
if diff_y < 0 then
self:SwitchValue(true, self.data[v].selected, 8 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, self.data[v].selected, 8 * rounded_diff_y)
end
elseif self.data[v].selected_group == 18 then -- UI orientation
if diff_y < 0 then
self:SwitchValue(true, self.data[v].selected, round_idp(0.02 * rounded_diff_y, 4))
elseif diff_y > 0 then
self:SwitchValue(false, self.data[v].selected, round_idp(0.02 * rounded_diff_y, 4))
end
elseif self.data[v].selected_group == 23 or
self.data[v].selected_group == 22 or
self.data[v].selected_group == 21 then -- Last 3 groups with single value
if diff_y < 0 then
self:SwitchValue(true, self.data[v].selected, round_idp(0.2 * rounded_diff_y, 4))
elseif diff_y > 0 then
self:SwitchValue(false, self.data[v].selected, round_idp(0.2 * rounded_diff_y, 4))
end
else -- Everything else
if diff_y < 0 then
self:SwitchValue(true, self.data[v].selected, 1 * rounded_diff_y)
elseif diff_y > 0 then
self:SwitchValue(false, self.data[v].selected, 1 * rounded_diff_y)
end
end
end
end
SetCursorPosition(self.pos)
end
---------------< Callbacks >---------------
function WpnHudEditor:OnButtonCopy()
local v = self.active_table
_cache[v] = _cache[v] or {}
_cache_i[v] = _cache_i[v] or {}
copy_table(_cache[v], self.data[v].value)
copy_table(_cache_i[v], self.data[v].value_i)
self:Send_MSG("Copied values")
end
function WpnHudEditor:OnButtonPaste()
local v = self.active_table
if (_cache and _cache_i and _cache[v] and _cache_i[v]) then
self:Reset(false, true)
self:Send_MSG("Applied copied values")
else
self:Send_MSG("No values are copied yet!")
end
end
function WpnHudEditor:SaveCacheDbg()
local section = self.section
local hud_section = ini_sys:r_string_ex(section,"hud")
local prefix = utils_xml.is_widescreen() and "_16x9" or ""
local all_prefix = self.btn_ratio:GetCheck()
local ini_cc = ui_debug_launcher.ini_cc
local function saveParams()
local to_save = {}
for par,v in pairs(parameters) do
local value, value_def
if (v.typ == 2) then
value = self.data[parameters].value_i[par][1] ..",".. self.data[parameters].value_i[par][2] ..",".. self.data[parameters].value_i[par][3]
value_def = v.def[1] ..",".. v.def[2] ..",".. v.def[3]
elseif (v.typ == 3) then
value = self.data[parameters].value_i[par][1] ..",".. self.data[parameters].value_i[par][2] ..",".. self.data[parameters].value_i[par][3] ..",".. self.data[parameters].value_i[par][4]
value_def = v.def[1] ..",".. v.def[2] ..",".. v.def[3] ..",".. v.def[4]
else
value = self.data[parameters].value_i[par][1]
value_def = v.def
end
value = tostring(value)
value_def = tostring(value_def)
local par_str = (v.hud and not v.no_16x9) and (par_str) or par
local old_value = v.hud and ini_sys:r_string_ex(hud_section, par_str) or ini_sys:r_string_ex(section, par)
local c_sec = v.hud and hud_section or section
local c_par = par_str
if (value ~= old_value) and (value ~= value_def) then
if (to_save[c_sec] == nil) then to_save[c_sec] = {} end
to_save[c_sec][c_par] = value
end
end
if is_empty(to_save) then
self:Print(nil, "No HUD values are modified for %s", section)
return
end
local params_wide = {
["hands_position"] = true,
["hands_orientation"] = true,
["base_hud_offset_pos"] = true,
["base_hud_offset_rot"] = true,
["aim_hud_offset_pos"] = true,
["aim_hud_offset_rot"] = true,
["gl_hud_offset_pos"] = true,
["gl_hud_offset_rot"] = true,
["aim_hud_offset_alt_pos"] = true,
["aim_hud_offset_alt_rot"] = true,
["lowered_hud_offset_pos"] = true,
["lowered_hud_offset_rot"] = true,
["strafe_hud_offset_pos"] = true,
["strafe_hud_offset_rot"] = true,
["strafe_aim_hud_offset_pos"] = true,
["strafe_aim_hud_offset_rot"] = true,
}
for k, v in pairs(to_save) do
for k1, v1 in pairs(v) do
ini_cc:w_value(k, k1, v1)
if all_prefix then
if params_wide[k1] then
ini_cc:w_value(k, k1 .. "_16x9", v1)
end
end
end
end
return true
end
local function saveThirdPersonParams()
local to_save = {}
for par,v in pairs(third_person_parameters) do
local value, value_def
if (v.typ == 2) then
value = self.data[third_person_parameters].value_i[par][1] ..",".. self.data[third_person_parameters].value_i[par][2] ..",".. self.data[third_person_parameters].value_i[par][3]
value_def = v.def[1] ..",".. v.def[2] ..",".. v.def[3]
elseif (v.typ == 3) then
value = self.data[third_person_parameters].value_i[par][1] ..",".. self.data[third_person_parameters].value_i[par][2] ..",".. self.data[third_person_parameters].value_i[par][3] ..",".. self.data[third_person_parameters].value_i[par][4]
value_def = v.def[1] ..",".. v.def[2] ..",".. v.def[3] ..",".. v.def[4]
else
value = self.data[third_person_parameters].value_i[par][1]
value_def = v.def
end
value = tostring(value)
value_def = tostring(value_def)
local par_str = par
local old_value = ini_sys:r_string_ex(section, par)
local c_sec = section
local c_par = par_str
if (value ~= old_value) and (value ~= value_def) then
if (to_save[c_sec] == nil) then to_save[c_sec] = {} end
to_save[c_sec][c_par] = value
end
end
if is_empty(to_save) then
self:Print(nil, "No Third Person values are modified for %s", section)
return
end
for k, v in pairs(to_save) do
for k1, v1 in pairs(v) do
ini_cc:w_value(k, k1, v1)
end
end
return true
end
local res = saveParams()
res = saveThirdPersonParams() or res
if res then
ini_cc:save()
self:Print(nil, "%s section is saved in cache_dbg.ltx", section)
else
self:Print(nil, "%s no changes were made", section)
end
end
function WpnHudEditor:CleanCacheDbg()
local path = getFS():update_path('$game_config$', '') .. "cache_dbg.ltx"
local ini_io = io.open(path, 'w')
ini_io:close()
ui_debug_launcher.ini_cc = ini_file_ex("cache_dbg.ltx",true)
self:Print(nil, "cache_dbg.ltx file cleaned")
end
function WpnHudEditor:OnButtonSave()
if self.save_mode then
return self:SaveCacheDbg()
end
local section = self.section
local hud_section = ini_sys:r_string_ex(section,"hud")
local prefix = utils_xml.is_widescreen() and "_16x9" or ""
local all_prefix = self.btn_ratio:GetCheck()
local to_save = {}
for par,v in pairs(parameters) do
local value, value_def
if (v.typ == 2) then
value = self.data[parameters].value_i[par][1] ..",".. self.data[parameters].value_i[par][2] ..",".. self.data[parameters].value_i[par][3]
value_def = v.def[1] ..",".. v.def[2] ..",".. v.def[3]
elseif (v.typ == 3) then
value = self.data[parameters].value_i[par][1] ..",".. self.data[parameters].value_i[par][2] ..",".. self.data[parameters].value_i[par][3] ..",".. self.data[parameters].value_i[par][4]
value_def = v.def[1] ..",".. v.def[2] ..",".. v.def[3] ..",".. v.def[4]
else
value = self.data[parameters].value_i[par][1]
value_def = v.def
end
value = tostring(value)
value_def = tostring(value_def)
local par_str = (v.hud and not v.no_16x9) and (par..prefix) or par
local old_value = v.hud and ini_sys:r_string_ex(hud_section, par_str) or ini_sys:r_string_ex(section, par)
local c_sec = v.hud and hud_section or section
local c_par = par_str
if (value ~= old_value) and (value ~= value_def) then
if (to_save[c_sec] == nil) then to_save[c_sec] = {} end
to_save[c_sec][c_par] = value
end
end
if is_empty(to_save) then
self:Print(nil, "No HUD values are modified for [%s]", section)
return
end
local function file_exists(path)
return io.open(path) ~= nil
end
local save_done
local ini_cc = ui_debug_launcher.ini_cc
local function on_execute(path,filename,quit)
if is_empty(to_save) then
return
end
local fullpath = path.."\\"..filename
local ltx = io.open(fullpath,"rb")
if (ltx) then
local data = ltx:read("*all")
ltx:close()
if (data) then
for sec,v in pairs(to_save) do
if (string.find(data,"["..sec.."]",nil,true)) then
ltx = utils_data.cfg_file(fullpath, true)
if (ltx) then
for par,val in pairs(v) do
local p = { par }
if all_prefix then
local p2 = par
if (prefix == "_16x9") then
p2 = string.gsub(p2, "_16x9", "")
else
p2 = p2 .. "_16x9"
end
p[2] = p2
end
for i=1,#p do
ltx:SetValue(sec, p[i], val)
-- Cache values for the first time so you can return to it upon reseting values
local cached_val = ini_cc:r_value(sec, p[i])
if not (cached_val and cached_val ~= "") then
local val_old = ini_sys:r_string_ex(sec, p[i])
ini_cc:w_value(sec, p[i], val_old)
end
printf("% WpnHudEditor | saving [%s]->[%s]->[%s]",sec, p[i], val)
end
end
ltx:SaveExt()
to_save[sec] = nil
save_done = true
self:Print(nil, "Applied and saved the new values for [%s]\\nFile: %s", sec, t_dir .. filename)
printf("% WpnHudEditor | saved changes for {%s}", fullpath)
end
end
end
end
end
end
local sp = getFS():update_path('$game_config$', t_dir)
sp = string.sub(sp,0,string.len(sp)-1)
lua_ext.recurse_subdirectories_and_execute(sp,{"ltx"},on_execute)
-- Reload system_ini() to adapt the new values in game
reload_ini_sys()
self:Reset()
if (not save_done) then
self:Print(nil, "No changes are made on [%s].\\nKeep in mind that configs must be unpacked before applying changes!", section)
else
-- Cache original values
ini_cc:save()
-- Remove cached HUD model from engine, so it updates to the new values
hud_adjust.remove_hud_model(section)
-- Close the UI
self:Close()
local str = strformat( "Changes are saved to [%s]", section)
actor_menu.set_msg(1, str,5)
-- Clean memory of this section to adapt the new changes
_memo[section] = nil
_memo_i[section] = nil
end
end
function WpnHudEditor:OnButtonAlign()
if self._h:IsShown() then
self._h:Show(false)
self._w:Show(false)
exec_console_cmd("hud_crosshair off")
print_dbg("! WpnHudEditor | Hide alignments")
else
self._h:Show(true)
self._w:Show(true)
exec_console_cmd("hud_crosshair on")
print_dbg("- WpnHudEditor | Show alignments")
end
end
function WpnHudEditor:OnButtonResume()
self:Close()
-- Resume normal hud behavior
hud_adjust.enabled(false)
adjust_active = false
actor_menu.set_msg(1, "HUD adjust mode is stopped",5)
--ui = nil
end
function WpnHudEditor:CleanMemo()
empty_table(_memo)
empty_table(_memo_i)
self:Reset(false)
self:Send_MSG("Cleared memory!")
end
function WpnHudEditor:SwitchParam(state, vert)
local v = self.active_table
local function get_param_index(state, vert)
--// Vertical movement
if vert then
local jumps = ((jump == jump_3) and 3) or ((jump == jump_2) and 2) or 1
if state then
self.data[v].selected_group = self.data[v].selected_group + jumps
else
self.data[v].selected_group = self.data[v].selected_group - jumps
end
if (self.data[v].selected_group > #self.data[v].cnt_group) then
self.data[v].selected_group = 1
elseif (self.data[v].selected_group < 1) then
self.data[v].selected_group = #self.data[v].cnt_group
end
return self.data[v].cnt_group[self.data[v].selected_group][1]
--// Horizental movement
else
print_dbg("selected_group: %s", self.data[v].selected_group)
local group = self.data[v].cnt_group[self.data[v].selected_group]
if group then
local first = group[1]
local last = group[#group]
if state and (self.data[v].selected < last) then
self.data[v].selected = self.data[v].selected + 1
elseif (not state) and (self.data[v].selected > first) then
self.data[v].selected = self.data[v].selected - 1
end
else
printe("! group doesn't exist for selected_group: %s", self.data[v].selected_group)
end
return self.data[v].selected
end
end
if (not self.data[v].selected) or (not self.data[v].selected_group) then
self.data[v].selected = _selected[v] or 1
self.data[v].selected_group = _selected_group[v] or 1
else
self.data[v].par_hl[self.data[v].selected]:Show(false)
self.data[v].selected = get_param_index(state, vert)
end
self.data[v].par_hl[self.data[v].selected]:Show(true)
_selected[v] = self.data[v].selected
_selected_group[v] = self.data[v].selected_group
end
function WpnHudEditor:SwitchParamByIndex(group, index)
local v = self.active_table
self.data[v].par_hl[self.data[v].selected]:Show(false)
self.data[v].selected_group = group
self.data[v].selected = index
self.data[v].par_hl[self.data[v].selected]:Show(true)
_selected[v] = self.data[v].selected
_selected_group[v] = self.data[v].selected_group
end
function WpnHudEditor:SwitchValue(state, selected, extra_k)
local v = self.active_table
if not extra_k then extra_k = 1 end
if not (selected) then
return
end
local n = selected
local typ = self.data[v].typ[n]
local parent = self.data[v].parent[n]
local val = self.data[v].value[n]
local new_val
if typ ~= 0 then
local input_val = self.data[v].par[n]:GetText()
local curr_val = (not self:IsInvalidValue(n,typ,input_val)) and tonumber(input_val)
if (not curr_val) then
self:Send_MSG("Couldn't read previous input for parameter (%s)", self.data[v].name[n])
return
end
curr_val = round_idp(curr_val, precision)
local max_val = v[parent].max
local min_val = v[parent].min
local step = v[parent].step * jump * extra_k
if state then
curr_val = curr_val + step
else
curr_val = curr_val - step
end
local precision = precision
if curr_val > 100 then
precision = precision - 2
elseif curr_val > 10 then
precision = precision - 1
end
curr_val = round_idp(curr_val, precision)
new_val = clamp(curr_val, min_val, max_val)
else
local curr_val = self.data[v].par[n]:GetText()
if (not curr_val) then
return
end
if not (self.data[v].par_list_n[n]) then
return
end
if (not self.data[v].index[n]) then
for i=1,#self.data[v].par_list_n[n] do
if (self.data[v].par_list_n[n][i] == curr_val) then
self.data[v].index[n] = i
break
end
end
if (not self.data[v].index[n]) then
return
end
end
local num = #self.data[v].par_list_n[n]
if state then
self.data[v].index[n] = (self.data[v].index[n] < num) and (self.data[v].index[n] + 1) or self.data[v].index[n]
else
self.data[v].index[n] = (self.data[v].index[n] > 0) and (self.data[v].index[n] - 1) or self.data[v].index[n]
end
local txt = self.data[v].par_list_n[n][self.data[v].index[n]]
if self:IsInvalidValue(n,0,txt) then
self:Send_MSG("Invalid path/section for parameter (%s)", self.data[v].name[n])
return
end
new_val = txt
end
if new_val then
self.data[v].value[n] = new_val
self.data[v].par[n]:SetText(new_val)
self:SetParameterValue(n,new_val)
self:ApplyParameterValue(typ,parent,v)
-- self:Send_MSG(self.data[v].name[n] .. " := " .. self.data[v].value[n], 4)
else
self:Send_MSG("No value can be set for (%s)",self.data[v].name[n])
end
end
function WpnHudEditor:SwitchValueGroup(state, selected_group)
local v = self.active_table
if (not selected_group) then
return
end
print_dbg("/ WpnHudEditor | selected_group: %s", selected_group)
local group = self.data[v].cnt_group[selected_group]
local size = (#group > 3) and 3 or #group -- no need for alpha value
for i=1,size do
self:SwitchValue(state, group[i])
end
end
function WpnHudEditor:OnInput(cnt)
local v = self.active_table
local val = self.data[v].par[cnt]:GetText()
local typ = self.data[v].typ[cnt]
local parent = self.data[v].parent[cnt]
if self:IsInvalidValue(cnt,typ,val) then
self:Send_MSG("Error with input for parameter (%s)", self.data[v].name[cnt])
return
end
if (typ == 0) then
val = val or ""
else
val = tonumber(val)
val = round_idp(val, precision)
end
self.data[v].value[cnt] = val
self:SetParameterValue(cnt,val)
self:ApplyParameterValue(typ,parent,v)
end
function WpnHudEditor:Close()
local v = self.active_table
if v ~= parameters then
self.data[v].scroll_par:Show(false)
end
self.weapon_cobj = nil
self.active_table = parameters
local v = self.active_table
self.data[v].scroll_par:Show(true)
self.third_person_mode = false
self:ResetSelects()
self:StopCam()
self:DisableWCT(false)
self:HideDialog()
self:Show(false)
--ui = nil
if adjust_active then
actor_menu.set_msg(1, "HUD adjust mode is still active",5)
end
exec_console_cmd("hud_crosshair " .. (self.crosshair and "on" or "off"))
UnregisterScriptCallback("on_key_release",on_key_release)
UnregisterScriptCallback("on_key_hold",on_key_hold)
Unregister_UI("WpnHudEditor")
if (level.present()) then
printf("- main_menu off")
exec_console_cmd("main_menu off")
end
end
local K_M1 = DIK_keys.MOUSE_1
local K_M2 = DIK_keys.MOUSE_2
local K_M3 = DIK_keys.MOUSE_3
local E_PRESS = ui_events.WINDOW_KEY_PRESSED
local E_RELEASE = ui_events.WINDOW_KEY_RELEASED
function WpnHudEditor:OnKeyboard(dik, keyboard_action)
local v = self.active_table
local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
if (res == false) then
local bind = dik_to_bind(dik)
-- Mouse
if dik == K_M1 or dik == K_M2 or (dik == K_M3 and self.third_person_mode) then
if (keyboard_action == E_PRESS) then
-- printf("mouse hold")
self.mouse_hold = dik
self.disable_drag = false
elseif (keyboard_action == E_RELEASE) then
-- printf("mouse release")
self.disable_drag = true
self.pos = nil
self.mouse_hold = nil
end
elseif keyboard_action == ui_events.WINDOW_KEY_PRESSED then
if dik == DIK_keys.DIK_NUMPAD8 then
self:SwitchValue(true, self.data[v].selected)
elseif dik == DIK_keys.DIK_NUMPAD2 then
self:SwitchValue(false, self.data[v].selected)
elseif dik == DIK_keys.DIK_NUMPAD9 then
self:SwitchValueGroup(true, self.data[v].selected_group)
elseif dik == DIK_keys.DIK_NUMPAD3 then
self:SwitchValueGroup(false, self.data[v].selected_group)
elseif dik == DIK_keys.DIK_NUMPADENTER then
self.save_mode = not self.save_mode
self:Print(nil, self.save_mode == true and "save to cache_dbg.ltx" or "vanilla save")
elseif dik == DIK_keys.DIK_NUMPAD1 then
self:CleanCacheDbg()
elseif dik == DIK_keys.DIK_UP then
self:SwitchParam(false, true)
elseif dik == DIK_keys.DIK_DOWN then
self:SwitchParam(true, true)
elseif dik == DIK_keys.DIK_RIGHT then
self:SwitchParam(true, false)
elseif dik == DIK_keys.DIK_LEFT then
self:SwitchParam(false, false)
elseif dik == DIK_keys.DIK_NUMPAD5 then
self:OnButtonCopy()
elseif dik == DIK_keys.DIK_NUMPAD6 then
self:OnButtonPaste()
elseif dik == DIK_keys.DIK_G then
self:OnButtonAlign()
elseif dik == DIK_keys.DIK_DELETE then
self:CleanMemo()
elseif dik == DIK_keys.DIK_H then
self:ShowHint()
elseif dik == DIK_keys.DIK_ESCAPE then
self:Close()
end
end
end
return res
end
function WpnHudEditor:OnButtonThirdPerson()
if not db.actor:active_item() then
self:Print(nil, "Actor has no current item, abort")
return
end
if not (
level.set_cam_custom_position_direction
and level.remove_cam_custom_position_direction
) then
self:Print(nil, "Missing camera functions from modded exes, TP mode is unavailable")
return
end
self.third_person_mode = not self.third_person_mode
local v = self.active_table
self.data[v].scroll_par:Show(false)
if self.third_person_mode then
self.active_table = third_person_parameters
self:ResetSelects(true)
hud_adjust.enabled(false)
dummy_npc = alife_create("sim_default_stalker_0", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id())
CreateTimeEvent("ui_debug_wpn_hud_dummy", "ui_debug_wpn_hud_dummy_npc", 0, function()
local obj = level.object_by_id(dummy_npc.id)
if obj then
db.storage[obj:id()] = db.storage[obj:id()] or {}
db.storage[obj:id()].ui_debug_wpn_hud_dummy = {
state = self.dummy_npc_states[1][2]
}
obj:iterate_inventory(function(owner, item)
alife_release_id(item:id())
end, obj)
local weapon_sec = db.actor:active_item():section()
local weapon = alife_create_item(weapon_sec, obj)
CreateTimeEvent("ui_debug_wpn_hud_dummy", "ui_debug_wpn_hud_dummy_weapon", 0, function()
local w = level.object_by_id(weapon.id)
if w then
self.weapon = w
self.weapon_cobj = w:cast_Weapon()
self:ApplyThirdPersonParameterValue()
return true
end
return false
end)
self:ResetNpcCam()
return true
end
return false
end)
-- self.weapon_cobj = db.actor:active_item():cast_Weapon()
else
self.active_table = parameters
self.weapon_cobj = nil
self.weapon = nil
self:StopCam()
hud_adjust.enabled(true)
end
local v = self.active_table
self.data[v].scroll_par:Show(true)
end
-- NPC Dummy
actid = 198122
evaid = 198122
class "evaluator_stalker_ui_debug_wpn_hud_dummy" (property_evaluator)
function evaluator_stalker_ui_debug_wpn_hud_dummy:__init(npc,name,storage) super (nil, name)
self.st = storage
end
function evaluator_stalker_ui_debug_wpn_hud_dummy:evaluate()
--utils_data.debug_write("eva_panic")
local npc = self.object
local id = npc:id()
db.storage[id] = db.storage[id] or {}
local st = db.storage[id]
-- printf("checking dummy_npc %s", npc:name())
if st.ui_debug_wpn_hud_dummy then
return true
end
return false
end
class "action_stalker_ui_debug_wpn_hud_dummy" (action_base)
function action_stalker_ui_debug_wpn_hud_dummy:__init (npc,name,storage) super (nil,name)
self.st = storage
end
function action_stalker_ui_debug_wpn_hud_dummy:initialize()
action_base.initialize(self)
-- local npc = self.object
-- npc:set_desired_position()
-- npc:set_desired_direction()
self.first_update = true
end
function action_stalker_ui_debug_wpn_hud_dummy:execute()
--utils_data.debug_write(strformat("action_stalker_ui_debug_wpn_hud_dummy:execute start"))
action_base.execute(self)
local npc = self.object
--printf("enemy = %s",enemy and enemy:name())
-- ensure and enforce path type
-- if (npc:path_type() ~= game_object.level_path) then
-- npc:set_path_type(game_object.level_path)
-- end
-- printf("executing dummy_npc %s", npc:name())
npc:set_desired_position()
npc:set_desired_direction()
npc:set_dest_level_vertex_id(npc:level_vertex_id())
state_mgr.set_state(npc, db.storage[npc:id()].ui_debug_wpn_hud_dummy.state, nil, nil, {
-- look_position = self.st.lvid and level.vertex_position(self.st.lvid) or npc:position(),
-- look_object = db.actor,
-- look_dir = self.st.lvid and level.vertex_position(self.st.lvid):sub(npc:position()):normalize() or npc:direction(),
}, {
fast_set = true,
animation = true,
})
-- First update force movement
if self.first_update then
-- npc:clear_animations()
-- npc:movement_enabled(false)
-- npc:set_movement_type(move.stand)
-- npc:set_body_state(move.standing)
-- npc:set_mental_state(anim.danger)
self.first_update = false
end
end
function action_stalker_ui_debug_wpn_hud_dummy:finalize()
action_base.finalize(self)
self.first_update = true
db.storage[self.object:id()].ui_debug_wpn_hud_dummy = nil
self.object:clear_animations()
self.object:movement_enabled(true)
end
function setup_generic_scheme(npc,ini,scheme,section,stype,temp)
local st = xr_logic.assign_storage_and_bind(npc,ini,"stalker_ui_debug_wpn_hud_dummy",section,temp)
end
function add_to_binder(npc,ini,scheme,section,storage,temp)
if not npc then return end
local manager = npc:motivation_action_manager()
if not manager then return end
if not npc:alive() then
manager:add_evaluator(evaid,property_evaluator_const(false))
temp.needs_configured = false
return
end
local evaluator = evaluator_stalker_ui_debug_wpn_hud_dummy(npc,"eva_stalker_ui_debug_wpn_hud_dummy",storage)
temp.action = action_stalker_ui_debug_wpn_hud_dummy(npc,"act_stalker_ui_debug_wpn_hud_dummy",storage)
if not evaluator or not temp.action then return end
manager:add_evaluator(evaid,evaluator)
temp.action:add_precondition(world_property(stalker_ids.property_alive,true))
temp.action:add_precondition(world_property(stalker_ids.property_danger, false))
temp.action:add_precondition(world_property(evaid,true))
temp.action:add_effect(world_property(evaid,false))
manager:add_action(actid,temp.action)
--xr_logic.subscribe_action_for_events(npc, storage, temp.action)
end
function configure_actions(npc,ini,scheme,section,stype,temp)
if not npc then return end
local manager = npc:motivation_action_manager()
if not manager or not temp.action then return end
temp.action:add_precondition(world_property(xr_evaluators_id.sidor_wounded_base,false))
-- temp.action:add_precondition(world_property(xr_evaluators_id.wounded_exist,false))
-- if (_G.schemes["rx_ff"]) then
-- temp.action:add_precondition(world_property(rx_ff.evaid,false))
-- end
if (_G.schemes["gl"]) then
temp.action:add_precondition(world_property(rx_gl.evid_gl_reload,false))
end
-- if (_G.schemes["facer"]) then
-- temp.action:add_precondition(world_property(xrs_facer.evid_facer,false))
-- temp.action:add_precondition(world_property(xrs_facer.evid_steal_up_facer,false))
-- end
local action
local p = {xr_danger.actid, stalker_ids.action_combat_planner, stalker_ids.action_danger_planner, xr_actions_id.state_mgr + 2, xr_actions_id.alife}
for i=1,#p do
--printf("ACTION_ALIFE_ID(permaban_material.configure_actions): " .. tostring(p[i]))
action = manager:action(p[i])
if (action) then
action:add_precondition(world_property(evaid,false))
else
printf("axr_panic: no action id p[%s]",i)
end
end
end
function disable_generic_scheme(npc,scheme,stype)
local st = db.storage[npc:id()][scheme]
if st then
st.enabled = false
end
end
function npc_add_precondition(action)
if not action then return end
action:add_precondition(world_property(evaid,false))
end
LoadScheme("ui_debug_wpn_hud", "stalker_ui_debug_wpn_hud_dummy", modules.stype_stalker)
function on_enemy_eval(obj, enemy, flags)
if dummy_npc and (obj:id() == dummy_npc.id or enemy:id() == dummy_npc.id) then
flags.override = true
flags.result = false
end
end
function npc_on_before_hit(npc,shit,bone_id,flags)
if dummy_npc and npc:id() == dummy_npc.id then
flags.ret_value = false
end
end
function on_game_start()
local function on_localization_change()
GUI = nil -- clear ui to force initing again
end
RegisterScriptCallback("on_localization_change",on_localization_change)
RegisterScriptCallback("on_enemy_eval", on_enemy_eval)
RegisterScriptCallback("npc_on_before_hit", npc_on_before_hit)
end