extensions/sdktools/vsound.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Fri Feb 07 22:11:31 2014 -0500 (2014-02-07)
changeset 4231 84b709f4103a
parent 4209 1621324faee5
child 4344 c445c3266192
permissions -rw-r--r--
Fix SDKHooks load issue and reliance on gEntList ptr on CS:GO and Dota 2 on Windows.
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@4141
    44
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || 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@4141
   291
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || 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
			{
kyle@4209
   341
				/* Client validation */
kyle@4209
   342
				for (int i = 0; i < size; i++)
kyle@4209
   343
				{
kyle@4209
   344
					int client = players[i];
kyle@4209
   345
					IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
kyle@4209
   346
kyle@4209
   347
					if (!pPlayer)
kyle@4209
   348
					{
kyle@4209
   349
						pFunc->GetParentContext()->ThrowNativeError("Client index %d is invalid", client);
kyle@4209
   350
					} else if (!pPlayer->IsInGame()) {
kyle@4209
   351
						pFunc->GetParentContext()->ThrowNativeError("Client %d is not connected", client);
kyle@4209
   352
					} else {
kyle@4209
   353
						continue;
kyle@4209
   354
					}
kyle@4209
   355
kyle@4209
   356
#if SOURCE_ENGINE >= SE_PORTAL2
kyle@4209
   357
					RETURN_META_VALUE(MRES_IGNORED, -1 );
kyle@4209
   358
#else
kyle@4209
   359
					return;
kyle@4209
   360
#endif
kyle@4209
   361
				}
kyle@4209
   362
faluco@1735
   363
				CellRecipientFilter crf;
faluco@1735
   364
				crf.Initialize(players, size);
skamonkey@3515
   365
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   366
				RETURN_META_VALUE_NEWPARAMS(
skamonkey@3515
   367
					MRES_IGNORED,
skamonkey@3515
   368
					-1,
skamonkey@3515
   369
					static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t, 
skamonkey@3515
   370
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3515
   371
					(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin, 
skamonkey@3515
   372
					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3515
   373
					);
skamonkey@4141
   374
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   375
				RETURN_META_NEWPARAMS(
skamonkey@3564
   376
					MRES_IGNORED,
skamonkey@3564
   377
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, 
skamonkey@3564
   378
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3564
   379
					(crf, iEntIndex, iChannel, buffer, flVolume, iSoundlevel, iFlags, iPitch, iSpecialDSP, pOrigin, 
skamonkey@3564
   380
					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3564
   381
					);
skamonkey@3515
   382
#else
faluco@1735
   383
				RETURN_META_NEWPARAMS(
faluco@1735
   384
					MRES_IGNORED,
faluco@1735
   385
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t, 
faluco@1735
   386
					int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
faluco@1735
   387
					(crf, iEntIndex, iChannel, buffer, flVolume, iSoundlevel, iFlags, iPitch, pOrigin, 
faluco@1735
   388
					pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
faluco@1735
   389
					);
skamonkey@3515
   390
#endif
faluco@1735
   391
			}
faluco@1735
   392
		}
faluco@1735
   393
	}
skamonkey@3515
   394
skamonkey@3515
   395
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   396
	RETURN_META_VALUE(MRES_IGNORED, -1 );
skamonkey@3515
   397
#endif
faluco@1735
   398
}
faluco@1735
   399
skamonkey@3515
   400
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   401
int SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample, 
skamonkey@3515
   402
							 float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin, 
skamonkey@3515
   403
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
skamonkey@3515
   404
							 float soundtime, int speakerentity)
skamonkey@4141
   405
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   406
void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
skamonkey@3564
   407
							 float flVolume, float flAttenuation, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin, 
skamonkey@3564
   408
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
skamonkey@3564
   409
							 float soundtime, int speakerentity)
skamonkey@3515
   410
#else
faluco@1735
   411
void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample, 
faluco@1735
   412
							 float flVolume, float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin, 
faluco@1735
   413
							 const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions, 
faluco@1735
   414
							 float soundtime, int speakerentity)
skamonkey@3515
   415
#endif
faluco@1735
   416
{
faluco@1735
   417
	SoundHookIter iter;
faluco@1735
   418
	IPluginFunction *pFunc;
faluco@1735
   419
	cell_t res = static_cast<ResultType>(Pl_Continue);
faluco@1735
   420
	cell_t sndlevel = static_cast<cell_t>(ATTN_TO_SNDLVL(flAttenuation));
faluco@1735
   421
	char buffer[PLATFORM_MAX_PATH];
faluco@1735
   422
	strcpy(buffer, pSample);
faluco@1735
   423
faluco@1735
   424
	for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
faluco@1735
   425
	{
faluco@1735
   426
		int players[64], size;
faluco@1735
   427
		size = _FillInPlayers(players, &filter);
faluco@1735
   428
		pFunc = (*iter);
faluco@1735
   429
faluco@1735
   430
		pFunc->PushArray(players, 64, SM_PARAM_COPYBACK);
faluco@1735
   431
		pFunc->PushCellByRef(&size);
faluco@1735
   432
		pFunc->PushStringEx(buffer, sizeof(buffer), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
faluco@1735
   433
		pFunc->PushCellByRef(&iEntIndex);
faluco@1735
   434
		pFunc->PushCellByRef(&iChannel);
faluco@1735
   435
		pFunc->PushFloatByRef(&flVolume);
faluco@1735
   436
		pFunc->PushCellByRef(&sndlevel);
faluco@1735
   437
		pFunc->PushCellByRef(&iPitch);
faluco@1735
   438
		pFunc->PushCellByRef(&iFlags);
faluco@1735
   439
		g_InSoundHook = true;
faluco@1735
   440
		pFunc->Execute(&res);
faluco@1735
   441
		g_InSoundHook = false;
faluco@1735
   442
faluco@1735
   443
		switch (res)
faluco@1735
   444
		{
faluco@1735
   445
		case Pl_Handled:
faluco@1735
   446
		case Pl_Stop:
faluco@1735
   447
			{
skamonkey@3515
   448
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   449
				RETURN_META_VALUE(MRES_SUPERCEDE, -1);
skamonkey@3515
   450
#else
faluco@1735
   451
				RETURN_META(MRES_SUPERCEDE);
skamonkey@3515
   452
#endif
faluco@1735
   453
			}
faluco@1735
   454
		case Pl_Changed:
faluco@1735
   455
			{
kyle@4209
   456
				/* Client validation */
kyle@4209
   457
				for (int i = 0; i < size; i++)
kyle@4209
   458
				{
kyle@4209
   459
					int client = players[i];
kyle@4209
   460
					IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
kyle@4209
   461
kyle@4209
   462
					if (!pPlayer)
kyle@4209
   463
					{
kyle@4209
   464
						pFunc->GetParentContext()->ThrowNativeError("Client index %d is invalid", client);
kyle@4209
   465
					} else if (!pPlayer->IsInGame()) {
kyle@4209
   466
						pFunc->GetParentContext()->ThrowNativeError("Client %d is not connected", client);
kyle@4209
   467
					} else {
kyle@4209
   468
						continue;
kyle@4209
   469
					}
kyle@4209
   470
kyle@4209
   471
#if SOURCE_ENGINE >= SE_PORTAL2
kyle@4209
   472
					RETURN_META_VALUE(MRES_IGNORED, -1 );
kyle@4209
   473
#else
kyle@4209
   474
					return;
kyle@4209
   475
#endif
kyle@4209
   476
				}
kyle@4209
   477
faluco@1735
   478
				CellRecipientFilter crf;
faluco@1735
   479
				crf.Initialize(players, size);
skamonkey@3515
   480
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   481
				RETURN_META_VALUE_NEWPARAMS(
skamonkey@3515
   482
					MRES_IGNORED,
skamonkey@3515
   483
					-1,
skamonkey@3515
   484
					static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, 
skamonkey@3515
   485
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3515
   486
					(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), 
skamonkey@3515
   487
					nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3515
   488
					);
skamonkey@4141
   489
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   490
RETURN_META_NEWPARAMS(
skamonkey@3564
   491
					MRES_IGNORED,
skamonkey@3564
   492
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, 
skamonkey@3564
   493
					int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
skamonkey@3564
   494
					(crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), 
skamonkey@3564
   495
					iFlags, iPitch, iSpecialDSP, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
skamonkey@3564
   496
					);
skamonkey@3515
   497
#else
faluco@1735
   498
				RETURN_META_NEWPARAMS(
faluco@1735
   499
					MRES_IGNORED,
skamonkey@3515
   500
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float, 
faluco@1735
   501
					int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound), 
faluco@1735
   502
					(crf, iEntIndex, iChannel, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)), 
faluco@1735
   503
					iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
faluco@1735
   504
					);
skamonkey@3515
   505
#endif
faluco@1735
   506
			}
faluco@1735
   507
		}
faluco@1735
   508
	}
skamonkey@3515
   509
skamonkey@3515
   510
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   511
	RETURN_META_VALUE(MRES_IGNORED, -1 );
skamonkey@3515
   512
#endif
faluco@1735
   513
}
faluco@1735
   514
faluco@1735
   515
/************************
faluco@1735
   516
*                       *
faluco@1735
   517
* Sound Related Natives *
faluco@1735
   518
*                       *
faluco@1735
   519
*************************/
faluco@1735
   520
faluco@1735
   521
SoundHooks s_SoundHooks;
dvander@1047
   522
dvander@1047
   523
static cell_t PrefetchSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   524
{
dvander@1047
   525
	char *name;
dvander@1047
   526
	pContext->LocalToString(params[1], &name);
dvander@1047
   527
dvander@1047
   528
	engsound->PrefetchSound(name);
dvander@1047
   529
dvander@1047
   530
	return 1;
dvander@1047
   531
}
dvander@1047
   532
dvander@1047
   533
static cell_t GetSoundDuration(IPluginContext *pContext, const cell_t *params)
dvander@1047
   534
{
dvander@1047
   535
	char *name;
dvander@1047
   536
	pContext->LocalToString(params[1], &name);
dvander@1047
   537
dvander@1047
   538
	return sp_ftoc(engsound->GetSoundDuration(name));
dvander@1047
   539
}
dvander@1047
   540
