Hello, I am trying to create a backstabbing knife for TTT. I have been messing with this code and keep getting the same error.
Garry's Mod won't even load the weapon. (I have tried sv_cheats, give and it didn't work.)
My Lua Checker says: unexpected end of input expecting a label, if statement, function definition, numeric for loop, generic for loop, variable definition, function call or return statement
I don't know how to fix it as I am very new to coding.
AddCSLuaFile()
SWEP.PrintName = "Backstabbing Knife"
SWEP.Category = "KiddleyWiffers' Sweps"
SWEP.Author = "Polkovnik, Edited by KiddleyWiffers"
SWEP.Contact = "snipped, snipped"
SWEP.Purpose = "Attacks from the front do 40 damage, attacks from the back do 200."
SWEP.Instructions = "Primary attack - hit."
SWEP.Spawnable = true
SWEP.AdminSpawnable = true
SWEP.AdminOnly = false
SWEP.ViewModelFOV = 60
SWEP.ViewModel = "models/weapons/cstrike/c_knife_t.mdl"
SWEP.WorldModel = "models/weapons/w_knife_t.mdl"
SWEP.ViewModelFlip = false
SWEP.ShowViewModel = true
SWEP.ShowWorldModel = true
SWEP.ViewModelBoneMods = {}
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false
SWEP.EquipMenuData = {
type = "item_weapon",
desc = "Can instantly kill with a backstab."
}
SWEP.Kind = WEAPON_EQUIP
SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy
SWEP.LimitedStock = true -- only buyable once
SWEP.IsSilent = true
SWEP.DeploySpeed = 2
SWEP.NoSights = true
SWEP.AutoSpawnable = false
SWEP.Icon = "vgui/ttt/icon_knife"
SWEP.IconLetter = "j"
if SERVER then
resource.AddFile("materials/vgui/ttt/icon_knife.vmt")
end
SWEP.Slot = 6
SWEP.SlotPos = 1
SWEP.UseHands = true
SWEP.HoldType = "knife"
SWEP.FiresUnderwater = true
SWEP.DrawCrosshair = false
SWEP.DrawAmmo = false
SWEP.ReloadSound = ""
SWEP.Base = "weapon_base"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "None"
SWEP.Secondary.ClipSize = 0
SWEP.Secondary.DefaultClip = 0
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "None"
function SWEP:PrimaryAttack()
if not IsValid(self:GetOwner()) then return end
self:GetOwner():LagCompensation(true)
local spos = self:GetOwner():GetShootPos()
local sdest = spos + (self:GetOwner():GetAimVector() * 70)
local kmins = Vector(1,1,1) * -10
local kmaxs = Vector(1,1,1) * 10
local tr = util.TraceHull({start=spos, endpos=sdest, filter=self:GetOwner(), mask=MASK_SHOT_HULL, mins=kmins, maxs=kmaxs})
-- Hull might hit environment stuff that line does not hit
if not IsValid(tr.Entity) then
tr = util.TraceLine({start=spos, endpos=sdest, filter=self:GetOwner(), mask=MASK_SHOT_HULL})
end
local hitEnt = tr.Entity
-- effects
if IsValid(hitEnt) then
self.Weapon:SendWeaponAnim( ACT_VM_HITCENTER )
local edata = EffectData()
edata:SetStart(spos)
edata:SetOrigin(tr.HitPos)
edata:SetNormal(tr.Normal)
edata:SetEntity(hitEnt)
if hitEnt:IsPlayer() or hitEnt:GetClass() == "prop_ragdoll" then
util.Effect("BloodImpact", edata)
end
else
self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER )
end
if SERVER then
self:GetOwner():SetAnimation( PLAYER_ATTACK1 )
end
if SERVER and tr.Hit and tr.HitNonWorld and IsValid(hitEnt) then
if hitEnt:IsPlayer() then
-- knife damage is never karma'd, so don't need to take that into
-- account we do want to avoid rounding error strangeness caused by
-- other damage scaling, causing a death when we don't expect one, so
-- when the target's health is close to kill-point we just kill
if hitEnt:Health() < (self.Primary.Damage + 10) then
self:StabKill(tr, spos, sdest)
else
local dmg = DamageInfo()
dmg:SetDamage(self.Primary.Damage)
dmg:SetAttacker(self:GetOwner())
dmg:SetInflictor(self.Weapon or self)
dmg:SetDamageForce(self:GetOwner():GetAimVector() * 5)
dmg:SetDamagePosition(self:GetOwner():GetPos())
dmg:SetDamageType(DMG_SLASH)
hitEnt:DispatchTraceAttack(dmg, spos + (self:GetOwner():GetAimVector() * 3), sdest)
end
end
end
self:GetOwner():LagCompensation(false)
end
function SWEP:StabKill(tr, spos, sdest)
local target = tr.Entity
local dmg = DamageInfo()
dmg:SetDamage(2000)
dmg:SetAttacker(self:GetOwner())
dmg:SetInflictor(self.Weapon or self)
dmg:SetDamageForce(self:GetOwner():GetAimVector())
dmg:SetDamagePosition(self:GetOwner():GetPos())
dmg:SetDamageType(DMG_SLASH)
-- now that we use a hull trace, our hitpos is guaranteed to be
-- terrible, so try to make something of it with a separate trace and
-- hope our effect_fn trace has more luck
-- first a straight up line trace to see if we aimed nicely
local retr = util.TraceLine({start=spos, endpos=sdest, filter=self:GetOwner(), mask=MASK_SHOT_HULL})
-- if that fails, just trace to worldcenter so we have SOMETHING
if retr.Entity != target then
local center = target:LocalToWorld(target:OBBCenter())
retr = util.TraceLine({start=spos, endpos=center, filter=self:GetOwner(), mask=MASK_SHOT_HULL})
end
-- create knife effect creation fn
local bone = retr.PhysicsBone
local pos = retr.HitPos
local norm = tr.Normal
local ang = Angle(-28,0,0) + norm:Angle()
ang:RotateAroundAxis(ang:Right(), -90)
pos = pos - (ang:Forward() * 7)
local prints = self.fingerprints
local ignore = self:GetOwner()
target.effect_fn = function(rag)
-- we might find a better location
local rtr = util.TraceLine({start=pos, endpos=pos + norm * 40, filter=ignore, mask=MASK_SHOT_HULL})
if IsValid(rtr.Entity) and rtr.Entity == rag then
bone = rtr.PhysicsBone
pos = rtr.HitPos
ang = Angle(-28,0,0) + rtr.Normal:Angle()
ang:RotateAroundAxis(ang:Right(), -90)
pos = pos - (ang:Forward() * 10)
end
local knife = ents.Create("prop_physics")
knife:SetModel("models/weapons/w_knife_t.mdl")
knife:SetPos(pos)
knife:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
knife:SetAngles(ang)
knife.CanPickup = false
knife:Spawn()
local phys = knife:GetPhysicsObject()
if IsValid(phys) then
phys:EnableCollisions(false)
end
constraint.Weld(rag, knife, bone, 0, 0, true)
-- need to close over knife in order to keep a valid ref to it
rag:CallOnRemove("ttt_knife_cleanup", function() SafeRemoveEntity(knife) end)
end
-- seems the spos and sdest are purely for effects/forces?
target:DispatchTraceAttack(dmg, spos + (self:GetOwner():GetAimVector() * 3), sdest)
-- target appears to die right there, so we could theoretically get to
-- the ragdoll in here...
self:Remove()
end
function SWEP:SecondaryAttack()
self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER )
if SERVER then
local ply = self:GetOwner()
if not IsValid(ply) then return end
ply:SetAnimation( PLAYER_ATTACK1 )
local ang = ply:EyeAngles()
if ang.p < 90 then
ang.p = -10 + ang.p * ((90 + 10) / 90)
else
ang.p = 360 - ang.p
ang.p = -10 + ang.p * -((90 + 10) / 90)
end
local vel = math.Clamp((90 - ang.p) * 5.5, 550, 800)
local vfw = ang:Forward()
local vrt = ang:Right()
local src = ply:GetPos() + (ply:Crouching() and ply:GetViewOffsetDucked() or ply:GetViewOffset())
src = src + (vfw * 1) + (vrt * 3)
local thr = vfw * vel + ply:GetVelocity()
local knife_ang = Angle(-28,0,0) + ang
knife_ang:RotateAroundAxis(knife_ang:Right(), -90)
local knife = ents.Create("ttt_knife_proj")
if not IsValid(knife) then return end
knife:SetPos(src)
knife:SetAngles(knife_ang)
knife:Spawn()
knife.Damage = self.Primary.Damage
knife:SetOwner(ply)
local phys = knife:GetPhysicsObject()
if IsValid(phys) then
phys:SetVelocity(thr)
phys:AddAngleVelocity(Vector(0, 1500, 0))
phys:Wake()
end
self:Remove()
end
end
function SWEP:Equip()
function SWEP:PreDrop()
-- for consistency, dropped knife should not have DNA/prints
self.fingerprints = {}
end
function SWEP:OnRemove()
if CLIENT and IsValid(self:GetOwner()) and self:GetOwner() == LocalPlayer() and self:GetOwner():Alive() then
RunConsoleCommand("lastinv")
end
end
if CLIENT then
function SWEP:DrawHUD()
local tr = self:GetOwner():GetEyeTrace(MASK_SHOT)
if tr.HitNonWorld and IsValid(tr.Entity) and tr.Entity:IsPlayer()
and tr.Entity:Health() < (self.Primary.Damage + 10) then
local x = ScrW() / 2.0
local y = ScrH() / 2.0
surface.SetDrawColor(255, 0, 0, 255)
local outer = 20
local inner = 10
surface.DrawLine(x - outer, y - outer, x - inner, y - inner)
surface.DrawLine(x + outer, y + outer, x + inner, y + inner)
surface.DrawLine(x - outer, y + outer, x - inner, y + inner)
surface.DrawLine(x + outer, y - outer, x + inner, y - inner)
draw.SimpleText(T("knife_instant"), "TabLarge", x, y - 30, COLOR_RED, TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
end
return self.BaseClass.DrawHUD(self)
end
end
-- Backstab
function SWEP:PrimaryAttack()
if not (self.Weapon:GetNextPrimaryFire() < CurTime()) then return end
local vm = self.Owner:GetViewModel()
local tr = self.Owner:GetEyeTrace()
if (tr.HitPos - self.Owner:GetShootPos()):Length() < 80 then
if IsValid(tr.Entity) and SERVER then
local dmginfo = DamageInfo()
dmginfo:SetDamageType(DMG_CLUB)
dmginfo:SetAttacker(self.Owner)
dmginfo:SetInflictor(self)
local angle = self.Owner:GetAngles().y - tr.Entity:GetAngles().y
if angle < -180 then
angle = 360 + angle
end
if angle <= 90 and angle >= -90 then
dmginfo:SetDamage(100)
vm = self.Owner:GetViewModel()
else
dmginfo:SetDamage(40)
end
if tr.Entity:IsNPC() or tr.Entity:IsPlayer() then
dmginfo:SetDamageForce(self.Owner:GetForward() * 1)
else
if IsValid(tr.Entity:GetPhysicsObject()) then
tr.Entity:GetPhysicsObject():ApplyForceCenter(self.Owner:GetForward() * 1)
end
end
tr.Entity:TakeDamageInfo(dmginfo)
end
self.Owner:SetAnimation(PLAYER_ATTACK1)
self:SetNextPrimaryFire(CurTime() + 0.8)
if SERVER then
self.Owner:EmitSound(Sound("weapons/blade_hit1.wav"))
end
else
if SERVER then
self.Owner:EmitSound(Sound("weapons/knife_swing.wav"))
end
vm = self.Owner:GetViewModel()
self.Owner:SetAnimation(PLAYER_ATTACK1)
self:SetNextPrimaryFire(CurTime() + 0.8)
end
end-- This is where the error keeps happening, they are seperate but facepunch keeps gluing them together.
There's a really simple way to find the true cause of the error fairly quickly using Notepad++.
Step 1:
Get the code into the editor with Lua syntax highlighting.
https://files.facepunch.com/forum/upload/57895/5f1fc8ee-c35b-4b5e-8ca8-9643b42b612e/image.png
Step 2:
Use the "Indent By Fold" plugin
https://files.facepunch.com/forum/upload/57895/47392035-bef7-4862-83f4-ffd44b984c5b/image.png
Step 3:
Scroll down until the indenting looks wrong
https://files.facepunch.com/forum/upload/57895/920a0754-a36b-4336-b941-571dc99a8144/image.png
Well well well, looks like that Equip() function isn't properly ended. Looks like you better fix that.
You can also try LUA linters. Heres the first result I found when I googled "Lua linter gmod": GitHub
I figured it out, turns out that I had an extra end lol. I can't believe that was my problem.
Sorry, you need to Log In to post a reply to this thread.