Skip to content

Commit

Permalink
Add ambient_extraspeaker
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeSlave committed Sep 2, 2024
1 parent 5236a19 commit 2c4b91c
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 18 deletions.
1 change: 1 addition & 0 deletions common/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
// entity flags
#define EFLAG_SLERP 1 // do studio interpolation of this entity
#define EFLAG_FLESH_SOUND 2
#define EFLAG_PREVENT_ORIGIN_UNSETTING 4

//
// temp entity events
Expand Down
9 changes: 6 additions & 3 deletions dlls/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1605,9 +1605,12 @@ void Entity_Encode( struct delta_s *pFields, const unsigned char *from, const un
if( ( t->movetype == MOVETYPE_FOLLOW ) &&
( t->aiment != 0 ) )
{
DELTA_UNSETBYINDEX( pFields, entity_field_alias[FIELD_ORIGIN0].field );
DELTA_UNSETBYINDEX( pFields, entity_field_alias[FIELD_ORIGIN1].field );
DELTA_UNSETBYINDEX( pFields, entity_field_alias[FIELD_ORIGIN2].field );
if ((t->eflags & EFLAG_PREVENT_ORIGIN_UNSETTING) == 0)
{
DELTA_UNSETBYINDEX( pFields, entity_field_alias[FIELD_ORIGIN0].field );
DELTA_UNSETBYINDEX( pFields, entity_field_alias[FIELD_ORIGIN1].field );
DELTA_UNSETBYINDEX( pFields, entity_field_alias[FIELD_ORIGIN2].field );
}
}
else if( t->aiment != f->aiment )
{
Expand Down
115 changes: 104 additions & 11 deletions dlls/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ class CAmbientGeneric : public CBaseEntity
int m_iChannel; //LRC - the channel to play from, for "play from X" sounds
EHANDLE m_hActivator; // this is for m_hPlayFrom, in case the entity is !activator

bool EntityToPlayFromIsDefined();
CBaseEntity* GetEntityToPlayFrom(CBaseEntity* pActivator);
virtual bool EntityToPlayFromIsDefined();
virtual CBaseEntity* GetEntityToPlayFrom(CBaseEntity* pActivator);
};

LINK_ENTITY_TO_CLASS( ambient_generic, CAmbientGeneric )
Expand Down Expand Up @@ -290,14 +290,11 @@ void CAmbientGeneric::Precache( void )
m_fActive = TRUE;
}

if( m_fActive )
if (m_fActive && !EntityToPlayFromIsDefined())
{
if (!EntityToPlayFromIsDefined())
{
UTIL_EmitAmbientSound( ENT( pev ), pev->origin, szSoundFile,
( m_dpv.vol * 0.01f ), m_flAttenuation, SND_SPAWNING, m_dpv.pitch );
pev->nextthink = gpGlobals->time + 0.1f;
}
UTIL_EmitAmbientSound( ENT( pev ), pev->origin, szSoundFile,
( m_dpv.vol * 0.01f ), m_flAttenuation, SND_SPAWNING, m_dpv.pitch );
pev->nextthink = gpGlobals->time + 0.1f;
}
}

Expand All @@ -318,8 +315,8 @@ void CAmbientGeneric::Activate()
CBaseEntity *pTarget = GetEntityToPlayFrom(m_hActivator);
if (!pTarget)
{
ALERT(at_console, "WARNING: ambient_generic \"%s\" can't find \"%s\", its entity to play from.\n",
STRING(pev->targetname), STRING(pev->target));
ALERT(at_console, "WARNING: %s \"%s\" can't find \"%s\", its entity to play from.\n",
STRING(pev->classname), STRING(pev->targetname), STRING(pev->target));
}
else
{
Expand Down Expand Up @@ -2171,3 +2168,99 @@ void CEnvSoundMark::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
UTIL_Remove(this);
}
}

class CExtraSpeaker : public CPointEntity
{
public:
void Think()
{
// Gargbage collection
CBaseEntity* pOwner = nullptr;
if (!FNullEnt(pev->owner))
{
pOwner = CBaseEntity::Instance(pev->owner);
}
if (!pOwner)
{
ALERT(at_console, "Removing %s because the owner has expired\n", STRING(pev->classname));
UTIL_Remove(this);
return;
}
pev->nextthink = gpGlobals->time + 1.0f;
}
};

LINK_ENTITY_TO_CLASS( extra_speaker, CExtraSpeaker )

class CAmbientExtraSpeaker : public CAmbientGeneric
{
public:
CBaseEntity* GetEntityToPlayFrom(CBaseEntity *pActivator);
bool EntityToPlayFromIsDefined() { return true; }

protected:
CBaseEntity* GetTargetEntity(CBaseEntity* pActivator);
CBaseEntity* GetSpeakerEntity(CBaseEntity* pTargetEntity);
};

LINK_ENTITY_TO_CLASS( ambient_extraspeaker, CAmbientExtraSpeaker )

