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