added enginesound support
authorDavid Anderson <dvander@alliedmods.net>
Sat Jul 07 17:46:17 2007 +0000 (2007-07-07)
changeset 104746da3a82493b
parent 1046 1072caab8a65
child 1048 9f5605daf52d
added enginesound support
extensions/sdktools/extension.cpp
extensions/sdktools/extension.h
extensions/sdktools/msvc8/sdktools.vcproj
extensions/sdktools/vnatives.h
extensions/sdktools/vsound.cpp
plugins/include/sdktools.inc
plugins/include/sdktools_sound.inc
     1.1 --- a/extensions/sdktools/extension.cpp	Sat Jul 07 16:31:57 2007 +0000
     1.2 +++ b/extensions/sdktools/extension.cpp	Sat Jul 07 17:46:17 2007 +0000
     1.3 @@ -36,6 +36,7 @@
     1.4  IBinTools *g_pBinTools = NULL;
     1.5  IGameConfig *g_pGameConf = NULL;
     1.6  IGameHelpers *g_pGameHelpers = NULL;
     1.7 +IEngineSound *engsound = NULL;
     1.8  HandleType_t g_CallHandle = 0;
     1.9  
    1.10  SMEXT_LINK(&g_SdkTools);
    1.11 @@ -49,6 +50,7 @@
    1.12  	sharesys->AddNatives(myself, g_CallNatives);
    1.13  	sharesys->AddNatives(myself, g_Natives);
    1.14  	sharesys->AddNatives(myself, g_TENatives);
    1.15 +	sharesys->AddNatives(myself, g_SoundNatives);
    1.16  
    1.17  	SM_GET_IFACE(GAMEHELPERS, g_pGameHelpers);
    1.18  
    1.19 @@ -89,7 +91,8 @@
    1.20  
    1.21  bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
    1.22  {
    1.23 -	GET_V_IFACE_CURRENT(serverFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS);
    1.24 +	GET_V_IFACE_ANY(serverFactory, gameents, IServerGameEnts, INTERFACEVERSION_SERVERGAMEENTS);
    1.25 +	GET_V_IFACE_ANY(engineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
    1.26  
    1.27  	return true;
    1.28  }
     2.1 --- a/extensions/sdktools/extension.h	Sat Jul 07 16:31:57 2007 +0000
     2.2 +++ b/extensions/sdktools/extension.h	Sat Jul 07 17:46:17 2007 +0000
     2.3 @@ -33,6 +33,7 @@
     2.4  #include <IBinTools.h>
     2.5  #include <IPlayerHelpers.h>
     2.6  #include <IGameHelpers.h>
     2.7 +#include <IEngineSound.h>
     2.8  
     2.9  /**
    2.10   * @brief Implementation of the SDK Tools extension.
    2.11 @@ -63,5 +64,6 @@
    2.12  extern IGameConfig *g_pGameConf;
    2.13  extern IGameHelpers *g_pGameHelpers;
    2.14  extern HandleType_t g_CallHandle;
    2.15 +extern IEngineSound *engsound;
    2.16  
    2.17  #endif //_INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
     3.1 --- a/extensions/sdktools/msvc8/sdktools.vcproj	Sat Jul 07 16:31:57 2007 +0000
     3.2 +++ b/extensions/sdktools/msvc8/sdktools.vcproj	Sat Jul 07 17:46:17 2007 +0000
     3.3 @@ -1,7 +1,7 @@
     3.4  <?xml version="1.0" encoding="Windows-1252"?>
     3.5  <VisualStudioProject
     3.6  	ProjectType="Visual C++"
     3.7 -	Version="8,00"
     3.8 +	Version="8.00"
     3.9  	Name="sdktools"
    3.10  	ProjectGUID="{7A740927-C751-4312-BF9D-6367F8C508F8}"
    3.11  	RootNamespace="sdk"
    3.12 @@ -65,6 +65,7 @@
    3.13  				AdditionalDependencies="vstdlib.lib tier0.lib tier1.lib"
    3.14  				OutputFile="$(OutDir)\sdktools.ext.dll"
    3.15  				LinkIncremental="2"
    3.16 +				IgnoreDefaultLibraryNames="LIBCMT"
    3.17  				GenerateDebugInformation="true"
    3.18  				SubSystem="2"
    3.19  				TargetMachine="1"
    3.20 @@ -139,6 +140,7 @@
    3.21  			/>
    3.22  			<Tool
    3.23  				Name="VCLinkerTool"
    3.24 +				AdditionalDependencies="vstdlib.lib tier0.lib tier1.lib"
    3.25  				OutputFile="$(OutDir)\sdktools.ext.dll"
    3.26  				LinkIncremental="1"
    3.27  				GenerateDebugInformation="true"
    3.28 @@ -209,6 +211,10 @@
    3.29  				RelativePath="..\vnatives.cpp"
    3.30  				>
    3.31  			</File>
    3.32 +			<File
    3.33 +				RelativePath="..\vsound.cpp"
    3.34 +				>
    3.35 +			</File>
    3.36  		</Filter>
    3.37  		<Filter
    3.38  			Name="Header Files"
     4.1 --- a/extensions/sdktools/vnatives.h	Sat Jul 07 16:31:57 2007 +0000
     4.2 +++ b/extensions/sdktools/vnatives.h	Sat Jul 07 17:46:17 2007 +0000
     4.3 @@ -28,5 +28,6 @@
     4.4  
     4.5  extern List<ValveCall *> g_RegCalls;
     4.6  extern sp_nativeinfo_t g_Natives[];
     4.7 +extern sp_nativeinfo_t g_SoundNatives[];
     4.8  
     4.9  #endif //_INCLUDE_SDKTOOLS_VNATIVES_H_
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/extensions/sdktools/vsound.cpp	Sat Jul 07 17:46:17 2007 +0000
     5.3 @@ -0,0 +1,278 @@
     5.4 +#include "extension.h"
     5.5 +#include "CellRecipientFilter.h"
     5.6 +
     5.7 +static cell_t PrefetchSound(IPluginContext *pContext, const cell_t *params)
     5.8 +{
     5.9 +	char *name;
    5.10 +	pContext->LocalToString(params[1], &name);
    5.11 +
    5.12 +	engsound->PrefetchSound(name);
    5.13 +
    5.14 +	return 1;
    5.15 +}
    5.16 +
    5.17 +static cell_t GetSoundDuration(IPluginContext *pContext, const cell_t *params)
    5.18 +{
    5.19 +	char *name;
    5.20 +	pContext->LocalToString(params[1], &name);
    5.21 +
    5.22 +	return sp_ftoc(engsound->GetSoundDuration(name));
    5.23 +}
    5.24 +
    5.25 +static cell_t EmitAmbientSound(IPluginContext *pContext, const cell_t *params)
    5.26 +{
    5.27 +	cell_t entity;
    5.28 +	Vector pos;
    5.29 +	char *name;
    5.30 +	float vol, delay;
    5.31 +	int pitch, flags, level;
    5.32 +
    5.33 +	entity = params[3];
    5.34 +
    5.35 +	cell_t *addr;
    5.36 +	pContext->LocalToPhysAddr(params[2], &addr);
    5.37 +	pos.x = sp_ctof(addr[0]);
    5.38 +	pos.y = sp_ctof(addr[1]);
    5.39 +	pos.z = sp_ctof(addr[2]);
    5.40 +
    5.41 +	pContext->LocalToString(params[1], &name);
    5.42 +
    5.43 +	vol = sp_ctof(params[6]);
    5.44 +	level = params[4];
    5.45 +	flags = params[5];
    5.46 +	pitch = params[7];
    5.47 +	delay = sp_ctof(params[8]);
    5.48 +
    5.49 +	engine->EmitAmbientSound(entity, pos, name, vol, (soundlevel_t)level, flags, pitch, delay);
    5.50 +
    5.51 +	return 1;
    5.52 +}
    5.53 +
    5.54 +static cell_t FadeClientVolume(IPluginContext *pContext, const cell_t *params)
    5.55 +{
    5.56 +	int client = params[1];
    5.57 +	if (client < 1 || client > playerhelpers->GetMaxClients())
    5.58 +	{
    5.59 +		return pContext->ThrowNativeError("Client index %d is not valid", client);
    5.60 +	}
    5.61 +
    5.62 +	IGamePlayer *player = playerhelpers->GetGamePlayer(client);
    5.63 +	if (!player->IsInGame())
    5.64 +	{
    5.65 +		return pContext->ThrowNativeError("Client index %d is not in game", client);
    5.66 +	}
    5.67 +
    5.68 +	engine->FadeClientVolume(player->GetEdict(),
    5.69 +		sp_ctof(params[2]),
    5.70 +		sp_ctof(params[3]),
    5.71 +		sp_ctof(params[4]),
    5.72 +		sp_ctof(params[5]));
    5.73 +
    5.74 +	return 1;
    5.75 +}
    5.76 +
    5.77 +static cell_t StopSound(IPluginContext *pContext, const cell_t *params)
    5.78 +{
    5.79 +	int entity = params[1];
    5.80 +	int channel = params[2];
    5.81 +
    5.82 +	char *name;
    5.83 +	pContext->LocalToString(params[3], &name);
    5.84 +
    5.85 +	engsound->StopSound(entity, channel, name);
    5.86 +
    5.87 +	return 1;
    5.88 +}
    5.89 +
    5.90 +static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
    5.91 +{
    5.92 +	cell_t *addr, *pl_addr;
    5.93 +
    5.94 +	CellRecipientFilter crf;
    5.95 +	pContext->LocalToPhysAddr(params[1], &pl_addr);
    5.96 +	crf.Initialize(pl_addr, params[2]);
    5.97 +
    5.98 +	char *sample;
    5.99 +	pContext->LocalToString(params[3], &sample);
   5.100 +	
   5.101 +	int entity = params[4];
   5.102 +	int channel = params[5];
   5.103 +	int level = params[6];
   5.104 +	int flags = params[7];
   5.105 +	float vol = sp_ctof(params[8]);
   5.106 +	int pitch = params[9];
   5.107 +	int speakerentity = params[10];
   5.108 +
   5.109 +	Vector *pOrigin = NULL, origin;
   5.110 +	Vector *pDir = NULL, dir;
   5.111 +
   5.112 +	pContext->LocalToPhysAddr(params[11], &addr);
   5.113 +	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
   5.114 +	{
   5.115 +		pOrigin = &origin;
   5.116 +		origin.x = sp_ctof(addr[0]);
   5.117 +		origin.y = sp_ctof(addr[1]);
   5.118 +		origin.z = sp_ctof(addr[2]);
   5.119 +	}
   5.120 +
   5.121 +	pContext->LocalToPhysAddr(params[12], &addr);
   5.122 +	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
   5.123 +	{
   5.124 +		pDir = &dir;
   5.125 +		dir.x = sp_ctof(addr[0]);
   5.126 +		dir.y = sp_ctof(addr[1]);
   5.127 +		dir.z = sp_ctof(addr[2]);
   5.128 +	}
   5.129 +
   5.130 +	bool updatePos = params[13] ? true : false;
   5.131 +	float soundtime = sp_ctof(params[14]);
   5.132 +
   5.133 +	CUtlVector<Vector> *pOrigVec = NULL;
   5.134 +	CUtlVector<Vector> origvec;
   5.135 +	if (params[0] > 14)
   5.136 +	{
   5.137 +		pOrigVec = &origvec;
   5.138 +		for (cell_t i = 15; i <= params[0]; i++)
   5.139 +		{
   5.140 +			Vector vec;
   5.141 +			pContext->LocalToPhysAddr(params[i], &addr);
   5.142 +			vec.x = sp_ctof(addr[0]);
   5.143 +			vec.y = sp_ctof(addr[1]);
   5.144 +			vec.z = sp_ctof(addr[2]);
   5.145 +			origvec.AddToTail(vec);
   5.146 +		}
   5.147 +	}
   5.148 +
   5.149 +	/* If we're going to a "local player" and this is a dedicated server,
   5.150 +	 * intelligently redirect each sound.
   5.151 +	 */
   5.152 +
   5.153 +	if (entity == SOUND_FROM_LOCAL_PLAYER && engine->IsDedicatedServer())
   5.154 +	{
   5.155 +		for (cell_t i=0; i<params[2]; i++)
   5.156 +		{
   5.157 +			cell_t player[1];
   5.158 +			player[0] = pl_addr[i];
   5.159 +			crf.Reset();
   5.160 +			crf.Initialize(player, 1);
   5.161 +			engsound->EmitSound(crf, 
   5.162 +				player[0], 
   5.163 +				channel, 
   5.164 +				sample, 
   5.165 +				vol, 
   5.166 +				(soundlevel_t)level, 
   5.167 +				flags, 
   5.168 +				pitch, 
   5.169 +				pOrigin,
   5.170 +				pDir,
   5.171 +				pOrigVec,
   5.172 +				updatePos,
   5.173 +				soundtime,
   5.174 +				speakerentity);
   5.175 +		}
   5.176 +	} else {
   5.177 +		engsound->EmitSound(crf, 
   5.178 +			entity, 
   5.179 +			channel, 
   5.180 +			sample, 
   5.181 +			vol, 
   5.182 +			(soundlevel_t)level, 
   5.183 +			flags, 
   5.184 +			pitch, 
   5.185 +			pOrigin,
   5.186 +			pDir,
   5.187 +			pOrigVec,
   5.188 +			updatePos,
   5.189 +			soundtime,
   5.190 +			speakerentity);
   5.191 +	}
   5.192 +
   5.193 +	return 1;
   5.194 +}
   5.195 +
   5.196 +static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
   5.197 +{
   5.198 +	cell_t *addr;
   5.199 +
   5.200 +	CellRecipientFilter crf;
   5.201 +	pContext->LocalToPhysAddr(params[1], &addr);
   5.202 +	crf.Initialize(addr, params[2]);
   5.203 +
   5.204 +	int sentence = params[3];
   5.205 +	int entity = params[4];
   5.206 +	int channel = params[5];
   5.207 +	int level = params[6];
   5.208 +	int flags = params[7];
   5.209 +	float vol = sp_ctof(params[8]);
   5.210 +	int pitch = params[9];
   5.211 +	int speakerentity = params[10];
   5.212 +
   5.213 +	Vector *pOrigin = NULL, origin;
   5.214 +	Vector *pDir = NULL, dir;
   5.215 +
   5.216 +	pContext->LocalToPhysAddr(params[11], &addr);
   5.217 +	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
   5.218 +	{
   5.219 +		pOrigin = &origin;
   5.220 +		origin.x = sp_ctof(addr[0]);
   5.221 +		origin.y = sp_ctof(addr[1]);
   5.222 +		origin.z = sp_ctof(addr[2]);
   5.223 +	}
   5.224 +
   5.225 +	pContext->LocalToPhysAddr(params[12], &addr);
   5.226 +	if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
   5.227 +	{
   5.228 +		pDir = &dir;
   5.229 +		dir.x = sp_ctof(addr[0]);
   5.230 +		dir.y = sp_ctof(addr[1]);
   5.231 +		dir.z = sp_ctof(addr[2]);
   5.232 +	}
   5.233 +
   5.234 +	bool updatePos = params[13] ? true : false;
   5.235 +	float soundtime = sp_ctof(params[14]);
   5.236 +
   5.237 +	CUtlVector<Vector> *pOrigVec = NULL;
   5.238 +	CUtlVector<Vector> origvec;
   5.239 +	if (params[0] > 14)
   5.240 +	{
   5.241 +		pOrigVec = &origvec;
   5.242 +		for (cell_t i = 15; i <= params[0]; i++)
   5.243 +		{
   5.244 +			Vector vec;
   5.245 +			pContext->LocalToPhysAddr(params[i], &addr);
   5.246 +			vec.x = sp_ctof(addr[0]);
   5.247 +			vec.y = sp_ctof(addr[1]);
   5.248 +			vec.z = sp_ctof(addr[2]);
   5.249 +			origvec.AddToTail(vec);
   5.250 +		}
   5.251 +	}
   5.252 +
   5.253 +	engsound->EmitSentenceByIndex(crf, 
   5.254 +		entity, 
   5.255 +		channel, 
   5.256 +		sentence, 
   5.257 +		vol, 
   5.258 +		(soundlevel_t)level, 
   5.259 +		flags, 
   5.260 +		pitch, 
   5.261 +		pOrigin,
   5.262 +		pDir,
   5.263 +		pOrigVec,
   5.264 +		updatePos,
   5.265 +		soundtime,
   5.266 +		speakerentity);
   5.267 +
   5.268 +	return 1;
   5.269 +}
   5.270 +
   5.271 +sp_nativeinfo_t g_SoundNatives[] = 
   5.272 +{
   5.273 +	{"EmitAmbientSound",	EmitAmbientSound},
   5.274 +	{"EmitSentence",		EmitSentence},
   5.275 +	{"EmitSound",			EmitSound},
   5.276 +	{"FadeClientVolume",	FadeClientVolume},
   5.277 +	{"GetSoundDuration",	GetSoundDuration},
   5.278 +	{"PrefetchSound",		PrefetchSound},
   5.279 +	{"StopSound",			StopSound},
   5.280 +	{NULL,					NULL},
   5.281 +};
     6.1 --- a/plugins/include/sdktools.inc	Sat Jul 07 16:31:57 2007 +0000
     6.2 +++ b/plugins/include/sdktools.inc	Sat Jul 07 17:46:17 2007 +0000
     6.3 @@ -22,6 +22,7 @@
     6.4  #include <sdktools_functions>
     6.5  #include <sdktools_tempents>
     6.6  #include <sdktools_tempents_stocks>
     6.7 +#include <sdktools_sound>
     6.8  
     6.9  enum SDKCallType
    6.10  {
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/plugins/include/sdktools_sound.inc	Sat Jul 07 17:46:17 2007 +0000
     7.3 @@ -0,0 +1,347 @@
     7.4 +/**
     7.5 + * vim: set ts=4 :
     7.6 + * ===============================================================
     7.7 + * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     7.8 + * ===============================================================
     7.9 + *
    7.10 + *  This file is part of the SourceMod/SourcePawn SDK.  This file may only be used 
    7.11 + * or modified under the Terms and Conditions of its License Agreement, which is found 
    7.12 + * in LICENSE.txt.  The Terms and Conditions for making SourceMod extensions/plugins 
    7.13 + * may change at any time.  To view the latest information, see:
    7.14 + *   http://www.sourcemod.net/license.php
    7.15 + *
    7.16 + * Version: $Id$
    7.17 + */
    7.18 +
    7.19 +#if defined _sdktools_sound_included
    7.20 +  #endinput
    7.21 +#endif
    7.22 +#define _sdktools_sound_included
    7.23 +
    7.24 +/**
    7.25 + * Sound is from the client.
    7.26 + */
    7.27 +#define SOUND_FROM_PLAYER		-1
    7.28 +
    7.29 +/**
    7.30 + * Sound is from the world.
    7.31 + */
    7.32 +#define SOUND_FROM_WORLD		0
    7.33 +
    7.34 +/**
    7.35 + * Sound channels.
    7.36 + */
    7.37 +enum
    7.38 +{
    7.39 +	SNDCHAN_REPLACE = -1,		/**< Unknown */
    7.40 +	SNDCHAN_AUTO = 0,			/**< Auto */
    7.41 +	SNDCHAN_WEAPON = 1,			/**< Weapons */
    7.42 +	SNDCHAN_VOICE = 2,			/**< Voices */
    7.43 +	SNDCHAN_ITEM = 3,			/**< Items */
    7.44 +	SNDCHAN_BODY = 4,			/**< Player? */
    7.45 +	SNDCHAN_STREAM = 5,			/**< "Stream channel from the static or dynamic area" */
    7.46 +	SNDCHAN_STATIC = 6,			/**< "Stream channel from the static area" */
    7.47 +	SNDCHAN_VOICE_BASE = 7,		/**< "Channel for network voice data" */
    7.48 +	SNDCHAN_USER_BASE = 135		/**< Anything >= this is allocated to game code */
    7.49 +};
    7.50 +
    7.51 +/**
    7.52 + * Sound flags for the sound emitter system.
    7.53 + */
    7.54 +enum
    7.55 +{
    7.56 +	SND_NOFLAGS= 0,			/**< Nothing */
    7.57 +	SND_CHANGEVOL = 1,		/**< Change sound volume */
    7.58 +	SND_CHANGEPITCH = 2,	/**< Change sound pitch */
    7.59 +	SND_STOP = 3,			/**< Stop the sound */
    7.60 +	SND_SPAWNING = 4,		/**< Used in some cases for ambients */
    7.61 +	SND_DELAY = 5,			/**< Sound has an initial delay */
    7.62 +	SND_STOPLOOPING = 6,	/**< Stop looping all sounds on the entity */
    7.63 +	SND_SPEAKER = 7,		/**< Being played by a mic through a speaker */
    7.64 +	SND_SHOULDPAUSE = 8,	/**< Pause if game is paused */
    7.65 +};
    7.66 +
    7.67 +/**
    7.68 + * Various predefined sound levels in dB.
    7.69 + */
    7.70 +enum
    7.71 +{
    7.72 +	SNDLEVEL_NONE = 0,			/**< None */
    7.73 +	SNDLEVEL_RUSTLE = 20,		/**< Rustling leaves */
    7.74 +	SNDLEVEL_WHISPER = 25,		/**< Whispering */
    7.75 +	SNDLEVEL_LIBRARY = 30,		/**< In a library */
    7.76 +	SNDLEVEL_FRIDGE = 45,		/**< Refridgerator */
    7.77 +	SNDLEVEL_HOME = 50,			/**< Average home (3.9 attn) */
    7.78 +	SNDLEVEL_CONVO = 60,		/**< Normal conversation (2.0 attn) */
    7.79 +	SNDLEVEL_DRYER = 60,		/**< Clothes dryer */
    7.80 +	SNDLEVEL_DISHWASHER = 65,	/**< Dishwasher/washing machine (1.5 attn) */
    7.81 +	SNDLEVEL_CAR = 70,			/**< Car or vacuum cleaner (1.0 attn) */
    7.82 +	SNDLEVEL_NORMAL = 75,		/**< Normal sound level */
    7.83 +	SNDLEVEL_TRAFFIC = 75,		/**< Busy traffic (0.8 attn) */
    7.84 +	SNDLEVEL_MINIBIKE = 80,		/**< Mini-bike, alarm clock (0.7 attn) */
    7.85 +	SNDLEVEL_SCREAMING = 90,	/**< Screaming child (0.5 attn) */
    7.86 +	SNDLEVEL_TRAIN = 100,		/**< Subway train, pneumatic drill (0.4 attn) */
    7.87 +	SNDLEVEL_HELICOPTER = 105,	/**< Helicopter */
    7.88 +	SNDLEVEL_SNOWMOBILE = 110,	/**< Snow mobile */
    7.89 +	SNDLEVEL_AIRCRAFT = 120,	/**< Auto horn, aircraft */
    7.90 +	SNDLEVEL_RAIDSIREN = 130,	/**< Air raid siren */
    7.91 +	SNDLEVEL_GUNFIRE = 140,		/**< Gunshot, jet engine (0.27 attn) */
    7.92 +	SNDLEVEL_ROCKET = 180,		/**< Rocket launching (0.2 attn) */
    7.93 +};
    7.94 +
    7.95 +#define SNDVOL_NORMAL		1.0		/**< Normal volume */
    7.96 +#define SNDPITCH_NORMAL		100		/**< Normal pitch */
    7.97 +#define SNDPITCH_LOW		95		/**< A low pitch */
    7.98 +#define SNDPITCH_HIGH		120		/**< A high pitch */
    7.99 +#define SNDATTN_NONE		0.0		/**< No attenuation */
   7.100 +#define SNDATTN_NORMAL		0.8		/**< Normal attenuation */
   7.101 +#define SNDATTN_STATIC		1.25	/**< Static attenuation? */
   7.102 +#define SNDATTN_RICOCHET	1.5		/**< Ricochet effect */
   7.103 +#define SNDATTN_IDLE		2.0		/**< Idle attenuation? */
   7.104 + 
   7.105 +/**
   7.106 + * Prefetches a sound.
   7.107 + *
   7.108 + * @param name		Sound file name.
   7.109 + * @noreturn
   7.110 + */
   7.111 +native PrefetchSound(const String:nane[]);
   7.112 +
   7.113 +/**
   7.114 + * Gets a sound's duration (does not work for mp3s).
   7.115 + *
   7.116 + * @param name		Sound file name.
   7.117 + * @return			Duration in seconds.
   7.118 + */
   7.119 +native Float:GetSoundDuration(const String:name[]);
   7.120 +
   7.121 +/**
   7.122 + * Emits an ambient sound.
   7.123 + *
   7.124 + * @param entity	Entity index to associate sound with.
   7.125 + * @param pos		Origin of sound.
   7.126 + * @param name		Sound file name.
   7.127 + * @param level		Sound level (from 0 to 255).
   7.128 + * @param flags		Sound flags.
   7.129 + * @param vol		Volume (from 0.0 to 1.0).
   7.130 + * @param pitch		Pitch (from 0 to 255).
   7.131 + * @param delay		Play delay.
   7.132 + * @noreturn
   7.133 + */
   7.134 +native EmitAmbientSound(const String:name[],
   7.135 +						const Float:pos[3],
   7.136 +						entity = SOUND_FROM_WORLD,
   7.137 +						level = SNDLEVEL_NORMAL,
   7.138 +						flags = SND_NOFLAGS,
   7.139 +						Float:vol = SNDVOL_NORMAL,
   7.140 +						pitch = SNDPITCH_NORMAL,
   7.141 +						Float:delay = 0.0);
   7.142 +
   7.143 +/**
   7.144 + * Fades a client's volume level toward silence or a given percentage.
   7.145 + *
   7.146 + * @param client	Client index.
   7.147 + * @param percent	Fade percentage.
   7.148 + * @param outtime	Fade out time, in seconds.
   7.149 + * @param holdtime	Hold time, in seconds.
   7.150 + * @param intime	Fade in time, in seconds.
   7.151 + * @noreturn
   7.152 + * @error			Invalid client index or client not in game.
   7.153 + */
   7.154 +native FadeClientVolume(client, Float:percent, Float:outtime, Float:holdtime, Float:intime);
   7.155 +
   7.156 +/**
   7.157 + * Stops a sound.
   7.158 + *
   7.159 + * @param entity	Entity index.
   7.160 + * @param channel	Channel number.
   7.161 + * @param name		Sound name.
   7.162 + * @noreturn
   7.163 + */
   7.164 +native StopSound(entity, channel, const String:name[]);
   7.165 +
   7.166 +/**
   7.167 + * Emits a sound to a list of clients.
   7.168 + *
   7.169 + * @param clients		Array of client indexes.
   7.170 + * @param numClients	Number of clients in the array.
   7.171 + * @param entity		Entity to emit from.
   7.172 + * @param channel		Channel to emit with.
   7.173 + * @param sample		Sound name.
   7.174 + * @param level			Sound level.
   7.175 + * @param flags			Sound flags.
   7.176 + * @param volume		Sound volume.
   7.177 + * @param pitch			Sound pitch.
   7.178 + * @param speakerentity	Unknown.
   7.179 + * @param origin		Sound origin.
   7.180 + * @param dir			Sound direction.
   7.181 + * @param updatePos		Unknown (updates positions?)
   7.182 + * @param soundtime		Alternate time to play sound for.
   7.183 + * @param ...			Optional list of Float[3] arrays to specify additional origins.
   7.184 + * @noreturn
   7.185 + * @error				Invalid client index.
   7.186 + */
   7.187 +native EmitSound(const clients[],
   7.188 +				 numClients,
   7.189 +				 const String:sample[],
   7.190 +				 entity = SOUND_FROM_WORLD,
   7.191 +				 channel = SNDCHAN_AUTO,
   7.192 +				 level = SNDLEVEL_NORMAL,
   7.193 +				 flags = SND_NOFLAGS,
   7.194 +				 Float:volume = SNDVOL_NORMAL,
   7.195 +				 pitch = SNDPITCH_NORMAL,
   7.196 +				 speakerentity = -1,
   7.197 +				 const Float:origin[3] = NULL_VECTOR,
   7.198 +				 const Float:dir[3] = NULL_VECTOR,
   7.199 +				 bool:updatePos = true,
   7.200 +				 Float:soundtime = 0.0,
   7.201 +				 any:...);
   7.202 +
   7.203 +/**
   7.204 + * Emits a sentence to a list of clients.
   7.205 + *
   7.206 + * @param clients		Array of client indexes.
   7.207 + * @param numClients	Number of clients in the array.
   7.208 + * @param entity		Entity to emit from.
   7.209 + * @param channel		Channel to emit with.
   7.210 + * @param sentence		Sentence index (from PrecacheSenteFile).
   7.211 + * @param level			Sound level.
   7.212 + * @param flags			Sound flags.
   7.213 + * @param volume		Sound volume.
   7.214 + * @param pitch			Sound pitch.
   7.215 + * @param speakerentity	Unknown.
   7.216 + * @param origin		Sound origin.
   7.217 + * @param dir			Sound direction.
   7.218 + * @param updatePos		Unknown (updates positions?)
   7.219 + * @param soundtime		Alternate time to play sound for.
   7.220 + * @param ...			Optional list of Float[3] arrays to specify additional origins.
   7.221 + * @noreturn
   7.222 + * @error				Invalid client index.
   7.223 + */
   7.224 +native EmitSentence(const clients[],
   7.225 +				 numClients,
   7.226 +				 sentence,
   7.227 +				 entity = SOUND_FROM_WORLD,
   7.228 +				 channel = SNDCHAN_AUTO,
   7.229 +				 level = SNDLEVEL_NORMAL,
   7.230 +				 flags = SND_NOFLAGS,
   7.231 +				 Float:volume = SNDVOL_NORMAL,
   7.232 +				 pitch = SNDPITCH_NORMAL,
   7.233 +				 speakerentity = -1,
   7.234 +				 const Float:origin[3] = NULL_VECTOR,
   7.235 +				 const Float:dir[3] = NULL_VECTOR,
   7.236 +				 bool:updatePos = true,
   7.237 +				 Float:soundtime = 0.0,
   7.238 +				 any:...);
   7.239 +
   7.240 +				 
   7.241 +/**
   7.242 + * Wrapper to emit sound to one client.
   7.243 + *
   7.244 + * @param client		Client index.
   7.245 + * @param entity		Entity to emit from.
   7.246 + * @param channel		Channel to emit with.
   7.247 + * @param sample		Sound name.
   7.248 + * @param level			Sound level.
   7.249 + * @param flags			Sound flags.
   7.250 + * @param volume		Sound volume.
   7.251 + * @param pitch			Sound pitch.
   7.252 + * @param speakerentity	Unknown.
   7.253 + * @param origin		Sound origin.
   7.254 + * @param dir			Sound direction.
   7.255 + * @param updatePos		Unknown (updates positions?)
   7.256 + * @param soundtime		Alternate time to play sound for.
   7.257 + * @noreturn
   7.258 + * @error				Invalid client index.
   7.259 + */
   7.260 +stock EmitSoundToClient(client,
   7.261 +				 const String:sample[],
   7.262 +				 entity = SOUND_FROM_PLAYER,
   7.263 +				 channel = SNDCHAN_AUTO,
   7.264 +				 level = SNDLEVEL_NORMAL,
   7.265 +				 flags = SND_NOFLAGS,
   7.266 +				 Float:volume = SNDVOL_NORMAL,
   7.267 +				 pitch = SNDPITCH_NORMAL,
   7.268 +				 speakerentity = -1,
   7.269 +				 const Float:origin[3] = NULL_VECTOR,
   7.270 +				 const Float:dir[3] = NULL_VECTOR,
   7.271 +				 bool:updatePos = true,
   7.272 +				 Float:soundtime = 0.0)
   7.273 +{
   7.274 +	new clients[1];
   7.275 +	clients[0] = client;
   7.276 +	/* Save some work for SDKTools and remove SOUND_FROM_PLAYER references */
   7.277 +	entity = (entity == SOUND_FROM_PLAYER) ? client : entity;
   7.278 +	EmitSound(clients, 1, sample, entity, channel, 
   7.279 +		level, flags, volume, pitch, speakerentity,
   7.280 +		origin, dir, updatePos, soundtime);
   7.281 +}
   7.282 +
   7.283 +/**
   7.284 + * Wrapper to emit sound to all clients.
   7.285 + *
   7.286 + * @param entity		Entity to emit from.
   7.287 + * @param channel		Channel to emit with.
   7.288 + * @param sample		Sound name.
   7.289 + * @param level			Sound level.
   7.290 + * @param flags			Sound flags.
   7.291 + * @param volume		Sound volume.
   7.292 + * @param pitch			Sound pitch.
   7.293 + * @param speakerentity	Unknown.
   7.294 + * @param origin		Sound origin.
   7.295 + * @param dir			Sound direction.
   7.296 + * @param updatePos		Unknown (updates positions?)
   7.297 + * @param soundtime		Alternate time to play sound for.
   7.298 + * @noreturn
   7.299 + * @error				Invalid client index.
   7.300 + */
   7.301 +stock EmitSoundToAll(const String:sample[],
   7.302 +				 entity = SOUND_FROM_PLAYER,
   7.303 +				 channel = SNDCHAN_AUTO,
   7.304 +				 level = SNDLEVEL_NORMAL,
   7.305 +				 flags = SND_NOFLAGS,
   7.306 +				 Float:volume = SNDVOL_NORMAL,
   7.307 +				 pitch = SNDPITCH_NORMAL,
   7.308 +				 speakerentity = -1,
   7.309 +				 const Float:origin[3] = NULL_VECTOR,
   7.310 +				 const Float:dir[3] = NULL_VECTOR,
   7.311 +				 bool:updatePos = true,
   7.312 +				 Float:soundtime = 0.0)
   7.313 +{
   7.314 +	new maxClients = GetMaxClients();
   7.315 +	new clients[maxClients];
   7.316 +	new total = 0;
   7.317 +	
   7.318 +	for (new i=1; i<=maxClients; i++)
   7.319 +	{
   7.320 +		if (IsClientInGame(i))
   7.321 +		{
   7.322 +			clients[total++] = i;
   7.323 +		}
   7.324 +	}
   7.325 +	
   7.326 +	if (!total)
   7.327 +	{
   7.328 +		return;
   7.329 +	}
   7.330 +	
   7.331 +	EmitSound(clients, total, sample, entity, channel, 
   7.332 +		level, flags, volume, pitch, speakerentity,
   7.333 +		origin, dir, updatePos, soundtime);
   7.334 +}
   7.335 +
   7.336 +/**
   7.337 + * Converts an attenuation value to a sound level.  
   7.338 + * This function is from the HL2SDK.
   7.339 + *
   7.340 + * @param attn		Attenuation value.
   7.341 + * @return			Integer sound level.
   7.342 + */
   7.343 +stock ATTN_TO_SNDLEVEL(Float:attn)
   7.344 +{
   7.345 +	if (attn > 0.0)
   7.346 +	{
   7.347 +		return RoundFloat(50.0 + (20.0 / attn));
   7.348 +	}
   7.349 +	return 0;
   7.350 +}