Compare commits
No commits in common. "a17730107aee267d7e81fed5f3279b61fcabcb8f" and "3d80bdbd25a84b7e643208806408ba2cd1830348" have entirely different histories.
a17730107a
...
3d80bdbd25
8 changed files with 41 additions and 150 deletions
11
addon.json
11
addon.json
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"title" : "Z-City NPC Integration",
|
|
||||||
"type" : "Effects",
|
|
||||||
"tags" : [ "realism", "fun", "scenic" ],
|
|
||||||
"ignore" :
|
|
||||||
[
|
|
||||||
"*.psd",
|
|
||||||
"*.vcproj",
|
|
||||||
"*.svn*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
11
addon.txt
Normal file
11
addon.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
"AddonInfo"
|
||||||
|
{
|
||||||
|
"name" "Z-City NPC Integration"
|
||||||
|
"version" "1.0"
|
||||||
|
"up_date" "24th August 2026"
|
||||||
|
"author_name" "owouw.us"
|
||||||
|
"author_email" "me@owouw.us"
|
||||||
|
"author_url" "owouw.us"
|
||||||
|
"info" "owouw.us"
|
||||||
|
"override" "0"
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,6 @@ local function PopulateRagdollSBXToolMenu(pnl)
|
||||||
|
|
||||||
pnl:Help(" ")
|
pnl:Help(" ")
|
||||||
|
|
||||||
pnl:Help(" ")
|
|
||||||
|
|
||||||
pnl:NumSlider("Stumble time", "zcnpci_stumble_time", 0, 10, 3)
|
pnl:NumSlider("Stumble time", "zcnpci_stumble_time", 0, 10, 3)
|
||||||
pnl:ControlHelp("How long the ragdoll should try to stumble for.")
|
pnl:ControlHelp("How long the ragdoll should try to stumble for.")
|
||||||
|
|
||||||
|
|
@ -17,33 +15,14 @@ local function PopulateRagdollSBXToolMenu(pnl)
|
||||||
|
|
||||||
pnl:NumSlider("Minimum down time", "zcnpci_down_time", 0, 20, 3)
|
pnl:NumSlider("Minimum down time", "zcnpci_down_time", 0, 20, 3)
|
||||||
pnl:ControlHelp("The minimum amount of time the ragdoll should be down before trying to get back up.")
|
pnl:ControlHelp("The minimum amount of time the ragdoll should be down before trying to get back up.")
|
||||||
end
|
|
||||||
|
|
||||||
local function PopulatePerformanceSBXToolMenu(pnl)
|
pnl:Help(" ")
|
||||||
|
|
||||||
pnl:NumSlider("Activation range", "zcnpci_active_range", 0, 5000, 0)
|
pnl:NumSlider("Activation range", "zcnpci_active_range", 0, 5000, 0)
|
||||||
pnl:ControlHelp("How close the ragdoll has to be to a player to be living when downed by damage. Enemies downed by other causes are unaffected.")
|
pnl:ControlHelp("How close the ragdoll has to be to a player to have euphoria physics")
|
||||||
|
|
||||||
pnl:CheckBox("Always activate on player kill", "zcnpci_always_active_on_player_kill")
|
pnl:CheckBox("Always activate on player kill", "zcnpci_always_active_on_player_kill")
|
||||||
pnl:ControlHelp("If on, all player-damaged ragdolls will be activated regardless of other factors.")
|
pnl:ControlHelp("If on, all player-killed ragdolls will be activated regardless of other factors.")
|
||||||
|
|
||||||
pnl:Help(" ")
|
|
||||||
|
|
||||||
pnl:Help(" ")
|
|
||||||
|
|
||||||
pnl:CheckBox("Enable automatic corpse removal", "zcnpci_enable_corpse_removal")
|
|
||||||
pnl:ControlHelp("Enable or disable the removal of dead corpses.")
|
|
||||||
|
|
||||||
pnl:NumSlider("Max corpses", "zcnpci_max_corpses", -1, 64, 0)
|
|
||||||
pnl:ControlHelp("The maximum amount of dead corpses that are allowed before one is removed. Set to -1 to disable")
|
|
||||||
|
|
||||||
pnl:NumSlider("Max time", "zcnpci_max_corpse_time", -1, 600, 2)
|
|
||||||
pnl:ControlHelp("The maximum amount of time before a corpse is removed. Set to -1 to disable")
|
|
||||||
|
|
||||||
pnl:NumSlider("Max distance between player", "zcnpci_max_corpse_distance", -1, 32768, 2)
|
|
||||||
pnl:ControlHelp("If the corpse is further than this distance, it will be removed. Set to -1 to disable")
|
|
||||||
|
|
||||||
pnl:CheckBox("Never remove corpses near the player", "zcnpci_disable_corpse_removal_near_player")
|
|
||||||
pnl:ControlHelp("If on, corpses under the variable above in distance will never be cleared.")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if engine.ActiveGamemode() == "sandbox" then
|
if engine.ActiveGamemode() == "sandbox" then
|
||||||
|
|
@ -56,10 +35,5 @@ if engine.ActiveGamemode() == "sandbox" then
|
||||||
pnl:ClearControls()
|
pnl:ClearControls()
|
||||||
PopulateRagdollSBXToolMenu(pnl)
|
PopulateRagdollSBXToolMenu(pnl)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
spawnmenu.AddToolMenuOption("Utilities", "zcnpci", "PerformanceSettings", "Performance", "", "", function(pnl)
|
|
||||||
pnl:ClearControls()
|
|
||||||
PopulatePerformanceSBXToolMenu(pnl)
|
|
||||||
end)
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
1
lua/autorun/server/fedh_init.lua
Normal file
1
lua/autorun/server/fedh_init.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
include("fedhoria.lua")
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
include("zcnpci.lua")
|
|
||||||
|
|
@ -1,21 +1,13 @@
|
||||||
include("zcnpci/modules.lua")
|
include("zcnpci/modules.lua")
|
||||||
|
|
||||||
local enabled = CreateConVar("zcnpci_enabled", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
local enabled = CreateConVar("zcnpci_enabled", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
local active_range = CreateConVar("zcnpci_active_range", 3000, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
local active_range = CreateConVar("zcnpci_active_range", 300, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
local always_active_on_player_kill = CreateConVar("zcnpci_always_active_on_player_kill", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
local always_active_on_player_kill = CreateConVar("zcnpci_always_active_on_player_kill", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
|
|
||||||
local remove_corpses = CreateConVar("zcnpci_enable_corpse_removal", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
|
||||||
local max_corpses = CreateConVar("zcnpci_max_corpses", 8, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
|
||||||
local max_corpse_time = CreateConVar("zcnpci_max_corpse_time", 30, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
|
||||||
local max_corpse_distance = CreateConVar("zcnpci_max_corpse_distance", 3000, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
|
||||||
local no_corpse_removal_near_player = CreateConVar("zcnpci_disable_corpse_removal_near_player", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
|
||||||
|
|
||||||
local last_dmgpos = {}
|
local last_dmgpos = {}
|
||||||
local last_hitgroup = {}
|
local last_hitgroup = {}
|
||||||
local last_attacker = {}
|
local last_attacker = {}
|
||||||
|
|
||||||
local corpses = {}
|
|
||||||
|
|
||||||
hook.Add("CreateEntityRagdoll", "zcnpci", function(ent, ragdoll)
|
hook.Add("CreateEntityRagdoll", "zcnpci", function(ent, ragdoll)
|
||||||
if !ent.organism then return end
|
if !ent.organism then return end
|
||||||
|
|
||||||
|
|
@ -83,25 +75,11 @@ hook.Add("ScaleNPCDamage", "zcnpci", function(npc, hitgroup, dmginfo)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hook.Add("Think", "zcnpci", function()
|
hook.Add("Think", "zcnpci", function()
|
||||||
for i, ent in pairs(corpses) do
|
|
||||||
if !IsValid(ent) then
|
|
||||||
table.RemoveByValue(corpses, ent)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (max_corpses:GetFloat() != -1) and (#corpses > max_corpses:GetFloat()) then
|
|
||||||
if IsValid(corpses[1]) then
|
|
||||||
corpses[1]:Remove()
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(corpses, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i, ent in pairs(ents.GetAll()) do
|
for i, ent in pairs(ents.GetAll()) do
|
||||||
if !IsValid(ent) then continue end
|
if !IsValid(ent) then continue end
|
||||||
|
if !ent:IsNPC() then continue end
|
||||||
if !ent.organism then continue end
|
if !ent.organism then continue end
|
||||||
|
|
||||||
if ent:IsNPC() then
|
|
||||||
-- Knock them down if something is off
|
-- Knock them down if something is off
|
||||||
if (
|
if (
|
||||||
((ent.organism.lleg >= 1) and (ent.organism.rleg >= 1)) or
|
((ent.organism.lleg >= 1) and (ent.organism.rleg >= 1)) or
|
||||||
|
|
@ -118,42 +96,6 @@ hook.Add("Think", "zcnpci", function()
|
||||||
|
|
||||||
ent:TakeDamageInfo(damage_info)
|
ent:TakeDamageInfo(damage_info)
|
||||||
end
|
end
|
||||||
elseif !ent.organism.alive and remove_corpses then
|
|
||||||
-- Add to corpse list if not there already
|
|
||||||
if !table.HasValue(corpses, ent) then
|
|
||||||
table.insert(corpses, ent)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Get nearest player for future checks
|
|
||||||
local nearby_player
|
|
||||||
local players = player.GetAll()
|
|
||||||
|
|
||||||
for i, loop_player in pairs(players) do
|
|
||||||
local player_position = loop_player:GetPos()
|
|
||||||
|
|
||||||
local distance = ent:GetPos():Distance(player_position)
|
|
||||||
|
|
||||||
if (distance <= max_corpse_distance:GetFloat()) or (max_corpse_distance:GetFloat() == -1) then
|
|
||||||
nearby_player = loop_player
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if nearby_player and IsValid(nearby_player) and no_corpse_removal_near_player:GetBool() then continue
|
|
||||||
elseif (max_corpse_distance:GetFloat() != -1) and !nearby_player then
|
|
||||||
ent:Remove()
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
|
|
||||||
if max_corpse_time:GetFloat() != -1 then
|
|
||||||
if !ent.corpse_timestamp then ent.corpse_timestamp = CurTime()
|
|
||||||
elseif (CurTime() - ent.corpse_timestamp) > max_corpse_time:GetFloat() then
|
|
||||||
ent:Remove()
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
print((CurTime() - ent.corpse_timestamp) > max_corpse_time:GetFloat())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ local cv_anim_roll_impact_threshold = CreateConVar("zcnpci_falling_anim_roll_imp
|
||||||
local cv_anim_roll_playback_rate = CreateConVar("zcnpci_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации")
|
local cv_anim_roll_playback_rate = CreateConVar("zcnpci_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации")
|
||||||
|
|
||||||
-- Down time
|
-- Down time
|
||||||
local minimum_down_time = CreateConVar("zcnpci_down_time", "3", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Down time!!!!!!!!!")
|
local minimum_down_time = CreateConVar("zcnpci_down_time", "5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Down time!!!!!!!!!")
|
||||||
|
|
||||||
--[[-------------------------------------------------------------------------
|
--[[-------------------------------------------------------------------------
|
||||||
Tug function
|
Tug function
|
||||||
|
|
@ -182,18 +182,8 @@ end
|
||||||
--[[-------------------------------------------------------------------------
|
--[[-------------------------------------------------------------------------
|
||||||
Think-hook
|
Think-hook
|
||||||
---------------------------------------------------------------------------]]
|
---------------------------------------------------------------------------]]
|
||||||
|
|
||||||
function MODULE:Think()
|
function MODULE:Think()
|
||||||
if !IsValid(target) then return end
|
-- Space for additional logic
|
||||||
|
|
||||||
print("target is valid")
|
|
||||||
|
|
||||||
local phys = target:GetPhysicsObject()
|
|
||||||
if !IsValid(phys) or !phys:IsAsleep() then return end
|
|
||||||
|
|
||||||
print("phys is valid")
|
|
||||||
|
|
||||||
phys:Wake()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[-------------------------------------------------------------------------
|
--[[-------------------------------------------------------------------------
|
||||||
|
|
@ -228,17 +218,11 @@ function MODULE:PhysicsCollide(data, phys)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MODULE:EntityTakeDamage(ent, dmginfo)
|
|
||||||
print("I TOOK DAMAGE")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[-------------------------------------------------------------------------
|
--[[-------------------------------------------------------------------------
|
||||||
Physics Simulation Hook (FIXED)
|
Physics Simulation Hook (FIXED)
|
||||||
---------------------------------------------------------------------------]]
|
---------------------------------------------------------------------------]]
|
||||||
function MODULE:PhysicsSimulate(phys, dt)
|
function MODULE:PhysicsSimulate(phys, dt)
|
||||||
phys:Wake()
|
|
||||||
|
|
||||||
if self.StopProcessing then return false end
|
if self.StopProcessing then return false end
|
||||||
|
|
||||||
local cur_time = CurTime()
|
local cur_time = CurTime()
|
||||||
|
|
@ -270,7 +254,7 @@ function MODULE:PhysicsSimulate(phys, dt)
|
||||||
-- If the NPC is dead, they probably aren't coming back; don't bother bringing them back to life
|
-- If the NPC is dead, they probably aren't coming back; don't bother bringing them back to life
|
||||||
self:Remove()
|
self:Remove()
|
||||||
return false -- Cut the bullshit
|
return false -- Cut the bullshit
|
||||||
elseif (target.organism.consciousness <= 0.3) or ((target.organism.lleg >= 0.85) and (target.organism.rleg >= 0.85)) then
|
elseif (target.organism.consciousness <= 0.3) or ((target.organism.lleg >= 1) and (target.organism.rleg >= 1)) then
|
||||||
self.StartDie = cur_time
|
self.StartDie = cur_time
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
@ -298,25 +282,13 @@ function MODULE:PhysicsSimulate(phys, dt)
|
||||||
|
|
||||||
ent:Spawn()
|
ent:Spawn()
|
||||||
|
|
||||||
timer.Simple(0, function()
|
ent.organism = table.Copy(target.organism)
|
||||||
hg.organism.Add(ent)
|
|
||||||
table.Merge(ent.organism, target.organism)
|
|
||||||
|
|
||||||
ent.tourniquets = table.Copy(target.tourniquets)
|
|
||||||
ent.bandaged_limbs = table.Copy(target.bandaged_limbs)
|
|
||||||
|
|
||||||
ent.organism.alive = true
|
|
||||||
ent.organism.owner = ent
|
ent.organism.owner = ent
|
||||||
|
|
||||||
ent:CallOnRemove("organism", hg.organism.Remove, ent)
|
|
||||||
hg.send_bareinfo(ent.organism)
|
|
||||||
|
|
||||||
target:Remove()
|
|
||||||
end)
|
|
||||||
|
|
||||||
self.StopProcessing = true
|
self.StopProcessing = true
|
||||||
|
|
||||||
self:Remove()
|
self:Remove()
|
||||||
|
target:Remove()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ local cv_anim_roll_duration = CreateConVar("zcnpci_falling_anim_roll_duration",
|
||||||
local cv_anim_roll_impact_threshold = CreateConVar("zcnpci_falling_anim_roll_impact_threshold", "300", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. скорость удара для запуска анимации")
|
local cv_anim_roll_impact_threshold = CreateConVar("zcnpci_falling_anim_roll_impact_threshold", "300", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. скорость удара для запуска анимации")
|
||||||
local cv_anim_roll_playback_rate = CreateConVar("zcnpci_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации")
|
local cv_anim_roll_playback_rate = CreateConVar("zcnpci_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации")
|
||||||
|
|
||||||
|
-- Down time
|
||||||
|
local minimum_down_time = CreateConVar("zcnpci_down_time", "5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Down time!!!!!!!!!")
|
||||||
|
|
||||||
-- Do it!
|
-- Do it!
|
||||||
function MODULE:DoTwitch()
|
function MODULE:DoTwitch()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue