diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc344ffc5..772c92862e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to TTT2 will be documented here. Inspired by [keep a changel - Added option to use right click to enable/disable roles in the role layering menu (by @TimGoll) - Added option to enable team name next to role name on the HUD (by @milkwxter) - Added score event for winning with configurable role parameter (by @MrXonte) +- Added ExplosiveSphereDamage game effect for easy calculation of explosion damage through walls (by @MrXonte) ### Fixed @@ -59,6 +60,7 @@ All notable changes to TTT2 will be documented here. Inspired by [keep a changel - Moved all role-related admin options into the "Roles" menu (by @nike4613) - Improved description of role layering (by @nike4613) - Improved the role layering menu by showing which role is enabled and which is disabled (by @TimGoll) +- Reworked C4 damage calculation with new gameEffect ExplosiveSphereDamage (by @MrXonte) ## [v0.14.0b](https://github.com/TTT-2/TTT2/tree/v0.14.0b) (2024-09-20) diff --git a/gamemodes/terrortown/entities/entities/ttt_c4/shared.lua b/gamemodes/terrortown/entities/entities/ttt_c4/shared.lua index a282e6689e..d2d4bcc55d 100644 --- a/gamemodes/terrortown/entities/entities/ttt_c4/shared.lua +++ b/gamemodes/terrortown/entities/entities/ttt_c4/shared.lua @@ -194,8 +194,8 @@ function ENT:Explode(tr) r_inner = r_inner / 2.5 r_outer = r_outer / 2.5 end - - gameEffects.ExplosiveSphereDamage(dmgowner, self, self:GetDmg(), pos, r_outer, r_inner, true) + + gameEffects.ExplosiveSphereDamage(dmgowner, self, self:GetDmg(), pos, r_outer, r_inner, true) local effect = EffectData() effect:SetStart(pos) diff --git a/lua/ttt2/libraries/game_effects.lua b/lua/ttt2/libraries/game_effects.lua index 2295971e0f..d3f90cb2b2 100644 --- a/lua/ttt2/libraries/game_effects.lua +++ b/lua/ttt2/libraries/game_effects.lua @@ -161,51 +161,51 @@ end -- @internal -- @realm server function gameEffects.ExplosiveSphereDamage(dmgowner, source, damage, origin, outerRadius, innerRadius, exponentialFalloff) - -- It seems intuitive to use FindInSphere here, but that will find all ents - -- in the radius, whereas there exist only ~16 players. Hence it is more - -- efficient to cycle through all those players and do a Lua-side distance - -- check. - - if outerRadius < innerRadius then - ErrorNoHalt("[Game Effects Explosive Sphere Damage] Outer radius too high! Setting both radi to outer radius.") - innerRadius = outerRadius - end - - -- pre-declare to avoid realloc - local d = 0.0 - local dFraction = 0.0 - local diff = nil - local dmg = 0 - local radiDiff = (outerRadius - innerRadius) - for _, ply in pairs(player.GetAll()) do - if IsValid(ply) and ply:Team() == TEAM_TERROR then - - diff = origin - ply:GetPos() - --we are using Length on purpose here. We would need a sqrt somewhere anyway and with this we dont need to square the radi - d = diff:Length() - --we now turn this into a % of damage based of the value of d - --100% from 0 to innerRadius - --100% to 0% from innerRadius to outerRadius - --<0% from outerRadius to infinity - dFraction = 1.0 - math.max((d - innerRadius) / radiDiff,0.0) - - --Next Iteration if we are outside the radius - if dFraction < 0.0 then - continue - end - - dmg = math.Round(damage * dFraction * ((exponentialFalloff and dFraction) or 1)) - - local dmginfo = DamageInfo() - dmginfo:SetDamage(dmg) - dmginfo:SetAttacker(dmgowner) - dmginfo:SetInflictor(source) - dmginfo:SetDamageType(DMG_BLAST) - dmginfo:SetDamageForce(diff) - dmginfo:SetDamagePosition(ply:GetPos()) - ply:TakeDamageInfo(dmginfo) - end - end + -- It seems intuitive to use FindInSphere here, but that will find all ents + -- in the radius, whereas there exist only ~16 players. Hence it is more + -- efficient to cycle through all those players and do a Lua-side distance + -- check. + + if outerRadius < innerRadius then + ErrorNoHalt("[Game Effects Explosive Sphere Damage] Outer radius too high! Setting both radi to outer radius.") + innerRadius = outerRadius + end + + -- pre-declare to avoid realloc + local d = 0.0 + local dFraction = 0.0 + local diff = nil + local dmg = 0 + local radiDiff = (outerRadius - innerRadius) + for _, ply in pairs(player.GetAll()) do + if IsValid(ply) and ply:Team() == TEAM_TERROR then + + diff = origin - ply:GetPos() + --we are using Length on purpose here. We would need a sqrt somewhere anyway and with this we dont need to square the radi + d = diff:Length() + --we now turn this into a % of damage based of the value of d + --100% from 0 to innerRadius + --100% to 0% from innerRadius to outerRadius + --<0% from outerRadius to infinity + dFraction = 1.0 - math.max((d - innerRadius) / radiDiff,0.0) + + --Next Iteration if we are outside the radius + if dFraction < 0.0 then + continue + end + + dmg = math.Round(damage * dFraction * ((exponentialFalloff and dFraction) or 1)) + + local dmginfo = DamageInfo() + dmginfo:SetDamage(dmg) + dmginfo:SetAttacker(dmgowner) + dmginfo:SetInflictor(source) + dmginfo:SetDamageType(DMG_BLAST) + dmginfo:SetDamageForce(diff) + dmginfo:SetDamagePosition(ply:GetPos()) + ply:TakeDamageInfo(dmginfo) + end + end end -- vFIRE INTEGRATION