CBaseEntity* CAmbientExtraSpeaker::GetEntityToPlayFrom(CBaseEntity *pActivator)
{
CBaseEntity* pTargetEntity = GetTargetEntity(pActivator);
if (!pTargetEntity)
return nullptr;

CBaseEntity* pSpeakerEntity = GetSpeakerEntity(pTargetEntity);
if (pSpeakerEntity)
{
pSpeakerEntity->pev->movetype = MOVETYPE_FOLLOW;
pSpeakerEntity->pev->aiment = pTargetEntity->edict();
}
return pSpeakerEntity;
}

CBaseEntity* CAmbientExtraSpeaker::GetTargetEntity(CBaseEntity *pActivator)
{
CBaseEntity* pTargetEntity = nullptr;
if (FStringNull(pev->target))
{
pTargetEntity = g_pGameRules->EffectivePlayer(pActivator);
}
else
{
pTargetEntity = UTIL_FindEntityByTargetname(nullptr, STRING(pev->target), pActivator);
}
return pTargetEntity;
}

CBaseEntity* CAmbientExtraSpeaker::GetSpeakerEntity(CBaseEntity *pTargetEntity)
{
CBaseEntity* pEntity = nullptr;
while((pEntity = UTIL_FindEntityByClassname(pEntity, "extra_speaker")) != nullptr)
{
if (pTargetEntity->edict() == pEntity->pev->owner)
{
return pEntity;
}
}

if (!pEntity) {
pEntity = CBaseEntity::CreateNoSpawn("extra_speaker", pTargetEntity->pev->origin, pTargetEntity->pev->angles);

if (pEntity) {
ALERT(at_console, "Created %s for %s\n", STRING(pEntity->pev->classname), STRING(pTargetEntity->pev->classname));
pEntity->pev->movetype = MOVETYPE_FOLLOW;
pEntity->pev->aiment = pTargetEntity->edict();
pEntity->pev->owner = pTargetEntity->edict();
pEntity->m_EFlags |= EFLAG_PREVENT_ORIGIN_UNSETTING;
DispatchSpawn(pEntity->edict());
SET_MODEL(pEntity->edict(), "sprites/iunknown.spr");
pEntity->pev->rendermode = kRenderTransAlpha;
pEntity->pev->renderamt = 0;
pEntity->pev->nextthink = gpGlobals->time + 1.0f;
}
}

return pEntity;
}
42 changes: 38 additions & 4 deletions fgd/halflife.fgd
Original file line number Diff line number Diff line change
Expand Up @@ -1153,11 +1153,15 @@

@PointClass base(ScriptedSequence) = aiscripted_sequence:"AI Scripted Sequence" []

@BaseClass iconsprite("sprites/ambient_generic.spr") base(Targetname) = Ambient
@BaseClass base(Targetname) = AmbientBase
[
message(sound) : "WAV Name"
health(integer) : "Volume (10 = loudest)" : 10
target(target_destination) : "Entity to play from"
]

@BaseClass = AmbientPlayFrom
[
target(target_generic) : "Entity to play from"
channel(choices) : "Channel to use for that entity" =
[
0: "Default (Static)"
Expand All @@ -1168,6 +1172,10 @@
5: "Stream"
6: "Static"
]
]

@BaseClass = AmbientDetails
[
preset(choices) :"Dynamic Presets" =
[
0: "None"
Expand Down Expand Up @@ -1232,16 +1240,42 @@
]
]

@PointClass base(Ambient) = ambient_generic : "Universal Ambient" []
@BaseClass = AmbientExtraSpeaker
[
target(string) : "Attach to entity" : "*player"
channel(choices) : "Channel to use" =
[
0: "Default (Static)"
1: "Weapon"
2: "Voice"
3: "Item"
4: "Body"
5: "Stream"
6: "Static"
]
]

@PointClass iconsprite("sprites/ambient_generic.spr") base(AmbientBase, AmbientExtraSpeaker, AmbientDetails) = ambient_extraspeaker : "Ambient played on the automatically created entity that is attached to another entity. This allows to play sounds like if they were playing from the main entity without interfering with its own audio channels. Use this for radio or narrator messages that should follow the player around."
[
spawnflags(flags) =
[
16 : "Start Silent": 1
32 : "Not Toggled": 1
]
]

@PointClass iconsprite("sprites/ambient_generic.spr") base(AmbientBase, AmbientPlayFrom, AmbientDetails) = ambient_generic : "Universal Ambient" []

@PointClass base(Ambient) = ambient_random : "Universal Ambient playing a random sound"
@BaseClass = AmbientRandomWavs
[
noise(sound) : "WAV Name 1"
noise1(sound) : "WAV Name 2"
noise2(sound) : "WAV Name 3"
noise3(sound) : "WAV Name 4"
]

@PointClass iconsprite("sprites/ambient_generic.spr") base(AmbientBase, AmbientRandomWavs, AmbientPlayFrom, AmbientDetails) = ambient_random : "Universal Ambient playing a random sound" []

//
// ammo
//
Expand Down

0 comments on commit 2c4b91c

Please sign in to comment.