add sborka
This commit is contained in:
9
garrysmod/addons/koska/addon.json
Normal file
9
garrysmod/addons/koska/addon.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"title": "Grappling Knife",
|
||||
"type": "weapon",
|
||||
"tags": [
|
||||
"realism",
|
||||
"fun"
|
||||
],
|
||||
"ignore": []
|
||||
}
|
||||
143
garrysmod/addons/koska/lua/autorun/client/cl_rope_knives.lua
Normal file
143
garrysmod/addons/koska/lua/autorun/client/cl_rope_knives.lua
Normal file
@@ -0,0 +1,143 @@
|
||||
local matBeam = Material("cable/rope")
|
||||
|
||||
function DrawRopeKnives()
|
||||
for k,ent in pairs(ents.FindByClass("sent_rope_knife")) do
|
||||
if LocalPlayer():GetPos():Distance( ent:GetPos() ) > 16000 then continue end
|
||||
if !ent:GetNWBool("Stuck") and !ent:GetNWBool("Useless") and IsValid(ent:GetNWEntity("Owner")) then
|
||||
|
||||
local att = ent:GetNWEntity("Owner"):GetAttachment(ent:GetNWEntity("Owner"):LookupAttachment("anim_attachment_RH"))
|
||||
if !att then continue end
|
||||
local pos = att.Pos
|
||||
|
||||
render.SetMaterial(matBeam)
|
||||
render.DrawBeam(ent:GetPos(), pos, 2, 0, 1, Color(255,255,255))
|
||||
|
||||
elseif ent:GetNWBool("Stuck") then
|
||||
|
||||
local pos = ent:GetPos()
|
||||
|
||||
local line = {}
|
||||
line.start = pos
|
||||
line.endpos = pos + Vector(0,0,-16000)
|
||||
line.filter = {ent}
|
||||
for k,ply in pairs(player.GetAll()) do
|
||||
table.insert(line.filter, ply)
|
||||
end
|
||||
|
||||
local tr = util.TraceLine( line )
|
||||
|
||||
render.SetMaterial(matBeam)
|
||||
render.DrawBeam(pos, tr.HitPos, 2, 0, 1, Color(255,255,255))
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("PostDrawOpaqueRenderables","DrawRopeKnives",DrawRopeKnives)
|
||||
|
||||
hook.Add( "ShouldDrawLocalPlayer", "DrawClimbPlayer", function()
|
||||
if IsValid(LocalPlayer():GetNWEntity("ClimbingEnt")) and LocalPlayer():GetMoveType() == MOVETYPE_CUSTOM and GetConVarString( "gk_thirdperson" ) == "1" and GetConVarString( "gk_forcefirstperson" ) == "0" then return true end
|
||||
end )
|
||||
|
||||
function FollowClimbHead( ply, pos, angle, fov )
|
||||
if ( !ply:IsValid() or !ply:Alive() or ply:GetViewEntity() != ply ) then return end
|
||||
if ply:InVehicle() or !IsValid(ply:GetNWEntity("ClimbingEnt")) or ply:GetMoveType() ~= MOVETYPE_CUSTOM or GetConVarString( "gk_thirdperson" ) == "0" or GetConVarString( "gk_forcefirstperson" ) == "1" then return end
|
||||
|
||||
pos = pos - angle:Forward()*64
|
||||
|
||||
local view = {}
|
||||
view.origin = pos
|
||||
view.angles = angle
|
||||
view.fov = fov
|
||||
|
||||
return view
|
||||
end
|
||||
hook.Add( "CalcView", "RopeKnifeFollowHead", FollowClimbHead )
|
||||
|
||||
function RopeKnifeAnimation( ply, velocity, maxseqgroundspeed )
|
||||
if IsValid(ply:GetNWEntity("ClimbingEnt")) and ply:GetMoveType() == MOVETYPE_CUSTOM then
|
||||
local speed = ply:GetNWInt("MoveSpeed")
|
||||
|
||||
if ply:GetNWEntity("ClimbingEnt"):GetNWBool("MultiAngle") then
|
||||
ply:SetRenderAngles( ply:GetNWVector("ClimbNormal"):Angle() )
|
||||
else
|
||||
ply:SetRenderAngles( ply:GetNWEntity("ClimbingEnt"):GetNWVector("HitNormal"):Angle() )
|
||||
end
|
||||
ply.CalcSeqOverride = ply:LookupSequence( "zombie_climb_loop" )
|
||||
ply:SetSequence( ply.CalcSeqOverride )
|
||||
ply:SetPlaybackRate( speed/180 )
|
||||
return true
|
||||
end
|
||||
end
|
||||
hook.Add("UpdateAnimation", "RopeKnifeAnimation", RopeKnifeAnimation)
|
||||
|
||||
surface.CreateFont("RopeKnifeHUD", {
|
||||
font = "Roboto",
|
||||
size = 20,
|
||||
weight = 800,
|
||||
antialias = true
|
||||
})
|
||||
|
||||
local function HUDTimer()
|
||||
if not IsValid(LocalPlayer()) then return end
|
||||
|
||||
local foundHook = nil
|
||||
local climbingEnt = LocalPlayer():GetNWEntity("ClimbingEnt")
|
||||
if IsValid(climbingEnt) then
|
||||
foundHook = climbingEnt
|
||||
else
|
||||
for k, v in pairs(ents.FindByClass("sent_rope_knife")) do
|
||||
if v:GetNWEntity("Owner") == LocalPlayer() and v:GetNWBool("Stuck") then
|
||||
foundHook = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(foundHook) then
|
||||
local time = foundHook:GetNWFloat("ExpirationTime", 0)
|
||||
local timeLeft = math.ceil(time - CurTime())
|
||||
if time > 0 and timeLeft > 0 then
|
||||
local w, h = ScrW(), ScrH()
|
||||
local boxW, boxH = 300, 50
|
||||
local x, y = w/2 - boxW/2, h - 140
|
||||
|
||||
local themeColor = Color(0, 120, 50, 230) -- Brighter Tactical Green
|
||||
local accentGreen = Color(100, 255, 150, 255) -- Very Bright Green
|
||||
local textColor = Color(200, 255, 200, 255) -- Light Green for text
|
||||
|
||||
-- Tactical Border
|
||||
surface.SetDrawColor(themeColor)
|
||||
surface.DrawOutlinedRect(x, y, boxW, boxH, 2)
|
||||
|
||||
-- Background Alpha (Slightly more transparent)
|
||||
draw.RoundedBox(0, x + 2, y + 2, boxW - 4, boxH - 4, Color(0, 0, 0, 200))
|
||||
|
||||
-- Grid Lines (Visual detail)
|
||||
surface.SetDrawColor(themeColor.r, themeColor.g, themeColor.b, 40)
|
||||
for i = 0, boxW, 25 do surface.DrawLine(x + i, y, x + i, y + boxH) end
|
||||
|
||||
-- Status Indicator (Simplified and centered)
|
||||
local text = "Исчезнет через: " .. timeLeft .. " сек."
|
||||
draw.SimpleText(text, "RopeKnifeHUD", w/2, y + 10, accentGreen, TEXT_ALIGN_CENTER)
|
||||
|
||||
-- Segmented Progress Bar
|
||||
local segments = 10
|
||||
local segW = (boxW - 30) / segments
|
||||
local activeSegs = math.ceil((timeLeft / 60) * segments)
|
||||
|
||||
for i = 0, segments - 1 do
|
||||
local segX = x + 15 + i * segW
|
||||
local col = (i < activeSegs) and themeColor or Color(40, 40, 40, 200)
|
||||
draw.RoundedBox(0, segX + 1, y + 32, segW - 2, 6, col)
|
||||
end
|
||||
|
||||
-- Corner Accents
|
||||
surface.SetDrawColor(255, 255, 255, 50)
|
||||
surface.DrawRect(x, y, 4, 1) surface.DrawRect(x, y, 1, 4)
|
||||
surface.DrawRect(x + boxW - 4, y, 4, 1) surface.DrawRect(x + boxW - 1, y, 1, 4)
|
||||
surface.DrawRect(x, y + boxH - 1, 4, 1) surface.DrawRect(x, y + boxH - 4, 1, 4)
|
||||
surface.DrawRect(x + boxW - 4, y + boxH - 1, 4, 1) surface.DrawRect(x + boxW - 1, y + boxH - 4, 1, 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("HUDPaint", "RopeKnifeTimerHUD", HUDTimer)
|
||||
131
garrysmod/addons/koska/lua/autorun/sh_rope_knives.lua
Normal file
131
garrysmod/addons/koska/lua/autorun/sh_rope_knives.lua
Normal file
@@ -0,0 +1,131 @@
|
||||
hook.Add("Move","RopeKnifeMove", function(ply,mv,cmd)
|
||||
local ent = ply:GetNWEntity("ClimbingEnt")
|
||||
if IsValid( ent ) and ply:GetMoveType() == MOVETYPE_CUSTOM then
|
||||
|
||||
local deltaTime = FrameTime()
|
||||
local pos = mv:GetOrigin()
|
||||
local targetpos = ply:GetNWEntity("ClimbingEnt"):GetPos()
|
||||
local maxspeed = ply:GetMaxSpeed()*0.6
|
||||
local forward = mv:GetForwardSpeed()/10000
|
||||
local vel = mv:GetVelocity()
|
||||
|
||||
ply:SetNWInt("MoveSpeed", forward*maxspeed)
|
||||
|
||||
local newVelocity = (Vector(0,0,1)*forward*maxspeed)
|
||||
local newOrigin = pos + newVelocity * deltaTime
|
||||
|
||||
if mv:KeyDown(IN_JUMP) and SERVER then
|
||||
ply:SetMoveType( MOVETYPE_WALK )
|
||||
ply:SetGroundEntity( NULL )
|
||||
ply:SetNWEntity("ClimbingEnt", NULL)
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
|
||||
-- Give a small boost
|
||||
mv:SetVelocity( ply:GetForward() * -50 + Vector(0,0,200) )
|
||||
|
||||
-- Multi-use: Hook remains until its global 60s timer finishes
|
||||
return true
|
||||
end
|
||||
|
||||
if pos.z >= targetpos.z + 50 and SERVER then
|
||||
ply:SetMoveType( MOVETYPE_WALK )
|
||||
ply:SetGroundEntity( NULL )
|
||||
ply:SetNWEntity("ClimbingEnt", NULL)
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
|
||||
-- Multi-use: Hook remains until its global 60s timer finishes
|
||||
end
|
||||
if pos.z <= ent:GetNWVector("DownHit").z + 5 and ply:KeyDown(IN_BACK) and SERVER then
|
||||
newOrigin = newOrigin - ply:GetNWEntity("ClimbingEnt"):GetNWVector("HitNormal"):Angle():Forward()*18
|
||||
ply:SetMoveType( MOVETYPE_WALK )
|
||||
ply:SetGroundEntity( NULL )
|
||||
ply:SetNWEntity("ClimbingEnt", NULL)
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
|
||||
-- Multi-use: Hook remains until its global 60s timer finishes
|
||||
end
|
||||
|
||||
mv:SetVelocity( newVelocity )
|
||||
|
||||
mv:SetOrigin( newOrigin )
|
||||
|
||||
return true;
|
||||
end
|
||||
end)
|
||||
|
||||
function RopeKnifeThink( ply )
|
||||
if IsValid(ply:GetNWEntity("ClimbingEnt")) then
|
||||
if ply:GetMoveType() == MOVETYPE_CUSTOM then
|
||||
local wep = ply:GetActiveWeapon()
|
||||
if IsValid(wep) and GetConVar( "gk_enableshooting" ):GetBool() == false then
|
||||
wep:SetNextPrimaryFire(CurTime() + 0.5)
|
||||
ply:DrawViewModel(false)
|
||||
if SERVER then
|
||||
ply:DrawWorldModel(false)
|
||||
end
|
||||
end
|
||||
elseif SERVER then
|
||||
ply:SetNWEntity("ClimbingEnt", NULL)
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("PlayerPostThink", "RopeKnifeThink", RopeKnifeThink)
|
||||
|
||||
function PlayerDieClimb( victim, weapon, killer )
|
||||
-- Multi-use: Hook remains until its global 60s timer finishes
|
||||
victim:SetNWEntity("ClimbingEnt", NULL)
|
||||
end
|
||||
hook.Add( "PlayerDeath", "PlayerClimbDeath", PlayerDieClimb )
|
||||
|
||||
CreateConVar("gk_enableshooting", "0", {FCVAR_ARCHIVE})
|
||||
CreateConVar("gk_forcefirstperson", "0", {FCVAR_ARCHIVE})
|
||||
CreateConVar("gk_enabledamage", "1", {FCVAR_ARCHIVE})
|
||||
|
||||
if CLIENT then
|
||||
if GetConVar("gk_thirdperson") == nil then
|
||||
CreateClientConVar("gk_thirdperson", "1", true, true)
|
||||
end
|
||||
if GetConVar("gk_ropemat") == nil then
|
||||
CreateClientConVar("gk_ropemat", "", true, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function GKSettingsPanel(panel)
|
||||
panel:ClearControls()
|
||||
|
||||
panel:AddControl("CheckBox", {
|
||||
Label = "Thirdperson",
|
||||
Command = "gk_thirdperson"
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
local function GKAdminSettingsPanel(panel)
|
||||
panel:ClearControls()
|
||||
|
||||
panel:AddControl("CheckBox", {
|
||||
Label = "Shoot while climbing",
|
||||
Command = "gk_enableshooting"
|
||||
})
|
||||
panel:AddControl("CheckBox", {
|
||||
Label = "Enable grapple damage",
|
||||
Command = "gk_enabledamage"
|
||||
})
|
||||
panel:AddControl("CheckBox", {
|
||||
Label = "Force First-person",
|
||||
Command = "gk_forcefirstperson"
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
local function PopulateGKMenu()
|
||||
spawnmenu.AddToolMenuOption("Options", "Grappling Knife", "Grappling Knife", "Settings", "", "", GKSettingsPanel)
|
||||
spawnmenu.AddToolMenuOption("Options", "Grappling Knife", "Admin Grappling Knife", "Admin Settings", "", "", GKAdminSettingsPanel)
|
||||
end
|
||||
hook.Add("PopulateToolMenu", "GK Cvars", PopulateGKMenu)
|
||||
@@ -0,0 +1,8 @@
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
127
garrysmod/addons/koska/lua/entities/sent_rope_knife/init.lua
Normal file
127
garrysmod/addons/koska/lua/entities/sent_rope_knife/init.lua
Normal file
@@ -0,0 +1,127 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include( "shared.lua" )
|
||||
|
||||
function ENT:Initialize()
|
||||
self.Entity:SetModel( "models/props_c17/TrapPropeller_Lever.mdl" )
|
||||
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:Wake()
|
||||
end
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
self.StartTime = CurTime()
|
||||
end
|
||||
|
||||
function ENT:Use( activator, caller )
|
||||
end
|
||||
|
||||
function ENT:Touch( ent )
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid(phys) and phys:GetVelocity():Length() > 100 then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( self:GetPos() )
|
||||
effectdata:SetNormal( self:GetPhysicsObject():GetVelocity():GetNormalized() * -1 )
|
||||
util.Effect( "Impact", effectdata )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local phys = self:GetPhysicsObject()
|
||||
if !self:GetNWBool("Stuck") and self.StartTime + 4 < CurTime() then
|
||||
if IsValid(phys) then
|
||||
phys:AddVelocity( Vector(0,0,-350) )
|
||||
end
|
||||
elseif !self:GetNWBool("Stuck") and self.StartTime + 2 < CurTime() then
|
||||
if IsValid(phys) then
|
||||
phys:EnableGravity(true)
|
||||
end
|
||||
end
|
||||
|
||||
if !self:GetNWBool("Stuck") then return end
|
||||
if self:GetNWBool("Useless") then return end
|
||||
|
||||
local hookPos = self:GetPos()
|
||||
local groundPos = self:GetNWVector("DownHit", hookPos + Vector(0,0,-1000))
|
||||
|
||||
for _, ply in ipairs(player.GetAll()) do
|
||||
if not IsValid(ply) or not ply:Alive() then continue end
|
||||
|
||||
local plyPos = ply:GetPos() + Vector(0, 0, 40)
|
||||
local dist = util.DistanceToLine(hookPos, groundPos, plyPos)
|
||||
|
||||
if dist < 60 then
|
||||
if ply:KeyDown(IN_USE) and (not ply.NextUse or ply.NextUse < CurTime()) then
|
||||
ply.NextUse = CurTime() + 0.5
|
||||
|
||||
if ply:GetNWEntity("ClimbingEnt") == self and ply:GetMoveType() == MOVETYPE_CUSTOM then
|
||||
ply:SetMoveType(MOVETYPE_WALK)
|
||||
ply:SetGroundEntity(NULL)
|
||||
ply:SetNWEntity("ClimbingEnt", NULL)
|
||||
|
||||
local dropPos = ply:GetPos()
|
||||
dropPos.x = hookPos.x
|
||||
dropPos.y = hookPos.y
|
||||
ply:SetPos(dropPos - self:GetNWVector("HitNormal"):Angle():Forward() * 18)
|
||||
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
elseif not IsValid(ply:GetNWEntity("ClimbingEnt")) then
|
||||
ply:SetMoveType(MOVETYPE_CUSTOM)
|
||||
ply:SetGroundEntity(NULL)
|
||||
ply:SetNWEntity("ClimbingEnt", self)
|
||||
|
||||
local attachPos = ply:GetPos()
|
||||
attachPos.x = hookPos.x
|
||||
attachPos.y = hookPos.y
|
||||
|
||||
if self:GetNWBool("MultiAngle") then
|
||||
local ang = ply:EyeAngles()
|
||||
ang.p = 0
|
||||
ang.r = 0
|
||||
ply:SetPos(attachPos - ang:Forward() * 14)
|
||||
ply:SetNWVector("ClimbNormal", ang:Forward())
|
||||
else
|
||||
ply:SetPos(attachPos - self:GetNWVector("HitNormal"):Angle():Forward() * 14)
|
||||
end
|
||||
|
||||
if GetConVar("gk_enableshooting"):GetBool() == false then
|
||||
ply:DrawViewModel(false)
|
||||
ply:DrawWorldModel(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
for k,ply in pairs(player.GetAll()) do
|
||||
if ply:GetNWEntity("ClimbingEnt") == self then
|
||||
ply:SetMoveType(MOVETYPE_WALK)
|
||||
ply:SetGroundEntity( NULL )
|
||||
ply:SetNWEntity("ClimbingEnt", NULL)
|
||||
ply:DrawViewModel(true)
|
||||
ply:DrawWorldModel(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("PlayerNoClip", "NoclipRope", function( pl )
|
||||
local oldstate = pl:GetMoveType()
|
||||
if oldstate == MOVETYPE_CUSTOM and IsValid(pl:GetNWEntity("ClimbingEnt")) then
|
||||
local ent = pl:GetNWEntity("ClimbingEnt")
|
||||
pl:SetMoveType(MOVETYPE_WALK)
|
||||
pl:SetGroundEntity( NULL )
|
||||
local pos = pl:GetPos()
|
||||
pos.x = ent:GetPos().x
|
||||
pos.y = ent:GetPos().y
|
||||
pl:SetPos( pos - ent:GetNWVector("HitNormal"):Angle():Forward()*18 )
|
||||
pl:SetNWEntity("ClimbingEnt", NULL)
|
||||
pl:DrawViewModel(true)
|
||||
pl:DrawWorldModel(true)
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,83 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_entity"
|
||||
ENT.PrintName = "item"
|
||||
ENT.Author = "Krede"
|
||||
|
||||
function ENT:PhysicsCollide( cdata, obj )
|
||||
|
||||
if( SERVER ) then
|
||||
|
||||
local line = {}
|
||||
line.start = self:GetPos()
|
||||
line.endpos = line.start + ( ( cdata.HitPos - line.start ) * 2 )
|
||||
line.filter = {self}
|
||||
|
||||
local tr = util.TraceLine( line )
|
||||
|
||||
if IsValid(tr.Entity) then
|
||||
tr.Entity:TakeDamage(10, self:GetNWEntity("Owner"), self:GetNWEntity("Owner"))
|
||||
end
|
||||
|
||||
if tr.HitSky or !tr.HitWorld or cdata.HitNormal.z < 0 then
|
||||
self:SetNWBool("Useless", true)
|
||||
SafeRemoveEntityDelayed( self, 2 )
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:EnableGravity(true)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Impact Effects
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetOrigin( cdata.HitPos )
|
||||
effectdata:SetNormal( cdata.HitNormal )
|
||||
util.Effect( "ManhackSparks", effectdata )
|
||||
self:EmitSound("weapons/iceaxe/iceaxe_impact1.wav", 75, 100)
|
||||
|
||||
if self:GetNWBool("Useless") then return end
|
||||
|
||||
self:SetAngles( cdata.HitNormal:Angle() + Angle(90,0,0) )
|
||||
|
||||
self:SetPos( cdata.HitPos - cdata.HitNormal*12 )
|
||||
|
||||
self:SetNotSolid(true)
|
||||
|
||||
if cdata.HitNormal.z == 0 then
|
||||
self:SetNWVector("HitNormal", cdata.HitNormal)
|
||||
elseif cdata.HitNormal.z == 1 then
|
||||
local norm = cdata.HitNormal
|
||||
norm.z = 0
|
||||
self:SetNWVector("HitNormal", norm)
|
||||
self:SetNWBool("MultiAngle", true)
|
||||
else
|
||||
local norm = cdata.HitNormal
|
||||
norm.z = 0
|
||||
self:SetNWVector("HitNormal", norm)
|
||||
end
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid(phys) and !IsValid(cdata.HitEntity) and !self.Weld then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||||
self:SetNWBool("Stuck", true)
|
||||
self:SetNWFloat("ExpirationTime", CurTime() + 300)
|
||||
SafeRemoveEntityDelayed(self, 300)
|
||||
|
||||
local pos = self:GetPos()
|
||||
|
||||
local line = {}
|
||||
line.start = pos
|
||||
line.endpos = pos + Vector(0,0,-16000)
|
||||
line.filter = {}
|
||||
for k,sent in pairs(ents.GetAll()) do
|
||||
table.insert(line.filter, sent)
|
||||
end
|
||||
|
||||
local tr = util.TraceLine( line )
|
||||
|
||||
self:SetNWVector("DownHit", tr.HitPos)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
210
garrysmod/addons/koska/lua/weapons/weapon_rope_knife/shared.lua
Normal file
210
garrysmod/addons/koska/lua/weapons/weapon_rope_knife/shared.lua
Normal file
@@ -0,0 +1,210 @@
|
||||
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
|
||||
Reference in New Issue
Block a user