-- Eddie's Edit September 6, 2021 local disable_hud_fps_fix_tmr = 0.2 -- sec ------------------------ SETTINGS ------------------------ local damagescale=zzz_player_injuries_mcm.get_config("DAMAGE_MULT") or 3.5 -- Damage scale to body parts from recieved damage; 0.5 means half of normal limbs do have 50 hp, torso has 100 hp and head has 50 hp local damagescale_floor = math.floor(damagescale) local damage_threshold=0.0293/damagescale_floor -- 0.0293 is default local hud_vertical_spacing=25--27 -- How low hitbox hud will be drown. The higher the number, the lower the HUD. 0 is default ~in the middle of screen. local hide_default_hud= (zzz_player_injuries_mcm.get_config("TEXT_BASED_PATCH")) and false or true local show_player_name=true local hide_if_healthy=false local natural_regeneration = zzz_player_injuries_mcm.get_config("NATURAL_REGENERATION") local natural_regeneration_speed_mod = zzz_player_injuries_mcm.get_config("regeneration_speed") local painkiller_grain_shader = zzz_player_injuries_mcm.get_config("PAINKILLER_GRAIN_SHADER") local tourniquet_is_splint = zzz_player_injuries_mcm.get_config("TOURNIQUET_IS_SPLINT") local bandage_is_splint = zzz_player_injuries_mcm.get_config("BANDAGE_IS_SPLINT") local splinting = zzz_player_injuries_mcm.get_config("SPLINTING") local medkit_is_splint = zzz_player_injuries_mcm.get_config("MEDKIT_IS_SPLINT") local medkits_heal_logic = zzz_player_injuries_mcm.get_config("MEDKITS_HEAL_LOGIC") or 2 local rebirth_heal_logic = zzz_player_injuries_mcm.get_config("REBIRTH_HEAL_LOGIC") or 2 local sleep_heal = zzz_player_injuries_mcm.get_config("SLEEP_HEALS") local sleep_heal_logic = zzz_player_injuries_mcm.get_config("SLEEP_HEALS_LOGICAL") local sleep_heal_power = zzz_player_injuries_mcm.get_config("SLEEP_HEALS_POWER") local using_surgery = zzz_player_injuries_mcm.get_config("USE_SURGERY") local surgery_heals = zzz_player_injuries_mcm.get_config("SURGERY_HEALS") local surgery_all_limbs = zzz_player_injuries_mcm.get_config("SURGERY_ALL_LIMBS") local cms_restores_hp_too = zzz_player_injuries_mcm.get_config("CMS_RESTORES_HP_TOO") bhs_exp_mode = zzz_player_injuries_mcm.get_config("BHS_EXPERIMENTAL_MODE") local bhs_bleed = zzz_player_injuries_mcm.get_config("BHS_BLEEDTHROUGH") local fall_mult = zzz_player_injuries_mcm.get_config("FALL_MULT") local regen=0 -- Don't change that. Use mcm instead. Automatic blue health regeneration on each limb. Setting it to 90000 would mean each 90 seconds 1 health point restores if natural_regeneration then regen = 300000/natural_regeneration_speed_mod end -- It's very important to keep the correct ratio between "effects_mult" and "maxhp" as shown in example effects_mult = 0.5 -- Divide this by maxhp and damagescale multipliers. Example "effects_mult = 1/10" if (default maxhp)*10, damagescale*10, medicines*10 etc (more immersive and harmful effects don't reduce the whole chunks) local prev_time = nil local head_tbl = {} local tinnitus_play = false function save_state(m_data) m_data.head_tbl = head_tbl end function load_state(m_data) head_tbl = m_data.head_tbl or {} end local aim_anm = {"earthquake_1","earthquake_2"} local rightleg_anm = {"med1","med4"} local leftleg_anm = {"med2","med3"} local bothlegs_anm = {"strong1","strong2","strong4"} function on_option_change() if r(head_tbl.volume) ~= r(ui_options.get("sound/general/master_volume")) then head_tbl.volume = (ui_options.get("sound/general/master_volume")) end end -- shameful steal from arti local speeds = {} function actor_on_first_update() options_vol = ui_options.get("sound/general/master_volume") if not (head_tbl.volume) then head_tbl.volume = options_vol end exec_console_cmd("snd_volume_eff " .. options_vol) volume_sound_x = get_console_cmd(2,"snd_volume_eff") speeds[0] = db.actor:get_actor_run_coef() speeds[1] = db.actor:get_actor_runback_coef() speeds[2] = db.actor:get_actor_sprint_koef() end ------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------ hit={} -- struct to store all the hit data i might need hit.type = nil hit.power = nil hit.bone_id = nil hit.bone_id_adj = nil hit.draftsman = nil hit.fall = false hit.death = false hit.apply = false hit.damage = false showtexthud=(zzz_player_injuries_mcm.get_config("TEXT_BASED_PATCH")) and 2 or 0 --1 large left down, 2 default center 0 texture show_hud_type=2 show_hud_change_time=0 local myhealth=0 healthstatus=true local init=false local healtimer=time_global() local display_width=2560 local display_height=1440 local display_ratio=169 local display={} display.types={} display.types[43]=1.3333 display.types[169]=1.7777 display.types[1610]=1.56 maxhp={} maxhp.head=22 maxhp.torso=22 maxhp.leftarm=10 maxhp.rightarm=10 maxhp.leftleg=10 maxhp.rightleg=10 health={} health.head=maxhp.head health.torso=maxhp.torso health.leftarm=maxhp.leftarm health.rightarm=maxhp.rightarm health.leftleg=maxhp.leftleg health.rightleg=maxhp.rightleg preview={} preview.health={} preview.health.head=nil preview.health.torso=nil preview.health.leftarm=nil preview.health.rightarm=nil preview.health.leftleg=nil preview.health.rightleg=nil preview.bonus={} preview.bonus.head=nil preview.bonus.torso=nil preview.bonus.leftarm=nil preview.bonus.rightarm=nil preview.bonus.leftleg=nil preview.bonus.rightleg=nil preview.surgeryhp={} preview.surgeryhp.head=nil preview.surgeryhp.torso=nil preview.surgeryhp.leftarm=nil preview.surgeryhp.rightarm=nil preview.surgeryhp.leftleg=nil preview.surgeryhp.rightleg=nil timedhp={} timedhp.head=0 timedhp.torso=0 timedhp.leftarm=0 timedhp.rightarm=0 timedhp.leftleg=0 timedhp.rightleg=0 surgeryhp={} surgeryhp.head=0 surgeryhp.torso=0 surgeryhp.leftarm=0 surgeryhp.rightarm=0 surgeryhp.leftleg=0 surgeryhp.rightleg=0 local timedheal={} timedheal.head=0 timedheal.torso=0 timedheal.leftarm=0 timedheal.rightarm=0 timedheal.leftleg=0 timedheal.rightleg=0 hud_blink_timer={} hud_blink_timer.head=0 hud_blink_timer.torso=0 hud_blink_timer.leftarm=0 hud_blink_timer.rightarm=0 hud_blink_timer.leftleg=0 hud_blink_timer.rightleg=0 hud_blink_timer.blinktime=1000 -- These items heal bodyparts over time, healing all listed body parts at the same time. Won't heal if body part is at 0 hp (=broken). -- * the numbers for each body part is the total amount of hp healed for each body part -- * healtimer: after this amount of time, 1 hp is added to each listed body part. healhelplist={} healhelplist.lastregen=time_global() healhelplist.healtimer=30000 healhelplist.healpower=0 if medkits_heal_logic == 1 then healhelplist.medkit={head=11,torso=11,rightleg=5,leftleg=5,rightarm=5,leftarm=5,healpower=1,healtimer=6000} healhelplist.medkit_army={head=16,torso=16,rightleg=7,leftleg=7,rightarm=7,leftarm=7,healpower=1,healtimer=4175} healhelplist.medkit_scientic={head=16,torso=16,rightleg=7,leftleg=7,rightarm=7,leftarm=7,healpower=1,healtimer=4175} healhelplist.stimpack={head=11,torso=11,rightleg=5,leftleg=5,rightarm=5,leftarm=5,healpower=1,healtimer=1000} healhelplist.stimpack_army={head=16,torso=16,rightleg=7,leftleg=7,rightarm=7,leftarm=7,healpower=1,healtimer=900} healhelplist.stimpack_scientic={head=16,torso=16,rightleg=7,leftleg=7,rightarm=7,leftarm=7,healpower=1,healtimer=900} end if rebirth_heal_logic == 1 then healhelplist.rebirth={head=22,torso=22,rightleg=10,leftleg=10,rightarm=10,leftarm=10,healpower=0,healtimer=772} end -- Items that add 1 hp at a time to the most injured body part. Won't heal if body part is at 0 hp (=broken). -- For broken limbs you first need to use a bandage (=splint). -- * healamount: how many hp to add in total. -- * healtimer: time it takes to heal 1 hp. -- * healactive: leave at 0, this is used to track it during runtime. -- * lasttimestamp: leave at 0, this is used to track it during runtime. healonelist={} healonelist.lastregen=time_global() healonelist.healtimer=30000 healonelist.healamount=0 healonelist.healpower=0 if medkits_heal_logic == 2 then healonelist.medkit={healamount=21,healtimer=3180,healpower=1} healonelist.medkit_army={healamount=32,healtimer=2084,healpower=1} healonelist.medkit_scientic={healamount=32,healtimer=2084,healpower=1} healonelist.stimpack={healamount=21,healtimer=571,healpower=1} healonelist.stimpack_army={healamount=32,healtimer=468,healpower=1} healonelist.stimpack_scientic={healamount=32,healtimer=468,healpower=1} healonelist.survival_kit={healamount=60,healtimer=1428,healpower=1} end if rebirth_heal_logic == 2 then healonelist.rebirth={healamount=60,healtimer=283,healpower=0} end healonelist.drug_coagulant={healamount=11,healtimer=39818,healpower=0} healonelist.propital={healamount=21,healtimer=6000,healpower=0} -- First aid items: -- * instant effect -- * splintamount: how much hp is healed in total. Hp is added to body part with lowest health first. -- * maxarmleg and maxheadtorso = can only heal body part up to this hp level. splintlist={} if splinting then if tourniquet_is_splint then splintlist.jgut={splintamount=1} end if bandage_is_splint then splintlist.bandage={splintamount=1} splintlist.bandage_army={splintamount=1} end splintlist.splint={splintamount=1} splintlist.alu_splint={splintamount=1} end surgerylist={} if using_surgery then surgerylist.surginst={surgeryamount=1} if cms_restores_hp_too then surgerylist.cms={surgeryamount=4} else surgerylist.cms={surgeryamount=1} end end -- Painkillers add painkillerpower as timedhp to limbs and double that to torso + head. -- timedhp are added to health when considering effects such as shaking hands and limping. Won't prevent death when torso or head hp = 0. painkillerlist={} painkillerlist.lasttimestamp=time_global() painkillerlist.painkillerduration=0 painkillerlist.painkillerpower=0 painkillerlist.countdown_increments=0 -- divides the total duration into x parts. Used to make sure painkillers actual duration stays closer to its set duration + up to length of one increment. painkillerlist.morphine={painkillerpower=7,painkillerduration=1518000,countdown_increments=92} painkillerlist.rebirth={painkillerpower=7,painkillerduration=305000,countdown_increments=30} painkillerlist.salicidic_acid={painkillerpower=6,painkillerduration=1152000,countdown_increments=80} painkillerlist.tetanus={painkillerpower=4,painkillerduration=202000,countdown_increments=20} painkillerlist.analgetic={painkillerpower=5,painkillerduration=1042000,countdown_increments=80} painkillerlist.sj1={painkillerpower=6,painkillerduration=1500000,countdown_increments=75} painkillerlist.sj6={painkillerpower=9,painkillerduration=1500000,countdown_increments=75} painkillerlist.analgin={painkillerpower=2,painkillerduration=180000,countdown_increments=36} painkillerlist.akvatab={painkillerpower=4,painkillerduration=290000,countdown_increments=29} painkillerlist.yadylin={painkillerpower=5,painkillerduration=505000,countdown_increments=50} painkillerlist.adrenalin={painkillerpower=2,painkillerduration=2184000,countdown_increments=105} painkillerlist.etg={painkillerpower=4,painkillerduration=1800000,countdown_increments=90} painkillerlist.medkit_army={painkillerpower=4,painkillerduration=128000,countdown_increments=25} painkillerlist.medkit_scientic={painkillerpower=3,painkillerduration=128000,countdown_increments=25} painkillerlist.stimpack={painkillerpower=2,painkillerduration=128000,countdown_increments=25} painkillerlist.stimpack_army={painkillerpower=4,painkillerduration=128000,countdown_increments=25} painkillerlist.stimpack_scientic={painkillerpower=3,painkillerduration=128000,countdown_increments=25} painkillerlist.cocaine={painkillerpower=2,painkillerduration=1644000,countdown_increments=80} painkillerlist.joint={painkillerpower=1,painkillerduration=420000,countdown_increments=42} painkillerlist.marijuana={painkillerpower=1,painkillerduration=652000,countdown_increments=40} painkillerlist.vodka={painkillerpower=1,painkillerduration=300000,countdown_increments=30} painkillerlist.vodka2={painkillerpower=1,painkillerduration=300000,countdown_increments=30} painkillerlist.vodka_quality={painkillerpower=2,painkillerduration=300000,countdown_increments=30} painkillerlist.bottle_metal={painkillerpower=2,painkillerduration=300000,countdown_increments=30} exp_druglist = {} exp_druglist.lasttimestamp=time_global() exp_druglist.restoreduration=0 exp_druglist.restorepower=0 exp_druglist.countdown_increments=0 exp_druglist.drug_coagulant={restorepower=0.0005,countdown_increments=438,restoretime=438} --exp_druglist.yadylin={restorepower=0.0005,countdown_increments=438,restoretime=438} local modifiedregen = regen local playername function trace_this(to_trace1) local log_file = io.open("log_memory_npc", "a") log_file:write(to_trace1) log_file:close(log_file) end local function GetConditionFromFloat(float,bodypart) if bodypart then if hud_blink_timer[bodypart] then if time_global()-hud_blink_timer[bodypart]=0.99 then -- --return "good" -- return "blue" -- elseif float>=0.79 then -- --return "ok" -- return "blue" -- elseif float>=0.33 then -- return "blue" -- elseif float>=0.19 then -- return "critical" -- else -- return "critical" -- end return "blue" end local colors={} --colors.blue="%c[0,50,200,200]" -- colors.good="%c[0,0,255,0]" -- colors.ok="%c[0,150,255,0]" -- colors.medium="%c[0,255,255,0]" -- colors.danger="%c[0,255,100,0]" -- colors.critical="%c[0,255,0,0]" colors.blue="%c[0,56,115,255]" colors.good="%c[0,15,143,20]" colors.ok="%c[0,138,204,51]" colors.medium="%c[0,255,208,0]" colors.danger="%c[0,255,79,0]" colors.critical="%c[0,230,10,10]" colors.grey="%c[0,161,161,161]" colors.preview_health="%c[0,140,0,255]" colors.preview_bonus="%c[0,0,212,24]" colors.blank="%c[0,156,156,156]" colors.white="%c[0,255,255,255]" --colors.grey="%c[0,185,185,185]" colors.black="%c[0,0,0,0]" local function SaveHealthStatus() utils_obj.save_var(db.actor,"health.head",health.head) utils_obj.save_var(db.actor,"health.torso",health.torso) utils_obj.save_var(db.actor,"health.rightarm",health.rightarm) utils_obj.save_var(db.actor,"health.leftarm",health.leftarm) utils_obj.save_var(db.actor,"health.rightleg",health.rightleg) utils_obj.save_var(db.actor,"health.leftleg",health.leftleg) utils_obj.save_var(db.actor,"timedheal.head",timedheal.head) utils_obj.save_var(db.actor,"timedheal.torso",timedheal.torso) utils_obj.save_var(db.actor,"timedheal.rightarm",timedheal.rightarm) utils_obj.save_var(db.actor,"timedheal.leftarm",timedheal.leftarm) utils_obj.save_var(db.actor,"timedheal.rightleg",timedheal.rightleg) utils_obj.save_var(db.actor,"timedheal.leftleg",timedheal.leftleg) utils_obj.save_var(db.actor,"timedhp.head",timedhp.head) utils_obj.save_var(db.actor,"timedhp.torso",timedhp.torso) utils_obj.save_var(db.actor,"timedhp.rightarm",timedhp.rightarm) utils_obj.save_var(db.actor,"timedhp.leftarm",timedhp.leftarm) utils_obj.save_var(db.actor,"timedhp.rightleg",timedhp.rightleg) utils_obj.save_var(db.actor,"timedhp.leftleg",timedhp.leftleg) utils_obj.save_var(db.actor,"surgeryhp.head",surgeryhp.head) utils_obj.save_var(db.actor,"surgeryhp.torso",surgeryhp.torso) utils_obj.save_var(db.actor,"surgeryhp.rightarm",surgeryhp.rightarm) utils_obj.save_var(db.actor,"surgeryhp.leftarm",surgeryhp.leftarm) utils_obj.save_var(db.actor,"surgeryhp.rightleg",surgeryhp.rightleg) utils_obj.save_var(db.actor,"surgeryhp.leftleg",surgeryhp.leftleg) utils_obj.save_var(db.actor,"healhelplist.healtimer",healhelplist.healtimer) utils_obj.save_var(db.actor,"healhelplist.healpower",healhelplist.healpower) utils_obj.save_var(db.actor,"healonelist.healtimer",healonelist.healtimer) utils_obj.save_var(db.actor,"healonelist.healpower",healonelist.healpower) utils_obj.save_var(db.actor,"healonelist.healamount",healonelist.healamount) utils_obj.save_var(db.actor,"painkillerlist.painkillerduration",painkillerlist.painkillerduration) utils_obj.save_var(db.actor,"painkillerlist.painkillerpower",painkillerlist.painkillerpower) utils_obj.save_var(db.actor,"painkillerlist.countdown_increments",painkillerlist.countdown_increments) utils_obj.save_var(db.actor,"exp_druglist.restoreduration",exp_druglist.restoreduration) utils_obj.save_var(db.actor,"exp_druglist.restorepower",exp_druglist.restorepower) utils_obj.save_var(db.actor,"exp_druglist.countdown_increments",exp_druglist.countdown_increments) end local function LoadHealthStatus() health.head=utils_obj.load_var(db.actor,"health.head") or maxhp.head health.torso=utils_obj.load_var(db.actor,"health.torso") or maxhp.torso health.rightarm=utils_obj.load_var(db.actor,"health.rightarm") or maxhp.rightarm health.leftarm=utils_obj.load_var(db.actor,"health.leftarm") or maxhp.leftarm health.rightleg=utils_obj.load_var(db.actor,"health.rightleg") or maxhp.rightleg health.leftleg=utils_obj.load_var(db.actor,"health.leftleg") or maxhp.leftleg timedheal.head=utils_obj.load_var(db.actor,"timedheal.head") or 0 timedheal.torso=utils_obj.load_var(db.actor,"timedheal.torso") or 0 timedheal.rightarm=utils_obj.load_var(db.actor,"timedheal.rightarm") or 0 timedheal.leftarm=utils_obj.load_var(db.actor,"timedheal.leftarm") or 0 timedheal.rightleg=utils_obj.load_var(db.actor,"timedheal.rightleg") or 0 timedheal.leftleg=utils_obj.load_var(db.actor,"timedheal.leftleg") or 0 timedhp.head=utils_obj.load_var(db.actor,"timedhp.head") or 0 timedhp.torso=utils_obj.load_var(db.actor,"timedhp.torso") or 0 timedhp.rightarm=utils_obj.load_var(db.actor,"timedhp.rightarm") or 0 timedhp.leftarm=utils_obj.load_var(db.actor,"timedhp.leftarm") or 0 timedhp.rightleg=utils_obj.load_var(db.actor,"timedhp.rightleg") or 0 timedhp.leftleg=utils_obj.load_var(db.actor,"timedhp.leftleg") or 0 surgeryhp.head=utils_obj.load_var(db.actor,"surgeryhp.head",surgeryhp.head) or 0 surgeryhp.torso=utils_obj.load_var(db.actor,"surgeryhp.torso",surgeryhp.torso) or 0 surgeryhp.rightarm=utils_obj.load_var(db.actor,"surgeryhp.rightarm",surgeryhp.rightarm) or 0 surgeryhp.leftarm=utils_obj.load_var(db.actor,"surgeryhp.leftarm",surgeryhp.leftarm) or 0 surgeryhp.rightleg=utils_obj.load_var(db.actor,"surgeryhp.rightleg",surgeryhp.rightleg) or 0 surgeryhp.leftleg=utils_obj.load_var(db.actor,"surgeryhp.leftleg",surgeryhp.leftleg) or 0 healhelplist.healtimer=utils_obj.load_var(db.actor,"healhelplist.healtimer",healhelplist.healtimer) or 0 healhelplist.healpower=utils_obj.load_var(db.actor,"healhelplist.healpower",healhelplist.healpower) or 0 healonelist.healtimer=utils_obj.load_var(db.actor,"healonelist.healtimer",healonelist.healtimer) or 0 healonelist.healpower=utils_obj.load_var(db.actor,"healonelist.healpower",healonelist.healpower) or 0 healonelist.healamount=utils_obj.load_var(db.actor,"healonelist.healamount",healonelist.healamount) or 0 painkillerlist.painkillerduration=utils_obj.load_var(db.actor,"painkillerlist.painkillerduration",painkillerlist.painkillerduration) or 0 painkillerlist.painkillerpower=utils_obj.load_var(db.actor,"painkillerlist.painkillerpower",painkillerlist.painkillerpower) or 0 painkillerlist.countdown_increments=utils_obj.load_var(db.actor,"painkillerlist.countdown_increments",painkillerlist.countdown_increments) or 0 exp_druglist.restoreduration=utils_obj.load_var(db.actor,"exp_druglist.restoreduration",exp_druglist.restoreduration) or 0 exp_druglist.restorepower=utils_obj.load_var(db.actor,"exp_druglist.restorepower",exp_druglist.restorepower) or 0 exp_druglist.countdown_increments=utils_obj.load_var(db.actor,"exp_druglist.countdown_increments",exp_druglist.countdown_increments) or 0 if painkillerlist.painkillerpower > 0 and painkiller_grain_shader then --printf("Adding the effector. Painkillerpower: %s , Painkillerduration: %s",painkillerlist.painkillerpower,painkillerlist.painkillerduration) level.add_pp_effector("radiation.ppe", 5020, true) else --printf("Removing the effector. Painkillerpower: %s , Painkillerduration: %s",painkillerlist.painkillerpower,painkillerlist.painkillerduration) level.remove_pp_effector(5020) end end function r(val) local shet = round_idp(val, 3) return shet end 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 shaking_hands() local activeslot = db.actor:active_slot() if not (activeslot == 2 or activeslot == 3 or activeslot == 1) then return end local item_in_slot = db.actor:item_in_slot(activeslot) if not (item_in_slot) then return end local section_name = item_in_slot:section() local weight if not (ini_sys:section_exist(section_name, "inv_weight")) then return end weight = ini_sys:r_float_ex(section_name, "inv_weight") local body_state = get_body_state() local cam_power = 0 local left_arm = (health.rightarm + timedhp.rightarm) * effects_mult left_arm = left_arm >=1 and left_arm or 0.75 local right_arm = (health.leftarm + 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 = (maxhp.rightarm + maxhp.leftarm) * effects_mult if arms_sum < (max_arms_sum * (zzz_player_injuries_mcm.get_config("arm_penalty_minimum_hp") * 0.05)) then cam_power = 0.65 * weight / arms_sum cam_power = (body_state == "crouch") and (0.60 * weight / arms_sum) or cam_power cam_power = (body_state == "low_crouch") and (0.55 * weight / arms_sum) or cam_power cam_power = clamp(cam_power, 0, 3) cam_power = cam_power * (zzz_player_injuries_mcm.get_config("arm_animation_power")) local cam_power_scope = cam_power * 0.33 if item_in_slot:weapon_is_scope() then cam_power = cam_power_scope end -- play anm level.add_cam_effector("camera_effects\\" .. aim_anm[math.random(#aim_anm)] .. ".anm", 9921, true, "", 0, true, cam_power) else cam_power = 0.19 * weight / max_arms_sum cam_power = (body_state == "crouch") and (0.18 * weight / max_arms_sum) or cam_power cam_power = (body_state == "low_crouch") and (0.17 * weight / max_arms_sum) or cam_power cam_power = clamp(cam_power, 0, 3) cam_power = cam_power * (zzz_player_injuries_mcm.get_config("arm_animation_power")) local cam_power_scope = cam_power * 0.33 if item_in_slot:weapon_is_scope() then cam_power = cam_power_scope end level.add_cam_effector("camera_effects\\" .. aim_anm[math.random(#aim_anm)] .. ".anm", 9921, true, "", 0, true, cam_power) end -- news_manager.send_tip(db.actor, r(cam_power), 0, nil, 1500) end function shaking_hands_remove() level.remove_cam_effector(9921) end function limp_speed_slow() local legs_summ = (health.leftleg + health.rightleg + timedhp.leftleg + timedhp.rightleg) * effects_mult local run_coef = 1 local sprint_coef = 1 local run_coef = 0.0625 * legs_summ + 0.375 local sprint_coef = 0.0625 * legs_summ + 0.375 local real_sprint_coef = 0.025 * legs_summ + 0.75 if (health.leftleg==0 and timedhp.leftleg<=2) or (health.rightleg==0 and timedhp.rightleg<=2) then real_sprint_coef = 0.75 elseif (health.leftleg + timedhp.leftleg) > (health.rightleg + timedhp.rightleg) then real_sprint_coef = 0.025 * ((health.leftleg + timedhp.leftleg) * effects_mult) + 0.75 elseif (health.leftleg + timedhp.leftleg) < (health.rightleg + timedhp.rightleg) then real_sprint_coef = 0.025 * ((health.rightleg + timedhp.rightleg) * effects_mult) + 0.75 end if (health.leftleg==0 and timedhp.leftleg<=2) or (health.rightleg==0 and timedhp.rightleg<=2) then run_coef = 0.22 --0.375 end speed.add_speed("bhs_speed_run", run_coef, false, true) -- speed.add_speed("bhs_speed_runback", run_coef, false, true) speed.add_speed("bhs_speed_sprint", real_sprint_coef, true, true) -- local vec = db.actor:get_movement_speed() -- local ms = (vec.x)^2 + (vec.y)^2 + (vec.z)^2 -- news_manager.send_tip(db.actor, r(ms), 0, nil, 1500) end local leftleg_flag = false local rightleg_flag = false local bothlegs_flag = false function legs_limp() local right_l = (health.leftleg + timedhp.leftleg) * effects_mult -- right is left local left_l = (health.rightleg + timedhp.rightleg) * effects_mult local legs_sum = left_l + right_l local max_right_l = maxhp.leftleg * effects_mult * (zzz_player_injuries_mcm.get_config("leg_penalty_minimum_hp") * 0.2) local max_left_l = maxhp.rightleg * effects_mult * (zzz_player_injuries_mcm.get_config("leg_penalty_minimum_hp") * 0.2) local max_legs_sum = max_left_l + max_right_l if (right_l == left_l) and (legs_sum < max_legs_sum) then bothlegs_flag = true leftleg_flag, rightleg_flag = false -- printf("bothlegs_flag = true") elseif (left_l < max_left_l) and (left_l < right_l) then leftleg_flag = true rightleg_flag, bothlegs_flag = false -- printf("leftleg_flag = true") elseif (right_l < max_right_l) and (right_l < left_l) then rightleg_flag = true leftleg_flag, bothlegs_flag = false -- printf("rightleg_flag = true") elseif (legs_sum >= max_legs_sum) then leftleg_flag, rightleg_flag, bothlegs_flag = false -- printf("ALL = false") end end function torso_penalty() local torso_health = (health.torso + timedhp.torso) * effects_mult local torso_max_hp = maxhp.torso * effects_mult torso_health = torso_health > torso_max_hp and torso_max_hp or ((health.torso + timedhp.torso) * effects_mult) local t_diff = (torso_max_hp - torso_health) / effects_mult local t_cap = 1 - t_diff * 0.035 if (t_diff > 0) and (db.actor.health > t_cap) then -- db.actor.health = t_cap t_cap = t_cap end end local tg_effects_regen = 0 local tg_effects_regen_delay = 500 local tg_stage_2_effects = 0 local tg_stage_2_effects_delay = 15000 -- just in case, duration of ppe is 7250 function bhs_concussion() local tg = time_global() local rnd = math.random(1, 100) local current = health.head * effects_mult -- reason not to add timedhp.head here: will block effect on first hit to head and then do nothing. if not (head_tbl.previous) then head_tbl.previous = current end local previous = head_tbl.previous local volume_sound_x = get_console_cmd(2,"snd_volume_eff") local volume_sound_x_fade = 0.01 local anm_damage_threshold = 2 local damage_taken = (previous - current) * math.pow(0.75, painkillerlist.painkillerpower) -- local damage_taken = previous - current damage_taken = damage_taken > 0 and damage_taken or 0 local max_head = maxhp.head * effects_mult local effector_k = damage_taken / max_head local effector_power = effector_k * (zzz_player_injuries_mcm.get_config("head_animation_power")) -- actor_menu.set_msg(1, strformat("head.tbl.volume: %s, console_volume: %s, stage: %s", r(head_tbl.volume), r(get_console_cmd(2,"snd_volume_eff")), r(head_tbl.stage))) -- removing effects if hp between previous and current yellow or blue (or dead) if head_tbl.stage ~= 0 and ((previous == current) or (current <= 0)) then exec_console_cmd("snd_volume_eff " .. head_tbl.volume) level.remove_pp_effector(99133) head_tbl.stage = 0 end -- stage 1 if (head_tbl.stage == 1) then level.add_pp_effector("concussion_bhs.ppe", 99123, false) exec_console_cmd("snd_volume_eff " .. volume_sound_x_fade) CreateTimeEvent(0, "set_stage_two", 1, set_stage_two) end -- stage 2 xd if (head_tbl.stage == 2) and (tg > tg_stage_2_effects) then if (tinnitus_play) then local snd = sound_object("bhs\\tinnitusx") snd:play_no_feedback(db.actor, sound_object.s2d, 0, VEC_ZERO, 1.0, 1.0) snd.volume = effector_k * 3 tinnitus_play = false end -- random chance for head shake if (damage_taken > anm_damage_threshold) and (rnd <= effector_k * 10) then level.add_cam_effector("camera_effects\\wake_up.anm", 96872, false, "", 0, true, effector_power * 0.2) end level.add_pp_effector("concussion_post_bhs.ppe", 99133, false) tg_stage_2_effects = tg + tg_stage_2_effects_delay end level.set_pp_effector_factor(99123, effector_power) level.set_pp_effector_factor(99133, effector_power) -- regen painkiller_regen_bonus = 0 if painkillerlist.painkillerpower > 0 then painkiller_regen_bonus = (painkillerlist.painkillerpower + 1) * 0.05 end if tg > tg_effects_regen then head_tbl.previous = clamp(head_tbl.previous - 0.01 - painkiller_regen_bonus, current, head_tbl.previous) -- effector's power decrease: 50 sec for each lost HP tg_effects_regen = tg + tg_effects_regen_delay end -- news_manager.send_tip(db.actor, string.format("previous: %s . current: %s", r(head_tbl.previous), r(current)), 0, nil, 1500) end function set_stage_two() exec_console_cmd("snd_volume_eff " .. head_tbl.volume) head_tbl.stage = 2 tinnitus_play = true return true end ------------------------------------------------------------------------ ------------------------------------------------------------------------ local function bonebreak() local helmet = (db.actor:item_in_slot(12) or db.actor:get_current_outfit()) if helmet then muffle = "" else muffle = "" end local sound_play = math.random(1,13) local file = "bhs\\" .. muffle .. "pain_" .. sound_play file_to_say = sound_object( file ) file_to_say:play(db.actor,0,sound_object.s2d) local file2 = "bhs\\" .. "bone_crack" file_to_say = sound_object( file2 ) file_to_say:play(db.actor,0,sound_object.s2d) level.add_pp_effector("blur_bhs.ppe", math.random(655808, 655820), false) end local function received_damage(amount) if grok_progressive_rad_damages then if grok_progressive_rad_damages.grok_rads == 1 then return end end local damage damage=math.ceil((amount*100)/11*damagescale) local damage_head=math.ceil((amount*2*100)/11*damagescale) local choosen_hitbox={} if hit.bone_id_adj then choosen_hitbox=hit.bone_id_adj printf("! Applying %s damage to %s. Damagescale: %s",damage , choosen_hitbox, damagescale) else local index=0 for k,v in pairs(health) do index=index+1 end local random_number=math.random(1,index) -- trace_this("random"..random_number.."\n") if random_number==1 then choosen_hitbox="head" elseif random_number==2 then choosen_hitbox="torso" elseif random_number==3 then choosen_hitbox="leftarm" elseif random_number==4 then choosen_hitbox="rightarm" elseif random_number==5 then choosen_hitbox="leftleg" elseif random_number==6 then choosen_hitbox="rightleg" end printf("! Applying damage to random bone, %s. Damagescale: %s", choosen_hitbox, damagescale) end if hit.type=="Explosive" then -- explosives = bad for health hud_blink_timer.head=time_global() hud_blink_timer.torso=time_global() hud_blink_timer.leftarm=time_global() hud_blink_timer.rightarm=time_global() hud_blink_timer.leftleg=time_global() hud_blink_timer.rightleg=time_global() health.head=math.floor(health.head-damage*0.75) health.torso=math.floor(health.torso-damage*0.75) health.leftarm=math.floor(health.leftarm-damage*0.75) health.rightarm=math.floor(health.rightarm-damage*0.75) health.leftleg=math.floor(health.leftleg-damage*0.75) health.rightleg=math.floor(health.rightleg-damage*0.75) surgeryhp.head=0 surgeryhp.torso=0 surgeryhp.leftarm=0 surgeryhp.rightarm=0 surgeryhp.leftleg=0 surgeryhp.rightleg=0 damage=0 elseif choosen_hitbox=="head" then if damage >= 18 then damage = 17 end if damage >= health.head and health.head > 0 then damage = damage - health.head health.head=0 bonebreak() hit.death=true db.actor.health=-1 elseif damage < health.head then health.head=health.head-damage damage=0 end hud_blink_timer.head=time_global() utils_obj.save_var(db.actor,"health.head",health.head) if damage_head > (zzz_player_injuries_mcm.get_config("head_penalty_minimum_hp") - 1) then head_tbl.stage = 1 end surgeryhp.head=0 elseif choosen_hitbox=="torso" then if damage >= 16 then damage = 14 end if damage >= health.torso and health.torso > 0 then damage = damage - health.torso health.torso=0 bonebreak() elseif damage < health.torso then health.torso=health.torso-damage damage=0 end hud_blink_timer.torso=time_global() utils_obj.save_var(db.actor,"health.torso",health.torso) surgeryhp.torso=0 elseif choosen_hitbox=="leftarm" then if damage >= 8 then damage = 7 end if damage >= health.leftarm and health.leftarm > 0 then damage = damage - health.leftarm health.leftarm=0 bonebreak() elseif damage < health.leftarm then health.leftarm=health.leftarm-damage damage=0 end hud_blink_timer.leftarm=time_global() utils_obj.save_var(db.actor,"health.leftarm",health.leftarm) surgeryhp.leftarm=0 elseif choosen_hitbox=="rightarm" then if damage >= 8 then damage = 7 end if damage >= health.rightarm and health.rightarm > 0 then damage = damage - health.rightarm health.rightarm=0 bonebreak() elseif damage < health.rightarm then health.rightarm=health.rightarm-damage damage=0 end hud_blink_timer.rightarm=time_global() utils_obj.save_var(db.actor,"health.rightarm",health.rightarm) surgeryhp.rightarm=0 elseif choosen_hitbox=="leftleg" then if not hit.fall then if damage >= 8 then damage = 7 end if damage >= health.leftleg and health.leftleg > 0 then damage = damage - health.leftleg health.leftleg=0 bonebreak() elseif damage < health.leftleg then health.leftleg=health.leftleg-damage damage=0 end hud_blink_timer.leftleg=time_global() surgeryhp.leftleg=0 else local damage_rl = damage local damage_ll = damage if damage_ll >= health.leftleg then damage_ll = damage_ll - health.leftleg health.leftleg=0 bonebreak() elseif damage < health.leftleg then health.leftleg=health.leftleg-damage damage_ll=0 end if damage_rl >= health.rightleg then damage_rl = damage_rl - health.rightleg health.rightleg=0 bonebreak() elseif damage < health.rightleg then health.rightleg=health.rightleg-damage damage_rl=0 end utils_obj.save_var(db.actor,"health.rightleg",health.rightleg) damage=damage_ll+damage_rl surgeryhp.leftleg=0 surgeryhp.rightleg=0 end utils_obj.save_var(db.actor,"health.leftleg",health.leftleg) elseif choosen_hitbox=="rightleg" then if not hit.fall then if damage >= 8 then damage = 7 end if damage >= health.rightleg and health.rightleg > 0 then damage = damage - health.rightleg health.rightleg=0 bonebreak() elseif damage < health.rightleg then health.rightleg=health.rightleg-damage damage=0 end hud_blink_timer.rightleg=time_global() surgeryhp.rightleg=0 else local damage_rl = damage local damage_ll = damage if damage_rl >= health.rightleg then damage_rl = damage_rl - health.rightleg health.rightleg=0 bonebreak() elseif damage < health.rightleg then health.rightleg=health.rightleg-damage damage_rl=0 end if damage_ll >= health.leftleg then damage_ll = damage_ll - health.leftleg health.leftleg=0 bonebreak() elseif damage < health.leftleg then health.leftleg=health.leftleg-damage damage_ll=0 end utils_obj.save_var(db.actor,"health.leftleg",health.leftleg) damage=damage_ll+damage_rl surgeryhp.leftleg=0 surgeryhp.rightleg=0 end utils_obj.save_var(db.actor,"health.rightleg",health.rightleg) end if damage>0 and (bhs_exp_mode or bhs_bleed) then printf("! Damage spilling over! Spillover: %s", damage) while damage > 0 do local damage_parts = 1 local damage_rest = 0 local count = 0 for k,v in pairs(health) do if v > 0 then if string.match(k, "torso") then count = count + 1 end count = count + 1 end end if count == 0 then break end if damage >= count then printf("! Enough damage(%s) to hit all healthy limbs(%s) %s times", damage, count, damage/count) printf("! Torso counts as 2") damage_parts=math.floor(damage/count) for k in pairs(health) do if health[k] > 0 then if string.match(k, "torso") then damage_torso = damage_parts*2 if damage_torso >= health.torso then damage_torso = damage_torso - health.torso health.torso=0 bonebreak() else health.torso=health.torso-damage_torso end damage = damage - damage_torso else if damage_parts >= health[k] then damage_parts = damage_parts - health[k] health[k]=0 bonebreak() else health[k]=health[k]-damage_parts end damage = damage - damage_parts end surgeryhp[k]=0 end end printf("! Damage left: %s", damage) printf("! Spillover pass finished, damage left: %s", damage) else printf("! NOT enough damage(%s) to hit all healthy limbs(%s) at least once.", damage, count) printf("! Hitting randomly") damage_rest=damage%count local index=0 for k,v in pairs(health) do index=index+1 end while damage_rest > 0 do local random_number=math.random(1,index) if random_number==1 then choosen_hitbox="head" elseif random_number==2 then choosen_hitbox="torso" elseif random_number==3 then choosen_hitbox="leftarm" elseif random_number==4 then choosen_hitbox="rightarm" elseif random_number==5 then choosen_hitbox="leftleg" elseif random_number==6 then choosen_hitbox="rightleg" end if health[choosen_hitbox] > 0 then health[choosen_hitbox]=health[choosen_hitbox]-1 surgeryhp[choosen_hitbox]=0 damage_rest=damage_rest-1 printf("! Hitting %s once", choosen_hitbox) else printf("! Hitting %s but it is damaged, trying again", choosen_hitbox) end end printf("! Finished hitting, no damage left. Breaking") break end end else damage = 0 end for k,v in pairs(health) do local missinghealth = 0 if v < maxhp[k] then missinghealth = maxhp[k] - v if missinghealth < 0 then missinghealth = 0 end end local bonus = painkillerlist.painkillerpower if string.match(k, "head") or string.match(k, "torso") then bonus = painkillerlist.painkillerpower * 2 end if bonus > missinghealth then bonus = missinghealth end timedhp[k] = bonus end healtimer=time_global() end --19 head --15 - head --16 - head --17 - head --13 - upper torso --12 - middle torso --11 - lower torso --2 pelvis --20 left shoulder --21 left upper arm --22 left forearm --23 left hand --33 right shoulder --34 right upepr arm --35 right forearm --36 right hand --3 left upper leg --4 left lower leg --7 right upeprleg --8 right lower leg local hitboxes={} hitboxes[19]="head" hitboxes[17]="head" hitboxes[16]="head" hitboxes[15]="head" hitboxes[14]="head" hitboxes[13]="torso" hitboxes[12]="torso" hitboxes[11]="torso" hitboxes[2]="torso" hitboxes[20]="leftarm" hitboxes[21]="leftarm" hitboxes[22]="leftarm" hitboxes[23]="leftarm" hitboxes[33]="rightarm" hitboxes[34]="rightarm" hitboxes[35]="rightarm" hitboxes[36]="rightarm" hitboxes[3]="leftleg" hitboxes[4]="leftleg" hitboxes[5]="fall damage" hitboxes[6]="fall damage" hitboxes[9]="fall damage" hitboxes[10]="fall damage" hitboxes[7]="rightleg" hitboxes[8]="rightleg" local function actor_on_hit_callback(obj, amount, local_direction, who, bone_id) local random = false local redirect = false local last_boneid = bone_id if bone_id == 65535 then -- toxic anomalies and radiation. It was hitting head or torso be redirected to arms or torso instead rand = math.random(1,5) redirect = true if rand == 1 or rand == 2 or rand == 3 then bone_id = 12 elseif rand == 4 then bone_id = 20 elseif rand == 5 then bone_id = 33 end end hit.fall = false if (bone_id == 0 or bone_id == 5 or bone_id == 6 or bone_id == 9 or bone_id == 10) and hit.type == "Strike" and hit.draftsman:id()==0 then -- attributes fall damage to left or right leg. 8 = explosive,7 = strike hit.fall=true if rand == 1 then bone_id = 3 else bone_id = 7 end end if bone_id == 0 and hit.type == "Chemical" then -- attributes chemical damage to left or right leg. if rand == 1 then bone_id = 3 else bone_id = 7 end redirect=true end if hitboxes[bone_id] then hit.bone_id_adj=hitboxes[bone_id] text=hitboxes[bone_id] else -- if an unknown bone is hit, arms or torso are hit random = true bone_id = math.random(1,3) if bone_id == 1 then bone_id = 35 elseif bone_id == 2 then bone_id = 23 elseif bone_id == 3 then bone_id = 11 end hit.bone_id_adj=hitboxes[bone_id] text=hitboxes[bone_id] end local damage=amount hit.damage = damage if hit.fall then text = "both legs" end printf("! Actor got hit in %s, random? %s, redirected? %s, damagescale: %s, damage threshold: %s. Original bone: %s, damage type: %s",text, random, redirect, damagescale, damage_threshold, hit.bone_id, hit.type) printf("! Damage: %s",damage) --printf("! Whodunit: %s",who:id()) if not hit.bone_id then printf("! NOT A PROPER HIT! BONEID: %s, WHODUNIT: %s", last_boneid, who:id()) end if damage>damage_threshold then if hit.fall then damage=damage*fall_mult printf("! Fall damage increased to %s, fall multiplier: %s", damage, fall_mult) end received_damage(damage) else --printf("! Not enough damage taken") hit.power = nil hit.fall = nil hit.bone_id = nil hit.bone_id_adj = nil hit.draftsman = nil end SaveHealthStatus() end function actor_on_before_hit(shit, bone_id) if shit.type == 7 then hit.type = "Strike" elseif shit.type == 6 then hit.type = "Gunshot" elseif shit.type == 8 then hit.type = "Explosive" elseif shit.type == 2 then hit.type = "Chemical" elseif shit.type == 1 then hit.type = "Electric" elseif shit.type == 10 then hit.type = "Fire" elseif shit.type == 0 then hit.type = "Burn" else hit.type=shit.type end hit.power=shit.power hit.bone_id=bone_id hit.draftsman=shit.draftsman if (hit.type == "Chemical" or hit.type == "Burn" or hit.type == "Flame") and shit.power <0.01 then hit.apply=true end end local progress_stamina=nil local progress_health=nil local progress_health_head=nil local progress_health_torso=nil local progress_health_rightarm=nil local progress_health_leftarm=nil local progress_health_rightleg=nil local progress_health_leftleg=nil local progress_health_head_time=nil local progress_health_torso_time=nil local progress_health_rightarm_time=nil local progress_health_leftarm_time=nil local progress_health_rightleg_time=nil local progress_health_leftleg_time=nil local progress_health_torso_surgery=nil local progress_health_rightarm_surgery=nil local progress_health_leftarm_surgery=nil local progress_health_rightleg_surgery=nil local progress_health_leftleg_surgery=nil local scuffed_fix = false local function HUDUpdate() if showtexthud>=1 then --text local staticname="body_health_system_text" if showtexthud==1 then staticname="body_health_system_text" elseif showtexthud==2 then staticname="cop_debug" end local hud = get_hud() local hud_d = hud:GetCustomStatic(staticname) local wnd if not healthstatus or show_hud_type~=2 then --not show if (hud_d ~= nil) then hud:RemoveCustomStatic(staticname) hud_d = nil end return end if (hud_d == nil) then hud:AddCustomStatic(staticname,true) hud_d = hud:GetCustomStatic(staticname) wnd = hud_d:wnd() if (wnd ~= nil) then wnd:SetAutoDelete(true) end end if (hud_d ~= nil) then wnd = hud_d:wnd() local str="" if hud_vertical_spacing or hud_vertical_spacing>0 then for i=1,hud_vertical_spacing do str=str.." \\n" end end local showparts=true if hide_if_healthy then showparts=false for k,v in pairs(health) do if (v0) then showparts=true break end end end if not showparts then str=str.." \\n".." \\n".." \\n".." \\n" end if show_player_name then str=str..colors.grey..db.actor:character_name().."\\n" else str=str.." \\n" end local function AddToHUDCircles(array,text,class,array2) if class=="main" and showparts then str = str..colors[GetConditionFromFloat(health[array]/maxhp[array],array)] for i=1,(preview.health[array] or health[array]) do str=str.."•" -- str=str.."�" end str=str..colors.critical for i=1,(preview.surgeryhp[array] or surgeryhp[array]) do str=str.."•" -- str=str.."�" end str=str..colors.good for i=1,(preview.bonus[array] or timedhp[array]) do str=str.."•" -- str=str.."�" end str=str..colors.blank for i=1,maxhp[array]-(preview.health[array] or health[array])-(preview.bonus[array] or timedhp[array]) do str=str.."•" -- str=str.."�" end local whatcolor="grey" if health[array]<=4 then whatcolor="critical" end if health[array]==0 then whatcolor="blank" end -- local hp_addition=preview.health[array] -- if hp_addition>0 then -- text=text..colors.blue.." +"..hp_addition -- end -- local green_addition=preview.bonus[array] -- if green_addition>0 then -- text=text..colors.good.." +"..green_addition -- end str=str..colors[whatcolor].." // "..text.."\\n"--.." H:"..health[array].." T:"..timedhp[array].." S:"..surgeryhp[array].." PH:"..preview.health[array].." PB:"..preview.bonus[array].." S:"..preview.surgeryhp[array].."\\n" end if not (zzz_player_injuries_mcm.get_config("TEXT_BASED_PATCH")) then if class=="condition" then local hp_in_ints=math.floor(db.actor.health*11) str = str..colors.blue if db.actor.health>=1.0 then hp_in_ints=11 end if db.actor.health<=0.0 then hp_in_ints=0 end for i=1,hp_in_ints do str=str.."•" -- str=str.."�" end str=str..colors.blank for i=1,11-hp_in_ints do str=str.."•" -- str=str.."�" end local whatcolor="grey" if db.actor.health<=0.4 then whatcolor="critical" end if db.actor.health<=0 then whatcolor="blank" end str=str..colors[whatcolor].." // "..text.."\\n" elseif class=="stamina" then local hp_in_ints=math.floor(db.actor.power*11) str = str..colors.blue if db.actor.power>=1.0 then hp_in_ints=11 end if db.actor.power>0.98 then hp_in_ints=11 end if db.actor.power<=0.0 then hp_in_ints=0 end for i=1,hp_in_ints do str=str.."•" -- str=str.."�" end str=str..colors.blank for i=1,11-hp_in_ints do str=str.."•" -- str=str.."�" end local whatcolor="grey" -- if db.actor.power<=0.4 then whatcolor="critical" end -- if db.actor.power<=0 then whatcolor="blank" end str=str..colors[whatcolor].." // "..text.."\\n" end end if class=="limbs" and showparts then str = str..colors[GetConditionFromFloat(health[array]/maxhp[array],array)] for i=1,(preview.health[array] or health[array]) do str=str.."•" -- str=str.."�" end str=str..colors.critical for i=1,(preview.surgeryhp[array] or surgeryhp[array]) do str=str.."•" -- str=str.."�" end str=str..colors.good for i=1,(preview.bonus[array] or timedhp[array]) do str=str.."•" -- str=str.."�" end str=str..colors.blank for i=1,maxhp[array]-(preview.health[array] or health[array])-(preview.bonus[array] or timedhp[array]) do str=str.."•" -- str=str.."�" end str=str.." " if (preview.health[array2] or health[array2])0 then -- text=text..colors.blue.." +"..hp_addition -- end -- local green_addition=preview.bonus[array] -- if green_addition>0 then -- text=text..colors.good.." +"..green_addition -- end str=str..colors[whatcolor].." // "..text.."\\n"--.." H[1]:"..health[array].." T[1]:"..timedhp[array].." S[1]:"..surgeryhp[array].." PH[1]:"..preview.health[array].." PB[1]:"..preview.bonus[array].." PS[1]:"..surgeryhp[array].." H[2]:"..health[array2].." T[2]:"..timedhp[array2].." S[2]:"..surgeryhp[array].." PH[2]:"..preview.health[array2].." PB[2]:"..preview.bonus[array2].." S[2]:"..surgeryhp[array].."\\n" end end local preview_show=false for k,v in pairs(preview.health) do if preview.health[k] then preview_show=true break end end for k,v in pairs(preview.bonus) do if preview.bonus[k] then preview_show=true break end end AddToHUDCircles("head","Head","main") AddToHUDCircles("torso","Torso","main") AddToHUDCircles("leftarm","Arms","limbs","rightarm") AddToHUDCircles("leftleg","Legs","limbs","rightleg") if not (zzz_player_injuries_mcm.get_config("TEXT_BASED_PATCH")) then AddToHUDCircles(nil,"Condition","condition") AddToHUDCircles(nil,"Stamina","stamina") end local green = math.floor(255 * ((100 - 100)/100)) local red = math.floor(255 * (100/100)) wnd:TextControl():SetTextST(str) wnd:TextControl():SetTextColor(GetARGB(255, 255, 255, 255)) local hud = get_hud() if not (hud) then return end end else --pics local staticname="body_health_system" if display.types[display_ratio] then if display_ratio~=169 then staticname=staticname.."_"..tostring(display_ratio) end end local hud = get_hud() local hud_d = hud:GetCustomStatic(staticname) local wnd if not healthstatus or show_hud_type~=2 then --not show if (hud_d ~= nil) then hud:RemoveCustomStatic(staticname) hud_d = nil end goto otherhudparts end if (hud_d == nil) then hud:AddCustomStatic(staticname,true) hud_d = hud:GetCustomStatic(staticname) wnd = hud_d:wnd() if (wnd ~= nil) then wnd:SetAutoDelete(true) end end if (hud_d ~= nil) then wnd = hud_d:wnd() local hud = get_hud() if not (hud) then return end end ::otherhudparts:: local xml = CScriptXmlInit() xml:ParseFile("ui_body_health.xml") local function ParamBar(barhandler,customstatic,barname,param,param_max,showbg) ---- minimal bgs ---- local staticname if showbg then staticname=customstatic.."_bg" else staticname="bhs_garbage" end if display.types[display_ratio] then if display_ratio~=169 then staticname=staticname.."_"..tostring(display_ratio) end end local hud = get_hud() local hud_d = hud:GetCustomStatic(staticname) local wnd if not healthstatus or show_hud_type~=1 or (not showbg) then --not show if (hud_d ~= nil) then hud:RemoveCustomStatic(staticname) hud_d = nil end else if (hud_d == nil) then hud:AddCustomStatic(staticname,true) hud_d = hud:GetCustomStatic(staticname) wnd = hud_d:wnd() if (wnd ~= nil) then wnd:SetAutoDelete(true) end end if (hud_d ~= nil) then wnd = hud_d:wnd() local hud = get_hud() if not (hud) then goto progressbars end end end ------------------- ::progressbars:: if display.types[display_ratio] then if display_ratio~=169 then customstatic=customstatic.."_"..tostring(display_ratio) barname=barname.."_"..tostring(display_ratio) end end local cs_name = hud:GetCustomStatic(customstatic) if (cs_name == nil) then if not (scuffed_fix) then hud:AddCustomStatic(customstatic, true) cs_name = hud:GetCustomStatic(customstatic) local w = cs_name:wnd() barhandler = xml:InitProgressBar(barname, w) barhandler:Show(true) barhandler:SetProgressPos(55) scuffed_fix = true CreateTimeEvent("bvcx", "bvcx", disable_hud_fps_fix_tmr, worst_possible_fix) end else if not param_max then --default 0 to 100 param=param*100 if not param then param=0 end barhandler:SetProgressPos(param) else param=param*100/param_max if not param then param=0 end barhandler:SetProgressPos(param) end end if show_hud_type<1 or (time_global()-show_hud_change_time<50) then --not show if (cs_name ~= nil) then hud:RemoveCustomStatic(customstatic) cs_name = nil end -- barhandler:Show(false) -- else -- barhandler:Show(true) end return barhandler end --- yellow bkg lines equials health+timedhp ----- local function nil_math(array) local arg=health[array]+timedhp[array] if preview.health[array] or preview.bonus[array] then arg=(preview.health[array] or 0)+(preview.bonus[array] or 0) end return arg end progress_health_head_time=ParamBar(progress_health_head_time,"bhs_health_head_bar_green","bhs_health_bodypart_green", nil_math("head"),maxhp.head,false) progress_health_torso_time=ParamBar(progress_health_torso_time,"bhs_health_torso_bar_green","bhs_health_bodypart_green", nil_math("torso"),maxhp.torso,false) progress_health_rightarm_time=ParamBar(progress_health_rightarm_time,"bhs_health_rightarm_bar_green","bhs_health_bodypart_green", nil_math("rightarm"),maxhp.rightarm,false) progress_health_leftarm_time=ParamBar(progress_health_leftarm_time,"bhs_health_leftarm_bar_green","bhs_health_bodypart_green", nil_math("leftarm"),maxhp.leftarm,false) progress_health_rightleg_time=ParamBar(progress_health_rightleg_time,"bhs_health_rightleg_bar_green","bhs_health_bodypart_green", nil_math("rightleg"),maxhp.rightleg,false) progress_health_leftleg_time=ParamBar(progress_health_leftleg_time,"bhs_health_leftleg_bar_green","bhs_health_bodypart_green", nil_math("leftleg"),maxhp.leftleg,false) ----------------------------- --- blue bkg health equals heals ----- if not (zzz_player_injuries_mcm.get_config("TEXT_BASED_PATCH")) then progress_stamina=ParamBar(progress_stamina,"bhs_stamina_bar","bhs_stamina",db.actor.power,nil,true) end progress_health=ParamBar(progress_health,"bhs_health_bar","bhs_health",db.actor.health,nil,true) progress_health_head=ParamBar(progress_health_head,"bhs_health_head_bar","bhs_health_bodypart", preview.health.head or health.head,maxhp.head,true) progress_health_torso=ParamBar(progress_health_torso,"bhs_health_torso_bar","bhs_health_bodypart", preview.health.torso or health.torso,maxhp.torso,true) progress_health_rightarm=ParamBar(progress_health_rightarm,"bhs_health_rightarm_bar","bhs_health_bodypart", preview.health.rightarm or health.rightarm,maxhp.rightarm,true) progress_health_leftarm=ParamBar(progress_health_leftarm,"bhs_health_leftarm_bar","bhs_health_bodypart", preview.health.leftarm or health.leftarm,maxhp.leftarm,true) progress_health_rightleg=ParamBar(progress_health_rightleg,"bhs_health_rightleg_bar","bhs_health_bodypart", preview.health.rightleg or health.rightleg,maxhp.rightleg,true) progress_health_leftleg=ParamBar(progress_health_leftleg,"bhs_health_leftleg_bar","bhs_health_bodypart", preview.health.leftleg or health.leftleg,maxhp.leftleg,true) ------------------------------------- --- red bkg health equals surgery ----- progress_health_torso_surgery=ParamBar(progress_health_torso_surgery,"bhs_health_torso_bar_blue","bhs_health_bodypart_blue", preview.surgeryhp.torso or surgeryhp.torso,maxhp.torso,false) progress_health_rightarm_surgery=ParamBar(progress_health_rightarm_surgery,"bhs_health_rightarm_bar_blue","bhs_health_bodypart_blue", preview.surgeryhp.rightarm or surgeryhp.rightarm,maxhp.rightarm,false) progress_health_leftarm_surgery=ParamBar(progress_health_leftarm_surgery,"bhs_health_leftarm_bar_blue","bhs_health_bodypart_blue", preview.surgeryhp.leftarm or surgeryhp.leftarm,maxhp.leftarm,false) progress_health_rightleg_surgery=ParamBar(progress_health_rightleg_surgery,"bhs_health_rightleg_bar_blue","bhs_health_bodypart_blue", preview.surgeryhp.rightleg or surgeryhp.rightleg,maxhp.rightleg,false) progress_health_leftleg_surgery=ParamBar(progress_health_leftleg_surgery,"bhs_health_leftleg_bar_blue","bhs_health_bodypart_blue", preview.surgeryhp.leftleg or surgeryhp.leftleg,maxhp.leftleg,false) ------------------------------------- end end function worst_possible_fix() scuffed_fix = false return true end function on_key_press(dik) if dik == DIK_keys.DIK_H then -- if healthstatus then -- healthstatus=false -- xr_sound.set_sound_play(db.actor:id(), "pda_tips") -- else -- healthstatus=true -- staticplacement=lazyworkaroundplacement -- xr_sound.set_sound_play(db.actor:id(), "pda_alarm") -- end if showtexthud>0 then healthstatus=not healthstatus else if show_hud_type==0 then show_hud_type=1 show_hud_change_time=time_global() elseif show_hud_type==1 then show_hud_type=2 show_hud_change_time=time_global() elseif show_hud_type==2 then show_hud_type=0 show_hud_change_time=time_global() end end xr_sound.set_sound_play(db.actor:id(), "pda_tips") HUDUpdate() -- elseif dik==DIK_keys.DIK_J then -- health.rightarm=health.rightarm-1 -- elseif dik==DIK_keys.DIK_K then -- health.leftarm=health.leftarm-1 -- db.actor:give_game_news("resolution", tostring(options) or "nil", db.actor:character_icon(), 0, 10000) -- xr_sound.set_sound_play(db.actor:id(), "pda_tips") end end local function actor_on_weapon_zoom_in(wpn) --maybe needed for sway idk shaking_hands() end local function actor_on_weapon_zoom_out(wpn) shaking_hands_remove() end local tg_anm = 0 local delay_anm_play = 500 cooldown = 1000 state_cooldown = 0 local function actor_on_footstep(material,power,hud_view,flags) local tg = time_global() local right_l = (health.leftleg + timedhp.leftleg) * effects_mult -- right is left local left_l = (health.rightleg + timedhp.rightleg) * effects_mult if right_l < 1 then right_l = 0.8 end -- exp will still make big difference between 1 and 0.8 if left_l < 1 then left_l = 0.8 end local legs_sum = (right_l + left_l) * effects_mult local left_limp = math.exp(1.5/left_l) -- local right_limp = math.exp(1.5/right_l) local both_limp = (right_limp + left_limp) / 2 local mst = IsMoveState('mcSprint') -- sprint is tearing animations apart, the only way is to increase delay for it if tg > tg_anm then if leftleg_flag then if not mst then level.add_cam_effector("camera_effects\\switch\\" .. leftleg_anm[math.random(#leftleg_anm)] .. ".anm", 99251, false, "", 0, false, ((left_limp - 1) * (zzz_player_injuries_mcm.get_config("leg_animation_power"))) ) tg_anm = tg + delay_anm_play end -- actor_menu.set_msg(1, strformat("Left leg HP: %s | Left leg Power: %s", left_l, left_limp)) elseif rightleg_flag then if not mst then level.add_cam_effector("camera_effects\\switch\\" .. rightleg_anm[math.random(#rightleg_anm)] .. ".anm", 99261, false, "", 0, false, ((right_limp - 1) * (zzz_player_injuries_mcm.get_config("leg_animation_power"))) ) tg_anm = tg + delay_anm_play end -- actor_menu.set_msg(1, strformat("Right leg HP: %s | Right leg Power: %s", right_l, right_limp)) elseif bothlegs_flag then level.add_cam_effector("camera_effects\\switch\\" .. bothlegs_anm[math.random(#bothlegs_anm)] .. ".anm", 99271, false, "", 0, false, ((both_limp - 1) * (zzz_player_injuries_mcm.get_config("leg_animation_power"))) ) if not mst then tg_anm = tg + delay_anm_play else tg_anm = tg + delay_anm_play * 1.6 end -- actor_menu.set_msg(1, strformat("Both legs HP: %s | Both legs Power: %s", legs_sum, both_limp)) end end local l_leg_power = 0 local r_leg_power = 0 local hit_power = 0 local cr = IsMoveState('mcCrouch') local low_cr = cr and IsMoveState('mcAccel') if mst then -- comment this and uncomment next one for super memes !! -- if (not (cr or low_cr) ) and (left_l < 1 or right_l < 1) then local right_l_mst = health.leftleg * effects_mult -- right is left local left_l_mst = health.rightleg * effects_mult if right_l_mst < 1 then right_l = 0.8 end -- exp will still make big difference between 1 and 0.8 if left_l_mst < 1 then left_l = 0.8 end if left_l_mst <= (zzz_player_injuries_mcm.get_config("leg_limping_damage_minimum_hp")) then l_leg_power = 0.0290 end if right_l_mst <= (zzz_player_injuries_mcm.get_config("leg_limping_damage_minimum_hp")) then r_leg_power = 0.0290 end hit_power = (l_leg_power + r_leg_power) / 2 -- printf("hit_power: " .. (hit_power)) local file local chance = math.random(1,100) if (hit_power > 0) and (state_cooldown < time_global()) and (chance<=35) then if zzz_player_injuries_mcm.get_config("new_voice_sounds") then local helmet = (db.actor:item_in_slot(12) or db.actor:get_current_outfit()) local sound_play = math.random(1,13) if helmet then muffle = "" else muffle = "" end file = "bhs\\" .. muffle .. "pain_" .. sound_play else file = "actor\\pain_" .. sound_play end file_to_say = sound_object( file ) file_to_say:play(db.actor,0,sound_object.s2d) level.add_pp_effector("blur_bhs.ppe", math.random(655808, 655820), false) state_cooldown = time_global() + cooldown actor_health = db.actor.health if bhs_exp_mode then hit_power = hit_power *0.25 end actor_health_reduced = actor_health - hit_power db.actor:set_health_ex(actor_health_reduced) --hit.type="Fracture" end end end ------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------ local is_body_parts_damaged = false local function check_body_parts() local head_difference = maxhp.head - health.head local torso_difference = maxhp.torso - health.torso local rightarm_difference = maxhp.rightarm - health.rightarm local leftarm_difference = maxhp.leftarm - health.leftarm local rightleg_difference = maxhp.rightleg - health.rightleg local leftleg_difference = maxhp.leftleg - health.leftleg is_body_parts_damaged = false if (head_difference > 0 or torso_difference > 0 or rightarm_difference > 0 or leftarm_difference > 0 or rightleg_difference > 0 or leftleg_difference > 0) then is_body_parts_damaged = true end end old_is_actor_not_healthy = dialogs.is_actor_not_healthy function dialogs.is_actor_not_healthy(first_speaker, second_speaker) check_body_parts() if (is_body_parts_damaged == true) then return true end return old_is_actor_not_healthy(first_speaker, second_speaker) end old_is_actor_injured = dialogs.is_actor_injured function dialogs.is_actor_injured(first_speaker, second_speaker) check_body_parts() if (is_body_parts_damaged == true) and (db.actor:money() >= 1850) then return true end return old_is_actor_injured(first_speaker, second_speaker) end old_is_actor_injured_irradiated = dialogs.is_actor_injured_irradiated function dialogs.is_actor_injured_irradiated(first_speaker, second_speaker) check_body_parts() if (is_body_parts_damaged == true) and (db.actor.radiation > 0) and (db.actor:money() >= 3350) then return true end return old_is_actor_injured_irradiated(first_speaker, second_speaker) end local function heal_body_parts() timedhp.head = 0 health.head = maxhp.head timedhp.torso = 0 health.torso = maxhp.torso timedhp.rightarm = 0 health.rightarm = maxhp.rightarm timedhp.leftarm = 0 health.leftarm = maxhp.leftarm timedhp.rightleg = 0 health.rightleg=maxhp.rightleg timedhp.leftleg = 0 health.leftleg=maxhp.leftleg SaveHealthStatus() end old_heal_actor_injury_radiation = dialogs.heal_actor_injury_radiation function dialogs.heal_actor_injury_radiation(first_speaker, second_speaker) old_heal_actor_injury_radiation(first_speaker, second_speaker) check_body_parts() if (is_body_parts_damaged == true) then heal_body_parts() end end old_heal_actor_injury = dialogs.heal_actor_injury function dialogs.heal_actor_injury(first_speaker, second_speaker) old_heal_actor_injury(first_speaker, second_speaker) check_body_parts() if (is_body_parts_damaged == true) then heal_body_parts() end end --new code Eddie-------------------------------------------------------- function rank_part(name) if string.find(name, "leg") then return 5 elseif string.find(name, "arm") then return 4 elseif string.match(name, "torso") then return 3 elseif string.match(name, "head") then return 2 else return 1 end end local functor = function(t,a,b) local rank_a = a and rank_part(a) or 0 local rank_b = b and rank_part(b) or 0 if rank_a ~= rank_b then return rank_a > rank_b else return a > b end end local function HealOne(healpower,health,surgeryhp) local healupto = healpower if healupto == 0 then healupto=db.actor.health --Heal up to this percentage value. Medicine should have 1, regeneration uses actor health. elseif healupto > 1 then healupto = 1 end local healamount = 1 local loopcounter = 1 --Only heal limbs that are not broken (broken = at 0 hp). if using_surgery then if splinting and (healpower>0 and medkit_is_splint) then loopcounter = 0 end while healamount > 0 do for k,v in pairs(health, functor) do adjustedhealth = v --Double health for arm&leg for deciding what to heal, since limbs have half hp of head/torso if string.find(k, "leg") or string.find(k, "arm") then adjustedhealth = adjustedhealth * 2 end if adjustedhealth == loopcounter then if ((loopcounter==0 and surgeryhp[k]>0) and health[k] < maxhp[k] * healupto) or (loopcounter>0 and health[k] < maxhp[k] * healupto) then health[k] = health[k] + 1 if health[k]>maxhp[k] then health[k]=maxhp[k] end if surgeryhp[k]>0 then surgeryhp[k] = surgeryhp[k] - 1 end healamount = 0 --printf("Healed once") break end end end if loopcounter >= maxhp.head * healupto and loopcounter >= maxhp.torso * healupto and loopcounter >= maxhp.rightarm * 2 * healupto and loopcounter >= maxhp.rightleg * 2 * healupto then break end loopcounter = loopcounter + 1 end else if (medkit_is_splint and healpower > 0) or not splinting then loopcounter=0 end while healamount > 0 do printf("Trying to limb with %s, healpower: %s",loopcounter,healpower) for k,v in pairs(health, functor) do adjustedhealth = v --Double health for arm&leg for deciding what to heal, since limbs have half hp of head/torso if string.find(k, "leg") or string.find(k, "arm") then adjustedhealth = adjustedhealth * 2 end if adjustedhealth == loopcounter then if health[k] < maxhp[k] * healupto then health[k] = health[k] + 1 if health[k]>maxhp[k] then health[k]=maxhp[k] end if surgeryhp[k]>0 then surgeryhp[k] = surgeryhp[k] - 1 end healamount = 0 --printf("Healed once") break end end end if loopcounter >= maxhp.head * healupto and loopcounter >= maxhp.torso * healupto and loopcounter >= maxhp.rightarm * 2 * healupto and loopcounter >= maxhp.rightleg * 2 * healupto then break end loopcounter = loopcounter + 1 end end SaveHealthStatus() end function ArtiHeal(healpower) printf("Artihealed or campfire once") HealOne(healpower,health,surgeryhp) end local function SurgeryUsed(name,health,surgeryhp) local surgeryamount = surgerylist[name].surgeryamount if surgeryamount <= 0 then return end --printf("Using surgery") if using_surgery and not surgery_all_limbs then if not surgery_heals and not (cms_restores_hp_too and string.match(name, "cms")) then for k,v in pairs(health, functor) do if v == 0 and surgeryhp[k] == 0 then if string.match(k, "torso") or string.match(k, "head") then surgeryhp[k] = surgeryamount*2 else surgeryhp[k] = surgeryamount end --printf("Surgery used on %s",k) surgeryamount = 0 if surgeryhp[k]>maxhp[k] then surgeryhp[k]=maxhp[k] end break end end else for k,v in pairs(health, functor) do if v == 0 then if string.match(k, "torso") or string.match(k, "head") then health[k] = surgeryamount*2 else health[k] = surgeryamount end --printf("Surgery used on %s",k) surgeryamount = 0 surgeryhp[k] = 0 if health[k]>maxhp[k] then health[k]=maxhp[k] end break end end end elseif using_surgery and surgery_all_limbs then if not surgery_heals and not (cms_restores_hp_too and string.match(name, "cms")) then for k,v in pairs(health, functor) do if v == 0 and surgeryhp[k] == 0 then if string.match(k, "torso") or string.match(k, "head") then surgeryhp[k] = surgeryamount*2 else surgeryhp[k] = surgeryamount end --printf("Surgery used on %s",k) if surgeryhp[k]>maxhp[k] then surgeryhp[k]=maxhp[k] end end end else for k,v in pairs(health, functor) do if v == 0 then if string.match(k, "torso") or string.match(k, "head") then health[k] = surgeryamount*2 else health[k] = surgeryamount end --printf("Surgery used on %s",k) if health[k]>maxhp[k] then health[k]=maxhp[k] end if surgeryhp[k]>0 then surgeryhp[k] = 0 end end end end end SaveHealthStatus() end local function SplintUsed(name,health,surgeryhp) local splintamount = splintlist[name].splintamount if splintamount <= 0 then return end local loopcounter = 0 if using_surgery then --printf("Using surgery") --printf("Splinting") for k,v in pairs(surgeryhp, functor) do if v >= 1 then health[k] = health[k] + surgeryhp[k] --printf("Splint used on %s",k) splintamount = 0 surgeryhp[k] = 0 if health[k]>maxhp[k] then health[k]=maxhp[k] end if splintamount <= 0 then break end end end else for k,v in pairs(health, functor) do if v == 0 then health[k] = health[k] + splintamount --printf("Splint used on %s",k) splintamount = 0 surgeryhp[k] = 0 if health[k]>maxhp[k] then health[k]=maxhp[k] end if splintamount <= 0 then break end end end end SaveHealthStatus() end ---------------------------------------------------------------- local currentBoosters = {} local boosterCounters = {} function manage_boosters() local c_obj = db.actor:cast_Actor() local function restoreState() if currentBoosters[BoosterID["HpRestore"]] then currentBoosters[BoosterID["HpRestore"]] = nil c_obj:conditions():BoostHpRestore(-(boosterCounters[BoosterID["HpRestore"]] or 0)) boosterCounters[BoosterID["HpRestore"]] = nil end end local foundRadiationBooster = false c_obj:conditions():BoosterForEach(function(booster_type, booster_time, booster_value) if booster_type == BoosterID["HpRestore"] and booster_value > 0 then if boosterCounters[booster_type] then c_obj:conditions():BoostHpRestore(-boosterCounters[booster_type]) else boosterCounters[booster_type] = 0 end currentBoosters[booster_type] = booster_value boosterCounters[booster_type] = -booster_value c_obj:conditions():BoostHpRestore(boosterCounters[booster_type]) foundRadiationBooster = true --printf("booster_type %s, booster_time %s, booster_value %s", booster_type, booster_time, booster_value+boosterCounters[booster_type]) end end) if not foundRadiationBooster and currentBoosters[BoosterID["HpRestore"]] then restoreState() end end local status_check_timer = 0 local status_check_interval = 250 function actor_on_update() local statuschanged = false if bhs_exp_mode then manage_boosters() --if time_global() >= status_check_timer then -- status_check_timer = time_global() + status_check_interval --end if exp_druglist.restorepower > 0 then if time_global() - exp_druglist.lasttimestamp > exp_druglist.restoreduration then if exp_druglist.countdown_increments == 1 or exp_druglist.countdown_increments < 0 then db.actor:change_health(exp_druglist.restorepower) exp_druglist.countdown_increments = 0 printf("(EXP) Restore effect ran out") exp_druglist.restoreduration = 0 exp_druglist.restorepower = 0 exp_druglist.lasttimestamp = time_global() elseif exp_druglist.countdown_increments > 1 then db.actor:change_health(exp_druglist.restorepower) exp_druglist.countdown_increments = exp_druglist.countdown_increments - 1 exp_druglist.lasttimestamp = time_global() --printf("Restore countdowns left: %s",exp_druglist.countdown_increments) end statuschanged = true end end end --actor_menu.set_msg("width:"..device().width.." height:"..device().height) local newhealth=db.actor.health local amount=myhealth-newhealth if amount>0 and hit.type and bhs_exp_mode then if hit.apply then hit.apply=false else db.actor:change_health(amount) end printf("Damage received: %s, Type: %s",amount,hit.type) hit.type = nil elseif amount>0.001 and bhs_exp_mode then printf("Typeless damage received: %s",amount) end if db.actor.health <= 0 and bhs_exp_mode then printf("Allowing death") hit.death=true db.actor.health=1 db.actor.health=-1 end myhealth=db.actor.health if time_global() >= status_check_timer then status_check_timer = time_global() + status_check_interval for k,v in pairs(health) do if v>maxhp[k] then health[k]=maxhp[k] end if v<=0 then health[k]=0 end end for k,v in pairs(preview.health) do if v>maxhp[k] then preview.health[k]=maxhp[k] preview.bonus[k]=0 end if v<=0 then preview.health[k]=0 end if (preview.health[k]+preview.bonus[k])>maxhp[k] then preview.bonus[k]=(health[k]-maxhp[k]) end -- needs a check end local allheal_ceiling=1 if timedheal.torso>0 and time_global()-healhelplist.lastregen>healhelplist.healtimer then healhelplist.lastregen=time_global() if healhelplist.healpower == 0 then allheal_ceiling=db.actor.health else allheal_ceiling=healhelplist.healpower end for k,v in pairs(timedheal) do if v>0 then if health[k]~=0 or (not splinting) or (medkit_is_splint and medkits_all_heal) then -- broken if health[k]maxhp[k] then health[k]=maxhp[k] end end --printf("Healed all") else --printf("Wasted healing on %s",k) end timedheal[k]=timedheal[k]-1 if timedheal[k]<0 then timedheal[k]=0 end end end statuschanged = true end if time_global() - healonelist.lastregen > healonelist.healtimer then if healonelist.healamount > 0 then HealOne(healonelist.healpower,health,surgeryhp) -- healing not capped to actor.health % healonelist.healamount = healonelist.healamount - 1 if healonelist.healamount < 0 then healonelist.healamount = 0 end if healonelist.healamount == 0 then healonelist.lastregen = 0 healonelist.healpower = 0 else healonelist.lastregen = time_global() end statuschanged = true end end if painkillerlist.painkillerpower > 0 then if time_global() - painkillerlist.lasttimestamp > painkillerlist.painkillerduration then if painkillerlist.countdown_increments == 1 or painkillerlist.countdown_increments < 0 then painkillerlist.countdown_increments = 0 printf("Painkillers ran out") painkillerlist.painkillerpower = 0 painkillerlist.painkillerduration = 0 painkillerlist.lasttimestamp = time_global() if painkiller_grain_shader then level.remove_pp_effector(5020) end for k,v in pairs(health) do timedhp[k] = 0 end elseif painkillerlist.countdown_increments > 1 then painkillerlist.countdown_increments = painkillerlist.countdown_increments - 1 painkillerlist.lasttimestamp = time_global() --printf("Countdowns left: %s",painkillerlist.countdown_increments) end statuschanged = true end end if modifiedregen>0 and init then if time_global() - healtimer > modifiedregen then HealOne(newhealth,health,surgeryhp) healtimer = time_global() statuschanged = true end end if not init then display_width=device().width display_height=device().height local currentratio=display_width/display_height local closest=999 local closestkey=999 for k,v in pairs(display.types) do local d=math.abs(currentratio-v) if d missinghealth then bonus = missinghealth end timedhp[k] = bonus end SaveHealthStatus() end if not (zzz_player_injuries_mcm.get_config("TEXT_BASED_PATCH")) then local hidehudonce=false if hide_default_hud and not hidehudonce then local maingameui = ActorMenu.get_maingame() maingameui.m_ui_hud_states.m_ui_health_bar_show = false maingameui.m_ui_hud_states.m_ui_stamina_bar_show = false -- maingameui.m_ui_hud_states.m_ui_psy_bar_show = false hidehudonce=true end end local speedvector=db.actor:get_movement_speed() local movementspeed=(speedvector.x*speedvector.x)+(speedvector.y*speedvector.y)+(speedvector.z*speedvector.z) -- xcvb --- limp_speed_slow() torso_penalty() bhs_concussion() local curr_time = game.get_game_time() if (prev_time == nil) then prev_time = curr_time end if (curr_time:diffSec(prev_time) > 3) then prev_time = curr_time legs_limp() end ---------------------------- end HUDUpdate() --if health.torso==0 then -- hit.death = true -- db.actor.health=-1 --end if health.head== 0 then hit.death = true db.actor.health=-1 printf("Allowing death from head reaching 0") end if hit.death then printf("Allowing death") db.actor.health=-1 end end local function actor_on_before_death(whoID,flags) if bhs_exp_mode and not hit.death and arszi_psy.get_psy_health() > 0 then printf("!Preventing death") --if myhealth <=0 then -- printf("Healing to full from: %s, actual health: %s",myhealth, db.actor.health) -- db.actor.health=1 --else -- printf("Resetting health to: %s, actual health: %s",myhealth, db.actor.health) -- db.actor.health=myhealth --end if hit.type then if hit.apply then hit.apply=false else db.actor.health=myhealth printf("!Revesing death damage") end end if db.actor.health <= 0 then printf("!Allowing death") hit.death=true end flags.ret_value = false return else HUDUpdate() health.head=maxhp.head health.torso=maxhp.torso health.rightarm=maxhp.rightarm health.leftarm=maxhp.leftarm health.rightleg=maxhp.rightleg health.leftleg=maxhp.leftleg timedhp.head=0 timedhp.torso=0 timedhp.rightarm=0 timedhp.leftarm=0 timedhp.rightleg=0 timedhp.leftleg=0 SaveHealthStatus() if volume_sound_x then exec_console_cmd("snd_volume_eff " .. volume_sound_x) end end end local function MedicineUsed(name,health,timedheal,surgeryhp,ispreview) --printf("Medicine used for %s",ispreview) if splintlist[name] then SplintUsed(name,health,surgeryhp) --printf("Splint used for %s",ispreview) -- see console output end if surgerylist[name] then SurgeryUsed(name,health,surgeryhp) --printf("Surgery used for %s",ispreview) -- see console output end if ispreview == 0 then if healhelplist[name] then healhelplist.lastregen=time_global() healhelplist.healtimer=healhelplist[name].healtimer healhelplist.healpower=healhelplist[name].healpower for k,v in pairs(timedheal) do local bonus=healhelplist[name][k] if bonus and (health[k]>0 or (health[k]==0 and (not splinting or (medkit_is_splint and healhelplist.healpower>0)))) then timedheal[k]=bonus end end --printf("Heal all used for %s",ispreview) end if healonelist[name] then healonelist.healamount = healonelist[name].healamount healonelist.healtimer = healonelist[name].healtimer healonelist.healpower = healonelist[name].healpower healonelist.lastregen = time_global() --printf("Heal one used for %s",ispreview) end if painkillerlist[name] then if painkillerlist.painkillerpower < painkillerlist[name].painkillerpower then painkillerlist.painkillerpower = painkillerlist[name].painkillerpower painkillerlist.countdown_increments=painkillerlist[name].countdown_increments --printf("Original duration: %s",painkillerlist[name].painkillerduration) painkillerlist.painkillerduration = painkillerlist[name].painkillerduration/painkillerlist.countdown_increments --printf("Countdowns set. New duration: %s",painkillerlist.painkillerduration) painkillerlist.lasttimestamp = time_global() elseif painkillerlist.painkillerpower == painkillerlist[name].painkillerpower then painkillerlist.countdown_increments=painkillerlist[name].countdown_increments --printf("Original duration: %s",painkillerlist[name].painkillerduration) painkillerlist.painkillerduration = painkillerlist[name].painkillerduration/painkillerlist.countdown_increments --printf("Countdowns set. New duration: %s",painkillerlist.painkillerduration) painkillerlist.lasttimestamp = time_global() end if painkiller_grain_shader then level.add_pp_effector("radiation.ppe", 5020, true) end --printf("Painkiller used for %s",ispreview) end for k,v in pairs(health) do local missinghealth = 0 if v < maxhp[k] then missinghealth = maxhp[k] - v if missinghealth < 0 then missinghealth = 0 end end local bonus = painkillerlist.painkillerpower if string.match(k, "head") or string.match(k, "torso") then bonus = painkillerlist.painkillerpower * 2 end if bonus > missinghealth then bonus = missinghealth end timedhp[k] = bonus end else if healonelist[name] then for i=1,healonelist[name].healamount do HealOne(healonelist[name].healpower,health,surgeryhp) --printf("HealOne used for %s",ispreview) end end if healhelplist[name] then local allheal_ceiling=1 if healhelplist[name].healpower <= 0 then allheal_ceiling=db.actor.health else allheal_ceiling=healhelplist[name].healpower end for k,v in pairs(health) do local bonus = healhelplist[name][k] if bonus and (health[k]>0 or (health[k]==0 and (not splinting or (medkit_is_splint and healhelplist[name].healpower>0)))) then if health[k]+bonus>maxhp[k]*allheal_ceiling then health[k]=maxhp[k]*allheal_ceiling else health[k]=health[k]+bonus end end end --printf("Heal all used for %s",ispreview) end painkillerpreview = painkillerlist.painkillerpower if painkillerlist[name] then if painkillerpreview < painkillerlist[name].painkillerpower then painkillerpreview = painkillerlist[name].painkillerpower end --printf("Painkiller used for %s",ispreview) end if painkillerpreview > 0 then for k,v in pairs(health) do missinghealth = 0 if v < maxhp[k] then missinghealth = maxhp[k] - v if missinghealth < 0 then missinghealth = 0 end end bonus = painkillerpreview if string.match(k, "head") or string.match(k, "torso") then bonus = painkillerpreview * 2 end if bonus > missinghealth then bonus = missinghealth end preview.bonus[k] = bonus end end end end local function actor_on_sleep(hours) local hoursleft=hours printf("Sleepie time for : %s", hoursleft) for k,v in pairs(timedhp) do timedhp[k]=0 painkillerlist.painkillerpower = 0 painkillerlist.painkillerduration = 0 painkillerlist.countdown_increments=0 if painkiller_grain_shader then level.remove_pp_effector(5020) end end hoursleft = hoursleft*sleep_heal_power printf("Adjusted hours: %s", hoursleft) if sleep_heal then if sleep_heal_logic then printf("Sleep logic is on") for i=1,hoursleft do HealOne(0,health,surgeryhp) end else printf("Sleep logic is off") local head_difference=maxhp.head-health.head if head_difference>0 then if hoursleft>head_difference then health.head=maxhp.head hoursleft=hoursleft-head_difference utils_obj.save_var(db.actor,"health.head",health.head) else health.head=health.head+hoursleft utils_obj.save_var(db.actor,"health.head",health.head) return end end local torso_difference=maxhp.torso-health.torso if torso_difference>0 then if hoursleft>torso_difference then health.torso=maxhp.torso hoursleft=hoursleft-torso_difference utils_obj.save_var(db.actor,"health.torso",health.torso) else health.torso=health.torso+hoursleft utils_obj.save_var(db.actor,"health.torso",health.torso) return end end local rightarm_difference=maxhp.rightarm-health.rightarm if rightarm_difference>0 then if hoursleft>rightarm_difference then health.rightarm=maxhp.rightarm hoursleft=hoursleft-rightarm_difference utils_obj.save_var(db.actor,"health.rightarm",health.rightarm) else health.rightarm=health.rightarm+hoursleft utils_obj.save_var(db.actor,"health.rightarm",health.rightarm) return end end local leftarm_difference=maxhp.leftarm-health.leftarm if leftarm_difference>0 then if hoursleft>leftarm_difference then health.leftarm=maxhp.leftarm hoursleft=hoursleft-leftarm_difference utils_obj.save_var(db.actor,"health.leftarm",health.leftarm) else health.leftarm=health.leftarm+hoursleft utils_obj.save_var(db.actor,"health.leftarm",health.leftarm) return end end local rightleg_difference=maxhp.rightleg-health.rightleg if rightleg_difference>0 then if hoursleft>rightleg_difference then health.rightleg=maxhp.rightleg hoursleft=hoursleft-rightleg_difference utils_obj.save_var(db.actor,"health.rightleg",health.rightleg) else health.rightleg=health.rightleg+hoursleft utils_obj.save_var(db.actor,"health.rightleg",health.rightleg) return end end local leftleg_difference=maxhp.leftleg-health.leftleg if leftleg_difference>0 then if hoursleft>leftleg_difference then health.leftleg=maxhp.leftleg hoursleft=hoursleft-leftleg_difference utils_obj.save_var(db.actor,"health.leftleg",health.leftleg) else health.leftleg=health.leftleg+hoursleft utils_obj.save_var(db.actor,"health.leftleg",health.leftleg) return end end end end SaveHealthStatus() end local function actor_on_item_use(obj,objname) --printf("Used %s",objname) if bhs_exp_mode and objname then if exp_druglist[objname] then --printf("Used a restore item: %s",objname) --printf("Will restore %s HP",exp_druglist[objname].restorepower*ini_sys:r_float_ex(objname, "boost_time")) exp_druglist.restoreduration = ini_sys:r_float_ex(objname, "boost_time")*1000/exp_druglist[objname].countdown_increments exp_druglist.restorepower = exp_druglist[objname].restorepower exp_druglist.lasttimestamp = time_global() exp_druglist.countdown_increments = exp_druglist[objname].countdown_increments --printf("Set countdown_increments to: %s",exp_druglist.restoreduration) end end --printf("%s used for %s",objname,obj) --printf("It deals %s damage",eat_damage) if bhs_exp_mode and objname then local eat_health = ini_sys:r_float_ex(objname, "eat_health") if eat_health>0 then db.actor:change_health(-eat_health) end --item.boost_time = ini_sys:r_float_ex(sec, "boost_time") --if item.boost_time and item.boost_time ~= 0 then -- item.boost_health_restore = ini_sys:r_float_ex(sec, "boost_health_restore") --end end MedicineUsed(objname,health,timedheal,surgeryhp,0) SaveHealthStatus() end local function InitializePreviewBars() -- db.actor:give_game_news("init", "yes", db.actor:character_icon(), 0, 10000) -- xr_sound.set_sound_play(db.actor:id(), "pda_tips") preview.health.head=health.head preview.health.torso=health.torso preview.health.rightarm=health.rightarm preview.health.leftarm=health.leftarm preview.health.rightleg=health.rightleg preview.health.leftleg=health.leftleg preview.bonus.head=timedhp.head preview.bonus.torso=timedhp.torso preview.bonus.rightarm=timedhp.rightarm preview.bonus.leftarm=timedhp.leftarm preview.bonus.rightleg=timedhp.rightleg preview.bonus.leftleg=timedhp.leftleg end local function EmptyPreviewBars() -- db.actor:give_game_news("empty", "yes", db.actor:character_icon(), 0, 10000) -- xr_sound.set_sound_play(db.actor:id(), "pda_tips") for k,v in pairs(preview.health) do preview.health[k]=nil end for k,v in pairs(preview.bonus) do preview.bonus[k]=nil end for k,v in pairs(preview.surgeryhp) do preview.surgeryhp[k]=nil end end local focused_item local function copy_table(t) local n={} for k,v in pairs(t) do if type(v)=='table' then n[k]=copy_table(v) else n[k]=v end end return n end local function ActorMenu_on_item_focus_receive(item) if item:id()~=focused_item then EmptyPreviewBars() end local item_name=item:section() focused_item=item:id() --printf("Focused %s item",item_name) if healhelplist[item_name] or splintlist[item_name] or painkillerlist[item_name] or healonelist[item_name] or surgerylist[item_name] then --printf("It was a medical item") -- InitializePreviewBars() preview.health=copy_table(health) preview.bonus=copy_table(timedhp) preview.surgeryhp=copy_table(surgeryhp) MedicineUsed(item_name,preview.health,preview.bonus,preview.surgeryhp,1) end end local function ActorMenu_on_item_focus_lost(item) --printf("! on item focus lost "..(item and item:section() or "nil")) if focused_item==item:id() then EmptyPreviewBars() focused_item=nil end end local function ActorMenu_on_mode_changed(mode,last_mode) if last_mode==1 then --inv closed EmptyPreviewBars() focused_item=nil elseif last_mode==4 then --looting closed EmptyPreviewBars() focused_item=nil end end function on_game_start() RegisterScriptCallback("on_option_change", on_option_change) -- xcvb RegisterScriptCallback("actor_on_first_update",actor_on_first_update) -- xcvb RegisterScriptCallback("on_key_press",on_key_press) RegisterScriptCallback("save_state",save_state) -- xcvb RegisterScriptCallback("load_state",load_state) -- xcvb RegisterScriptCallback("actor_on_weapon_zoom_in",actor_on_weapon_zoom_in) -- xcvb RegisterScriptCallback("actor_on_weapon_zoom_out",actor_on_weapon_zoom_out) -- xcvb RegisterScriptCallback("actor_on_footstep",actor_on_footstep) -- xcvb RegisterScriptCallback("actor_on_sleep",actor_on_sleep) if not grok_actor_damage_balancer then RegisterScriptCallback("actor_on_before_hit",actor_on_before_hit) end RegisterScriptCallback("actor_on_hit_callback",actor_on_hit_callback) RegisterScriptCallback("actor_on_update",actor_on_update) RegisterScriptCallback("actor_on_before_death",actor_on_before_death) RegisterScriptCallback("actor_on_item_use",actor_on_item_use) RegisterScriptCallback("ActorMenu_on_item_focus_receive",ActorMenu_on_item_focus_receive) RegisterScriptCallback("ActorMenu_on_item_focus_lost",ActorMenu_on_item_focus_lost) RegisterScriptCallback("ActorMenu_on_mode_changed",ActorMenu_on_mode_changed) end