Make sound stop in area

I wanted to, when the PC is entering an area, that some sounds would stop. Earlier there was a fire in the area but the fire has stopped so I wanted to stop the fire sounds also. I made a script like this:

#include "ginc_param_const"

void main()

{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

object oTarget1;
object oTarget2;
object oTarget3;
object oTarget4;
object oTarget5;
object oTarget6;
object oTarget7;

oTarget1 = GetSoundObjectByTag("SmolderLarge");
oTarget2 = GetSoundObjectByTag("FireSmolder");
oTarget3 = GetSoundObjectByTag("FireLarge1");
oTarget4 = GetSoundObjectByTag("FireLarge2");
oTarget5 = GetSoundObjectByTag("FireMedium2");
oTarget6 = GetSoundObjectByTag("FireMedium1");
oTarget7 = GetSoundObjectByTag("Firepit");

SoundObjectStop(oTarget1);
SoundObjectStop(oTarget2);
SoundObjectStop(oTarget3);
SoundObjectStop(oTarget4);
SoundObjectStop(oTarget5);
SoundObjectStop(oTarget6);
SoundObjectStop(oTarget7);

}

However, this wont work. Nothing happens. Maybe I’m missing something…

I’d probably start by checking that the returned sound objects are valid.

You could also put in a Delay before stopping the sounds and see if that will allow the sounds to start and then get stopped.

I don’t think delay would work in this case, because I’ve tried with the PC coming to the area and then entering the New Generic Trigger with this script that is supposed to make the sounds stop, but nothing happens.

If I were to put a check if the sound objects are invalid in the script what would that solve? Then if nothing happens I wouldn’t know if it is because the objects are invalid or if there is some other weird misstake I’ve made, but sure, I can do that… And, I mean, why would they be invalid? I’ve looked at the area under sounds and just copied the tags of the sounds from there onto the script. Let’s say they are in some weird way invalid, how do I make the sounds stop then? Is there no way to make a “painted” sound stop in an area?

Ok, so now I’ve changed the script to this, but just like before nothing happens:

#include "ginc_param_const"

void main()

{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;


	object oTarget1 = GetSoundObjectByTag("SmolderLarge");
	if (GetIsObjectValid(oTarget1)) 
		SoundObjectStop(oTarget1);

	object oTarget2 = GetSoundObjectByTag("FireSmolder");
	if (GetIsObjectValid(oTarget2)) 
		SoundObjectStop(oTarget2);

	object oTarget3 = GetSoundObjectByTag("FireLarge1");
	if (GetIsObjectValid(oTarget3)) 
		SoundObjectStop(oTarget3);
		
	object oTarget4 = GetSoundObjectByTag("FireLarge2");
	if (GetIsObjectValid(oTarget4)) 
		SoundObjectStop(oTarget4);
	
	object oTarget5 = GetSoundObjectByTag("FireMedium2");
	if (GetIsObjectValid(oTarget5)) 
		SoundObjectStop(oTarget5);
				
	
	object oTarget6 = GetSoundObjectByTag("FireMedium1");
	if (GetIsObjectValid(oTarget6)) 
		SoundObjectStop(oTarget6);		
		
	object oTarget7 = GetSoundObjectByTag("Firepit");
	if (GetIsObjectValid(oTarget7)) 
		SoundObjectStop(oTarget7);
				
}

One thing that I’m wondering if that could be the problem is that some of the sounds I’ve painted more than one time in the area. Maybe that is what scews it up.

This is how it looks in the toolset of the area.

Why not look and see how they stopped the sound of the fire from MotB. You know after you destroy the fire creature trying to burn down the forest.

2 Likes

the function GetSoundObjectByTag() in ‘ginc_param_const’ is not a healthy function. There’s no OBJECT_TYPE_SOUND, so it relies on the target being OBJECT_TYPE_INVALID.

That assumes that only sound-objects are invalid …

 
so I think Rj means give yourself feedback (to chat) if the objects are being found. Eg,

object oTarget1 = GetSoundObjectByTag("SmolderLarge");
if (GetIsObjectValid(oTarget1))
{
    SendMessageToPC(GetFirstPC(FALSE), ". SmolderLarge is VALID");
    SoundObjectStop(oTarget1);
}

 
what i’d be tempted to do (however) is label each of the sound-objects w/ a tag prefix, like “sound_fire_”

then loop over all objects in the area, searching for the tag prefix …

    object oScan = GetFirstObjectInArea();
    while (GetIsObjectValid(oScan))
    {
        if (GetStringLeft(GetTag(oScan), 11) == "sound_fire_")
        {
            SendMessageToPC(GetFirstPC(FALSE), ". found fire sound= " + GetTag(oScan)); // debug only.
            SoundObjectStop(oScan);
        }
        oScan = GetNextObjectInArea();
    }

 
With debug in place you can narrow down (a) are the sounds being found, (b) or is there a problem w/ SoundObjectStop()

1 Like

Thanks for the replies! I’m not totally following you with the last bit of what you’re saying KevL_s so I’ll wait with that…

I trust your judgement if you say that GetSoundObjectByTag is not a healthy function, so I will try with just using GetObjectByTag instead. In the Script Generator they use the old normal GetObjectByTag but since I found the script ga_sound_object_stop and looked at that, I thought that was the way to do things. So I’ll try with this first and see how it goes:

void main()

{


object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

object oTarget1;
object oTarget2;
object oTarget3;
object oTarget4;
object oTarget5;
object oTarget6;
object oTarget7;

oTarget1 = GetObjectByTag("SmolderLarge");
oTarget2 = GetObjectByTag("FireSmolder");
oTarget3 = GetObjectByTag("FireLarge1");
oTarget4 = GetObjectByTag("FireLarge2");
oTarget5 = GetObjectByTag("FireMedium2");
oTarget6 = GetObjectByTag("FireMedium1");
oTarget7 = GetObjectByTag("Firepit");

SoundObjectStop(oTarget1);
SoundObjectStop(oTarget2);
SoundObjectStop(oTarget3);
SoundObjectStop(oTarget4);
SoundObjectStop(oTarget5);
SoundObjectStop(oTarget6);
SoundObjectStop(oTarget7);

}

Maybe, like you said, there is something wrong with SoundObjectStop…

I will then test the SendMessageToPC thing.

I will also check, like you said Greenman6220, the fire in MotB. It was about 10 years ago that I played MotB so I actually don’t remember that thing at all. But I will search in the module. Maybe it is easy to find?

Hmmm. This is interesting. I did a script like this (from your suggestion rjshae and kevL_s):

void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

object oTarget1 = GetObjectByTag("SmolderLarge");
if (GetIsObjectValid(oTarget1))
{
    SendMessageToPC(GetFirstPC(FALSE), ". SmolderLarge is VALID");
    SoundObjectStop(oTarget1);
}

object oTarget2 = GetObjectByTag("FireSmolder");
if (GetIsObjectValid(oTarget2))
{
    SendMessageToPC(GetFirstPC(FALSE), ". FireSmolder is VALID");
    SoundObjectStop(oTarget2);
}

object oTarget3 = GetObjectByTag("FireLarge1");
if (GetIsObjectValid(oTarget3))
{
    SendMessageToPC(GetFirstPC(FALSE), ". FireLarge1 is VALID");
    SoundObjectStop(oTarget3);
}

object oTarget4 = GetObjectByTag("FireLarge2");
if (GetIsObjectValid(oTarget4))
{
    SendMessageToPC(GetFirstPC(FALSE), ". FireLarge2 is VALID");
    SoundObjectStop(oTarget4);
}

object oTarget5 = GetObjectByTag("FireMedium2");
if (GetIsObjectValid(oTarget5))
{
    SendMessageToPC(GetFirstPC(FALSE), ". FireMedium2 is VALID");
    SoundObjectStop(oTarget5);
}

object oTarget6 = GetObjectByTag("FireMedium1");
if (GetIsObjectValid(oTarget6))
{
    SendMessageToPC(GetFirstPC(FALSE), ". FireMedium1 is VALID");
    SoundObjectStop(oTarget6);
}


object oTarget7 = GetObjectByTag("Firepit");
if (GetIsObjectValid(oTarget7))
{
    SendMessageToPC(GetFirstPC(FALSE), ". Firepit is VALID");
    SoundObjectStop(oTarget7);
}


}

And in game I now got a return message that every one of the objects were valid! So…that has to mean that there is something wrong with SoundObjectStop() right? Or am I interpreting this the wrong way?

Your script with looping kevL_s is above my understanding but still I tried something like this (if that was what you intended):

void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;

object oScan = GetFirstObjectInArea();
    while (GetIsObjectValid(oScan))
    {
        if (GetStringLeft(GetTag(oScan), 11) == "sound_fire_")
        {
            SendMessageToPC(GetFirstPC(FALSE), ". found fire sound= " + GetTag(oScan)); // debug only.
            SoundObjectStop(oScan);
        }
        oScan = GetNextObjectInArea();
    }
}

