zombiesurvival-evolved/gamemodes/zombiesurvival/entities/effects/dismemberment.lua

139 lines
5.3 KiB
Lua
Raw Permalink Normal View History

2014-10-02 08:49:54 +08:00
function EFFECT:Init(data)
self.eEnt = data:GetEntity()
self.iScale = math.Round(data:GetScale())
self.DieTime = CurTime() + 3
end
local Dismembers = {DISMEMBER_HEAD, DISMEMBER_LEFTLEG, DISMEMBER_RIGHTLEG, DISMEMBER_LEFTARM, DISMEMBER_RIGHTARM}
local DismemberBones = {
{ToZero = {"ValveBiped.Bip01_Head1"}, ToBleed = {["ValveBiped.Bip01_Head1"] = true}},
{ToZero = {"ValveBiped.Bip01_L_Thigh", "ValveBiped.Bip01_L_Calf", "ValveBiped.Bip01_L_Foot"}, ToBleed = {["ValveBiped.Bip01_L_Thigh"]=true}},
{ToZero = {"ValveBiped.Bip01_R_Thigh", "ValveBiped.Bip01_R_Calf", "ValveBiped.Bip01_R_Foot"}, ToBleed = {["ValveBiped.Bip01_R_Thigh"]=true}},
{ToZero = {"ValveBiped.Bip01_L_UpperArm", "ValveBiped.Bip01_L_Forearm", "ValveBiped.Bip01_L_Hand"}, ToBleed = {["ValveBiped.Bip01_L_UpperArm"]=true}},
{ToZero = {"ValveBiped.Bip01_R_UpperArm", "ValveBiped.Bip01_R_Forearm", "ValveBiped.Bip01_R_Hand"}, ToBleed = {["ValveBiped.Bip01_R_UpperArm"]=true}}
}
local BoneTranslates = {}
BoneTranslates["models/zombie/classic.mdl"] = {["ValveBiped.Bip01_Head1"]="ValveBiped.Bip01_Spine2"}
BoneTranslates["models/zombie/poison.mdl"] = {["ValveBiped.Bip01_Head1"]="ValveBiped.Bip01_Spine4"}
BoneTranslates["models/zombie/fast.mdl"] = {["ValveBiped.Bip01_Head1"]="ValveBiped.HC_BodyCube"}
BoneTranslates["models/player/zombie_classic.mdl"] = {["ValveBiped.Bip01_Head1"]="ValveBiped.Bip01_Spine4"}
BoneTranslates["models/player/zombie_classic_hbfix.mdl"] = {["ValveBiped.Bip01_Head1"]="ValveBiped.Bip01_Spine4"}
2014-10-02 08:49:54 +08:00
local function CollideCallback(particle, hitpos, hitnormal)
if particle:GetDieTime() == 0 then return end
particle:SetDieTime(0)
if math.random(6) == 1 then
sound.Play("physics/flesh/flesh_bloody_impact_hard1.wav", hitpos, 50, math.random(95, 105))
end
util.Decal("Impact.Flesh", hitpos + hitnormal, hitpos - hitnormal)
end
function EFFECT:Think()
local eEnt = self.eEnt
if not self.SetDoll and eEnt:IsValid() and eEnt:IsPlayer() then
local eRag = eEnt:GetRagdollEntity()
if eRag and eRag:IsValid() then
self.SetDoll = true
self.eRagdoll = eRag
eRag.Dismemberment = bit.bor((eRag.Dismemberment or 0), self.iScale)
self.DieTime = CurTime() + math.Rand(5, 7)
eRag.NextEmit = 0
self.Entity:SetRenderBounds(Vector(-128, -128, -128), Vector(128, 128, 128))
end
end
if self.eRagdoll and self.eRagdoll:IsValid() then
self.Entity:SetPos(self.eRagdoll:GetPos())
end
return CurTime() < self.DieTime
end
function EFFECT:Render()
local eRagdoll = self.eRagdoll
local fCurTime = CurTime()
if eRagdoll and eRagdoll:IsValid() and eRagdoll.NextEmit <= fCurTime then
eRagdoll.NextEmit = fCurTime + 0.05
local emitter = ParticleEmitter(eRagdoll:GetPos())
emitter:SetNearClip(20, 30)
local iDismemberment = eRagdoll.Dismemberment or 0
for index, iDismemberPart in pairs(Dismembers) do
if bit.band(iDismemberPart, iDismemberment) == iDismemberPart then
for _, sZeroBone in pairs(DismemberBones[index].ToZero) do
local mdl = string.lower(eRagdoll:GetModel())
if BoneTranslates[mdl] and BoneTranslates[mdl][sZeroBone] then
sZeroBone = BoneTranslates[mdl][sZeroBone]
end
local iBone = eRagdoll:LookupBone(sZeroBone)
if iBone and iBone > 0 then
eRagdoll:ManipulateBoneScale(iBone, vector_tiny)
end
end
for sZeroBone in pairs(DismemberBones[index].ToBleed) do
local mdl = string.lower(eRagdoll:GetModel())
if BoneTranslates[mdl] and BoneTranslates[mdl][sZeroBone] then
sZeroBone = BoneTranslates[mdl][sZeroBone]
end
local iBone = eRagdoll:LookupBone(sZeroBone)
if iBone and iBone > 0 then
local delta = math.max(0, self.DieTime - fCurTime)
if 0 < delta then
local vBonePos, aBoneAng = eRagdoll:GetBonePosition(iBone)
if vBonePos and aBoneAng then
emitter:SetPos(vBonePos)
local vForward = aBoneAng:Forward()
for i=1, math.random(0, 2) do
local particle = emitter:Add("!sprite_bloodspray"..math.random(8), vBonePos)
2014-10-02 08:49:54 +08:00
local force = math.min(1.5, delta) * math.Rand(175, 300)
particle:SetVelocity(force * vForward + 0.2 * force * VectorRand())
particle:SetDieTime(math.Rand(2.25, 3))
particle:SetStartAlpha(240)
particle:SetEndAlpha(0)
particle:SetStartSize(math.random(1, 8))
particle:SetEndSize(0)
particle:SetRoll(math.Rand(0, 360))
particle:SetRollDelta(math.Rand(-40, 40))
particle:SetColor(255, 0, 0)
particle:SetAirResistance(5)
particle:SetBounce(0)
particle:SetGravity(Vector(0, 0, -600))
particle:SetCollide(true)
particle:SetCollideCallback(CollideCallback)
particle:SetLighting(true)
end
local particle = emitter:Add("!sprite_bloodspray"..math.random(8), vBonePos)
2014-10-02 08:49:54 +08:00
local vel = eRagdoll:GetVelocity()
particle:SetVelocity(vel)
particle:SetDieTime(math.Rand(0.5, 0.75))
particle:SetStartAlpha(240)
particle:SetEndAlpha(0)
particle:SetStartSize(math.random(6, 12))
particle:SetEndSize(0)
particle:SetRoll(math.Rand(0, 360))
local vellength = vel:Length() * 0.45
particle:SetRollDelta(math.Rand(-vellength, vellength))
particle:SetColor(255, 0, 0)
particle:SetAirResistance(20)
particle:SetLighting(true)
end
end
end
end
end
end
emitter:Finish() emitter = nil collectgarbage("step", 64)
2014-10-02 08:49:54 +08:00
end
end