Skip to content

Commit

Permalink
some net combat checks and fixes
Browse files Browse the repository at this point in the history
add func_physbox to list of damageables

hitmarker recycling no longer used by default (it was unreliable). now it's like projectiles, creating new parts every time
  • Loading branch information
pingu7867 committed Oct 31, 2024
1 parent 0507911 commit de10931
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
69 changes: 65 additions & 4 deletions lua/pac3/core/client/parts/damage_zone.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ local renderhooks = {
"PreDrawViewModel"
}

local recycle_hitmark = CreateConVar("pac_damage_zone_recycle_hitmarkers", "0", FCVAR_ARCHIVE, "Whether to use the experimental recycling system to save performance on spawning already created hit markers.\nIf this is 0, it will be more reliable but more costly because it creates new parts every time.")


BUILDER:StartStorableVars()
:SetPropertyGroup("Targets")
Expand Down Expand Up @@ -121,9 +123,10 @@ BUILDER:StartStorableVars()
:GetSet("CriticalHealth",1, {editor_onchange = function(self,num) return math.floor(math.Clamp(num,0,65535)) end})
:GetSet("MaxHpScaling", 0, {editor_clamp = {0,1}})
:SetPropertyGroup("DamageOverTime")
:GetSet("DOTMode", false, {description = "Repeats your damage a few times. Subject to serverside convar."})
:GetSet("DOTTime", 0, {editor_clamp = {0,32}})
:GetSet("DOTCount", 0, {editor_onchange = function(self,num) return math.floor(math.Clamp(num,0,127)) end})
:GetSet("DOTMode", false, {editor_friendly = "DoT mode",
description = "Repeats your damage a few times. Subject to serverside convar."})
:GetSet("DOTTime", 0, {editor_friendly = "DoT time", editor_clamp = {0,32}, description = "delay between each repeated damage"})
:GetSet("DOTCount", 0, {editor_friendly = "DoT count", editor_onchange = function(self,num) return math.floor(math.Clamp(num,0,127)) end, description = "number of repeated damage instances"})
:GetSet("NoInitialDOT", false, {description = "Skips the first instance (the instant one) of damage to achieve a delayed damage for example."})
:SetPropertyGroup("HitOutcome")
:GetSetPart("HitSoundPart")
Expand Down Expand Up @@ -649,7 +652,7 @@ function PART:SendNetMessage()
net.WriteUInt(self.DOTCount, 7)
net.WriteUInt(math.ceil(math.Clamp(64*self.DOTTime, 0, 2047)), 11)
net.WriteString(string.sub(self.UniqueID,0,6))
local using_hit_feedback = self.HitMarkerPart ~= nil or self.KillMarkerPart ~= nil
local using_hit_feedback = IsValid(self.HitMarkerPart) or IsValid(self.KillMarkerPart)
net.WriteBool(using_hit_feedback)
net.SendToServer()
end
Expand Down Expand Up @@ -699,6 +702,40 @@ function PART:SetAttachPartsToTargetEntity(b)
end
end

--revertable to projectile part's version which wastes time creating new parts but has less issues
local_hitmarks = {}
function PART:LegacyAttachToEntity(part, ent)
if not part:IsValid() then return false end

ent.pac_draw_distance = 0

local tbl = part:ToTable()

local group = pac.CreatePart("group", self:GetPlayerOwner())
group:SetShowInEditor(false)

local part_clone = pac.CreatePart(tbl.self.ClassName, self:GetPlayerOwner(), tbl, tostring(tbl))
group:AddChild(part_clone)

group:SetOwner(ent)
group.SetOwner = function(s) s.Owner = ent end
part_clone:SetHide(false)

local id = group.Id
local owner_id = self:GetPlayerOwnerId()
if owner_id then
id = id .. owner_id
end

ent:CallOnRemove("pac_hitmarker_" .. id, function() group:Remove() end)
group:CallRecursive("Think")

ent.pac_hitmark_part = group
ent.pac_hitmark = self --that's just the launcher though

return true
end

net.Receive("pac_hit_results", function(len)
local uid = net.ReadString() or ""
local self = part_partialUID_caches[uid]
Expand Down Expand Up @@ -746,6 +783,30 @@ net.Receive("pac_hit_results", function(len)
if part == self then return end --stop infinite feedback loops of using the damagezone as a hitmarker
--what if people employ a more roundabout method? CRACKDOWN!


if not recycle_hitmark:GetBool() then
local ent = parent_ent
if not self.AttachPartsToTargetEntity then
ent = pac.CreateEntity("models/props_junk/popcan01a.mdl")
ent:SetNoDraw(true)
ent:SetPos(pos)
end
self:LegacyAttachToEntity(killing and self.KillMarkerPart or self.HitMarkerPart, ent)

timer.Simple(math.Clamp(killing and self.KillMarkerLifetime or self.HitMarkerLifetime, 0, 30), function()
if IsValid(ent) then
if ent.pac_hitmark_part and ent.pac_hitmark_part:IsValid() then
ent.pac_hitmark_part:Remove()
end

timer.Simple(0.5, function()
SafeRemoveEntity(ent)
end)
end
end)
return
end

if not owner.hitparts then owner.hitparts = {} end

if owner.stop_hit_markers_until then
Expand Down
10 changes: 6 additions & 4 deletions lua/pac3/extra/shared/net_combat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ if SERVER then
["npc_satchel"] = true,
["func_breakable_surf"] = true,
["func_breakable"] = true,
["func_physbox"] = true,
["physics_cannister"] = true
}

Expand Down Expand Up @@ -1068,7 +1069,7 @@ if SERVER then
end

--this may benefit from some flattening treatment, lotta pyramids over here
if tbl.DamageType == "heal" then
if tbl.DamageType == "heal" and ent.Health then
if ent:Health() < ent:GetMaxHealth() then
if tbl.ReverseDoNotKill then --don't heal if health is below critical
if ent:Health() > tbl.CriticalHealth then --default behavior
Expand All @@ -1084,7 +1085,7 @@ if SERVER then
end
end
end
elseif tbl.DamageType == "armor" then
elseif tbl.DamageType == "armor" and ent.Armor then
if ent:Armor() < ent:GetMaxArmor() then
if tbl.ReverseDoNotKill then --don't heal if armor is below critical
if ent:Armor() > tbl.CriticalHealth then --default behavior
Expand Down Expand Up @@ -2166,6 +2167,7 @@ if SERVER then
local prop_protected, reason = IsPropProtected(targ_ent, ply)

local owner = Try_CPPIGetOwner(targ_ent)
if not IsValid(owner) then return end


local unconsenting_owner = owner ~= ply and (grab_consents[owner] == false or (targ_ent:IsPlayer() and grab_consents[targ_ent] == false))
Expand Down Expand Up @@ -2467,7 +2469,7 @@ if SERVER then
local fraction = math.Clamp(1 - (1-bulletinfo.DamageFalloffFraction)*(distance / bulletinfo.DamageFalloffDistance),bulletinfo.DamageFalloffFraction,1)
local ent = trc.Entity

if bulletinfo.dmgtype_str == "heal" then
if bulletinfo.dmgtype_str == "heal" and ent.Health then
dmg:SetDamageType(0)

if ent:Health() < ent:GetMaxHealth() then
Expand All @@ -2476,7 +2478,7 @@ if SERVER then

dmg:SetDamage(0)
return
elseif bulletinfo.dmgtype_str == "armor" then
elseif bulletinfo.dmgtype_str == "armor" and ent.Armor then
dmg:SetDamageType(0)

if ent:Armor() < ent:GetMaxArmor() then
Expand Down

0 comments on commit de10931

Please sign in to comment.