dvander@1047
   541
static cell_t EmitAmbientSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   542
{
dvander@1047
   543
	cell_t entity;
dvander@1047
   544
	Vector pos;
dvander@1047
   545
	char *name;
dvander@1047
   546
	float vol, delay;
dvander@1047
   547
	int pitch, flags, level;
dvander@1047
   548
pred@2760
   549
	entity = SoundReferenceToIndex(params[3]);
dvander@1047
   550
dvander@1047
   551
	cell_t *addr;
dvander@1047
   552
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@1047
   553
	pos.x = sp_ctof(addr[0]);
dvander@1047
   554
	pos.y = sp_ctof(addr[1]);
dvander@1047
   555
	pos.z = sp_ctof(addr[2]);
dvander@1047
   556
dvander@1047
   557
	pContext->LocalToString(params[1], &name);
dvander@1047
   558
dvander@1047
   559
	vol = sp_ctof(params[6]);
dvander@1047
   560
	level = params[4];
dvander@1047
   561
	flags = params[5];
dvander@1047
   562
	pitch = params[7];
dvander@1047
   563
	delay = sp_ctof(params[8]);
dvander@1047
   564
faluco@1735
   565
	if (g_InSoundHook)
faluco@1735
   566
	{
faluco@1735
   567
		ENGINE_CALL(EmitAmbientSound)(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay);
faluco@1735
   568
	}
faluco@1735
   569
	else
faluco@1735
   570
	{
faluco@1735
   571
		engine->EmitAmbientSound(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay);
faluco@1735
   572
	}
dvander@1047
   573
dvander@1047
   574
	return 1;
dvander@1047
   575
}
dvander@1047
   576
dvander@1047
   577
static cell_t FadeClientVolume(IPluginContext *pContext, const cell_t *params)
dvander@1047
   578
{
dvander@1047
   579
	int client = params[1];
dvander@1047
   580
	if (client < 1 || client > playerhelpers->GetMaxClients())
dvander@1047
   581
	{
dvander@1047
   582
		return pContext->ThrowNativeError("Client index %d is not valid", client);
dvander@1047
   583
	}
dvander@1047
   584
dvander@1047
   585
	IGamePlayer *player = playerhelpers->GetGamePlayer(client);
dvander@1047
   586
	if (!player->IsInGame())
dvander@1047
   587
	{
dvander@1047
   588
		return pContext->ThrowNativeError("Client index %d is not in game", client);
dvander@1047
   589
	}
dvander@1047
   590
skamonkey@3913
   591
	engine->FadeClientVolume(
skamonkey@3913
   592
#if SOURCE_ENGINE == SE_DOTA
skamonkey@3913
   593
		player->GetIndex(),
skamonkey@3913
   594
#else
skamonkey@3913
   595
		player->GetEdict(),
skamonkey@3913
   596
#endif
dvander@1047
   597
		sp_ctof(params[2]),
dvander@1047
   598
		sp_ctof(params[3]),
dvander@1047
   599
		sp_ctof(params[4]),
dvander@1047
   600
		sp_ctof(params[5]));
dvander@1047
   601
dvander@1047
   602
	return 1;
dvander@1047
   603
}
dvander@1047
   604
dvander@1047
   605
static cell_t StopSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   606
{
pred@2760
   607
	int entity = SoundReferenceToIndex(params[1]);
dvander@1047
   608
	int channel = params[2];
dvander@1047
   609
dvander@1047
   610
	char *name;
dvander@1047
   611
	pContext->LocalToString(params[3], &name);
dvander@1047
   612
skamonkey@3515
   613
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   614
	engsound->StopSound(entity, channel, name, -1);
skamonkey@3515
   615
#else
dvander@1047
   616
	engsound->StopSound(entity, channel, name);
skamonkey@3515
   617
#endif
dvander@1047
   618
dvander@1047
   619
	return 1;
dvander@1047
   620
}
dvander@1047
   621
dvander@1047
   622
