extensions/sdktools/vsound.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Sun Jul 21 11:53:56 2013 -0400 (2013-07-21)
changeset 3961 0dc477c29792
parent 3942 7aaa00382627
child 4141 8ff66ae5ffcc
permissions -rw-r--r--
Split TF2, DoD:S, HL2:DM, and ND to separate binaries (bug 5813, r=asherkin).
ds@1114
     1
/**
ds@1114
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1233
     4
 * SourceMod SDKTools Extension
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
ds@1114
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1233
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1233
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1233
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
ds@1114
    28
 *
ds@1114
    29
 * Version: $Id$
ds@1114
    30
 */
ds@1114
    31
faluco@1735
    32
#include "vsound.h"
faluco@1735
    33
#include <IForwardSys.h>
faluco@1735
    34
skamonkey@3942
    35
#if SOURCE_ENGINE == SE_DOTA
skamonkey@3942
    36
SH_DECL_HOOK8_void(IVEngineServer, EmitAmbientSound, SH_NOATTRIB, 0, CEntityIndex, const Vector &, const char *, float, soundlevel_t, int, int, float);
skamonkey@3942
    37
#else
faluco@1735
    38
SH_DECL_HOOK8_void(IVEngineServer, EmitAmbientSound, SH_NOATTRIB, 0, int, const Vector &, const char *, float, soundlevel_t, int, int, float);
skamonkey@3942
    39
#endif
skamonkey@3942
    40
skamonkey@3515
    41
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
    42
SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 0, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
skamonkey@3515
    43
SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 1, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
skamonkey@3961
    44
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
    45
SH_DECL_HOOK15_void(IEngineSound, EmitSound, SH_NOATTRIB, 0, IRecipientFilter &, int, int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
skamonkey@3564
    46
SH_DECL_HOOK15_void(IEngineSound, EmitSound, SH_NOATTRIB, 1, IRecipientFilter &, int, int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
skamonkey@3515
    47
#else
faluco@1735
    48
SH_DECL_HOOK14_void(IEngineSound, EmitSound, SH_NOATTRIB, 0, IRecipientFilter &, int, int, const char *, float, float, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
faluco@1735
    49
SH_DECL_HOOK14_void(IEngineSound, EmitSound, SH_NOATTRIB, 1, IRecipientFilter &, int, int, const char *, float, soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
skamonkey@3515
    50
#endif
faluco@1735
    51
faluco@1735
    52
bool g_InSoundHook = false;
faluco@1735
    53
faluco@1735
    54
/***************************
faluco@1735
    55
*                          *
faluco@1735
    56
* Sound Related Hook Class *
faluco@1735
    57
*                          *
faluco@1735
    58
****************************/
faluco@1735
    59
pred@2760
    60
cell_t SoundReferenceToIndex(cell_t ref)
pred@2760
    61
{
pred@2760
    62
	if (ref == 0 || ref == -1 || ref == -2)
pred@2760
    63
	{
pred@2760
    64
		return ref;
pred@2760
    65
	}
pred@2760
    66
pred@2760
    67
	return gamehelpers->ReferenceToIndex(ref);
pred@2760
    68
}
pred@2760
    69
faluco@1735
    70
size_t SoundHooks::_FillInPlayers(int *pl_array, IRecipientFilter *pFilter)
faluco@1735
    71
{
faluco@1735
    72
	size_t size = static_cast<size_t>(pFilter->GetRecipientCount());
faluco@1735
    73
faluco@1735
    74
	for (size_t i=0; i<size; i++)
faluco@1735
    75
	{
skamonkey@3918
    76
		int index;
skamonkey@3918
    77
#if SOURCE_ENGINE == SE_DOTA
skamonkey@3942
    78
		index = pFilter->GetRecipientIndex(i).Get();
skamonkey@3918
    79
#else
skamonkey@3918
    80
		index = pFilter->GetRecipientIndex(i);
skamonkey@3918
    81
#endif
skamonkey@3918
    82
		pl_array[i] = index;
faluco@1735
    83
	}
faluco@1735
    84
faluco@1735
    85
	return size;
faluco@1735
    86
}
faluco@1735
    87
faluco@1735
    88
void SoundHooks::_IncRefCounter(int type)
faluco@1735
    89
{
faluco@1735
    90
	if (type == NORMAL_SOUND_HOOK)
faluco@1735
    91
	{
faluco@1735
    92
		if (m_NormalCount++ == 0)
faluco@1735
    93
		{
kyle@3819
    94
			SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
kyle@3819
    95
			SH_ADD_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
faluco@1735
    96
		}
faluco@1735
    97
	}
faluco@1735
    98
	else if (type == AMBIENT_SOUND_HOOK)
faluco@1735
    99
	{
faluco@1735
   100
		if (m_AmbientCount++ == 0)
faluco@1735
   101
		{
kyle@3819
   102
			SH_ADD_HOOK(IVEngineServer, EmitAmbientSound, engine, SH_MEMBER(this, &SoundHooks::OnEmitAmbientSound), false);
faluco@1735
   103
		}
faluco@1735
   104
	}
faluco@1735
   105
}
faluco@1735
   106
faluco@1735
   107
void SoundHooks::_DecRefCounter(int type)
faluco@1735
   108
{
faluco@1735
   109
	if (type == NORMAL_SOUND_HOOK)
faluco@1735
   110
	{
faluco@1735
   111
		if (--m_NormalCount == 0)
faluco@1735
   112
		{
kyle@3819
   113
			SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
kyle@3819
   114
			SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
faluco@1735
   115
		}
faluco@1735
   116
	}
faluco@1735
   117
	else if (type == AMBIENT_SOUND_HOOK)
faluco@1735
   118
	{
faluco@1735
   119
		if (--m_AmbientCount == 0)
faluco@1735
   120
		{
kyle@3819
   121
			SH_REMOVE_HOOK(IVEngineServer, EmitAmbientSound, engine, SH_MEMBER(this, &SoundHooks::OnEmitAmbientSound), false);
faluco@1735
   122
		}
faluco@1735
   123
	}
faluco@1735
   124
}
faluco@1735
   125
faluco@1735
   126
void SoundHooks::Initialize()
faluco@1735
   127
{
faluco@1735
   128
	plsys->AddPluginsListener(this);
faluco@1735
   129
}
faluco@1735
   130
faluco@1735
   131
void SoundHooks::Shutdown()
faluco@1735
   132
{
faluco@1735
   133
	plsys->RemovePluginsListener(this);
faluco@1735
   134
	if (m_NormalCount)
faluco@1735
   135
	{
kyle@3819
   136
		SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound), false);
kyle@3819
   137
		SH_REMOVE_HOOK(IEngineSound, EmitSound, engsound, SH_MEMBER(this, &SoundHooks::OnEmitSound2), false);
faluco@1735
   138
	}
faluco@1735
   139
	if (m_AmbientCount)
faluco@1735
   140
	{
kyle@3819
   141
		SH_REMOVE_HOOK(IVEngineServer, EmitAmbientSound, engine, SH_MEMBER(this, &SoundHooks::OnEmitAmbientSound), false);
faluco@1735
   142
	}
faluco@1735
   143
}
faluco@1735
   144
faluco@1735
   145
void SoundHooks::OnPluginUnloaded(IPlugin *plugin)
faluco@1735
   146
{
faluco@1735
   147
	SoundHookIter iter;
faluco@1735
   148
	IPluginContext *pContext = plugin->GetBaseContext();
faluco@1735
   149
faluco@1735
   150
	if (m_AmbientCount)
faluco@1735
   151
	{
faluco@1735
   152
		for (iter=m_AmbientFuncs.begin(); iter!=m_AmbientFuncs.end(); )
faluco@1735
   153
		{
faluco@1735
   154
			if ((*iter)->GetParentContext() == pContext)
faluco@1735
   155
			{
faluco@1735
   156
				iter = m_AmbientFuncs.erase(iter);
faluco@1735
   157
				_DecRefCounter(AMBIENT_SOUND_HOOK);
faluco@1735
   158
			}
faluco@1735
   159
			else
faluco@1735
   160
			{
faluco@1735
   161
				iter++;
faluco@1735
   162
			}
faluco@1735
   163
		}
faluco@1735
   164
	}
faluco@1735
   165
	if (m_NormalCount)
faluco@1735
   166
	{
faluco@1735
   167
		for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); )
faluco@1735
   168
		{
faluco@1735
   169
			if ((*iter)->GetParentContext() == pContext)
faluco@1735
   170
			{
faluco@1735
   171
				iter = m_NormalFuncs.erase(iter);
faluco@1735
   172
				_DecRefCounter(NORMAL_SOUND_HOOK);
faluco@1735
   173
			}
faluco@1735
   174
			else
faluco@1735
   175
			{
faluco@1735
   176
				iter++;
faluco@1735
   177
			}
faluco@1735
   178
		}
faluco@1735
   179
	}
faluco@1735
   180
}
faluco@1735
   181
