Files
wnsrc/gamemodes/terrortown/entities/entities/base_ammo_ttt.lua
lifestorm c6d9b6f580 Upload
2024-08-05 18:40:29 +03:00

132 lines
3.7 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/
--]]
-- Ammo override base
AddCSLuaFile()
ENT.Type = "anim"
-- Override these values
ENT.AmmoType = "Pistol"
ENT.AmmoAmount = 1
ENT.AmmoMax = 10
ENT.AmmoEntMax = 1
ENT.Model = Model( "models/items/boxsrounds.mdl" )
function ENT:RealInit() end -- bw compat
-- Some subclasses want to do stuff before/after initing (eg. setting color)
-- Using self.BaseClass gave weird problems, so stuff has been moved into a fn
-- Subclasses can easily call this whenever they want to
function ENT:Initialize()
self:SetModel( self.Model )
self:PhysicsInit( SOLID_VPHYSICS )
self:SetMoveType( MOVETYPE_VPHYSICS )
self:AddSolidFlags( FSOLID_TRIGGER )
self:SetCollisionGroup( COLLISION_GROUP_WEAPON )
self:UseTriggerBounds( true, 24 )
self.tickRemoval = false
-- this made the ammo get physics'd too early, meaning it would fall
-- through physics surfaces it was lying on on the client, leading to
-- inconsistencies
-- local phys = self:GetPhysicsObject()
-- if (phys:IsValid()) then
-- phys:Wake()
-- end
self.AmmoEntMax = self.AmmoAmount
end
-- Pseudo-clone of SDK's UTIL_ItemCanBeTouchedByPlayer
-- aims to prevent picking stuff up through fences and stuff
function ENT:PlayerCanPickup(ply)
if ply == self:GetOwner() then return false end
local result = hook.Call("TTTCanPickupAmmo", nil, ply, self)
if result != nil then
return result
end
local ent = self
local phys = ent:GetPhysicsObject()
local spos = phys:IsValid() and phys:GetPos() or ent:OBBCenter()
local epos = ply:GetShootPos() -- equiv to EyePos in SDK
local tr = util.TraceLine({start=spos, endpos=epos, filter={ply, ent}, mask=MASK_SOLID})
-- can pickup if trace was not stopped
return tr.Fraction == 1.0
end
function ENT:CheckForWeapon(ply)
if not self.CachedWeapons then
-- create a cache of what weapon classes use this ammo
local tbl = {}
for k,v in pairs(weapons.GetList()) do
if v and v.AmmoEnt == self:GetClass() then
table.insert(tbl, WEPS.GetClass(v))
end
end
self.CachedWeapons = tbl
end
-- Check if player has a weapon that we know needs us. This is called in
-- Touch, which is called many a time, so we use the cache here to avoid
-- looping through every weapon the player has to check their AmmoEnt.
for _, w in ipairs(self.CachedWeapons) do
if ply:HasWeapon(w) then return true end
end
return false
end
function ENT:Touch(ent)
if (SERVER and self.tickRemoval ~= true) and ent:IsValid() and ent:IsPlayer() and self:CheckForWeapon(ent) and self:PlayerCanPickup(ent) then
local ammo = ent:GetAmmoCount(self.AmmoType)
-- need clipmax info and room for at least 1/4th
if self.AmmoMax >= (ammo + math.ceil(self.AmmoAmount * 0.25)) then
local given = self.AmmoAmount
given = math.min(given, self.AmmoMax - ammo)
ent:GiveAmmo(given, self.AmmoType)
local newEntAmount = self.AmmoAmount - given
self.AmmoAmount = newEntAmount
if self.AmmoAmount <= 0 or math.ceil(self.AmmoEntMax * 0.25) > self.AmmoAmount then
self.tickRemoval = true
self:Remove()
end
end
end
end
-- Hack to force ammo to physwake
if SERVER then
function ENT:Think()
if not self.first_think then
self:PhysWake()
self.first_think = true
-- Immediately unhook the Think, save cycles. The first_think thing is
-- just there in case it still Thinks somehow in the future.
self.Think = nil
end
end
end