mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
110 lines
4.3 KiB
Lua
110 lines
4.3 KiB
Lua
--[[
|
|
| 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) |