mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-19 06:00:24 +02:00
1514 lines
40 KiB
C++
1514 lines
40 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// soundman.cpp: Sound Manager
|
|
//
|
|
|
|
#include "g_local.h"
|
|
#include "debuglines.h"
|
|
#include "entity.h"
|
|
#include "trigger.h"
|
|
#include "player.h"
|
|
#include "soundman.h"
|
|
|
|
SoundManager SoundMan;
|
|
|
|
/******************************************************************************
|
|
|
|
Sound Manager
|
|
|
|
******************************************************************************/
|
|
|
|
Event EV_SoundManager_AddSpeaker
|
|
(
|
|
"addspeaker",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Add a new sound where the player is standing.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_AddRandomSpeaker
|
|
(
|
|
"addrandomspeaker",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Add a new sound where the player is standing.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_AddMusicTrigger
|
|
(
|
|
"addmusictrigger",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Add a new music trigger where the player is standing.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_AddReverbTrigger
|
|
(
|
|
"addreverbtrigger",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Add a new reverb trigger where the player is standing.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_Replace
|
|
(
|
|
"replace",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Replace the current sound position with the player's.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_Delete
|
|
(
|
|
"delete",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Delete the current sound.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_MovePlayer
|
|
(
|
|
"moveplayer",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Move the player to the current sound position.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_Next
|
|
(
|
|
"next",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Go to the next sound.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_Previous
|
|
(
|
|
"prev",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Go to the previous sound.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_Show
|
|
(
|
|
"show",
|
|
EV_CONSOLE,
|
|
"E",
|
|
"path",
|
|
"Show all the sounds.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_ShowingSounds
|
|
(
|
|
"_showing_sounds",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Internal event for showing the sounds.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_Hide
|
|
(
|
|
"hide",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Hides the sounds.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_Save
|
|
(
|
|
"save",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Saves the sounds.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_SoundManager_UpdateInput
|
|
(
|
|
"updateinput",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Updates the current sound with user interface values.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_Reset
|
|
(
|
|
"reset",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Resets the state of all sounds and triggers.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_GlobalTranslate
|
|
(
|
|
"globaltranslate",
|
|
EV_CONSOLE,
|
|
"v",
|
|
"translate_amount",
|
|
"Translates all sounds and triggers by specified amount.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_SwitchFacet
|
|
(
|
|
"switchfacet",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Switch the current facet that we are editing.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_PreviewReverb
|
|
(
|
|
"previewreverb",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"Test out the current reverb settings.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
Event EV_SoundManager_ResetReverb
|
|
(
|
|
"resetreverb",
|
|
EV_CONSOLE,
|
|
NULL,
|
|
NULL,
|
|
"reset the reverb settings to a normal.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
CLASS_DECLARATION(Listener, SoundManager, NULL) {
|
|
{&EV_SoundManager_AddSpeaker, &SoundManager::AddSpeaker },
|
|
{&EV_SoundManager_AddRandomSpeaker, &SoundManager::AddRandomSpeaker },
|
|
{&EV_SoundManager_AddMusicTrigger, &SoundManager::AddMusicTrigger },
|
|
{&EV_SoundManager_AddReverbTrigger, &SoundManager::AddReverbTrigger },
|
|
{&EV_SoundManager_Replace, &SoundManager::Replace },
|
|
{&EV_SoundManager_Delete, &SoundManager::Delete },
|
|
{&EV_SoundManager_MovePlayer, &SoundManager::MovePlayer },
|
|
{&EV_SoundManager_Next, &SoundManager::Next },
|
|
{&EV_SoundManager_Previous, &SoundManager::Previous },
|
|
{&EV_SoundManager_Show, &SoundManager::Show },
|
|
{&EV_SoundManager_ShowingSounds, &SoundManager::ShowingSounds },
|
|
{&EV_SoundManager_Hide, &SoundManager::Hide },
|
|
{&EV_SoundManager_Save, &SoundManager::Save },
|
|
{&EV_SoundManager_UpdateInput, &SoundManager::UpdateEvent },
|
|
{&EV_SoundManager_Reset, &SoundManager::ResetEvent },
|
|
{&EV_SoundManager_GlobalTranslate, &SoundManager::GlobalTranslateEvent},
|
|
{&EV_SoundManager_SwitchFacet, &SoundManager::SwitchFacetEvent },
|
|
{&EV_SoundManager_PreviewReverb, &SoundManager::PreviewReverbEvent },
|
|
{&EV_SoundManager_ResetReverb, &SoundManager::ResetReverbEvent },
|
|
{NULL, NULL }
|
|
};
|
|
|
|
Player *SoundManager_GetPlayer(void)
|
|
{
|
|
assert(g_entities[0].entity && g_entities[0].entity->isSubclassOf(Player));
|
|
if (!g_entities[0].entity || !(g_entities[0].entity->isSubclassOf(Player))) {
|
|
gi.Printf("No player found.\n");
|
|
return NULL;
|
|
}
|
|
|
|
return (Player *)g_entities[0].entity;
|
|
}
|
|
|
|
SoundManager::SoundManager()
|
|
{
|
|
currentFacet = 0;
|
|
Reset();
|
|
}
|
|
|
|
void SoundManager::Reset(void)
|
|
{
|
|
current = NULL;
|
|
soundList.ClearObjectList();
|
|
}
|
|
|
|
void SoundManager::UpdateUI(void)
|
|
{
|
|
if (current) {
|
|
gi.cvar_set("snd_multifaceted", "");
|
|
gi.cvar_set("snd_currentfacet", "");
|
|
gi.cvar_set("snd_onetime", "0");
|
|
gi.cvar_set("snd_useangles", "0");
|
|
gi.cvar_set("snd_yaw", "0");
|
|
|
|
gi.cvar_set("snd_origin", va("%.2f %.2f %.2f", current->origin[0], current->origin[1], current->origin[2]));
|
|
gi.cvar_set("snd_targetname", current->targetname.c_str());
|
|
if (current->isSubclassOf(TriggerSpeaker)) {
|
|
TriggerSpeaker *speaker;
|
|
|
|
speaker = (TriggerSpeaker *)current;
|
|
if (speaker->volume != DEFAULT_VOL) {
|
|
gi.cvar_set("snd_volume", va("%.1f", speaker->volume));
|
|
} else {
|
|
gi.cvar_set("snd_volume", "Default");
|
|
}
|
|
if (speaker->min_dist != DEFAULT_MIN_DIST) {
|
|
gi.cvar_set("snd_mindist", va("%.1f", speaker->min_dist));
|
|
} else {
|
|
gi.cvar_set("snd_mindist", "Default");
|
|
}
|
|
|
|
// setup the sound
|
|
gi.cvar_set("ui_pickedsound", speaker->Noise().c_str());
|
|
|
|
if (current->isSubclassOf(RandomSpeaker)) {
|
|
RandomSpeaker *random;
|
|
|
|
random = (RandomSpeaker *)current;
|
|
gi.cvar_set("snd_mindelay", va("%.1f", random->mindelay));
|
|
gi.cvar_set("snd_maxdelay", va("%.1f", random->maxdelay));
|
|
gi.cvar_set("snd_channel", va("%d", random->channel));
|
|
gi.cvar_set("snd_chance", va("%.1f", random->chance));
|
|
gi.cvar_set("snd_type", "RandomSpeaker");
|
|
} else {
|
|
gi.cvar_set("snd_type", "Speaker");
|
|
}
|
|
} else if (current->isSubclassOf(TriggerMusic) || current->isSubclassOf(TriggerReverb)) {
|
|
int multiFaceted;
|
|
Trigger *trigger;
|
|
|
|
trigger = (Trigger *)current;
|
|
gi.cvar_set("snd_width", va("%.0f", trigger->maxs[0]));
|
|
gi.cvar_set("snd_length", va("%.0f", trigger->maxs[1]));
|
|
gi.cvar_set("snd_height", va("%.0f", trigger->maxs[2]));
|
|
if (trigger->UsingTriggerDir()) {
|
|
gi.cvar_set("snd_useangles", "1");
|
|
} else {
|
|
gi.cvar_set("snd_useangles", "0");
|
|
}
|
|
gi.cvar_set("snd_yaw", va("%.0f", trigger->angles[1]));
|
|
multiFaceted = trigger->GetMultiFaceted();
|
|
if (multiFaceted) {
|
|
if (multiFaceted == 1) {
|
|
gi.cvar_set("snd_multifaceted", "North/South");
|
|
if (currentFacet) {
|
|
gi.cvar_set("snd_currentfacet", "South");
|
|
} else {
|
|
gi.cvar_set("snd_currentfacet", "North");
|
|
}
|
|
} else {
|
|
gi.cvar_set("snd_multifaceted", "East/West");
|
|
if (currentFacet) {
|
|
gi.cvar_set("snd_currentfacet", "West");
|
|
} else {
|
|
gi.cvar_set("snd_currentfacet", "East");
|
|
}
|
|
}
|
|
} else {
|
|
gi.cvar_set("snd_multifaceted", "Not");
|
|
}
|
|
|
|
if (current->isSubclassOf(TriggerMusic)) {
|
|
TriggerMusic *music;
|
|
|
|
music = (TriggerMusic *)trigger;
|
|
|
|
gi.cvar_set("snd_type", "MusicTrigger");
|
|
if (music->oneshot) {
|
|
gi.cvar_set("snd_onetime", "1");
|
|
} else {
|
|
gi.cvar_set("snd_onetime", "0");
|
|
}
|
|
|
|
if (!currentFacet) {
|
|
gi.cvar_set("snd_currentmood", Director.GetString(music->current).c_str());
|
|
gi.cvar_set("snd_fallbackmood", Director.GetString(music->fallback).c_str());
|
|
} else {
|
|
gi.cvar_set("snd_currentmood", Director.GetString(music->altcurrent).c_str());
|
|
gi.cvar_set("snd_fallbackmood", Director.GetString(music->altfallback).c_str());
|
|
}
|
|
} else if (current->isSubclassOf(TriggerReverb)) {
|
|
TriggerReverb *reverb;
|
|
|
|
reverb = (TriggerReverb *)trigger;
|
|
|
|
gi.cvar_set("snd_type", "ReverbTrigger");
|
|
if (reverb->oneshot) {
|
|
gi.cvar_set("snd_onetime", "1");
|
|
} else {
|
|
gi.cvar_set("snd_onetime", "0");
|
|
}
|
|
|
|
if (!currentFacet) {
|
|
gi.cvar_set("snd_reverbtypedisplay", EAXMode_NumToName(reverb->reverbtype));
|
|
gi.cvar_set("snd_reverbtype", va("%d", reverb->reverbtype));
|
|
gi.cvar_set("snd_reverblevel", va("%.2f", reverb->reverblevel));
|
|
} else {
|
|
gi.cvar_set("snd_reverbtypedisplay", EAXMode_NumToName(reverb->altreverbtype));
|
|
gi.cvar_set("snd_reverbtype", va("%d", reverb->altreverbtype));
|
|
gi.cvar_set("snd_reverblevel", va("%.2f", reverb->altreverblevel));
|
|
}
|
|
}
|
|
}
|
|
if (EventPending(EV_SoundManager_ShowingSounds)) {
|
|
gi.cvar_set("snd_hiddenstate", "visible");
|
|
} else {
|
|
gi.cvar_set("snd_hiddenstate", "hidden");
|
|
}
|
|
gi.cvar_set("snd_speakernum", va("%d", soundList.IndexOfObject(current) - 1));
|
|
}
|
|
}
|
|
|
|
void SoundManager::UpdateRandomSpeaker(RandomSpeaker *speaker)
|
|
{
|
|
cvar_t *cvar;
|
|
Vector tempvec;
|
|
|
|
if (!speaker) {
|
|
return;
|
|
}
|
|
|
|
// get origin
|
|
cvar = gi.Cvar_Get("snd_origin", "", 0);
|
|
sscanf(cvar->string, "%f %f %f", &tempvec[0], &tempvec[1], &tempvec[2]);
|
|
speaker->setOrigin(tempvec);
|
|
|
|
// get targetname
|
|
cvar = gi.Cvar_Get("snd_targetname", "", 0);
|
|
speaker->SetTargetName(cvar->string);
|
|
|
|
// get volume
|
|
cvar = gi.Cvar_Get("snd_volume", "", 0);
|
|
if (str(cvar->string) == "Default") {
|
|
speaker->SetVolume(DEFAULT_VOL);
|
|
} else {
|
|
speaker->SetVolume(cvar->value);
|
|
}
|
|
|
|
// get min_dist
|
|
cvar = gi.Cvar_Get("snd_mindist", "", 0);
|
|
if (str(cvar->string) == "Default") {
|
|
speaker->SetMinDist(DEFAULT_MIN_DIST);
|
|
} else {
|
|
speaker->SetMinDist(cvar->value);
|
|
}
|
|
|
|
// get mindelay
|
|
cvar = gi.Cvar_Get("snd_mindelay", "", 0);
|
|
speaker->SetMinDelay(cvar->value);
|
|
|
|
// get maxdelay
|
|
cvar = gi.Cvar_Get("snd_maxdelay", "", 0);
|
|
speaker->SetMaxDelay(cvar->value);
|
|
|
|
// get chance
|
|
cvar = gi.Cvar_Get("snd_chance", "", 0);
|
|
speaker->SetChance(cvar->value);
|
|
|
|
// get sound
|
|
cvar = gi.Cvar_Get("ui_pickedsound", "", 0);
|
|
if (cvar->string[0]) {
|
|
speaker->SetNoise(cvar->string);
|
|
speaker->ScheduleSound();
|
|
}
|
|
}
|
|
|
|
void SoundManager::UpdateSpeaker(TriggerSpeaker *speaker)
|
|
{
|
|
cvar_t *cvar;
|
|
Vector tempvec;
|
|
|
|
if (!speaker) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// make sure the speaker is an ambient speaker
|
|
//
|
|
speaker->ambient = true;
|
|
|
|
// get origin
|
|
cvar = gi.Cvar_Get("snd_origin", "", 0);
|
|
sscanf(cvar->string, "%f %f %f", &tempvec[0], &tempvec[1], &tempvec[2]);
|
|
speaker->setOrigin(tempvec);
|
|
|
|
// get targetname
|
|
cvar = gi.Cvar_Get("snd_targetname", "", 0);
|
|
speaker->SetTargetName(cvar->string);
|
|
|
|
// get volume
|
|
cvar = gi.Cvar_Get("snd_volume", "", 0);
|
|
if (str(cvar->string) == "Default") {
|
|
speaker->SetVolume(DEFAULT_VOL);
|
|
} else {
|
|
speaker->SetVolume(cvar->value);
|
|
}
|
|
|
|
// get min_dist
|
|
cvar = gi.Cvar_Get("snd_mindist", "", 0);
|
|
if (str(cvar->string) == "Default") {
|
|
speaker->SetMinDist(DEFAULT_MIN_DIST);
|
|
} else {
|
|
speaker->SetMinDist(cvar->value);
|
|
}
|
|
|
|
// get sound
|
|
cvar = gi.Cvar_Get("ui_pickedsound", "", 0);
|
|
if (cvar->string[0]) {
|
|
speaker->SetNoise(cvar->string);
|
|
speaker->StartSound();
|
|
}
|
|
}
|
|
|
|
void SoundManager::UpdateTriggerMusic(TriggerMusic *music)
|
|
{
|
|
cvar_t *cvar;
|
|
str current;
|
|
str fallback;
|
|
str faceted;
|
|
Vector tempvec;
|
|
|
|
if (!music) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// go to a known state
|
|
//
|
|
|
|
music->SetOneShot(false);
|
|
// no angle use
|
|
music->useTriggerDir = false;
|
|
// make sure it doesn't trigger
|
|
music->triggerable = false;
|
|
|
|
// get origin
|
|
cvar = gi.Cvar_Get("snd_origin", "", 0);
|
|
sscanf(cvar->string, "%f %f %f", &tempvec[0], &tempvec[1], &tempvec[2]);
|
|
music->setOrigin(tempvec);
|
|
|
|
// get targetname
|
|
cvar = gi.Cvar_Get("snd_targetname", "", 0);
|
|
music->SetTargetName(cvar->string);
|
|
|
|
// get width
|
|
cvar = gi.Cvar_Get("snd_width", "", 0);
|
|
music->mins[0] = -cvar->value;
|
|
music->maxs[0] = cvar->value;
|
|
|
|
// get length
|
|
cvar = gi.Cvar_Get("snd_length", "", 0);
|
|
music->mins[1] = -cvar->value;
|
|
music->maxs[1] = cvar->value;
|
|
|
|
// get height
|
|
cvar = gi.Cvar_Get("snd_height", "", 0);
|
|
music->mins[2] = 0;
|
|
music->maxs[2] = cvar->value;
|
|
|
|
music->setSize(music->mins, music->maxs);
|
|
|
|
// get current multi faceted ness
|
|
cvar = gi.Cvar_Get("snd_multifaceted", "", 0);
|
|
faceted = cvar->string;
|
|
|
|
if (faceted == "North/South") {
|
|
music->SetMultiFaceted(1);
|
|
} else if (faceted == "East/West") {
|
|
music->SetMultiFaceted(2);
|
|
} else {
|
|
music->SetMultiFaceted(0);
|
|
}
|
|
|
|
// get current mood
|
|
cvar = gi.Cvar_Get("snd_currentmood", "", 0);
|
|
current = cvar->string;
|
|
|
|
// get fallback mood
|
|
cvar = gi.Cvar_Get("snd_fallbackmood", "", 0);
|
|
fallback = cvar->string;
|
|
|
|
if (music->multiFaceted && currentFacet) {
|
|
music->SetAltMood(current, fallback);
|
|
} else {
|
|
music->SetMood(current, fallback);
|
|
}
|
|
|
|
// get onetime
|
|
cvar = gi.Cvar_Get("snd_onetime", "", 0);
|
|
if (cvar->integer) {
|
|
music->SetOneShot(true);
|
|
}
|
|
|
|
// get yaw
|
|
cvar = gi.Cvar_Get("snd_yaw", "", 0);
|
|
music->angles[YAW] = cvar->value;
|
|
music->setAngles();
|
|
|
|
// get useangles
|
|
cvar = gi.Cvar_Get("snd_useangles", "", 0);
|
|
if (cvar->integer) {
|
|
music->SetTriggerDir(music->angles[YAW]);
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::UpdateTriggerReverb(TriggerReverb *reverb)
|
|
{
|
|
cvar_t *cvar;
|
|
int reverbtype;
|
|
float reverblevel;
|
|
str faceted;
|
|
Vector tempvec;
|
|
|
|
if (!reverb) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// go to a known state
|
|
//
|
|
|
|
reverb->SetOneShot(false);
|
|
// no angle use
|
|
reverb->useTriggerDir = false;
|
|
// make sure it doesn't trigger
|
|
reverb->triggerable = false;
|
|
|
|
// get origin
|
|
cvar = gi.Cvar_Get("snd_origin", "", 0);
|
|
sscanf(cvar->string, "%f %f %f", &tempvec[0], &tempvec[1], &tempvec[2]);
|
|
reverb->setOrigin(tempvec);
|
|
|
|
// get targetname
|
|
cvar = gi.Cvar_Get("snd_targetname", "", 0);
|
|
reverb->SetTargetName(cvar->string);
|
|
|
|
// get width
|
|
cvar = gi.Cvar_Get("snd_width", "", 0);
|
|
reverb->mins[0] = -cvar->value;
|
|
reverb->maxs[0] = cvar->value;
|
|
|
|
// get length
|
|
cvar = gi.Cvar_Get("snd_length", "", 0);
|
|
reverb->mins[1] = -cvar->value;
|
|
reverb->maxs[1] = cvar->value;
|
|
|
|
// get height
|
|
cvar = gi.Cvar_Get("snd_height", "", 0);
|
|
reverb->mins[2] = 0;
|
|
reverb->maxs[2] = cvar->value;
|
|
|
|
reverb->setSize(reverb->mins, reverb->maxs);
|
|
|
|
// get current multi faceted ness
|
|
cvar = gi.Cvar_Get("snd_multifaceted", "", 0);
|
|
faceted = cvar->string;
|
|
|
|
if (faceted == "North/South") {
|
|
reverb->SetMultiFaceted(1);
|
|
} else if (faceted == "East/West") {
|
|
reverb->SetMultiFaceted(2);
|
|
} else {
|
|
reverb->SetMultiFaceted(0);
|
|
}
|
|
|
|
// get reverb type
|
|
cvar = gi.Cvar_Get("snd_reverbtype", "", 0);
|
|
reverbtype = cvar->integer;
|
|
|
|
// get reverb level
|
|
cvar = gi.Cvar_Get("snd_reverblevel", "", 0);
|
|
reverblevel = cvar->value;
|
|
|
|
if (reverb->multiFaceted && currentFacet) {
|
|
reverb->SetAltReverb(reverbtype, reverblevel);
|
|
} else {
|
|
reverb->SetReverb(reverbtype, reverblevel);
|
|
}
|
|
|
|
// get onetime
|
|
cvar = gi.Cvar_Get("snd_onetime", "", 0);
|
|
if (cvar->integer) {
|
|
reverb->SetOneShot(true);
|
|
}
|
|
|
|
// get yaw
|
|
cvar = gi.Cvar_Get("snd_yaw", "", 0);
|
|
reverb->angles[YAW] = cvar->value;
|
|
reverb->setAngles();
|
|
|
|
// get useangles
|
|
cvar = gi.Cvar_Get("snd_useangles", "", 0);
|
|
if (cvar->integer) {
|
|
reverb->SetTriggerDir(reverb->angles[YAW]);
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::UpdateEvent(Event *ev)
|
|
{
|
|
if (!current) {
|
|
return;
|
|
}
|
|
if (current->isSubclassOf(RandomSpeaker)) {
|
|
UpdateRandomSpeaker((RandomSpeaker *)current);
|
|
} else if (current->isSubclassOf(TriggerSpeaker)) {
|
|
UpdateSpeaker((TriggerSpeaker *)current);
|
|
} else if (current->isSubclassOf(TriggerMusic)) {
|
|
UpdateTriggerMusic((TriggerMusic *)current);
|
|
} else if (current->isSubclassOf(TriggerReverb)) {
|
|
UpdateTriggerReverb((TriggerReverb *)current);
|
|
}
|
|
}
|
|
|
|
void SoundManager::AddSpeaker(Event *ev)
|
|
{
|
|
Player *player;
|
|
Vector ang;
|
|
Vector pos;
|
|
|
|
player = SoundManager_GetPlayer();
|
|
if (player) {
|
|
player->GetPlayerView(&pos, &ang);
|
|
|
|
current = new TriggerSpeaker;
|
|
current->setOrigin(pos);
|
|
current->setAngles(ang);
|
|
|
|
soundList.AddUniqueObject(current);
|
|
|
|
Show();
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::AddRandomSpeaker(Event *ev)
|
|
{
|
|
Player *player;
|
|
Vector ang;
|
|
Vector pos;
|
|
|
|
player = SoundManager_GetPlayer();
|
|
if (player) {
|
|
player->GetPlayerView(&pos, &ang);
|
|
|
|
current = new RandomSpeaker;
|
|
current->setOrigin(pos);
|
|
current->setAngles(ang);
|
|
|
|
soundList.AddUniqueObject(current);
|
|
|
|
Show();
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::AddMusicTrigger(Event *ev)
|
|
{
|
|
Player *player;
|
|
Vector ang;
|
|
|
|
player = SoundManager_GetPlayer();
|
|
if (player) {
|
|
player->GetPlayerView(NULL, &ang);
|
|
|
|
current = new TriggerMusic;
|
|
// we grab the origin from the feet of the player
|
|
current->setOrigin(player->origin);
|
|
current->setAngles(ang);
|
|
current->setSize(Vector("-16 -16 0"), Vector("16 16 64"));
|
|
// make sure it doesn't trigger
|
|
((TriggerMusic *)current)->triggerable = false;
|
|
|
|
soundList.AddUniqueObject(current);
|
|
|
|
Show();
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::AddReverbTrigger(Event *ev)
|
|
{
|
|
Player *player;
|
|
Vector ang;
|
|
|
|
player = SoundManager_GetPlayer();
|
|
if (player) {
|
|
player->GetPlayerView(NULL, &ang);
|
|
|
|
current = new TriggerReverb;
|
|
// we grab the origin from the feet of the player
|
|
current->setOrigin(player->origin);
|
|
current->setAngles(ang);
|
|
current->setSize(Vector("-16 -16 0"), Vector("16 16 64"));
|
|
// make sure it doesn't trigger
|
|
((TriggerReverb *)current)->triggerable = false;
|
|
|
|
soundList.AddUniqueObject(current);
|
|
|
|
Show();
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::Replace(Event *ev)
|
|
{
|
|
Player *player;
|
|
Vector ang;
|
|
Vector pos;
|
|
|
|
player = SoundManager_GetPlayer();
|
|
if (current && player) {
|
|
player->GetPlayerView(&pos, &ang);
|
|
|
|
if (current->isSubclassOf(TriggerMusic) || current->isSubclassOf(TriggerReverb)) {
|
|
current->setOrigin(player->origin);
|
|
} else {
|
|
current->setOrigin(pos);
|
|
}
|
|
current->setAngles(ang);
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::Delete(Event *ev)
|
|
{
|
|
int index = 0;
|
|
|
|
if (!current) {
|
|
return;
|
|
}
|
|
|
|
if (soundList.ObjectInList(current)) {
|
|
index = soundList.IndexOfObject(current);
|
|
// remove the speaker
|
|
soundList.RemoveObject(current);
|
|
}
|
|
current->PostEvent(EV_Remove, 0);
|
|
|
|
if ((index > 0) && (index < soundList.NumObjects())) {
|
|
current = soundList.ObjectAt(index);
|
|
CurrentGainsFocus();
|
|
} else {
|
|
current = NULL;
|
|
}
|
|
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::MovePlayer(Event *ev)
|
|
{
|
|
Player *player;
|
|
Vector pos;
|
|
|
|
player = SoundManager_GetPlayer();
|
|
if (current && player) {
|
|
player->GetPlayerView(&pos, NULL);
|
|
|
|
if (current->isSubclassOf(TriggerMusic) || current->isSubclassOf(TriggerReverb)) {
|
|
player->setOrigin(current->origin);
|
|
} else {
|
|
player->setOrigin(current->origin - pos + player->origin);
|
|
}
|
|
player->SetViewAngles(current->angles);
|
|
}
|
|
}
|
|
|
|
void SoundManager::CurrentLostFocus(void)
|
|
{
|
|
if (current) {
|
|
if (current->isSubclassOf(TriggerMusic) || current->isSubclassOf(TriggerReverb)) {
|
|
current->PostEvent(EV_Trigger_SetTriggerable, 0.1f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SoundManager::CurrentGainsFocus(void)
|
|
{
|
|
if (current) {
|
|
if (current->isSubclassOf(TriggerMusic) || current->isSubclassOf(TriggerReverb)) {
|
|
current->ProcessEvent(EV_Trigger_SetNotTriggerable);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SoundManager::Next(Event *ev)
|
|
{
|
|
int index;
|
|
|
|
currentFacet = 0;
|
|
|
|
if (current) {
|
|
//
|
|
// find current sound in container of sounds
|
|
//
|
|
index = soundList.IndexOfObject(current);
|
|
if (index < soundList.NumObjects()) {
|
|
index++;
|
|
} else {
|
|
index = 1;
|
|
}
|
|
CurrentLostFocus();
|
|
} else {
|
|
index = 1;
|
|
}
|
|
|
|
if (index <= soundList.NumObjects()) {
|
|
current = soundList.ObjectAt(index);
|
|
CurrentGainsFocus();
|
|
UpdateUI();
|
|
}
|
|
}
|
|
|
|
void SoundManager::Previous(Event *ev)
|
|
{
|
|
int index;
|
|
|
|
currentFacet = 0;
|
|
|
|
if (current) {
|
|
//
|
|
// find current sound in container of sounds
|
|
//
|
|
index = soundList.IndexOfObject(current);
|
|
if (index > 1) {
|
|
index--;
|
|
} else {
|
|
index = soundList.NumObjects();
|
|
}
|
|
CurrentLostFocus();
|
|
} else {
|
|
index = 1;
|
|
}
|
|
|
|
if (index <= soundList.NumObjects()) {
|
|
current = soundList.ObjectAt(index);
|
|
CurrentGainsFocus();
|
|
UpdateUI();
|
|
}
|
|
}
|
|
|
|
void SoundManager::ResetEvent(Event *ev)
|
|
{
|
|
int i;
|
|
Entity *ent;
|
|
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
ent = soundList.ObjectAt(i);
|
|
if (ent->isSubclassOf(TriggerSpeaker)) {
|
|
// nothing to reset
|
|
} else if (ent->isSubclassOf(TriggerMusic)) {
|
|
TriggerMusic *music;
|
|
|
|
music = (TriggerMusic *)ent;
|
|
music->SetOneShot(music->oneshot);
|
|
} else if (ent->isSubclassOf(TriggerReverb)) {
|
|
TriggerReverb *reverb;
|
|
|
|
reverb = (TriggerReverb *)ent;
|
|
reverb->SetOneShot(reverb->oneshot);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SoundManager::GlobalTranslateEvent(Event *ev)
|
|
{
|
|
int i;
|
|
Entity *ent;
|
|
Vector amount;
|
|
|
|
amount = ev->GetVector(1);
|
|
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
ent = soundList.ObjectAt(i);
|
|
ent->addOrigin(amount);
|
|
}
|
|
}
|
|
|
|
void SoundManager::SwitchFacetEvent(Event *ev)
|
|
{
|
|
if (current && current->isSubclassOf(Trigger)) {
|
|
Trigger *trigger;
|
|
|
|
trigger = (Trigger *)current;
|
|
if (trigger->GetMultiFaceted() && !currentFacet) {
|
|
currentFacet = 1;
|
|
} else {
|
|
currentFacet = 0;
|
|
}
|
|
}
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::PreviewReverbEvent(Event *ev)
|
|
{
|
|
cvar_t *cvar;
|
|
int reverbtype;
|
|
float reverblevel;
|
|
|
|
// get reverb type
|
|
cvar = gi.Cvar_Get("snd_reverbtype", "", 0);
|
|
reverbtype = cvar->integer;
|
|
|
|
// get reverb level
|
|
cvar = gi.Cvar_Get("snd_reverblevel", "", 0);
|
|
reverblevel = cvar->value;
|
|
|
|
if (g_entities[0].inuse && g_entities[0].client) {
|
|
Player *client;
|
|
|
|
client = (Player *)g_entities[0].entity;
|
|
client->SetReverb(reverbtype, reverblevel);
|
|
}
|
|
}
|
|
|
|
void SoundManager::ResetReverbEvent(Event *ev)
|
|
{
|
|
if (g_entities[0].inuse && g_entities[0].client) {
|
|
Player *client;
|
|
|
|
client = (Player *)g_entities[0].entity;
|
|
client->SetReverb("Generic", 0);
|
|
}
|
|
}
|
|
|
|
void SoundManager::ShowingSounds(Event *ev)
|
|
{
|
|
int i;
|
|
Entity *ent;
|
|
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
ent = soundList.ObjectAt(i);
|
|
if (ent->isSubclassOf(TriggerSpeaker)) {
|
|
TriggerSpeaker *speaker;
|
|
|
|
speaker = (TriggerSpeaker *)ent;
|
|
if (current == ent) {
|
|
if (speaker->volume != DEFAULT_VOL) {
|
|
G_DrawDebugNumber(speaker->origin + Vector(0, 0, 10), speaker->volume, 0.5, 0, 1, 0, 2);
|
|
}
|
|
if (speaker->min_dist != DEFAULT_MIN_DIST) {
|
|
G_DrawDebugNumber(speaker->origin + Vector(0, 0, 20), speaker->min_dist, 0.5, 0, 0, 1, 0);
|
|
}
|
|
|
|
// falloff circles
|
|
if (speaker->min_dist != DEFAULT_VOL) {
|
|
G_DebugCircle(speaker->origin, speaker->min_dist, 0, 1, 1, 1, true);
|
|
G_DebugCircle(speaker->origin, 2 * speaker->min_dist, 0, 0.5, 0.5, 0.5, true);
|
|
G_DebugCircle(speaker->origin, 4 * speaker->min_dist, 0, 0.25, 0.25, 0.25, true);
|
|
}
|
|
|
|
if (speaker->isSubclassOf(RandomSpeaker)) {
|
|
RandomSpeaker *random;
|
|
|
|
G_DebugPyramid(speaker->origin, 24, 1, 1, 0.5, 1);
|
|
random = (RandomSpeaker *)ent;
|
|
|
|
G_DrawDebugNumber(random->origin + Vector(0, 0, 30), random->mindelay, 0.5, 0.25, 0, 1, 1);
|
|
G_DrawDebugNumber(random->origin + Vector(0, 0, 38), random->maxdelay, 0.5, 0.25, 0, 1, 1);
|
|
G_DrawDebugNumber(random->origin + Vector(0, 0, 46), random->chance, 0.5, 0.25, 0, 1, 2);
|
|
} else {
|
|
G_DebugPyramid(speaker->origin, 24, 1, 1, 0, 1);
|
|
}
|
|
} else {
|
|
if (speaker->isSubclassOf(RandomSpeaker)) {
|
|
G_DebugPyramid(speaker->origin, 24, 1, 0, 1, 1);
|
|
} else {
|
|
G_DebugPyramid(speaker->origin, 24, 1, 0, 0, 1);
|
|
}
|
|
}
|
|
} else if (ent->isSubclassOf(TriggerMusic)) {
|
|
int facet;
|
|
TriggerMusic *music;
|
|
|
|
music = (TriggerMusic *)ent;
|
|
|
|
if (current == ent) {
|
|
if (music->oneshot) {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 0, 1, 1, 1);
|
|
} else {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 1, 1, 0, 1);
|
|
}
|
|
} else {
|
|
if (music->oneshot) {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 0, 0.5, 0.5, 1);
|
|
} else {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 1, 0, 0, 1);
|
|
}
|
|
}
|
|
|
|
if (music->useTriggerDir) {
|
|
Vector org;
|
|
|
|
org = ent->origin;
|
|
org[2] += 0.5f * ent->maxs[2];
|
|
|
|
G_DebugArrow(org, music->GetTriggerDir(), 48, 0.5, 1, 1, 1);
|
|
}
|
|
facet = music->GetMultiFaceted();
|
|
if (facet) {
|
|
if (current == ent) {
|
|
G_DebugHighlightFacet(
|
|
ent->origin, ent->mins, ent->maxs, (facet_t)(((facet - 1) << 1) + currentFacet), 1, 1, 1, 1
|
|
);
|
|
} else {
|
|
G_DebugHighlightFacet(
|
|
ent->origin, ent->mins, ent->maxs, (facet_t)(((facet - 1) << 1) + 0), 0.6f, 0.3f, 0.2f, 0.1f
|
|
);
|
|
G_DebugHighlightFacet(
|
|
ent->origin, ent->mins, ent->maxs, (facet_t)(((facet - 1) << 1) + 1), 0.6f, 0.3f, 0.2f, 0.1f
|
|
);
|
|
}
|
|
}
|
|
} else if (ent->isSubclassOf(TriggerReverb)) {
|
|
int facet;
|
|
TriggerReverb *reverb;
|
|
|
|
reverb = (TriggerReverb *)ent;
|
|
|
|
if (current == ent) {
|
|
if (reverb->oneshot) {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 0.5, 0.5, 1, 1);
|
|
} else {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 0, 0.5, 1, 1);
|
|
}
|
|
} else {
|
|
if (reverb->oneshot) {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 0.5, 0, 1, 1);
|
|
} else {
|
|
G_DebugBBox(ent->origin, ent->mins, ent->maxs, 0, 0, 1, 1);
|
|
}
|
|
}
|
|
|
|
if (reverb->useTriggerDir) {
|
|
Vector org;
|
|
|
|
org = ent->origin;
|
|
org[2] += 0.5f * ent->maxs[2];
|
|
|
|
G_DebugArrow(org, reverb->GetTriggerDir(), 48, 0.5, 1, 1, 1);
|
|
}
|
|
facet = reverb->GetMultiFaceted();
|
|
if (facet) {
|
|
if (current == ent) {
|
|
G_DebugHighlightFacet(
|
|
ent->origin, ent->mins, ent->maxs, (facet_t)(((facet - 1) << 1) + currentFacet), 1, 1, 1, 1
|
|
);
|
|
} else {
|
|
G_DebugHighlightFacet(
|
|
ent->origin, ent->mins, ent->maxs, (facet_t)(((facet - 1) << 1) + 0), 0.3f, 0.3f, 0.6f, 0.1f
|
|
);
|
|
G_DebugHighlightFacet(
|
|
ent->origin, ent->mins, ent->maxs, (facet_t)(((facet - 1) << 1) + 1), 0.3f, 0.3f, 0.6f, 0.1f
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
PostEvent(EV_SoundManager_ShowingSounds, FRAMETIME);
|
|
}
|
|
|
|
void SoundManager::Show(void)
|
|
{
|
|
CurrentGainsFocus();
|
|
CancelEventsOfType(EV_SoundManager_ShowingSounds);
|
|
PostEvent(EV_SoundManager_ShowingSounds, FRAMETIME);
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::Show(Event *ev)
|
|
{
|
|
Show();
|
|
}
|
|
|
|
void SoundManager::Hide(Event *ev)
|
|
{
|
|
CurrentLostFocus();
|
|
CancelEventsOfType(EV_SoundManager_ShowingSounds);
|
|
UpdateUI();
|
|
}
|
|
|
|
void SoundManager::Save(void)
|
|
{
|
|
Entity *ent;
|
|
str buf;
|
|
str filename;
|
|
size_t i;
|
|
|
|
// get the name of the sound file from the world
|
|
filename = "maps/";
|
|
filename += level.mapname;
|
|
for (i = filename.length() - 1; i >= 0; i--) {
|
|
if (filename[i] == '.') {
|
|
filename[i] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
filename += ".snd";
|
|
|
|
gi.Printf("Saving soundmanager file to '%s'...\n", filename.c_str());
|
|
|
|
buf = "";
|
|
buf += va("//\n");
|
|
buf += va("// Sound Manager File \"%s\", %d Sound Entities.\n", filename.c_str(), soundList.NumObjects());
|
|
buf += va("//\n");
|
|
|
|
//
|
|
// save out normal TriggerSpeakers
|
|
//
|
|
buf += va("// TriggerSpeakers\n");
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
TriggerSpeaker *speaker;
|
|
|
|
ent = soundList.ObjectAt(i);
|
|
if (!ent->isSubclassOf(TriggerSpeaker) || ent->isSubclassOf(RandomSpeaker)) {
|
|
continue;
|
|
}
|
|
|
|
speaker = (TriggerSpeaker *)ent;
|
|
//
|
|
// start off the spawn command
|
|
//
|
|
buf += "spawn TriggerSpeaker";
|
|
//
|
|
// set the targetname
|
|
//
|
|
if (ent->targetname != "") {
|
|
buf += va(" targetname %s", ent->targetname.c_str());
|
|
}
|
|
//
|
|
// set the origin
|
|
//
|
|
buf += va(" origin \"%.2f %.2f %.2f\"", ent->origin.x, ent->origin.y, ent->origin.z);
|
|
//
|
|
// make the speaker ambient and on
|
|
//
|
|
buf += " spawnflags 1";
|
|
//
|
|
// set the volume
|
|
//
|
|
if (speaker->volume != DEFAULT_VOL) {
|
|
buf += va(" volume %.2f", speaker->volume);
|
|
}
|
|
//
|
|
// set the mindist
|
|
//
|
|
if (speaker->min_dist != DEFAULT_MIN_DIST) {
|
|
buf += va(" min_dist %.1f", speaker->min_dist);
|
|
}
|
|
//
|
|
// save the sound
|
|
//
|
|
buf += va(" sound \"%s\"", speaker->Noise().c_str());
|
|
//
|
|
// make sure it gets re-added to the sound manager
|
|
//
|
|
buf += " _addtosoundmanager 0";
|
|
buf += va("\n");
|
|
}
|
|
//
|
|
// save out RandomSpeakers
|
|
//
|
|
buf += va("// RandomSpeakers\n");
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
RandomSpeaker *speaker;
|
|
|
|
ent = soundList.ObjectAt(i);
|
|
if (!ent->isSubclassOf(TriggerSpeaker) || !ent->isSubclassOf(RandomSpeaker)) {
|
|
continue;
|
|
}
|
|
|
|
speaker = (RandomSpeaker *)ent;
|
|
//
|
|
// start off the spawn command
|
|
//
|
|
buf += "spawn RandomSpeaker";
|
|
//
|
|
// set the targetname
|
|
//
|
|
if (ent->targetname != "") {
|
|
buf += va(" targetname %s", ent->targetname.c_str());
|
|
}
|
|
//
|
|
// set the origin
|
|
//
|
|
buf += va(" origin \"%.2f %.2f %.2f\"", ent->origin.x, ent->origin.y, ent->origin.z);
|
|
//
|
|
// set the volume
|
|
//
|
|
if (speaker->volume != DEFAULT_VOL) {
|
|
buf += va(" volume %.2f", speaker->volume);
|
|
}
|
|
//
|
|
// set the mindist
|
|
//
|
|
if (speaker->min_dist != DEFAULT_MIN_DIST) {
|
|
buf += va(" min_dist %.1f", speaker->min_dist);
|
|
}
|
|
//
|
|
// set the channel
|
|
//
|
|
buf += va(" channel %d", speaker->channel);
|
|
//
|
|
// set the mindelay
|
|
//
|
|
buf += va(" mindelay %.2f", speaker->mindelay);
|
|
//
|
|
// set the maxdelay
|
|
//
|
|
buf += va(" maxdelay %.2f", speaker->maxdelay);
|
|
//
|
|
// set the chance
|
|
//
|
|
buf += va(" chance %.2f", speaker->chance);
|
|
//
|
|
// save the sound
|
|
//
|
|
buf += va(" sound \"%s\"", speaker->Noise().c_str());
|
|
//
|
|
// make sure it gets re-added to the sound manager
|
|
//
|
|
buf += " _addtosoundmanager 0";
|
|
buf += va("\n");
|
|
}
|
|
//
|
|
// save out TriggerMusic
|
|
//
|
|
buf += va("// TriggerMusics\n");
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
TriggerMusic *music;
|
|
|
|
ent = soundList.ObjectAt(i);
|
|
if (!ent->isSubclassOf(TriggerMusic)) {
|
|
continue;
|
|
}
|
|
|
|
music = (TriggerMusic *)ent;
|
|
//
|
|
// start off the spawn command
|
|
//
|
|
buf += "spawn TriggerMusic";
|
|
//
|
|
// set the targetname
|
|
//
|
|
if (ent->targetname != "") {
|
|
buf += va(" targetname %s", ent->targetname.c_str());
|
|
}
|
|
//
|
|
// set the origin
|
|
//
|
|
buf += va(" origin \"%.2f %.2f %.2f\"", ent->origin.x, ent->origin.y, ent->origin.z);
|
|
//
|
|
// set the angle
|
|
//
|
|
if (music->useTriggerDir) {
|
|
buf += va(" angle %.1f", AngleMod(ent->angles.y));
|
|
}
|
|
//
|
|
// set the oneshot
|
|
//
|
|
if (music->oneshot) {
|
|
buf += " oneshot 0";
|
|
}
|
|
//
|
|
// set current
|
|
//
|
|
buf += va(" current %s", Director.GetString(music->current).c_str());
|
|
|
|
//
|
|
// set fallback
|
|
//
|
|
buf += va(" fallback %s", Director.GetString(music->fallback).c_str());
|
|
|
|
if (music->GetMultiFaceted()) {
|
|
//
|
|
// save out multi faceted
|
|
//
|
|
buf += va(" multifaceted %d", music->GetMultiFaceted());
|
|
|
|
//
|
|
// set alt current
|
|
//
|
|
buf += va(" altcurrent %s", Director.GetString(music->altcurrent).c_str());
|
|
|
|
//
|
|
// set alt fallback
|
|
//
|
|
buf += va(" altfallback %s", Director.GetString(music->altfallback).c_str());
|
|
}
|
|
|
|
//
|
|
// set mins
|
|
//
|
|
buf += va(" _setmins \"%.2f %.2f %.2f\"", ent->mins.x, ent->mins.y, ent->mins.z);
|
|
|
|
//
|
|
// set maxs
|
|
//
|
|
buf += va(" _setmaxs \"%.2f %.2f %.2f\"", ent->maxs.x, ent->maxs.y, ent->maxs.z);
|
|
//
|
|
// make sure it gets re-added to the sound manager
|
|
//
|
|
buf += " _addtosoundmanager 0";
|
|
buf += va("\n");
|
|
}
|
|
|
|
//
|
|
// save out TriggerReverb
|
|
//
|
|
buf += va("// TriggerReverbs\n");
|
|
for (i = 1; i <= soundList.NumObjects(); i++) {
|
|
TriggerReverb *reverb;
|
|
|
|
ent = soundList.ObjectAt(i);
|
|
if (!ent->isSubclassOf(TriggerReverb)) {
|
|
continue;
|
|
}
|
|
|
|
reverb = (TriggerReverb *)ent;
|
|
//
|
|
// start off the spawn command
|
|
//
|
|
buf += "spawn TriggerReverb";
|
|
//
|
|
// set the targetname
|
|
//
|
|
if (ent->targetname != "") {
|
|
buf += va(" targetname %s", ent->targetname.c_str());
|
|
}
|
|
//
|
|
// set the origin
|
|
//
|
|
buf += va(" origin \"%.2f %.2f %.2f\"", ent->origin.x, ent->origin.y, ent->origin.z);
|
|
//
|
|
// set the angle
|
|
//
|
|
if (reverb->useTriggerDir) {
|
|
buf += va(" angle %.1f", AngleMod(ent->angles.y));
|
|
}
|
|
//
|
|
// set the oneshot
|
|
//
|
|
if (reverb->oneshot) {
|
|
buf += " oneshot 0";
|
|
}
|
|
//
|
|
// set reverb type
|
|
//
|
|
buf += va(" reverbtype %d", reverb->reverbtype);
|
|
|
|
//
|
|
// set reverb level
|
|
//
|
|
buf += va(" reverblevel %.2f", reverb->reverblevel);
|
|
|
|
if (reverb->GetMultiFaceted()) {
|
|
//
|
|
// save out multi faceted
|
|
//
|
|
buf += va(" multifaceted %d", reverb->GetMultiFaceted());
|
|
|
|
//
|
|
// set alt reverb type
|
|
//
|
|
buf += va(" altreverbtype %d", reverb->altreverbtype);
|
|
|
|
//
|
|
// set alt reverb level
|
|
//
|
|
buf += va(" altreverblevel %.2f", reverb->altreverblevel);
|
|
}
|
|
|
|
//
|
|
// set mins
|
|
//
|
|
buf += va(" _setmins \"%.2f %.2f %.2f\"", ent->mins.x, ent->mins.y, ent->mins.z);
|
|
|
|
//
|
|
// set maxs
|
|
//
|
|
buf += va(" _setmaxs \"%.2f %.2f %.2f\"", ent->maxs.x, ent->maxs.y, ent->maxs.z);
|
|
//
|
|
// make sure it gets re-added to the sound manager
|
|
//
|
|
buf += " _addtosoundmanager 0";
|
|
buf += va("\n");
|
|
}
|
|
|
|
buf += "end\n";
|
|
|
|
gi.FS_WriteFile(filename.c_str(), (void *)buf.c_str(), buf.length() + 1);
|
|
gi.Printf("done.\n");
|
|
}
|
|
|
|
void SoundManager::Save(Event *ev)
|
|
{
|
|
Save();
|
|
}
|
|
|
|
void SoundManager::Load(void)
|
|
{
|
|
str filename;
|
|
intptr_t i;
|
|
|
|
// get the name of the sound file from the world
|
|
filename = "maps/";
|
|
filename += level.mapname;
|
|
for (i = filename.length() - 1; i >= 0; i--) {
|
|
if (filename[i] == '.') {
|
|
filename[i] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
filename += ".snd";
|
|
|
|
// If there isn't a script with the same name as the map, then don't try to load script
|
|
if (gi.FS_ReadFile(filename.c_str(), NULL, true) != -1) {
|
|
Reset();
|
|
|
|
Director.ExecuteThread(filename, "");
|
|
}
|
|
}
|
|
|
|
void SoundManager::AddEntity(Entity *ent)
|
|
{
|
|
if (ent) {
|
|
soundList.AddUniqueObject(ent);
|
|
}
|
|
}
|