439 lines
15 KiB
Plaintext
439 lines
15 KiB
Plaintext
|
------------------------------- mcm stuff --------------------------------------
|
||
|
local weapon_sway_enable = weapon_sway_mcm.get_config("weapon_sway_feature")
|
||
|
local aim_anm = weapon_sway_mcm.get_config("animation_type")
|
||
|
local max_effect_power = weapon_sway_mcm.get_config("max_effect_power")
|
||
|
local sway_keybind = weapon_sway_mcm.get_config("sway_keybind")
|
||
|
|
||
|
local power_stand = weapon_sway_mcm.get_config("power_stand")
|
||
|
local power_crouch = weapon_sway_mcm.get_config("power_crouch")
|
||
|
local power_low_crouch = weapon_sway_mcm.get_config("power_low_crouch")
|
||
|
|
||
|
local power_stand_scoped = weapon_sway_mcm.get_config("power_stand_scoped")
|
||
|
local power_crouch_scoped = weapon_sway_mcm.get_config("power_crouch_scoped")
|
||
|
local power_low_crouch_scoped = weapon_sway_mcm.get_config("power_low_crouch_scoped")
|
||
|
|
||
|
local weapon_mount_feature = weapon_sway_mcm.get_config("weapon_mount_feature")
|
||
|
local weapon_mounted_power = weapon_sway_mcm.get_config("weapon_mounted_power")
|
||
|
local y_axis_mounted_distance = weapon_sway_mcm.get_config("y_axis_mounted_distance")
|
||
|
|
||
|
local weapon_handling_mult = weapon_sway_mcm.get_config("handling_mult")
|
||
|
|
||
|
local weight_factor = weapon_sway_mcm.get_config("weight_factor")
|
||
|
local max_power_weight = weapon_sway_mcm.get_config("max_power_weight")
|
||
|
|
||
|
local hold_breath_feature = weapon_sway_mcm.get_config("hold_breath_feature")
|
||
|
local enable_breath_sound = weapon_sway_mcm.get_config("enable_breath_sound")
|
||
|
local breath_restore_mult = weapon_sway_mcm.get_config("breath_restore_mult")
|
||
|
local max_hold_breath_time = weapon_sway_mcm.get_config("max_hold_breath_time")
|
||
|
|
||
|
local hold_breath_mult = weapon_sway_mcm.get_config("hold_breath_mult")
|
||
|
local release_breath_mult = weapon_sway_mcm.get_config("release_breath_mult")
|
||
|
|
||
|
local weapon_sway_debug = weapon_sway_mcm.get_config("debugx")
|
||
|
|
||
|
------------------------------- mcm patch --------------------------------------
|
||
|
local bhs_patch = 1
|
||
|
local effects_mult = zzz_player_injuries.effects_mult -- If you changed this in BHS script - you need to change it here too
|
||
|
|
||
|
-- demonized's and Raven's magic, i dont even know how it works
|
||
|
if zzz_player_injuries then
|
||
|
zzz_player_injuries.RegisterScriptCallback = function(k, func)
|
||
|
if not (k == "actor_on_weapon_zoom_in") then
|
||
|
_G.RegisterScriptCallback(k, func)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
------------------------------- main ----------------------------------
|
||
|
local zoom_flag = false
|
||
|
local holding_breath = false
|
||
|
local breath_held_for = 0
|
||
|
|
||
|
function weapon_sway()
|
||
|
local wpn = db.actor:active_item()
|
||
|
if not (wpn and IsWeapon(wpn)) then return end
|
||
|
if (IsMelee(wpn)) then return end
|
||
|
|
||
|
local wpn_sec = wpn:section()
|
||
|
if not wpn_sec then return end
|
||
|
|
||
|
local wpn_scoped = wpn:weapon_is_scope()
|
||
|
local handling = utils_ui.prop_handling(wpn, wpn_sec)
|
||
|
|
||
|
-- anm power mults
|
||
|
local body_mult = get_body_state_power(wpn, wpn_scoped) or 1 -- power based on body state
|
||
|
local extra_mult = wpn_scoped and 0.02 or 0.1 -- reduce scoped anm power
|
||
|
local mount_mult = wpn_mounted() and weapon_mounted_power or 1 -- weapon mounted
|
||
|
local handling_mult = handling and ((2.5 - 0.02 * handling * 100)^weapon_handling_mult) or 1 -- handling
|
||
|
local weight = get_weight_power(wpn_sec) and clamp(get_weight_power(wpn_sec) * weight_factor, 0.01, max_power_weight) or 1 -- weight factor
|
||
|
local breath_mult = holding_breath and hold_breath_mult or 1 + breath_held_for * release_breath_mult -- breath mult
|
||
|
|
||
|
-- Summary power
|
||
|
local cam_power = body_mult * weight * extra_mult * mount_mult * breath_mult * handling_mult
|
||
|
cam_power = clamp(cam_power, 0, max_effect_power)
|
||
|
|
||
|
-- Play anim or Change its power
|
||
|
if level.check_cam_effector(99215) then
|
||
|
level.set_cam_effector_factor(99215, cam_power)
|
||
|
else
|
||
|
level.add_cam_effector("weapon_sway\\sway_" .. aim_anm .. ".anm", 99215, true, "", 0, true, cam_power)
|
||
|
end
|
||
|
|
||
|
|
||
|
-- dbg
|
||
|
if not weapon_sway_debug then return end
|
||
|
actor_menu.set_msg(1, strformat("weight_mult: %s | handling_mult: %s | Total Power: %s", r(weight), r(handling_mult), r(cam_power)))
|
||
|
|
||
|
end
|
||
|
|
||
|
function weapon_sway_remove()
|
||
|
level.remove_cam_effector(99215)
|
||
|
end
|
||
|
|
||
|
----------------------- manage breath ------------------------
|
||
|
-- start holding breath
|
||
|
local press_tg = 0
|
||
|
function on_key_press(key)
|
||
|
if not weapon_sway_enable then return end
|
||
|
if not hold_breath_feature then return end
|
||
|
|
||
|
-- when we aiming and press "hold breath" button
|
||
|
if not (zoom_flag and key == sway_keybind) then return end
|
||
|
|
||
|
-- set "holding_breath" to TRUE
|
||
|
holding_breath = true
|
||
|
|
||
|
local tg = time_global()
|
||
|
if tg < press_tg then return end
|
||
|
press_tg = tg + 2000 -- against people who trying their best to break it ;]
|
||
|
|
||
|
-- and play hold sound
|
||
|
breath_snd_hold()
|
||
|
|
||
|
end
|
||
|
|
||
|
-- increase/decrease breath hold
|
||
|
local breath_tmr = 0
|
||
|
function breath_update()
|
||
|
local tg = time_global()
|
||
|
if tg < breath_tmr then return end
|
||
|
breath_tmr = tg + 250
|
||
|
|
||
|
-- increase "breath_held_for" if hold, decrease "breath_held_for" otherwise
|
||
|
breath_held_for = holding_breath and breath_held_for + 0.25 or breath_held_for - 0.25 * breath_restore_mult
|
||
|
breath_held_for = clamp(breath_held_for, 0, max_hold_breath_time)
|
||
|
|
||
|
-- end holding breath if reached max time
|
||
|
if breath_held_for < max_hold_breath_time then return end
|
||
|
|
||
|
-- to give at least 1 sec if someone tries to spam it xd
|
||
|
breath_held_for = breath_held_for - 1
|
||
|
|
||
|
-- set "holding_breath" to FALSE
|
||
|
holding_breath = false
|
||
|
|
||
|
-- and play release sound
|
||
|
breath_snd_release()
|
||
|
|
||
|
end
|
||
|
|
||
|
-- end holding breath on key
|
||
|
function on_key_release(key)
|
||
|
if not (zoom_flag and holding_breath and key == sway_keybind) then return end
|
||
|
|
||
|
-- set "holding_breath" to FALSE
|
||
|
holding_breath = false
|
||
|
|
||
|
-- if breath was held for more than 3 seconds - play release sound
|
||
|
if breath_held_for > 3 then
|
||
|
breath_snd_release()
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
function breath_snd_hold()
|
||
|
if not enable_breath_sound then return end
|
||
|
local snd_hold = sound_object("weapon_sway\\hold_1")
|
||
|
snd_hold:play_no_feedback(db.actor, sound_object.s2d, 0, VEC_ZERO, 1.0, 1.0)
|
||
|
end
|
||
|
|
||
|
function breath_snd_release()
|
||
|
if not enable_breath_sound then return end
|
||
|
local snd_release = sound_object("weapon_sway\\release_1")
|
||
|
snd_release:play_no_feedback(db.actor, sound_object.s2d, 0, VEC_ZERO, 1.0, 1.0)
|
||
|
end
|
||
|
|
||
|
----------------------- power mults ------------------------
|
||
|
function get_body_state_power(wpn, scope)
|
||
|
local body_state = get_body_state()
|
||
|
if not body_state then return end
|
||
|
|
||
|
local body_mult = 1
|
||
|
body_mult = scope and power_stand_scoped or power_stand
|
||
|
|
||
|
if body_state == "crouch" then
|
||
|
body_mult = scope and power_crouch_scoped or power_crouch
|
||
|
elseif body_state == "low_crouch" then
|
||
|
body_mult = scope and power_low_crouch_scoped or power_low_crouch
|
||
|
end
|
||
|
|
||
|
return body_mult
|
||
|
end
|
||
|
|
||
|
function wpn_mounted()
|
||
|
if not weapon_mount_feature then return end
|
||
|
|
||
|
local rp_diff = get_rp_diff()
|
||
|
|
||
|
return rp_diff > 0.1
|
||
|
end
|
||
|
|
||
|
function get_weight_power(wpn_sec)
|
||
|
if not ini_sys:section_exist(wpn_sec, "inv_weight") then return end
|
||
|
|
||
|
return ini_sys:r_float_ex(wpn_sec, "inv_weight")
|
||
|
end
|
||
|
|
||
|
----------------------- utils ------------------------
|
||
|
function get_body_state()
|
||
|
local crouch = IsMoveState('mcCrouch')
|
||
|
local accel = IsMoveState('mcAccel')
|
||
|
local body_st = "stand"
|
||
|
|
||
|
if crouch then
|
||
|
if accel then
|
||
|
body_st = "low_crouch"
|
||
|
else
|
||
|
body_st = "crouch"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return body_st
|
||
|
end
|
||
|
|
||
|
function ray_pick_dir(add_x, add_y, add_z, range)
|
||
|
local pos = device().cam_pos
|
||
|
local dir = device().cam_dir
|
||
|
local vec_x = dir.x + add_x
|
||
|
local vec_y = dir.y + add_y
|
||
|
local vec_z = dir.z + add_z
|
||
|
vec_x = clamp( r(vec_x), -1, 1)
|
||
|
vec_y = clamp( r(vec_y), -1, 1)
|
||
|
vec_z = clamp( r(vec_z), -1, 1)
|
||
|
|
||
|
-- dbg
|
||
|
if weapon_sway_debug then
|
||
|
printf("--------------------")
|
||
|
printf("dir: %s", dir)
|
||
|
printf("edited dir: x: %s, y: %s, z: %s", vec_x, vec_y, vec_z)
|
||
|
end
|
||
|
|
||
|
local pick = ray_pick()
|
||
|
pick:set_position(pos)
|
||
|
pick:set_direction(vector():set(vec_x, vec_y, vec_z))
|
||
|
pick:set_flags(2)
|
||
|
pick:set_range(range)
|
||
|
pick:query()
|
||
|
local distance = pick:get_distance()
|
||
|
|
||
|
return distance
|
||
|
end
|
||
|
|
||
|
function normal_ray_pick()
|
||
|
local pos = device().cam_pos
|
||
|
local dir = device().cam_dir
|
||
|
local pick = ray_pick()
|
||
|
pick:set_position(pos)
|
||
|
pick:set_direction(dir)
|
||
|
pick:set_flags(2)
|
||
|
pick:set_range(0.85)
|
||
|
pick:query()
|
||
|
local distance = pick:get_distance()
|
||
|
|
||
|
return distance
|
||
|
end
|
||
|
|
||
|
function get_rp_diff()
|
||
|
local default_raycast = normal_ray_pick()
|
||
|
local x = 0
|
||
|
local y = y_axis_mounted_distance
|
||
|
local z = 0
|
||
|
local range = 0.85
|
||
|
local custom_raycast = r(ray_pick_dir(x, y, z, range))
|
||
|
local diff = custom_raycast - default_raycast
|
||
|
|
||
|
return diff
|
||
|
end
|
||
|
|
||
|
function r(val)
|
||
|
return round_idp(val, 2)
|
||
|
end
|
||
|
|
||
|
----------------------- BHS compatibility ------------------------
|
||
|
if bhs_patch and zzz_player_injuries then
|
||
|
function bhs_sway_func()
|
||
|
|
||
|
local wpn = db.actor:active_item()
|
||
|
if not (wpn and IsWeapon(wpn)) then return end
|
||
|
if (IsMelee(wpn)) then return end
|
||
|
|
||
|
local wpn_sec = wpn:section()
|
||
|
if not wpn_sec then return end
|
||
|
|
||
|
local wpn_scoped = wpn:weapon_is_scope()
|
||
|
local handling = utils_ui.prop_handling(wpn, wpn_sec)
|
||
|
|
||
|
local body_state = get_body_state()
|
||
|
local left_arm = (zzz_player_injuries.health.rightarm + zzz_player_injuries.timedhp.rightarm) * effects_mult
|
||
|
left_arm = left_arm >=1 and left_arm or 0.75
|
||
|
local right_arm = (zzz_player_injuries.health.leftarm + zzz_player_injuries.timedhp.leftarm) * effects_mult
|
||
|
right_arm = right_arm >=1 and right_arm or 0.75
|
||
|
local arms_sum = left_arm + right_arm
|
||
|
local max_arms_sum = (zzz_player_injuries.maxhp.rightarm + zzz_player_injuries.maxhp.leftarm) * effects_mult
|
||
|
|
||
|
-- anm power mults
|
||
|
local bhs_cam_power = 1
|
||
|
local body_mult = get_body_state_power(wpn, wpn_scoped) or 1 -- power based on body state
|
||
|
local extra_mult = wpn_scoped and 0.02 or 0.1 -- reduce scoped anm power
|
||
|
local mount_mult = wpn_mounted() and weapon_mounted_power or 1 -- weapon mounted
|
||
|
local handling_mult = handling and ((2.5 - 0.02 * handling * 100)^weapon_handling_mult) or 1 -- handling
|
||
|
local weight = get_weight_power(wpn_sec) and clamp(get_weight_power(wpn_sec) * weight_factor, 0.01, max_power_weight) or 1 -- weight factor
|
||
|
local breath_mult = holding_breath and hold_breath_mult or 1 + breath_held_for * release_breath_mult -- breath mult
|
||
|
|
||
|
-- Summary Weapon Sway power
|
||
|
local cam_power = body_mult * weight * extra_mult * mount_mult * breath_mult * handling_mult
|
||
|
cam_power = clamp(cam_power, 0, max_effect_power)
|
||
|
|
||
|
-- BHS
|
||
|
if arms_sum < (max_arms_sum * (zzz_player_injuries_mcm.get_config("arm_penalty_minimum_hp") * 0.05)) then
|
||
|
if (left_arm < right_arm / 1.5) or (right_arm < left_arm / 1.5) then
|
||
|
bhs_cam_power = 1.15 * weight / arms_sum
|
||
|
bhs_cam_power = (body_state == "crouch") and (0.8 * weight / arms_sum) or bhs_cam_power
|
||
|
bhs_cam_power = (body_state == "low_crouch") and (0.4 * weight / arms_sum) or bhs_cam_power
|
||
|
else
|
||
|
bhs_cam_power = 0.8 * weight / arms_sum
|
||
|
bhs_cam_power = (body_state == "crouch") and (0.55 * weight / arms_sum) or bhs_cam_power
|
||
|
bhs_cam_power = (body_state == "low_crouch") and (0.3 * weight / arms_sum) or bhs_cam_power
|
||
|
end
|
||
|
|
||
|
-- Summary BHS power
|
||
|
bhs_cam_power = clamp((bhs_cam_power * mount_mult * breath_mult * handling_mult), 0, 3)
|
||
|
bhs_cam_power = bhs_cam_power * (zzz_player_injuries_mcm.get_config("arm_animation_power"))
|
||
|
local cam_power_scope = bhs_cam_power * 0.2
|
||
|
if wpn:weapon_is_scope() then
|
||
|
bhs_cam_power = cam_power_scope
|
||
|
end
|
||
|
|
||
|
-- Play anim or Change its power
|
||
|
if level.check_cam_effector(99215) then
|
||
|
level.set_cam_effector_factor(99215, bhs_cam_power)
|
||
|
else
|
||
|
level.add_cam_effector("weapon_sway\\sway_" .. aim_anm .. ".anm", 99215, true, "", 0, true, bhs_cam_power)
|
||
|
end
|
||
|
|
||
|
-- Weapon Sway
|
||
|
elseif weapon_sway_enable then
|
||
|
-- Play anim or Change its power
|
||
|
if level.check_cam_effector(99215) then
|
||
|
level.set_cam_effector_factor(99215, cam_power)
|
||
|
else
|
||
|
level.add_cam_effector("weapon_sway\\sway_" .. aim_anm .. ".anm", 99215, true, "", 0, true, cam_power)
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
-- dbg
|
||
|
if not weapon_sway_debug then return end
|
||
|
news_manager.send_tip(db.actor, string.format("y-axis diff: %s", ( get_rp_diff() )), 0, nil, 1500)
|
||
|
|
||
|
if not hold_breath_feature then return end
|
||
|
news_manager.send_tip(db.actor, string.format("Breath being held for: %s", breath_held_for), 0, nil, 1500)
|
||
|
|
||
|
end
|
||
|
end
|
||
|
|
||
|
----------------------- cb ------------------------
|
||
|
function actor_on_weapon_zoom_in(wpn)
|
||
|
zoom_flag = true
|
||
|
end
|
||
|
|
||
|
function actor_on_weapon_zoom_out(wpn)
|
||
|
weapon_sway_remove()
|
||
|
zoom_flag = false
|
||
|
|
||
|
if not (holding_breath) then return end
|
||
|
|
||
|
holding_breath = false
|
||
|
|
||
|
-- if breath was held for more than 3 seconds - play release sound
|
||
|
if breath_held_for > 3 then
|
||
|
breath_snd_release()
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
local tg_act = 0
|
||
|
function main_update()
|
||
|
local tg = time_global()
|
||
|
if tg < tg_act then return end
|
||
|
tg_act = tg + 250
|
||
|
|
||
|
if weapon_sway_enable and zoom_flag then
|
||
|
if bhs_patch and zzz_player_injuries and bhs_sway_func then
|
||
|
bhs_sway_func()
|
||
|
else
|
||
|
weapon_sway()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- dbg
|
||
|
if not weapon_sway_debug then return end
|
||
|
news_manager.send_tip(db.actor, string.format("y-axis diff: %s", ( get_rp_diff() )), 0, nil, 1500)
|
||
|
|
||
|
if not hold_breath_feature then return end
|
||
|
news_manager.send_tip(db.actor, string.format("Breath being held for: %s", breath_held_for), 0, nil, 1500)
|
||
|
|
||
|
end
|
||
|
|
||
|
function on_option_change()
|
||
|
weapon_sway_enable = weapon_sway_mcm.get_config("weapon_sway_feature")
|
||
|
aim_anm = weapon_sway_mcm.get_config("animation_type")
|
||
|
max_effect_power = weapon_sway_mcm.get_config("max_effect_power")
|
||
|
sway_keybind = weapon_sway_mcm.get_config("sway_keybind")
|
||
|
|
||
|
power_stand = weapon_sway_mcm.get_config("power_stand")
|
||
|
power_crouch = weapon_sway_mcm.get_config("power_crouch")
|
||
|
power_low_crouch = weapon_sway_mcm.get_config("power_low_crouch")
|
||
|
|
||
|
power_stand_scoped = weapon_sway_mcm.get_config("power_stand_scoped")
|
||
|
power_crouch_scoped = weapon_sway_mcm.get_config("power_crouch_scoped")
|
||
|
power_low_crouch_scoped = weapon_sway_mcm.get_config("power_low_crouch_scoped")
|
||
|
|
||
|
weapon_mount_feature = weapon_sway_mcm.get_config("weapon_mount_feature")
|
||
|
weapon_mounted_power = weapon_sway_mcm.get_config("weapon_mounted_power")
|
||
|
y_axis_mounted_distance = weapon_sway_mcm.get_config("y_axis_mounted_distance")
|
||
|
|
||
|
weapon_handling_mult = weapon_sway_mcm.get_config("handling_mult")
|
||
|
|
||
|
weight_factor = weapon_sway_mcm.get_config("weight_factor")
|
||
|
max_power_weight = weapon_sway_mcm.get_config("max_power_weight")
|
||
|
|
||
|
hold_breath_feature = weapon_sway_mcm.get_config("hold_breath_feature")
|
||
|
enable_breath_sound = weapon_sway_mcm.get_config("enable_breath_sound")
|
||
|
breath_restore_mult = weapon_sway_mcm.get_config("breath_restore_mult")
|
||
|
max_hold_breath_time = weapon_sway_mcm.get_config("max_hold_breath_time")
|
||
|
|
||
|
hold_breath_mult = weapon_sway_mcm.get_config("hold_breath_mult")
|
||
|
release_breath_mult = weapon_sway_mcm.get_config("release_breath_mult")
|
||
|
|
||
|
weapon_sway_debug = weapon_sway_mcm.get_config("debugx")
|
||
|
end
|
||
|
|
||
|
function on_game_start()
|
||
|
RegisterScriptCallback("on_key_press", on_key_press)
|
||
|
RegisterScriptCallback("actor_on_update", breath_update)
|
||
|
RegisterScriptCallback("on_key_release", on_key_release)
|
||
|
RegisterScriptCallback("actor_on_weapon_zoom_in", actor_on_weapon_zoom_in)
|
||
|
RegisterScriptCallback("actor_on_weapon_zoom_out", actor_on_weapon_zoom_out)
|
||
|
RegisterScriptCallback("actor_on_update", main_update)
|
||
|
RegisterScriptCallback("on_option_change", on_option_change)
|
||
|
end
|