static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
dvander@1047
   623
{
ds@2112
   624
	cell_t *addr, *cl_array;
dvander@1047
   625
	CellRecipientFilter crf;
ds@2112
   626
	unsigned int numClients;
ds@2112
   627
	int client;
ds@2112
   628
	IGamePlayer *pPlayer = NULL;
ds@2112
   629
ds@2112
   630
	pContext->LocalToPhysAddr(params[1], &cl_array);
ds@2112
   631
	numClients = params[2];
ds@2112
   632
ds@2112
   633
	/* Client validation */
ds@2112
   634
	for (unsigned int i = 0; i < numClients; i++)
ds@2112
   635
	{
ds@2112
   636
		client = cl_array[i];
ds@2112
   637
		pPlayer = playerhelpers->GetGamePlayer(client);
ds@2112
   638
ds@2112
   639
		if (!pPlayer)
ds@2112
   640
		{
ds@2112
   641
			return pContext->ThrowNativeError("Client index %d is invalid", client);
ds@2112
   642
		} else if (!pPlayer->IsInGame()) {
ds@2112
   643
			return pContext->ThrowNativeError("Client %d is not connected", client);
ds@2112
   644
		}
ds@2112
   645
	}
ds@2112
   646
ds@2112
   647
	crf.Initialize(cl_array, numClients);
dvander@1047
   648
dvander@1047
   649
	char *sample;
dvander@1047
   650
	pContext->LocalToString(params[3], &sample);
dvander@1047
   651
	
pred@2760
   652
	int entity = SoundReferenceToIndex(params[4]);
dvander@1047
   653
	int channel = params[5];
dvander@1047
   654
	int level = params[6];
dvander@1047
   655
	int flags = params[7];
dvander@1047
   656
	float vol = sp_ctof(params[8]);
dvander@1047
   657
	int pitch = params[9];
dvander@1047
   658
	int speakerentity = params[10];
dvander@1047
   659
dvander@1047
   660
	Vector *pOrigin = NULL, origin;
dvander@1047
   661
	Vector *pDir = NULL, dir;
dvander@1047
   662
dvander@1047
   663
	pContext->LocalToPhysAddr(params[11], &addr);
dvander@1047
   664
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
   665
	{
dvander@1047
   666
		pOrigin = &origin;
dvander@1047
   667
		origin.x = sp_ctof(addr[0]);
dvander@1047
   668
		origin.y = sp_ctof(addr[1]);
dvander@1047
   669
		origin.z = sp_ctof(addr[2]);
dvander@1047
   670
	}
dvander@1047
   671
dvander@1047
   672
	pContext->LocalToPhysAddr(params[12], &addr);
dvander@1047
   673
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
   674
	{
dvander@1047
   675
		pDir = &dir;
dvander@1047
   676
		dir.x = sp_ctof(addr[0]);
dvander@1047
   677
		dir.y = sp_ctof(addr[1]);
dvander@1047
   678
		dir.z = sp_ctof(addr[2]);
dvander@1047
   679
	}
dvander@1047
   680
dvander@1047
   681
	bool updatePos = params[13] ? true : false;
dvander@1047
   682
	float soundtime = sp_ctof(params[14]);
dvander@1047
   683
dvander@1047
   684
	CUtlVector<Vector> *pOrigVec = NULL;
dvander@1047
   685
	CUtlVector<Vector> origvec;
dvander@1047
   686
	if (params[0] > 14)
dvander@1047
   687
	{
dvander@1047
   688
		pOrigVec = &origvec;
dvander@1047
   689
		for (cell_t i = 15; i <= params[0]; i++)
dvander@1047
   690
		{
dvander@1047
   691
			Vector vec;
dvander@1047
   692
			pContext->LocalToPhysAddr(params[i], &addr);
dvander@1047
   693
			vec.x = sp_ctof(addr[0]);
dvander@1047
   694
			vec.y = sp_ctof(addr[1]);
dvander@1047
   695
			vec.z = sp_ctof(addr[2]);
dvander@1047
   696
			origvec.AddToTail(vec);
dvander@1047
   697
		}
dvander@1047
   698
	}
dvander@1047
   699
dvander@1047
   700
	/* If we're going to a "local player" and this is a dedicated server,
dvander@1047
   701
	 * intelligently redirect each sound.
dvander@1047
   702
	 */
dvander@1047
   703
dvander@1048
   704
	if (entity == -2 && engine->IsDedicatedServer())
dvander@1047
   705
	{
ds@2112
   706
		for (unsigned int i = 0; i < numClients; i++)
dvander@1047
   707
		{
dvander@1047
   708
			cell_t player[1];
ds@2112
   709
			player[0] = cl_array[i];
dvander@1047
   710
			crf.Reset();
dvander@1047
   711
			crf.Initialize(player, 1);
skamonkey@3515
   712
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   713
			if (g_InSoundHook)
skamonkey@3515
   714
			{
skamonkey@3515
   715
				SH_CALL(enginesoundPatch, 
skamonkey@3515
   716
					static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, 
skamonkey@3515
   717
					soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3515
   718
skamonkey@3515
   719
					(&IEngineSound::EmitSound))
skamonkey@3515
   720
					(crf, 
skamonkey@3515
   721
					player[0], 
skamonkey@3515
   722
					channel, 
skamonkey@3515
   723
					sample, 
skamonkey@3515
   724
					-1, 
skamonkey@3515
   725
					sample, 
skamonkey@3515
   726
					vol, 
skamonkey@3515
   727
					(soundlevel_t)level, 
skamonkey@3515
   728
					0, 
skamonkey@3515
   729
					flags, 
skamonkey@3515
   730
					pitch, 
skamonkey@3515
   731
					pOrigin,
skamonkey@3515
   732
					pDir,
skamonkey@3515
   733
					pOrigVec,
skamonkey@3515
   734
					updatePos,
skamonkey@3515
   735
					soundtime,
skamonkey@3515
   736
					speakerentity);
skamonkey@3515
   737
			}
skamonkey@3515
   738
			else
skamonkey@3515
   739
			{
skamonkey@3515
   740
				engsound->EmitSound(crf, 
skamonkey@3515
   741
					player[0], 
skamonkey@3515
   742
					channel, 
skamonkey@3515
   743
					sample, 
skamonkey@3515
   744
					-1, 
skamonkey@3515
   745
					sample, 
skamonkey@3515
   746
					vol, 
skamonkey@3515
   747
					(soundlevel_t)level, 
skamonkey@3515
   748
					0, 
skamonkey@3515
   749
					flags, 
skamonkey@3515
   750
					pitch, 
skamonkey@3515
   751
					pOrigin,
skamonkey@3515
   752
					pDir,
skamonkey@3515
   753
					pOrigVec,
skamonkey@3515
   754
					updatePos,
skamonkey@3515
   755
					soundtime,
skamonkey@3515
   756
					speakerentity);
skamonkey@3515
   757
			}
skamonkey@4141
   758
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   759
			if (g_InSoundHook)
skamonkey@3564
   760
			{
skamonkey@3564
   761
				SH_CALL(enginesoundPatch, 
skamonkey@3564
   762
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
skamonkey@3564
   763
					soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3564
   764
					(&IEngineSound::EmitSound))
skamonkey@3564
   765
					(crf, 
skamonkey@3564
   766
					player[0], 
skamonkey@3564
   767
					channel, 
skamonkey@3564
   768
					sample, 
skamonkey@3564
   769
					vol, 
skamonkey@3564
   770
					(soundlevel_t)level, 
skamonkey@3564
   771
					flags, 
skamonkey@3564
   772
					pitch, 
skamonkey@3564
   773
					0, 
skamonkey@3564
   774
					pOrigin,
skamonkey@3564
   775
					pDir,
skamonkey@3564
   776
					pOrigVec,
skamonkey@3564
   777
					updatePos,
skamonkey@3564
   778
					soundtime,
skamonkey@3564
   779
					speakerentity);
skamonkey@3564
   780
			}
skamonkey@3564
   781
			else
skamonkey@3564
   782
			{
skamonkey@3564
   783
				engsound->EmitSound(crf, 
skamonkey@3564
   784
					player[0], 
skamonkey@3564
   785
					channel, 
skamonkey@3564
   786
					sample, 
skamonkey@3564
   787
					vol, 
skamonkey@3564
   788
					(soundlevel_t)level, 
skamonkey@3564
   789
					flags, 
skamonkey@3564
   790
					pitch, 
skamonkey@3564
   791
					0, 
skamonkey@3564
   792
					pOrigin,
skamonkey@3564
   793
					pDir,
skamonkey@3564
   794
					pOrigVec,
skamonkey@3564
   795
					updatePos,
skamonkey@3564
   796
					soundtime,
skamonkey@3564
   797
					speakerentity);
skamonkey@3564
   798
			}
skamonkey@3515
   799
#else
faluco@1735
   800
			if (g_InSoundHook)
faluco@1735
   801
			{
faluco@1735
   802
				SH_CALL(enginesoundPatch, 
faluco@1735
   803
					static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
faluco@1735
   804
					soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
faluco@1735
   805
					(&IEngineSound::EmitSound))
faluco@1735
   806
					(crf, 
faluco@1735
   807
					player[0], 
faluco@1735
   808
					channel, 
faluco@1735
   809
					sample, 
faluco@1735
   810
					vol, 
faluco@1735
   811
					(soundlevel_t)level, 
faluco@1735
   812
					flags, 
faluco@1735
   813
					pitch, 
faluco@1735
   814
					pOrigin,
faluco@1735
   815
					pDir,
faluco@1735
   816
					pOrigVec,
faluco@1735
   817
					updatePos,
faluco@1735
   818
					soundtime,
faluco@1735
   819
					speakerentity);
faluco@1735
   820
			}
faluco@1735
   821
			else
faluco@1735
   822
			{
faluco@1735
   823
				engsound->EmitSound(crf, 
faluco@1735
   824
					player[0], 
faluco@1735
   825
					channel, 
faluco@1735
   826
					sample, 
faluco@1735
   827
					vol, 
faluco@1735
   828
					(soundlevel_t)level, 
faluco@1735
   829
					flags, 
faluco@1735
   830
					pitch, 
faluco@1735
   831
					pOrigin,
faluco@1735
   832
					pDir,
faluco@1735
   833
					pOrigVec,
faluco@1735
   834
					updatePos,
faluco@1735
   835
					soundtime,
faluco@1735
   836
					speakerentity);
faluco@1735
   837
			}
skamonkey@3515
   838
#endif
faluco@1735
   839
		}
faluco@1735
   840
	} else {
skamonkey@3515
   841
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
   842
		if (g_InSoundHook)
skamonkey@3515
   843
		{
skamonkey@3515
   844
			SH_CALL(enginesoundPatch, 
skamonkey@3515
   845
				static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, 
skamonkey@3515
   846
				soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3515
   847
				(&IEngineSound::EmitSound))
skamonkey@3515
   848
				(crf, 
skamonkey@3515
   849
				entity, 
skamonkey@3515
   850
				channel, 
skamonkey@3515
   851
				sample, 
skamonkey@3515
   852
				-1, 
skamonkey@3515
   853
				sample, 
skamonkey@3515
   854
				vol, 
skamonkey@3515
   855
				(soundlevel_t)level, 
skamonkey@3515
   856
				0, 
skamonkey@3515
   857
				flags, 
skamonkey@3515
   858
				pitch, 
skamonkey@3515
   859
				pOrigin,
skamonkey@3515
   860
				pDir,
skamonkey@3515
   861
				pOrigVec,
skamonkey@3515
   862
				updatePos,
skamonkey@3515
   863
				soundtime,
skamonkey@3515
   864
				speakerentity);
skamonkey@3515
   865
		}
skamonkey@3515
   866
		else
skamonkey@3515
   867
		{
skamonkey@3515
   868
			engsound->EmitSound(crf, 
skamonkey@3515
   869
				entity, 
skamonkey@3515
   870
				channel, 
skamonkey@3515
   871
				sample, 
skamonkey@3515
   872
				-1, 
skamonkey@3515
   873
				sample, 
skamonkey@3515
   874
				vol, 
skamonkey@3515
   875
				(soundlevel_t)level, 
skamonkey@3515
   876
				0, 
skamonkey@3515
   877
				flags, 
skamonkey@3515
   878
				pitch, 
skamonkey@3515
   879
				pOrigin,
skamonkey@3515
   880
				pDir,
skamonkey@3515
   881
				pOrigVec,
skamonkey@3515
   882
				updatePos,
skamonkey@3515
   883
				soundtime,
skamonkey@3515
   884
				speakerentity);
skamonkey@3515
   885
		}
skamonkey@4141
   886
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3564
   887
		if (g_InSoundHook)
skamonkey@3564
   888
		{
skamonkey@3564
   889
			SH_CALL(enginesoundPatch, 
skamonkey@3564
   890
				static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
skamonkey@3564
   891
				soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
skamonkey@3564
   892
				(&IEngineSound::EmitSound))
skamonkey@3564
   893
				(crf, 
skamonkey@3564
   894
				entity, 
skamonkey@3564
   895
				channel, 
skamonkey@3564
   896
				sample, 
skamonkey@3564
   897
				vol, 
skamonkey@3564
   898
				(soundlevel_t)level, 
skamonkey@3564
   899
				flags, 
skamonkey@3564
   900
				pitch, 
skamonkey@3564
   901
				0, 
skamonkey@3564
   902
				pOrigin,
skamonkey@3564
   903
				pDir,
skamonkey@3564
   904
				pOrigVec,
skamonkey@3564
   905
				updatePos,
skamonkey@3564
   906
				soundtime,
skamonkey@3564
   907
				speakerentity);
skamonkey@3564
   908
		}
skamonkey@3564
   909
		else
skamonkey@3564
   910
		{
skamonkey@3564
   911
			engsound->EmitSound(crf, 
skamonkey@3564
   912
				entity, 
skamonkey@3564
   913
				channel, 
skamonkey@3564
   914
				sample, 
skamonkey@3564
   915
				vol, 
skamonkey@3564
   916
				(soundlevel_t)level, 
skamonkey@3564
   917
				flags, 
skamonkey@3564
   918
				pitch, 
skamonkey@3564
   919
				0, 
skamonkey@3564
   920
				pOrigin,
skamonkey@3564
   921
				pDir,
skamonkey@3564
   922
				pOrigVec,
skamonkey@3564
   923
				updatePos,
skamonkey@3564
   924
				soundtime,
skamonkey@3564
   925
				speakerentity);
skamonkey@3564
   926
		}
skamonkey@3515
   927
#else
faluco@1735
   928
		if (g_InSoundHook)
faluco@1735
   929
		{
faluco@1735
   930
			SH_CALL(enginesoundPatch, 
faluco@1735
   931
				static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, 
faluco@1735
   932
				soundlevel_t, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>
faluco@1735
   933
				(&IEngineSound::EmitSound))
faluco@1735
   934
				(crf, 
faluco@1735
   935
				entity, 
dvander@1047
   936
				channel, 
dvander@1047
   937
				sample, 
dvander@1047
   938
				vol, 
dvander@1047
   939
				(soundlevel_t)level, 
dvander@1047
   940
				flags, 
dvander@1047
   941
				pitch, 
dvander@1047
   942
				pOrigin,
dvander@1047
   943
				pDir,
dvander@1047
   944
				pOrigVec,
dvander@1047
   945
				updatePos,
dvander@1047
   946
				soundtime,
dvander@1047
   947
				speakerentity);
dvander@1047
   948
		}
faluco@1735
   949
		else
faluco@1735
   950
		{
faluco@1735
   951
			engsound->EmitSound(crf, 
faluco@1735
   952
				entity, 
faluco@1735
   953
				channel, 
faluco@1735
   954
				sample, 
faluco@1735
   955
				vol, 
faluco@1735
   956
				(soundlevel_t)level, 
faluco@1735
   957
				flags, 
faluco@1735
   958
				pitch, 
faluco@1735
   959
				pOrigin,
faluco@1735
   960
				pDir,
faluco@1735
   961
				pOrigVec,
faluco@1735
   962
				updatePos,
faluco@1735
   963
				soundtime,
faluco@1735
   964
				speakerentity);
faluco@1735
   965
		}
skamonkey@3515
   966
#endif
dvander@1047
   967
	}
dvander@1047
   968
dvander@1047
   969
	return 1;
dvander@1047
   970
}
dvander@1047
   971
