Skip to content

Commit

Permalink
add custom sentences
Browse files Browse the repository at this point in the history
vanilla hl clients can't play attach custom sentences to an edict ("spk" command), so the server plays custom sentences as normal sounds. This means sentence word timing will be affected by network lag. Start offsets (s0-100) and tempo changes (t0-100) also don't work. No mod-level custom sentences use these effects.
  • Loading branch information
wootguy committed Nov 20, 2024
1 parent 5fa82a3 commit 9119f91
Show file tree
Hide file tree
Showing 13 changed files with 542 additions and 11 deletions.
32 changes: 26 additions & 6 deletions dlls/CBaseToggle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "saverestore.h"
#include "nodes.h"
#include "CBaseDoor.h"
#include "sentences.h"

// Global Savedata for Toggle
TYPEDESCRIPTION CBaseToggle::m_SaveData[] =
Expand Down Expand Up @@ -209,17 +210,36 @@ float CBaseToggle::AxisDelta(int flags, const Vector& angle1, const Vector& angl
return angle1.y - angle2.y;
}


void CBaseToggle::PlaySentence(const char* pszSentence, float duration, float volume, float attenuation)
{
if (pszSentence && IsAlive())
{
if (pszSentence[0] == '!')
EMIT_SOUND_DYN(edict(), CHAN_VOICE, pszSentence, volume, attenuation, 0, PITCH_NORM);
else if (pszSentence[0] == '+')
if (pszSentence[0] == '!') {
CustomSentence* sent = GetCustomSentence(pszSentence + 1);

if (sent) {
AddCustomSentencePlayer(this, sent, volume, attenuation);
}
else {
// default sentence, let the engine handle it
EMIT_SOUND_DYN(edict(), CHAN_VOICE, pszSentence, volume, attenuation, 0, PITCH_NORM);
}
}
else if (pszSentence[0] == '+') {
// path to a sound file, not a sentence name
EMIT_SOUND_DYN(edict(), CHAN_VOICE, pszSentence + 1, volume, attenuation, 0, PITCH_NORM);
else
SENTENCEG_PlayRndSz(edict(), pszSentence, volume, attenuation, 0, PITCH_NORM);
}
else {
CustomSentence* sent = GetRandomCustomSentence(pszSentence);

if (sent) {
AddCustomSentencePlayer(this, sent, volume, attenuation);
}
else {
// default sentence, let the engine handle it
SENTENCEG_PlayRndSz(edict(), pszSentence, volume, attenuation, 0, PITCH_NORM);
}
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions dlls/CBaseToggle.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once
#include "CBaseAnimating.h"

struct CustomSentence;

//
// generic Toggle entity.
//
Expand Down Expand Up @@ -33,6 +35,12 @@ class EXPORT CBaseToggle : public CBaseAnimating

int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does

CustomSentence* m_customSent;
float m_customSentStartTime; // when the sentence began playing
float m_customSentVol; // overall volume for the custom sentence
float m_customSentAttn; // attenuation for the custom sentence
int m_customSentLastWord; // last sentence word which was played

virtual int Save(CSave& save);
virtual int Restore(CRestore& restore);

Expand Down
2 changes: 2 additions & 0 deletions dlls/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ set(UTIL_HDR
util/lagcomp.h
util/vector.h
util/Scheduler.h
util/sentences.h
util/TextMenu.h
util/ThreadSafeInt.h
util/ThreadSafeQueue.h
Expand All @@ -447,6 +448,7 @@ set(UTIL_SRC
util/lagcomp.cpp
util/saverestore.cpp
util/Scheduler.cpp
util/sentences.cpp
util/subs.cpp
util/TextMenu.cpp
util/ThreadSafeInt.cpp
Expand Down
42 changes: 42 additions & 0 deletions dlls/CWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "teamplay_gamerules.h"
#include "bodyque.h"
#include "PluginManager.h"
#include "sentences.h"

extern CGraph WorldGraph;
extern CSoundEnt* pSoundEnt;
Expand Down Expand Up @@ -100,6 +101,41 @@ void CWorld::loadReplacementFiles() {
g_soundReplacements.insert(g_soundReplacementsMod.begin(), g_soundReplacementsMod.end());
}

void CWorld::loadSentenceFiles() {
const char* sentPath = "sound/hlcoop/sentences.txt";
static uint64_t lastEditTimeSent = 0;

std::string spath = getGameFilePath(sentPath);

if (spath.empty()) {
g_customSentencesMod.clear();
g_customSentenceGroupsMod.clear();
ALERT(at_warning, "Missing sentence file: %s\n", sentPath);
}

uint64_t editTimeSent = getFileModifiedTime(spath.c_str());

if (lastEditTimeSent != editTimeSent) {
lastEditTimeSent = editTimeSent;
LoadSentenceFile(sentPath, g_customSentencesMod, g_customSentenceGroupsMod);
}

g_customSentencesMap.clear();
g_customSentenceGroupsMap.clear();
if (m_sentenceFile) {
LoadSentenceFile(STRING(m_sentenceFile), g_customSentencesMap, g_customSentenceGroupsMap);
}

// map models/sounds have priority over mod models
g_customSentences.clear();
g_customSentences.insert(g_customSentencesMap.begin(), g_customSentencesMap.end());
g_customSentences.insert(g_customSentencesMod.begin(), g_customSentencesMod.end());

g_customSentenceGroups.clear();
g_customSentenceGroups.insert(g_customSentenceGroupsMap.begin(), g_customSentenceGroupsMap.end());
g_customSentenceGroups.insert(g_customSentenceGroupsMod.begin(), g_customSentenceGroupsMod.end());
}

void CWorld::Precache(void)
{
#if 1
Expand All @@ -124,6 +160,7 @@ void CWorld::Precache(void)
g_pluginManager.UpdatePlugins();
}
loadReplacementFiles();
loadSentenceFiles();

// init here so sprites can be replaced
g_VoiceGameMgr.Init(&g_GameMgrHelper, gpGlobals->maxClients);
Expand Down Expand Up @@ -439,6 +476,11 @@ void CWorld::KeyValue(KeyValueData* pkvd)
m_globalSoundList = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "sentence_file"))
{
m_sentenceFile = ALLOC_STRING(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "freeroam"))
{
m_freeRoam = atoi(pkvd->szValue) == 1;
Expand Down
2 changes: 2 additions & 0 deletions dlls/CWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ class EXPORT CWorld : public CBaseEntity
void Precache( void );
void KeyValue( KeyValueData *pkvd );
void loadReplacementFiles();
void loadSentenceFiles();
const char* getDisplayName() { return "World"; }

string_t m_globalModelList;
string_t m_globalSoundList;
string_t m_sentenceFile;
string_t m_wadlist;
bool m_freeRoam;
};
3 changes: 2 additions & 1 deletion dlls/EHandle.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "CBaseEntity.h"

class CBaseEntity;

//
// EHANDLE. Safe way to point to CBaseEntities who may die between frames
Expand Down
3 changes: 2 additions & 1 deletion dlls/game/gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ void execMapCfg() {
"starthealth",
"globalmodellist",
"globalsoundlist",
"sentence_file",
"mp_shitcode",
"map_plugin",
"nosuit",
Expand Down Expand Up @@ -269,7 +270,7 @@ void execMapCfg() {
}

// model/sound lists must be loaded now or else other entities might precache the wrong files
if (name == "globalmodellist" || name == "globalsoundlist") {
if (name == "globalmodellist" || name == "globalsoundlist" || name == "sentence_file") {
KeyValueData dat;
dat.fHandled = false;
dat.szClassName = (char*)"worldspawn";
Expand Down
3 changes: 3 additions & 0 deletions dlls/hooks/hlds_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "CGamePlayerEquip.h"
#include "PluginManager.h"
#include "Scheduler.h"
#include "sentences.h"

#if !defined ( _WIN32 )
#include <ctype.h>
Expand Down Expand Up @@ -914,6 +915,8 @@ void StartFrame( void )

g_Scheduler.Think();

PlayCustomSentences();

handleThreadPrints();
}

Expand Down
8 changes: 6 additions & 2 deletions dlls/monster/CScriptedSentence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "schedule.h"
#include "CCineMonster.h"
#include "defaultai.h"
#include "sentences.h"

class CScriptedSentence : public CBaseToggle
{
Expand Down Expand Up @@ -160,8 +161,11 @@ void CScriptedSentence::Spawn(void)
}

void CScriptedSentence::Precache(void) {
if (m_iszSentence && STRING(m_iszSentence)[0] == '+') {
PRECACHE_SOUND(STRING(m_iszSentence) + 1);
if (m_iszSentence) {
if (STRING(m_iszSentence)[0] == '+')
PRECACHE_SOUND(STRING(m_iszSentence) + 1);
else
PrecacheCustomSentence(this, STRING(m_iszSentence));
}
}

Expand Down
Loading

0 comments on commit 9119f91

Please sign in to comment.