Divergent/mods/Screen Space Shaders/gamedata/scripts/ssfx_weapons_dof.script

552 lines
14 KiB
Plaintext
Raw Permalink Normal View History

2024-03-17 20:18:03 -04:00
-- @ Version: SCREEN SPACE SHADERS - UPDATE 17
-- @ Description: Weapons DOF script
-- @ Author: https://www.moddb.com/members/ascii1457
-- @ Mod: https://www.moddb.com/mods/stalker-anomaly/addons/screen-space-shaders
-- Internal vars
local ssfx_wpn_dof_minlen = 0
local ssfx_wpn_dof_maxlen = 0
local ssfx_wpn_dof_blur = 0
local ssfx_wpn_dof_edgeblur = 0
local ssfx_wpn_dof_aim_minlen = 0
local ssfx_wpn_dof_aim_maxlen = 0
local ssfx_wpn_dof_aim_blur = 0
local ssfx_wpn_dof_aim_edgeblur = 0
local ssfx_wpn_dof_reload = true
local ssfx_wpn_dof_pda = true
local ssfx_wpn_dof_inventory = true
local ssfx_wpn_dof_FDDA = true
local ssfx_wpn_dof_loot_mutant = true
-- Weapons that have kind "pistol" but aren't pistols
local ssfx_not_pistol = {
wpn_svt40_short = true,
wpn_avt40_short = true,
wpn_aek919k = true,
}
local ssfx_wpn_dof_blur_current = 0.0
local ssfx_wpn_dof_blur_to = 0.0
local ssfx_reloading = 0
local ssfx_reloadtime = 0
local ssfx_reloadforce_end = 0
local ssfx_wpn_one_shot = false
local ssfx_wpn_state = 0
local ssfx_inv_state = 0
local ssfx_itm_state = 0
local ssfx_pda_state = 0
local ssfx_pda_zoom = 0
local ssfx_itm_in_use
local ssfx_wpn_reloadtime_save = {}
-- Load FDDA settigns if exist
local ssfx_items_anim = ini_file("items\\items\\animations_settings.ltx") or {}
local tg_update = 0
local function ssfx_aim_in()
-- Apply aim DOF
if (not ssfx_check_item()) then
ssfx_set_dof(ssfx_wpn_dof_aim_minlen, ssfx_wpn_dof_aim_maxlen, 0, ssfx_wpn_dof_aim_blur)
ssfx_wpn_state = 1
else
ssfx_wpn_state = 2
get_console():execute("ssfx_wpn_dof_1 (0,0,0," .. ssfx_wpn_dof_aim_blur .. ")")
end
get_console():execute("ssfx_wpn_dof_2 " .. ssfx_wpn_dof_aim_edgeblur )
end
local function ssfx_aim_out()
-- Apply default DOF
ssfx_set_dof(ssfx_wpn_dof_minlen, ssfx_wpn_dof_maxlen, 0, ssfx_wpn_dof_blur)
get_console():execute("ssfx_wpn_dof_2 " .. ssfx_wpn_dof_edgeblur )
ssfx_wpn_state = 0
end
-- End Item animation
local function ssfx_item_anim_stop()
ssfx_itm_state = 0
ssfx_far_blur(0, 0)
return true
end
-- Use Item
local original_function = itms_manager.actor_on_item_before_use
function itms_manager.actor_on_item_before_use(obj,flags)
original_function(obj,flags)
if ssfx_wpn_dof_FDDA == false then
return
end
-- Item passes the utilization checks? only_movekeys is only true if check is ok ( FDDA reset the flags.ret_value )
if game.only_movekeys_allowed() then
ssfx_itm_state = 1
ssfx_itm_in_use = obj:section()
end
end
-- Loot monsters with FFDA
local function ssfx_monster_on_actor_use(obj)
if (ssfx_wpn_dof_loot_mutant == false) then
return
end
ssfx_itm_state = 1
ssfx_itm_in_use = "mutant_looting"
end
local function GUI_on_show(name)
if ssfx_wpn_dof_loot_mutant == false then return end
if name == "UIMutantLoot" then -- Remove time animation end if loot UIMutantLoot GUI shows
RemoveTimeEvent("ssfx_endanim", "ssfx_item_anim_stop")
-- Even without the FFDA animation, we want DOF with the UI
ssfx_itm_state = 2
ssfx_far_blur(1, 0)
end
end
local function GUI_on_hide(name)
if name == "UIMutantLoot" then -- Remove DOF if UIMutantLoot GUI hide
ssfx_item_anim_stop()
end
end
-- Check for PDA zoom
local function ssfx_on_key_press(dik)
if ssfx_pda_state ~= 2 then return end
local bind = dik_to_bind(dik)
local kb = key_bindings
if bind == kb.kWPN_ZOOM or bind == kb.kWPN_FIRE or bind == kb.kWPN_RELOAD then
if bind == kb.kWPN_RELOAD then
ssfx_pda_zoom = 1 - ssfx_pda_zoom
else
ssfx_pda_zoom = 1
end
end
end
-- Check PDA states
local function ssfx_PDA_state()
if ssfx_pda_state == 0 or ssfx_wpn_dof_pda == false then
return
end
-- Sprint disable PDA zoom
if IsMoveState("mcSprint") then
ssfx_pda_zoom = 0
end
-- PDA states
if ssfx_pda_state == 1 then
-- Wait for 100% ready
itm = db.actor:active_item()
if itm then
if itm:get_state() == 0 then ssfx_pda_state = 2 end
end
elseif ssfx_pda_state == 2 then
-- If Zoom, Enable DOF
if ssfx_pda_zoom == 1 then
ssfx_far_blur(1, 0)
else
ssfx_wpn_dof_minlen = 0
ssfx_wpn_dof_maxlen = 0
ssfx_far_blur(0, 0)
end
end
end
-- Function to end the PDA state
local function ssfx_PDA_reset()
ssfx_wpn_dof_minlen = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "fadestart", ssfx_weapons_dof_settings)
ssfx_wpn_dof_maxlen = ssfx_wpn_dof_minlen + ssfx_001_mcm.ssfx_get_setting("wpn_dof", "fadelen", ssfx_weapons_dof_settings)
ssfx_far_blur(0, 0)
ssfx_pda_state = 0
ssfx_pda_zoom = 0
end
local function actor_on_update()
-- Check Inventory, Reloading, PDA and Items states
ssfx_PDA_state() -- Outside the tick limit to avoid any unsync ( The zoom code is very hacky )
-- Not necessary to check every tick, let's update each 100ms
local tg = time_global()
if tg < tg_update then
return
end
tg_update = tg + 100
local itm = db.actor:active_item()
local slot = db.actor:active_slot()
local is_weapon = itm and IsWeapon(itm) or false
local is_pda = itm and slot == 8 or slot == 14 or false
local sec = nil
-- Item usage FDDA
if ssfx_itm_state == 1 then
if not db.actor:active_detector() and slot == 0 then -- ( Without a detector equiped and using slot 0 )
-- Change item state
ssfx_itm_state = 2
-- Get the animation time
local tm = ssfx_items_anim:r_float_ex(ssfx_itm_in_use, "tm")
if not tm then
ssfx_itm_state = 0
tm = 0
end
if ssfx_itm_in_use == "mutant_looting" then
tm = 4500
end
if tm > 0 then
-- Initialize far blur
ssfx_far_blur(1, 0)
-- Millisecs to secs
anim_tm = tm * 0.001
-- 70% of the animation or custom from settings...
if ssfx_weapons_dof_settings.items_time[ssfx_itm_in_use] then
anim_tm = anim_tm * ssfx_weapons_dof_settings.items_time[ssfx_itm_in_use]
else
anim_tm = anim_tm * 0.7
end
-- Create end of animation event
CreateTimeEvent("ssfx_endanim", "ssfx_item_anim_stop", anim_tm, ssfx_item_anim_stop)
end
end
end
-- Inventory stuff ( "Inventory" = 1 -- "trade" = 2 -- "repair" = 3 -- "loot" = 4 )
if actor_menu.last_mode == 1 and ssfx_wpn_dof_inventory then
if (ssfx_inv_state == 0) then
ssfx_inv_state = 1
ssfx_far_blur(1, 0)
end
else
if (ssfx_inv_state == 1) then
ssfx_inv_state = 0
ssfx_far_blur(0, ssfx_reloading + ssfx_itm_state)
end
end
-- PDA stuff
if is_pda then
local itm_state = itm:get_state()
if itm_state == 1 then -- Show PDA
ssfx_pda_state = 1
ssfx_set_dof(0, 0, 0, ssfx_wpn_dof_blur)
elseif itm_state == 2 then -- Hide PDA
ssfx_PDA_reset()
end
end
-- Reload stuff ( "Idle" = 0 -- "Raise" = 1 -- "Lower" = 2 -- "Reload" = 7 )
if is_weapon and ssfx_wpn_dof_reload then
--printf( "DEBUG %s", game.get_motion_length(itm:section(), "anm_reload", 1) )
-- Reload states
if ssfx_reloading == 0 then -- Idle
if itm:get_state() == 7 then -- Reload start
sec = itm:section()
-- Pump action, bold action, etc.
ssfx_wpn_one_shot = (ini_sys:r_string_ex(sec, "tri_state_reload") == "on") or (ini_sys:r_string_ex(sec, "class") == "WP_BM16")
ssfx_reloading = 1 -- Reloading
ssfx_far_blur(1, 0)
ssfx_reloadtime = tg
-- Check if we know the reload animation length, omit if ssfx_wpn_one_shot true
if ssfx_wpn_reloadtime_save[sec] or ssfx_weapons_dof_settings.wpn_reloadtime[sec] then
if not ssfx_wpn_one_shot then
-- Stop DOF at 80% of the animation
local anim_percentage = 0.8
-- Pistols lower the %
if SYS_GetParam(0, sec, "kind", "") == "w_pistol" and not ssfx_not_pistol[sec] then
anim_percentage = 0.7
end
-- From reloatime file or save
if ssfx_weapons_dof_settings.wpn_reloadtime[sec] then
ssfx_reloadforce_end = ssfx_weapons_dof_settings.wpn_reloadtime[sec] * anim_percentage -- % of animation
else
ssfx_reloadforce_end = ssfx_wpn_reloadtime_save[sec] * anim_percentage -- % of animation
end
end
else
ssfx_reloadforce_end = nil
end
end
elseif ssfx_reloading == 1 then -- Reload in progress...
if ssfx_reloadforce_end then
-- End reload if reload time
if (tg - ssfx_reloadtime) > ssfx_reloadforce_end then
ssfx_far_blur(0, ssfx_inv_state)
ssfx_reloading = 2 -- Wait animation to end
end
else
sec = itm:section()
-- End reload if current ammo == mag size
if itm:get_ammo_in_magazine() == ini_sys:r_u32(sec, "ammo_mag_size") then
ssfx_far_blur(0, ssfx_inv_state)
ssfx_reloading = 2 -- Wait animation to end
-- Save time if not ssfx_wpn_one_shot
if not ssfx_wpn_one_shot then
ssfx_wpn_reloadtime_save[sec] = tg - ssfx_reloadtime
end
end
end
end
-- Wait for the end of the reloading animation or any other state.
if itm:get_state() ~= 7 and ssfx_reloading > 0 then
ssfx_far_blur(0, ssfx_inv_state)
ssfx_reloading = 0
end
end
-- If weapon or PDA is dropped
if itm == nil then
if ssfx_reloading > 0 then
ssfx_far_blur(0, ssfx_inv_state)
ssfx_reloading = 0
end
if ssfx_pda_state > 0 then
ssfx_PDA_reset()
end
end
end
local function ssfx_change_blur()
-- Smooth to target
local smoothed = ssfx_diminish()
if (ssfx_wpn_dof_blur_to == 1) then
ssfx_set_dof(0, 0, smoothed, ssfx_wpn_dof_blur)
else
ssfx_set_dof(ssfx_wpn_dof_minlen, ssfx_wpn_dof_maxlen, smoothed, ssfx_wpn_dof_blur)
end
if (smoothed == ssfx_wpn_dof_blur_to) then
ssfx_stop_blur()
end
end
function ssfx_far_blur(to_val, checkvar)
if checkvar > 0 then return end
if (ssfx_wpn_dof_blur_to ~= to_val) then
ssfx_stop_blur()
ssfx_wpn_dof_blur_to = to_val
RegisterScriptCallback("actor_on_update", ssfx_change_blur)
end
end
function ssfx_stop_blur()
UnregisterScriptCallback("actor_on_update", ssfx_change_blur)
end
function ssfx_check_item()
local itm = db.actor:active_item()
if itm then
local name = itm:section() or nil
if (name and ssfx_weapons_dof_settings.wpn_nodof[name]) then
return true
end
end
return false
end
function ssfx_diminish()
-- Frame independent smoothing
local smoothing = math.min(0.1 * device().time_delta / 20, 0.19)
-- Let's go!
if (ssfx_wpn_dof_blur_current < ssfx_wpn_dof_blur_to) then
ssfx_wpn_dof_blur_current = ssfx_wpn_dof_blur_current + smoothing
else
ssfx_wpn_dof_blur_current = ssfx_wpn_dof_blur_current - smoothing
end
if math.abs(ssfx_wpn_dof_blur_current - ssfx_wpn_dof_blur_to) <= 0.1 then
ssfx_wpn_dof_blur_current = ssfx_wpn_dof_blur_to
end
return ssfx_wpn_dof_blur_current
end
function ssfx_set_dof(var1, var2, var3, var4)
ssfx_wpn_dof_blur_current = var3
get_console():execute("ssfx_wpn_dof_1 (" .. var1 .. "," .. var2 .. "," .. var3 .. "," .. var4 .. ")")
end
function actor_on_first_update()
-- Let's be sure
ssfx_aim_out()
end
local function save_state(mdata)
-- Save reload times
mdata.ssfx_saved_reload_time = ssfx_wpn_reloadtime_save
end
local function load_state(mdata)
-- Load reload times
ssfx_wpn_reloadtime_save = mdata.ssfx_saved_reload_time or {}
end
function on_option_change()
-- Force DOF
get_console():execute("r2_dof_enable 1")
-- Get settings
ssfx_wpn_dof_minlen = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "fadestart", ssfx_weapons_dof_settings)
ssfx_wpn_dof_maxlen = ssfx_wpn_dof_minlen + ssfx_001_mcm.ssfx_get_setting("wpn_dof", "fadelen", ssfx_weapons_dof_settings)
ssfx_wpn_dof_blur = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "blur", ssfx_weapons_dof_settings)
ssfx_wpn_dof_edgeblur = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "edgeblur", ssfx_weapons_dof_settings) / 2
ssfx_wpn_dof_aim_minlen = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "aim_fadestart", ssfx_weapons_dof_settings)
ssfx_wpn_dof_aim_maxlen = ssfx_wpn_dof_aim_minlen + ssfx_001_mcm.ssfx_get_setting("wpn_dof", "aim_fadelen", ssfx_weapons_dof_settings)
ssfx_wpn_dof_aim_blur = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "aim_blur", ssfx_weapons_dof_settings)
ssfx_wpn_dof_aim_edgeblur = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "aim_edgeblur", ssfx_weapons_dof_settings) / 2
ssfx_wpn_dof_reload = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "reloading", ssfx_weapons_dof_settings)
ssfx_wpn_dof_pda = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "pda", ssfx_weapons_dof_settings)
ssfx_wpn_dof_inventory = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "inventory", ssfx_weapons_dof_settings)
ssfx_wpn_dof_FDDA = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "fdda", ssfx_weapons_dof_settings)
ssfx_wpn_dof_loot_mutant = ssfx_001_mcm.ssfx_get_setting("wpn_dof", "looting_mutant", ssfx_weapons_dof_settings)
-- Apply settings to current state
-- Weapon
if ssfx_wpn_state == 0 then -- IDLE
ssfx_set_dof(ssfx_wpn_dof_minlen, ssfx_wpn_dof_maxlen, 0, ssfx_wpn_dof_blur)
get_console():execute("ssfx_wpn_dof_2 " .. ssfx_wpn_dof_edgeblur )
elseif ssfx_wpn_state == 1 then -- Aim
ssfx_set_dof(ssfx_wpn_dof_aim_minlen, ssfx_wpn_dof_aim_maxlen, 0, ssfx_wpn_dof_aim_blur)
get_console():execute("ssfx_wpn_dof_2 " .. ssfx_wpn_dof_aim_edgeblur )
elseif ssfx_wpn_state == 2 then -- Aim no DOF
get_console():execute("ssfx_wpn_dof_2 " .. ssfx_wpn_dof_aim_edgeblur )
end
-- Reload
if ssfx_reloading > 0 and ssfx_wpn_dof_reload ~= true then
ssfx_far_blur(0, ssfx_inv_state)
ssfx_reloading = 0
end
-- Inventory
if actor_menu.last_mode == 1 and ssfx_wpn_dof_inventory ~= true then
ssfx_inv_state = 0
ssfx_far_blur(0, ssfx_reloading)
end
-- FDAA or Looting mutant
if enhanced_animations == nil then
ssfx_wpn_dof_FDDA = false
else
if enhanced_animations.enable_animations == false then
ssfx_wpn_dof_FDDA = false
end
end
if ssfx_wpn_dof_FDDA == false or ssfx_wpn_dof_loot_mutant == false then
if ssfx_itm_state > 0 then
ssfx_itm_state = 0
ssfx_far_blur(0, ssfx_reloading)
end
end
-- PDA Zoom
if ssfx_wpn_dof_pda then
RegisterScriptCallback("on_key_press", ssfx_on_key_press)
else
UnregisterScriptCallback("on_key_press", ssfx_on_key_press)
end
end
function on_game_start()
-- General Functions
RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
RegisterScriptCallback("on_option_change", on_option_change)
RegisterScriptCallback("actor_on_update", actor_on_update)
-- Save reload times
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
-- Weapon
RegisterScriptCallback("actor_on_weapon_zoom_in", ssfx_aim_in)
RegisterScriptCallback("actor_on_weapon_zoom_out", ssfx_aim_out)
-- Used for mutant loot
RegisterScriptCallback("GUI_on_show", GUI_on_show)
RegisterScriptCallback("GUI_on_hide", GUI_on_hide)
RegisterScriptCallback("monster_on_actor_use_callback",ssfx_monster_on_actor_use)
-- Read and apply settigns
on_option_change()
end