dvander@1047
   972
static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
dvander@1047
   973
{
dvander@1047
   974
	cell_t *addr;
ds@2112
   975
	CellRecipientFilter crf;
ds@2112
   976
	unsigned int numClients;
ds@2112
   977
	int client;
ds@2112
   978
	IGamePlayer *pPlayer = NULL;
dvander@1047
   979
dvander@1047
   980
	pContext->LocalToPhysAddr(params[1], &addr);
ds@2112
   981
	numClients = params[2];
ds@2112
   982
ds@2112
   983
	/* Client validation */
ds@2112
   984
	for (unsigned int i = 0; i < numClients; i++)
ds@2112
   985
	{
ds@2112
   986
		client = addr[i];
ds@2112
   987
		pPlayer = playerhelpers->GetGamePlayer(client);
ds@2112
   988
ds@2112
   989
		if (!pPlayer)
ds@2112
   990
		{
ds@2112
   991
			return pContext->ThrowNativeError("Client index %d is invalid", client);
ds@2112
   992
		} else if (!pPlayer->IsInGame()) {
ds@2112
   993
			return pContext->ThrowNativeError("Client %d is not connected", client);
ds@2112
   994
		}
ds@2112
   995
	}
ds@2112
   996
ds@2112
   997
	crf.Initialize(addr, numClients);
dvander@1047
   998
dvander@1047
   999
	int sentence = params[3];
pred@2760
  1000
	int entity = SoundReferenceToIndex(params[4]);
dvander@1047
  1001
	int channel = params[5];
dvander@1047
  1002
	int level = params[6];
dvander@1047
  1003
	int flags = params[7];
dvander@1047
  1004
	float vol = sp_ctof(params[8]);
dvander@1047
  1005
	int pitch = params[9];
dvander@1047
  1006
	int speakerentity = params[10];
dvander@1047
  1007
dvander@1047
  1008
	Vector *pOrigin = NULL, origin;
dvander@1047
  1009
	Vector *pDir = NULL, dir;
dvander@1047
  1010
dvander@1047
  1011
	pContext->LocalToPhysAddr(params[11], &addr);
dvander@1047
  1012
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
  1013
	{
dvander@1047
  1014
		pOrigin = &origin;
dvander@1047
  1015
		origin.x = sp_ctof(addr[0]);
dvander@1047
  1016
		origin.y = sp_ctof(addr[1]);
dvander@1047
  1017
		origin.z = sp_ctof(addr[2]);
dvander@1047
  1018
	}
dvander@1047
  1019
dvander@1047
  1020
	pContext->LocalToPhysAddr(params[12], &addr);
dvander@1047
  1021
	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
dvander@1047
  1022
	{
dvander@1047
  1023
		pDir = &dir;
dvander@1047
  1024
		dir.x = sp_ctof(addr[0]);
dvander@1047
  1025
		dir.y = sp_ctof(addr[1]);
dvander@1047
  1026
		dir.z = sp_ctof(addr[2]);
dvander@1047
  1027
	}
dvander@1047
  1028
dvander@1047
  1029
	bool updatePos = params[13] ? true : false;
dvander@1047
  1030
	float soundtime = sp_ctof(params[14]);
dvander@1047
  1031
dvander@1047
  1032
	CUtlVector<Vector> *pOrigVec = NULL;
dvander@1047
  1033
	CUtlVector<Vector> origvec;
dvander@1047
  1034
	if (params[0] > 14)
dvander@1047
  1035
	{
dvander@1047
  1036
		pOrigVec = &origvec;
dvander@1047
  1037
		for (cell_t i = 15; i <= params[0]; i++)
dvander@1047
  1038
		{
dvander@1047
  1039
			Vector vec;
dvander@1047
  1040
			pContext->LocalToPhysAddr(params[i], &addr);
dvander@1047
  1041
			vec.x = sp_ctof(addr[0]);
dvander@1047
  1042
			vec.y = sp_ctof(addr[1]);
dvander@1047
  1043
			vec.z = sp_ctof(addr[2]);
dvander@1047
  1044
			origvec.AddToTail(vec);
dvander@1047
  1045
		}
dvander@1047
  1046
	}
dvander@1047
  1047
dvander@1047
  1048
	engsound->EmitSentenceByIndex(crf, 
dvander@1047
  1049
		entity, 
dvander@1047
  1050
		channel, 
dvander@1047
  1051
		sentence, 
dvander@1047
  1052
		vol, 
dvander@1047
  1053
		(soundlevel_t)level, 
skamonkey@3515
  1054
#if SOURCE_ENGINE >= SE_PORTAL2
skamonkey@3515
  1055
		0, 
skamonkey@3515
  1056
#endif
dvander@1047
  1057
		flags, 
dvander@1047
  1058
		pitch, 
skamonkey@4141
  1059
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
skamonkey@3566
  1060
		0, 
skamonkey@3566
  1061
#endif
dvander@1047
  1062
		pOrigin,
dvander@1047
  1063
		pDir,
dvander@1047
  1064
		pOrigVec,
dvander@1047
  1065
		updatePos,
dvander@1047
  1066
		soundtime,
dvander@1047
  1067
		speakerentity);
dvander@1047
  1068
dvander@1047
  1069
	return 1;
dvander@1047
  1070
}
dvander@1047
  1071