faluco@1735
   182
void SoundHooks::AddHook(int type, IPluginFunction *pFunc)
faluco@1735
   183
{
faluco@1735
   184
	if (type == NORMAL_SOUND_HOOK)
faluco@1735
   185
	{
faluco@1735
   186
		m_NormalFuncs.push_back(pFunc);
faluco@1735
   187
		_IncRefCounter(NORMAL_SOUND_HOOK);
faluco@1735
   188
	}
faluco@1735
   189
	else if (type == AMBIENT_SOUND_HOOK)
faluco@1735
   190
	{
faluco@1735
   191
		m_AmbientFuncs.push_back(pFunc);
faluco@1735
   192
		_IncRefCounter(AMBIENT_SOUND_HOOK);
faluco@1735
   193
	}
faluco@1735
   194
}
faluco@1735
   195
faluco@1735
   196
bool SoundHooks::RemoveHook(int type, IPluginFunction *pFunc)
faluco@1735
   197
{
faluco@1735
   198
	SoundHookIter iter;
faluco@1735
   199
	if (type == NORMAL_SOUND_HOOK)
faluco@1735
   200
	{
faluco@1735
   201
		if ((iter=m_NormalFuncs.find(pFunc)) != m_NormalFuncs.end())
faluco@1735
   202
		{
faluco@1735
   203
			m_NormalFuncs.erase(iter);
faluco@1735
   204
			_DecRefCounter(NORMAL_SOUND_HOOK);
faluco@1735
   205
			return true;
faluco@1735
   206
		}
faluco@1735
   207
		else
faluco@1735
   208
		{
faluco@1735
   209
			return false;
faluco@1735
   210
		}
faluco@1735
   211
	}
faluco@1735
   212
	else if (type == AMBIENT_SOUND_HOOK)
faluco@1735
   213
	{
faluco@1735
   214
		if ((iter=m_AmbientFuncs.find(pFunc)) != m_AmbientFuncs.end())
faluco@1735
   215
		{
faluco@1735
   216
			m_AmbientFuncs.erase(iter);
faluco@1735
   217
			_DecRefCounter(AMBIENT_SOUND_HOOK);
faluco@1735
   218
			return true;
faluco@1735
   219
		}
faluco@1735
   220
		else
faluco@1735
   221
		{
faluco@1735
   222
			return false;
faluco@1735
   223
		}
faluco@1735
   224
	}
faluco@1735
   225
faluco@1735
   226
	return false;
faluco@1735
   227
}
faluco@1735
   228
skamonkey@3942
   229
#if SOURCE_ENGINE == SE_DOTA
skamonkey@3942
   230
void SoundHooks::OnEmitAmbientSound(CEntityIndex index, const Vector &pos, const char *samp, float vol, 
skamonkey@3942
   231
									soundlevel_t soundlevel, int fFlags, int pitch, float delay)
skamonkey@3942
   232
{
skamonkey@3942
   233
	int entindex = index.Get();
skamonkey@3942
   234
#else
faluco@1735
   235
void SoundHooks::OnEmitAmbientSound(int entindex, const Vector &pos, const char *samp, float vol, 
faluco@1735
   236
									soundlevel_t soundlevel, int fFlags, int pitch, float delay)
faluco@1735
   237
{
skamonkey@3942
   238
#endif
faluco@1735
   239
	SoundHookIter iter;
faluco@1735
   240
	IPluginFunction *pFunc;
faluco@1735
   241
	cell_t vec[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
faluco@1735
   242
	cell_t res = static_cast<ResultType>(Pl_Continue);
faluco@1735
   243
	char buffer[PLATFORM_MAX_PATH];
faluco@1735
   244
	strcpy(buffer, samp);
faluco@1735
   245
faluco@1735
   246
	for (iter=m_AmbientFuncs.begin(); iter!=m_AmbientFuncs.end(); iter++)
faluco@1735
   247
	{
faluco@1735
   248
		pFunc = (*iter);
faluco@1735
   249
		pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
faluco@1735
   250
		pFunc->PushCellByRef(&entindex);
faluco@1735
   251
		pFunc->PushFloatByRef(&vol);
faluco@1735
   252
		pFunc->PushCellByRef(reinterpret_cast<cell_t *>(&soundlevel));
faluco@1735
   253
		pFunc->PushCellByRef(&pitch);
faluco@1735
   254
		pFunc->PushArray(vec, 3, SM_PARAM_COPYBACK);
faluco@1735
   255
		pFunc->PushCellByRef(&fFlags);
faluco@1735
   256
		pFunc->PushFloatByRef(&delay);
faluco@1735
   257
		g_InSoundHook = true;
faluco@1735
   258
		pFunc->Execute(&res);
faluco@1735
   259
		g_InSoundHook = false;
faluco@1735
   260
faluco@1735
   261
		switch (res)
faluco@1735
   262
		{
faluco@1735
   263
		case Pl_Handled:
faluco@1735
   264
		case Pl_Stop:
faluco@1735
   265
			{
faluco@1735
   266
				RETURN_META(MRES_SUPERCEDE);
faluco@1735
   267
			}
faluco@1735
   268
		case Pl_Changed:
faluco@1735
   269
			{
faluco@1735
   270
				Vector vec2;
faluco@1735
   271
				vec2.x = sp_ctof(vec[0]);
faluco@1735
   272
				vec2.y = sp_ctof(vec[1]);
faluco@1735
   273
				vec2.z = sp_ctof(vec[2]);
skamonkey@3942
   274
#if SOURCE_ENGINE == SE_DOTA
faluco@1735
   275
				RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::EmitAmbientSound, 
skamonkey@3942
   276
										(CEntityIndex(entindex), vec2, buffer, vol, soundlevel, fFlags, pitch, delay));
skamonkey@3942
   277
#else
skamonkey@3942
   278
				RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::EmitAmbientSound,
faluco@1735
   279
										(entindex, vec2, buffer, vol, soundlevel, fFlags, pitch, delay));
skamonkey@3942
   280
#endif
faluco@1735
   281
			}
faluco@1735
   282
		}
faluco@1735
   283
	}
faluco@1735
   284
}
faluco@1735
   285
