• Help with grenade SWEP
    6 replies, posted
I've designed a grenade intending Traitors to randomly produce one of several overpowered weapons. However, my test SWEP is not functioning correctly, while it occasioonally successfully drops one of the listed weapons it does not leave the players inventory and it only drops one kind of weapon per map. Any help would be wonderful. [CODE] if SERVER then AddCSLuaFile( "shared.lua" ) end SWEP.HoldType = "grenade" if CLIENT then SWEP.PrintName = "Mystery" SWEP.Slot = 3 SWEP.SlotPos = 0 SWEP.Icon = "VGUI/ttt/icon_nades" end SWEP.Base = "weapon_tttbasegrenade" SWEP.Kind = WEAPON_NADE SWEP.WeaponID = AMMO_DISCOMB SWEP.Spawnable = true SWEP.AdminSpawnable = true SWEP.AutoSpawnable = false SWEP.UseHands = true SWEP.ViewModelFlip = false SWEP.ViewModelFOV = 54 SWEP.ViewModel = "models/weapons/cstrike/c_eq_fraggrenade.mdl" SWEP.WorldModel = "models/weapons/w_eq_fraggrenade.mdl" SWEP.Weight = 5 -- really the only difference between grenade weapons: the model and the thrown -- ent. function SWEP:GetGrenadeName() local chance = math.random(4) if chance == 1 then return "weapon_ttt_knife" elseif chance == 2 then return "dragon" elseif chance == 3 then return "heatgoogles" else return "ttt_manhacknade_proj" end end [/CODE]
Try that [CODE]function SWEP:GetGrenadeName() local chance = math.random(1,4) if chance == 1 then return "weapon_ttt_knife" elseif chance == 2 then return "dragon" elseif chance == 3 then return "heatgoogles" else return "ttt_manhacknade_proj" end end[/CODE] or this: [CODE]function SWEP:GetGrenadeName() local chance = math.Rand(1,4) if chance == 1 then return "weapon_ttt_knife" elseif chance == 2 then return "dragon" elseif chance == 3 then return "heatgoogles" else return "ttt_manhacknade_proj" end end[/CODE]
All that does is change the possible numbers from 0, 1, 2, or 3 to 1, 2, 3, or 4. Or it does nothing I forget whether lua counts from zero.
Well if that is the case then you need to look at the grenades base. I see nothing wrong with what you have.
I should mention that the only thing I've gotten to work from it is the knife. Additionally here is the base grenade code, it is quite lengthy. -- common code for all types of grenade [LUA]if SERVER then AddCSLuaFile( "shared.lua" ) end SWEP.HoldReady = "grenade" SWEP.HoldNormal = "slam" if CLIENT then SWEP.PrintName = "Incendiary grenade" SWEP.Instructions = "Burn." SWEP.Slot = 3 SWEP.SlotPos = 0 SWEP.Icon = "VGUI/ttt/icon_nades" end SWEP.Base = "weapon_tttbase" SWEP.Kind = WEAPON_NADE SWEP.ViewModel = "models/weapons/v_eq_flashbang.mdl" SWEP.WorldModel = "models/weapons/w_eq_flashbang.mdl" SWEP.Weight = 5 SWEP.ViewModelFlip = true SWEP.AutoSwitchFrom = true SWEP.DrawCrosshair = false SWEP.Primary.ClipSize = -1 SWEP.Primary.DefaultClip = -1 SWEP.Primary.Automatic = false SWEP.Primary.Delay = 1.0 SWEP.Primary.Ammo = "none" SWEP.Secondary.ClipSize = -1 SWEP.Secondary.DefaultClip = -1 SWEP.Secondary.Automatic = false SWEP.Secondary.Ammo = "none" SWEP.IsGrenade = true SWEP.NoSights = true SWEP.pin_pulled = false SWEP.throw_time = 0 SWEP.was_thrown = false SWEP.detonate_timer = 5 SWEP.DeploySpeed = 1.5 AccessorFuncDT( SWEP, "pin_pulled", "Pin") AccessorFuncDT( SWEP, "throw_time", "ThrowTime") AccessorFunc(SWEP, "det_time", "DetTime") CreateConVar("ttt_no_nade_throw_during_prep", "0") function SWEP:SetupDataTables() self:DTVar("Bool", 0, "pin_pulled") self:DTVar("Int", 0, "throw_time") end function SWEP:PrimaryAttack() self.Weapon:SetNextPrimaryFire(CurTime() + self.Primary.Delay) if GetRoundState() == ROUND_PREP and GetConVar("ttt_no_nade_throw_during_prep"):GetBool() then return end self:PullPin() end function SWEP:SecondaryAttack() end function SWEP:PullPin() if self:GetPin() then return end local ply = self.Owner if not IsValid(ply) then return end self.Weapon:SendWeaponAnim(ACT_VM_PULLPIN) if self.SetWeaponHoldType then self:SetWeaponHoldType(self.HoldReady) end self:SetPin(true) self:SetDetTime(CurTime() + self.detonate_timer) end function SWEP:Think() local ply = self.Owner if not IsValid(ply) then return end -- pin pulled and attack loose = throw if self:GetPin() then -- we will throw now if not ply:KeyDown(IN_ATTACK) then self:StartThrow() self:SetPin(false) self.Weapon:SendWeaponAnim(ACT_VM_THROW) if SERVER then self.Owner:SetAnimation( PLAYER_ATTACK1 ) end else -- still cooking it, see if our time is up if SERVER and self:GetDetTime() < CurTime() then self:BlowInFace() end end elseif self:GetThrowTime() > 0 and self:GetThrowTime() < CurTime() then self:Throw() end end function SWEP:BlowInFace() local ply = self.Owner if not IsValid(ply) then return end if self.was_thrown then return end self.was_thrown = true -- drop the grenade so it can immediately explode local ang = ply:GetAngles() local src = ply:GetPos() + (ply:Crouching() and ply:GetViewOffsetDucked() or ply:GetViewOffset()) src = src + (ang:Right() * 10) self:CreateGrenade(src, Angle(0,0,0), Vector(0,0,1), Vector(0,0,1), ply) self:SetThrowTime(0) self:Remove() end function SWEP:StartThrow() self:SetThrowTime(CurTime() + 0.1) end function SWEP:Throw() if CLIENT then self:SetThrowTime(0) elseif SERVER then local ply = self.Owner if not IsValid(ply) then return end if self.was_thrown then return end self.was_thrown = true local ang = ply:EyeAngles() -- don't even know what this bit is for, but SDK has it -- probably to make it throw upward a bit 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.min(800, (90 - ang.p) * 6) local vfw = ang:Forward() local vrt = ang:Right() -- local vup = ang:Up() local src = ply:GetPos() + (ply:Crouching() and ply:GetViewOffsetDucked() or ply:GetViewOffset()) src = src + (vfw * 8) + (vrt * 10) local thr = vfw * vel + ply:GetVelocity() self:CreateGrenade(src, Angle(0,0,0), thr, Vector(600, math.random(-1200, 1200), 0), ply) self:SetThrowTime(0) self:Remove() end end -- subclasses must override with their own grenade ent function SWEP:GetGrenadeName() ErrorNoHalt("SWEP BASEGRENADE ERROR: GetGrenadeName not overridden! This is probably wrong!\n") return "ttt_firegrenade_proj" end function SWEP:CreateGrenade(src, ang, vel, angimp, ply) local gren = ents.Create(self:GetGrenadeName()) if not IsValid(gren) then return end gren:SetPos(src) gren:SetAngles(ang) -- gren:SetVelocity(vel) gren:SetOwner(ply) gren:SetThrower(ply) gren:SetGravity(0.4) gren:SetFriction(0.2) gren:SetElasticity(0.45) gren:Spawn() gren:PhysWake() local phys = gren:GetPhysicsObject() if IsValid(phys) then phys:SetVelocity(vel) phys:AddAngleVelocity(angimp) end -- This has to happen AFTER Spawn() calls gren's Initialize() gren:SetDetonateExact(self:GetDetTime()) return gren end function SWEP:PreDrop() -- if owner dies or drops us while the pin has been pulled, create the armed -- grenade anyway if self:GetPin() then self:BlowInFace() end end function SWEP:Deploy() if self.SetWeaponHoldType then self:SetWeaponHoldType(self.HoldNormal) end self:SetThrowTime(0) self:SetPin(false) return true end function SWEP:Holster() if self:GetPin() then return false -- no switching after pulling pin end self:SetThrowTime(0) self:SetPin(false) return true end function SWEP:Reload() return false end function SWEP:Initialize() if self.SetWeaponHoldType then self:SetWeaponHoldType(self.HoldNormal) end self:SetDeploySpeed(self.DeploySpeed) self:SetDetTime(0) self:SetThrowTime(0) self:SetPin(false) self.was_thrown = false end function SWEP:OnRemove() if CLIENT and IsValid(self.Owner) and self.Owner == LocalPlayer() and self.Owner:Alive() then RunConsoleCommand("use", "weapon_ttt_unarmed") end end [/LUA]
Instead of it being a grenade which throws a knife and such, why dont you just make it a weapon? I mean why dont you just do the math random and just do if chance == 4 then self.Owner:Give("weapon_ttt_manhackgrenade") ? It would work better.
Ideally I'm trying to make a grenade that will wait a few seconds and then spawn an item with this grenade acting as a placeholder but that may work as a last resort. [editline]24th January 2014[/editline] Alright modified the primary attack of the teleporter slightly to give weapons with an effect so here is the code I modified [CODE]function SWEP:PrimaryAttack() --test self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) if SERVER then self:TeleportStore() else surface.PlaySound("ui/buttonrollover.wav") end --test self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) if self.Weapon:Clip1() <= 0 then self:DryFire(self.SetNextSecondaryFire) return end -- Disallow initiating teleports during post, as it will occur across the -- restart and allow the user an advantage during prep if GetRoundState() == ROUND_POST then return end if SERVER then self:TeleportRecall() self.remove() local chance = math.Rand(1,4) if chance == 1 then self.Owner:Give("weapon_ttt_knife") elseif chance == 2 then self.Owner:Give("dragon") elseif chance == 3 then self.Owner:Give("heatgoogles") else self.Owner:Give("weapon_ttt_manhackgrenade") end else surface.PlaySound("buttons/combine_button7.wav") end end[/CODE] And here is all of the code put together [CODE] -- traitor equipment: teleporter if SERVER then AddCSLuaFile( "shared.lua" ) end SWEP.HoldType = "normal" if CLIENT then SWEP.PrintName = "Mystery" SWEP.Slot = 7 SWEP.ViewModelFOV = 10 SWEP.EquipMenuData = { type = "item_weapon", desc = "Teleport a weapon from the aether" }; SWEP.Icon = "VGUI/ttt/icon_beacon" end SWEP.Base = "weapon_tttbase" SWEP.ViewModel = "models/weapons/v_crowbar.mdl" SWEP.WorldModel = "models/weapons/w_slam.mdl" SWEP.DrawCrosshair = false SWEP.ViewModelFlip = false SWEP.Primary.ClipSize = 1 SWEP.Primary.DefaultClip = 1 SWEP.Primary.ClipMax = 1 SWEP.Primary.Automatic = false SWEP.Primary.Ammo = "GaussEnergy" SWEP.Primary.Delay = 0.5 SWEP.Secondary.Automatic = false SWEP.Secondary.Ammo = "none" SWEP.Secondary.Delay = 1.0 SWEP.Kind = WEAPON_EQUIP2 --SWEP.CanBuy = {ROLE_TRAITOR, ROLE_DETECTIVE} SWEP.WeaponID = AMMO_TELEPORT SWEP.AllowDrop = true SWEP.NoSights = true SWEP.CSMuzzleFlashes = false local delay_beamup = 1 local delay_beamdown = 1 local ttt_telefrags = CreateConVar("ttt_teleport_telefrags", "0") function SWEP:SetTeleportMark(pos, ang) self.teleport = {pos = pos, ang = ang} end function SWEP:GetTeleportMark() return self.teleport end function SWEP:PrimaryAttack() --test self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) if SERVER then self:TeleportStore() else surface.PlaySound("ui/buttonrollover.wav") end --test self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) if self.Weapon:Clip1() <= 0 then self:DryFire(self.SetNextSecondaryFire) return end -- Disallow initiating teleports during post, as it will occur across the -- restart and allow the user an advantage during prep if GetRoundState() == ROUND_POST then return end if SERVER then self:TeleportRecall() self.remove() local chance = math.Rand(1,4) if chance == 1 then self.Owner:Give("weapon_ttt_knife") elseif chance == 2 then self.Owner:Give("dragon") elseif chance == 3 then self.Owner:Give("heatgoogles") else self.Owner:Give("weapon_ttt_manhackgrenade") end else surface.PlaySound("buttons/combine_button7.wav") end end function SWEP:SecondaryAttack() self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) if SERVER then self:TeleportStore() else surface.PlaySound("ui/buttonrollover.wav") end end local zap = Sound("ambient/levels/labs/electric_explosion4.wav") local unzap = Sound("ambient/levels/labs/electric_explosion2.wav") local function Telefrag(victim, attacker) if not IsValid(victim) then return end local dmginfo = DamageInfo() dmginfo:SetDamage(5000) dmginfo:SetDamageType(DMG_SONIC) dmginfo:SetAttacker(attacker) dmginfo:SetDamageForce(Vector(0,0,10)) dmginfo:SetDamagePosition(attacker:GetPos()) victim:TakeDamageInfo(dmginfo) end local function ShouldCollide(ent) local g = ent:GetCollisionGroup() return (g != COLLISION_GROUP_WEAPON and g != COLLISION_GROUP_DEBRIS and g != COLLISION_GROUP_DEBRIS_TRIGGER and g != COLLISION_GROUP_INTERACTIVE_DEBRIS) end -- Teleport a player to a {pos, ang} local function TeleportPlayer(ply, teleport) local oldpos = ply:GetPos() local pos = teleport.pos local ang = teleport.ang -- print decal on destination util.PaintDown(pos + Vector(0,0,25), "GlassBreak", ply) -- perform teleport ply:SetPos(pos) ply:SetEyeAngles(ang) -- ineffective due to freeze... timer.Simple(delay_beamdown, function () if IsValid(ply) then ply:Freeze(false) end end) sound.Play(zap, oldpos, 65, 100) sound.Play(unzap, pos, 55, 100) -- print decal on source now that we're gone, because else it will refuse -- to draw for some reason util.PaintDown(oldpos + Vector(0,0,25), "GlassBreak", ply) end -- Checks teleport destination. Returns bool and table, if bool is true then -- location is blocked by world or prop. If table is non-nil it contains a list -- of blocking players. local function CanTeleportToPos(ply, pos) -- first check if we can teleport here at all, because any solid object or -- brush will make us stuck and therefore kills/blocks us instead, so the -- trace checks for anything solid to players that isn't a player local tr = nil local tres = {start=pos, endpos=pos, mask=MASK_PLAYERSOLID, filter=player.GetAll()} local collide = false -- This thing is unnecessary if we can supply a collision group to trace -- functions, like we can in source and sanity suggests we should be able -- to do so, but I have not found a way to do so yet. Until then, re-trace -- while extending our filter whenever we hit something we don't want to -- hit (like weapons or ragdolls). repeat tr = util.TraceEntity(tres, ply) if tr.HitWorld then collide = true elseif IsValid(tr.Entity) then if ShouldCollide(tr.Entity) then collide = true else table.insert(tres.filter, tr.Entity) end end until (not tr.Hit) or collide if collide then --Telefrag(ply, ply) return true, nil else -- find all players in the place where we will be and telefrag them local blockers = ents.FindInBox(pos + Vector(-16, -16, 0), pos + Vector(16, 16, 64)) local blocking_plys = {} for _, block in pairs(blockers) do if IsValid(block) then if block:IsPlayer() and block != ply then if block:IsTerror() and block:Alive() then table.insert(blocking_plys, block) -- telefrag blocker --Telefrag(block, ply) end end end end return false, blocking_plys end return false, nil end local function DoTeleport(ply, teleport) if IsValid(ply) and ply:IsTerror() and teleport then local fail = false local block_world, block_plys = CanTeleportToPos(ply, teleport.pos) if block_world then -- if blocked by prop/world, always fail fail = true elseif block_plys and #block_plys > 0 then -- if blocked by player, maybe telefrag if ttt_telefrags:GetBool() then for _, p in pairs(block_plys) do
Sorry, you need to Log In to post a reply to this thread.