When testing this in game absolutely nothing happened however…

You could output a feedback message at the top of the routine, before doing anything else, just to make sure it is firing.

It looks like you have 14 fire sound objects you want to shut off. So give all of your fire sound objects unique tags of fire1, fire2, fire3…and so on until the last one, fire14.

Then use this script:

#include "ginc_param_const"

void main()
{
	object oPC = GetEnteringObject();

	if (!GetIsPC(oPC)) return;

	int i;

	for (i; i < 15; i++)
	{ 
		SoundObjectStop(GetSoundObjectByTag("fire" + IntToString(i)));
	}
}

Tried your suggestion travus but it didn’t work either. I don’t know what’s going on. It should have worked. Your sollution seemed the most simple and logical.

I feel like I’ve tried everything now. I even found something in the MotB, a part of a script that looked like this, that I thought felt promising:

#include "ginc_math"
#include "c_inc_global"
#include "kinc_spirit_eater"

const string FIRE_WP = "wp_fire";
const string FIRE_RR = "c_fx_tree_fire";
const string TORCH_TAG = "NW_IT_TORCH001";
const string BLAZE_TAG = "c_fx_blaze_fire";
const string VAR_DISABLED = "bFireDisabled";
const string FIRE_SOUND_TAG = "sfx_fire";
const int NUM_BURNABLE_TREES = 11;

void StopFireSounds(object oNear)
{
	int i = 1;
	object oSound = GetNearestObjectByTag(FIRE_SOUND_TAG,oNear,i);
	while(GetIsObjectValid(oSound))
	{
		SoundObjectStop(oSound);
		i++;
		oSound = GetNearestObjectByTag(FIRE_SOUND_TAG,oNear,i);
	}
}

So I made my own version of that:

#include "ginc_math"
#include "c_inc_global"
#include "kinc_spirit_eater"


const string FIRE_WP = "wp_fire";
const string FIRE_RR = "c_fx_tree_fire";
const string TORCH_TAG = "NW_IT_TORCH001";
const string BLAZE_TAG = "c_fx_blaze_fire";
const string VAR_DISABLED = "bFireDisabled";
const string FIRE_SOUND_TAG = "sfx_fire";
const int NUM_BURNABLE_TREES = 11;

void main()
{

object oPC = GetEnteringObject();

if (!GetIsPC(oPC)) return;



int i = 1;
object oSound = GetNearestObjectByTag(FIRE_SOUND_TAG,oPC,i);

while(GetIsObjectValid(oSound))
	{
		SoundObjectStop(oSound);
		i++;
		oSound = GetNearestObjectByTag(FIRE_SOUND_TAG,oPC,i);
	}
}

But with this I didn’t really know what I was doing. Still the compiler didn’t complain, and I renamed all the tags of my fire sounds to sfx_fire so…but as before nothing happens.

I’m really tempted right now to just copy the area and make one version without sound, but I have so many areas already that I thought it would be nice if I didn’t need to do that. And I shouldn’t need to do that, I think.

I tried with travus’ script again to control that the trigger is firing as it should and in game I got the message so the script is firing. But the darn fire sounds are still there:

#include "ginc_param_const"

void main()
{
	object oPC = GetEnteringObject();

	if (!GetIsPC(oPC)) return;

	SendMessageToPC(GetFirstPC(FALSE), "This trigger works");
	
	int i;

	for (i; i < 15; i++)
	{ 
		SoundObjectStop(GetSoundObjectByTag("fire" + IntToString(i)));
	}
}

Are you testing this by having the PC enter the area? Or are you launching the game and testing it with the PC already in the area?

I am testing this by having the PC enter the area from another area, teleporting by New Area Transition. Then I walk with the PC into the trigger so to speak.

That’s strange. I created a small test area with 14 different sound objects similar to yours. I then used the script I mentioned above and they all shut off as expected. The script was fired from the OnEnter of a trigger. Just to confirm, all of the sound objects in question have unique tags of fire1, fire2, fire3 and so on?

Yes, although I changed the tags of the sounds when they were already in the area. I didn’t make new blueprints with new tags (I was a bit unsure of this, if this was possible, but in MotB it seemed they had done it that way, and the toolset didn’t crash) and placed them there anew.

I know there’s an issue with light objects losing their tags, so that light management requires storing the light objects on the area. Not sure if there is a similar situation with sounds. But the fact that you’re not getting a hit on any of the objects makes me wonder.

Another option would be to use Ipoints.