• Playing a sound if a player has fallen a certain distance
    14 replies, posted
Hello. I'm looking to find a code that has a player play a sound if they've fallen a certain distance. How would I do this? Any help is appreciated.
You could simulate this using fall speed since the acceleration of gravity will apply what you need automatically on normal falls: [url]http://wiki.garrysmod.com/page/GM/GetFallDamage[/url]
[QUOTE=code_gs;48008582]You could simulate this using fall speed since the acceleration of gravity will apply what you need automatically on normal falls: [url]http://wiki.garrysmod.com/page/GM/GetFallDamage[/url][/QUOTE] Huh? Could I have an example code? The way it was worded confused me a bit [url=http://www.freesmileys.org/smileys.php][img]http://www.freesmileys.org/smileys/smiley-devil14.gif[/img][/url]
[code]hook.Add( "GetFallDamage", "FallSound", function( ply, speed ) if not IsValid( ply ) then return end if ( speed < 100 ) then ply:EmitSound( "sound.wav" ) else ply:EmitSound( "sound2.wav" ) end end )[/code]
There's no reliable way to get the distance someone has fallen, however simple mechanics tells us that you can somewhat approximate it like this: s = (v^2 - u^2)/2a where s is the distance, v is the final velocity (second argument of the hook), u is the initial velocity (you'll have a hard time figuring this out, so just assume 0 because that's pretty much what it will be unless the player jumps before falling), and a is the acceleration due to gravity in source (which I think is 200, though someone should correct me if I'm wrong).
[QUOTE=James xX;48008892]There's no reliable way to get the distance someone has fallen, however simple mechanics tells us that you can somewhat approximate it like this: s = (v^2 - u^2)/2a where s is the distance, v is the final velocity (second argument of the hook), u is the initial velocity (you'll have a hard time figuring this out, so just assume 0 because that's pretty much what it will be unless the player jumps before falling), and a is the acceleration due to gravity in source (which I think is 200, though someone should correct me if I'm wrong).[/QUOTE] That forumla assumes, though, that there's no applied force on the person falling, which could create a problem if someone jumps on them/a prop is pushed against them.
Oh, wait, I think we're misunderstanding each other. I want to play the sound in [i]mid air[/i], not when they land.
No way really without checking the player's speed in a think hook, which could be reached in the ground anyway.
[lua] fallDist = 20 -- Falling distance before playing sound. function doPlyFalling() for _, ply in pairs(player.GetAll()) do if (ply:GetVelocity()[2] > ply:GetRunSpeed() + 10) or (ply:GetVelocity()[2] > ply:GetWalkSpeed() + 10) and not ply:GetMoveType == MOVETYPE_NOCLIP then if ply.fallPosOne and ply.fallTimeOne then ply.timeTwo = CurTime() ply.fallVelocityTwo = ply:GetVelocity()[2] plyFallDist = (ply.fallVelocityOne + ply.fallVelocityTwo * 0.5) * (ply.timeTwo - ply.timeOne) if fallDist >= plyFallDist then -- Play Sound Code ply.timeOne =CurTime() ply.fallVelocityOne = ply:GetVelocity()[2] else ply.timeOne = CurTime() ply.fallVelocityOne = ply:GetVelocity()[2] end else ply.timeOne = CurTime() ply.fallVelocityOne = ply:GetVelocity()[2] end end end end hook.Add("Think", "SoundUponPlayerFall", doPlyFalling) [/lua] Disclaimer: I wrote this on an iPad, in Devon, with no access to Gmod. It might not work, and you need to add your own sound code. It's something though, I guess?
Have a Think hook check if a player is falling down and is not on the ground, then when that happens, call a function or hook where you pass the player and position he started falling from as arguments. From there, hook.Add a Think hook that calculates the distance between the player and the position he started falling from until it hits your desired length, where you play the sound and remove this hook again. Also be sure to check if he hits the ground before that distance and remove the hook. Don't know if this is the most optimal, but that's how I'd do it.
So, having spent way to long on this, my best attempt is... [lua] minFallDist = 20 -- Falling distance before playing sound. function getFallDist(velOne, velTwo, timeOne, timeTwo) --print(velOne) --print(velTwo) local fallDist = 0 - ((((velOne + velTwo) * 0.5) * (timeTwo - timeOne))) return fallDist end -- In this function, the timer runs every tick, for a second. The emitsound is only played once per fall, but takes about 1.5 seconds to reset. Blame the think hook. -- To change this, get rid of the if not ply.isFalling statement, the else of falldist >= minfalldist statement, then insert own code. -- In fact, you should. Sometimes it plays multiple times. It's buggy as hell. function doPlyFallingHelper(ply, oldTime, oldSpeed) timer.Simple(1, function() newTime = CurTime() newSpeed = tonumber(ply:GetVelocity()[3]) fallDist = getFallDist(oldSpeed, newSpeed, oldTime, newTime) --print("Player "..ply:Nick().." fell "..fallDist.." units.") if fallDist >= minFallDist then if not ply.isFalling then ply:EmitSound("items/ammo_pickup.wav") --ply:ChatPrint("Fallen "..fallDist) --ply:ChatPrint("You have fallen more than the minimum distance!") ply.isFalling = true end else ply.isFalling = false end end) end function doPlyFalling() for _, ply in pairs(player.GetAll()) do ply.startFallLoop = true if ply.startFallLoop then ply.startFallLoop = false ply.oldTime = CurTime() ply.oldSpeed = tonumber(ply:GetVelocity()[3]) ply.timeToFall = CurTime() + 1 end if ply.timeToFall >= CurTime() then doPlyFallingHelper(ply, ply.oldTime, ply.oldSpeed) ply.oldTime = CurTime() ply.oldSpeed = tonumber(ply:GetVelocity()[3]) end end end function doPlyFallSound(ply) print("Calling Sound Function") if ply.initialFall then ply.initialFall = false ply:SendLua([[surface.PlaySound( "items/ammo_pickup.wav" )]]) return else return end end --hook.Add("PlyFalling", "DoPlayerFallSound", doPlyFallSound) hook.Add("Think", "SoundUponPlayerFall", doPlyFalling) --hook.Remove("Think", "SoundUponPlayerFall") [/lua] It works, but not very well. If you can code a better implementation than this, use it. This is shit. With 20, I've only had it play 1 sound. However, with a minFallDist of 500, it often repeats itself. Not a clue why. Sorry.
[code] ply.startFallLoop = true if ply.startFallLoop then ply.startFallLoop = false[/code] Uh
[QUOTE=code_gs;48018766][code] ply.startFallLoop = true if ply.startFallLoop then ply.startFallLoop = false[/code] Uh[/QUOTE] [QUOTE=jonjon1234;48018228]It works, but not very well. If you can code a better implementation than this, use it. This is shit.[/QUOTE] GS, you are a much better coder than me, so please, improve my crap attempt. Mine works, and that's about it. It is really hacky, and to be honest, I was surprised that it worked.
You're code is fine; it was a good job, I'm just saying that specific set of variables is not needed
True point, but I don't want to touch it now.... Something might break...
Sorry, you need to Log In to post a reply to this thread.