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