Page 1 of 1

Custom sounds for custom levers, buttons or other animations

Posted: Sat Jan 25, 2014 8:56 pm
by Isaac
It's probably not an issue in the upcoming LoG2, but I was asked about custom sounds (or removing the hard coded ones) in LoG1. So here is a method that works reasonably well, and allows for the use of custom sounds for buttons, levers, or custom versions of these.

As far as I know there is no way to prevent the default sounds from playing, and there are no lever or button hooks, (and so no easy way to detect the use of switches) ~that I am aware of.
So this is the way I devised.
________________
How to do it:
First, re-define the default Button and Lever sounds to a silent sound effect, placed in your "sounds" folder. Use the following script placed in the sounds.lua file in your project.

Code: Select all

	defineSound{
		name = "modButton",
		filename = "assets/samples/env/button_01.wav",
		loop = false,
		volume = 1,
		minDistance = 1,
		maxDistance = 10,
	}

	defineSound{
		name = "modLever",
		filename = "assets/samples/env/lever_01.wav",
		loop = false,
		volume = 1,
		minDistance = 1,
		maxDistance = 10,
	}

		defineSound{
		name = "button",
		filename = "mod_assets/sounds/silent.wav",
		loop = false,
		volume = 1,
		minDistance = 1,
		maxDistance = 10,
	}

	defineSound{
		name = "lever",
		filename = "mod_assets/sounds/silent.wav",
		loop = false,
		volume = 1,
		minDistance = 1,
		maxDistance = 10,
	}
This will make ALL buttons and levers silent unless connected to the sound effect script.

Next add the soundEffect script to the map: [note:updated script, now does the connections automatically.]
Place this code in a script object and name it 'customSounds'.

Code: Select all

	for l = 1, getMaxLevels() do
		for e in allEntities(l) do
			if e.class ~= nil and e.class == "Button" then
				e:addConnector('toggle', 'customSounds', 'soundEffect')
			elseif e.class ~= nil and e.class == "Lever" then
				e:addConnector('any', 'customSounds', 'soundEffect')			
			end
		end
			print('Sound connections added to all buttons and levers!')
	end

function soundEffect(caller)
	if caller and string.match(caller.id, 'SND_') then
		local sEffect = string.match(caller.id, "SND_"..".+")
		playSoundAt(string.sub(sEffect,5),caller.level,caller.x,caller.y)
	elseif caller and caller.class == "Button" then
		playSoundAt('modButton', caller.level,caller.x,caller.y)
	elseif caller and caller.class == "Lever" then
		playSoundAt('modLever', caller.level,caller.x,caller.y)
	end
end
When connected to this script, all regular buttons and levers sound like they would normally. The feature of this is that you can now define custom sounds (usually in the sounds.lua file) and have any button or lever play that sound when used; and you do this by appending the capital letters 'SND' and then the name of the sound effect to the object.id.

In a real map you would use the name of your custom sound, but for the example I will use the Ogre's scream with a button. You do this by making a button, and adding 'SND_' plus the name of the sound; in this case: 'ogre_rush_begin'... So you add 'SND_ogre_rush_begin' and you have a button named 'wall_button_1SNDogre_rush_begin'. This makes the button scream when pressed, just as it would play any defined sound, if you used that name instead.

On large multi-floor maps, you could use copies of the sound effect script per floor, to keep from needing to connect switches to a script on a different floor. Duplicated scripts will work just the same.

Video example.

UPDATED!:
I updated the script, and it will now auto-update all levers and buttons to have sounds ~without manual connections. I also changed the token from an Asterisk to the letters 'SND_', because it seems that anything but an alphanumeric character messes up calling the object in scripts.

Code: Select all

	for l = 1, getMaxLevels() do
		for e in allEntities(l) do
			if  e.class == "Button" then
				e:addConnector('toggle', 'customSounds', 'soundEffect')
			elseif  e.class == "Lever" then
				e:addConnector('any', 'customSounds', 'soundEffect')			
			end
		end
			print('Sound connections added to all buttons and levers!')
	end

