BigTruck's Fan Page

BOD Python Scripting

10 - Sounds

Things a bit quiet? Sounds and Music add a lot of atmos to a map.

In mapping terms, Sounds and Music are different things. Music is not 'heard' in the map as such. It is like the music in a movie.
Sounds are localised and have a position in the map and are louder the nearer the Player is to them.

Sounds need to be created in a similar way to objects, etc. If you intend using lots of them, make a separate file. Name it mysounds.py or sonidos.py (to keep it in its native language.) Yes, there is a source file Sounds.py . This is the code to create sounds:
			import Bladex
			snd_bang1=Bladex.CreateSound("..\\..\\sounds\\golpe-arma-escudo.wav","SoundBang1")
The filepath to the sound file in the Sounds folder is included in the code. There are a lot of sound files and most of them have Spanish names, but you soon figure it out. (golpe = hit for example). Exec the file in cfg.py as before.

What happens after you have created the sound? Nothing . You have to play it with a function call:
snd_bang1.Play(49000, 6000, -58000,0)
This code is usually put in a function to correspond with an event.
The first three arguments are the map coords for the focus of the sound. The last 0 is the number of times the file will be played, in this case once. (put 1 and you get 2 bangs.). Some sounds are looped so that they can play continuously. For a looped sound (wind,waterfall,fire, etc) put -1.

Sometimes you want a sound to play at the Player position. You may not know where exactly the Player may be. You can 'get' the current Player position (and anything else for that matter) with this:
			charpos=Bladex.GetEntity("Player1").Position
			snd_bang1.Play(charpos[0],charpos[1]charpos[2],0)
You might be wondering why all the []s have appeared. Why not just put charpos. Well, the variable charpos has three values stored. You have to unpack them. So charpos[0] acesses the first value (the X coord), etc. You could do it like this:
			x,z,y=Bladex.GetEntity("Player1").Position
			snd_bang1.Play(x,z,y,0)
Which is probably neater. There is usually more than one of doing things in Python.

Sounds have many Attributes. Some I am not sure exactly the purpose of. The useful ones are:
			snd_bang1.Volume=0.8
			snd_bang1.MinDistance=500
			snd_bang1.MaxDistnce=50000
Which are self explanatary. (I am not sure whether sounds get any louder if you set the Volume greater than 1.0)

There is also Pitch, which can be useful to vary sounds slightly.
There is a function that allows you to play sounds at random intervals.
			snd_crow1=CreatePeriodicSound("..\\..\\sounds\\raven-call.wav","SoundCrow1",20,8,(40000,-2000,67000))
			snd_crow1.PlayPeriodic()
It includes two extra args, 20,8. The sound will play at a random interval somewhere between 20 and 8 seconds. Set these values to your own preferences.

Music

The backgroud music is all defined in a file 'MusicEvents.py'. This is a key file and must have that name for savegame integrity. Exec it as usual in cfg.py.
			import Bladex

			# for .wav files
			Bladex.AddMusicEventADCPM("Atmos24","..\\..\\sounds\\ATMOSFERA24.wav",1.0,1.0,1.0,1.0,0,-1)

			# for mp3s

			Bladex.AddMusicEventMP3(....rest is the same
There are 6 args follwing the filepath. In practice you only need pay attention to the last one. Like Sounds it controls the number of times the file is played. 0 for once, -1 continuous.

You start the music with this:
Bladex.ExeMusicEvent(Bladex.GetMusicEvent("Atmos24"))
this call is usually contained in a function.

To stop whatever music is playing:
Bladex.KillMusic()
You usually have to 'kill' whatever music is playing before starting a new track.

CombatMusic

You can assign music to enemies that starts to play when they go into Combat mode. Use the same MusicEvents.py file but:
			import DMusic
			Dmusic.AddCombatMusic("Ork1",..\\..\\sounds\\combate-hard.wav,400,1.0,1.0,1.0,1.0)
You can assign it to individual enemies or a whole Kind.

I haven't quite figured all the args yet, but the first is the priority. If you have lots of enemies in a group, set this value slightly lower for each one so that they don't all try to play their music at once.

If there was a piece of background music playing when you started fighting the Ork, it will not resume after he is dead. His combat music will stop and there will be silence. I made a little routine to restore the music (if any).

In DefFuncs.py:
			CurrentMusic="" # declare a variable and assign and empty string ""

			def ChangeMusic(music):
			Bladex.KillMusic()
			Bladex.ExeMusicEvent(music)
			global CurrentMusic
			CurrentMusic=music

			#then, start all music with:

			ChangeMusic("Atmos24")
A word on global variables. If you need to access a variable within the body of a function, you must declare it as a global or it will not be recognised. With this func you can change the music at any time and the identity of the music is stored in the CurrentMusic var.

Then if you happen to have to interrupt the music for any reason, you can restore it with:
			def ResumeMusic():
				global CurrentMusic
				Bladex.KillMusic()
				if CurrentMusic != "": 
					 Bladex.ExeMusicEvent(CurrentMusic)

			# to clear the var if necessary

			def StopMusic():
				global CurrentMusic
				Bladex.KillMusic()
				CurrentMusic=""
This func is most likely to be called after the death of an enemy. Then, whatever music was playing when you started the fight will carry on after enemy is dead. For this you have to tap into his ImDead function. I'll come to that later.

You can either use the Sounds library, or you can make your own. To use your own stuff, just alter the filepath to your own file:

"..\\..\\Maps\\MyMap\\coolsound1.wav"