faluco@1735
  1072
static cell_t smn_AddAmbientSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1073
{
faluco@1735
  1074
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1075
	if (!pFunc)
faluco@1735
  1076
	{
faluco@1735
  1077
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1078
	}
faluco@1735
  1079
faluco@1735
  1080
	s_SoundHooks.AddHook(AMBIENT_SOUND_HOOK, pFunc);
faluco@1735
  1081
faluco@1735
  1082
	return 1;
faluco@1735
  1083
}
faluco@1735
  1084
faluco@1735
  1085
static cell_t smn_AddNormalSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1086
{
faluco@1735
  1087
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1088
	if (!pFunc)
faluco@1735
  1089
	{
faluco@1735
  1090
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1091
	}
faluco@1735
  1092
faluco@1735
  1093
	s_SoundHooks.AddHook(NORMAL_SOUND_HOOK, pFunc);
faluco@1735
  1094
faluco@1735
  1095
	return 1;
faluco@1735
  1096
}
faluco@1735
  1097
faluco@1735
  1098
static cell_t smn_RemoveAmbientSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1099
{
faluco@1735
  1100
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1101
	if (!pFunc)
faluco@1735
  1102
	{
faluco@1735
  1103
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1104
	}
faluco@1735
  1105
faluco@1735
  1106
	if (!s_SoundHooks.RemoveHook(AMBIENT_SOUND_HOOK, pFunc))
faluco@1735
  1107
	{
faluco@1735
  1108
		return pContext->ThrowNativeError("Invalid hooked function");
faluco@1735
  1109
	}
faluco@1735
  1110
faluco@1735
  1111
	return 1;
faluco@1735
  1112
}
faluco@1735
  1113
