2054 lines
62 KiB
Lua
2054 lines
62 KiB
Lua
-- Neurotrauma human update functions
|
|
-- Hooks Lua event "think" to update and use for applying NT specific character data (its called 'c') with
|
|
-- values/functions defined here in NT.UpdateHuman, NT.LimbAfflictions and NT.Afflictions
|
|
NT.UpdateCooldown = 0
|
|
NT.UpdateInterval = 120
|
|
NT.Deltatime = NT.UpdateInterval / 60 -- Time in seconds that transpires between updates
|
|
|
|
Hook.Add("think", "NT.update", function()
|
|
if HF.GameIsPaused() then
|
|
return
|
|
end
|
|
|
|
NT.UpdateCooldown = NT.UpdateCooldown - 1
|
|
if NT.UpdateCooldown <= 0 then
|
|
NT.UpdateCooldown = NT.UpdateInterval
|
|
NT.Update()
|
|
end
|
|
|
|
NT.TickUpdate()
|
|
end)
|
|
|
|
-- gets run once every two seconds
|
|
function NT.Update()
|
|
local updateHumans = {}
|
|
local amountHumans = 0
|
|
local updateMonsters = {}
|
|
local amountMonsters = 0
|
|
|
|
-- fetchcharacters to update
|
|
for key, character in pairs(Character.CharacterList) do
|
|
if not character.IsDead then
|
|
if character.IsHuman then
|
|
table.insert(updateHumans, character)
|
|
amountHumans = amountHumans + 1
|
|
else
|
|
table.insert(updateMonsters, character)
|
|
amountMonsters = amountMonsters + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
-- we spread the characters out over the duration of an update so that the load isnt done all at once
|
|
for key, value in pairs(updateHumans) do
|
|
-- make sure theyre still alive and human
|
|
if value ~= nil and not value.Removed and value.IsHuman and not value.IsDead then
|
|
Timer.Wait(function()
|
|
if value ~= nil and not value.Removed and value.IsHuman and not value.IsDead then
|
|
NT.UpdateHuman(value)
|
|
end
|
|
end, ((key + 1) / amountHumans) * NT.Deltatime * 1000)
|
|
end
|
|
end
|
|
|
|
-- we spread the monsters out over the duration of an update so that the load isnt done all at once
|
|
for key, value in pairs(updateMonsters) do
|
|
-- make sure theyre still alive
|
|
if value ~= nil and not value.Removed and not value.IsDead then
|
|
Timer.Wait(function()
|
|
if value ~= nil and not value.Removed and not value.IsDead then
|
|
NT.UpdateMonster(value)
|
|
end
|
|
end, ((key + 1) / amountMonsters) * NT.Deltatime * 1000)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- some local functions to avoid code duplicates
|
|
local function limbLockedInitial(c, limbtype, key)
|
|
return not NTC.GetSymptomFalse(c.character, key)
|
|
and (
|
|
NTC.GetSymptom(c.character, key)
|
|
or c.afflictions.t_paralysis.strength > 0
|
|
or NT.LimbIsAmputated(c.character, limbtype)
|
|
or (HF.GetAfflictionStrengthLimb(c.character, limbtype, "bandaged", 0) <= 0 and HF.GetAfflictionStrengthLimb(
|
|
c.character,
|
|
limbtype,
|
|
"dirtybandage",
|
|
0
|
|
) <= 0 and NT.LimbIsDislocated(c.character, limbtype))
|
|
or (
|
|
HF.GetAfflictionStrengthLimb(c.character, limbtype, "gypsumcast", 0) <= 0
|
|
and NT.LimbIsBroken(c.character, limbtype)
|
|
)
|
|
)
|
|
end
|
|
NT.organDamageCalc = function(c, damagevalue, nomaxstrength)
|
|
if damagevalue >= 99 and (nomaxstrength == nil or nomaxstrength == false) then
|
|
return 100
|
|
end
|
|
return damagevalue - 0.01 * c.stats.healingrate * c.stats.specificOrganDamageHealMultiplier * NT.Deltatime
|
|
end
|
|
local function kidneyDamageCalc(c, damagevalue)
|
|
if damagevalue >= 99 then
|
|
return 100
|
|
end
|
|
if damagevalue >= 50 then
|
|
if damagevalue <= 51 then
|
|
return damagevalue
|
|
end
|
|
return damagevalue - 0.01 * c.stats.healingrate * c.stats.specificOrganDamageHealMultiplier * NT.Deltatime
|
|
end
|
|
return damagevalue - 0.02 * c.stats.healingrate * c.stats.specificOrganDamageHealMultiplier * NT.Deltatime
|
|
end
|
|
local function isExtremity(type)
|
|
return type ~= LimbType.Torso and type ~= LimbType.Head
|
|
end
|
|
local limbtypes = {
|
|
LimbType.Torso,
|
|
LimbType.Head,
|
|
LimbType.LeftArm,
|
|
LimbType.RightArm,
|
|
LimbType.LeftLeg,
|
|
LimbType.RightLeg,
|
|
}
|
|
|
|
-- define all the afflictions and their update functions
|
|
NT.Afflictions = {
|
|
-- Arterial cuts
|
|
t_arterialcut = {},
|
|
-- Fractures and amputations
|
|
t_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.Torso))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
h_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.Head))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
la_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.LeftArm))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
ra_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.RightArm))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
ll_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.LeftLeg))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
rl_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.RightLeg))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
n_fracture = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ 2
|
|
* HF.BoolToNum(not HF.HasAfflictionLimb(c.character, "gypsumcast", LimbType.Head))
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
tla_amputation = {},
|
|
tra_amputation = {},
|
|
tll_amputation = {},
|
|
trl_amputation = {},
|
|
sla_amputation = {},
|
|
sra_amputation = {},
|
|
sll_amputation = {},
|
|
srl_amputation = {},
|
|
t_paralysis = {},
|
|
alv = {}, -- artificial ventilation
|
|
needlec = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = c.afflictions[i].strength - 0.15 * NT.Deltatime
|
|
end,
|
|
},
|
|
forceprone = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and not c.character.IsClimbing
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or (c.stats.lockleftleg and c.stats.lockrightleg and not c.stats.wheelchaired)
|
|
or c.character.IsKeyDown(InputType.Attack)
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
onwheelchair = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (NTC.GetSymptom(c.character, i) or c.stats.wheelchaired),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
|
|
-- Organ conditions
|
|
cardiacarrest = {
|
|
update = function(c, i)
|
|
-- triggers
|
|
if
|
|
not NTC.GetSymptomFalse(c.character, "triggersym_cardiacarrest")
|
|
and (
|
|
NTC.GetSymptom(c.character, "triggersym_cardiacarrest")
|
|
or c.stats.stasis
|
|
or c.afflictions.heartremoved.strength > 0
|
|
or c.afflictions.brainremoved.strength > 0
|
|
or (c.afflictions.heartdamage.strength > 99 and HF.Chance(0.3))
|
|
or (c.afflictions.traumaticshock.strength > 40 and HF.Chance(0.1))
|
|
or (c.afflictions.coma.strength > 40 and HF.Chance(0.03))
|
|
or (c.afflictions.hypoxemia.strength > 80 and HF.Chance(0.01))
|
|
or (
|
|
c.afflictions.fibrillation.strength > 20
|
|
and HF.Chance((c.afflictions.fibrillation.strength / 100) ^ 4)
|
|
)
|
|
)
|
|
then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 10
|
|
end
|
|
end,
|
|
},
|
|
respiratoryarrest = {
|
|
update = function(c, i)
|
|
-- passive regen
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
- (0.05 + HF.BoolToNum(c.afflictions.sym_unconsciousness.strength < 0.1, 0.45)) * NT.Deltatime
|
|
-- triggers
|
|
if
|
|
not NTC.GetSymptomFalse(c.character, "triggersym_respiratoryarrest")
|
|
and (
|
|
NTC.GetSymptom(c.character, "triggersym_respiratoryarrest")
|
|
or c.stats.stasis
|
|
or c.afflictions.lungremoved.strength > 0
|
|
or c.afflictions.brainremoved.strength > 0
|
|
or c.afflictions.opiateoverdose.strength > 60
|
|
or (c.afflictions.lungdamage.strength > 99 and HF.Chance(0.8))
|
|
or (c.afflictions.traumaticshock.strength > 30 and HF.Chance(0.2))
|
|
or (
|
|
(c.afflictions.cerebralhypoxia.strength > 100 or c.afflictions.hypoxemia.strength > 70)
|
|
and HF.Chance(0.05)
|
|
)
|
|
)
|
|
then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 10
|
|
end
|
|
end,
|
|
},
|
|
pneumothorax = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = HF.Clamp(
|
|
c.afflictions[i].strength
|
|
+ NT.Deltatime
|
|
* (
|
|
0.5 -- gain 0.5/s
|
|
- HF.BoolToNum(c.afflictions[i].strength > 15)
|
|
* HF.Clamp(c.afflictions.needlec.strength, 0, 1)
|
|
), -- ...except if needled and >15%, then lose 0.5/s
|
|
0,
|
|
100
|
|
)
|
|
end
|
|
end,
|
|
},
|
|
tamponade = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + NT.Deltatime * 0.5
|
|
end
|
|
|
|
if c.afflictions.heartremoved.strength > 0 then
|
|
c.afflictions[i].strength = 0
|
|
end
|
|
end,
|
|
},
|
|
heartattack = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = c.afflictions[i].strength - NT.Deltatime
|
|
|
|
-- triggers
|
|
if
|
|
not NTC.GetSymptomFalse(c.character, "triggersym_heartattack")
|
|
and not c.stats.stasis
|
|
and c.afflictions.afstreptokinase.strength <= 0
|
|
and c.afflictions.heartremoved.strength <= 0
|
|
and (
|
|
NTC.GetSymptom(c.character, "triggersym_heartattack")
|
|
or (
|
|
c.afflictions.bloodpressure.strength > 150
|
|
and HF.Chance(
|
|
NTConfig.Get("NT_heartattackChance", 1)
|
|
* ((c.afflictions.bloodpressure.strength - 150) / 50 * 0.02)
|
|
)
|
|
)
|
|
)
|
|
then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 50
|
|
end
|
|
|
|
if c.afflictions.heartremoved.strength > 0 then
|
|
c.afflictions[i].strength = 0
|
|
end
|
|
end,
|
|
},
|
|
-- Organs removed
|
|
brainremoved = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = 1
|
|
+ HF.BoolToNum(HF.HasAfflictionLimb(c.character, "retractedskin", LimbType.Head, 99), 99)
|
|
end
|
|
end,
|
|
},
|
|
heartremoved = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = 1
|
|
+ HF.BoolToNum(HF.HasAfflictionLimb(c.character, "retractedskin", LimbType.Torso, 99), 99)
|
|
end
|
|
end,
|
|
},
|
|
lungremoved = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = 1
|
|
+ HF.BoolToNum(HF.HasAfflictionLimb(c.character, "retractedskin", LimbType.Torso, 99), 99)
|
|
end
|
|
end,
|
|
},
|
|
liverremoved = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = 1
|
|
+ HF.BoolToNum(HF.HasAfflictionLimb(c.character, "retractedskin", LimbType.Torso, 99), 99)
|
|
end
|
|
end,
|
|
},
|
|
kidneyremoved = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions[i].strength = 1
|
|
+ HF.BoolToNum(HF.HasAfflictionLimb(c.character, "retractedskin", LimbType.Torso, 99), 99)
|
|
end
|
|
end,
|
|
},
|
|
-- Organ damage
|
|
cerebralhypoxia = {
|
|
max = 200,
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
-- calculate new neurotrauma
|
|
local gain = (
|
|
-0.1 * c.stats.healingrate -- passive regen
|
|
+ c.afflictions.hypoxemia.strength / 100 -- from hypoxemia
|
|
+ HF.Clamp(c.afflictions.stroke.strength, 0, 20) * 0.1 -- from stroke
|
|
+ c.afflictions.sepsis.strength / 100 * 0.4 -- from sepsis
|
|
+ c.afflictions.liverdamage.strength / 800 -- from liverdamage
|
|
+ c.afflictions.kidneydamage.strength / 1000 -- from kidneydamage
|
|
+ c.afflictions.traumaticshock.strength / 100 -- from traumatic shock
|
|
) * NT.Deltatime
|
|
|
|
if gain > 0 then
|
|
gain = gain
|
|
* NTC.GetMultiplier(c.character, "neurotraumagain") -- NTC multiplier
|
|
* NTConfig.Get("NT_neurotraumaGain", 1) -- Config multiplier
|
|
* (1 - HF.Clamp(c.afflictions.afmannitol.strength, 0, 0.5)) -- half if mannitol
|
|
end
|
|
|
|
c.afflictions[i].strength = c.afflictions[i].strength + gain
|
|
|
|
c.afflictions[i].strength = HF.Clamp(c.afflictions[i].strength, 0, 200)
|
|
end,
|
|
},
|
|
heartdamage = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = NT.organDamageCalc(
|
|
c,
|
|
c.afflictions[i].strength
|
|
+ NTC.GetMultiplier(c.character, "heartdamagegain")
|
|
* (c.stats.neworgandamage + HF.Clamp(c.afflictions.heartattack.strength, 0, 0.5) * NT.Deltatime)
|
|
)
|
|
end,
|
|
},
|
|
lungdamage = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = NT.organDamageCalc(
|
|
c,
|
|
c.afflictions.lungdamage.strength
|
|
+ NTC.GetMultiplier(c.character, "lungdamagegain")
|
|
* (c.stats.neworgandamage + math.max(c.afflictions.radiationsickness.strength - 25, 0) / 800 * NT.Deltatime)
|
|
)
|
|
end,
|
|
},
|
|
liverdamage = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = NT.organDamageCalc(
|
|
c,
|
|
c.afflictions.liverdamage.strength
|
|
+ NTC.GetMultiplier(c.character, "liverdamagegain") * c.stats.neworgandamage
|
|
)
|
|
if
|
|
c.afflictions[i].strength >= 99
|
|
and not NTC.GetSymptom(c.character, "sym_hematemesis")
|
|
and HF.Chance(0.05)
|
|
then
|
|
-- if liver failed: 5% chance for 6-20 seconds of blood vomiting and internal bleeding
|
|
NTC.SetSymptomTrue(c.character, "sym_hematemesis", math.random(3, 10))
|
|
c.afflictions.internalbleeding.strength = c.afflictions.internalbleeding.strength + 2
|
|
end
|
|
end,
|
|
},
|
|
kidneydamage = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = kidneyDamageCalc(
|
|
c,
|
|
c.afflictions.kidneydamage.strength
|
|
+ NTC.GetMultiplier(c.character, "kidneydamagegain")
|
|
* (c.stats.neworgandamage + HF.Clamp((c.afflictions.bloodpressure.strength - 120) / 160, 0, 0.5) * NT.Deltatime * 0.5)
|
|
)
|
|
if
|
|
c.afflictions[i].strength >= 60
|
|
and not NTC.GetSymptom(c.character, "sym_vomiting")
|
|
and HF.Chance((c.afflictions[i].strength - 60) / 40 * 0.07)
|
|
then
|
|
-- at 60% kidney damage: 0% chance for vomiting
|
|
-- at 100% kidney damage: 7% chance for vomiting
|
|
NTC.SetSymptomTrue(c.character, "sym_vomiting", math.random(3, 10))
|
|
end
|
|
end,
|
|
},
|
|
bonedamage = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = NT.organDamageCalc(
|
|
c,
|
|
c.afflictions.bonedamage.strength
|
|
+ NTC.GetMultiplier(c.character, "bonedamagegain")
|
|
* (c.afflictions.sepsis.strength / 500 + c.afflictions.hypoxemia.strength / 1000 + math.max(
|
|
c.afflictions.radiationsickness.strength - 25,
|
|
0
|
|
) / 600)
|
|
* NT.Deltatime
|
|
)
|
|
if c.afflictions[i].strength < 90 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength - (c.stats.bonegrowthCount * 0.3) * NT.Deltatime
|
|
elseif c.stats.bonegrowthCount >= 6 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength - 2 * NT.Deltatime
|
|
end
|
|
if c.afflictions.kidneydamage.strength > 70 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ (c.afflictions.kidneydamage.strength - 70) / 30 * 0.15 * NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
organdamage = {
|
|
max = 200,
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength =
|
|
NT.organDamageCalc(c, c.afflictions.organdamage.strength + c.stats.neworgandamage, true)
|
|
end,
|
|
},
|
|
-- Blood
|
|
sepsis = {
|
|
update = function(c, i)
|
|
if c.afflictions.afantibiotics.strength > 0.1 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength - NT.Deltatime
|
|
end
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
if c.afflictions[i].strength > 0.1 then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 0.05 * NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
immunity = {
|
|
default = -1,
|
|
min = 5,
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength == -1 then
|
|
-- no immunity affliction!
|
|
-- assume it has been wiped by "revive" or "heal all", attempt to assign new blood type
|
|
if NT.HasBloodtype(c.character) then
|
|
-- if blood type is already here, set immunity to the minimum
|
|
c.afflictions[i].strength = 5
|
|
else
|
|
-- no bloodtype -> all afflictions have been cleared, set immunity to maximum
|
|
c.afflictions[i].strength = 100
|
|
NT.TryRandomizeBlood(c.character)
|
|
end
|
|
end
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
|
|
-- immunity regeneration
|
|
c.afflictions[i].strength =
|
|
HF.Clamp(c.afflictions[i].strength + (0.5 + c.afflictions[i].strength / 100) * NT.Deltatime, 5, 100)
|
|
end,
|
|
},
|
|
bloodloss = { max = 200 },
|
|
bloodpressure = {
|
|
min = 5,
|
|
max = 200,
|
|
default = 100,
|
|
update = function(c, i)
|
|
-- fix people not having a blood pressure
|
|
if not HF.HasAffliction(c.character, i) then
|
|
HF.SetAffliction(c.character, i, 100)
|
|
end
|
|
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
-- calculate new blood pressure
|
|
local desiredbloodpressure = (
|
|
c.stats.bloodamount
|
|
- c.afflictions.tamponade.strength / 2 -- -50 if full tamponade
|
|
- HF.Clamp(c.afflictions.afpressuredrug.strength * 5, 0, 45) -- -45 if blood pressure medication
|
|
- HF.Clamp(c.afflictions.anesthesia.strength, 0, 15) -- -15 if propofol (fuck propofol)
|
|
+ HF.Clamp(c.afflictions.afadrenaline.strength * 10, 0, 30) -- +30 if adrenaline
|
|
+ HF.Clamp(c.afflictions.afsaline.strength * 5, 0, 30) -- +30 if saline
|
|
+ HF.Clamp(c.afflictions.afringerssolution.strength * 5, 0, 30) -- +30 if ringers
|
|
)
|
|
* (1 + 0.5 * ((c.afflictions.liverdamage.strength / 100) ^ 2)) -- elevated if full liver damage
|
|
* (1 + 0.5 * ((c.afflictions.kidneydamage.strength / 100) ^ 2)) -- elevated if full kidney damage
|
|
* (1 + c.afflictions.alcoholwithdrawal.strength / 200) -- elevated if alcohol withdrawal
|
|
* HF.Clamp((100 - c.afflictions.traumaticshock.strength * 2) / 100, 0, 1) -- none if half or more traumatic shock
|
|
* ((100 - c.afflictions.fibrillation.strength) / 100) -- lowered if fibrillated
|
|
* (1 - math.min(1, c.afflictions.cardiacarrest.strength)) -- none if cardiac arrest
|
|
* NTC.GetMultiplier(c.character, "bloodpressure")
|
|
|
|
local bloodpressurelerp = 0.2 * NTC.GetMultiplier(c.character, "bloodpressurerate")
|
|
-- adjust three times slower to heightened blood pressure
|
|
if desiredbloodpressure > c.afflictions.bloodpressure.strength then
|
|
bloodpressurelerp = bloodpressurelerp / 3
|
|
end
|
|
c.afflictions.bloodpressure.strength = HF.Clamp(
|
|
HF.Round(HF.Lerp(c.afflictions.bloodpressure.strength, desiredbloodpressure, bloodpressurelerp), 2),
|
|
5,
|
|
200
|
|
)
|
|
end,
|
|
},
|
|
hypoxemia = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
-- completely cancel out hypoxemia regeneration if penumothorax is full
|
|
c.stats.availableoxygen = math.min(c.stats.availableoxygen, 100 - c.afflictions.pneumothorax.strength / 2)
|
|
|
|
local hypoxemiagain = NTC.GetMultiplier(c.character, "hypoxemiagain")
|
|
local regularHypoxemiaChange = (-c.stats.availableoxygen + 50) / 8
|
|
if regularHypoxemiaChange > 0 then
|
|
-- not enough oxygen, increase hypoxemia
|
|
regularHypoxemiaChange = regularHypoxemiaChange * hypoxemiagain
|
|
else
|
|
-- enough oxygen, decrease hypoxemia
|
|
regularHypoxemiaChange =
|
|
HF.Lerp(regularHypoxemiaChange * 2, 0, HF.Clamp((50 - c.stats.bloodamount) / 50, 0, 1))
|
|
end
|
|
c.afflictions.hypoxemia.strength = HF.Clamp(
|
|
c.afflictions.hypoxemia.strength
|
|
+ (
|
|
-math.min(0, (c.afflictions.bloodpressure.strength - 70) / 7) * hypoxemiagain -- loss because of low blood pressure (+10 at 0 bp)
|
|
- math.min(0, (c.stats.bloodamount - 60) / 4) * hypoxemiagain -- loss because of low blood amount (+15 at 0 blood)
|
|
+ regularHypoxemiaChange -- change because of oxygen in lungs (+6.25 <> -12.5)
|
|
)
|
|
* NT.Deltatime,
|
|
0,
|
|
100
|
|
)
|
|
end,
|
|
},
|
|
hemotransfusionshock = {},
|
|
-- Other
|
|
oxygenlow = {
|
|
max = 200,
|
|
update = function(c, i)
|
|
-- respiratory arrest? -> oxygen in lungs rapidly decreases
|
|
if c.afflictions.respiratoryarrest.strength > 0 then
|
|
c.afflictions.oxygenlow.strength = c.afflictions.oxygenlow.strength + 15 * NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
radiationsickness = {
|
|
max = 200,
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = c.afflictions[i].strength - NT.Deltatime * 0.02
|
|
end,
|
|
},
|
|
stasis = {},
|
|
table = {},
|
|
internalbleeding = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = c.afflictions[i].strength - NT.Deltatime * 0.02 * c.stats.clottingrate
|
|
if c.afflictions[i].strength > 0 then
|
|
c.afflictions.bloodloss.strength = c.afflictions.bloodloss.strength
|
|
+ c.afflictions[i].strength * (1 / 40) * NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
acidosis = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
+ HF.BoolToNum(c.afflictions.hypoventilation.strength > 0 and c.afflictions.alv.strength <= 0.1) * 0.09 * NT.Deltatime
|
|
+ HF.BoolToNum(
|
|
(
|
|
c.afflictions.cardiacarrest.strength
|
|
+ c.afflictions.respiratoryarrest.strength * HF.BoolToNum(c.afflictions.alv.strength <= 0.1)
|
|
) > 0
|
|
) * 0.18 * NT.Deltatime
|
|
+ math.max(0, c.afflictions.kidneydamage.strength - 80) / 20 * 0.1 * NT.Deltatime
|
|
- NT.Deltatime * 0.03
|
|
end,
|
|
},
|
|
alkalosis = {
|
|
update = function(c, i)
|
|
if not c.stats.stasis then
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
- NT.Deltatime * 0.03
|
|
+ HF.Clamp(c.afflictions.hyperventilation.strength, 0, 1) * 0.09 * NT.Deltatime
|
|
+ HF.Clamp(c.afflictions.sym_vomiting.strength, 0, 1) * 0.1 * NT.Deltatime
|
|
+ HF.Clamp(HF.GetAfflictionStrength(c.character, "nausea", 0), 0, 1) * 0.1 * NT.Deltatime
|
|
end
|
|
if c.afflictions.acidosis.strength > 1 and c.afflictions.alkalosis.strength > 1 then
|
|
local min = math.min(c.afflictions.acidosis.strength, c.afflictions.alkalosis.strength)
|
|
c.afflictions.acidosis.strength = c.afflictions.acidosis.strength - min
|
|
c.afflictions.alkalosis.strength = c.afflictions.alkalosis.strength - min
|
|
end
|
|
end,
|
|
},
|
|
seizure = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = c.afflictions[i].strength - NT.Deltatime
|
|
|
|
-- triggers
|
|
if
|
|
not NTC.GetSymptomFalse(c.character, "triggersym_seizure")
|
|
and not c.stats.stasis
|
|
and (
|
|
NTC.GetSymptom(c.character, "triggersym_seizure")
|
|
or (c.afflictions.stroke.strength > 1 and HF.Chance(0.05))
|
|
or (c.afflictions.acidosis.strength > 60 and HF.Chance(0.05))
|
|
or (c.afflictions.alkalosis.strength > 60 and HF.Chance(0.05))
|
|
or HF.Chance(HF.Minimum(c.afflictions.radiationsickness.strength, 50, 0) / 200 * 0.1)
|
|
or (c.afflictions.alcoholwithdrawal.strength > 50 and HF.Chance(
|
|
c.afflictions.alcoholwithdrawal.strength / 1000
|
|
))
|
|
or (
|
|
c.afflictions.opiateoverdose.strength > 60
|
|
and HF.Chance(c.afflictions.opiateoverdose.strength / 500)
|
|
)
|
|
)
|
|
then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 10
|
|
end
|
|
|
|
-- check for spasm trigger
|
|
if c.afflictions[i].strength > 0.1 then
|
|
for type in limbtypes do
|
|
if HF.Chance(0.5) then
|
|
HF.AddAfflictionLimb(c.character, "spasm", type, 10)
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
},
|
|
stroke = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = c.afflictions[i].strength - (1 / 20) * c.stats.clottingrate * NT.Deltatime
|
|
|
|
-- triggers
|
|
if
|
|
not NTC.GetSymptomFalse(c.character, "triggersym_stroke")
|
|
and not c.stats.stasis
|
|
and (
|
|
NTC.GetSymptom(c.character, "triggersym_stroke")
|
|
or (
|
|
c.afflictions.bloodpressure.strength > 150
|
|
and HF.Chance(
|
|
NTConfig.Get("NT_strokeChance", 1)
|
|
* (
|
|
(c.afflictions.bloodpressure.strength - 150) / 50 * 0.02
|
|
+ HF.Clamp(c.afflictions.afstreptokinase.strength, 0, 1) * 0.05
|
|
)
|
|
)
|
|
)
|
|
)
|
|
then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 5
|
|
end
|
|
end,
|
|
},
|
|
coma = {
|
|
update = function(c, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
c.afflictions[i].strength = c.afflictions[i].strength - NT.Deltatime / 5
|
|
|
|
-- triggers
|
|
if
|
|
not NTC.GetSymptomFalse(c.character, "triggersym_coma")
|
|
and not c.stats.stasis
|
|
and (
|
|
NTC.GetSymptom(c.character, "triggersym_coma")
|
|
or (c.afflictions.cardiacarrest.strength > 1 and HF.Chance(0.05))
|
|
or (c.afflictions.stroke.strength > 1 and HF.Chance(0.05))
|
|
or (
|
|
c.afflictions.acidosis.strength > 60
|
|
and HF.Chance(0.05 + (c.afflictions.acidosis.strength - 60) / 100)
|
|
)
|
|
)
|
|
then
|
|
c.afflictions[i].strength = c.afflictions[i].strength + 14
|
|
end
|
|
end,
|
|
},
|
|
stun = {
|
|
max = 30,
|
|
update = function(c, i)
|
|
if c.afflictions.t_paralysis.strength > 0 or c.afflictions.anesthesia.strength > 15 then
|
|
c.afflictions[i].strength = math.max(5, c.afflictions[i].strength)
|
|
end
|
|
end,
|
|
apply = function(c, i, newval)
|
|
-- using the character stun property to apply instead of an affliction so that the networking doesnt shit itself (hopefully)
|
|
c.character.Stun = newval
|
|
end,
|
|
},
|
|
slowdown = {
|
|
lateupdate = function(c, i)
|
|
c.afflictions[i].strength = HF.Clamp(100 * (1 - c.stats.speedmultiplier), 0, 100)
|
|
end,
|
|
},
|
|
givein = {
|
|
max = 1,
|
|
update = function(c, i)
|
|
c.afflictions[i].strength =
|
|
HF.BoolToNum(c.afflictions.t_paralysis.strength > 0 or c.afflictions.sym_unconsciousness.strength > 0)
|
|
end,
|
|
},
|
|
lockedhands = {
|
|
update = function(c, i)
|
|
-- arm locking
|
|
local leftlockitem = c.character.Inventory.FindItemByIdentifier("armlock2", false)
|
|
local rightlockitem = c.character.Inventory.FindItemByIdentifier("armlock1", false)
|
|
|
|
-- handcuffs
|
|
local handcuffs = c.character.Inventory.FindItemByIdentifier("handcuffs", false)
|
|
local handcuffed = handcuffs ~= nil and c.character.Inventory.FindIndex(handcuffs) <= 6
|
|
if handcuffed then
|
|
-- drop non-handcuff items
|
|
local leftHandItem = HF.GetItemInLeftHand(c.character)
|
|
local rightHandItem = HF.GetItemInRightHand(c.character)
|
|
if leftHandItem ~= nil and leftHandItem ~= handcuffs and leftlockitem == nil then
|
|
leftHandItem.Drop(c.character)
|
|
end
|
|
if rightHandItem ~= nil and rightHandItem ~= handcuffs and rightlockitem == nil then
|
|
rightHandItem.Drop(c.character)
|
|
end
|
|
end
|
|
|
|
local leftarmlocked = leftlockitem ~= nil and not handcuffed
|
|
local rightarmlocked = rightlockitem ~= nil and not handcuffed
|
|
|
|
if leftarmlocked and not c.stats.lockleftarm then
|
|
HF.RemoveItem(leftlockitem)
|
|
end
|
|
if rightarmlocked and not c.stats.lockrightarm then
|
|
HF.RemoveItem(rightlockitem)
|
|
end
|
|
|
|
if not leftarmlocked and c.stats.lockleftarm then
|
|
HF.ForceArmLock(c.character, "armlock2")
|
|
end
|
|
if not rightarmlocked and c.stats.lockrightarm then
|
|
HF.ForceArmLock(c.character, "armlock1")
|
|
end
|
|
|
|
c.afflictions[i].strength = HF.BoolToNum((c.stats.lockleftarm and c.stats.lockrightarm) or handcuffed, 100)
|
|
end,
|
|
},
|
|
traumaticshock = {
|
|
update = function(c, i)
|
|
local shouldReduce = (c.stats.sedated and c.afflictions.table.strength > 0)
|
|
or c.afflictions.anesthesia.strength > 15
|
|
c.afflictions[i].strength = c.afflictions[i].strength
|
|
- (0.5 + HF.BoolToNum(shouldReduce, 1.5)) * NT.Deltatime
|
|
|
|
if c.afflictions[i].strength > 5 and c.afflictions.sym_unconsciousness.strength < 0.1 then
|
|
HF.AddAffliction(c.character, "shockpain", 10 * NT.Deltatime)
|
|
HF.AddAffliction(c.character, "psychosis", c.afflictions[i].strength / 100 * NT.Deltatime)
|
|
end
|
|
end,
|
|
},
|
|
alcoholwithdrawal = {},
|
|
opiatewithdrawal = {},
|
|
chemwithdrawal = {},
|
|
opiateoverdose = {},
|
|
-- Drugs
|
|
analgesia = { max = 200 },
|
|
|
|
-- propofol (i hate it)
|
|
anesthesia = {
|
|
update = function(c, i)
|
|
if c.afflictions[i].strength <= 0 then
|
|
return
|
|
end
|
|
-- cause bloody vomiting or hallucinations sometimes (real sideeffects of propofol!)
|
|
if HF.Chance(0.06) then
|
|
local case = math.random()
|
|
local casecount = 7
|
|
|
|
if case < 1 / casecount then
|
|
NTC.SetSymptomTrue(c.character, "sym_hematemesis", 5 + math.random() * 10)
|
|
elseif case < 2 / casecount then
|
|
NTC.SetSymptomTrue(c.character, "sym_blurredvision", 5 + math.random() * 10)
|
|
elseif case < 3 / casecount then
|
|
NTC.SetSymptomTrue(c.character, "sym_confusion", 5 + math.random() * 10)
|
|
elseif case < 4 / casecount then
|
|
NTC.SetSymptomTrue(c.character, "sym_fever", 5 + math.random() * 10)
|
|
elseif case < 5 / casecount then
|
|
NTC.SetSymptomTrue(c.character, "triggersym_seizure", 1 + math.random() * 2)
|
|
elseif case < 6 / casecount then
|
|
NT.Fibrillate(c.character, 5 + math.random() * 30)
|
|
else
|
|
HF.AddAffliction(c.character, "psychosis", 10)
|
|
end
|
|
end
|
|
end,
|
|
},
|
|
drunk = { max = 200 },
|
|
afadrenaline = {},
|
|
afantibiotics = {},
|
|
afthiamine = {},
|
|
afsaline = {},
|
|
afringerssolution = {},
|
|
afstreptokinase = {},
|
|
afmannitol = {},
|
|
afpressuredrug = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = c.afflictions[i].strength - 0.25 * NT.Deltatime
|
|
end,
|
|
},
|
|
concussion = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = c.afflictions[i].strength - 0.01 * NT.Deltatime
|
|
if c.afflictions[i].strength <= 0 then
|
|
return
|
|
end
|
|
|
|
-- cause headaches, blurred vision, nausea, confusion
|
|
if HF.Chance(HF.Clamp(c.afflictions[i].strength / 10 * 0.08, 0.02, 0.08)) then
|
|
local case = math.random()
|
|
|
|
if case < 0.25 then
|
|
NTC.SetSymptomTrue(c.character, "sym_nausea", 5 + math.random() * 10)
|
|
elseif case < 0.5 then
|
|
NTC.SetSymptomTrue(c.character, "sym_blurredvision", 5 + math.random() * 9)
|
|
elseif case < 0.75 then
|
|
NTC.SetSymptomTrue(c.character, "sym_headache", 6 + math.random() * 8)
|
|
else
|
|
NTC.SetSymptomTrue(c.character, "sym_confusion", 6 + math.random() * 8)
|
|
end
|
|
end
|
|
end,
|
|
},
|
|
|
|
-- /// Symptoms ///
|
|
--==============================================================================
|
|
sym_unconsciousness = {
|
|
update = function(c, i)
|
|
local isUnconscious = not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.stats.stasis
|
|
or c.afflictions.brainremoved.strength > 0
|
|
or (not HF.HasAffliction(c.character, "implacable", 0.05) and (c.character.Vitality <= 0 or c.afflictions.hypoxemia.strength > 80))
|
|
or c.afflictions.cerebralhypoxia.strength > 100
|
|
or c.afflictions.coma.strength > 15
|
|
or c.afflictions.t_arterialcut.strength > 0
|
|
or c.afflictions.seizure.strength > 0.1
|
|
or c.afflictions.opiateoverdose.strength > 60
|
|
)
|
|
c.afflictions[i].strength = HF.BoolToNum(isUnconscious, 2)
|
|
if isUnconscious then
|
|
c.afflictions.stun.strength = math.max(7, c.afflictions.stun.strength)
|
|
end
|
|
end,
|
|
},
|
|
tachycardia = {
|
|
update = function(c, i)
|
|
-- harmless symptom (doesnt lead to fibrillation)
|
|
local hasSymHarmless = not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.cardiacarrest.strength < 1
|
|
and c.afflictions.heartremoved.strength < 1
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.sepsis.strength > 20
|
|
or c.stats.bloodamount < 60
|
|
or c.afflictions.acidosis.strength > 20
|
|
or c.afflictions.pneumothorax.strength > 30
|
|
or c.afflictions.afadrenaline.strength > 1
|
|
or c.afflictions.alcoholwithdrawal.strength > 75
|
|
)
|
|
c.afflictions[i].strength = math.max(c.afflictions[i].strength, HF.BoolToNum(hasSymHarmless, 2))
|
|
|
|
-- harmful symptom (leads to fibrillation and cardiac arrest)
|
|
local fibrillationSpeed = -0.1
|
|
+ HF.Clamp(c.afflictions.t_arterialcut.strength, 0, 2) -- aortic rupture (very fast)
|
|
+ HF.Clamp(c.afflictions.acidosis.strength / 200, 0, 0.5) -- acidosis (slow)
|
|
+ HF.Clamp(
|
|
0.9
|
|
- ( -- low blood pressure (varies)
|
|
(
|
|
c.afflictions.bloodpressure.strength
|
|
+ HF.Clamp(c.afflictions.afpressuredrug.strength * 5, 0, 20) -- less fibrillation from low blood pressure if blood pressure reducing medicines active
|
|
) / 90
|
|
),
|
|
0,
|
|
1
|
|
)
|
|
* 2
|
|
+ HF.Clamp(c.afflictions.hypoxemia.strength / 100, 0, 1) * 1.5 -- hypoxemia (varies)
|
|
+ HF.Clamp((c.afflictions.traumaticshock.strength - 5) / 40, 0, 3) -- traumatic shock (fast)
|
|
- HF.Clamp(c.afflictions.afadrenaline.strength, 0, 0.9) -- faster defib if adrenaline
|
|
|
|
if fibrillationSpeed > 0 and c.afflictions.afadrenaline.strength > 0 then
|
|
-- if adrenaline, fibrillate half as fast
|
|
fibrillationSpeed = fibrillationSpeed / 2
|
|
end
|
|
|
|
if c.afflictions.cardiacarrest.strength > 0 or c.afflictions.heartremoved.strength > 0 then
|
|
fibrillationSpeed = -1000
|
|
c.afflictions.fibrillation.strength = 0
|
|
c.afflictions[i].strength = 0
|
|
end
|
|
|
|
-- fibrillation multiplier
|
|
if fibrillationSpeed > 0 then
|
|
fibrillationSpeed = fibrillationSpeed
|
|
* NTC.GetMultiplier(c.character, "fibrillation")
|
|
* NTConfig.Get("NT_fibrillationSpeed", 1)
|
|
end
|
|
|
|
if c.afflictions.fibrillation.strength <= 0 then -- havent reached fibrillation yet
|
|
c.afflictions[i].strength = c.afflictions[i].strength + fibrillationSpeed * 5 * NT.Deltatime
|
|
-- we reached max tachycardia, switch over to fibrillation
|
|
if c.afflictions[i].strength >= 100 then
|
|
c.afflictions.fibrillation.strength = 5
|
|
c.afflictions[i].strength = 0
|
|
end
|
|
else -- have reached fibrillation
|
|
c.afflictions[i].strength = 0 -- set tachycardia to 0
|
|
c.afflictions.fibrillation.strength = c.afflictions.fibrillation.strength
|
|
+ fibrillationSpeed * NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
fibrillation = {
|
|
update = function(c, i)
|
|
-- see above for vfib accumulation logic
|
|
if
|
|
NTC.GetSymptomFalse(c.character, i)
|
|
or c.afflictions.cardiacarrest.strength >= 1
|
|
or c.afflictions.heartremoved.strength >= 1
|
|
then
|
|
c.afflictions[i].strength = 0
|
|
end
|
|
end,
|
|
},
|
|
hyperventilation = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.respiratoryarrest.strength < 1
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.hypoxemia.strength > 10
|
|
or c.afflictions.bloodpressure.strength < 80
|
|
or c.afflictions.afadrenaline.strength > 1
|
|
or c.afflictions.pneumothorax.strength > 15
|
|
or c.afflictions.sepsis.strength > 15
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
hypoventilation = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.respiratoryarrest.strength < 1
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.analgesia.strength > 20
|
|
or c.afflictions.anesthesia.strength > 40
|
|
or c.afflictions.opiateoverdose.strength > 30
|
|
),
|
|
2
|
|
)
|
|
if c.afflictions.hyperventilation.strength > 0 and c.afflictions.hypoventilation.strength > 0 then
|
|
c.afflictions.hyperventilation.strength = 0
|
|
c.afflictions.hypoventilation.strength = 0
|
|
end
|
|
end,
|
|
},
|
|
dyspnea = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.respiratoryarrest.strength <= 0
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.heartattack.strength > 1
|
|
or c.afflictions.heartdamage.strength > 80
|
|
or c.afflictions.hypoxemia.strength > 20
|
|
or c.afflictions.lungdamage.strength > 45
|
|
or c.afflictions.pneumothorax.strength > 40
|
|
or c.afflictions.tamponade.strength > 10
|
|
or (
|
|
c.afflictions.hemotransfusionshock.strength > 0
|
|
and c.afflictions.hemotransfusionshock.strength < 70
|
|
)
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_cough = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and c.afflictions.lungremoved.strength <= 0
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.lungdamage.strength > 50
|
|
or c.afflictions.heartdamage.strength > 50
|
|
or c.afflictions.tamponade.strength > 20
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_paleskin = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.stats.bloodamount < 60
|
|
or c.afflictions.bloodpressure.strength < 50
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_lightheadedness = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.bloodpressure.strength < 60),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_blurredvision = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.bloodpressure.strength < 55),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_confusion = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.acidosis.strength > 15
|
|
or c.afflictions.bloodpressure.strength < 30
|
|
or c.afflictions.hypoxemia.strength > 50
|
|
or c.afflictions.sepsis.strength > 40
|
|
or c.afflictions.alcoholwithdrawal.strength > 80
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_headache = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and not c.stats.sedated
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.stats.bloodamount < 50
|
|
or c.afflictions.acidosis.strength > 20
|
|
or c.afflictions.stroke.strength > 1
|
|
or c.afflictions.hypoxemia.strength > 40
|
|
or c.afflictions.bloodpressure.strength < 60
|
|
or c.afflictions.alcoholwithdrawal.strength > 50
|
|
or c.afflictions.h_fracture.strength > 0
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_legswelling = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and HF.GetAfflictionStrength(c.character, "rl_cyber", 0) < 0.1
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.liverdamage.strength > 40
|
|
or c.afflictions.kidneydamage.strength > 60
|
|
or c.afflictions.heartdamage.strength > 80
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_weakness = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.tamponade.strength > 30
|
|
or c.stats.bloodamount < 40
|
|
or c.afflictions.acidosis.strength > 35
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_wheezing = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.respiratoryarrest.strength <= 0
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or (
|
|
c.afflictions.hemotransfusionshock.strength > 0
|
|
and c.afflictions.hemotransfusionshock.strength < 90
|
|
)
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_vomiting = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.drunk.strength > 100
|
|
or (c.afflictions.hemotransfusionshock.strength > 0 and c.afflictions.hemotransfusionshock.strength < 40)
|
|
or c.afflictions.alcoholwithdrawal.strength > 60
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_nausea = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.kidneydamage.strength > 60
|
|
or c.afflictions.radiationsickness.strength > 80
|
|
or (c.afflictions.hemotransfusionshock.strength > 0 and c.afflictions.hemotransfusionshock.strength < 90)
|
|
or c.stats.withdrawal > 40
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_hematemesis = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.internalbleeding.strength > 50),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
fever = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.sepsis.strength > 5
|
|
or c.afflictions.alcoholwithdrawal.strength > 90
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_abdomdiscomfort = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.liverdamage.strength > 65),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_bloating = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.liverdamage.strength > 50),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_jaundice = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.liverdamage.strength > 80),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_sweating = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or c.afflictions.heartattack.strength > 1
|
|
or c.stats.withdrawal > 30
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_palpitations = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.cardiacarrest.strength <= 0
|
|
and (NTC.GetSymptom(c.character, i) or c.afflictions.alkalosis.strength > 20),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
sym_craving = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (NTC.GetSymptom(c.character, i) or c.stats.withdrawal > 20),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
pain_abdominal = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and not c.stats.sedated
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or (c.afflictions.hemotransfusionshock.strength > 0 and c.afflictions.hemotransfusionshock.strength < 80)
|
|
or c.afflictions.t_arterialcut.strength > 0
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
pain_chest = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(
|
|
not NTC.GetSymptomFalse(c.character, i)
|
|
and c.afflictions.sym_unconsciousness.strength <= 0
|
|
and (
|
|
NTC.GetSymptom(c.character, i)
|
|
or (c.afflictions.hemotransfusionshock.strength > 0 and c.afflictions.hemotransfusionshock.strength < 60)
|
|
or c.afflictions.t_fracture.strength > 0
|
|
or c.afflictions.t_arterialcut.strength > 0
|
|
),
|
|
2
|
|
)
|
|
end,
|
|
},
|
|
luabotomy = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = 0
|
|
end,
|
|
},
|
|
modconflict = {
|
|
update = function(c, i)
|
|
c.afflictions[i].strength = HF.BoolToNum(NT.modconflict, 1)
|
|
end,
|
|
},
|
|
-- Heelge: this really does the same thing as vanilla burns, why does it even exists?
|
|
--sym_scorched = {
|
|
-- update = function(c, i)
|
|
-- c.afflictions[i].strength = HF.BoolToNum(c.stats.burndamage > 500, 10)
|
|
-- end,
|
|
--},
|
|
}
|
|
-- define all the limb specific afflictions and their update functions
|
|
NT.LimbAfflictions = {
|
|
bandaged = {
|
|
update = function(c, limbaff, i)
|
|
-- turning a bandage into a dirty bandage
|
|
local wounddamage = limbaff.burn.strength
|
|
+ limbaff.lacerations.strength
|
|
+ limbaff.gunshotwound.strength
|
|
+ limbaff.bitewounds.strength
|
|
+ limbaff.explosiondamage.strength
|
|
|
|
local bandageDirtifySpeed = 0.1 + HF.Clamp(wounddamage / 100, 0, 0.4) + limbaff.bleeding.strength / 20
|
|
|
|
if limbaff[i].strength > 0 then
|
|
limbaff[i].strength = limbaff[i].strength - bandageDirtifySpeed * NT.Deltatime
|
|
if limbaff[i].strength <= 0 then
|
|
-- transition to dirty bandage
|
|
limbaff.dirtybandage.strength = math.max(limbaff.dirtybandage.strength, 1)
|
|
limbaff[i].strength = 0
|
|
end
|
|
end
|
|
if limbaff.dirtybandage.strength > 0 then
|
|
limbaff.dirtybandage.strength = limbaff.dirtybandage.strength + bandageDirtifySpeed * NT.Deltatime
|
|
end
|
|
|
|
-- bandage slowdown
|
|
if limbaff[i].strength > 0 or limbaff.dirtybandage.strength > 0 then
|
|
c.stats.speedmultiplier = c.stats.speedmultiplier * 0.9
|
|
end
|
|
end,
|
|
},
|
|
dirtybandage = {}, -- for bandage dirtifaction logic see above
|
|
iced = {
|
|
update = function(c, limbaff, i, type)
|
|
-- over time skin temperature goes up again
|
|
if limbaff[i].strength > 0 then
|
|
limbaff[i].strength = limbaff[i].strength - 1.7 * NT.Deltatime
|
|
end
|
|
-- iced slowdown
|
|
if limbaff[i].strength > 0 then
|
|
c.stats.speedmultiplier = c.stats.speedmultiplier * 0.95
|
|
end
|
|
end,
|
|
},
|
|
gypsumcast = {
|
|
update = function(c, limbaff, i, type)
|
|
-- gypsum slowdown and fracture healing
|
|
if limbaff[i].strength > 0 then
|
|
c.stats.speedmultiplier = c.stats.speedmultiplier * 0.8
|
|
NT.BreakLimb(c.character, type, -(100 / 300) * NT.Deltatime)
|
|
end
|
|
end,
|
|
},
|
|
ointmented = {},
|
|
bonegrowth = {
|
|
update = function(c, limbaff, i, type)
|
|
if limbaff[i].strength <= 0 then
|
|
-- check for bone death fracture triggers
|
|
if c.afflictions.bonedamage.strength > 90 and HF.Chance(0.01) then
|
|
NT.BreakLimb(c.character, type)
|
|
end
|
|
end
|
|
end,
|
|
},
|
|
arteriesclamp = {},
|
|
-- damage
|
|
bleeding = {
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength > 0 and math.abs(c.stats.clottingrate - 1) > 0.05 then
|
|
limbaff[i].strength = limbaff[i].strength - (c.stats.clottingrate - 1) * 0.1 * NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
burn = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength < 50 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
- (c.afflictions.immunity.prev / 3000 + HF.Clamp(limbaff.bandaged.strength, 0, 1) * 0.1)
|
|
* c.stats.healingrate
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
acidburn = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
-- convert acid burns to regular burns
|
|
if limbaff[i].strength > 0 then
|
|
limbaff.burn.strength = limbaff.burn.strength + limbaff[i].strength
|
|
limbaff[i].strength = 0
|
|
end
|
|
end,
|
|
},
|
|
lacerations = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength < 50 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
- (c.afflictions.immunity.prev / 3000 + HF.Clamp(limbaff.bandaged.strength, 0, 1) * 0.1)
|
|
* c.stats.healingrate
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
gunshotwound = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength < 50 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
- (c.afflictions.immunity.prev / 3000 + HF.Clamp(limbaff.bandaged.strength, 0, 1) * 0.1)
|
|
* c.stats.healingrate
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
bitewounds = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength < 100 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
- (c.afflictions.immunity.prev / 3000 + HF.Clamp(limbaff.bandaged.strength, 0, 1) * 0.1)
|
|
* c.stats.healingrate
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
explosiondamage = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength < 50 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
- (c.afflictions.immunity.prev / 3000 + HF.Clamp(limbaff.bandaged.strength, 0, 1) * 0.1)
|
|
* c.stats.healingrate
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
blunttrauma = {
|
|
max = 200,
|
|
update = function(c, limbaff, i)
|
|
if limbaff[i].strength < 100 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
- (
|
|
c.afflictions.immunity.prev / 8000
|
|
+ HF.Clamp(limbaff.bandaged.strength, 0, 1) * 0.1
|
|
+ HF.Clamp(limbaff.iced.strength, 0, 1) * 0.3
|
|
)
|
|
* c.stats.healingrate
|
|
* NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
internaldamage = {
|
|
max = 200,
|
|
update = function(c, limbaff, i, type)
|
|
limbaff[i].strength = limbaff[i].strength
|
|
+ (
|
|
-HF.BoolToNum(limbaff[i].strength < 50, 0.05 * c.stats.healingrate)
|
|
+ HF.BoolToNum(
|
|
not c.stats.sedated
|
|
and limbaff.gypsumcast.strength <= 0
|
|
and (
|
|
(
|
|
NT.LimbIsBroken(c.character, type)
|
|
and (
|
|
HF.LimbIsExtremity(type)
|
|
or (limbaff.bandaged.strength <= 0 and limbaff.dirtybandage.strength <= 0)
|
|
)
|
|
)
|
|
or (
|
|
NT.LimbIsDislocated(c.character, type)
|
|
and limbaff.bandaged.strength <= 0
|
|
and limbaff.dirtybandage.strength <= 0
|
|
)
|
|
),
|
|
0.1
|
|
)
|
|
)
|
|
* NT.Deltatime
|
|
end,
|
|
},
|
|
-- other
|
|
infectedwound = {
|
|
update = function(c, limbaff, i)
|
|
if c.stats.stasis then
|
|
return
|
|
end
|
|
local infectindex = (
|
|
-c.afflictions.immunity.prev / 200
|
|
- HF.Clamp(limbaff.bandaged.strength, 0, 1) * 1.5
|
|
- limbaff.ointmented.strength * 3
|
|
+ limbaff.burn.strength / 20
|
|
+ limbaff.lacerations.strength / 40
|
|
+ limbaff.bitewounds.strength / 30
|
|
+ limbaff.gunshotwound.strength / 40
|
|
+ limbaff.explosiondamage.strength / 40
|
|
) * NT.Deltatime
|
|
|
|
local wounddamage = limbaff.burn.strength
|
|
+ limbaff.lacerations.strength
|
|
+ limbaff.gunshotwound.strength
|
|
+ limbaff.bitewounds.strength
|
|
+ limbaff.explosiondamage.strength
|
|
|
|
-- open wounds and a dirty bandage? :grimacing:
|
|
if limbaff.dirtybandage.strength > 10 and wounddamage > 5 then
|
|
infectindex = infectindex + (wounddamage / 40 + limbaff.dirtybandage.strength / 20) * NT.Deltatime
|
|
end
|
|
|
|
if infectindex > 0 then
|
|
infectindex = infectindex * NTConfig.Get("NT_infectionRate", 1)
|
|
end
|
|
|
|
limbaff[i].strength = limbaff[i].strength + infectindex / 5
|
|
c.afflictions.immunity.strength = c.afflictions.immunity.strength - HF.Clamp(infectindex / 3, 0, 10)
|
|
end,
|
|
},
|
|
foreignbody = {
|
|
update = function(c, limbaff, i, type)
|
|
if limbaff[i].strength < 15 then
|
|
limbaff[i].strength = limbaff[i].strength - 0.05 * c.stats.healingrate * NT.Deltatime
|
|
end
|
|
|
|
-- check for arterial cut triggers and foreign body sepsis
|
|
local foreignbodycutchance = ((HF.Minimum(limbaff[i].strength, 20) / 100) ^ 6) * 0.5
|
|
if limbaff.bleeding.strength > 80 or HF.Chance(foreignbodycutchance) then
|
|
NT.ArteryCutLimb(c.character, type)
|
|
end
|
|
|
|
-- sepsis
|
|
local sepsischance = HF.Minimum(limbaff.gangrene.strength, 15, 0) / 400
|
|
+ HF.Minimum(limbaff.infectedwound.strength, 50) / 1000
|
|
+ foreignbodycutchance
|
|
if HF.Chance(sepsischance) then
|
|
c.afflictions.sepsis.strength = c.afflictions.sepsis.strength + NT.Deltatime
|
|
end
|
|
end,
|
|
},
|
|
gangrene = {
|
|
update = function(c, limbaff, i, type)
|
|
-- see foreignbody for sepsis chance
|
|
if isExtremity(type) then
|
|
-- surgical amputation prevents all gangrene on that stump
|
|
if NT.LimbIsSurgicallyAmputated(c.character, type) then
|
|
limbaff[i].strength = 0
|
|
return
|
|
end
|
|
|
|
if limbaff[i].strength < 15 and limbaff[i].strength > 0 then
|
|
limbaff[i].strength = limbaff[i].strength - 0.01 * c.stats.healingrate * NT.Deltatime
|
|
end
|
|
if c.afflictions.sepsis.strength > 5 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
+ HF.BoolToNum(HF.Chance(0.04), 0.5 + c.afflictions.sepsis.strength / 150)
|
|
* NTConfig.Get("NT_gangrenespeed", 1)
|
|
* NT.Deltatime
|
|
end
|
|
if limbaff.arteriesclamp.strength > 0 then
|
|
limbaff[i].strength = limbaff[i].strength
|
|
+ HF.BoolToNum(HF.Chance(0.1), 1) * 0.5 * NTConfig.Get("NT_gangrenespeed", 1) * NT.Deltatime
|
|
end
|
|
end
|
|
end,
|
|
},
|
|
pain_extremity = {
|
|
max = 10,
|
|
update = function(c, limbaff, i, type)
|
|
if c.afflictions.sym_unconsciousness.strength > 0 then
|
|
limbaff[i].strength = 0
|
|
return
|
|
end
|
|
limbaff[i].strength = limbaff[i].strength
|
|
+ (
|
|
-0.5
|
|
+ HF.BoolToNum(
|
|
type ~= LimbType.Torso
|
|
and limbaff.gypsumcast.strength <= 0
|
|
and (
|
|
(
|
|
NT.LimbIsBroken(c.character, type)
|
|
and (
|
|
HF.LimbIsExtremity(type)
|
|
or (limbaff.bandaged.strength <= 0 and limbaff.dirtybandage.strength <= 0)
|
|
)
|
|
)
|
|
or (
|
|
NT.LimbIsDislocated(c.character, type)
|
|
and limbaff.bandaged.strength <= 0
|
|
and limbaff.dirtybandage.strength <= 0
|
|
)
|
|
),
|
|
2
|
|
)
|
|
- HF.BoolToNum(c.stats.sedated, 100)
|
|
)
|
|
* NT.Deltatime
|
|
end,
|
|
},
|
|
-- limb symptoms
|
|
inflammation = {
|
|
update = function(c, limbaff, i)
|
|
limbaff[i].strength = limbaff[i].strength
|
|
+ (
|
|
-0.1
|
|
+ HF.BoolToNum(limbaff.infectedwound.strength > 10 or limbaff.foreignbody.strength > 15, 0.15)
|
|
)
|
|
* NT.Deltatime
|
|
end,
|
|
},
|
|
burn_deg1 = {
|
|
update = function(c, limbaff, i)
|
|
if limbaff.burn.strength < 1 or limbaff.burn.strength > 20 then
|
|
limbaff[i].strength = 0
|
|
else
|
|
limbaff[i].strength = limbaff.burn.strength * 5
|
|
end
|
|
end,
|
|
},
|
|
burn_deg2 = {
|
|
update = function(c, limbaff, i)
|
|
if limbaff.burn.strength <= 20 or limbaff.burn.strength > 50 then
|
|
limbaff[i].strength = 0
|
|
else
|
|
limbaff[i].strength = math.max(5, (limbaff.burn.strength - 20) / 30 * 100)
|
|
end
|
|
end,
|
|
},
|
|
burn_deg3 = {
|
|
update = function(c, limbaff, i)
|
|
if limbaff.burn.strength <= 50 then
|
|
limbaff[i].strength = 0
|
|
else
|
|
limbaff[i].strength = HF.Clamp((limbaff.burn.strength - 50) / 50 * 100, 5, 100)
|
|
end
|
|
end,
|
|
},
|
|
}
|
|
-- define the stats and multipliers
|
|
NT.CharStats = {
|
|
healingrate = {
|
|
getter = function(c)
|
|
return NTC.GetMultiplier(c.character, "healingrate")
|
|
end,
|
|
},
|
|
specificOrganDamageHealMultiplier = {
|
|
getter = function(c)
|
|
return NTC.GetMultiplier(c.character, "anyspecificorgandamage")
|
|
+ HF.Clamp(c.afflictions.afthiamine.strength, 0, 1) * 4
|
|
end,
|
|
},
|
|
neworgandamage = {
|
|
getter = function(c)
|
|
return (
|
|
c.afflictions.sepsis.strength / 300
|
|
+ c.afflictions.hypoxemia.strength / 400
|
|
+ math.max(c.afflictions.radiationsickness.strength - 25, 0) / 400
|
|
)
|
|
* NTC.GetMultiplier(c.character, "anyorgandamage")
|
|
* NTConfig.Get("NT_organDamageGain", 1)
|
|
* NT.Deltatime
|
|
end,
|
|
},
|
|
clottingrate = {
|
|
getter = function(c)
|
|
return HF.Clamp(1 - c.afflictions.liverdamage.strength / 100, 0, 1)
|
|
* c.stats.healingrate
|
|
* HF.Clamp(1 - c.afflictions.afstreptokinase.strength, 0, 1)
|
|
* NTC.GetMultiplier(c.character, "clottingrate")
|
|
end,
|
|
},
|
|
|
|
bloodamount = {
|
|
getter = function(c)
|
|
return HF.Clamp(100 - c.afflictions.bloodloss.strength, 0, 100)
|
|
end,
|
|
},
|
|
stasis = {
|
|
getter = function(c)
|
|
return c.afflictions.stasis.strength > 0
|
|
end,
|
|
},
|
|
sedated = {
|
|
getter = function(c)
|
|
return c.afflictions.analgesia.strength > 0
|
|
or c.afflictions.anesthesia.strength > 10
|
|
or c.afflictions.drunk.strength > 30
|
|
or c.stats.stasis
|
|
end,
|
|
},
|
|
withdrawal = {
|
|
getter = function(c)
|
|
return math.max(
|
|
c.afflictions.opiatewithdrawal.strength,
|
|
c.afflictions.chemwithdrawal.strength,
|
|
c.afflictions.alcoholwithdrawal.strength
|
|
)
|
|
end,
|
|
},
|
|
availableoxygen = {
|
|
getter = function(c)
|
|
local res = HF.Clamp(c.character.Oxygen, 0, 100)
|
|
-- heart isnt pumping blood? no new oxygen is getting into the bloodstream, no matter how oxygen rich the air in the lungs
|
|
res = res * (1 - c.afflictions.fibrillation.strength / 100)
|
|
-- and uuuh, maybe also dont let people without lungs use the oxygen where their lungs should be
|
|
if c.afflictions.cardiacarrest.strength > 1 or c.afflictions.lungremoved.strength > 0.1 then
|
|
res = 0
|
|
end
|
|
return res
|
|
end,
|
|
},
|
|
speedmultiplier = {
|
|
getter = function(c)
|
|
local res = 1
|
|
if c.afflictions.t_paralysis.strength > 0 then
|
|
res = -9001
|
|
end
|
|
|
|
if c.afflictions.sym_vomiting.strength > 0 then
|
|
res = res * 0.8
|
|
end
|
|
if c.afflictions.sym_nausea.strength > 0 then
|
|
res = res * 0.9
|
|
end
|
|
if c.afflictions.anesthesia.strength > 0 then
|
|
res = res * 0.5
|
|
end
|
|
if c.afflictions.opiateoverdose.strength > 50 then
|
|
res = res * 0.5
|
|
end
|
|
|
|
if c.stats.withdrawal > 80 then
|
|
res = res * 0.5
|
|
elseif c.stats.withdrawal > 40 then
|
|
res = res * 0.7
|
|
elseif c.stats.withdrawal > 20 then
|
|
res = res * 0.9
|
|
end
|
|
|
|
if c.afflictions.drunk.strength > 80 then
|
|
res = res * 0.5
|
|
elseif c.afflictions.drunk.strength > 40 then
|
|
res = res * 0.7
|
|
elseif c.afflictions.drunk.strength > 20 then
|
|
res = res * 0.8
|
|
end
|
|
|
|
res = res + c.afflictions.afadrenaline.strength / 100 -- mitigate slowing effects if doped up on epinephrine
|
|
|
|
res = res * NTC.GetSpeedMultiplier(c.character)
|
|
|
|
return res
|
|
end,
|
|
},
|
|
|
|
lockleftarm = {
|
|
getter = function(c)
|
|
return limbLockedInitial(c, LimbType.LeftArm, "lockleftarm")
|
|
end,
|
|
},
|
|
lockrightarm = {
|
|
getter = function(c)
|
|
return limbLockedInitial(c, LimbType.RightArm, "lockrightarm")
|
|
end,
|
|
},
|
|
lockleftleg = {
|
|
getter = function(c)
|
|
return limbLockedInitial(c, LimbType.LeftLeg, "lockleftleg")
|
|
end,
|
|
},
|
|
lockrightleg = {
|
|
getter = function(c)
|
|
return limbLockedInitial(c, LimbType.RightLeg, "lockrightleg")
|
|
end,
|
|
},
|
|
|
|
wheelchaired = {
|
|
getter = function(c)
|
|
local outerwearItem = c.character.Inventory.GetItemAt(4)
|
|
local res = outerwearItem ~= nil and outerwearItem.Prefab.Identifier.Value == "wheelchair"
|
|
if res then
|
|
c.stats.lockleftleg = c.stats.lockleftarm
|
|
c.stats.lockrightleg = c.stats.lockrightarm
|
|
end
|
|
-- leg and wheelchair slowdown
|
|
if c.stats.lockleftleg or c.stats.lockrightleg or res then
|
|
c.stats.speedmultiplier = c.stats.speedmultiplier * 0.5
|
|
end
|
|
local isProne = c.stats.lockleftleg and c.stats.lockrightleg
|
|
-- okay climbing ability
|
|
if isProne and c.character.IsClimbing then
|
|
c.stats.speedmultiplier = c.stats.speedmultiplier * 0.5
|
|
end
|
|
-- moving prone with one arm or 95% slowdown when no arms
|
|
if (isProne or res) and c.stats.lockleftarm and c.stats.lockrightarm then
|
|
c.stats.speedmultiplier = 0.05
|
|
elseif isProne and (c.stats.lockleftarm or c.stats.lockrightarm) then
|
|
c.stats.speedmultiplier = c.stats.speedmultiplier * 0.8
|
|
end
|
|
-- if isProne then
|
|
-- c.character.AnimController.RagdollParams.ColliderHeightFromFloor = 4.0
|
|
-- end - Heelge: collider adjustment scrapped for now, lets wait for proper method in Workshop
|
|
return res
|
|
end,
|
|
},
|
|
|
|
bonegrowthCount = {
|
|
getter = function(c)
|
|
local res = 0
|
|
for type in limbtypes do
|
|
if HF.GetAfflictionStrengthLimb(c.character, type, "bonegrowth", 0) > 0 then
|
|
res = res + 1
|
|
end
|
|
end
|
|
return res
|
|
end,
|
|
},
|
|
burndamage = {
|
|
getter = function(c)
|
|
local res = 0
|
|
for type in limbtypes do
|
|
res = res + HF.GetAfflictionStrengthLimb(c.character, type, "burn", 0)
|
|
end
|
|
return res
|
|
end,
|
|
},
|
|
}
|
|
|
|
function NT.UpdateHuman(character)
|
|
-- pre humanupdate hooks
|
|
for key, val in pairs(NTC.PreHumanUpdateHooks) do
|
|
val(character)
|
|
end
|
|
|
|
local charData = { character = character, afflictions = {}, stats = {} }
|
|
|
|
-- fetch all the current affliction data
|
|
for identifier, data in pairs(NT.Afflictions) do
|
|
local strength = HF.GetAfflictionStrength(character, identifier, data.default or 0)
|
|
charData.afflictions[identifier] = { prev = strength, strength = strength }
|
|
end
|
|
-- fetch and calculate all the current stats
|
|
for identifier, data in pairs(NT.CharStats) do
|
|
if data.getter ~= nil then
|
|
charData.stats[identifier] = data.getter(charData)
|
|
else
|
|
charData.stats[identifier] = data.default or 1
|
|
end
|
|
end
|
|
-- update non-limb-specific afflictions
|
|
for identifier, data in pairs(NT.Afflictions) do
|
|
if data.update ~= nil then
|
|
data.update(charData, identifier)
|
|
end
|
|
end
|
|
|
|
-- update and apply limb specific stuff
|
|
local function FetchLimbData(type)
|
|
local keystring = tostring(type) .. "afflictions"
|
|
charData[keystring] = {}
|
|
for identifier, data in pairs(NT.LimbAfflictions) do
|
|
local strength = HF.GetAfflictionStrengthLimb(character, type, identifier, data.default or 0)
|
|
charData[keystring][identifier] = { prev = strength, strength = strength }
|
|
end
|
|
end
|
|
local function UpdateLimb(type)
|
|
local keystring = tostring(type) .. "afflictions"
|
|
for identifier, data in pairs(NT.LimbAfflictions) do
|
|
if data.update ~= nil then
|
|
data.update(charData, charData[keystring], identifier, type)
|
|
end
|
|
end
|
|
end
|
|
local function ApplyLimb(type)
|
|
local keystring = tostring(type) .. "afflictions"
|
|
for identifier, data in pairs(charData[keystring]) do
|
|
local newval = HF.Clamp(
|
|
data.strength,
|
|
NT.LimbAfflictions[identifier].min or 0,
|
|
NT.LimbAfflictions[identifier].max or 100
|
|
)
|
|
if newval ~= data.prev then
|
|
if NT.LimbAfflictions[identifier].apply == nil then
|
|
HF.SetAfflictionLimb(character, identifier, type, newval)
|
|
else
|
|
NT.LimbAfflictions[identifier].apply(charData, identifier, type, newval)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- stasis completely halts activity in limbs
|
|
if not charData.stats.stasis then
|
|
for type in limbtypes do
|
|
FetchLimbData(type)
|
|
end
|
|
for type in limbtypes do
|
|
UpdateLimb(type)
|
|
end
|
|
for type in limbtypes do
|
|
ApplyLimb(type)
|
|
end
|
|
end
|
|
|
|
-- non-limb-specific late update (useful for things that use stats that are altered by limb specifics)
|
|
for identifier, data in pairs(NT.Afflictions) do
|
|
if data.lateupdate ~= nil then
|
|
data.lateupdate(charData, identifier)
|
|
end
|
|
end
|
|
|
|
-- apply non-limb-specific changes
|
|
for identifier, data in pairs(charData.afflictions) do
|
|
local newval =
|
|
HF.Clamp(data.strength, NT.Afflictions[identifier].min or 0, NT.Afflictions[identifier].max or 100)
|
|
if newval ~= data.prev then
|
|
if NT.Afflictions[identifier].apply == nil then
|
|
HF.SetAffliction(character, identifier, newval)
|
|
else
|
|
NT.Afflictions[identifier].apply(charData, identifier, newval)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- compatibility
|
|
NTC.TickCharacter(character)
|
|
-- humanupdate hooks
|
|
for key, val in pairs(NTC.HumanUpdateHooks) do
|
|
val(character)
|
|
end
|
|
|
|
NTC.CharacterSpeedMultipliers[character] = nil
|
|
end
|
|
|
|
function NT.UpdateMonster(character)
|
|
-- trade bloodloss on this creature for organ damage so that creatures can still bleed out
|
|
local bloodloss = HF.GetAfflictionStrength(character, "bloodloss", 0)
|
|
local oxygenlow = HF.GetAfflictionStrength(character, "oxygenlow", 0)
|
|
if bloodloss > 0 then
|
|
HF.AddAffliction(character, "organdamage", bloodloss * 2)
|
|
HF.SetAffliction(character, "bloodloss", 0)
|
|
elseif oxygenlow > 50 then
|
|
HF.AddAffliction(character, "organdamage", (oxygenlow - 50) * 2)
|
|
HF.SetAffliction(character, "oxygenlow", 50)
|
|
end
|
|
end
|
|
|
|
-- gets run every tick, shouldnt be used unless necessary
|
|
|
|
function NT.TickUpdate()
|
|
for key, value in pairs(NT.tickTasks) do
|
|
value.duration = value.duration - 1
|
|
if value.duration <= 0 then
|
|
NT.tickTasks[key] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
NT.tickTasks = {}
|
|
NT.tickTaskID = 0
|
|
function NT.AddTickTask(type, duration, character)
|
|
local newtask = {}
|
|
newtask.type = type
|
|
newtask.duration = duration
|
|
newtask.character = character
|
|
NT.tickTasks[NT.tickTaskID] = newtask
|
|
NT.tickTaskID = NT.tickTaskID + 1
|
|
end
|