skamonkey@3515
   286
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   287
int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample, 
skamonkey@3515
   288
							 float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin, 
skamonkey@3515
   289
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
skamonkey@3515
   290
							 float soundtime, int speakerentity)
skamonkey@3961
   291
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   292
void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
skamonkey@3564
   293
							 float flVolume, soundlevel_t iSoundlevel, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin, 
skamonkey@3564
   294
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
skamonkey@3564
   295
							 float soundtime, int speakerentity)
skamonkey@3515
   296
#else
faluco@1735
   297
void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
faluco@1735
   298
							 float flVolume, soundlevel_t iSoundlevel, int iFlags, int iPitch, const Vector *pOrigin, 
faluco@1735
   299
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
faluco@1735
   300
							 float soundtime, int speakerentity)
skamonkey@3515
   301
#endif
faluco@1735
   302
{
faluco@1735
   303
	SoundHookIter iter;
faluco@1735
   304
	IPluginFunction *pFunc;
faluco@1735
   305
	cell_t res = static_cast<ResultType>(Pl_Continue);
faluco@1735
   306
	char buffer[PLATFORM_MAX_PATH];
faluco@1735
   307
	strcpy(buffer, pSample);
faluco@1735
   308
faluco@1735
   309
	for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
faluco@1735
   310
	{
faluco@1735
   311
		int players[64], size;
faluco@1735
   312
		size = _FillInPlayers(players, &filter);
faluco@1735
   313
		pFunc = (*iter);
faluco@1735
   314
faluco@1735
   315
		pFunc->PushArray(players, 64, SM_PARAM_COPYBACK);
faluco@1735
   316
		pFunc->PushCellByRef(&size);
faluco@1735
   317
		pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
faluco@1735
   318
		pFunc->PushCellByRef(&iEntIndex);
faluco@1735
   319
		pFunc->PushCellByRef(&iChannel);
faluco@1735
   320
		pFunc->PushFloatByRef(&flVolume);
faluco@1735
   321
		pFunc->PushCellByRef(reinterpret_cast<cell_t *>(&iSoundlevel));
faluco@1735
   322
		pFunc->PushCellByRef(&iPitch);
faluco@1735
   323
		pFunc->PushCellByRef(&iFlags);
faluco@1735
   324
		g_InSoundHook = true;
faluco@1735
   325
		pFunc->Execute(&res);
faluco@1735
   326
		g_InSoundHook = false;
faluco@1735
   327
faluco@1735
   328
		switch (res)
faluco@1735
   329
		{
faluco@1735
   330
		case Pl_Handled:
faluco@1735
   331
		case Pl_Stop:
faluco@1735
   332
			{
skamonkey@3515
   333
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   334
				RETURN_META_VALUE(MRES_SUPERCEDE, -1);
skamonkey@3515
   335
#else
faluco@1735
   336
				RETURN_META(MRES_SUPERCEDE);
skamonkey@3515
   337
#endif
faluco@1735
   338
			}
faluco@1735
   339
		case Pl_Changed:
faluco@1735
   340
			{
faluco@1735
   341
				CellRecipientFilter crf;
faluco@1735
   342
				crf.Initialize(players, size);
skamonkey@3515
   343
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   344
				RETURN_META_VALUE_NEWPARAMS(
skamonkey@3515
   345
					MRES_IGNORED,
skamonkey@3515
   346
					-1,
skamonkey@3515
   347
					static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, 
skamonkey@3515
   348
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3515
   349
					(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin, 
skamonkey@3515
   350
					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3515
   351
					);
skamonkey@3961
   352
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   353
				RETURN_META_NEWPARAMS(
skamonkey@3564
   354
					MRES_IGNORED,
skamonkey@3564
   355
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, 
skamonkey@3564
   356
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3564
   357
					(crf, iEntIndex, iChannel, buffer, flVolume, iSoundlevel, iFlags, iPitch, iSpecialDSP, pOrigin, 
skamonkey@3564
   358
					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3564
   359
					);
skamonkey@3515
   360
#else
faluco@1735
   361
				RETURN_META_NEWPARAMS(
faluco@1735
   362
					MRES_IGNORED,
faluco@1735
   363
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, 
faluco@1735
   364
					int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
faluco@1735
   365
					(crf, iEntIndex, iChannel, buffer, flVolume, iSoundlevel, iFlags, iPitch, pOrigin, 
faluco@1735
   366
					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
faluco@1735
   367
					);
skamonkey@3515
   368
#endif
faluco@1735
   369
			}
faluco@1735
   370
		}
faluco@1735
   371
	}
skamonkey@3515
   372
skamonkey@3515
   373
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   374
	RETURN_META_VALUE(MRES_IGNORED, -1 );
skamonkey@3515
   375
#endif
faluco@1735
   376
}
faluco@1735
   377
skamonkey@3515
   378
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   379
int SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample, 
skamonkey@3515
   380
							 float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin, 
skamonkey@3515
   381
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
skamonkey@3515
   382
							 float soundtime, int speakerentity)
skamonkey@3961
   383
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   384
void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
skamonkey@3564
   385
							 float flVolume, float flAttenuation, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin, 
skamonkey@3564
   386
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
skamonkey@3564
   387
							 float soundtime, int speakerentity)
skamonkey@3515
   388
#else
faluco@1735
   389
void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
faluco@1735
   390
							 float flVolume, float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin, 
faluco@1735
   391
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
faluco@1735
   392
							 float soundtime, int speakerentity)
skamonkey@3515
   393
