dvander@1047: /** dvander@1047: * vim: set ts=4 : ds@1330: * ============================================================================= ds@1947: * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. ds@1330: * ============================================================================= ds@1330: * ds@1330: * This file is part of the SourceMod/SourcePawn SDK. dvander@1047: * ds@1330: * This program is free software; you can redistribute it and/or modify it under ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the ds@1330: * Free Software Foundation. ds@1330: * ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ds@1330: * details. ds@1330: * ds@1330: * You should have received a copy of the GNU General Public License along with ds@1330: * this program. If not, see . ds@1330: * ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants ds@1330: * this exception to all derivative works. AlliedModders LLC defines further ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), ds@1330: * or . dvander@1047: * dvander@1047: * Version: $Id$ dvander@1047: */ dvander@1047: dvander@1047: #if defined _sdktools_sound_included dvander@1047: #endinput dvander@1047: #endif dvander@1047: #define _sdktools_sound_included dvander@1047: dvander@1047: /** dvander@1048: * Sound should be from the target client. dvander@1047: */ dvander@1048: #define SOUND_FROM_PLAYER -2 dvander@1048: dvander@1048: /** dvander@1048: * Sound should be from the listen server player. dvander@1048: */ dvander@1048: #define SOUND_FROM_LOCAL_PLAYER -1 dvander@1047: dvander@1047: /** dvander@1047: * Sound is from the world. dvander@1047: */ dvander@1047: #define SOUND_FROM_WORLD 0 dvander@1047: dvander@1047: /** dvander@1047: * Sound channels. dvander@1047: */ dvander@1047: enum dvander@1047: { dvander@1047: SNDCHAN_REPLACE = -1, /**< Unknown */ dvander@1047: SNDCHAN_AUTO = 0, /**< Auto */ dvander@1047: SNDCHAN_WEAPON = 1, /**< Weapons */ dvander@1047: SNDCHAN_VOICE = 2, /**< Voices */ dvander@1047: SNDCHAN_ITEM = 3, /**< Items */ dvander@1047: SNDCHAN_BODY = 4, /**< Player? */ dvander@1047: SNDCHAN_STREAM = 5, /**< "Stream channel from the static or dynamic area" */ dvander@1047: SNDCHAN_STATIC = 6, /**< "Stream channel from the static area" */ dvander@1047: SNDCHAN_VOICE_BASE = 7, /**< "Channel for network voice data" */ dvander@1047: SNDCHAN_USER_BASE = 135 /**< Anything >= this is allocated to game code */ dvander@1047: }; dvander@1047: dvander@1047: /** dvander@1047: * Sound flags for the sound emitter system. dvander@1047: */ dvander@1047: enum dvander@1047: { dvander@1047: SND_NOFLAGS= 0, /**< Nothing */ dvander@1047: SND_CHANGEVOL = 1, /**< Change sound volume */ dvander@1047: SND_CHANGEPITCH = 2, /**< Change sound pitch */ dvander@1047: SND_STOP = 3, /**< Stop the sound */ dvander@1047: SND_SPAWNING = 4, /**< Used in some cases for ambients */ dvander@1047: SND_DELAY = 5, /**< Sound has an initial delay */ dvander@1047: SND_STOPLOOPING = 6, /**< Stop looping all sounds on the entity */ dvander@1047: SND_SPEAKER = 7, /**< Being played by a mic through a speaker */ dvander@1047: SND_SHOULDPAUSE = 8, /**< Pause if game is paused */ dvander@1047: }; dvander@1047: dvander@1047: /** dvander@1047: * Various predefined sound levels in dB. dvander@1047: */ dvander@1047: enum dvander@1047: { dvander@1047: SNDLEVEL_NONE = 0, /**< None */ dvander@1047: SNDLEVEL_RUSTLE = 20, /**< Rustling leaves */ dvander@1047: SNDLEVEL_WHISPER = 25, /**< Whispering */ dvander@1047: SNDLEVEL_LIBRARY = 30, /**< In a library */ dvander@1047: SNDLEVEL_FRIDGE = 45, /**< Refridgerator */ dvander@1047: SNDLEVEL_HOME = 50, /**< Average home (3.9 attn) */ dvander@1047: SNDLEVEL_CONVO = 60, /**< Normal conversation (2.0 attn) */ dvander@1047: SNDLEVEL_DRYER = 60, /**< Clothes dryer */ dvander@1047: SNDLEVEL_DISHWASHER = 65, /**< Dishwasher/washing machine (1.5 attn) */ dvander@1047: SNDLEVEL_CAR = 70, /**< Car or vacuum cleaner (1.0 attn) */ dvander@1047: SNDLEVEL_NORMAL = 75, /**< Normal sound level */ dvander@1047: SNDLEVEL_TRAFFIC = 75, /**< Busy traffic (0.8 attn) */ dvander@1047: SNDLEVEL_MINIBIKE = 80, /**< Mini-bike, alarm clock (0.7 attn) */ dvander@1047: SNDLEVEL_SCREAMING = 90, /**< Screaming child (0.5 attn) */ dvander@1047: SNDLEVEL_TRAIN = 100, /**< Subway train, pneumatic drill (0.4 attn) */ dvander@1047: SNDLEVEL_HELICOPTER = 105, /**< Helicopter */ dvander@1047: SNDLEVEL_SNOWMOBILE = 110, /**< Snow mobile */ dvander@1047: SNDLEVEL_AIRCRAFT = 120, /**< Auto horn, aircraft */ dvander@1047: SNDLEVEL_RAIDSIREN = 130, /**< Air raid siren */ dvander@1047: SNDLEVEL_GUNFIRE = 140, /**< Gunshot, jet engine (0.27 attn) */ dvander@1047: SNDLEVEL_ROCKET = 180, /**< Rocket launching (0.2 attn) */ dvander@1047: }; dvander@1047: dvander@1047: #define SNDVOL_NORMAL 1.0 /**< Normal volume */ dvander@1047: #define SNDPITCH_NORMAL 100 /**< Normal pitch */ dvander@1047: #define SNDPITCH_LOW 95 /**< A low pitch */ dvander@1047: #define SNDPITCH_HIGH 120 /**< A high pitch */ dvander@1047: #define SNDATTN_NONE 0.0 /**< No attenuation */ dvander@1047: #define SNDATTN_NORMAL 0.8 /**< Normal attenuation */ dvander@1047: #define SNDATTN_STATIC 1.25 /**< Static attenuation? */ dvander@1047: #define SNDATTN_RICOCHET 1.5 /**< Ricochet effect */ dvander@1047: #define SNDATTN_IDLE 2.0 /**< Idle attenuation? */ dvander@1047: dvander@1047: /** dvander@1047: * Prefetches a sound. dvander@1047: * dvander@1733: * @param name Sound file name relative to the "sounds" folder. dvander@1047: * @noreturn dvander@1047: */ dvander@1047: native PrefetchSound(const String:nane[]); dvander@1047: dvander@1047: /** dvander@1928: * This function is not known to work, and may crash. You should dvander@1928: * not use it. It is provided for backwards compatibility only. dvander@1047: * dvander@1733: * @param name Sound file name relative to the "sounds" folder. dvander@1047: * @return Duration in seconds. dvander@1047: */ dvander@1928: #pragma deprecated Does not work, may crash. dvander@1047: native Float:GetSoundDuration(const String:name[]); dvander@1047: dvander@1047: /** dvander@1047: * Emits an ambient sound. dvander@1047: * dvander@1733: * @param name Sound file name relative to the "sounds" folder. dvander@1047: * @param pos Origin of sound. dvander@1733: * @param entity Entity index to associate sound with. dvander@1047: * @param level Sound level (from 0 to 255). dvander@1047: * @param flags Sound flags. dvander@1047: * @param vol Volume (from 0.0 to 1.0). dvander@1047: * @param pitch Pitch (from 0 to 255). dvander@1047: * @param delay Play delay. dvander@1047: * @noreturn dvander@1047: */ dvander@1047: native EmitAmbientSound(const String:name[], dvander@1047: const Float:pos[3], dvander@1047: entity = SOUND_FROM_WORLD, dvander@1047: level = SNDLEVEL_NORMAL, dvander@1047: flags = SND_NOFLAGS, dvander@1047: Float:vol = SNDVOL_NORMAL, dvander@1047: pitch = SNDPITCH_NORMAL, dvander@1047: Float:delay = 0.0); dvander@1047: dvander@1047: /** dvander@1047: * Fades a client's volume level toward silence or a given percentage. dvander@1047: * dvander@1047: * @param client Client index. dvander@1047: * @param percent Fade percentage. dvander@1047: * @param outtime Fade out time, in seconds. dvander@1047: * @param holdtime Hold time, in seconds. dvander@1047: * @param intime Fade in time, in seconds. dvander@1047: * @noreturn dvander@1047: * @error Invalid client index or client not in game. dvander@1047: */ dvander@1047: native FadeClientVolume(client, Float:percent, Float:outtime, Float:holdtime, Float:intime); dvander@1047: dvander@1047: /** dvander@1047: * Stops a sound. dvander@1047: * dvander@1047: * @param entity Entity index. dvander@1047: * @param channel Channel number. dvander@1733: * @param name Sound file name relative to the "sounds" folder. dvander@1047: * @noreturn dvander@1047: */ dvander@1047: native StopSound(entity, channel, const String:name[]); dvander@1047: dvander@1047: /** dvander@1047: * Emits a sound to a list of clients. dvander@1047: * dvander@1047: * @param clients Array of client indexes. dvander@1047: * @param numClients Number of clients in the array. dvander@1733: * @param sample Sound file name relative to the "sounds" folder. dvander@1047: * @param entity Entity to emit from. dvander@1047: * @param channel Channel to emit with. dvander@1047: * @param level Sound level. dvander@1047: * @param flags Sound flags. dvander@1047: * @param volume Sound volume. dvander@1047: * @param pitch Sound pitch. dvander@1047: * @param speakerentity Unknown. dvander@1047: * @param origin Sound origin. dvander@1047: * @param dir Sound direction. dvander@1047: * @param updatePos Unknown (updates positions?) dvander@1047: * @param soundtime Alternate time to play sound for. dvander@1047: * @param ... Optional list of Float[3] arrays to specify additional origins. dvander@1047: * @noreturn dvander@1047: * @error Invalid client index. dvander@1047: */ dvander@1047: native EmitSound(const clients[], dvander@1047: numClients, dvander@1047: const String:sample[], dvander@1048: entity = SOUND_FROM_PLAYER, dvander@1047: channel = SNDCHAN_AUTO, dvander@1047: level = SNDLEVEL_NORMAL, dvander@1047: flags = SND_NOFLAGS, dvander@1047: Float:volume = SNDVOL_NORMAL, dvander@1047: pitch = SNDPITCH_NORMAL, dvander@1047: speakerentity = -1, dvander@1047: const Float:origin[3] = NULL_VECTOR, dvander@1047: const Float:dir[3] = NULL_VECTOR, dvander@1047: bool:updatePos = true, dvander@1047: Float:soundtime = 0.0, dvander@1047: any:...); dvander@1047: dvander@1047: /** dvander@1047: * Emits a sentence to a list of clients. dvander@1047: * dvander@1047: * @param clients Array of client indexes. dvander@1047: * @param numClients Number of clients in the array. dvander@1733: * @param sentence Sentence index (from PrecacheSenteFile). dvander@1047: * @param entity Entity to emit from. dvander@1047: * @param channel Channel to emit with. dvander@1047: * @param level Sound level. dvander@1047: * @param flags Sound flags. dvander@1047: * @param volume Sound volume. dvander@1047: * @param pitch Sound pitch. dvander@1047: * @param speakerentity Unknown. dvander@1047: * @param origin Sound origin. dvander@1047: * @param dir Sound direction. dvander@1047: * @param updatePos Unknown (updates positions?) dvander@1047: * @param soundtime Alternate time to play sound for. dvander@1047: * @param ... Optional list of Float[3] arrays to specify additional origins. dvander@1047: * @noreturn dvander@1047: * @error Invalid client index. dvander@1047: */ dvander@1047: native EmitSentence(const clients[], dvander@1047: numClients, dvander@1047: sentence, dvander@1048: entity, dvander@1047: channel = SNDCHAN_AUTO, dvander@1047: level = SNDLEVEL_NORMAL, dvander@1047: flags = SND_NOFLAGS, dvander@1047: Float:volume = SNDVOL_NORMAL, dvander@1047: pitch = SNDPITCH_NORMAL, dvander@1047: speakerentity = -1, dvander@1047: const Float:origin[3] = NULL_VECTOR, dvander@1047: const Float:dir[3] = NULL_VECTOR, dvander@1047: bool:updatePos = true, dvander@1047: Float:soundtime = 0.0, dvander@1047: any:...); dvander@1047: faluco@1735: /** faluco@1735: * Called when an ambient sound is about to be emitted to one or more clients. faluco@1735: * faluco@1735: * NOTICE: all parameters can be overwritten to modify the default behavior. faluco@1735: * faluco@1735: * @param sample Sound file name relative to the "sounds" folder. faluco@1735: * @param entity Entity index associated to the sound. faluco@1735: * @param volume Volume (from 0.0 to 1.0). faluco@1735: * @param level Sound level (from 0 to 255). faluco@1735: * @param pitch Pitch (from 0 to 255). faluco@1735: * @param pos Origin of sound. faluco@1735: * @param flags Sound flags. faluco@1735: * @param delay Play delay. faluco@1735: * @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it, faluco@1735: * Plugin_Changed when any parameter has been modified. faluco@1735: */ dvander@2317: functag public Action:AmbientSHook(String:sample[PLATFORM_MAX_PATH], &entity, &Float:volume, &level, &pitch, Float:pos[3], &flags, &Float:delay); faluco@1735: faluco@1735: /** faluco@1735: * Called when a sound is going to be emitted to one or more clients. faluco@1735: * NOTICE: all params can be overwritten to modify the default behaviour. faluco@1735: * faluco@1735: * @param clients Array of client indexes. faluco@1735: * @param numClients Number of clients in the array (modify this value if you add/remove elements from the client array). faluco@1735: * @param sample Sound file name relative to the "sounds" folder. faluco@1735: * @param entity Entity emitting the sound. faluco@1735: * @param channel Channel emitting the sound. faluco@1735: * @param volume Sound volume. faluco@1735: * @param level Sound level. faluco@1735: * @param pitch Sound pitch. faluco@1735: * @param flags Sound flags. faluco@1735: * @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it, faluco@1735: * Plugin_Changed when any parameter has been modified. faluco@1735: */ dvander@2317: functag public Action:NormalSHook(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags); faluco@1735: faluco@1735: /** faluco@1735: * Hooks all played ambient sounds. faluco@1735: * faluco@1735: * @param hook Function to use as a hook. faluco@1735: * @noreturn faluco@1735: * @error Invalid function hook. faluco@1735: */ faluco@1735: native AddAmbientSoundHook(AmbientSHook:hook); faluco@1735: faluco@1735: /** faluco@1735: * Hooks all played normal sounds. faluco@1735: * faluco@1735: * @param hook Function to use as a hook. faluco@1735: * @noreturn faluco@1735: * @error Invalid function hook. faluco@1735: */ faluco@1735: native AddNormalSoundHook(NormalSHook:hook); faluco@1735: faluco@1735: /** faluco@1735: * Unhooks all played ambient sounds. faluco@1735: * faluco@1735: * @param hook Function used for the hook. faluco@1735: * @noreturn faluco@1735: * @error Invalid function hook. faluco@1735: */ faluco@1735: native RemoveAmbientSoundHook(AmbientSHook:hook); faluco@1735: faluco@1735: /** faluco@1735: * Unhooks all played normal sounds. faluco@1735: * faluco@1735: * @param hook Function used for the hook. faluco@1735: * @noreturn faluco@1735: * @error Invalid function hook. faluco@1735: */ faluco@1735: native RemoveNormalSoundHook(NormalSHook:hook); dvander@1047: dvander@1047: /** dvander@1047: * Wrapper to emit sound to one client. dvander@1047: * dvander@1047: * @param client Client index. dvander@1733: * @param sample Sound file name relative to the "sounds" folder. dvander@1047: * @param entity Entity to emit from. dvander@1047: * @param channel Channel to emit with. dvander@1047: * @param level Sound level. dvander@1047: * @param flags Sound flags. dvander@1047: * @param volume Sound volume. dvander@1047: * @param pitch Sound pitch. dvander@1047: * @param speakerentity Unknown. dvander@1047: * @param origin Sound origin. dvander@1047: * @param dir Sound direction. dvander@1047: * @param updatePos Unknown (updates positions?) dvander@1047: * @param soundtime Alternate time to play sound for. dvander@1047: * @noreturn dvander@1047: * @error Invalid client index. dvander@1047: */ dvander@1047: stock EmitSoundToClient(client, dvander@1047: const String:sample[], dvander@1047: entity = SOUND_FROM_PLAYER, dvander@1047: channel = SNDCHAN_AUTO, dvander@1047: level = SNDLEVEL_NORMAL, dvander@1047: flags = SND_NOFLAGS, dvander@1047: Float:volume = SNDVOL_NORMAL, dvander@1047: pitch = SNDPITCH_NORMAL, dvander@1047: speakerentity = -1, dvander@1047: const Float:origin[3] = NULL_VECTOR, dvander@1047: const Float:dir[3] = NULL_VECTOR, dvander@1047: bool:updatePos = true, dvander@1047: Float:soundtime = 0.0) dvander@1047: { dvander@1047: new clients[1]; dvander@1047: clients[0] = client; dvander@1047: /* Save some work for SDKTools and remove SOUND_FROM_PLAYER references */ dvander@1047: entity = (entity == SOUND_FROM_PLAYER) ? client : entity; dvander@1047: EmitSound(clients, 1, sample, entity, channel, dvander@1047: level, flags, volume, pitch, speakerentity, dvander@1047: origin, dir, updatePos, soundtime); dvander@1047: } dvander@1047: dvander@1047: /** dvander@1047: * Wrapper to emit sound to all clients. dvander@1047: * dvander@1733: * @param sample Sound file name relative to the "sounds" folder. dvander@1047: * @param entity Entity to emit from. dvander@1047: * @param channel Channel to emit with. dvander@1047: * @param level Sound level. dvander@1047: * @param flags Sound flags. dvander@1047: * @param volume Sound volume. dvander@1047: * @param pitch Sound pitch. dvander@1047: * @param speakerentity Unknown. dvander@1047: * @param origin Sound origin. dvander@1047: * @param dir Sound direction. dvander@1047: * @param updatePos Unknown (updates positions?) dvander@1047: * @param soundtime Alternate time to play sound for. dvander@1047: * @noreturn dvander@1047: * @error Invalid client index. dvander@1047: */ dvander@1047: stock EmitSoundToAll(const String:sample[], dvander@1047: entity = SOUND_FROM_PLAYER, dvander@1047: channel = SNDCHAN_AUTO, dvander@1047: level = SNDLEVEL_NORMAL, dvander@1047: flags = SND_NOFLAGS, dvander@1047: Float:volume = SNDVOL_NORMAL, dvander@1047: pitch = SNDPITCH_NORMAL, dvander@1047: speakerentity = -1, dvander@1047: const Float:origin[3] = NULL_VECTOR, dvander@1047: const Float:dir[3] = NULL_VECTOR, dvander@1047: bool:updatePos = true, dvander@1047: Float:soundtime = 0.0) dvander@1047: { dvander@1047: new maxClients = GetMaxClients(); dvander@1047: new clients[maxClients]; dvander@1047: new total = 0; dvander@1047: dvander@1047: for (new i=1; i<=maxClients; i++) dvander@1047: { dvander@1047: if (IsClientInGame(i)) dvander@1047: { dvander@1047: clients[total++] = i; dvander@1047: } dvander@1047: } dvander@1047: dvander@1047: if (!total) dvander@1047: { dvander@1047: return; dvander@1047: } dvander@1047: dvander@1047: EmitSound(clients, total, sample, entity, channel, dvander@1047: level, flags, volume, pitch, speakerentity, dvander@1047: origin, dir, updatePos, soundtime); dvander@1047: } dvander@1047: dvander@1047: /** dvander@1047: * Converts an attenuation value to a sound level. dvander@1047: * This function is from the HL2SDK. dvander@1047: * dvander@1047: * @param attn Attenuation value. dvander@1047: * @return Integer sound level. dvander@1047: */ dvander@1047: stock ATTN_TO_SNDLEVEL(Float:attn) dvander@1047: { dvander@1047: if (attn > 0.0) dvander@1047: { dvander@1047: return RoundFloat(50.0 + (20.0 / attn)); dvander@1047: } dvander@1047: return 0; dvander@1047: }