function soundEffect(caller)
	if caller and string.match(caller.id, 'SND_') then
		local sEffect = string.match(caller.id, "SND_"..".+")
		playSoundAt(string.sub(sEffect,5),caller.level,caller.x,caller.y)
	elseif caller and caller.class == "Button" then
		playSoundAt('modButton', caller.level,caller.x,caller.y)
	elseif caller and caller.class == "Lever" then
		playSoundAt('modLever', caller.level,caller.x,caller.y)
	end
end

Re: Custom sounds for custom levers, buttons or other animat

Posted: Sat Jan 25, 2014 9:26 pm
by chaoscommencer
Neat trick. Germanny could probably use this method for his wheel (custom lever). Good timing on announcing this one. Didn't know the original sound would still be played.

Re: Custom sounds for custom levers, buttons or other animat

Posted: Sat Jan 25, 2014 9:31 pm
by Isaac
chaoscommencer wrote:Neat trick. Germanny could probably use this method for his wheel (custom lever). Good timing on announcing this one.
He's the one that asked. ;)
Didn't know the original sound would still be played.
The original sound always plays, unfortunately... So the script makes it a silent sound, and plays the custom sound along with it. In the case of regular buttons & levers (with no asterisk in the name; have to be careful on that), the 'custom' sound is the regular one from the game.

Re: Custom sounds for custom levers, buttons or other animat

Posted: Sat Jan 25, 2014 11:02 pm
by AdrTru
Its very useful trick. Thak you much.
I made special button with special sound as scripted alcove, but this way is much better.

Re: Custom sounds for custom levers, buttons or other animat

Posted: Sat Jan 25, 2014 11:03 pm
by chaoscommencer
Ya I read the script. Clever work around man :)

Re: Custom sounds for custom levers, buttons or other animat

Posted: Sun Jan 26, 2014 7:01 pm
by germanny
Nice work Isaac.
Where will we be without this great knowledge here :)

Re: Custom sounds for custom levers, buttons or other animat

Posted: Mon Jan 27, 2014 9:46 pm
by germanny
Isaac, this is great! :geek:

My script: Twin Custom Sounds only for levers!

What i wanted to do: Set a custom sound to each lever state - activated or deactivated.

Wow - Got it to work with another solution, maybe a bit noobish, but seems to work fine.
Isaac, i borrowed your first part - set connectors for all levers^^

Then i had a problem with sound volume, if playSoundAt() is set to lever position by script.
The custom sounds play very silent if party stands facing the lever. Strange.. is it only in my dungeon? :?
*EDIT* This was an error with my speakers xD, not necessary! I commented those lines..

*obsolete
I solved this issue by getting the facing value from current lever and add or subtract 1 to
lever.x or lever.y for moving the soundplay-position.
Now custom sounds play nice with wanted soundvolume!
obsolete*

With this script one sound for each state (activated,deactivated) is added to all levers in the dungeon.
- It is necessary to define new sounds in 'sounds.lua' first. Must be *.wav, mono, 16bit.
- a silent sound for 'lever' needed, similar to Isaac´s (see his post)
- Create a custom lever or use a community one
- Simply place this script into your dungeon, thats all.
*EDIT* - Or Dl example file at end^^

If you want to add a new custom lever inside this script, simply add:
-------------------------------------------------------------------

Code: Select all

elseif lvNam == 'MyNewLeverName' and lvState == 'activated' then 
	playSoundAt("MyNewLeverActivSound", lvLevl, lvPosX, lvPosY)

elseif lvNam == 'MyNewLeverName' and lvState == 'deactivated' then 
	playSoundAt("MyNewLeverDeactivSound", lvLevl, lvPosX, lvPosY) 
-------------------------------------------------------------------

The new defined sounds in this example are: leverwheel_open, leverwheel_close, dm_lever_on, dm_lever_off.

Twin Custom Sounds only for levers!
-----------------------------------------------------------------

Code: Select all

-- Set connectors to all levers in dungeon (thx to Isaac!)

for l = 1, getMaxLevels() do
      for e in allEntities(l) do
         if  e.class == "Lever" then
            e:addConnector('any', 'leverSndSet', 'playLvSnd')
         end
         end
