Track LocalMods as part of monolith

This commit is contained in:
2026-06-08 18:50:16 +03:00
parent 143f2fed7c
commit 1b214b44c2
1287 changed files with 139255 additions and 1 deletions
+174
View File
@@ -0,0 +1,174 @@
-- Neurotrauma blood types functions
-- Hooks Lua event "characterCreated" to create a randomized blood type for spawned character and sets their immunity to 100
---@diagnostic disable: lowercase-global, undefined-global
NT.BLOODTYPE = { -- blood types and chance in percent
{ "ominus", 7 },
{ "oplus", 37 },
{ "aminus", 6 },
{ "aplus", 36 },
{ "bminus", 2 },
{ "bplus", 8 },
{ "abminus", 1 },
{ "abplus", 3 },
}
NT.setBlood = {}
NT.foundAny = false
-- Insert all blood types in one table for RandomizeBlood()
for index, value in ipairs(NT.BLOODTYPE) do
-- print(index," : ",value[1],", ",value[2],"%")
table.insert(NT.setBlood, index, { value[2], value[1] })
end
-- Applies math.random() blood type.
-- returns the applied bloodtype as an affliction identifier
function NT.RandomizeBlood(character)
rand = math.random(0, 99)
local i = 0
for index, value in ipairs(NT.setBlood) do
i = i + value[1]
if i > rand then
HF.SetAffliction(character, value[2], 100)
return value[2]
end
end
end
Hook.Add("characterCreated", "NT.BloodAndImmunity", function(createdCharacter)
Timer.Wait(function()
if createdCharacter.IsHuman and not createdCharacter.IsDead then
NT.TryRandomizeBlood(createdCharacter)
-- add immunity
local conditional2 = createdCharacter.CharacterHealth.GetAffliction("immunity")
if conditional2 == nil then HF.SetAffliction(createdCharacter, "immunity", 100) end
end
end, 1000)
end)
-- applies a new bloodtype only if the character doesnt already have one
function NT.TryRandomizeBlood(character)
NT.GetBloodtype(character)
end
-- returns the bloodtype of the character as an affliction identifier string
-- generates blood type if none present
function NT.GetBloodtype(character)
for index, affliction in ipairs(NT.BLOODTYPE) do
local conditional = character.CharacterHealth.GetAffliction(affliction[1])
if conditional ~= nil and conditional.Strength > 0 then
return affliction[1] -- TODO: give out abplus (AB+) to enemy team for blood infusions
end
end
return NT.RandomizeBlood(character)
end
function NT.HasBloodtype(character)
for index, affliction in ipairs(NT.BLOODTYPE) do
local conditional = character.CharacterHealth.GetAffliction(affliction[1])
if conditional ~= nil and conditional.Strength > 0 then return true end
end
return false
end
Hook.Add("OnInsertedIntoBloodAnalyzer", "NT.BloodAnalyzer", function(effect, deltaTime, item, targets, position)
-- Hematology Analyzer (bloodanalyzer) can scan inserted blood bags
local owner = item.GetRootInventoryOwner()
if owner == nil then return end
if not LuaUserData.IsTargetType(owner, "Barotrauma.Character") then return end
if not owner.IsPlayer then return end
local character = owner
local contained = item.OwnInventory.GetItemAt(0)
local BaseColor = "127,255,255"
local NameColor = "127,255,255"
local LowColor = "127,255,255"
local HighColor = "127,255,255"
local VitalColor = "127,255,255"
if NTConfig.Get("NTSCAN_enablecoloredscanner", 1) then
BaseColor = table.concat(NTConfig.Get("NTSCAN_basecolor", 1), ",")
NameColor = table.concat(NTConfig.Get("NTSCAN_namecolor", 1), ",")
LowColor = table.concat(NTConfig.Get("NTSCAN_lowcolor", 1), ",")
HighColor = table.concat(NTConfig.Get("NTSCAN_highcolor", 1), ",")
VitalColor = table.concat(NTConfig.Get("NTSCAN_vitalcolor", 1), ",")
end
-- NT adds bloodbag; NT Blood Work or 'Real Sonar Medical Item Recipes Patch for Neurotrauma' add allblood, lets check for either
if contained ~= nil and (contained.HasTag("bloodbag") or contained.HasTag("allblood")) then
HF.GiveItem(character, "ntsfx_syringe")
Timer.Wait(function()
if item == nil or character == nil or item.OwnInventory.GetItemAt(0) ~= contained then return end
local identifier = contained.Prefab.Identifier.Value
local packtype = "o-"
if identifier ~= "antibloodloss2" then packtype = string.sub(identifier, string.len("bloodpack") + 1) end
local bloodTypeDisplay = string.gsub(packtype, "abc", "c")
bloodTypeDisplay = string.gsub(bloodTypeDisplay, "plus", "+")
bloodTypeDisplay = string.gsub(bloodTypeDisplay, "minus", "-")
bloodTypeDisplay = string.upper(bloodTypeDisplay)
local readoutString = "‖color:"
.. BaseColor
.. ""
.. "Bloodpack: "
.. "‖color:end‖"
.. "‖color:"
.. NameColor
.. ""
.. bloodTypeDisplay
.. "‖color:end‖"
-- check if acidosis, alkalosis or sepsis
local tags = HF.SplitString(contained.Tags, ",")
local defects = ""
for tag in tags do
if tag == "sepsis" then
defects = defects .. "‖color:" .. VitalColor .. "" .. "\nSepsis detected" .. "‖color:end‖"
end
if HF.StartsWith(tag, "acid") then
local split = HF.SplitString(tag, ":")
if split[2] ~= nil then
defects = defects
.. "‖color:"
.. HighColor
.. ""
.. "\nAcidosis: "
.. tonumber(split[2])
.. "%"
.. "‖color:end‖"
end
elseif HF.StartsWith(tag, "alkal") then
local split = HF.SplitString(tag, ":")
if split[2] ~= nil then
defects = defects
.. "‖color:"
.. HighColor
.. ""
.. "\nAlkalosis: "
.. tonumber(split[2])
.. "%"
.. "‖color:end‖"
end
end
end
if defects ~= "" then
readoutString = readoutString .. defects
else
readoutString = readoutString
.. "‖color:"
.. LowColor
.. ""
.. "\nNo blood defects"
.. "‖color:end‖"
end
HF.DMClient(HF.CharacterToClient(character), readoutString, Color(127, 255, 255, 255))
end, 1500)
end
end)
@@ -0,0 +1,32 @@
-- Hooks CalculateMovementPenalty method of Barotrauma.Character
-- when painless enough, disable weapon sway / movement hindrance limb penalties
-- !!! Lags the game, though GetAimWobble seems to be ok to patch
-- Disable movement penalties for painless characters
-- Has about 2 ms performance drop on a many character save
--Hook.Patch("Barotrauma.Character", "CalculateMovementPenalty", function(instance, ptable)
-- if HF.HasAffliction(instance, "analgesia", 20) then
-- ptable.PreventExecution = true
-- return 0
-- end
--end, Hook.HookMethodType.Before)
-- Disable aim penalties for painless characters
Hook.Patch("Barotrauma.AnimController", "GetAimWobble", function(instance, ptable)
if HF.HasAffliction(instance.Character, "analgesia", 20) then
ptable.PreventExecution = true
return 0
end
end, Hook.HookMethodType.Before)
-- Patch to cause unconscious from the game rather than stun
-- Lags the game by 6 times (on the same save)
--Hook.Patch("Barotrauma.CharacterHealth", "get_IsUnconscious", function(instance, ptable)
-- local isUnconscious = HF.HasAffliction(instance.Character, "sym_unconsciousness")
-- ptable.PreventExecution = true
-- return instance.Character.IsDead
-- or (
-- (instance.Character.Vitality <= 0.0 or isUnconscious)
-- and not instance.Character.HasAbilityFlag(AbilityFlags.AlwaysStayConscious)
-- )
--end, Hook.HookMethodType.After)
@@ -0,0 +1,108 @@
-- THIS FILE IS NO LONGER IN USE
-- the defunct item in question has been removed from the mod
-- i'm keeping it here for...safekeeping i guess
LuaUserData.RegisterTypeBarotrauma("PurchasedItem")
LuaUserData.RegisterType("System.Xml.Linq.XElement")
local VANILLA_PREFAB_ID = "antibloodloss2"
local DEFUNCT_PREFAB_ID = "bloodpackominus"
-- Removes vanilla bloodpacks from cached stores in case the user installed
-- this mod mid-campaign.
-- NOTE: stores that had their stocks generated before installing this mod
-- won't have any new medical items added.
Hook.HookMethod("Barotrauma.Location", "LoadStores", function(instance, ptable)
if instance.Stores == nil then return end
for storeId, store in pairs(instance.Stores) do
for _, purchasedItem in pairs(store.Stock) do
local itemId = purchasedItem.ItemPrefabIdentifier
if itemId == DEFUNCT_PREFAB_ID then
-- print("Removing defunct bloodpack (qty " .. purchasedItem.Quantity .. ") from " .. tostring(storeId))
store.RemoveStock({ purchasedItem })
end
end
end
end, Hook.HookMethodType.After)
-- Replaces all vanilla bloodpack items with O- blood
local function replaceItems()
local ntBloodPrefab = ItemPrefab.Prefabs[DEFUNCT_PREFAB_ID]
local vanillaBloodPrefab = ItemPrefab.Prefabs[VANILLA_PREFAB_ID]
if ntBloodPrefab == nil then
print("ERROR: couldn't find " .. DEFUNCT_PREFAB_ID)
return
end
for _, item in pairs(Item.ItemList) do
local id = tostring(item.Prefab.Identifier)
if id == DEFUNCT_PREFAB_ID then
-- Don't replace decorative blood packs
if item.NonInteractable then return end
local pos = item.WorldPosition
local inv = item.ParentInventory
local condition = item.ConditionPercentage
local quality = item.Quality
-- print("replacing blood pack (pos=" .. tostring(pos) .. ", inv=" .. tostring(inv) .. ")")
local slotIdx = -1
if inv ~= nil then
slotIdx = inv.FindIndex(item)
if slotIdx < 0 then
print(
"ERROR: couldn't find item ("
.. tostring(item)
.. ", pos "
.. tostring(pos)
.. ") in inventory ("
.. tostring(inv)
.. ")"
)
return
end
end
-- We call `Drop()` first in case the inventory is full because
-- `AddEntityToRemoveQueue` may not remove the item before we
-- insert the new one, causing the inventory to overflow.
item.Drop()
Entity.Spawner.AddEntityToRemoveQueue(item)
Entity.Spawner.AddItemToSpawnQueue(vanillaBloodPrefab, pos, condition, quality, function(newItem)
newItem.Rotation = item.Rotation
-- Stolen items stay stolen
newItem.AllowStealing = item.AllowStealing
newItem.OriginalOutpost = item.OriginalOutpost
if inv ~= nil then
if not inv.TryPutItem(newItem, slotIdx, false, true, nil) then
print(
"ERROR: failed to replace neurotrauma bloodpack ("
.. tostring(item)
.. ", pos "
.. tostring(pos)
.. ", slotIdx "
.. tostring(slotIdx)
.. ", inv "
.. tostring(inv)
.. ") with new item: "
.. tostring(newItem)
)
end
end
end)
end
end
end
Hook.Add("roundStart", "NT.ConvertBloodPacks", function()
replaceItems()
end)
-- Hook.Add("chatMessage", "NT.BloodPackTesting", function(msg, client)
-- if (msg == "convertblood") then
-- replaceItems()
-- end
-- end)
+49
View File
@@ -0,0 +1,49 @@
-- Hooks Lua event "human.CPRSuccess" to prevent fractures from ragdoll jank, and
-- apply NT affliction cpr_buff or cause rib fractures in Hooked Lua event "human.CPRFailed"
-- human.CPRSuccess was changed to character.CPRSuccess? Way above my paygrade - Lukako
Hook.Add("character.CPRSuccess", "NT.CPRSuccess", function(animcontroller)
if
animcontroller == nil
or animcontroller.Character == nil
or animcontroller.Character.SelectedCharacter == nil
then
return
end
local character = animcontroller.Character.SelectedCharacter
if not HF.HasAffliction(character, "luabotomy") then HF.SetAffliction(character, "luabotomy", 1) end
if not HF.HasAffliction(character, "cpr_buff_auto") then HF.AddAffliction(character, "cpr_buff", 2) end
HF.AddAffliction(character, "cpr_fracturebuff", 2) -- prevent fractures during CPR (fuck baro physics)
end)
Hook.Add("character.CPRFailed", "NT.CPRFailed", function(animcontroller)
if
animcontroller == nil
or animcontroller.Character == nil
or animcontroller.Character.SelectedCharacter == nil
then
return
end
local character = animcontroller.Character.SelectedCharacter
if not HF.HasAffliction(character, "luabotomy") then HF.SetAffliction(character, "luabotomy", 1) end
HF.AddAffliction(character, "cpr_fracturebuff", 2) -- prevent fractures during CPR (fuck baro physics)
HF.AddAfflictionLimb(character, "blunttrauma", LimbType.Torso, 0.3)
if
HF.Chance(
NTConfig.Get("NT_fractureChance", 1)
* NTConfig.Get("NT_CPRFractureChance", 1)
* 0.2
/ HF.GetSkillLevel(animcontroller.Character, "medical")
)
then
HF.AddAffliction(character, "t_fracture", 1)
end
end)
+25
View File
@@ -0,0 +1,25 @@
-- Based on config settings, which items ought to be destroyed
local function DynamicRemoveItems()
local blockedItems = HF.DynamicUnavailableItems()
for _, item in pairs(Item.ItemList) do
local id = item.Prefab.Identifier.Value
if blockedItems[id] then item.Remove() end
end
end
-- On level swap, remove any items that shouldn't be there
Hook.Add("roundEnd", "nt_dynamicremoveitems", function()
DynamicRemoveItems()
end)
-- Recreate stores command to make sure newly added items are actually in stores
Game.AddCommand("nt_recreatestores", "Recreate all stores.", function()
if Game.GameSession.Map ~= nil then
for location in Game.GameSession.Map.Locations do
location.CreateStores(true)
end
else
print("nt_recreatestores: Tried to recreate stores in the campaign map, but there is none!")
end
end)
+300
View File
@@ -0,0 +1,300 @@
-- Hooks Lua event "changeFallDamage" to cause more damage and NT afflictions like fractures and artery cuts on extremities depending on severity
local limbtypes = {
LimbType.Torso,
LimbType.Head,
LimbType.LeftArm,
LimbType.RightArm,
LimbType.LeftLeg,
LimbType.RightLeg,
}
local function HasLungs(c)
return not HF.HasAffliction(c, "lungremoved")
end
local function getCalculatedReductionSuit(armor, strength, limbtype)
if armor == nil then return 0 end
local reduction = 0
if armor.HasTag("deepdivinglarge") or armor.HasTag("deepdiving") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "blunttrauma") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
elseif armor.HasTag("clothing") and armor.HasTag("smallitem") and limbtype == LimbType.Torso then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "blunttrauma") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
end
return reduction
end
local function getCalculatedReductionClothes(armor, strength, limbtype)
if armor == nil then return 0 end
local reduction = 0
if armor.HasTag("deepdiving") or armor.HasTag("diving") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "blunttrauma") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
elseif armor.HasTag("clothing") and armor.HasTag("smallitem") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "blunttrauma") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
end
return reduction
end
local function getCalculatedReductionHelmet(armor, strength)
if armor == nil then return 0 end
local reduction = 0
if armor.HasTag("smallitem") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "blunttrauma") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
end
return reduction
end
local function getCalculatedConcussionReduction(armor, strength)
if armor == nil then return 0 end
local reduction = 0
if armor.HasTag("deepdiving") or armor.HasTag("deepdivinglarge") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "concussion") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
elseif armor.HasTag("smallitem") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "concussion") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
end
return reduction
end
Hook.Add("changeFallDamage", "NT.falldamage", function(impactDamage, character, impactPos, velocity)
-- don't run the code if we ignore the code
if not NTConfig.Get("NT_Calculations", true) then return 0 end
-- dont bother with creatures
if not character.IsHuman then return 0 end
-- dont apply fall damage in water
if character.InWater then return 0 end
-- dont apply fall damage when dragged by someone
if character.SelectedBy ~= nil then return 0 end
-- don't apply fall damage if were specifically immune to it
if HF.HasAffliction(character, "cpr_fracturebuff") or HF.HasAffliction(character, "stopcreatureabuse") then
return 0
end
if not HF.HasAffliction(character, "luabotomy") then HF.SetAffliction(character, "luabotomy", 1) end
local velocityMagnitude = HF.Magnitude(velocity)
velocityMagnitude = velocityMagnitude ^ 1.3
-- apply fall damage to all limbs based on fall direction
local mainlimbPos = character.AnimController.MainLimb.WorldPosition
local limbDotResults = {}
local minDotRes = 1000
for limb in character.AnimController.Limbs do
for type in limbtypes do
if limb.type == type then
-- fetch the direction of each limb relative to the torso
local limbPosition = limb.WorldPosition
local posDif = limbPosition - mainlimbPos
posDif.X = posDif.X / 100
posDif.Y = posDif.Y / 100
local posDifMagnitude = HF.Magnitude(posDif)
if posDifMagnitude > 1 then posDif.Normalize() end
local normalizedVelocity = Vector2(velocity.X, velocity.Y)
normalizedVelocity.Normalize()
-- compare those directions to the direction we're moving
-- this will later be used to hurt the limbs facing impact more than the others
local limbDot = Vector2.Dot(posDif, normalizedVelocity)
limbDotResults[type] = limbDot
if minDotRes > limbDot then minDotRes = limbDot end
break
end
end
end
-- shift all weights out of the negatives
-- increase the weight of all limbs if speed is high
-- the effect of this is that, at higher speeds, all limbs take damage instead of mainly the ones facing the impact site
for type, dotResult in pairs(limbDotResults) do
limbDotResults[type] = dotResult - minDotRes + math.max(0, (velocityMagnitude - 30) / 10)
end
-- count weight so we're able to distribute the damage fractionally
local weightsum = 0
for dotResult in limbDotResults do
weightsum = weightsum + dotResult
end
for type, dotResult in pairs(limbDotResults) do
local relativeWeight = dotResult / weightsum
-- lets limit the numbers to the max value of blunttrauma so that resistances make sense
local damageInflictedToThisLimb = math.min(
relativeWeight * math.max(0, velocityMagnitude - 10) ^ 1.5 * NTConfig.Get("NT_falldamage", 1) * 0.5,
NTConfig.Get("NT_falldamageCeiling", 1) * 60
)
NT.CauseFallDamage(character, type, damageInflictedToThisLimb)
end
-- make the normal damage not run
return 0
end)
NT.CauseFallDamage = function(character, limbtype, strength)
local armor1 = character.Inventory.GetItemInLimbSlot(InvSlotType.OuterClothes)
local armor2 = character.Inventory.GetItemInLimbSlot(InvSlotType.InnerClothes)
if limbtype ~= LimbType.Head then
strength = math.max(
strength
- getCalculatedReductionSuit(armor1, strength, limbtype)
- getCalculatedReductionClothes(armor2, strength, limbtype),
0
)
else
armor2 = character.Inventory.GetItemInLimbSlot(InvSlotType.Head)
strength = math.max(
strength
- getCalculatedReductionSuit(armor1, strength, limbtype)
- getCalculatedReductionHelmet(armor2, strength, limbtype),
0
)
end
-- additionally calculate the affliction reduced damage
local prefab = AfflictionPrefab.Prefabs["blunttrauma"]
local resistance = character.CharacterHealth.GetResistance(prefab, limbtype)
if resistance >= 1 then return end
strength = strength * (1 - resistance)
HF.AddAfflictionLimb(character, "blunttrauma", limbtype, strength)
-- return earlier if the strength value is not high enough for damage checks
if strength < 1 then return end
local fractureImmune = false
local injuryChanceMultiplier = NTConfig.Get("NT_falldamageSeriousInjuryChance", 1)
-- torso
if not fractureImmune and strength >= 1 and limbtype == LimbType.Torso then
if
HF.Chance(
(strength - 15)
/ 100
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
* injuryChanceMultiplier
)
then
NT.BreakLimb(character, limbtype)
if
HasLungs(character)
and strength >= 5
and HF.Chance(
strength
/ 70
* NTC.GetMultiplier(character, "pneumothoraxchance")
* NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
end
end
end
-- head
if not fractureImmune and strength >= 1 and limbtype == LimbType.Head then
if strength >= 15 and HF.Chance(math.min(strength / 100, 0.7)) then
HF.AddAfflictionResisted(
character,
"concussion",
math.max(
10
- getCalculatedConcussionReduction(armor1, 10, limbtype)
- getCalculatedConcussionReduction(armor2, 10, limbtype),
0
)
)
end
if
strength >= 15
and HF.Chance(
math.min((strength - 15) / 100, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
* injuryChanceMultiplier
)
then
NT.BreakLimb(character, limbtype)
end
if
strength >= 55
and HF.Chance(
math.min((strength - 15) / 100, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
* injuryChanceMultiplier
)
then
HF.AddAffliction(character, "n_fracture", 5)
end
if strength >= 5 and HF.Chance(0.7) then
HF.AddAffliction(character, "cerebralhypoxia", strength * HF.RandomRange(0.1, 0.4))
end
end
-- extremities
if not fractureImmune and strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
HF.Chance(
(strength - 15)
/ 100
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
* injuryChanceMultiplier
)
then
NT.BreakLimb(character, limbtype)
if HF.Chance((strength - 2) / 60) then
-- this is here to simulate open fractures
NT.ArteryCutLimb(character, limbtype)
end
end
if
HF.Chance(
HF.Clamp((strength - 5) / 120, 0, 0.5)
* NTC.GetMultiplier(character, "dislocationchance")
* NTConfig.Get("NT_dislocationChance", 1)
* injuryChanceMultiplier
) and not NT.LimbIsAmputated(character, limbtype)
then
NT.DislocateLimb(character, limbtype)
end
end
end
+98
View File
@@ -0,0 +1,98 @@
LuaUserData.MakeMethodAccessible(Descriptors["Barotrauma.HumanAIController"], "SpeakAboutIssues")
-- hopefully this stops bots from doing any rescuing at all.
-- and also hopefully my assumption that this very specific thing
-- about bots is what is causing them to eat frames is correct.
if NTConfig.Get("NT_disableBotAlgorithms", true) then
Hook.Patch("Barotrauma.AIObjectiveRescueAll", "IsValidTarget", {
"Barotrauma.Character",
"Barotrauma.Character",
"out System.Boolean",
}, function(instance, ptable)
-- TODO: some bot behavior
-- make it hostile act if:
-- surgery without corresponding ailments
-- treatment without ailments
-- basic self treatments:
-- find items to treat each other for blood loss or bleeding or suturable damage or fractures and dislocations
-- ^ would possibly need items to have proper suitable treatments too, and yk bots dont spawn with enough meds...
ptable.PreventExecution = true
return false
end, Hook.HookMethodType.Before)
end
local afflictions = {
"n_fracture", -- urgent perceivable afflictions
"h_arterialcut",
"ll_arterialcut",
"rl_arterialcut",
"ra_arterialcut",
"la_arterialcut",
"sym_hematemesis", -- urgent causes
"sym_paleskin",
"sym_confusion",
"sym_lightheadedness",
"pain_abdominal",
"inflammation",
"gangrene",
"fever",
"sym_headache",
"sym_blurredvision",
"t_fracture", -- not urgent afflictions
"h_fracture",
"ra_fracture",
"la_fracture",
"rl_fracture",
"ll_fracture",
"dislocation1",
"dislocation2",
"dislocation3",
"dislocation4",
"pain_chest", -- not urgent causes
"sym_weakness",
"sym_sweating",
"dyspnea",
"sym_bloating",
"sym_legswelling",
"sym_craving",
"sym_palpitations",
}
NT.SymsForNPC = { ntaffs = afflictions }
-- How to add own symptoms example:
--local goobertable = { "goober", "gooberer" }
--table.insert(NT.SymsForNPC, goobertable)
-- allows npcs to talk about their neuro afflictions
Hook.Patch("Barotrauma.HumanAIController", "SpeakAboutIssues", function(instance)
local character = instance.Character
if not HF.HasAffliction(character, "luabotomy", 1) then return end
local message = ""
local chatType = ChatMessageType.Default
if ChatMessage.CanUseRadio(character) then chatType = ChatMessageType.Radio end
for identifier in NT.SymsForNPC.ntaffs do
if HF.HasAffliction(character, identifier, 1) then
message = TextManager.Get("npcdialogsym." .. identifier)
character.Speak(message, chatType, math.random(0, 5), Identifier(identifier .. "DialogSym"), 600.0)
break
end
end
for table in NT.SymsForNPC do
for identifier in table do
if HF.HasAffliction(character, identifier, 1) then
message = TextManager.Get("npcdialogsym." .. identifier)
character.Speak(message, chatType, math.random(0, 5), Identifier(identifier .. "DialogSym"), 600.0)
break
end
end
end
end, Hook.HookMethodType.After)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+90
View File
@@ -0,0 +1,90 @@
-- Spawns items inside medstartercrate
-- Hooks XML Lua event "NT.medstartercrate.spawn" to create medstartercrate items and put them inside it
Hook.Add(
"NT.medstartercrate.spawn",
"NT.medstartercrate.spawn",
function(effect, deltaTime, item, targets, worldPosition)
Timer.Wait(function()
if item == nil then return end
-- check if the item already got populated before
-- got broken somehow and is no longer needed, handled with oneshot="true" for the StatusEffect inside the medstartercrate item that calls this hook on spawn
-- local populated = item.HasTag("used")
-- if populated then return end
-- add used tag
-- local tags = HF.SplitString(item.Tags,",")
-- table.insert(tags,"used")
-- local tagstring = ""
-- for index, value in ipairs(tags) do
-- tagstring = tagstring..value
-- if index < #tags then tagstring=tagstring.."," end
-- end
-- item.Tags = tagstring
-- populate with goodies!!
if item.Scale == 0.5 then return end
item.Scale = 0.5
HF.SpawnItemPlusFunction("medtoolbox", function(params)
HF.SpawnItemPlusFunction("defibrillator", nil, nil, params.item.OwnInventory, 0)
HF.SpawnItemPlusFunction("autocpr", nil, nil, params.item.OwnInventory, 1)
for i = 1, 2, 1 do
HF.SpawnItemPlusFunction("tourniquet", nil, nil, params.item.OwnInventory, 2)
end
for i = 1, 2, 1 do
HF.SpawnItemPlusFunction("ringerssolution", nil, nil, params.item.OwnInventory, 3)
end
HF.SpawnItemPlusFunction("surgicaldrill", nil, nil, params.item.OwnInventory, 4)
HF.SpawnItemPlusFunction("surgerysaw", nil, nil, params.item.OwnInventory, 5)
end, nil, item.OwnInventory, 0)
HF.SpawnItemPlusFunction("medtoolbox", function(params)
HF.SpawnItemPlusFunction("antibleeding1", nil, nil, params.item.OwnInventory, 0)
HF.SpawnItemPlusFunction("gypsum", nil, nil, params.item.OwnInventory, 1)
HF.SpawnItemPlusFunction("opium", nil, nil, params.item.OwnInventory, 2)
HF.SpawnItemPlusFunction("antibiotics", nil, nil, params.item.OwnInventory, 3)
HF.SpawnItemPlusFunction("ointment", nil, nil, params.item.OwnInventory, 4)
end, nil, item.OwnInventory, 1)
HF.SpawnItemPlusFunction("surgerytoolbox", function(params)
HF.SpawnItemPlusFunction("advscalpel", nil, nil, params.item.OwnInventory, 0)
HF.SpawnItemPlusFunction("advhemostat", nil, nil, params.item.OwnInventory, 1)
HF.SpawnItemPlusFunction("advretractors", nil, nil, params.item.OwnInventory, 2)
for i = 1, 16, 1 do
HF.SpawnItemPlusFunction("suture", nil, nil, params.item.OwnInventory, 3)
end
HF.SpawnItemPlusFunction("tweezers", nil, nil, params.item.OwnInventory, 4)
HF.SpawnItemPlusFunction("traumashears", nil, nil, params.item.OwnInventory, 5)
HF.SpawnItemPlusFunction("drainage", nil, nil, params.item.OwnInventory, 6)
HF.SpawnItemPlusFunction("needle", nil, nil, params.item.OwnInventory, 7)
end, nil, item.OwnInventory, 3)
HF.SpawnItemPlusFunction("bloodanalyzer", nil, nil, item.OwnInventory, 6)
HF.SpawnItemPlusFunction("healthscanner", function(params)
local prefab = ItemPrefab.GetItemPrefab("batterycell")
Entity.Spawner.AddItemToSpawnQueue(prefab, params["item"].WorldPosition, nil, nil, function(batteryItem)
params["item"].OwnInventory.TryPutItem(batteryItem)
end)
end, nil, item.OwnInventory, 7)
end, 35)
end
)
Hook.Add("character.giveJobItems", "NT.giveHealthScannersBatteries", function(character)
Timer.Wait(function()
for item in character.Inventory.AllItems do
local thisIdentifier = item.Prefab.Identifier.Value
if thisIdentifier == "healthscanner" then
if item.OwnInventory ~= nil and item.OwnInventory.GetItemAt(0) == nil then
local prefab = ItemPrefab.GetItemPrefab("batterycell")
Entity.Spawner.AddItemToSpawnQueue(prefab, character.WorldPosition, nil, nil, function(batteryItem)
item.OwnInventory.TryPutItem(batteryItem, character)
end)
end
end
end
end, 1000)
end)
+34
View File
@@ -0,0 +1,34 @@
-- Modders, please use ModDir:Neurotrauma when taking dependencies, and
-- name your patches with the word "neurotrauma" (letter case doesnt matter)
-- sets NT.modconflict to true if incompatible mod detected
-- this applies meta affliction "modconflict" every round
-- prints out the warning and incompatible mod on server startup
-- Hooks Lua event "roundStart" to do the above each round
NT.modconflict = false
function NT.CheckModConflicts()
NT.modconflict = false
if NTConfig.Get("NT_ignoreModConflicts", false) then return end
local itemsToCheck = { "antidama2", "opdeco_hospitalbed" }
for prefab in ItemPrefab.Prefabs do
if HF.TableContains(itemsToCheck, prefab.Identifier.Value) then
local mod = prefab.ConfigElement.ContentPackage.Name
if not string.find(string.lower(mod), "neurotrauma") then
NT.modconflict = true
print("Found Neurotrauma incompatibility with mod: ", mod)
print("WARNING! mod conflict detected! Neurotrauma may not function correctly and requires a patch!")
return
end
end
end
end
Timer.Wait(function()
NT.CheckModConflicts()
end, 1000)
Hook.Add("roundStart", "NT.RoundStart.modconflicts", function()
Timer.Wait(function()
NT.CheckModConflicts()
end, 10000)
end)
+278
View File
@@ -0,0 +1,278 @@
-- NT functions for multiscalpel mode setting
-- Hooks XML Lua events defined in the multiscalpel item.xml
-- Hooks Lua event "roundStart" to RefreshAllMultiscalpels descriptions
function NT.SetMultiscalpelFunction(item, func)
if func ~= "" then
item.Tags = "multiscalpel_" .. func
else
item.Tags = ""
end
NT.RefreshScalpelDescription(item)
end
local function GetMultiscalpelMode(item)
local functiontag = ""
local tags = HF.SplitString(item.Tags, ",")
for tag in tags do
if HF.StartsWith(tag, "multiscalpel_") then
functiontag = HF.SplitString(tag, "_")[2]
break
end
end
return functiontag
end
function NT.RefreshScalpelDescription(item)
-- if not HF.ItemHasTag(item,"init") then return end
-- hostside only
if Game.IsMultiplayer and CLIENT then return end
if not Entity.Spawner then
Timer.Wait(function()
NT.RefreshScalpelDescription(item)
end, 35)
return
end
local functiontag = GetMultiscalpelMode(item)
if functiontag == "" then return end
local targetinventory = item.ParentInventory
local targetslot = 0
if targetinventory ~= nil then targetslot = targetinventory.FindIndex(item) end
local function SpawnFunc(newscalpelitem, targetinventory)
if targetinventory ~= nil then targetinventory.TryPutItem(newscalpelitem, targetslot, true, true, nil) end
newscalpelitem.DescriptionTag = "multiscalpel." .. functiontag
newscalpelitem.Tags = "multiscalpel_" .. functiontag
end
HF.RemoveItem(item)
Timer.Wait(function()
local prefab = item.Prefab
Entity.Spawner.AddItemToSpawnQueue(prefab, item.WorldPosition, nil, nil, function(newscalpelitem)
SpawnFunc(newscalpelitem, targetinventory)
end)
end, 35)
end
-- Let's faithfully believe Ydrec that said the item descriptions are already serialized by base game
--Hook.Add("roundStart", "NT.RoundStart.Multiscalpels", function()
-- Timer.Wait(function()
-- NT.RefreshAllMultiscalpels()
-- end, 10000) -- maybe 10 seconds is enough?
--end)
function NT.RefreshAllMultiscalpels()
-- descriptions dont get serialized, so i have to respawn
-- every scalpel every round to keep their descriptions (big oof)
-- fetch scalpel items
local scalpelItems = {}
for item in Item.ItemList do
if item.Prefab.Identifier.Value == "multiscalpel" then table.insert(scalpelItems, item) end
end
-- refresh items
for scalpel in scalpelItems do
NT.RefreshScalpelDescription(scalpel)
end
end
--Timer.Wait(function()
-- NT.RefreshAllMultiscalpels()
--end, 50)
Hook.Add(
"NT.multiscalpel.incision",
"NT.multiscalpel.incision",
function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "incision")
end
)
Hook.Add("NT.multiscalpel.kidneys", "NT.multiscalpel.kidneys", function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "kidneys")
end)
Hook.Add("NT.multiscalpel.liver", "NT.multiscalpel.liver", function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "liver")
end)
Hook.Add("NT.multiscalpel.lungs", "NT.multiscalpel.lungs", function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "lungs")
end)
Hook.Add("NT.multiscalpel.heart", "NT.multiscalpel.heart", function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "heart")
end)
Hook.Add("NT.multiscalpel.brain", "NT.multiscalpel.brain", function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "brain")
end)
Hook.Add("NT.multiscalpel.bandage", "NT.multiscalpel.bandage", function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "bandage")
end)
Hook.Add(
"NT.multiscalpel.speedflex",
"NT.multiscalpel.speedflex",
function(effect, deltaTime, item, targets, worldPosition)
NT.SetMultiscalpelFunction(item, "speedflex")
end
)
NT.ItemMethods.multiscalpel = function(item, usingCharacter, targetCharacter, limb)
local limbtype = HF.NormalizeLimbType(limb.type)
local mode = GetMultiscalpelMode(item)
if mode == "" then mode = "none" end
local modeFunctions = {
none = function(item, usingCharacter, targetCharacter, limb) end,
incision = NT.ItemMethods.advscalpel,
kidneys = NT.ItemMethods.organscalpel_kidneys,
liver = NT.ItemMethods.organscalpel_liver,
lungs = NT.ItemMethods.organscalpel_lungs,
heart = NT.ItemMethods.organscalpel_heart,
brain = NT.ItemMethods.organscalpel_brain,
bandage = function(item, usingCharacter, targetCharacter, limb)
-- remove casts, bandages, and if none of those apply, cause some damage
-- code snippet taken from NT.ItemMethods.traumashears
-- does the target have any cuttable afflictions?
local cuttables = HF.CombineArrays(NT.CuttableAfflictions, NT.TraumashearsAfflictions)
local canCut = false
for val in cuttables do
local prefab = AfflictionPrefab.Prefabs[val]
if prefab ~= nil then
if prefab.LimbSpecific then
if HF.HasAfflictionLimb(targetCharacter, val, limbtype, 0.1) then
canCut = true
break
end
elseif limbtype == prefab.IndicatorLimb then
if HF.HasAffliction(targetCharacter, val, 0.1) then
canCut = true
break
end
end
end
end
if canCut then
NT.ItemMethods.traumashears(item, usingCharacter, targetCharacter, limb)
else
-- malpractice time!!!!
local open = HF.HasAfflictionLimb(targetCharacter, "retractedskin", limbtype, 1)
local istorso = limbtype == LimbType.Torso
local ishead = limbtype == LimbType.Head
if not open then
HF.AddAfflictionLimb(targetCharacter, "bleeding", limbtype, 6 + math.random() * 4, usingCharacter)
HF.AddAfflictionLimb(
targetCharacter,
"lacerations",
limbtype,
2.5 + math.random() * 5,
usingCharacter
)
HF.GiveItem(targetCharacter, "ntsfx_slash")
else
if istorso then
-- stabbing an open torso (not good for the organs therein!)
HF.AddAffliction(targetCharacter, "internalbleeding", 6 + math.random() * 12, usingCharacter)
HF.AddAfflictionLimb(
targetCharacter,
"lacerations",
limbtype,
4 + math.random() * 6,
usingCharacter
)
HF.AddAfflictionLimb(
targetCharacter,
"internaldamage",
limbtype,
4 + math.random() * 6,
usingCharacter
)
local case = math.random()
local casecount = 4
if case < 1 / casecount then
HF.AddAffliction(targetCharacter, "kidneydamage", 10 + math.random() * 10, usingCharacter)
elseif case < 2 / casecount then
HF.AddAffliction(targetCharacter, "liverdamage", 10 + math.random() * 10, usingCharacter)
elseif case < 3 / casecount then
HF.AddAffliction(targetCharacter, "lungdamage", 10 + math.random() * 10, usingCharacter)
elseif case < 4 / casecount then
HF.AddAffliction(targetCharacter, "heartdamage", 10 + math.random() * 10, usingCharacter)
end
elseif ishead then
-- stabbing an open head (brain surgery done right!)
HF.AddAffliction(targetCharacter, "cerebralhypoxia", 15 + math.random() * 15, usingCharacter)
HF.AddAfflictionLimb(
targetCharacter,
"internaldamage",
limbtype,
10 + math.random() * 10,
usingCharacter
)
HF.AddAfflictionLimb(
targetCharacter,
"bleeding",
limbtype,
6 + math.random() * 12,
usingCharacter
)
else
-- stabbing an open arm or leg (how to cause fractures)
HF.AddAfflictionLimb(
targetCharacter,
"bleeding",
limbtype,
6 + math.random() * 6,
usingCharacter
)
HF.AddAfflictionLimb(
targetCharacter,
"lacerations",
limbtype,
4 + math.random() * 6,
usingCharacter
)
HF.AddAfflictionLimb(
targetCharacter,
"internaldamage",
limbtype,
4 + math.random() * 6,
usingCharacter
)
if HF.Chance(0.1) then NT.BreakLimb(targetCharacter, limbtype) end
end
HF.GiveItem(targetCharacter, "ntsfx_slash")
end
end
end,
speedflex = function(item, usingCharacter, targetCharacter, limb)
local animcontroller = targetCharacter.AnimController
local torsoLimb = limb
if animcontroller ~= nil then torsoLimb = animcontroller.MainLimb end
if limbtype == LimbType.Head then
NT.ItemMethods.organscalpel_brain(item, usingCharacter, targetCharacter, limb)
elseif limbtype == LimbType.LeftArm then
NT.ItemMethods.organscalpel_kidneys(item, usingCharacter, targetCharacter, torsoLimb)
elseif limbtype == LimbType.Torso then
NT.ItemMethods.organscalpel_liver(item, usingCharacter, targetCharacter, torsoLimb)
elseif limbtype == LimbType.RightArm then
NT.ItemMethods.organscalpel_heart(item, usingCharacter, targetCharacter, torsoLimb)
elseif limbtype == LimbType.LeftLeg then
NT.ItemMethods.organscalpel_lungs(item, usingCharacter, targetCharacter, torsoLimb)
end
end,
}
if modeFunctions[mode] ~= nil then modeFunctions[mode](item, usingCharacter, targetCharacter, limb) end
if mode ~= "none" then Timer.Wait(function()
item.Tags = "multiscalpel_" .. mode
end, 50) end
end
+334
View File
@@ -0,0 +1,334 @@
NTC = {} -- a class containing compatibility functions for other mods to make use of neurotraumas symptom system
-- use this function to register your expansion mod to be displayed by the
-- console lua startup readout of neurotrauma expansions
-- check surgery plus or cybernetics for an example
-- example of code for registering your expansion in init.lua:
-- MyExp = {} -- Example Expansions
-- MyExp.Name="My Expansion"
-- MyExp.Version = "A1.0"
-- MyExp.VersionNum = 01000000 -- split into two digits (01->1.; 00->0.; 00->0h; 00->0) -> 1.0.0h0
-- MyExp.MinNTVersion = "A1.7.1"
-- MyExp.MinNTVersionNum = 01070100 -- 01.07.01.00 -> A1.7.1h0
-- Timer.Wait(function() if NT ~= nil then NTC.RegisterExpansion(MyExp) end end,1)
NTC.RegisteredExpansions = {}
-- The function to add your addon to NT, see above for more info.
---@param expansionMainObject table The table of the addon.
function NTC.RegisterExpansion(expansionMainObject)
table.insert(NTC.RegisteredExpansions, expansionMainObject)
end
-- a table of tables, each character that has some custom data has an entry
NTC.CharacterData = {}
-- use this function to induce symptoms temporarily
-- duration is in humanupdates (~2 seconds), should at least be 2 to prevent symptom flickering
---@param character Character The character to set the symptom on.
---@param symptomidentifer string The identifier of the symptom.
---@param duration integer The number of human updates it lasts for.
function NTC.SetSymptomTrue(character, symptomidentifer, duration)
if duration == nil then duration = 2 end
NTC.AddEmptyCharacterData(character)
local data = NTC.GetCharacterData(character)
data[symptomidentifer] = duration
NTC.CharacterData[character.ID] = data
end
-- use this function to suppress symptoms temporarily. this takes precedence over NTC.SetSymptomTrue.
-- duration is in humanupdates (~2 seconds), should at least be 2 to prevent symptom flickering
---@param character Character The character to set the symptom on.
---@param symptomidentifer string The identifier of the symptom.
---@param duration integer The number of human updates it lasts for.
function NTC.SetSymptomFalse(character, symptomidentifer, duration)
if duration == nil then duration = 2 end
NTC.AddEmptyCharacterData(character)
local data = NTC.GetCharacterData(character)
data["!" .. symptomidentifer] = duration
NTC.CharacterData[character.ID] = data
end
-- usage example: anywhere in your lua code, cause 4 seconds (2 humanupdates) of pale skin with this:
-- NTC.SetSymptomTrue(targetCharacter,"sym_paleskin",2)
-- a list of possible symptom identifiers:
-- sym_unconsciousness
-- tachycardia
-- hyperventilation
-- hypoventilation
-- dyspnea
-- sym_cough
-- sym_paleskin
-- sym_lightheadedness
-- sym_blurredvision
-- sym_confusion
-- sym_headache
-- sym_legswelling
-- sym_weakness
-- sym_wheezing
-- sym_vomiting
-- sym_nausea
-- sym_hematemesis
-- sym_fever
-- sym_abdomdiscomfort
-- sym_bloating
-- sym_jaundice
-- sym_sweating
-- sym_palpitations
-- sym_craving
-- pain_abdominal
-- pain_chest
-- lockleftarm
-- lockrightarm
-- lockleftleg
-- lockrightleg
-- with the following identifiers you can either cause things or prevent them.
-- i recommend setting the duration when using these to cause things to 1.
-- triggersym_seizure
-- triggersym_coma
-- triggersym_stroke
-- triggersym_heartattack
-- triggersym_cardiacarrest
-- triggersym_respiratoryarrest
-- prints all of the current compatibility data in the chat
-- might be useful for debugging
function NTC.DebugPrintAllData()
local res = "neurotrauma compatibility data:\n"
for key, value in pairs(NTC.CharacterData) do
res = res .. "\n" .. value["character"].Name
for key2, value2 in pairs(value) do
res = res .. "\n " .. tostring(key2) .. " : " .. tostring(value2)
end
end
PrintChat(res)
end
NTC.PreHumanUpdateHooks = {}
-- use this function to add a function to be executed before humanupdate with a character parameter
---@param func function The actual function to be called before a human update.
function NTC.AddPreHumanUpdateHook(func)
NTC.PreHumanUpdateHooks[#NTC.PreHumanUpdateHooks + 1] = func
end
NTC.HumanUpdateHooks = {}
-- use this function to add a function to be executed after humanupdate with a character parameter
---@param func function The actual function to be called after a human update.
function NTC.AddHumanUpdateHook(func)
NTC.HumanUpdateHooks[#NTC.HumanUpdateHooks + 1] = func
end
NTC.OnDamagedHooks = {}
-- use this function to add a function to be executed after ondamaged
-- with a characterhealth, attack result and limb parameter
---@param func function The actual function to be called on damaged.
function NTC.AddOnDamagedHook(func)
NTC.OnDamagedHooks[#NTC.OnDamagedHooks + 1] = func
end
NTC.ModifyingOnDamagedHooks = {}
-- use this function to add a function to be executed before ondamaged
-- with a characterhealth, afflictions and limb parameter, and afflictions return type
---@param func function The actual function to be called on damaged. Modifying.
function NTC.AddModifyingOnDamagedHook(func)
NTC.ModifyingOnDamagedHooks[#NTC.ModifyingOnDamagedHooks + 1] = func
end
NTC.CharacterSpeedMultipliers = {}
-- use this function to multiply a characters speed for one human update.
-- should always be called from within a prehumanupdate hook
---@param character Character The character to set the speed multiplier to.
---@param multiplier number The value of the multiplier.
function NTC.MultiplySpeed(character, multiplier)
if NTC.CharacterSpeedMultipliers[character] == nil then
NTC.CharacterSpeedMultipliers[character] = multiplier
else
NTC.CharacterSpeedMultipliers[character] = NTC.CharacterSpeedMultipliers[character] * multiplier
end
end
-- use this function to register an affliction to be detected by the hematology analyzer
---@param identifier string The identifier of the affliction to be visible on hematology.
function NTC.AddHematologyAffliction(identifier)
Timer.Wait(function()
if not HF.TableContains(NT.HematologyDetectable, identifier) then
table.insert(NT.HematologyDetectable, identifier)
end
end, 1)
end
-- use this function to register an affliction to be healed by sutures
-- identifier: the identifier of the affliction to be healed
-- surgeryskillgain: how much surgery skill is gained by healing this affliction (optional, default: 0)
-- requiredaffliction: what affliction has to be present alongside the healed affliction for it to get healed (optional, default: none)
-- func: a function that gets run if the affliction is present. if provided, doesnt heal the affliction automatically (optional, default: none)
-- func(item, usingCharacter, targetCharacter, limb)
---@param identifier string The identifier of the affliction to be cured by sutures.
---@param surgeryskillgain number The surgeryskill increase from sutured affliction.
---@param requiredaffliction string The identifier of the requiredaffliction (Might need more documentation!)
---@param func function The function to be called when the affliction is cured with sutures.
function NTC.AddSuturedAffliction(identifier, surgeryskillgain, requiredaffliction, func)
Timer.Wait(function()
if not HF.TableContains(NT.SutureAfflictions, identifier) then
NT.SutureAfflictions[identifier] = {
xpgain = surgeryskillgain,
case = requiredaffliction,
func = func,
}
end
end, 1)
end
-- use this function to register an affliction to be healed by drainage
---@param identifier string The identifier of the affliction to be healed.
function NTC.AddDrainageAffliction(identifier)
Timer.Wait(function()
if not HF.TableContains(NT.DrainageAfflictions, identifier) then
table.insert(NT.DrainageAfflictions, identifier)
end
end, 1)
end
NTC.AfflictionsAffectingVitality = {
bleeding = true,
bleedingnonstop = true,
burn = true,
acidburn = true,
lacerations = true,
gunshotwound = true,
bitewounds = true,
explosiondamage = true,
blunttrauma = true,
internaldamage = true,
organdamage = true,
cerebralhypoxia = true,
gangrene = true,
th_amputation = true,
sh_amputation = true,
suturedw = true,
alcoholaddiction = true,
opiateaddiction = true,
}
-- use this function to register an affliction that will cause vitality damage. (Might need more documentation!)
---@param identifier string The identifier of the affliction to cause damage.
function NTC.AddAfflictionAffectingVitality(identifier)
NTC.AfflictionsAffectingVitality[identifier] = true
end
-- these functions are used by neurotrauma to check for symptom overrides
---@param character Character The character to check the symptom on.
---@param symptomidentifer string The identifier of the symptom.
---@return boolean
function NTC.GetSymptom(character, symptomidentifer)
local chardata = NTC.GetCharacterData(character)
if chardata == nil then return false end
local durationleft = chardata[symptomidentifer]
if durationleft == nil then return false end
return true
end
---@param character Character The character to check the symptom false on.
---@param symptomidentifer string The identifier of the symptom false.
---@return boolean
function NTC.GetSymptomFalse(character, symptomidentifer)
local chardata = NTC.GetCharacterData(character)
if chardata == nil then return false end
local durationleft = chardata["!" .. symptomidentifer]
if durationleft == nil then return false end
return true
end
-- sets multiplier data for one humanupdate, should be called from within a humanupdate hook
---@param character Character The character to set the multiplier on.
---@param multiplieridentifier string The identifier of the multiplier.
---@param multiplier number The multiplier number.
function NTC.SetMultiplier(character, multiplieridentifier, multiplier)
NTC.AddEmptyCharacterData(character)
local data = NTC.GetCharacterData(character)
data["mult_" .. multiplieridentifier] = NTC.GetMultiplier(character, multiplieridentifier) * multiplier
NTC.CharacterData[character.ID] = data
end
---@param character Character The character to set the multiplier on.
---@param multiplieridentifier string The identifier of the multiplier.
function NTC.GetMultiplier(character, multiplieridentifier)
local data = NTC.GetCharacterData(character)
if data == nil or data["mult_" .. multiplieridentifier] == nil then return 1 end
return data["mult_" .. multiplieridentifier]
end
-- sets tag data for one humanupdate, should be called from within a humanupdate hook
---@param character Character The character to set the tag on.
---@param multiplieridentifier string The identifier of the tag.
function NTC.SetTag(character, tagidentifier)
NTC.AddEmptyCharacterData(character)
local data = NTC.GetCharacterData(character)
data["tag_" .. tagidentifier] = 1
end
function NTC.HasTag(character, tagidentifier)
local data = NTC.GetCharacterData(character)
if data == nil or data["tag_" .. tagidentifier] == nil then return false end
return true
end
-- // Utility functions //
-- don't concern yourself with these
function NTC.AddEmptyCharacterData(character)
if NTC.GetCharacterData(character) ~= nil then return end
local newdat = {}
newdat["character"] = character
NTC.CharacterData[character.ID] = newdat
end
function NTC.CheckChardataEmpty(character)
local chardat = NTC.GetCharacterData(character)
if chardat == nil or HF.TableSize(chardat) > 1 then return end
-- remove entry from data
NTC.CharacterData[character.ID] = nil
end
function NTC.GetCharacterData(character)
return NTC.CharacterData[character.ID]
end
function NTC.TickCharacter(character)
local chardata = NTC.GetCharacterData(character)
if chardata == nil then return end
for key, value in pairs(chardata) do
if key ~= "character" then
if HF.StartsWith(key, "mult_") then -- multipliers
chardata[key] = nil
NTC.CheckChardataEmpty(character)
else -- symptoms
local durationleft = value
if durationleft ~= nil and durationleft > 1 then
chardata[key] = durationleft - 1
else
chardata[key] = nil
NTC.CheckChardataEmpty(character)
end
end
end
end
NTC.CharacterData[character.ID] = chardata
end
function NTC.GetSpeedMultiplier(character)
if NTC.CharacterSpeedMultipliers[character] ~= nil then return NTC.CharacterSpeedMultipliers[character] end
return 1
end
+733
View File
@@ -0,0 +1,733 @@
-- Hooks Lua event "character.applyDamage" to cause NT afflictions after attacks depending on the damaging affliction defined here in NT.OnDamagedMethods
local function getCalculatedConcussionReduction(armor, strength)
if armor == nil then return 0 end
local reduction = 0
if armor.HasTag("deepdiving") or armor.HasTag("deepdivinglarge") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "concussion") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
elseif armor.HasTag("smallitem") then
local modifiers = armor.GetComponentString("Wearable").DamageModifiers
for modifier in modifiers do
if string.find(modifier.AfflictionIdentifiers, "concussion") ~= nil then
reduction = strength - strength * modifier.DamageMultiplier
end
end
end
return reduction
end
Hook.Add(
"character.damageLimb",
"NT.ondamagedby",
function(
character,
worldPosition,
hitLimb,
afflictions,
stun,
playSound,
attackImpulse,
attacker,
damageMultiplier,
allowStacking,
penetration,
shouldImplode
)
if -- invalid attack data, don't do anything
character == nil
or character.IsDead
or not character.IsHuman
or afflictions == nil
or hitLimb == nil
or hitLimb.IsSevered
or attacker == nil
or not NTConfig.Get("NT_Calculations", true)
then
return
end
local creatureCategory = NTConfig.Get("NT_creatureNoFallDamage", 1)
-- they make the game miserable with falldamage on
for val in creatureCategory do
if attacker.SpeciesName == val then
HF.AddAffliction(character, "stopcreatureabuse", 2)
break
end
end
end
)
Hook.Add("character.applyDamage", "NT.ondamaged", function(characterHealth, attackResult, hitLimb)
--print(hitLimb.HealthIndex or hitLimb ~= nil)
if -- invalid attack data, don't do anything
characterHealth == nil
or characterHealth.Character == nil
or characterHealth.Character.IsDead
or not characterHealth.Character.IsHuman
or attackResult == nil
or attackResult.Afflictions == nil
or #attackResult.Afflictions <= 0
or hitLimb == nil
or hitLimb.IsSevered
or not NTConfig.Get("NT_Calculations", true)
then
return
end
if not HF.HasAffliction(characterHealth.Character, "luabotomy") then
HF.SetAffliction(characterHealth.Character, "luabotomy", 1)
end
local afflictions = attackResult.Afflictions
-- ntc
-- modifying ondamaged hooks
for key, val in pairs(NTC.ModifyingOnDamagedHooks) do
afflictions = val(characterHealth, afflictions, hitLimb)
end
local identifier = ""
local methodtorun = nil
for value in afflictions do
-- execute fitting method, if available
identifier = value.Prefab.Identifier.Value
methodtorun = NT.OnDamagedMethods[identifier]
if methodtorun ~= nil then
-- make resistance from afflictions apply
local resistance = HF.GetResistance(characterHealth.Character, identifier, hitLimb.type)
local strength = value.Strength * (1 - resistance)
methodtorun(characterHealth.Character, strength, hitLimb.type)
end
end
-- ntc
-- ondamaged hooks
for key, val in pairs(NTC.OnDamagedHooks) do
val(characterHealth, attackResult, hitLimb)
end
end)
NT.OnDamagedMethods = {}
local function HasLungs(c)
return not HF.HasAffliction(c, "lungremoved")
end
local function HasHeart(c)
return not HF.HasAffliction(c, "heartremoved")
end
-- cause foreign bodies, rib fractures, pneumothorax, tamponade, internal bleeding, fractures, neurotrauma
NT.OnDamagedMethods.gunshotwound = function(character, strength, limbtype)
limbtype = HF.NormalizeLimbType(limbtype)
local causeFullForeignBody = false
-- torso specific
if strength >= 1 and limbtype == LimbType.Torso then
local hitOrgan = false
if
HF.Chance(
HF.Clamp(strength * 0.02, 0, 0.3)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
causeFullForeignBody = true
end
if
HasLungs(character)
and HF.Chance(
0.3 * NTC.GetMultiplier(character, "pneumothoraxchance") * NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
HF.AddAffliction(character, "lungdamage", strength)
HF.AddAffliction(character, "organdamage", strength / 4)
hitOrgan = true
end
if
HasHeart(character)
and hitOrgan == false
and strength >= 5
and HF.Chance(
strength / 50 * NTC.GetMultiplier(character, "tamponadechance") * NTConfig.Get("NT_tamponadeChance", 1)
)
then
HF.AddAffliction(character, "tamponade", 5)
HF.AddAffliction(character, "heartdamage", strength)
HF.AddAffliction(character, "organdamage", strength / 4)
hitOrgan = true
end
if strength >= 5 then HF.AddAffliction(character, "internalbleeding", strength * HF.RandomRange(0.3, 0.6)) end
-- liver and kidney damage
if hitOrgan == false and strength >= 2 and HF.Chance(0.5) then
HF.AddAfflictionLimb(character, "organdamage", limbtype, strength / 4)
if HF.Chance(0.5) then
HF.AddAffliction(character, "liverdamage", strength)
else
HF.AddAffliction(character, "kidneydamage", strength)
end
end
end
-- head
if strength >= 1 and limbtype == LimbType.Head then
if
HF.Chance(
strength / 90 * NTC.GetMultiplier(character, "anyfracturechance") * NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
causeFullForeignBody = true
end
if strength >= 5 and HF.Chance(0.7) then
HF.AddAffliction(character, "cerebralhypoxia", strength * HF.RandomRange(0.1, 0.4))
end
end
-- extremities
if strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
NT.LimbIsBroken(character, limbtype)
and not NT.LimbIsAmputated(character, limbtype)
and HF.Chance(
strength
/ 60
* NTC.GetMultiplier(character, "traumamputatechance")
* NTConfig.Get("NT_traumaticAmputationChance", 1)
)
then
NT.TraumamputateLimb(character, limbtype)
end
if
HF.Chance(
strength / 60 * NTC.GetMultiplier(character, "anyfracturechance") * NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
causeFullForeignBody = true
end
end
-- foreign bodies
if causeFullForeignBody then
HF.AddAfflictionLimb(
character,
"foreignbody",
limbtype,
HF.Clamp(strength, 0, 30) * NTC.GetMultiplier(character, "foreignbodymultiplier")
)
else
if HF.Chance(0.75) then
HF.AddAfflictionLimb(
character,
"foreignbody",
limbtype,
HF.Clamp(strength / 4, 0, 20) * NTC.GetMultiplier(character, "foreignbodymultiplier")
)
end
end
end
-- cause foreign bodies, rib fractures, pneumothorax, internal bleeding, concussion, fractures
NT.OnDamagedMethods.explosiondamage = function(character, strength, limbtype)
limbtype = HF.NormalizeLimbType(limbtype)
if HF.Chance(0.75) then
HF.AddAfflictionLimb(
character,
"foreignbody",
limbtype,
strength / 2 * NTC.GetMultiplier(character, "foreignbodymultiplier")
)
end
-- torso specific
if strength >= 1 and limbtype == LimbType.Torso then
if
strength >= 10
and HF.Chance(
strength / 50 * NTC.GetMultiplier(character, "anyfracturechance") * NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
HasLungs(character)
and strength >= 5
and HF.Chance(
strength
/ 50
* NTC.GetMultiplier(character, "pneumothoraxchance")
* NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
end
if strength >= 5 then HF.AddAffliction(character, "internalbleeding", strength * HF.RandomRange(0.2, 0.5)) end
end
-- head
if strength >= 1 and limbtype == LimbType.Head then
if strength >= 15 and HF.Chance(math.min(strength / 60, 0.7)) then
local armor1 = character.Inventory.GetItemInLimbSlot(InvSlotType.OuterClothes)
local armor2 = character.Inventory.GetItemInLimbSlot(InvSlotType.Head)
local reduceddmg = math.max(
10
- getCalculatedConcussionReduction(armor1, 10, limbtype)
- getCalculatedConcussionReduction(armor2, 10, limbtype),
0
)
HF.AddAfflictionResisted(character, "concussion", reduceddmg)
end
if
strength >= 15
and HF.Chance(
math.min(strength / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
strength >= 15
and HF.Chance(
math.min(strength / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
HF.AddAffliction(character, "n_fracture", 5)
end
if strength >= 75 and HF.Chance(0.25) then
-- drop previously held item
local previtem = HF.GetHeadWear(character)
if previtem ~= nil then previtem.Drop(character, true) end
NT.TraumamputateLimb(character, limbtype)
end
end
-- extremities
if strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
NT.LimbIsBroken(character, limbtype)
and not NT.LimbIsAmputated(character, limbtype)
and HF.Chance(
strength
/ 60
* NTC.GetMultiplier(character, "traumamputatechance")
* NTConfig.Get("NT_traumaticAmputationChance", 1)
)
then
NT.TraumamputateLimb(character, limbtype)
end
if
HF.Chance(
strength / 60 * NTC.GetMultiplier(character, "anyfracturechance") * NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
HF.Chance(
0.35 * NTC.GetMultiplier(character, "dislocationchance") * NTConfig.Get("NT_dislocationChance", 1)
) and not NT.LimbIsAmputated(character, limbtype)
then
NT.DislocateLimb(character, limbtype)
end
end
end
-- cause rib fractures, pneumothorax, internal bleeding, concussion, fractures
NT.OnDamagedMethods.bitewounds = function(character, strength, limbtype)
limbtype = HF.NormalizeLimbType(limbtype)
-- torso specific
if strength >= 1 and limbtype == LimbType.Torso then
if
strength >= 10
and HF.Chance(
(strength - 10)
/ 50
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
HasLungs(character)
and strength >= 5
and HF.Chance(
(strength - 5)
/ 50
* NTC.GetMultiplier(character, "pneumothoraxchance")
* NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
end
if strength >= 5 then HF.AddAffliction(character, "internalbleeding", strength * HF.RandomRange(0.2, 0.5)) end
end
-- head
if strength >= 1 and limbtype == LimbType.Head then
if strength >= 15 and HF.Chance(math.min(strength / 60, 0.7)) then
local armor1 = character.Inventory.GetItemInLimbSlot(InvSlotType.OuterClothes)
local armor2 = character.Inventory.GetItemInLimbSlot(InvSlotType.Head)
local reduceddmg = math.max(
10
- getCalculatedConcussionReduction(armor1, 10, limbtype)
- getCalculatedConcussionReduction(armor2, 10, limbtype),
0
)
HF.AddAfflictionResisted(character, "concussion", reduceddmg)
end
if
strength >= 15
and HF.Chance(
math.min((strength - 10) / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
end
-- extremities
if strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
NT.LimbIsBroken(character, limbtype)
and not NT.LimbIsAmputated(character, limbtype)
and HF.Chance(
(strength - 5)
/ 60
* NTC.GetMultiplier(character, "traumamputatechance")
* NTConfig.Get("NT_traumaticAmputationChance", 1)
)
then
NT.TraumamputateLimb(character, limbtype, character.LastAttacker)
end
if
HF.Chance(
(strength - 5)
/ 60
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
end
end
-- cause rib fractures, pneumothorax, tamponade, internal bleeding, fractures
NT.OnDamagedMethods.lacerations = function(character, strength, limbtype)
limbtype = HF.NormalizeLimbType(limbtype)
-- torso specific
if strength >= 1 and limbtype == LimbType.Torso then
if
strength >= 10
and HF.Chance(
(strength - 10)
/ 50
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
HasLungs(character)
and strength >= 5
and HF.Chance(
(strength - 5)
/ 50
* NTC.GetMultiplier(character, "pneumothoraxchance")
* NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
end
if
HasHeart(character)
and strength >= 5
and HF.Chance(
(strength - 5)
/ 50
* NTC.GetMultiplier(character, "tamponadechance")
* NTConfig.Get("NT_tamponadeChance", 1)
)
then
HF.AddAffliction(character, "tamponade", 5)
end
if strength >= 5 then HF.AddAffliction(character, "internalbleeding", strength * HF.RandomRange(0.2, 0.5)) end
end
-- head
if strength >= 1 and limbtype == LimbType.Head then
if
strength >= 15
and HF.Chance(
math.min((strength - 15) / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
end
-- extremities
if strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
NT.LimbIsBroken(character, limbtype)
and not NT.LimbIsAmputated(character, limbtype)
and HF.Chance(
strength
/ 60
* NTC.GetMultiplier(character, "traumamputatechance")
* NTConfig.Get("NT_traumaticAmputationChance", 1)
)
then
NT.TraumamputateLimb(character, limbtype)
end
if
HF.Chance(
(strength - 5)
/ 60
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
end
end
-- cause rib fractures, organ damage, pneumothorax, concussion, fractures, neurotrauma
NT.OnDamagedMethods.blunttrauma = function(character, strength, limbtype)
limbtype = HF.NormalizeLimbType(limbtype)
local fractureImmune = HF.HasAffliction(character, "cpr_fracturebuff")
-- torso
if not fractureImmune and strength >= 1 and limbtype == LimbType.Torso then
if
HF.Chance(
strength / 50 * NTC.GetMultiplier(character, "anyfracturechance") * NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
HF.AddAffliction(character, "lungdamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "heartdamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "liverdamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "kidneydamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "organdamage", strength * HF.RandomRange(0, 1))
if
HasLungs(character)
and strength >= 5
and HF.Chance(
strength
/ 50
* NTC.GetMultiplier(character, "pneumothoraxchance")
* NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
end
end
-- head
if not fractureImmune and strength >= 1 and limbtype == LimbType.Head then
if strength >= 15 and HF.Chance(math.min(strength / 60, 0.7)) then
local armor1 = character.Inventory.GetItemInLimbSlot(InvSlotType.OuterClothes)
local armor2 = character.Inventory.GetItemInLimbSlot(InvSlotType.Head)
local reduceddmg = math.max(
10
- getCalculatedConcussionReduction(armor1, 10, limbtype)
- getCalculatedConcussionReduction(armor2, 10, limbtype),
0
)
HF.AddAfflictionResisted(character, "concussion", reduceddmg)
end
if
strength >= 15
and HF.Chance(
math.min((strength - 10) / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
strength >= 15
and HF.Chance(
math.min((strength - 10) / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
HF.AddAffliction(character, "n_fracture", 5)
end
if strength >= 5 and HF.Chance(0.7) then
HF.AddAffliction(character, "cerebralhypoxia", strength * HF.RandomRange(0.1, 0.4))
end
end
-- extremities
if not fractureImmune and strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
strength > 15
and NT.LimbIsBroken(character, limbtype)
and not NT.LimbIsAmputated(character, limbtype)
and HF.Chance(
strength
/ 100
* NTC.GetMultiplier(character, "traumamputatechance")
* NTConfig.Get("NT_traumaticAmputationChance", 1)
)
then
NT.TraumamputateLimb(character, limbtype)
end
if
HF.Chance(
(strength - 2)
/ 60
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
HF.Chance(
HF.Clamp((strength - 2) / 80, 0, 0.5)
* NTC.GetMultiplier(character, "dislocationchance")
* NTConfig.Get("NT_dislocationChance", 1)
) and not NT.LimbIsAmputated(character, limbtype)
then
NT.DislocateLimb(character, limbtype)
end
end
end
-- cause rib fractures, organ damage, pneumothorax, concussion, fractures
NT.OnDamagedMethods.internaldamage = function(character, strength, limbtype)
limbtype = HF.NormalizeLimbType(limbtype)
-- torso
if strength >= 1 and limbtype == LimbType.Torso then
if
HF.Chance(
(strength - 5)
/ 50
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
HF.AddAffliction(character, "lungdamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "heartdamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "liverdamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "kidneydamage", strength * HF.RandomRange(0, 1))
HF.AddAffliction(character, "organdamage", strength * HF.RandomRange(0, 1))
if
HasLungs(character)
and strength >= 5
and HF.Chance(
(strength - 5)
/ 50
* NTC.GetMultiplier(character, "pneumothoraxchance")
* NTConfig.Get("NT_pneumothoraxChance", 1)
)
then
HF.AddAffliction(character, "pneumothorax", 5)
end
end
-- head
if strength >= 1 and limbtype == LimbType.Head then
if strength >= 15 and HF.Chance(math.min(strength / 60, 0.7)) then
local armor1 = character.Inventory.GetItemInLimbSlot(InvSlotType.OuterClothes)
local armor2 = character.Inventory.GetItemInLimbSlot(InvSlotType.Head)
local reduceddmg = math.max(
10
- getCalculatedConcussionReduction(armor1, 10, limbtype)
- getCalculatedConcussionReduction(armor2, 10, limbtype),
0
)
HF.AddAfflictionResisted(character, "concussion", reduceddmg)
end
if
strength >= 15
and HF.Chance(
math.min((strength - 5) / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
strength >= 15
and HF.Chance(
math.min((strength - 5) / 60, 0.7)
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
HF.AddAffliction(character, "n_fracture", 5)
end
end
-- extremities
if strength >= 1 and HF.LimbIsExtremity(limbtype) then
if
strength > 10
and NT.LimbIsBroken(character, limbtype)
and not NT.LimbIsAmputated(character, limbtype)
and HF.Chance(
(strength - 10)
/ 60
* NTC.GetMultiplier(character, "traumamputatechance")
* NTConfig.Get("NT_traumaticAmputationChance", 1)
)
then
NT.TraumamputateLimb(character, limbtype)
end
if
HF.Chance(
(strength - 5)
/ 60
* NTC.GetMultiplier(character, "anyfracturechance")
* NTConfig.Get("NT_fractureChance", 1)
)
then
NT.BreakLimb(character, limbtype)
end
if
HF.Chance(
0.25 * NTC.GetMultiplier(character, "dislocationchance") * NTConfig.Get("NT_dislocationChance", 1)
) and not NT.LimbIsAmputated(character, limbtype)
then
NT.DislocateLimb(character, limbtype)
end
end
end
+20
View File
@@ -0,0 +1,20 @@
-- Hooks Lua event "Barotrauma.Character" to apply vanilla burning (formerly NT onfire) affliction and set a human on fire
Hook.HookMethod("Barotrauma.Character", "ApplyStatusEffects", function(instance, ptable)
if ptable.actionType == ActionType.OnFire then
local function ApplyBurn(character, limbtype)
HF.AddAfflictionLimb(character, "burning", limbtype, ptable.deltaTime * 3)
end
if instance.IsHuman then
if not HF.HasAffliction(instance, "luabotomy") then HF.SetAffliction(instance, "luabotomy", 1) end
ApplyBurn(instance, LimbType.Torso)
ApplyBurn(instance, LimbType.Head)
ApplyBurn(instance, LimbType.LeftArm)
ApplyBurn(instance, LimbType.RightArm)
ApplyBurn(instance, LimbType.LeftLeg)
ApplyBurn(instance, LimbType.RightLeg)
else
HF.AddAfflictionLimb(instance, "burning", instance.AnimController.MainLimb.type, ptable.deltaTime * 5)
end
end
end, Hook.HookMethodType.After)
+7
View File
@@ -0,0 +1,7 @@
-- Hooks XML Lua event "NT.causeScreams" to cause character to scream if config has enabled screaming
Hook.Add("NT.causeScreams", "NT.causeScreams", function(...)
if not NTConfig.Get("NT_screams", true) then return end
local character = table.pack(...)[3]
HF.SetAffliction(character, "screaming", 10)
end)