-----------------------------------------
-- MEDKIT_BACKPACK (MILITARY RP)
-- Собственность Олега Закона и Scripty
-----------------------------------------
AddCSLuaFile()

ENT.Type = "anim"
ENT.Base = "base_gmodentity"
ENT.Category = "Equipment"
ENT.PrintName = "BF2 Medikit"
ENT.Author = "V92"
ENT.Spawnable = true
ENT.AdminOnly = true

local DeployModel = Model("models/v92/bf2/weapons/handheld/medikit_w.mdl")
local HealSound   = Sound("BF2.Weapon.Handheld.Medikit.Pickup")
local AttachSound = Sound("items/ammo_pickup.wav")
local DetachSound = Sound("items/medshotno1.wav")

ENT.MaxUses    = 5
ENT.HealPerUse = 25

if CLIENT then
    function ENT:Draw()
        return
    end
    return
end

function ENT:Initialize()
    self:SetModel(DeployModel)
    self:SetNoDraw(false)
    self:PhysicsInit(SOLID_VPHYSICS)
    self:SetMoveType(MOVETYPE_VPHYSICS)
    self:SetSolid(SOLID_VPHYSICS)
    self:SetCollisionGroup(COLLISION_GROUP_WEAPON)

    local phys = self:GetPhysicsObject()
    if IsValid(phys) then
        phys:Wake()
        phys:SetMass(5)
    end

    self.AttachedPlayer   = nil
    self.AttachmentBone   = "ValveBiped.Bip01_Spine2"
    self.IsAttached       = false
    self.HasInfiniteCharge = false
    self.RemoveTimer      = nil

    self.CurrentUses = self.MaxUses

    self:SetNWBool("V92_Medikit_IsAttached", false)
    self:SetNWEntity("V92_Medikit_AttachedPlayer", NULL)

    util.PrecacheModel(DeployModel)
    util.PrecacheSound(HealSound)
    util.PrecacheSound(AttachSound)
    util.PrecacheSound(DetachSound)

    self.RemoveTimer = timer.Simple(300, function()
        if IsValid(self) and not self.IsAttached then
            SafeRemoveEntity(self)
        end
    end)
end

function ENT:AttachToPlayer(ply)
    if not IsValid(ply) or not ply:IsPlayer() then return false end

    for _, ent in ipairs(ents.FindByClass("v92_bf2_medikit_ent")) do
        if ent ~= self and IsValid(ent) and ent.IsAttached
        and IsValid(ent.AttachedPlayer) and ent.AttachedPlayer == ply then
            ent:DetachFromPlayer()
        end
    end

    self.AttachedPlayer    = ply
    self.IsAttached        = true
    self.HasInfiniteCharge = true

    self:SetNWBool("V92_Medikit_IsAttached", true)
    self:SetNWEntity("V92_Medikit_AttachedPlayer", ply)

    if self.RemoveTimer then
        timer.Remove(self.RemoveTimer)
        self.RemoveTimer = nil
    end
    self:SetModel("")
    self:SetMoveType(MOVETYPE_NONE)
    self:SetSolid(SOLID_NONE)
    self:SetCollisionGroup(COLLISION_GROUP_IN_VEHICLE)
    self:SetNoDraw(true)
    ply:EmitSound(AttachSound)
    self:SetOwner(ply)

    return true
end

function ENT:DetachFromPlayer()
    if not self.IsAttached then return end

    self:SetNWBool("V92_Medikit_IsAttached", false)
    self:SetNWEntity("V92_Medikit_AttachedPlayer", NULL)

    if IsValid(self.AttachedPlayer) then
        self.AttachedPlayer:EmitSound(DetachSound)
    end

    self.HasInfiniteCharge = false

    timer.Simple(0.05, function()
        if IsValid(self) then
            self:SetModel(DeployModel)
            self:SetNoDraw(false)
            self:PhysicsInit(SOLID_VPHYSICS)
            self:SetMoveType(MOVETYPE_VPHYSICS)
            self:SetSolid(SOLID_VPHYSICS)
            self:SetCollisionGroup(COLLISION_GROUP_WEAPON)

            timer.Simple(0, function()
                if not IsValid(deployEnt) then return end

                local phys = deployEnt:GetPhysicsObject()
                if IsValid(phys) then
                    phys:Wake()
                    phys:SetMass(5)
                    phys:SetVelocity(owner:GetAimVector() * (owner:KeyDown(IN_USE) and 50 or 400))
                end
            end)

            self.RemoveTimer = timer.Simple(300, function()
                if IsValid(self) then
                    SafeRemoveEntity(self)
                end
            end)
        end
    end)

    self.IsAttached     = false
    self.AttachedPlayer = nil
