Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playing sentence on the same channel of the same entity may lead to playing both sounds in parallel #1196

Closed
FreeSlave opened this issue Jan 1, 2023 · 3 comments

Comments

@FreeSlave
Copy link
Member

I have the entity that creates the entity singletone which plays a sound either in world or on player by attaching itself to the player.

// add somewhere, e.g. in sound.cpp

#define SF_AMBIENT_RADIO_NOT_ON_PLAYER 1

class CAmbientRadio : public CPointEntity
{
public:
	void Spawn();
	void Precache();
	void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
};

LINK_ENTITY_TO_CLASS( ambient_radio, CAmbientRadio )

void CAmbientRadio::Spawn()
{
	CPointEntity::Spawn();
	Precache();
}

void CAmbientRadio::Precache()
{
	PRECACHE_MODEL("sprites/iunknown.spr");
	//PRECACHE_SOUND(STRING(pev->message));
}

void CAmbientRadio::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
	edict_t* pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 );

	if (!pPlayer) {
		ALERT(at_console, "Could not find a player to play a radio message on!\n");
		return;
	}

	const char *szSoundFile = STRING( pev->message );

	CBaseEntity* pRadioEnt = UTIL_FindEntityByTargetname(0, "__player_radio");
	if (!pRadioEnt) {
		edict_t	*pent;

		pent = CREATE_NAMED_ENTITY( MAKE_STRING( "info_target" ) );
		if( FNullEnt( pent ) )
		{
			ALERT ( at_console, "NULL info_target!\n" );
			return;
		}
		pRadioEnt = Instance( pent );
		pRadioEnt->pev->origin = pPlayer->v.origin;
		pRadioEnt->pev->angles = pPlayer->v.angles;

		if (pRadioEnt) {
			ALERT(at_console, "Created radio info_target\n");
			pRadioEnt->pev->targetname = MAKE_STRING("__player_radio");
			pRadioEnt->pev->movetype = MOVETYPE_FOLLOW;
			pRadioEnt->pev->aiment = pPlayer;
			DispatchSpawn(pRadioEnt->edict());
			SET_MODEL( pRadioEnt->edict(), "sprites/iunknown.spr" );
			pRadioEnt->pev->rendermode = kRenderTransAlpha;
		}
	}

	if (pRadioEnt) {
		float attenuation = ATTN_NORM;
		if (FBitSet(pev->spawnflags, SF_AMBIENT_RADIO_NOT_ON_PLAYER)) {
			pRadioEnt->pev->movetype = MOVETYPE_NONE;
			pRadioEnt->pev->aiment = 0;
			UTIL_SetOrigin(pRadioEnt->pev, pev->origin);
		} else {
			pRadioEnt->pev->movetype = MOVETYPE_FOLLOW;
			pRadioEnt->pev->aiment = pPlayer;
			attenuation = ATTN_NONE;
		}

		EMIT_SOUND( pRadioEnt->edict(), CHAN_VOICE, szSoundFile, 1.0f, attenuation);
	}
}

The point is to override any sentence which is currently played on CHAN_VOICE on triggering other ambient_radio. This way we should ensure that two sentences don't play in parallel, and it works this way in GoldSource.

However it doesn't work as expected in Xash3D, at least when one ambient_radio plays a sentence in world, and other one plays another sentence on the player. Instead both are playing in parallel.

Here's the test map: radiotest.bsp.zip. Push two buttons to reproduce the bug.

Field Intensity mod is affected by the bug when playing on Xash3D, on the map fid1a0a. Pickup the radio right after the radioman plays its sentence and you'll hear his next sentence playing in parallel to the previous one.

@a1batross
Copy link
Member

We probably need that mixer rewrite I planned a while ago.

@a1batross
Copy link
Member

Turns out, it isn't a mixer error, but yet another undocumented Xash extension.

In SV_BuildSoundMsg, there is a check:

	if( SV_IsValidEdict( ent ) && SV_IsValidEdict( ent->v.aiment ))
		entityIndex = NUM_FOR_EDICT( ent->v.aiment );
	else if( SV_IsValidEdict( ent ))
		entityIndex = NUM_FOR_EDICT( ent );
	else entityIndex = 0; // assume world

When an entity has an aiment set, the sound is automatically gets attached to that entity.

I think this check is kinda stupid, if a game developer explicitly passed an edict to EmitSound, then they might actually want to play sound from that entity, not from whatever was set in the aiment.

This check was added more than 10 years ago: FWGS/Xash3DArchive@8f6f3fc. Judging by changelog entry, it was made to fix the sound problem with weapons. I'm pretty sure this is an outdated check and can be safely reverted.

@a1batross
Copy link
Member

080eba9

a1batross referenced this issue Jul 6, 2024
…me from has an aiment set

This check was added 10+ years ago in 8f6f3fc (viewable in Xash3DArchive) and
probably doesn't make any sense anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants