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