faluco@1735
  1114
static cell_t smn_RemoveNormalSoundHook(IPluginContext *pContext, const cell_t *params)
faluco@1735
  1115
{
faluco@1735
  1116
	IPluginFunction *pFunc = pContext->GetFunctionById(params[1]);
faluco@1735
  1117
	if (!pFunc)
faluco@1735
  1118
	{
faluco@1735
  1119
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
faluco@1735
  1120
	}
faluco@1735
  1121
faluco@1735
  1122
	if (!s_SoundHooks.RemoveHook(NORMAL_SOUND_HOOK, pFunc))
faluco@1735
  1123
	{
faluco@1735
  1124
		return pContext->ThrowNativeError("Invalid hooked function");
faluco@1735
  1125
	}
faluco@1735
  1126
faluco@1735
  1127
	return 1;
faluco@1735
  1128
}
faluco@1735
  1129
javalia@3384
  1130
static cell_t smn_GetDistGainFromSoundLevel(IPluginContext *pContext, const cell_t *params)
javalia@3384
  1131
{
javalia@3384
  1132
	int decibel = params[1];
javalia@3384
  1133
	float distance = sp_ctof(params[2]);
javalia@3384
  1134
skamonkey@3385
  1135
	return sp_ftoc(engsound->GetDistGainFromSoundLevel((soundlevel_t)decibel, distance));
javalia@3384
  1136
}
javalia@3384
  1137