#endif
faluco@1735
   394
{
faluco@1735
   395
	SoundHookIter iter;
faluco@1735
   396
	IPluginFunction *pFunc;
faluco@1735
   397
	cell_t res = static_cast<ResultType>(Pl_Continue);
faluco@1735
   398
	cell_t sndlevel = static_cast<cell_t>(ATTN_TO_SNDLVL(flAttenuation));
faluco@1735
   399
	char buffer[PLATFORM_MAX_PATH];
faluco@1735
   400
	strcpy(buffer, pSample);
faluco@1735
   401
faluco@1735
   402
	for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
faluco@1735
   403
	{
faluco@1735
   404
		int players[64], size;
faluco@1735
   405
		size = _FillInPlayers(players, &filter);
faluco@1735
   406
		pFunc = (*iter);
faluco@1735
   407
faluco@1735
   408
		pFunc->PushArray(players, 64, SM_PARAM_COPYBACK);
faluco@1735
   409
		pFunc->PushCellByRef(&size);
faluco@1735
   410
		pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
faluco@1735
   411
		pFunc->PushCellByRef(&iEntIndex);
faluco@1735
   412
		pFunc->PushCellByRef(&iChannel);
faluco@1735
   413
		pFunc->PushFloatByRef(&flVolume);
faluco@1735
   414
		pFunc->PushCellByRef(&sndlevel);
faluco@1735
   415
		pFunc->PushCellByRef(&iPitch);
faluco@1735
   416
		pFunc->PushCellByRef(&iFlags);
faluco@1735
   417
		g_InSoundHook = true;
faluco@1735
   418
		pFunc->Execute(&res);
faluco@1735
   419
		g_InSoundHook = false;
faluco@1735
   420
faluco@1735
   421
		switch (res)
faluco@1735
   422
		{
faluco@1735
   423
		case Pl_Handled:
faluco@1735
   424
		case Pl_Stop:
faluco@1735
   425
			{
skamonkey@3515
   426
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   427
				RETURN_META_VALUE(MRES_SUPERCEDE, -1);
skamonkey@3515
   428
#else
faluco@1735
   429
				RETURN_META(MRES_SUPERCEDE);
skamonkey@3515
   430
#endif
faluco@1735
   431
			}
faluco@1735
   432
		case Pl_Changed:
faluco@1735
   433
			{
faluco@1735
   434
				CellRecipientFilter crf;
faluco@1735
   435
				crf.Initialize(players, size);
skamonkey@3515
   436
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   437
				RETURN_META_VALUE_NEWPARAMS(
skamonkey@3515
   438
					MRES_IGNORED,
skamonkey@3515
   439
					-1,
skamonkey@3515
   440
					static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, 
skamonkey@3515
   441
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3515
   442
					(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), 
skamonkey@3515
   443
					nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3515
   444
					);
skamonkey@3961
   445
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   446
RETURN_META_NEWPARAMS(
skamonkey@3564
   447
					MRES_IGNORED,
skamonkey@3564
   448
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, 
skamonkey@3564
   449
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3564
   450
					(crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), 
skamonkey@3564
   451
					iFlags, iPitch, iSpecialDSP, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3564
   452
					);
skamonkey@3515
   453
#else
faluco@1735
   454
				RETURN_META_NEWPARAMS(
faluco@1735
   455
					MRES_IGNORED,
skamonkey@3515
   456
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, 
faluco@1735
   457
					int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
faluco@1735
   458
					(crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), 
faluco@1735
   459
					iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
faluco@1735
   460
					);
skamonkey@3515
   461
#endif
faluco@1735
   462
			}
faluco@1735
   463
		}
faluco@1735
   464
	}
skamonkey@3515
   465
skamonkey@3515
   466
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   467
	RETURN_META_VALUE(MRES_IGNORED, -1 );
skamonkey@3515
   468
#endif
faluco@1735
   469
}
faluco@1735
   470
faluco@1735
   471
/************************
faluco@1735
   472
*                       *
faluco@1735
   473
* Sound Related Natives *
faluco@1735
   474
*                       *
faluco@1735
   475
*************************/
faluco@1735
   476
faluco@1735
   477
SoundHooks s_SoundHooks;
dvander@1047
   478
dvander@1047
   479
static cell_t PrefetchSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   480
{
dvander@1047
   481
	char *name;
dvander@1047
   482
	pContext->LocalToString(params[1], &name);
dvander@1047
   483
dvander@1047
   484
	engsound->PrefetchSound(name);
dvander@1047
   485
dvander@1047
   486
	return 1;
dvander@1047
   487
}
dvander@1047
   488
dvander@1047
   489
static cell_t GetSoundDuration(IPluginContext *pContext, const cell_t *params)
dvander@1047
   490
{
dvander@1047
   491
	char *name;
dvander@1047
   492
	pContext->LocalToString(params[1], &name);
dvander@1047
   493
dvander@1047
   494
	return sp_ftoc(engsound->GetSoundDuration(name));
dvander@1047
   495
}
dvander@1047
   496
dvander@1047
   497
static cell_t EmitAmbientSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   498
{
dvander@1047
   499
	cell_t entity;
dvander@1047
   500
	Vector pos;
dvander@1047
   501
	char *name;
dvander@1047
   502
	float vol, delay;
dvander@1047
   503
	int pitch, flags, level;
dvander@1047
   504
pred@2760
   505
	entity = SoundReferenceToIndex(params[3]);
dvander@1047
   506
dvander@1047
   507
	cell_t *addr;
dvander@1047
   508
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@1047
   509
	pos.x = sp_ctof(addr[0]);
dvander@1047
   510
	pos.y = sp_ctof(addr[1]);
dvander@1047
   511
	pos.z = sp_ctof(addr[2]);
dvander@1047
   512
dvander@1047
   513
	pContext->LocalToString(params[1], &name);
dvander@1047
   514
dvander@1047
   515
	vol = sp_ctof(params[6]);
dvander@1047
   516
	level = params[4];
dvander@1047
   517
	flags = params[5];
dvander@1047
   518
	pitch = params[7];
dvander@1047
   519
	delay = sp_ctof(params[8]);
dvander@1047
   520
faluco@1735
   521
	if (g_InSoundHook)
faluco@1735
   522
	{
faluco@1735
   523
		ENGINE_CALL(EmitAmbientSound)(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay);
faluco@1735
   524
	}
faluco@1735
   525
	else
faluco@1735
   526
	{
faluco@1735
   527
		engine->EmitAmbientSound(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay);
faluco@1735
   528
	}
dvander@1047
   529
dvander@1047
   530
	return 1;
dvander@1047
   531
}
dvander@1047
   532
dvander@1047
   533
