Thirsty Panther Posted November 2, 2015 Share Posted November 2, 2015 How do you check if a sound is already playing? This is what I have so far. If the players Ammo is 0 then I check to see if the DryFire sound is playing and if not then play it. if self.ammo == 0 then if self.DryFireSoundFile:GetState()~= Source.Playing then self.DryFireSoundFile:Play() else self.FireSoundFile:Play() self.ammo=self.ammo-1 self.FireRateTimer = 0 end When I run this it stops at GetState call with a nil value. Quote Link to comment Share on other sites More sharing options...
reepblue Posted November 2, 2015 Share Posted November 2, 2015 Use the sound class instead for simplicity. I did the same thing in my weapon script I did a while ago. Feel free to pick at it, or use the entire thing if you want. It has a max ammo count, and it auto reloads when the clip is empty, but the player has ammo. import "Scripts/AnimationManager.lua" Script.index=1--int "Weapon slot" Script.offset=Vec3(0,0,0)--Vec3 "Offset" Script.rotation=Vec3(0,0,0)--Vec3 "Rotation" Script.clipsize=6--int "Clip size" Script.ammo=200--int "Ammunition" Script.maxammo=200--int "Max Ammunition" Script.maxswayamplitude=0.01 Script.amplitude=0 Script.swayspeed=0 Script.timeunits=0 Script.smoothedposition=Vec3(0) Script.smoothedrotation=Vec3(0) Script.verticalbob=0 Script.jumpoffset=0 Script.bulletspeed=200--float "Bullet speed" Script.landoffset=0 Script.pellets=1--int "Pellets" Script.scatter=0.01--float "Scatter" Script.firetime=0 Script.refirerate=100--int "Refire rate" Script.bulletrange=1000 Script.muzzleflashscale=0.2--float "Flash size" Script.bulletforce=500--float "Force" Script.bulletdamage=10--int "Damage" Script.automatic=true--bool "Automatic" Script.dryfiresoundfile=""--path "Dry fire" "Wav File (*wav):wav|Sound" Script.fire1soundfile=""--path "Fire sound 1" "Wav File (*wav):wav|Sound" Script.fire2soundfile=""--path "Fire sound 2" "Wav File (*wav):wav|Sound" Script.fire3soundfile=""--path "Fire sound 3" "Wav File (*wav):wav|Sound" Script.pumpsoundfile=""--path "Pump sound" "Wav File (*wav):wav|Sound" Script.crosshairtexfile="Materials/HUD/crosshair_weapon.tex" --path "Crosshair" "Tex File (*tex):tex|Texture" Script.ricochet1soundfile=Sound:Load("Sound/Ricochet/bullet_impact_dirt_01.wav") Script.ricochet2soundfile=Sound:Load("Sound/Ricochet/bullet_impact_dirt_02.wav") Script.ricochet3soundfile=Sound:Load("Sound/Ricochet/bullet_impact_dirt_03.wav") Script.pickupsoundfile=Sound:Load("Sound/Player/pickupammo.wav") Script.reloadsoundfile=""--path "Reload sound" "Wav File (*wav):wav|Sound" Script.reloadspeed=0.05--float "Reload speed" Script.firespeed=0.05--float "Fire speed" Script.tracer = Sprite:Create() Script.tracer:Hide() Script.currentaction=nil function Script:Start() if self.started then return end self.started=true self.entity:SetPickMode(0,true) self.entity:SetAnimationFrame(0,1,"fire") self.entity:Hide() self.bullets = {} self.entity:SetShadowMode(0) self.entity:SetOcclusionCullingMode(false) self.tracer:SetViewMode(6)--Rotate around z axis self.tracer:SetSize(0.1,2) local mtl = Material:Load("Materials/Effects/tracer.mat") if mtl then self.tracer:SetMaterial(mtl) mtl:Release() end self.currentaction=nil self.clipammo=self.clipsize self.IsWeapon=true self.ammo = self.ammo - self.clipammo self.muzzle = self.entity:FindChild("muzzle") self.sound={} if self.sound.dryfiresoundfile~="" then self.sound.dryfire=Sound:Load(self.dryfiresoundfile) end self.sound.fire={} if self.pumpsoundfile~="" then self.sound.pump=Sound:Load(self.pumpsoundfile) end if self.fire1soundfile~="" then self.sound.fire[1]=Sound:Load(self.fire1soundfile) end if self.fire2soundfile~="" then self.sound.fire[2]=Sound:Load(self.fire2soundfile) end if self.fire3soundfile~="" then self.sound.fire[3]=Sound:Load(self.fire3soundfile) end if self.reloadsoundfile~="" then self.sound.reload=Sound:Load(self.reloadsoundfile) end self.sound.ricochet={} self.sound.ricochet[1]=Sound:Load("Sound/Ricochet/bullet_impact_dirt_01.wav") self.sound.ricochet[2]=Sound:Load("Sound/Ricochet/bullet_impact_dirt_02.wav") self.sound.ricochet[3]=Sound:Load("Sound/Ricochet/bullet_impact_dirt_03.wav") self.sound.ammo=Sound:Load("Sound/Player/pickupammo.wav") -- Crosshair self.image={} self.image.crosshair = Texture:Load(self.crosshairtexfile) --self.image.crosshairleft = Texture:Load("Materials/HUD/crosshair_bracket_left.tex") --self.image.crosshairright = Texture:Load("Materials/HUD/crosshair_bracket_right.tex") self.entity:SetPickMode(0) self.muzzleflash = Sprite:Create() self.muzzleflash:SetSize(self.muzzleflashscale,self.muzzleflashscale) self.muzzleflash:SetCollisionType(0) local material = Material:Load("Materials/Effects/muzzleflash.mat") self.muzzleflash:SetMaterial(material) self.muzzlelight = PointLight:Create() self.muzzlelight:SetColor(1,0.75,0) self.muzzlelight:SetRange(4) self.muzzleflash:SetShadowMode(0) local tag = self.entity:FindChild("muzzle") self.muzzlelight:SetParent(tag) self.muzzlelight:SetPosition(0,0,0) self.muzzlelight:Hide() self.muzzleflash:SetParent(self.muzzlelight,false) self.animationmanager = AnimationManager:Create(self.entity) self.originalposition = self.entity:GetPosition() self.originalrotation = self.entity:GetRotation() self.emitter={} --[[ --Debris emitter - This will throw chunks off of walls and make it look like they are breaking self.emitter[0]=Emitter:Create() self.emitter[0]:SetMaterial("Materials/Effects/tracer.mat") self.emitter[0]:SetEmissionVolume(0.05,0.05,0.05) self.emitter[0]:SetColor(1,1,1,1) self.emitter[0]:SetVelocity(10,10,10,1) self.emitter[0]:SetParticleCount(5) self.emitter[0]:SetReleaseQuantity(5) self.emitter[0]:SetMaxScale(0.25,1) self.emitter[0]:SetDuration(150) self.emitter[0]:SetRotationByVelocityMode(true) self.emitter[0]:Hide() ]]-- --Debris emitter - This will throw chunks off of walls and make it look like they are breaking self.emitter[0]=Emitter:Create() self.emitter[0]:SetMaterial("Materials/Effects/default.mat") self.emitter[0]:SetEmissionVolume(0.05,0.05,0.05) self.emitter[0]:SetColor(0.1,0.1,0.1,1) self.emitter[0]:SetVelocity(1.5,1.5,1.5,1) self.emitter[0]:SetParticleCount(10) self.emitter[0]:SetReleaseQuantity(10) self.emitter[0]:SetMaxScale(0.3) self.emitter[0]:SetDuration(1000) self.emitter[0]:SetAcceleration(0,-12,0) self.emitter[0]:Hide() --Smoke emitter - This will provide a soft dust effect around bullet impacts self.emitter[1]=Emitter:Create() self.emitter[1]:SetColor(1,1,1,0.25) self.emitter[1]:SetMaterial("Materials/Effects/smoke.mat") self.emitter[1]:SetEmissionVolume(0.1,0.1,0.1) self.emitter[1]:SetVelocity(0.3,0.3,0.3,1) self.emitter[1]:SetParticleCount(3) self.emitter[1]:SetReleaseQuantity(3) self.emitter[1]:SetMaxScale(4) self.emitter[1]:SetDuration(2500) self.emitter[1]:AddScaleControlPoint(0,0.5) self.emitter[1]:AddScaleControlPoint(1,1) self.emitter[1]:SetRotationSpeed(10) self.emitter[1]:Hide() --Blood emitter - This will provide a visual cue when an enemy is shot self.emitter[2]=self.emitter[1]:Instance() self.emitter[2] = tolua.cast(self.emitter[2],"Emitter") self.emitter[2]:SetMaterial("Materials/Effects/bloodspatter.mat") self.emitter[2]:SetColor(1,1,1,0.25) self.emitter[2]:SetParticleCount(3) self.emitter[2]:SetReleaseQuantity(3) self.emitter[2]:SetDuration(200) self.emitter[2]:SetEmissionVolume(0,0,0) self.emitter[2]:SetMaxScale(1) self.emitter[2]:SetRotationSpeed(10) self.emitter[2]:AddScaleControlPoint(0,0) self.emitter[2]:AddScaleControlPoint(1,1) self.emitter[2]:SetVelocity(0,0,0,0) self.emitter[2]:SetVelocity(0,0,0,1) self.emitter[2]:Hide() --[[if self.autogive then local player,n for n,player in ipairs(players) do player:AddWeapon(self,self.index) end end]]-- self.entity:Hide() end function Script:Holster() if self.entity:FindAnimationSequence("holster")>-1 then self.animationmanager:SetAnimationSequence("holster",self.reloadspeed,0,1)--,self,self.EndHolster,25) end end function Script:Unholster() if self.entity:FindAnimationSequence("unholster")>-1 then self.animationmanager:SetAnimationSequence("unholster",self.reloadspeed,0,1) self.currentaction="unholster" end end function Script:Hide() self.entity:Hide() self.muzzlelight:Hide() end function Script:FindScriptedParent(entity,func) while entity~=nil do if entity.script then if type(entity.script[func])=="function" then if entity.script.enabled~=false then return entity else return nil end end end entity = entity:GetParent() end return nil end function Script:BeginJump() self.jumpoffset = -180 end function Script:BeginLand() self.landoffset = -180 end function Script:SupressCrosshair() self.supresscrosshair = true end function Script:UnSupressCrosshair() self.supresscrosshair = false end function Script:FinalizeReload() self.currentaction=nil if self.cancelreload then self.cancelreload=false end end function Script:ReceiveAmmo(ammount) self.ammo = self.ammo + ammount if self.sound.ammo~=nil then self.sound.ammo:Play() end if self.ammo > self.maxammo then self.ammo = self.maxammo end end function Script:IsAmmoMaxed() if self.ammo < self.maxammo then return true end return false end function Script:EndReload() if self.entity:FindAnimationSequence("ReloadLoop")>-1 then if self.ammo>0 and self.clipammo<self.clipsize and (self.reloadedshells==0 or self.cancelreload==false) then if self.sound.reload~=nil then self.sound.reload:Play() end self.animationmanager:SetAnimationSequence("ReloadLoop",self.reloadspeed,300,1,self,self.EndReload) self.clipammo = self.clipammo + 1 self.ammo = self.ammo - 1 self.reloadedshells = self.reloadedshells + 1 else self.animationmanager:SetAnimationSequence("ReloadEnd",self.reloadspeed,300,1,self,self.FinalizeReload) end else self.currentaction=nil local rounds = self.clipsize - self.clipammo rounds = math.min(self.ammo,rounds) self.ammo = self.ammo - rounds self.clipammo = self.clipammo + rounds end end function Script:CanReload() if self.currentaction==nil then return true else return false end end function Script:Reload() if self.currentaction==nil then self.cancelreload=false if self.clipammo<self.clipsize and self.ammo>0 and self.currentaction==nil then self.currentaction="reload" self.reloadedshells=0 if self.entity:FindAnimationSequence("Reload")>-1 then self.animationmanager:SetAnimationSequence("Reload",self.reloadspeed,300,1,self,self.EndReload) self.reloadstarttime=Time:GetCurrent() if self.sound.reload~=nil then self.sound.reload:Play() end elseif self.entity:FindAnimationSequence("ReloadStart")>-1 then self.animationmanager:SetAnimationSequence("ReloadStart",self.reloadspeed,300,1,self,self.EndReload) end end end end function Script:FinalizeFire() self.currentaction=nil end function Script:EndFire() if self.entity:FindAnimationSequence("Pump")>-1 then self.animationmanager:SetAnimationSequence("Pump",0.03,300,1,self,self.FinalizeFire) if self.sound.pump~=nil then self.sound.pump:Play() end else self.currentaction=nil end end function Script:UpdateWorld() local bullet,n,dist local pickinfo=PickInfo() local firstbullet=true local travel for n,bullet in ipairs(self.bullets) do --Check how far the bullet has travelled dist = (bullet.position-bullet.origin):Length() if dist>self.bulletrange then table.remove(self.bullets,n) bullet.sprite:Release() bullet=nil end if bullet~=nil then travel = bullet.velocity/60.0*Time:GetSpeed() if self.entity.world:Pick(bullet.position,bullet.position+travel,pickinfo,0,true,Collision.Projectile) then table.remove(self.bullets,n) bullet.sprite:Release() --Find first parent with the Hurt() function local enemy = self:FindScriptedParent(pickinfo.entity,"Hurt") if enemy~=nil then if enemy.script.health>0 then enemy.script:Hurt(self.bulletdamage,self.player) end --Blood emitter e = self.emitter[2]:Instance() e = tolua.cast(e,"Emitter") e:Show() e:SetLoopMode(false,true) e:SetPosition(pickinfo.position+pickinfo.normal*0.1) e:SetVelocity(0,0,0) else --Add a temporary particle emitter for bullet effects local e e = self.emitter[0]:Instance() e = tolua.cast(e,"Emitter") e:Show() e:SetLoopMode(false,true) e:SetPosition(pickinfo.position) local v=3 e:SetVelocity(pickinfo.normal.x*v,pickinfo.normal.y*v,pickinfo.normal.z*v,0) --Smoke emitter e = self.emitter[1]:Instance() e = tolua.cast(e,"Emitter") e:Show() e:SetLoopMode(false,true) e:SetPosition(pickinfo.position+pickinfo.normal*0.1) local v=0.2 e:SetVelocity(pickinfo.normal.x*v,pickinfo.normal.y*v,pickinfo.normal.z*v,0) --Play bullet impact noise e:EmitSound(self.sound.ricochet[math.random(#self.sound.ricochet)],30) if pickinfo.entity~=nil then --Add impulse to the hit object if pickinfo.entity:GetMass()>0 then --local force = pickinfo.normal*-1*self.bulletforce local dir = bullet.velocity:Normalize() local force = dir * self.bulletforce * math.max(0,-pickinfo.normal:Dot(dir)) --force = force * math.max(0,-pickinfo.normal:Dot(d))--multiply by dot product of velocity and collided normal, to weaken glancing blows pickinfo.entity:AddPointForce(force,pickinfo.position) end --Extract a partial surface from the hit surface and make a bullet mark --To be added later --if pickinfo.surface~=nil then -- local aabb = AABB(pickinfo.position-radius,pickinfo.position+radius) -- local surf = pickinfo.surface:Extract(aabb) --end end end else bullet.position = bullet.position+travel bullet.sprite:SetPosition(bullet.position - bullet.velocity:Normalize()*1) if bullet.sprite:Hidden() then dist = (bullet.position-bullet.origin):Length() if dist>bullet.sprite:GetSize().y then bullet.sprite:Show() end end end end firstbullet = false end end function Script:Fire() if self.player.weaponlowerangle==0 then local currenttime=Time:GetCurrent() if self.lastfiretime==nil then self.lastfiretime=0 end if currenttime-self.lastfiretime>self.refirerate then if self.currentaction==nil then self.lastfiretime = currenttime if self.clipammo==0 then if self.sound.dryfire then if self.suspenddryfire~=true then self.sound.dryfire:Play() if self.player~=nil then self.player.suspendfire=false self:Reload() end end end else self.currentaction="fire" if #self.sound.fire>0 then self.sound.fire[math.random(#self.sound.fire)]:Play() end self.clipammo = self.clipammo - 1 self.firetime = Time:GetCurrent() self.muzzlelight:Point(self.player.camera,1) self.muzzlelight:Show() self.muzzleflash:SetAngle(math.random(0,360)) self.animationmanager:SetAnimationSequence("Fire",self.firespeed,300,1,self,self.EndFire) --Spawn bullet local n for n=1,self.pellets do local d = Transform:Normal(0,0,1,self.player.camera,nil) d = d + Vec3(math.random(-1,1),math.random(-1,1),math.random(-1,1)) * self.scatter d = d:Normalize() local p if self.muzzle then p=self.muzzle:GetPosition(true) self:SpawnBullet(p,d*self.bulletspeed) else System:Print("Warning: Muzzle entity not found.") end end end else self.cancelreload=true end end end end --Creates a bullet function Script:SpawnBullet(position,velocity) local bullet = {} bullet.sprite = tolua.cast(self.tracer:Instance(),"Sprite") bullet.sprite:SetPosition(position) bullet.sprite:AlignToVector(velocity) bullet.sprite:Hide() bullet.position = position bullet.origin = Vec3(position.x,position.y,position.z) bullet.velocity = velocity table.insert(self.bullets,bullet) end function Script:Draw() local t = Time:GetCurrent() if self.muzzlelight:Hidden()==false then if t-self.firetime>50 then self.muzzlelight:Hide() end end local jumpbob = 0 if self.jumpoffset<0 then jumpbob = (Math:Sin(self.jumpoffset))*0.01 self.jumpoffset = self.jumpoffset + 8*Time:GetSpeed() end if self.landoffset<0 then jumpbob = jumpbob + (Math:Sin(self.landoffset))*0.01 self.landoffset = self.landoffset + 10*Time:GetSpeed() end --Animate the weapon local bob = 0; local speed = math.max(0.1,self.player.entity:GetVelocity():xz():Length()) if self.player.entity:GetAirborne() then speed = 0.1 end self.swayspeed = Math:Curve(speed,self.swayspeed,20) self.swayspeed = math.max(0.5,self.swayspeed) self.amplitude = math.max(2,Math:Curve(speed,self.amplitude,20)) self.timeunits = self.timeunits + self.swayspeed*4*Time:GetSpeed() local sway = math.sin(self.timeunits/120.0) * self.amplitude * self.maxswayamplitude bob = (1-math.cos(self.timeunits/60.0)) * self.maxswayamplitude * 0.1 * self.amplitude local campos = self.player.camera:GetPosition(true) self.smoothedposition.x = campos.x self.smoothedposition.y = Math:Curve(campos.y,self.smoothedposition.y,2) self.smoothedposition.z = campos.z self.entity:SetRotation(self.rotation) self.entity:SetPosition(sway*self.entity.scale.x,bob+jumpbob,0) self.entity:Translate(self.offset,false) self.animationmanager:Update() end function Script:Release() if self.emitter~=nil then self.emitter[0]:Release() self.emitter[1]:Release() self.emitter[2]:Release() self.emitter=nil end if self.sound~=nil then ReleaseTableObjects(self.sound) self.sound=nil end end function Script:Cleanup() self.tracer:Release() end --This function will be called after the world is rendered, before the screen is refreshed. --Use this to perform any 2D drawing you want the entity to display. function Script:PostRender(context) -- Don't draw if we don't have a player. if self.player == nil then return end -- Don't draw if we are not a weapon. if not self.IsWeapon then return end -- Don't draw if player is dead. if self.player.health<=0 then return end -- Crosshair keyvalues if self.supresscrosshair then return end -- From crosshair keyvalue. if self.player.supresswpncrosshair then return end -- If we are holding something if self.player.carryingEntity then return end -- Disable the default crosshair. --self.player.supresscrosshair = true local crossHairX = math.floor((context:GetWidth() - self.image.crosshair:GetWidth()))/2 local crossHairY = math.floor((context:GetHeight() - self.image.crosshair:GetHeight()))/2 context:SetBlendMode(Blend.Alpha) context:SetColor(1,1,1,1) context:DrawImage(self.image.crosshair, crossHairX, crossHairY) context:SetBlendMode(Blend.Solid) end Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Rick Posted November 2, 2015 Share Posted November 2, 2015 I'm guessing that means your self.DryFireSoundFile variable is nil. It didn't get loaded correctly most likely. Make sure it's a Source and not Sound. Make sure the path is correct when loading. Make sure the .wav file is correct format. Quote Link to comment Share on other sites More sharing options...
Thirsty Panther Posted November 2, 2015 Author Share Posted November 2, 2015 Thank you both. @ Rick, the path and wave format are correct. The file plays normally if I comment out "get state" line although it repeats. I think your on to something with the sound/source idea. Could you explain the source/ sound and how that works. @ Reepblue thanks for sharing your work, I am trying to build a very basic firing system no animation, no reloading no emitters etc. I could of used the default script that comes with Leadwerks but It is overly complicated for what I'm trying to do. In your script you load all your sounds into a table called sound right? Then when the player tries to fire but has no ammo you play the dry fire sound. Do you use self.suspenddryfire as a flag to prevent the sound being repeated? You don't use "get state" for this? Again thanks for the help. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 2, 2015 Share Posted November 2, 2015 Sounds will just allow you to play or stop. You need to make a Source FROM the Sound to allow more tweaking/checking. See examples here: http://www.leadwerks.com/werkspace/page/api-reference/_/source/ 1 Quote Link to comment Share on other sites More sharing options...
Thirsty Panther Posted November 3, 2015 Author Share Posted November 3, 2015 Great. Just got it to work. Cheers Rick and thanks also to Reepblue. Here is what I did. initially define where to get the wav file and initalize our script variable.. Script.DryFireSoundPath=""--path "Dry Fire Sound" "Wav File (*wav):wav|Sound" Script.DryFireSoundFile = nil In the start function load the wav file into a variable. if self.DryFireireSoundPath ~= "" then self.DryFireSoundFile = Sound:Load(self.DryFireSoundPath) end Also in the start function we create a source for our sound and tell it what sound to play. self.source = Source:Create() self.source:SetSound(self.DryFireSoundFile) Now in the updateworld function we check if the source (DryFileSoundFile) is NOT playing and if not then play it. if (self.source:GetState()~=Source.Playing) then self.source:Play() end Hope this helps others. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.