As we all know, Spring has supported the "play-sound" command in scripts since 0.63b1:
-Added support for loading TA:K COB files and implemented the TA:K-specific opcode play-sound.
This allows a unitmaker to play any sound he wants (a wav file in the /sounds/ directory) at any volume at any point in the script. This is useful, since now we can do things such as running engine sounds while units move, foot step noises, or anything else of that nature.
Getting it to work isn't as simple as that makes it appear, though. After bothering Fnordia for a while, we finally got it working nicely.
Since I use scriptor, that's all this little guide is written for. I don't think any other compilers would be up to this task anyway. First of all, you must be compiling in TA:K mode. You can either click the little green TAK button in the scriptor GUI or you can put the following line at the beginning of your script:
#define TAK
Secondly, you cannot use the stock SmokeUnit.h file. If your unit uses SmokeUnit and you want it to play sounds, you can't right off the bat. This is because TAK handled smoking units differently than TA, mainly with a different function, but the point is if you try to compile with the original SmokeUnit you will crash scriptor.
So, to rectify this, I've made a hacked up Spring-sound-ready Smokeunit.h. It's available for download by clicking here. Simply put this .h file in your Includes directory, and then change the line:
#include "smokeunit.h"
in any scripts you want to play sounds in with:
#include "springsmoke.h"
And everything will compile and work just fine (barring other errors on your part, of course). You don't have to make this change for units that don't use play-sound.
Then, to use play-sound, you just type in the following line:
play-sound("filename", 1);
where filename is the filename of the .wav file in the /sounds/ directory to play, and 1 is the volume. There is no limit to volume afaik. For reference, I had to use a volume value of 10 for the Raven's explosion sound to make it about the same volume as it is normally in game. There's no limit to what functions it can be played in, as far as I know, but I'm sure putting a play-sound in a repeating loop without a sleep wouldn't be a good thing.
Using play-sound in Spring
Moderator: Moderators
- GrOuNd_ZeRo
- Posts: 1370
- Joined: 30 Apr 2005, 01:10
Just a random update to this:
After further experimenting, putting play-sound in StartMoving() does not loop, at least not without doing while( TRUE ), and last time I tried that in Spring it froze up (I imagine because it's an infinite loop). It will only play the sound in StartMoving() once, UNLESS (this is the important part!) the unit is in first person control! If the unit is being manually controlled, StartMoving() is apparently continuously called. I call this the Zwzsg Effect, in honor of zwzsg's battle with the constantly-being-called AimPrimary() function.
Anyway, what this means is that with some crafty scripting, you could probably make engine noises (such as a running engine) when a unit is in first person control. Ok, the scripting isn't all that crafty. It'd be along these lines:
Where X is the length of the sound in milliseconds. This is necessary because otherwise the game just continuously starts the sound without waiting to start it again. Also note my volume in that example--sounds in first person are far louder than normal. You should take into consideration the fact that the sound will be played one time every time the unit is issued an order which results in moving in third person as well. Finally, remember that this little first-person engine sound hack is purely conjecture on my part, I haven't actually tested it yet but from what I have done with StartMoving() and play-sound it should work.
After further experimenting, putting play-sound in StartMoving() does not loop, at least not without doing while( TRUE ), and last time I tried that in Spring it froze up (I imagine because it's an infinite loop). It will only play the sound in StartMoving() once, UNLESS (this is the important part!) the unit is in first person control! If the unit is being manually controlled, StartMoving() is apparently continuously called. I call this the Zwzsg Effect, in honor of zwzsg's battle with the constantly-being-called AimPrimary() function.
Anyway, what this means is that with some crafty scripting, you could probably make engine noises (such as a running engine) when a unit is in first person control. Ok, the scripting isn't all that crafty. It'd be along these lines:
Code: Select all
StartMoving() {
if( TRUE ) {
play-sound("filename", 5);
sleep X;
}
}
Actually, the battle was short, as soon as I figured out that my problems came from AimPrimary being constantly re-called, I "protected" all the aiming script of my Spring unit from then on.
Your script workaround doesn't seem right to me. I know Cavedog's script use if( TRUE ) alot, but still TRUE being always true not matter what, a if(TRUE) {...} is the same as not having any if, right?
What I'd advise to use would be more:
Your script workaround doesn't seem right to me. I know Cavedog's script use if( TRUE ) alot, but still TRUE being always true not matter what, a if(TRUE) {...} is the same as not having any if, right?
What I'd advise to use would be more:
Code: Select all
static-var DoingTheMovingSound;
Create()
{
DoingTheMovingSound=FALSE;// Don't forget the initialisation!
....
....
}
StartMoving()
{
if(DoingTheMovingSound)
{return;}
DoingTheMovingSound=TRUE;
play-sound("filename", 5);
sleep X;
DoingTheMovingSound=FALSE;
}
-
- Posts: 854
- Joined: 28 Jan 2005, 18:15
Wouldn't something like this work better?
This should make engine sound while the unit is moving, with special start and stop sounds (which will play every time the unit is issued new order, even if it didn't stop, might need tweaking to work around that).
Code: Select all
static-var isMoving;
SoundControl()
{
while(TRUE)
{
if(isMoving)
{
play-sound("engine", 2);
}
//Adjust according to sound length
sleep 200;
}
}
Create()
{
isMoving = FALSE;
start-script SoundControl();
...
}
StartMoving()
{
play-sound("engine_start", 2);
//wait till it's played completely
sleep 200;
isMoving = TRUE;
...
}
StopMoving()
{
isMoving = FALSE;
//wait till engine sound stops
sleep 200;
play-sound("engine_stop", 2);
...
}