static cell_t FadeClientVolume(IPluginContext *pContext, const cell_t *params)
dvander@1047
   534
{
dvander@1047
   535
	int client = params[1];
dvander@1047
   536
	if (client < 1 || client > playerhelpers->GetMaxClients())
dvander@1047
   537
	{
dvander@1047
   538
		return pContext->ThrowNativeError("Client index %d is not valid", client);
dvander@1047
   539
	}
dvander@1047
   540
dvander@1047
   541
	IGamePlayer *player = playerhelpers->GetGamePlayer(client);
dvander@1047
   542
	if (!player->IsInGame())
dvander@1047
   543
	{
dvander@1047
   544
		return pContext->ThrowNativeError("Client index %d is not in game", client);
dvander@1047
   545
	}
dvander@1047
   546
skamonkey@3913
   547
	engine->FadeClientVolume(
skamonkey@3913
   548
#if SOURCE_ENGINE == SE_DOTA
skamonkey@3913
   549
		player->GetIndex(),
skamonkey@3913
   550
#else
skamonkey@3913
   551
		player->GetEdict(),
skamonkey@3913
   552
#endif
dvander@1047
   553
		sp_ctof(params[2]),
dvander@1047
   554
		sp_ctof(params[3]),
dvander@1047
   555
		sp_ctof(params[4]),
dvander@1047
   556
		sp_ctof(params[5]));
dvander@1047
   557
dvander@1047
   558
	return 1;
dvander@1047
   559
}
dvander@1047
   560
dvander@1047
   561
static cell_t StopSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   562
{
pred@2760
   563
	int entity = SoundReferenceToIndex(params[1]);
dvander@1047
   564
	int channel = params[2];
dvander@1047
   565
dvander@1047
   566
	char *name;
dvander@1047
   567
	pContext->LocalToString(params[3], &name);
dvander@1047
   568
skamonkey@3515
   569
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   570
	engsound->StopSound(entity, channel, name, -1);
skamonkey@3515
   571
#else
dvander@1047
   572
	engsound->StopSound(entity, channel, name);
skamonkey@3515
   573
#endif
dvander@1047
   574
dvander@1047
   575
	return 1;
dvander@1047
   576
}
dvander@1047
   577
dvander@1047
   578
