Proof-of-concept "momentum shield"

This commit is contained in:
LostTrackpad 2024-07-18 21:34:43 +07:00
parent 7122778304
commit 7efc6edc00

View file

@ -6,8 +6,95 @@ else
end) end)
end end
local momentumshield = CreateConVar("Beatrun_MomentumShield", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE})
if SERVER then
local healthRegen = CreateConVar("Beatrun_HealthRegen", 1, {FCVAR_REPLICATED, FCVAR_ARCHIVE})
hook.Add("PlayerPostThink", "HealthRegen", function(ply)
if not healthRegen:GetBool() then return end
if not ply.LastHP then
ply.LastHP = ply:Health()
ply.RegenTime = 0
return
end
if ply:Health() < ply.LastHP then
ply.RegenTime = CurTime() + 5
end
if ply:Alive() and ply.RegenTime < CurTime() and ply:Health() < ply:GetMaxHealth() then
ply:SetHealth(math.Approach(ply:Health(), ply:GetMaxHealth(), 1))
ply.RegenTime = CurTime() + 0.05
end
ply.LastHP = ply:Health()
end)
for _,v in ipairs(player.GetAll()) do
v:SetNWFloat("MomentumShieldPer", 0)
end
hook.Add("Move", "MomentumShieldRegen", function(ply, mv)
-- I use the move hook because I need momentum data...blame Garry
--if !momentumshield:GetBool() then return end
local shieldpercent = ply:GetNWFloat("MomentumShieldPer", 0)
if !ply.shielddecaytime then
ply.shielddecaytime = 0
return
end
if ply:GetVelocity():Length2D() > (GetConVar("Beatrun_SpeedLimit"):GetInt() * 0.8181818181818182) then
ply:SetNWFloat("MomentumShieldPer", math.Approach(shieldpercent, 300, FrameTime() * 30))
ply.shielddecaytime = CurTime() + 3
elseif ply.shielddecaytime < CurTime() then
ply:SetNWFloat("MomentumShieldPer", math.Approach(shieldpercent, 0, FrameTime() * 250))
end
--print(shieldpercent)
end)
end
if CLIENT then
local lastmomshield = -1
local shieldlerptime = 0.16
local start, oldshield, newshield = 0, -1, -1
local hudscale = ScrH() / 1080
hook.Add("HUDPaint", "MomentumShieldHUD", function()
local ply = LocalPlayer()
if !IsValid(ply) then return end
local shieldpercent = ply:GetNWFloat("MomentumShieldPer", 0)
if oldshield == -1 and newshield == -1 then
oldshield = shieldpercent
newshield = shieldpercent
end
local shieldsmooth = Lerp((CurTime() - start) / shieldlerptime, oldshield, newshield)
if newshield != shieldpercent then
if shieldsmooth != shieldpercent then
newshield = shieldsmooth
end
oldshield = newshield
start = CurTime()
newshield = shieldpercent
end
surface.SetDrawColor(255,255,255)
surface.DrawRect(ScrW() * 0.5 - 75,ScrH() * 0.6,150 * (math.max(0, shieldsmooth) / 300) * hudscale, 3 * hudscale)
end)
end
hook.Add("ScalePlayerDamage", "MissedMe", function(ply, hitgroup, dmginfo) hook.Add("ScalePlayerDamage", "MissedMe", function(ply, hitgroup, dmginfo)
if IsValid(dmginfo:GetAttacker()) and dmginfo:GetAttacker():IsPlayer() then return end if IsValid(dmginfo:GetAttacker()) and dmginfo:GetAttacker():IsPlayer() or momentumshield:GetBool() then return end
local vel = ply:GetVelocity() local vel = ply:GetVelocity()
local vel_len = vel:Length() local vel_len = vel:Length()
@ -16,13 +103,27 @@ hook.Add("ScalePlayerDamage", "MissedMe", function(ply, hitgroup, dmginfo)
end) end)
hook.Add("EntityTakeDamage", "MissedMe", function(victim, dmginfo) hook.Add("EntityTakeDamage", "MissedMe", function(victim, dmginfo)
if not victim:IsPlayer() then return end if not victim:IsPlayer() or momentumshield:GetBool() then return end
local dmgtype = dmginfo:GetDamageType() local dmgtype = dmginfo:GetDamageType()
if victim:GetSliding() and (dmgtype == DMG_SLASH or dmgtype == DMG_CLUB) then return true end if victim:GetSliding() and (dmgtype == DMG_SLASH or dmgtype == DMG_CLUB) then return true end
end) end)
hook.Add("EntityTakeDamage", "ShieldProtectPlayer", function(ent, dmg)
if !ent:IsPlayer() or !momentumshield:GetBool() then return end
shieldper = ent:GetNWFloat("MomentumShieldPer", 0)
local dmgamount = dmg:GetDamage()
if shieldper > 0 and (shieldper - dmgamount) > 0 then
ent:SetNWFloat("MomentumShieldPer", math.Clamp(shieldper - dmgamount, 0, 300))
dmg:ScaleDamage(0)
elseif shieldper > 0 then
ent:SetNWFloat("MomentumShieldPer", math.Clamp(shieldper - dmgamount, 0, 300))
dmg:SetDamage(shieldper - dmgamount)
end
end)
hook.Add("PlayerShouldTakeDamage", "DBNO", function(ply, attacker) hook.Add("PlayerShouldTakeDamage", "DBNO", function(ply, attacker)
if not IsValid(attacker) then return end if not IsValid(attacker) then return end
@ -75,29 +176,3 @@ if CLIENT then
surface.DrawTexturedRect(0, 0, w, h) surface.DrawTexturedRect(0, 0, w, h)
end) end)
end end
if SERVER then
local healthRegen = CreateConVar("Beatrun_HealthRegen", 1, {FCVAR_REPLICATED, FCVAR_ARCHIVE})
hook.Add("PlayerPostThink", "HealthRegen", function(ply)
if not healthRegen:GetBool() then return end
if not ply.LastHP then
ply.LastHP = ply:Health()
ply.RegenTime = 0
return
end
if ply:Health() < ply.LastHP then
ply.RegenTime = CurTime() + 5
end
if ply:Alive() and ply.RegenTime < CurTime() and ply:Health() < ply:GetMaxHealth() then
ply:SetHealth(math.Approach(ply:Health(), ply:GetMaxHealth(), 1))
ply.RegenTime = CurTime() + 0.05
end
ply.LastHP = ply:Health()
end)
end