• Smoke Effect (Particle Emitter)
    6 replies, posted
Im pretty new to lua, Ive got a script that generates smoke and it works okay, except it only shows client side. [code] if CLIENT then local ply = LocalPlayer() smokeParticle = ParticleEmitter( ply:GetPos() ) SmokeTable = { smokeParticle:Add( Model("particle/particle_noisesphere") , ply:GetPos()), smokeParticle:Add( Model("particle/particle_noisesphere") , ply:GetPos()), smokeParticle:Add( Model("particle/particle_noisesphere") , ply:GetPos()) } for i=1,3 do local gray = math.random(75, 200) SmokeTable[i]:SetColor(gray, gray, gray) SmokeTable[i]:SetStartAlpha(255) SmokeTable[i]:SetEndAlpha(200) SmokeTable[i]:SetVelocity(VectorRand() * math.Rand(900, 1300)) SmokeTable[i]:SetLifeTime(0) SmokeTable[i]:SetDieTime(math.Rand(50, 70)) SmokeTable[i]:SetStartSize(math.random(140, 150)) SmokeTable[i]:SetEndSize(math.random(1, 40)) SmokeTable[i]:SetRoll(math.random(-180, 180)) SmokeTable[i]:SetRollDelta(math.Rand(-0.1, 0.1)) SmokeTable[i]:SetAirResistance(600) SmokeTable[i]:SetCollide(true) SmokeTable[i]:SetBounce(0.4) SmokeTable[i]:SetLighting(false) end print("lol2") end ParticleEffectAttach(Model("particle/particle_noisesphere"),PATTACH_ABSORIGIN_FOLLOW,smokeParticle,0) [/code] Can anyone help?
That's normal... You'll need to comunicate an information saying other clients to start particle emitter. For example, on server side entity do self:SetNWBool("DoSmoke", true) Then on client check if that NWBool is true and spawn particles if that's the case. Second way : your particle emiter is desined to be static (always emits, never stops), then you can just spawn your particles. I assume in your case, it's an effect you want, so you can simply use NW bools...
Can you elaborate? I dont really understand. Edit Can I not just attach i to an entity ?
I changed the code around , however Ive got a new error : [quote] [ERROR] gamemodes/terrortown/entities/weapons/wepon_ttt_knife.lua:127: attempt to call method 'CreateSmoke' ( a nil value ) [/quote] This is the new code : [code] if(CLIENT) then function SWEP:CreateSmoke() local smokeParticle = ParticleEmitter( self.Owner:GetPos() ) SmokeTable = { smokeParticle:Add( Model("particle/particle_noisesphere") , self.Owner:GetPos()), smokeParticle:Add( Model("particle/particle_noisesphere") , self.Owner:GetPos()), smokeParticle:Add( Model("particle/particle_noisesphere") , self.Owner:GetPos()) } for i=1,3 do local gray = math.random(75, 200) SmokeTable[i]:SetColor(gray, gray, gray) SmokeTable[i]:SetStartAlpha(255) SmokeTable[i]:SetEndAlpha(200) SmokeTable[i]:SetVelocity(VectorRand() * math.Rand(900, 1300)) SmokeTable[i]:SetLifeTime(0) SmokeTable[i]:SetDieTime(math.Rand(50, 70)) SmokeTable[i]:SetStartSize(math.random(140, 150)) SmokeTable[i]:SetEndSize(math.random(1, 40)) SmokeTable[i]:SetRoll(math.random(-180, 180)) SmokeTable[i]:SetRollDelta(math.Rand(-0.1, 0.1)) SmokeTable[i]:SetAirResistance(600) SmokeTable[i]:SetCollide(true) SmokeTable[i]:SetBounce(0.4) SmokeTable[i]:SetLighting(false) end print("test") end end [/code] The function above is declared in the code here : [code] function SWEP:StabKill(tr, spos, sdest) local target = tr.Entity local dmg = DamageInfo() dmg:SetDamage(2000) dmg:SetAttacker(self.Owner) dmg:SetInflictor(self.Weapon or self) dmg:SetDamageForce(self.Owner:GetAimVector()) dmg:SetDamagePosition(self.Owner: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.Owner, 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.Owner, 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.Owner 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.Owner:GetAimVector() * 3), sdest) -- target appears to die right there, so we could theoretically get to -- the ragdoll in here... self:Remove() end [/code]
Can you post the whole knife file in code tags? I have a feeling that you're not calling it serverside
[code] AddCSLuaFile() SWEP.HoldType = "knife" if CLIENT then SWEP.PrintName = "knife_name" SWEP.Slot = 6 SWEP.ViewModelFlip = false SWEP.EquipMenuData = { type = "item_weapon", desc = "knife_desc" }; SWEP.Icon = "vgui/ttt/icon_knife" SWEP.IconLetter = "j" end SWEP.Base = "weapon_tttbase" SWEP.UseHands = true SWEP.ViewModelFlip = false SWEP.ViewModelFOV = 54 SWEP.ViewModel = "models/weapons/cstrike/c_knife_t.mdl" SWEP.WorldModel = "models/weapons/w_knife_t.mdl" SWEP.DrawCrosshair = false SWEP.Primary.Damage = 50 SWEP.Primary.ClipSize = -1 SWEP.Primary.DefaultClip = -1 SWEP.Primary.Automatic = true SWEP.Primary.Delay = 1.1 SWEP.Primary.Ammo = "none" SWEP.Secondary.ClipSize = -1 SWEP.Secondary.DefaultClip = -1 SWEP.Secondary.Automatic = true SWEP.Secondary.Ammo = "none" SWEP.Secondary.Delay = 1.4 SWEP.Kind = WEAPON_EQUIP SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy SWEP.LimitedStock = true -- only buyable once SWEP.WeaponID = AMMO_KNIFE SWEP.IsSilent = true -- Pull out faster than standard guns SWEP.DeploySpeed = 2 function SWEP:PrimaryAttack() self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) if not IsValid(self.Owner) then return end self.Owner:LagCompensation(true) local spos = self.Owner:GetShootPos() local sdest = spos + (self.Owner: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.Owner, 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.Owner, 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.Owner: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(100 ) dmg:SetAttacker(self.Owner) dmg:SetInflictor(self.Weapon or self) dmg:SetDamageForce(self.Owner:GetAimVector() * 5) dmg:SetDamagePosition(self.Owner:GetPos()) dmg:SetDamageType(DMG_SLASH) self.Owner:StripWeapon(self.WeaponClass ) hitEnt:DispatchTraceAttack(dmg, spos + (self.Owner:GetAimVector() * 3), sdest) end end end self.Owner:LagCompensation(false) end function SWEP:StabKill(tr, spos, sdest) local target = tr.Entity local dmg = DamageInfo() dmg:SetDamage(2000) dmg:SetAttacker(self.Owner) dmg:SetInflictor(self.Weapon or self) dmg:SetDamageForce(self.Owner:GetAimVector()) dmg:SetDamagePosition(self.Owner: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.Owner, 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.Owner, 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.Owner 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.Owner: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:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER ) if SERVER then local ply = self.Owner 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() self.Weapon:SetNextPrimaryFire( CurTime() + (self.Primary.Delay * 1.5) ) self.Weapon:SetNextSecondaryFire( CurTime() + (self.Secondary.Delay * 1.5) ) end function SWEP:PreDrop() -- for consistency, dropped knife should not have DNA/prints self.fingerprints = {} end function SWEP:OnR
Hold on I'll start RealisticRoleplay with your weapon to see exactly where the problem is. [editline]31st March 2015[/editline] Your weapon has so much errors ! I got a warning everytime I hit an entity : "Trying to start a new lag compensation session while one is already active!" And it crashs at line 114 : attempt to call method GetAimVector (a nil value). [editline]31st March 2015[/editline] Succeeded to correct errors and even warning, however it does not make any damage to the pointed entity. [editline]31st March 2015[/editline] I got that which no longer creates lua errors however I can't test the Right-Click, because I'm not on a TTT server so it says attempted to create unknown entity type ttt_knife_proj [code] AddCSLuaFile() SWEP.HoldType = "knife" if CLIENT then SWEP.PrintName = "knife_name" SWEP.Slot = 6 SWEP.ViewModelFlip = false SWEP.EquipMenuData = { type = "item_weapon", desc = "knife_desc" }; SWEP.Icon = "vgui/ttt/icon_knife" SWEP.IconLetter = "j" end SWEP.Base = "weapon_base" SWEP.UseHands = true SWEP.ViewModelFlip = false SWEP.ViewModelFOV = 54 SWEP.ViewModel = "models/weapons/cstrike/c_knife_t.mdl" SWEP.WorldModel = "models/weapons/w_knife_t.mdl" SWEP.DrawCrosshair = false SWEP.Primary.Damage = 50 SWEP.Primary.ClipSize = -1 SWEP.Primary.DefaultClip = -1 SWEP.Primary.Automatic = true SWEP.Primary.Delay = 1.1 SWEP.Primary.Ammo = "none" SWEP.Secondary.ClipSize = -1 SWEP.Secondary.DefaultClip = -1 SWEP.Secondary.Automatic = true SWEP.Secondary.Ammo = "none" SWEP.Secondary.Delay = 1.4 SWEP.Kind = WEAPON_EQUIP SWEP.CanBuy = {ROLE_TRAITOR} -- only traitors can buy SWEP.LimitedStock = true -- only buyable once SWEP.WeaponID = AMMO_KNIFE SWEP.IsSilent = true -- Pull out faster than standard guns SWEP.DeploySpeed = 2 function SWEP:PrimaryAttack() self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) if not IsValid(self.Owner) then return end --self.Owner:LagCompensation(true) local spos = self.Owner:GetShootPos() local sdest = spos + (self.Owner: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.Owner, 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.Owner, 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.Owner: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(100 ) dmg:SetAttacker(self.Owner) dmg:SetInflictor(self.Weapon or self) dmg:SetDamageForce(self.Owner:GetAimVector() * 5) dmg:SetDamagePosition(self.Owner:GetPos()) dmg:SetDamageType(DMG_SLASH) self.Owner:StripWeapon("weapon_knife") if (IsValid(self.Owner)) then hitEnt:DispatchTraceAttack(dmg, spos + (self.Owner:GetAimVector() * 3), sdest) end end end end --self.Owner:LagCompensation(false) end function SWEP:StabKill(tr, spos, sdest) local target = tr.Entity local dmg = DamageInfo() dmg:SetDamage(2000) dmg:SetAttacker(self.Owner) dmg:SetInflictor(self.Weapon or self) dmg:SetDamageForce(self.Owner:GetAimVector()) dmg:SetDamagePosition(self.Owner: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.Owner, 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.Owner, 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.Owner 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.Owner: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:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self.Weapon:SetNextSecondaryFire( CurTime() + self.Secondary.Delay ) self.Weapon:SendWeaponAnim( ACT_VM_MISSCENTER ) if SERVER then local ply = self.Owner 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:GetPh
Sorry, you need to Log In to post a reply to this thread.