static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   579
{
ds@2112
   580
	cell_t *addr, *cl_array;
dvander@1047
   581
	CellRecipientFilter crf;
ds@2112
   582
	unsigned int numClients;
ds@2112
   583
	int client;
ds@2112
   584
	IGamePlayer *pPlayer = NULL;
ds@2112
   585
ds@2112
   586
	pContext->LocalToPhysAddr(params[1], &cl_array);
ds@2112
   587
	numClients = params[2];
ds@2112
   588
ds@2112
   589
	/* Client validation */
ds@2112
   590
	for (unsigned int i = 0; i < numClients; i++)
ds@2112
   591
	{
ds@2112
   592
		client = cl_array[i];
ds@2112
   593
		pPlayer = playerhelpers->GetGamePlayer(client);
ds@2112
   594
ds@2112
   595
		if (!pPlayer)
ds@2112
   596
		{
ds@2112
   597
			return pContext->ThrowNativeError("Client index %d is invalid", client);
ds@2112
   598
		} else if (!pPlayer->IsInGame()) {
ds@2112
   599
			return pContext->ThrowNativeError("Client %d is not connected", client);
ds@2112
   600
		}
ds@2112
   601
	}
ds@2112
   602
ds@2112
   603
	crf.Initialize(cl_array, numClients);
dvander@1047
   604
dvander@1047
   605
	char *sample;
dvander@1047
   606
	pContext->LocalToString(params[3], &sample);
dvander@1047
   607
	
pred@2760
   608
	int entity = SoundReferenceToIndex(params[4]);
dvander@1047
   609
	int channel = params[5];
dvander@1047
   610
	int level = params[6];
dvander@1047
   611
	int flags = params[7];
dvander@1047
   612
	float vol = sp_ctof(params[8]);
dvander@1047
   613
	int pitch = params[9];
dvander@1047
   614
	int speakerentity = params[10];
dvander@1047
   615
dvander@1047
   616
	Vector *pOrigin = NULL, origin;
dvander@1047
   617
	Vector *pDir = NULL, dir;
dvander@1047
   618
dvander@1047
   619
	pContext->LocalToPhysAddr(params[11], &addr);
dvander@1047
   620
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
   621
	{
dvander@1047
   622
		pOrigin = &origin;
dvander@1047
   623
		origin.x = sp_ctof(addr[0]);
dvander@1047
   624
		origin.y = sp_ctof(addr[1]);
dvander@1047
   625
		origin.z = sp_ctof(addr[2]);
dvander@1047
   626
	}
dvander@1047
   627
dvander@1047
   628
	pContext->LocalToPhysAddr(params[12], &addr);
dvander@1047
   629
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
   630
	{
dvander@1047
   631
		pDir = &dir;
dvander@1047
   632
		dir.x = sp_ctof(addr[0]);
dvander@1047
   633
		dir.y = sp_ctof(addr[1]);
dvander@1047
   634
		dir.z = sp_ctof(addr[2]);
dvander@1047
   635
	}
dvander@1047
   636
dvander@1047
   637
	bool updatePos = params[13] ? true : false;
dvander@1047
   638
	float soundtime = sp_ctof(params[14]);
dvander@1047
   639
dvander@1047
   640
	CUtlVector<Vector> *pOrigVec = NULL;
dvander@1047
   641
	CUtlVector<Vector> origvec;
dvander@1047
   642
	if (params[0] > 14)
dvander@1047
   643
	{
dvander@1047
   644
		pOrigVec = &origvec;
dvander@1047
   645
		for (cell_t i = 15; i <= params[0]; i++)
dvander@1047
   646
		{
dvander@1047
   647
			Vector vec;
dvander@1047
   648
			pContext->LocalToPhysAddr(params[i], &addr);
dvander@1047
   649
			vec.x = sp_ctof(addr[0]);
dvander@1047
   650
			vec.y = sp_ctof(addr[1]);
dvander@1047
   651
			vec.z = sp_ctof(addr[2]);
dvander@1047
   652
			origvec.AddToTail(vec);
dvander@1047
   653
		}
dvander@1047
   654
	}
dvander@1047
   655
dvander@1047
   656
	/* If we're going to a "local player" and this is a dedicated server,
dvander@1047
   657
	 * intelligently redirect each sound.
dvander@1047
   658
	 */
dvander@1047
   659
dvander@1048
   660
	if (entity == -2 && engine->IsDedicatedServer())
dvander@1047
   661
	{
ds@2112
   662
		for (unsigned int i = 0; i < numClients; i++)
dvander@1047
   663
		{
dvander@1047
   664
			cell_t player[1];
ds@2112
   665
			player[0] = cl_array[i];
dvander@1047
   666
			crf.Reset();
dvander@1047
   667
			crf.Initialize(player, 1);
skamonkey@3515
   668
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   669
			if (g_InSoundHook)
skamonkey@3515
   670
			{
skamonkey@3515
   671
				SH_CALL(enginesoundPatch, 
skamonkey@3515
   672
					static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, 
skamonkey@3515
   673
					soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3515
   674
skamonkey@3515
   675
					(&IEngineSound::EmitSound))
skamonkey@3515
   676
					(crf, 
skamonkey@3515
   677
					player[0], 
skamonkey@3515
   678
					channel, 
skamonkey@3515
   679
					sample, 
skamonkey@3515
   680
					-1, 
skamonkey@3515
   681
					sample, 
skamonkey@3515
   682
					vol, 
skamonkey@3515
   683
					(soundlevel_t)level, 
skamonkey@3515
   684
					0, 
skamonkey@3515
   685
					flags, 
skamonkey@3515
   686
					pitch, 
skamonkey@3515
   687
					pOrigin,
skamonkey@3515
   688
					pDir,
skamonkey@3515
   689
					pOrigVec,
skamonkey@3515
   690
					updatePos,
skamonkey@3515
   691
					soundtime,
skamonkey@3515
   692
					speakerentity);
skamonkey@3515
   693
			}
skamonkey@3515
   694
			else
skamonkey@3515
   695
			{
skamonkey@3515
   696
				engsound->EmitSound(crf, 
skamonkey@3515
   697
					player[0], 
skamonkey@3515
   698
					channel, 
skamonkey@3515
   699
					sample, 
skamonkey@3515
   700
					-1, 
skamonkey@3515
   701
					sample, 
skamonkey@3515
   702
					vol, 
skamonkey@3515
   703
					(soundlevel_t)level, 
skamonkey@3515
   704
					0, 
skamonkey@3515
   705
					flags, 
skamonkey@3515
   706
					pitch, 
skamonkey@3515
   707
					pOrigin,
skamonkey@3515
   708
					pDir,
skamonkey@3515
   709
					pOrigVec,
skamonkey@3515
   710
					updatePos,
skamonkey@3515
   711
					soundtime,
skamonkey@3515
   712
					speakerentity);
skamonkey@3515
   713
			}
skamonkey@3961
   714
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   715
			if (g_InSoundHook)
skamonkey@3564
   716
			{
skamonkey@3564
   717
				SH_CALL(enginesoundPatch, 
skamonkey@3564
   718
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
skamonkey@3564
   719
					soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3564
   720
					(&IEngineSound::EmitSound))
skamonkey@3564
   721
					(crf, 
skamonkey@3564
   722
					player[0], 
skamonkey@3564
   723
					channel, 
skamonkey@3564
   724
					sample, 
skamonkey@3564
   725
					vol, 
skamonkey@3564
   726
					(soundlevel_t)level, 
skamonkey@3564
   727
					flags, 
skamonkey@3564
   728
					pitch, 
skamonkey@3564
   729
					0, 
skamonkey@3564
   730
					pOrigin,
skamonkey@3564
   731
					pDir,
skamonkey@3564
   732
					pOrigVec,
skamonkey@3564
   733
					updatePos,
skamonkey@3564
   734
					soundtime,
skamonkey@3564
   735
					speakerentity);
skamonkey@3564
   736
			}
skamonkey@3564
   737
			else
skamonkey@3564
   738
			{
skamonkey@3564
   739
				engsound->EmitSound(crf, 
skamonkey@3564
   740
					player[0], 
skamonkey@3564
   741
					channel, 
skamonkey@3564
   742
					sample, 
skamonkey@3564
   743
					vol, 
skamonkey@3564
   744
					(soundlevel_t)level, 
skamonkey@3564
   745
					flags, 
skamonkey@3564
   746
					pitch, 
skamonkey@3564
   747
					0, 
skamonkey@3564
   748
					pOrigin,
skamonkey@3564
   749
					pDir,
skamonkey@3564
   750
					pOrigVec,
skamonkey@3564
   751
					updatePos,
skamonkey@3564
   752
					soundtime,
skamonkey@3564
   753
					speakerentity);
skamonkey@3564
   754
			}
skamonkey@3515
   755
#else
faluco@1735
   756
			if (g_InSoundHook)
faluco@1735
   757
			{
faluco@1735
   758
				SH_CALL(enginesoundPatch, 
faluco@1735
   759
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
faluco@1735
   760
					soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
faluco@1735
   761
					(&IEngineSound::EmitSound))
faluco@1735
   762
					(crf, 
faluco@1735
   763
					player[0], 
faluco@1735
   764
					channel, 
faluco@1735
   765
					sample, 
faluco@1735
   766
					vol, 
faluco@1735
   767
					(soundlevel_t)level, 
faluco@1735
   768
					flags, 
faluco@1735
   769
					pitch, 
faluco@1735
   770
					pOrigin,
faluco@1735
   771
					pDir,
faluco@1735
   772
					pOrigVec,
faluco@1735
   773
					updatePos,
faluco@1735
   774
					soundtime,
faluco@1735
   775
					speakerentity);
faluco@1735
   776
			}
faluco@1735
   777
			else
faluco@1735
   778
			{
faluco@1735
   779
				engsound->EmitSound(crf, 
faluco@1735
   780
					player[0], 
faluco@1735
   781
					channel, 
faluco@1735
   782
					sample, 
faluco@1735
   783
					vol, 
faluco@1735
   784
					(soundlevel_t)level, 
faluco@1735
   785
					flags, 
faluco@1735
   786
					pitch, 
faluco@1735
   787
					pOrigin,
faluco@1735
   788
					pDir,
faluco@1735
   789
					pOrigVec,
faluco@1735
   790
					updatePos,
faluco@1735
   791
					soundtime,
faluco@1735
   792
					speakerentity);
faluco@1735
   793
			}
skamonkey@3515
   794
#endif
faluco@1735
   795
		}
faluco@1735
   796
	} else {
skamonkey@3515
   797
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   798
		if (g_InSoundHook)
skamonkey@3515
   799
		{
skamonkey@3515
   800
			SH_CALL(enginesoundPatch, 
skamonkey@3515
   801
				static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, 
skamonkey@3515
   802
				soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3515
   803
				(&IEngineSound::EmitSound))
skamonkey@3515
   804
				(crf, 
skamonkey@3515
   805
				entity, 
skamonkey@3515
   806
				channel, 
skamonkey@3515
   807
				sample, 
skamonkey@3515
   808
				-1, 
skamonkey@3515
   809
				sample, 
skamonkey@3515
   810
				vol, 
skamonkey@3515
   811
				(soundlevel_t)level, 
skamonkey@3515
   812
				0, 
skamonkey@3515
   813
				flags, 
skamonkey@3515
   814
				pitch, 
skamonkey@3515
   815
				pOrigin,
skamonkey@3515
   816
				pDir,
skamonkey@3515
   817
				pOrigVec,
skamonkey@3515
   818
				updatePos,
skamonkey@3515
   819
				soundtime,
skamonkey@3515
   820
				speakerentity);
skamonkey@3515
   821
		}
skamonkey@3515
   822
		else
skamonkey@3515
   823
		{
skamonkey@3515
   824
			engsound->EmitSound(crf, 
skamonkey@3515
   825
				entity, 
skamonkey@3515
   826
				channel, 
skamonkey@3515
   827
				sample, 
skamonkey@3515
   828
				-1, 
skamonkey@3515
   829
				sample, 
skamonkey@3515
   830
				vol, 
skamonkey@3515
   831
				(soundlevel_t)level, 
skamonkey@3515
   832
				0, 
skamonkey@3515
   833
				flags, 
skamonkey@3515
   834
				pitch, 
skamonkey@3515
   835
				pOrigin,
skamonkey@3515
   836
				pDir,
skamonkey@3515
   837
				pOrigVec,
skamonkey@3515
   838
				updatePos,
skamonkey@3515
   839
				soundtime,
skamonkey@3515
   840
				speakerentity);
skamonkey@3515
   841
		}
skamonkey@3961
   842
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   843
		if (g_InSoundHook)
skamonkey@3564
   844
		{
skamonkey@3564
   845
			SH_CALL(enginesoundPatch, 
skamonkey@3564
   846
				static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
skamonkey@3564
   847
				soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3564
   848
				(&IEngineSound::EmitSound))
skamonkey@3564
   849
				(crf, 
skamonkey@3564
   850
				entity, 
skamonkey@3564
   851
				channel, 
skamonkey@3564
   852
				sample, 
skamonkey@3564
   853
				vol, 
skamonkey@3564
   854
				(soundlevel_t)level, 
skamonkey@3564
   855
				flags, 
skamonkey@3564
   856
				pitch, 
skamonkey@3564
   857
				0, 
skamonkey@3564
   858
				pOrigin,
skamonkey@3564
   859
				pDir,
skamonkey@3564
   860
				pOrigVec,
skamonkey@3564
   861
				updatePos,
skamonkey@3564
   862
				soundtime,
skamonkey@3564
   863
				speakerentity);
skamonkey@3564
   864
		}
skamonkey@3564
   865
		else
skamonkey@3564
   866
		{
skamonkey@3564
   867
			engsound->EmitSound(crf, 
skamonkey@3564
   868
				entity, 
skamonkey@3564
   869
				channel, 
skamonkey@3564
   870
				sample, 
skamonkey@3564
   871
				vol, 
skamonkey@3564
   872
				(soundlevel_t)level, 
skamonkey@3564
   873
				flags, 
skamonkey@3564
   874
				pitch, 
skamonkey@3564
   875
				0, 
skamonkey@3564
   876
				pOrigin,
skamonkey@3564
   877
				pDir,
skamonkey@3564
   878
				pOrigVec,
skamonkey@3564
   879
				updatePos,
skamonkey@3564
   880
				soundtime,
skamonkey@3564
   881
				speakerentity);
skamonkey@3564
   882
		}
skamonkey@3515
   883
#else
faluco@1735
   884
		if (g_InSoundHook)
faluco@1735
   885
		{
faluco@1735
   886
			SH_CALL(enginesoundPatch, 
faluco@1735
   887
				static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
faluco@1735
   888
				soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
faluco@1735
   889
				(&IEngineSound::EmitSound))
faluco@1735
   890
				(crf, 
faluco@1735
   891
				entity, 
dvander@1047
   892
				channel, 
dvander@1047
   893
				sample, 
dvander@1047
   894
				vol, 
dvander@1047
   895
				(soundlevel_t)level, 
dvander@1047
   896
				flags, 
dvander@1047
   897
				pitch, 
dvander@1047
   898
				pOrigin,
dvander@1047
   899
				pDir,
dvander@1047
   900
				pOrigVec,
dvander@1047
   901
				updatePos,
dvander@1047
   902
				soundtime,
dvander@1047
   903
				speakerentity);
dvander@1047
   904
		}
faluco@1735
   905
		else
faluco@1735
   906
		{
faluco@1735
   907
			engsound->EmitSound(crf, 
faluco@1735
   908
				entity, 
faluco@1735
   909
				channel, 
faluco@1735
   910
				sample, 
faluco@1735
   911
				vol, 
faluco@1735
   912
				(soundlevel_t)level, 
faluco@1735
   913
				flags, 
faluco@1735
   914
				pitch, 
faluco@1735
   915
				pOrigin,
faluco@1735
   916
				pDir,
faluco@1735
   917
				pOrigVec,
faluco@1735
   918
				updatePos,
faluco@1735
   919
				soundtime,
faluco@1735
   920
				speakerentity);
faluco@1735
   921
		}
skamonkey@3515
   922
#endif
dvander@1047
   923
	}
dvander@1047
   924
dvander@1047
   925
	return 1;
dvander@1047
   926
}
dvander@1047
   927