end

-- The function to play custom sounds

function playLvSnd(dmDungLev)

-- declare and set variables

lvState = dmDungLev:getLeverState()
lvLevl = dmDungLev.level
lvNam = dmDungLev.name
lvFac = dmDungLev.facing
lvPosX = dmDungLev.x
lvPosY = dmDungLev.y

-- Display lever states on screen - for debugging, remove this

hudPrint(lvState..", "..lvNam..", "..lvPosX..", "..lvPosY..", "..lvFac)

-- This section is defined as comment, not needed anymore, was: Correct the position for playSoundAt()

-- if lvFac == 0 then lvPosY = lvPosY-1      -- if lever Facing North
-- elseif lvFac == 1 then lvPosX = lvPosX+1  -- if lever Facing West
-- elseif lvFac == 2 then lvPosY = lvPosY+1  -- if lever Facing South
-- else lvPosX = lvPosX-1                    -- if lever Facing East
-- end

-- play sounds for each state

if lvState == 'activated' and lvNam == 'lever' then 
	playSoundAt("dm_lever_on", lvLevl, lvPosX, lvPosY)
	
elseif lvState == 'deactivated' and lvNam == 'lever' then 
	playSoundAt("dm_lever_off", lvLevl, lvPosX, lvPosY)
	
elseif lvNam == 'dm_lever_wheel' and lvState == 'activated' then 
	playSoundAt("leverwheel_open", lvLevl, lvPosX, lvPosY)

elseif lvNam == 'dm_lever_wheel' and lvState == 'deactivated' then 
	playSoundAt("leverwheel_close", lvLevl, lvPosX, lvPosY)

end	
end
---------------------------------------------------------------------

Tested the whole thing in editor over four levels, all seems well.
Didn´t do tests with compiled (exported) level - yet!

HERE is a ready to go solution for standard lever, add custom if desired^^
Twin Sounds for Levers
DL: grimrock_lever_twin_custom_sounds.7z

Can it be done simpler?

Re: Custom sounds for custom levers, buttons or other animat

Posted: Fri Jan 31, 2014 11:21 pm
by germanny
Well.. haha.. :oops:
While testing the handwheel lever custom sounds, i didn´t hear normal sound if party stood in front of the lever.
So i made an addition to the twin sound script, sound shifting +1 field to avoid that.

In fact.. mmh :D - i have a receiver with 7.1 sound coupled to my pc, and today i noticed
that the front right speaker didn´t make any noise^^
It was a loose connection with the output cables, now it is fixed :evil:

Sorry for my mistake, this was the last thing i thought about.
The script works anyway, but my fix isn´t needed. I´ll patch that by deactivate the lines..
maybe one of you has sometimes a defective speaker, he can use this then xD

Corrected:
Ready to go solution twin sounds for standard lever, add custom levers+sounds if desired^^
Twin Sounds for Levers
DL: grimrock_lever_twin_custom_sounds.7z

..Damn^^

Re: Custom sounds for custom levers, buttons or other animat

Posted: Sat Feb 01, 2014 5:58 am
by Isaac
germanny wrote:...
Diarmuid suggested a nifty change to my original script; that being to define a block of objects by name, and assign the sounds that way.

Code: Select all

customSounds = {
["customButton_1"] = "buttonSound_1",
["customButton_2"] = "buttonSound_2",
["customLever_1"] = "leverSound_1",

-- Make this list as long as you want; include what you want.
-- Define each object that you include, and each sound to be played.
}

function soundEffect(caller)
 if customSounds[caller.name] then
    playSoundAt(customSounds[caller.name], caller.level, caller.x, caller.y);
  return;
 end
This works when you define each custom button or lever as a separate object. It's very effective, but the trade off is that you have to define those objects, and that you cannot change the sound by just changing the Id; you must erase and replace the object(s) on the map. The great benefit of it is that you don't have to micro-manage the object IDs, just place and forget, and it works with engine named assets ~because it ignores the object's unique id, and plays the sound based on what it is rather than what it's called.