Files
2026-03-31 10:27:04 +03:00

211 lines
5.7 KiB
Lua

if SERVER then
AddCSLuaFile( "shared.lua" )
end
if CLIENT then
if (file.Exists("materials/hud/rope_knife.vmt","GAME")) then
SWEP.WepSelectIcon = surface.GetTextureID("hud/rope_knife")
end
SWEP.ViewModelFOV = 70
SWEP.ViewModelFlip = false
SWEP.BobScale = 1.5
SWEP.SwayScale = 1.5
SWEP.PrintName = "Grappling Knife"
SWEP.Slot = 0
SWEP.Slotpos = 0
SWEP.BounceWeaponIcon = false
SWEP.DrawWeaponInfoBox = true
end
SWEP.HoldType = "melee"
SWEP.Author = "Krede"
SWEP.Contact = "Through Steam"
SWEP.Instructions = "Use it to easily climb up buildings and high places"
SWEP.Category = "Krede's SWEPs"
SWEP.ViewModel = "models/props_c17/TrapPropeller_Lever.mdl"
SWEP.WorldModel = "models/props_c17/TrapPropeller_Lever.mdl"
SWEP.UseHands = true
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.DrawCrosshair = false
SWEP.Spawnable = true
SWEP.AdminSpawnable = true
function SWEP:GetViewModelPosition( pos, ang )
pos = pos + ang:Right() * 8
pos = pos + ang:Forward() * 12
pos = pos - ang:Up() * 5
ang:RotateAroundAxis(ang:Up(), 90)
ang:RotateAroundAxis(ang:Right(), -10)
ang:RotateAroundAxis(ang:Forward(), -10)
return pos, ang
end
function SWEP:SecondaryAttack()
return false
end
function SWEP:Think()
end
function SWEP:PrimaryAttack()
self.Weapon:SendWeaponAnim( ACT_VM_SECONDARYATTACK )
self.Owner:DoAnimationEvent(ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE)
self.Weapon:SetNextPrimaryFire( CurTime() + 2 )
if CLIENT then return end
timer.Simple(0.2, function()
self:EmitSound("weapons/iceaxe/iceaxe_swing1.wav")
if self == NULL or !IsValid(self) then return false end
local ent = ents.Create("sent_rope_knife")
ent:SetNWEntity("Owner", self.Owner)
ent:SetPos (self.Owner:EyePos() + (self.Owner:GetAimVector() * 48))
ent:SetAngles(self.Owner:EyeAngles() + Angle(90,0,0))
ent:Spawn()
local phys = ent:GetPhysicsObject()
if IsValid(phys) then
phys:ApplyForceCenter(self.Owner:GetAimVector()*7500)
phys:AddAngleVelocity(Vector(0,10000,0))
phys:EnableGravity(false)
end
undo.Create( "Grappling Knife" )
undo.AddEntity( ent )
undo.SetPlayer( self.Owner )
undo.Finish()
-- Single use: remove the weapon
if IsValid(self.Owner) then
self:Remove()
end
end)
end
function SWEP:OnRemove()
end
function SWEP:Reload()
return false
end
function SWEP:Holster()
return true
end
function SWEP:Deploy()
self.Weapon:SendWeaponAnim( ACT_VM_DRAW )
end
function SWEP:Initialize()
self.Weapon:SetWeaponHoldType( self.HoldType )
end
if CLIENT then
surface.CreateFont("RopeKnifeCrosshair", {
font = "Roboto",
size = 18,
weight = 800,
antialias = true,
shadow = true
})
end
function SWEP:DrawHUD()
if not IsValid(self.Owner) then return end
local tr = self.Owner:GetEyeTrace()
local pos = tr.HitPos
local ent = tr.Entity
local vel = LocalPlayer():GetVelocity():Length()
local movement = math.Clamp(vel / 20, 0, 40)
local time = CurTime()
if IsValid(self.Owner:GetNWEntity("ClimbingEnt")) and self.Owner:GetMoveType() == MOVETYPE_CUSTOM and GetConVar("gk_enableshooting"):GetBool() == false then
pos = self.Owner:GetNWEntity("ClimbingEnt"):GetPos()
end
local screenpos = pos:ToScreen()
local dist = self.Owner:GetPos():Distance(pos)
local distM = math.Round(dist / 60, 1)
-- Tactical Theme Colors
local themeColor = Color(0, 67, 28, 255) -- #00431c (Military Green)
local accentColor = Color(0, 150, 60, 200)
-- Dynamic Range Status
local crossCol = themeColor
local statusText = "RANGE: STABLE"
if dist > 5000 then
crossCol = Color(200, 50, 50, 220)
statusText = "RANGE: EXCEEDED"
elseif dist > 3000 then
crossCol = Color(200, 150, 0, 220)
statusText = "RANGE: UNSTABLE"
end
local x, y = screenpos.x, screenpos.y
local gap = 12 + movement
local cornerSize = 8
surface.SetDrawColor(crossCol)
-- Tactical Corner Brackets
-- Top Left
surface.DrawLine(x - gap, y - gap, x - gap + cornerSize, y - gap)
surface.DrawLine(x - gap, y - gap, x - gap, y - gap + cornerSize)
-- Top Right
surface.DrawLine(x + gap, y - gap, x + gap - cornerSize, y - gap)
surface.DrawLine(x + gap, y - gap, x + gap, y - gap + cornerSize)
-- Bottom Left
surface.DrawLine(x - gap, y + gap, x - gap + cornerSize, y + gap)
surface.DrawLine(x - gap, y + gap, x - gap, y + gap - cornerSize)
-- Bottom Right
surface.DrawLine(x + gap, y + gap, x + gap - cornerSize, y + gap)
surface.DrawLine(x + gap, y + gap, x + gap, y + gap - cornerSize)
-- Central Aim Dot
draw.RoundedBox(0, x - 1, y - 1, 2, 2, Color(255, 255, 255, 100))
-- Tactical Data Display
local dataX = x + gap + 15
draw.SimpleText("DIST: " .. string.format("%05.1f", distM) .. "m", "RopeKnifeCrosshair", dataX, y - 8, crossCol, TEXT_ALIGN_LEFT)
draw.SimpleText(statusText, "RopeKnifeCrosshair", dataX, y + 8, crossCol, TEXT_ALIGN_LEFT)
-- Target ID (TOP)
if GetConVar("gk_enabledamage"):GetBool() == true and IsValid(ent) and not IsValid(self.Owner:GetNWEntity("ClimbingEnt")) then
local name = ""
if ent:IsPlayer() then
name = ent:Nick()
elseif ent:IsNPC() or ent:IsNextBot() then
name = ent:GetClass():gsub("^npc_", ""):gsub("^ent_", ""):gsub("_", " "):upper()
end
if name ~= "" then
draw.SimpleText("[TARGET: " .. name .. "]", "RopeKnifeCrosshair", x, y - gap - 20, Color(255, 255, 255, 120), TEXT_ALIGN_CENTER)
end
end
-- Command Hint
if IsValid(self.Owner:GetNWEntity("ClimbingEnt")) then
local hintY = ScrH() - 175
draw.SimpleText("КОМАНДА: [ПРЫЖОК] - ОТЦЕПИТЬ", "RopeKnifeCrosshair", ScrH()/2, hintY, accentColor, TEXT_ALIGN_CENTER)
end
end