dvander@1047
   928
static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
dvander@1047
   929
{
dvander@1047
   930
	cell_t *addr;
ds@2112
   931
	CellRecipientFilter crf;
ds@2112
   932
	unsigned int numClients;
ds@2112
   933
	int client;
ds@2112
   934
	IGamePlayer *pPlayer = NULL;
dvander@1047
   935
dvander@1047
   936
	pContext->LocalToPhysAddr(params[1], &addr);
ds@2112
   937
	numClients = params[2];
ds@2112
   938
ds@2112
   939
	/* Client validation */
ds@2112
   940
	for (unsigned int i = 0; i < numClients; i++)
ds@2112
   941
	{
ds@2112
   942
		client = addr[i];
ds@2112
   943
		pPlayer = playerhelpers->GetGamePlayer(client);
ds@2112
   944
ds@2112
   945
		if (!pPlayer)
ds@2112
   946
		{
ds@2112
   947
			return pContext->ThrowNativeError("Client index %d is invalid", client);
ds@2112
   948
		} else if (!pPlayer->IsInGame()) {
ds@2112
   949
			return pContext->ThrowNativeError("Client %d is not connected", client);
ds@2112
   950
		}
ds@2112
   951
	}
ds@2112
   952
ds@2112
   953
	crf.Initialize(addr, numClients);
dvander@1047
   954
dvander@1047
   955
	int sentence = params[3];
pred@2760
   956
	int entity = SoundReferenceToIndex(params[4]);
dvander@1047
   957
	int channel = params[5];
dvander@1047
   958
	int level = params[6];
dvander@1047
   959
	int flags = params[7];
dvander@1047
   960
	float vol = sp_ctof(params[8]);
dvander@1047
   961
	int pitch = params[9];
dvander@1047
   962
	int speakerentity = params[10];
dvander@1047
   963
dvander@1047
   964
	Vector *pOrigin = NULL, origin;
dvander@1047
   965
	Vector *pDir = NULL, dir;
dvander@1047
   966
dvander@1047
   967
	pContext->LocalToPhysAddr(params[11], &addr);
dvander@1047
   968
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
   969
	{
dvander@1047
   970
		pOrigin = &origin;
dvander@1047
   971
		origin.x = sp_ctof(addr[0]);
dvander@1047
   972
		origin.y = sp_ctof(addr[1]);
dvander@1047
   973
		origin.z = sp_ctof(addr[2]);
dvander@1047
   974
	}
dvander@1047
   975
dvander@1047
   976
	pContext->LocalToPhysAddr(params[12], &addr);
dvander@1047
   977
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
   978
	{
dvander@1047
   979
		pDir = &dir;
dvander@1047
   980
		dir.x = sp_ctof(addr[0]);
dvander@1047
   981
		dir.y = sp_ctof(addr[1]);
dvander@1047
   982
		dir.z = sp_ctof(addr[2]);
dvander@1047
   983
	}
dvander@1047
   984
dvander@1047
   985
	bool updatePos = params[13] ? true : false;
dvander@1047
   986
	float soundtime = sp_ctof(params[14]);
dvander@1047
   987
dvander@1047
   988
	CUtlVector<Vector> *pOrigVec = NULL;
dvander@1047
   989
	CUtlVector<Vector> origvec;
dvander@1047
   990
	if (params[0] > 14)
dvander@1047
   991
	{
dvander@1047
   992
		pOrigVec = &origvec;
dvander@1047
   993
		for (cell_t i = 15; i <= params[0]; i++)
dvander@1047
   994
		{
dvander@1047
   995
			Vector vec;
dvander@1047
   996
			pContext->LocalToPhysAddr(params[i], &addr);
dvander@1047
   997
			vec.x = sp_ctof(addr[0]);
dvander@1047
   998
			vec.y = sp_ctof(addr[1]);
dvander@1047
   999
			vec.z = sp_ctof(addr[2]);
dvander@1047
  1000
			origvec.AddToTail(vec);
dvander@1047
  1001
		}
dvander@1047
  1002
	}
dvander@1047
  1003
dvander@1047
  1004
	engsound->EmitSentenceByIndex(crf, 
dvander@1047
  1005
		entity, 
dvander@1047
  1006
		channel, 
dvander@1047
  1007
		sentence, 
dvander@1047
  1008
		vol, 
dvander@1047
  1009
		(soundlevel_t)level, 
skamonkey@3515
  1010
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
  1011
		0, 
skamonkey@3515
  1012
#endif
dvander@1047
  1013
		flags, 
dvander@1047
  1014
		pitch, 
skamonkey@3961
  1015
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
skamonkey@3566
  1016
		0, 
skamonkey@3566
  1017
#endif
dvander@1047
  1018
		pOrigin,
dvander@1047
  1019
		pDir,
dvander@1047
  1020
		pOrigVec,
dvander@1047
  1021
		updatePos,
dvander@1047
  1022
		soundtime,
dvander@1047
  1023
		speakerentity);
dvander@1047
  1024
dvander@1047
  1025
	return 1;
dvander@1047
  1026
}
dvander@1047
  1027
