mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
110
lua/arccw/server/sv_doors.lua
Normal file
110
lua/arccw/server/sv_doors.lua
Normal file
@@ -0,0 +1,110 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
if CLIENT then return end
|
||||
|
||||
function ArcCW.DoorBust(ent, vel)
|
||||
local cvar = ArcCW.ConVars["doorbust"]:GetInt()
|
||||
local t = ArcCW.ConVars["doorbust_time"]:GetFloat()
|
||||
if cvar == 0 or ent.ArcCW_DoorBusted then return end
|
||||
ent.ArcCW_DoorBusted = true
|
||||
|
||||
local oldSpeed = ent:GetInternalVariable("m_flSpeed")
|
||||
ent:Fire("SetSpeed", tostring(oldSpeed * 5), 0)
|
||||
ent:Fire("Open", "", 0)
|
||||
ent:Fire("SetSpeed", oldSpeed, 0.3)
|
||||
|
||||
if ent:GetPhysicsObject():IsValid() and cvar == 1 then
|
||||
|
||||
-- Don't remove the door, that's a silly thing to do
|
||||
ent.ArcCW_DoorOldPos = ent:GetPos()
|
||||
ent:SetNoDraw(true)
|
||||
ent:SetNotSolid(true)
|
||||
|
||||
-- Make a busted door prop and fling it
|
||||
local prop = ents.Create("prop_physics")
|
||||
prop:SetModel(ent:GetModel())
|
||||
prop:SetPos(ent:GetPos())
|
||||
prop:SetAngles(ent:GetAngles())
|
||||
prop:SetSkin(ent:GetSkin())
|
||||
prop:Spawn()
|
||||
prop:GetPhysicsObject():SetVelocity(vel)
|
||||
|
||||
ent:SetPos(ent:GetPos() - Vector(0, 0, 10000))
|
||||
|
||||
-- Make it not collide with players after a bit cause that's annoying
|
||||
timer.Create("ArcCW_DoorBust_" .. prop:EntIndex(), 2, 1, function()
|
||||
if IsValid(prop) then
|
||||
prop:SetCollisionGroup(COLLISION_GROUP_WEAPON)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Reset it after a while
|
||||
SafeRemoveEntityDelayed(prop, t)
|
||||
timer.Create("ArcCW_DoorBust_" .. ent:EntIndex(), t, 1, function()
|
||||
if IsValid(ent) then
|
||||
ent:SetNoDraw(false)
|
||||
ent:SetNotSolid(false)
|
||||
ent.ArcCW_DoorBusted = false
|
||||
ent:SetPos(ent.ArcCW_DoorOldPos)
|
||||
ent.ArcCW_DoorOldPos = nil
|
||||
end
|
||||
end)
|
||||
else
|
||||
timer.Create("ArcCW_DoorBust_" .. ent:EntIndex(), 0.5, 1, function()
|
||||
if IsValid(ent) then
|
||||
ent.ArcCW_DoorBusted = false
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ArcCW.TryBustDoor(ent, dmginfo)
|
||||
if ArcCW.ConVars["doorbust"]:GetInt() == 0 or !IsValid(ent) or !string.find(ent:GetClass(), "door") then return end
|
||||
local wep = IsValid(dmginfo:GetAttacker()) and ((dmginfo:GetInflictor():IsWeapon() and dmginfo:GetInflictor()) or dmginfo:GetAttacker():GetActiveWeapon())
|
||||
if !wep or !wep:IsWeapon() or !wep.ArcCW or !dmginfo:IsDamageType(DMG_BUCKSHOT) then return end
|
||||
if ent:GetNoDraw() or ent.ArcCW_NoBust or ent.ArcCW_DoorBusted then return end
|
||||
|
||||
--- TTT may choose for some doors to not be openable by a crowbar, let's respect that
|
||||
if GAMEMODE.crowbar_unlocks and GAMEMODE.crowbar_unlocks[ent] != true then return end
|
||||
|
||||
-- Magic number: 119.506 is the size of door01_left
|
||||
-- The bigger the door is, the harder it is to bust
|
||||
local threshold = ArcCW.ConVars["doorbust_threshold"]:GetInt() * math.pow((ent:OBBMaxs() - ent:OBBMins()):Length() / 119.506, 2)
|
||||
|
||||
-- Because shotgun damage is done per pellet, we must count them together
|
||||
if ent.ArcCW_BustCurTime and (ent.ArcCW_BustCurTime + 0.1 < CurTime()) then
|
||||
ent.ArcCW_BustCurTime = nil
|
||||
ent.ArcCW_BustDamage = 0
|
||||
end
|
||||
if dmginfo:GetDamage() < (threshold - (ent.ArcCW_BustDamage or 0)) then
|
||||
ent.ArcCW_BustCurTime = ent.ArcCW_BustCurTime or CurTime()
|
||||
ent.ArcCW_BustDamage = (ent.ArcCW_BustDamage or 0) + dmginfo:GetDamage()
|
||||
return
|
||||
else
|
||||
ent.ArcCW_BustCurTime = nil
|
||||
ent.ArcCW_BustDamage = nil
|
||||
end
|
||||
ArcCW.DoorBust(ent, dmginfo:GetDamageForce() * 0.5)
|
||||
-- Double doors are usually linked to the same areaportal. We must destroy the second half of the double door no matter what
|
||||
for _, otherDoor in pairs(ents.FindInSphere(ent:GetPos(), 64)) do
|
||||
if ent != otherDoor and otherDoor:GetClass() == ent:GetClass() and !otherDoor:GetNoDraw() then
|
||||
ArcCW.DoorBust(otherDoor, dmginfo:GetDamageForce() * 0.5)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("PlayerUse", "ArcCW_DoorBust", function(ply, ent)
|
||||
if ent.ArcCW_DoorBusted then return false end
|
||||
end)
|
||||
|
||||
-- This hook is not called on brush doors. Let's call this, uhh, intended behavior.
|
||||
-- hook.Add("EntityTakeDamage", "ArcCW_DoorBust", ArcCW.TryBustDoor)
|
||||
Reference in New Issue
Block a user