Frictional Games Forum (read-only)
[SCRIPT] Sounds don't play - Printable Version

+- Frictional Games Forum (read-only) (https://www.frictionalgames.com/forum)
+-- Forum: Amnesia: The Dark Descent (https://www.frictionalgames.com/forum/forum-6.html)
+--- Forum: Custom Stories, TCs & Mods - Development (https://www.frictionalgames.com/forum/forum-38.html)
+---- Forum: Development Support (https://www.frictionalgames.com/forum/forum-39.html)
+---- Thread: [SCRIPT] Sounds don't play (/thread-19533.html)

Pages: 1 2


RE: Sounds don't play - The chaser - 12-13-2012

(12-13-2012, 10:50 AM)beecake Wrote: Can you fix the error? Smile
I don't see the issue. It's, probabily, an easy one that I haven't seen. What fails is the callback.


RE: Sounds don't play - TheGreatCthulhu - 12-17-2012

What do you think this line of code does?
"windysound_"+RandInt(1, 3);

Are you trying to make a call to one of your windysound_# functions?
What that line does is it simply creates a string, that is then never used.
Better add them as timer callbacks or something along those lines.


RE: Sounds don't play - The chaser - 12-17-2012

(12-17-2012, 01:40 PM)TheGreatCthulhu Wrote: What do you think this line of code does?
"windysound_"+RandInt(1, 3);

Are you trying to make a call to one of your windysound_# functions?
What that line does is it simply creates a string, that is then never used.
Better add them as timer callbacks or something along those lines.
Uhmmm... I'll try timers instead the other thing. I'm in my laptop right now, so I can't test it. Sorry for not replying, I was waiting for the page 200 in the Random stuff thread to post my 1.000 post Big Grin


RE: Sounds don't play - TheGreatCthulhu - 12-19-2012

In this case, you can think of timer functionality as of a way to indirectly make a function call via a string that matches it's name, with the extra benefit of being able to set when the call should occur. However, there are some limitations - the signature (parameter list) has to match to the one defined for the timer callback, and there's probably some performance overhead.

A better, more flexible way to do it is to use function handles (funcdefs). If you're not that familiar with them, funcdefs make it possible for you to define a data type that allows you to create variables that point to functions, and then use those variables to make calls to the pointed-to functions as if you were calling them in the normal way.
What you should be able to do (I'm not in position to test it at the moment as well) is to create an array of function handles ("pointers"), initialize those handles to your functions, and then use the RandInt() function to pick one randomly from the array (by simply using the random number to access it by index).

I'll probably be able to test this later on today, so I'll write some more guidelines about the syntax and the overall approach - till then, here's a tutorial on funcdefs .


RE: Sounds don't play - TheGreatCthulhu - 12-19-2012

So, about using funcdefs instead - first you'd define a function handle type, like this:
funcdef void WindFunc();

This should be a global declaration (outside of any function).

Here, WindFunc is a function pointer type which can point to any function wich has the signature:
void SomeFuncName();

==> and your functions do, so they qualify:
void windysound_1 ()

Then you can declare (globally) an array of these function handles (function pointers):
WindFunc@[] functions(3); // declares an array of size 3

Next, in OnEnter(), you can assign the appropriate function to each member of the array:
@functions[0] = @windysound_1;
@functions[1] = @windysound_2;
@functions[2] = @windysound_3;


Finally, when the time comes, you can pick one randomly, and make the call, like this:
WindFunc@ f = functions[RandInt(0, functions.length() - 1)];
f();


In the first line, RandInt(0, functions.length() - 1) randomly picks an index to some array member ( indices range from 0 to length-1). The resulting array member is assigned to the local variable f, and then in the next line, f is used to make the call to whichever of your windysound_#() functions got picked.

BTW, if it's easier to undersand, you can also write the same thing like this:

int maxValue = functions.length() - 1;
int index = RandInt(0, maxValue);
WindFunc@ f = functions[index];
f();



RE: Sounds don't play - The chaser - 12-19-2012

(12-19-2012, 08:07 PM)TheGreatCthulhu Wrote: So, about using funcdefs instead - first you'd define a function handle type, like this:
funcdef void WindFunc();

This should be a global declaration (outside of any function).

Here, WindFunc is a function pointer type which can point to any function wich has the signature:
void SomeFuncName();

==> and your functions do, so they qualify:
void windysound_1 ()

Then you can declare (globally) an array of these function handles (function pointers):
WindFunc@[] functions(3); // declares an array of size 3

Next, in OnEnter(), you can assign the appropriate function to each member of the array:
@functions[0] = @windysound_1;
@functions[1] = @windysound_2;
@functions[2] = @windysound_3;


Finally, when the time comes, you can pick one randomly, and make the call, like this:
Action@ f = functions[RandInt(0, functions.length() - 1)];
f();


In the first line, RandInt(0, functions.length() - 1) randomly picks an index to some array member ( indices range from 0 to length-1). The resulting array member is assigned to the local variable f, and then in the next line, f is used to make the call to whichever of your windysound_#() functions got picked.

BTW, if it's easier to undersand, you can also write the same thing like this:

int maxValue = functions.length() - 1;
int index = RandInt(0, maxValue);
Action@ f = functions[index];
f();

TheGreatChtulhu, you have the sea of your mind filled with knowledge XD

Now, you seem a good scripter, but I'm not so that good. Can you please put me an example for this? It's just that I'm not familiar with this, you know? Oh, and thanks to take your time in helping me Smile


RE: Sounds don't play - TheGreatCthulhu - 12-19-2012

OK. Using your original script as a starting point, it would look something like this:
PHP Code:
funcdef void WindFunc();
WindFunc@[] functions(3);

void OnEnter()
{
    
AddTimer(""1"Wind");

    
// Note that the indices start from 0, not 1!
    
@functions[0] = @windysound_1;
    @
functions[1] = @windysound_2;
    @
functions[2] = @windysound_3;

}


void Wind (string &in asTimer)
{
    
AddTimer(""0.1"Windy");
    
PlaySoundAtEntity("wind_amb""wind_amb.snt"""1.ffalse);
}

void Windy (string &in asTimer)
{
    
CreateParticleSystemAtEntity("""ps_dust_whirl""Windy_"+RandInt(17), false);

    
int index RandInt(0functions.length() - 1);   // in this case same as RandInt(0,  2)
    
WindFuncfunctions[index];
    
f();

    
AddTimer(""RandInt(1.07.0), "Windy");
}

void windysound_1()
{
    
PlaySoundAtEntity("""scare_wind.snt""Windy_"+RandInt(17), 0.ffalse);
}

void windysound_2()
{
    
PlaySoundAtEntity("""scare_wind_reverse.snt","Windy_"+RandInt(17), 0.ffalse);
}

void windysound_3()
{
    
PlaySoundAtEntity("""general_wind_whirl_rand.snt""Windy_"+RandInt(17), 0.ffalse);


The only difference to your original code is that here I declared the funcdef at the top, and the function pointer array right after it. Then all the function pointers inside the array are set to point to windysound_#() functions.

And then, in place of your
"windysound_"+RandInt(1, 3);

line, there's this instead:
int index = RandInt(0, functions.length() - 1); // in this case same as RandInt(0, 2)
WindFunc@ f = functions[index];
f();


P.S. I just noticed I made an accidental mistake in my previous post; wherever it says Action it should say WindFunc instead. In my test code I named it Action, but then decided to change it to WindFunc in order for it to make more sense in your map. Gonna edit the post to correct.

The timer based alternative would go like this:
PHP Code:
void OnEnter()
{
    
AddTimer(""1"Wind");
}


void Wind (string &in asTimer)
{
    
AddTimer(""0.1"Windy");
    
PlaySoundAtEntity("wind_amb""wind_amb.snt"""1.ffalse);
}

void Windy (string &in asTimer)
{
    
CreateParticleSystemAtEntity("""ps_dust_whirl""Windy_"+RandInt(17), false);
    
    
AddTimer(""0.0f"windysound_" RandInt(13));     // <--------- here

    
AddTimer(""RandInt(1.07.0), "Windy");    // <--- BTW, you probably wanted RandFloat() here?
}

void windysound_1(string &in asTimer)
{
    
AddDebugMessage("wnd_1"false);
    
PlaySoundAtEntity("""scare_wind.snt""Windy_"+RandInt(17), 0.ffalse);
}

void windysound_2(string &in asTimer)
{
    
AddDebugMessage("wnd_2"false);
    
PlaySoundAtEntity("""scare_wind_reverse.snt","Windy_"+RandInt(17), 0.ffalse);


If using timers, make sure that you change the parameter lists for windysound_#() functions to match those required for timer callbacks.

With funcdefs you don't need to do that - funcdef can be defined to point to a function with arbitrary parameter list and return type (see the tutorial from a few posts above), so they offer more flexibility.