faluco@1735
  1028
static cell_t smn_AddAmbientSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1029
{
faluco@1735
  1030
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1031
	if (!pFunc)
faluco@1735
  1032
	{
faluco@1735
  1033
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1034
	}
faluco@1735
  1035
faluco@1735
  1036
	s_SoundHooks.AddHook(AMBIENT_SOUND_HOOK, pFunc);
faluco@1735
  1037
faluco@1735
  1038
	return 1;
faluco@1735
  1039
}
faluco@1735
  1040
faluco@1735
  1041
static cell_t smn_AddNormalSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1042
{
faluco@1735
  1043
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1044
	if (!pFunc)
faluco@1735
  1045
	{
faluco@1735
  1046
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1047
	}
faluco@1735
  1048
faluco@1735
  1049
	s_SoundHooks.AddHook(NORMAL_SOUND_HOOK, pFunc);
faluco@1735
  1050
faluco@1735
  1051
	return 1;
faluco@1735
  1052
}
faluco@1735
  1053
faluco@1735
  1054
static cell_t smn_RemoveAmbientSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1055
{
faluco@1735
  1056
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1057
	if (!pFunc)
faluco@1735
  1058
	{
faluco@1735
  1059
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1060
	}
faluco@1735
  1061
faluco@1735
  1062
	if (!s_SoundHooks.RemoveHook(AMBIENT_SOUND_HOOK, pFunc))
faluco@1735
  1063
	{
faluco@1735
  1064
		return pContext->ThrowNativeError("Invalid hooked function");
faluco@1735
  1065
	}
faluco@1735
  1066
faluco@1735
  1067
	return 1;
faluco@1735
  1068
}
faluco@1735
  1069
faluco@1735
  1070
static cell_t smn_RemoveNormalSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1071
{
faluco@1735
  1072
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1073
	if (!pFunc)
faluco@1735
  1074
	{
faluco@1735
  1075
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1076
	}
faluco@1735
  1077
faluco@1735
  1078
	if (!s_SoundHooks.RemoveHook(NORMAL_SOUND_HOOK, pFunc))
faluco@1735
  1079
	{
faluco@1735
  1080
		return pContext->ThrowNativeError("Invalid hooked function");
faluco@1735
  1081
	}
faluco@1735
  1082
faluco@1735
  1083
	return 1;
faluco@1735
  1084
}
faluco@1735
  1085
javalia@3384
  1086
static cell_t smn_GetDistGainFromSoundLevel(IPluginContext *pContext, const cell_t *params)
javalia@3384
  1087
{
javalia@3384
  1088
	int decibel = params[1];
javalia@3384
  1089
	float distance = sp_ctof(params[2]);
javalia@3384
  1090
skamonkey@3385
  1091
	return sp_ftoc(engsound->GetDistGainFromSoundLevel((soundlevel_t)decibel, distance));
javalia@3384
  1092
}
javalia@3384
  1093
dvander@1047
  1094
sp_nativeinfo_t g_SoundNatives[] = 
dvander@1047
  1095
{
faluco@1735
  1096
	{"EmitAmbientSound",		EmitAmbientSound},
faluco@1735
  1097
	{"EmitSentence",			EmitSentence},
faluco@1735
  1098
	{"EmitSound",				EmitSound},
faluco@1735
  1099
	{"FadeClientVolume",		FadeClientVolume},
faluco@1735
  1100
	{"GetSoundDuration",		GetSoundDuration},
faluco@1735
  1101
	{"PrefetchSound",			PrefetchSound},
faluco@1735
  1102
	{"StopSound",				StopSound},
faluco@1735
  1103
	{"AddAmbientSoundHook",		smn_AddAmbientSoundHook},
faluco@1735
  1104
	{"AddNormalSoundHook",		smn_AddNormalSoundHook},
faluco@1735
  1105
	{"RemoveAmbientSoundHook",	smn_RemoveAmbientSoundHook},
faluco@1735
  1106
	{"RemoveNormalSoundHook",	smn_RemoveNormalSoundHook},
javalia@3384
  1107
	{"GetDistGainFromSoundLevel", smn_GetDistGainFromSoundLevel},
faluco@1735
  1108
	{NULL,						NULL},
dvander@1047
  1109
};