end

function ENT:Use(activator, caller, useType, value)
    if not IsValid(self) then return end
    if not IsValid(activator) or not activator:IsPlayer() then return end

    if self.IsAttached and IsValid(self.AttachedPlayer) then
        local need = math.min(activator:GetMaxHealth() - activator:Health(), self.HealPerUse)
        if need > 0 then
            activator:SetHealth(math.min(activator:GetMaxHealth(), activator:Health() + need))
            activator:EmitSound(HealSound)
        end
    end
end

function ENT:StartTouch(toucher)
    if not IsValid(self) then return end
    if not (toucher:IsPlayer() or toucher:IsNPC()) or toucher:Health() >= toucher:GetMaxHealth() then
        return false
    end

    if toucher:Health() < toucher:GetMaxHealth() then
        local need = math.min(toucher:GetMaxHealth() - toucher:Health(), self.HealPerUse)

        if need > 0 then
            if not (self.IsAttached and self.HasInfiniteCharge) then
                self.CurrentUses = self.CurrentUses - 1
            end

            toucher:SetHealth(math.min(toucher:GetMaxHealth(), toucher:Health() + need))
            toucher:EmitSound(HealSound)

            if self.CurrentUses <= 0 and not (self.IsAttached and self.HasInfiniteCharge) then
                self:Remove()
            end
        end
    end

    return
end

function ENT:OnRemove()
    if self.RemoveTimer then
        timer.Remove(self.RemoveTimer)
        self.RemoveTimer = nil
    end

    if self.IsAttached then
        self.IsAttached = false
        self.AttachedPlayer = nil
    end
end

function ENT:Think()
    if self.IsAttached and (not IsValid(self.AttachedPlayer) or not self.AttachedPlayer:Alive()) then
        self:DetachFromPlayer()
    end

    self:NextThink(CurTime() + 0.5)
    return true
end

hook.Add("PlayerDeath", "V92_Medikit_PlayerDeath", function(victim)
    for _, ent in ipairs(ents.FindByClass("v92_bf2_medikit_ent")) do
        if IsValid(ent) and ent.IsAttached and IsValid(ent.AttachedPlayer)
        and ent.AttachedPlayer == victim then
            ent:DetachFromPlayer()
        end
    end
end)

hook.Add("PlayerDisconnected", "V92_Medikit_PlayerDisconnected", function(ply)
    for _, ent in ipairs(ents.FindByClass("v92_bf2_medikit_ent")) do
        if IsValid(ent) and ent.IsAttached and IsValid(ent.AttachedPlayer)
        and ent.AttachedPlayer == ply then
            ent:DetachFromPlayer()
        end
    end
end)

hook.Add("KeyPress", "V92_Medikit_TreatFromPlayer", function(ply, key)
    if key ~= IN_USE then return end
    if not IsValid(ply) or not ply:Alive() then return end

    local trace = ply:GetEyeTrace()
    if not IsValid(trace.Entity) then return end

    local target = trace.Entity

    if IsValid(target) and target:IsPlayer() and target:Alive() and target ~= ply then
        for _, medikit in ipairs(ents.FindByClass("v92_bf2_medikit_ent")) do
            if IsValid(medikit) and medikit.IsAttached
            and IsValid(medikit.AttachedPlayer) and medikit.AttachedPlayer == target then

                local need = math.min(ply:GetMaxHealth() - ply:Health(), 25)

                if need > 0 then
                    ply:SetHealth(math.min(ply:GetMaxHealth(), ply:Health() + need))
                    ply:EmitSound(HealSound)
                end

                break
            end
        end
    end
end)
-----------------------------------------
-- MEDKIT_BACKPACK (MILITARY RP)
-- Собственность Олега Закона и Scripty
-----------------------------------------
