219 lines
5.8 KiB
Lua
219 lines
5.8 KiB
Lua
AddCSLuaFile("cl_init.lua")
|
|
AddCSLuaFile("shared.lua")
|
|
|
|
include("shared.lua")
|
|
|
|
ENT.LastHitSomething = 0
|
|
|
|
local function RefreshTurretOwners(pl)
|
|
for _, ent in pairs(ents.FindByClass("prop_gunturret")) do
|
|
if ent:IsValid() and ent:GetObjectOwner() == pl then
|
|
ent:ClearObjectOwner()
|
|
ent:ClearTarget()
|
|
end
|
|
end
|
|
end
|
|
hook.Add("PlayerDisconnected", "GunTurret.PlayerDisconnected", RefreshTurretOwners)
|
|
hook.Add("OnPlayerChangedTeam", "GunTurret.OnPlayerChangedTeam", RefreshTurretOwners)
|
|
|
|
function ENT:Initialize()
|
|
self:SetModel("models/Combine_turrets/Floor_turret.mdl")
|
|
self:PhysicsInit(SOLID_VPHYSICS)
|
|
|
|
self:SetUseType(SIMPLE_USE)
|
|
|
|
local phys = self:GetPhysicsObject()
|
|
if phys:IsValid() then
|
|
phys:SetMass(50)
|
|
phys:EnableMotion(false)
|
|
phys:Wake()
|
|
end
|
|
|
|
self:SetAmmo(self.DefaultAmmo)
|
|
self:SetMaxObjectHealth(250)
|
|
self:SetObjectHealth(self:GetMaxObjectHealth())
|
|
end
|
|
|
|
function ENT:SetObjectHealth(health)
|
|
self:SetDTFloat(3, health)
|
|
if health <= 0 and not self.Destroyed then
|
|
self.Destroyed = true
|
|
|
|
local pos = self:LocalToWorld(self:OBBCenter())
|
|
|
|
local effectdata = EffectData()
|
|
effectdata:SetOrigin(pos)
|
|
util.Effect("Explosion", effectdata, true, true)
|
|
|
|
local amount = math.ceil(self:GetAmmo() * 0.5)
|
|
while amount > 0 do
|
|
local todrop = math.min(amount, 50)
|
|
amount = amount - todrop
|
|
local ent = ents.Create("prop_ammo")
|
|
if ent:IsValid() then
|
|
local heading = VectorRand():GetNormalized()
|
|
ent:SetAmmoType("smg1")
|
|
ent:SetAmmo(todrop)
|
|
ent:SetPos(pos + heading * 8)
|
|
ent:SetAngles(VectorRand():Angle())
|
|
ent:Spawn()
|
|
|
|
local phys = ent:GetPhysicsObject()
|
|
if phys:IsValid() then
|
|
phys:ApplyForceOffset(heading * math.Rand(8000, 32000), pos)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local tempknockback
|
|
function ENT:StartBulletKnockback()
|
|
tempknockback = {}
|
|
end
|
|
|
|
function ENT:EndBulletKnockback()
|
|
tempknockback = nil
|
|
end
|
|
|
|
function ENT:DoBulletKnockback(scale)
|
|
for ent, prevvel in pairs(tempknockback) do
|
|
local curvel = ent:GetVelocity()
|
|
ent:SetVelocity(curvel * -1 + (curvel - prevvel) * scale + prevvel)
|
|
end
|
|
end
|
|
|
|
local function BulletCallback(attacker, tr, dmginfo)
|
|
local ent = tr.Entity
|
|
if ent:IsValid() then
|
|
if ent:IsPlayer() then
|
|
if ent:Team() == TEAM_UNDEAD and tempknockback then
|
|
if attacker:GetTarget() == ent then
|
|
attacker.LastHitSomething = CurTime()
|
|
end
|
|
tempknockback[ent] = ent:GetVelocity()
|
|
end
|
|
else
|
|
local phys = ent:GetPhysicsObject()
|
|
if ent:GetMoveType() == MOVETYPE_VPHYSICS and phys:IsValid() and phys:IsMoveable() then
|
|
ent:SetPhysicsAttacker(attacker)
|
|
end
|
|
end
|
|
|
|
dmginfo:SetAttacker(attacker:GetObjectOwner())
|
|
dmginfo:SetInflictor(attacker)
|
|
end
|
|
end
|
|
|
|
function ENT:FireTurret(src, dir)
|
|
if self:GetNextFire() <= CurTime() then
|
|
local curammo = self:GetAmmo()
|
|
if curammo > 0 then
|
|
self:SetNextFire(CurTime() + 0.1)
|
|
self:SetAmmo(curammo - 1)
|
|
|
|
self:StartBulletKnockback()
|
|
self:FireBullets({Num = 1, Src = src, Dir = dir, Spread = Vector(0.05, 0.05, 0), Tracer = 1, Force = 1, Damage = 12, Callback = BulletCallback})
|
|
self:DoBulletKnockback(0.04)
|
|
self:EndBulletKnockback()
|
|
else
|
|
self:SetNextFire(CurTime() + 2)
|
|
self:EmitSound("npc/turret_floor/die.wav")
|
|
end
|
|
end
|
|
end
|
|
|
|
function ENT:Think()
|
|
if self.Destroyed then
|
|
self:Remove()
|
|
return
|
|
end
|
|
|
|
self:CalculatePoseAngles()
|
|
|
|
local owner = self:GetObjectOwner()
|
|
if owner:IsValid() and self:GetAmmo() > 0 and self:GetMaterial() == "" then
|
|
if self:GetManualControl() then
|
|
if owner:KeyDown(IN_ATTACK) then
|
|
if not self:IsFiring() then self:SetFiring(true) end
|
|
self:FireTurret(self:ShootPos(), self:GetGunAngles():Forward())
|
|
elseif self:IsFiring() then
|
|
self:SetFiring(false)
|
|
end
|
|
|
|
local target = self:GetTarget()
|
|
if target:IsValid() then self:ClearTarget() end
|
|
else
|
|
if self:IsFiring() then self:SetFiring(false) end
|
|
local target = self:GetTarget()
|
|
if target:IsValid() then
|
|
if self:IsValidTarget(target) and CurTime() < self.LastHitSomething + 0.5 then
|
|
local shootpos = self:ShootPos()
|
|
self:FireTurret(shootpos, (self:GetTargetPos(target) - shootpos):GetNormalized())
|
|
else
|
|
self:ClearTarget()
|
|
self:EmitSound("npc/turret_floor/deploy.wav")
|
|
end
|
|
else
|
|
local target = self:SearchForTarget()
|
|
if target then
|
|
self:SetTarget(target)
|
|
self:SetTargetReceived(CurTime())
|
|
self:EmitSound("npc/turret_floor/active.wav")
|
|
end
|
|
end
|
|
end
|
|
elseif self:IsFiring() then
|
|
self:SetFiring(false)
|
|
end
|
|
|
|
self:NextThink(CurTime())
|
|
return true
|
|
end
|
|
|
|
function ENT:Use(activator, caller)
|
|
if self.Removing or not activator:IsPlayer() or self:GetMaterial() ~= "" then return end
|
|
|
|
if activator:Team() == TEAM_HUMAN then
|
|
if self:GetObjectOwner():IsValid() then
|
|
local curammo = self:GetAmmo()
|
|
local togive = math.min(math.min(15, activator:GetAmmoCount("smg1")), self.MaxAmmo - curammo)
|
|
if togive > 0 then
|
|
self:SetAmmo(curammo + togive)
|
|
activator:RemoveAmmo(togive, "smg1")
|
|
activator:RestartGesture(ACT_GMOD_GESTURE_ITEM_GIVE)
|
|
self:EmitSound("npc/turret_floor/click1.wav")
|
|
--gamemode.Call("PlayerRepairedObject", activator, self, togive * 1.5, self)
|
|
end
|
|
else
|
|
self:SetObjectOwner(activator)
|
|
if not activator:HasWeapon("weapon_zs_gunturretcontrol") then
|
|
activator:Give("weapon_zs_gunturretcontrol")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function ENT:AltUse(activator, tr)
|
|
self:PackUp(activator)
|
|
end
|
|
|
|
function ENT:OnPackedUp(pl)
|
|
pl:GiveEmptyWeapon("weapon_zs_gunturret")
|
|
pl:GiveAmmo(1, "thumper")
|
|
|
|
pl:PushPackedItem(self:GetClass(), self:GetObjectHealth())
|
|
pl:GiveAmmo(self:GetAmmo(), "smg1")
|
|
|
|
self:Remove()
|
|
end
|
|
|
|
function ENT:OnTakeDamage(dmginfo)
|
|
self:TakePhysicsDamage(dmginfo)
|
|
|
|
local attacker = dmginfo:GetAttacker()
|
|
if not (attacker:IsValid() and attacker:IsPlayer() and attacker:Team() == TEAM_HUMAN) then
|
|
self:ResetLastBarricadeAttacker(attacker, dmginfo)
|
|
self:SetObjectHealth(self:GetObjectHealth() - dmginfo:GetDamage())
|
|
end
|
|
end
|