dvander@1047
  1138
sp_nativeinfo_t g_SoundNatives[] = 
dvander@1047
  1139
{
faluco@1735
  1140
	{"EmitAmbientSound",		EmitAmbientSound},
faluco@1735
  1141
	{"EmitSentence",			EmitSentence},
faluco@1735
  1142
	{"EmitSound",				EmitSound},
faluco@1735
  1143
	{"FadeClientVolume",		FadeClientVolume},
faluco@1735
  1144
	{"GetSoundDuration",		GetSoundDuration},
faluco@1735
  1145
	{"PrefetchSound",			PrefetchSound},
faluco@1735
  1146
	{"StopSound",				StopSound},
faluco@1735
  1147
	{"AddAmbientSoundHook",		smn_AddAmbientSoundHook},
faluco@1735
  1148
	{"AddNormalSoundHook",		smn_AddNormalSoundHook},
faluco@1735
  1149
	{"RemoveAmbientSoundHook",	smn_RemoveAmbientSoundHook},
faluco@1735
  1150
	{"RemoveNormalSoundHook",	smn_RemoveNormalSoundHook},
javalia@3384
  1151
	{"GetDistGainFromSoundLevel", smn_GetDistGainFromSoundLevel},
faluco@1735
  1152
	{NULL,						NULL},
dvander@1047
  1153
};