diff --git a/Makefile b/Makefile index 84b92b5..95f5cee 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ SOURCEDIR=src SMINCLUDES=env/include BUILDDIR=build -SPCOMP=env/linux/bin/spcomp +SPCOMP=env/linux/bin/spcomp-1.3.4 VERSIONDUMP=./updateversion.sh vpath %.sp $(SOURCEDIR) diff --git a/compile.bat b/compile.bat index be8a5e8..38e5e5b 100644 --- a/compile.bat +++ b/compile.bat @@ -3,7 +3,7 @@ set SOURCEDIR=src set SMINCLUDES=env\include set BUILDDIR=build -set SPCOMP=env\win32\bin\spcomp.exe +set SPCOMP=env\win32\bin\spcomp-1.3.4.exe set VERSIONDUMP=updateversion.bat :: Dump version and revision information first. diff --git a/env/include/admin.inc b/env/include/admin.inc index b367eb5..0278156 100644 --- a/env/include/admin.inc +++ b/env/include/admin.inc @@ -516,6 +516,15 @@ native bool:FindFlagByName(const String:name[], &AdminFlag:flag); */ native bool:FindFlagByChar(c, &AdminFlag:flag); +/** + * Finds a flag char by a gived admin flag. + * + * @param flag Flag to look up. + * @param c Variable to store flag char. + * @return True on success, false if not found. + */ +native bool:FindFlagChar(AdminFlag:flag, &c); + /** * Converts a string of flag characters to a bit string. * diff --git a/env/include/adminmenu.inc b/env/include/adminmenu.inc index c417b4c..f96eb2a 100644 --- a/env/include/adminmenu.inc +++ b/env/include/adminmenu.inc @@ -38,8 +38,9 @@ /* Decide whether topmenus should be required */ #if !defined REQUIRE_PLUGIN #if defined REQUIRE_EXTENSIONS - #define TEMP_REQUIRE_EXTENSIONS - #undef REQUIRE_EXTENSIONS + #define TEMP_REQUIRE_EXTENSIONS + #undef REQUIRE_EXTENSIONS + #endif #endif #include diff --git a/env/include/adt_array.inc b/env/include/adt_array.inc index b76991c..038ca29 100644 --- a/env/include/adt_array.inc +++ b/env/include/adt_array.inc @@ -199,7 +199,7 @@ native GetArrayArray(Handle:array, index, any:buffer[], size=-1); * @noreturn * @error Invalid Handle, invalid index, or invalid block. */ -native any:SetArrayCell(Handle:array, index, any:value, block=0, bool:asChar=false); +native SetArrayCell(Handle:array, index, any:value, block=0, bool:asChar=false); /** * Sets a string value in an array. diff --git a/env/include/clientprefs.inc b/env/include/clientprefs.inc index 723bb93..5466399 100644 --- a/env/include/clientprefs.inc +++ b/env/include/clientprefs.inc @@ -85,10 +85,14 @@ enum CookieMenuAction /** * Creates a new Client preference cookie. * + * Handles returned by RegClientCookie can be closed via CloseHandle() when + * no longer needed. + * * @param name Name of the new preference cookie. * @param description Optional description of the preference cookie. * @param access What CookieAccess level to assign to this cookie. - * @return A handle to the newly created cookie. If the cookie already exists, a handle to it will still be returned. + * @return A handle to the newly created cookie. If the cookie already + * exists, a handle to it will still be returned. * @error Cookie name is blank. */ native Handle:RegClientCookie(const String:name[], const String:description[], CookieAccess:access); @@ -96,6 +100,9 @@ native Handle:RegClientCookie(const String:name[], const String:description[], C /** * Searches for a Client preference cookie. * + * Handles returned by FindClientCookie can be closed via CloseHandle() when + * no longer needed. + * * @param name Name of cookie to find. * @return A handle to the cookie if it is found. INVALID_HANDLE otherwise. */ @@ -222,6 +229,15 @@ native bool:ReadCookieIterator(Handle:iter, */ native CookieAccess:GetCookieAccess(Handle:cookie); +/** + * Returns the last updated timestamp for a client cookie + * + * @param client Client index. + * @param cookie Cookie handle. + * @return Last updated timestamp. + */ +native GetClientCookieTime(client, Handle:cookie); + /** * Do not edit below this line! */ diff --git a/env/include/clients.inc b/env/include/clients.inc index 2065b74..4facbc1 100644 --- a/env/include/clients.inc +++ b/env/include/clients.inc @@ -117,6 +117,9 @@ forward OnClientDisconnect_Post(client); /** * Called when a client is sending a command. * + * As of SourceMod 1.3, the client is guaranteed to be in-game. + * Use command listeners (console.inc) for more advanced hooks. + * * @param client Client index. * @param args Number of arguments. * @noreturn @@ -133,9 +136,8 @@ forward OnClientSettingsChanged(client); /** * Called when a client receives a Steam ID. The state of a client's - * authorization via Steam or as an admin is not guaranteed here. - * Use OnClientAuthorized() or OnClientPostAdminCheck() for those, - * respectively. + * authorization as an admin is not guaranteed here. Use + * OnClientPostAdminCheck() if you need a client's admin status. * * This is called by bots, but the ID will be "BOT". * @@ -599,7 +601,7 @@ native Float:GetClientTime(client); * * @param client Player's index. * @param flow Traffic flowing direction. - * @return Latency. + * @return Latency, or -1 if network info is not available. * @error Invalid client index, client not in game, or fake client. */ native Float:GetClientLatency(client, NetFlow:flow); @@ -609,7 +611,7 @@ native Float:GetClientLatency(client, NetFlow:flow); * * @param client Player's index. * @param flow Traffic flowing direction. - * @return Average latency. + * @return Latency, or -1 if network info is not available. * @error Invalid client index, client not in game, or fake client. */ native Float:GetClientAvgLatency(client, NetFlow:flow); @@ -619,7 +621,7 @@ native Float:GetClientAvgLatency(client, NetFlow:flow); * * @param client Player's index. * @param flow Traffic flowing direction. - * @return Average packet loss. + * @return Average packet loss, or -1 if network info is not available. * @error Invalid client index, client not in game, or fake client. */ native Float:GetClientAvgLoss(client, NetFlow:flow); @@ -629,7 +631,7 @@ native Float:GetClientAvgLoss(client, NetFlow:flow); * * @param client Player's index. * @param flow Traffic flowing direction. - * @return Average packet choke. + * @return Average packet loss, or -1 if network info is not available. * @error Invalid client index, client not in game, or fake client. */ native Float:GetClientAvgChoke(client, NetFlow:flow); diff --git a/env/include/console.inc b/env/include/console.inc index 019e664..177d23b 100644 --- a/env/include/console.inc +++ b/env/include/console.inc @@ -473,9 +473,8 @@ native bool:GetConVarBool(Handle:convar); /** * Sets the boolean value of a console variable. * - * Note: The replicate and notify params are ignored on the engines for Episode 2/Orange Box - * and Left 4 Dead. These engines automatically replicates and notifies as soon as the convar - * is changed. + * Note: The replicate and notify params are only relevant for the original, Dark Messiah, and + * Episode 1 engines. Newer engines automatically do these things when the convar value is changed. * * @param convar Handle to the convar. * @param value New boolean value. @@ -501,9 +500,8 @@ native GetConVarInt(Handle:convar); /** * Sets the integer value of a console variable. * - * Note: The replicate and notify params are ignored on the engines for Episode 2/Orange Box - * and Left 4 Dead. These engines automatically replicates and notifies as soon as the convar - * is changed. + * Note: The replicate and notify params are only relevant for the original, Dark Messiah, and + * Episode 1 engines. Newer engines automatically do these things when the convar value is changed. * * @param convar Handle to the convar. * @param value New integer value. @@ -529,9 +527,8 @@ native Float:GetConVarFloat(Handle:convar); /** * Sets the floating point value of a console variable. * - * Note: The replicate and notify params are ignored on the engines for Episode 2/Orange Box - * and Left 4 Dead. These engines automatically replicates and notifies as soon as the convar - * is changed. + * Note: The replicate and notify params are only relevant for the original, Dark Messiah, and + * Episode 1 engines. Newer engines automatically do these things when the convar value is changed. * * @param convar Handle to the convar. * @param value New floating point value. @@ -559,9 +556,8 @@ native GetConVarString(Handle:convar, String:value[], maxlength); /** * Sets the string value of a console variable. * - * Note: The replicate and notify params are ignored on the engines for Episode 2/Orange Box - * and Left 4 Dead. These engines automatically replicates and notifies as soon as the convar - * is changed. + * Note: The replicate and notify params are only relevant for the original, Dark Messiah, and + * Episode 1 engines. Newer engines automatically do these things when the convar value is changed. * * @param convar Handle to the convar. * @param value New string value. @@ -578,9 +574,8 @@ native SetConVarString(Handle:convar, const String:value[], bool:replicate=false /** * Resets the console variable to its default value. * - * Note: The replicate and notify params are ignored on the engines for Episode 2/Orange Box - * and Left 4 Dead. These engines automatically replicates and notifies as soon as the convar - * is changed. + * Note: The replicate and notify params are only relevant for the original, Dark Messiah, and + * Episode 1 engines. Newer engines automatically do these things when the convar value is changed. * * @param convar Handle to the convar. * @param replicate If set to true, the new convar value will be set on all clients. @@ -593,6 +588,17 @@ native SetConVarString(Handle:convar, const String:value[], bool:replicate=false */ native ResetConVar(Handle:convar, bool:replicate=false, bool:notify=false); +/** + * Retrieves the default string value of a console variable. + * + * @param convar Handle to the convar. + * @param value Buffer to store the default value of the convar. + * @param maxlength Maximum length of string buffer. + * @return Number of bytes written to the buffer (UTF-8 safe). + * @error Invalid or corrupt Handle. + */ +native GetConVarDefault(Handle:convar, String:value[], maxlength); + /** * Returns the bitstring of flags on a console variable. * @@ -639,12 +645,12 @@ native SetConVarBounds(Handle:convar, ConVarBounds:type, bool:set, Float:value=0 * Retrieves the name of a console variable. * * @param convar Handle to the convar. - * @param value Buffer to store the name of the convar. + * @param name Buffer to store the name of the convar. * @param maxlength Maximum length of string buffer. * @noreturn * @error Invalid or corrupt Handle. */ -native GetConVarName(Handle:convar, const String:name[], maxlength); +native GetConVarName(Handle:convar, String:name[], maxlength); funcenum ConVarQueryFinished { @@ -835,3 +841,61 @@ native AddServerTag(const String:tag[]); * @noreturn */ native RemoveServerTag(const String:tag[]); + +/** + * Callback for command listeners. This is invoked whenever any command + * reaches the server, from the server console itself or a player. + * + * Clients may be in the process of connecting when they are executing commands + * IsClientConnected(client) is not guaranteed to return true. Other functions + * such as GetClientIP() may not work at this point either. + * + * Returning Plugin_Handled or Plugin_Stop will prevent the original, + * baseline code from running. + * + * -- TEXT BELOW IS IMPLEMENTATION, AND NOT GUARANTEED -- + * Even if returning Plugin_Handled or Plugin_Stop, some callbacks will still + * trigger. These are: + * * C++ command dispatch hooks from Metamod:Source plugins + * * Reg*Cmd() hooks that did not create new commands. + * + * @param client Client, or 0 for server. + * Client may not be connected or in game. + * @param command Command name, lower case. To get name as typed, use + * GetCmdArg() and specify argument 0. + * @param argc Argument count. + * @return Action to take (see extended notes above). + */ +functag public Action:CommandListener(client, const String:command[], argc); + +#define FEATURECAP_COMMANDLISTENER "command listener" + +/** + * Adds a callback that will fire when a command is sent to the server. + * + * Registering commands is designed to create a new command as part of the UI, + * whereas this is a lightweight hook on a command string, existing or not. + * Using Reg*Cmd to intercept is in poor practice, as it physically creates a + * new command and can slow down dispatch in general. + * + * To see if this feature is available, use FeatureType_Capability and + * FEATURECAP_COMMANDLISTENER. + * + * @param callback Callback. + * @param command Command, or if not specified, a global listener. + * The command is case insensitive. + * @return True if this feature is available on the current game, + * false otherwise. + */ +native bool:AddCommandListener(CommandListener:callback, const String:command[]=""); + +/** + * Removes a previously added command listener, in reverse order of being added. + * + * @param callback Callback. + * @param command Command, or if not specified, a global listener. + * The command is case insensitive. + * @error Callback has no active listeners. + */ +native RemoveCommandListener(CommandListener:callback, const String:command[]=""); + diff --git a/env/include/core.inc b/env/include/core.inc index 751a849..13ae42a 100644 --- a/env/include/core.inc +++ b/env/include/core.inc @@ -151,8 +151,22 @@ public Extension:__ext_core = native VerifyCoreVersion(); +/** + * Sets a native as optional, such that if it is unloaded, removed, + * or otherwise non-existent, the plugin will still work. Calling + * removed natives results in a run-time error. + * + * @param name Native name. + * @noreturn + */ +native MarkNativeAsOptional(const String:name[]); + public __ext_core_SetNTVOptional() { + MarkNativeAsOptional("GetFeatureStatus"); + MarkNativeAsOptional("RequireFeature"); + MarkNativeAsOptional("AddCommandListener"); + MarkNativeAsOptional("RemoveCommandListener"); VerifyCoreVersion(); } diff --git a/env/include/dbi.inc b/env/include/dbi.inc index ed82476..5fb9ba8 100644 --- a/env/include/dbi.inc +++ b/env/include/dbi.inc @@ -288,6 +288,10 @@ native bool:SQL_GetError(Handle:hndl, String:error[], maxlength); * characters are safely escaped according to the database engine and * the database's character set. * + * NOTE: SourceMod only guarantees properly escaped strings when the query + * encloses the string in ''. While drivers tend to allow " instead, the string + * may be not be escaped (for example, on SQLite)! + * * @param hndl A database Handle. * @param string String to quote. * @param buffer Buffer to store quoted string in. diff --git a/env/include/events.inc b/env/include/events.inc index aa28408..3308fe7 100644 --- a/env/include/events.inc +++ b/env/include/events.inc @@ -241,3 +241,17 @@ native SetEventString(Handle:event, const String:key[], const String:value[]); * @error Invalid or corrupt Handle. */ native GetEventName(Handle:event, String:name[], maxlength); + +/** + * Sets whether an event's broadcasting will be disabled or not. + * + * This has no effect on events Handles that are not from HookEvent + * or HookEventEx callbacks. + * + * @param event Handle to an event from an event hook. + * @param dontBroadcast True to disable broadcasting, false otherwise. + * @noreturn + * @error Invalid Handle. + */ +native SetEventBroadcast(Handle:event, bool:dontBroadcast); + diff --git a/env/include/float.inc b/env/include/float.inc index 13ad7f6..73a5c3e 100644 --- a/env/include/float.inc +++ b/env/include/float.inc @@ -413,3 +413,46 @@ stock Float:RadToDeg(Float:angle) { return (angle*180)/FLOAT_PI; } + +/** + * Returns a random integer in the range [0, 2^31-1]. + * + * Note: Uniform random number streams are seeded automatically per-plugin. + * + * @return Random integer. + */ +native GetURandomInt(); + +/** + * Returns a uniform random float in the range [0, 1). + * + * Note: Uniform random number streams are seeded automatically per-plugin. + * + * @return Uniform random floating-point number. + */ +native Float:GetURandomFloat(); + +/** + * Seeds a plugin's uniform random number stream. This is done automatically, + * so normally it is totally unnecessary to call this. + * + * @param seeds Array of numbers to use as seeding data. + * @param numSeeds Number of seeds in the seeds array. + * @noreturn + */ +native SetURandomSeed(const seeds[], numSeeds); + +/** + * Seeds a plugin's uniform random number stream. This is done automatically, + * so normally it is totally unnecessary to call this. + * + * @param seed Single seed value. + * @noreturn + */ +stock SetURandomSeedSimple(seed) +{ + new seeds[1]; + seeds[0] = seed; + SetURandomSeed(seeds, 1); +} + diff --git a/env/include/functions.inc b/env/include/functions.inc index 1ad804f..1a6ddcb 100644 --- a/env/include/functions.inc +++ b/env/include/functions.inc @@ -30,6 +30,11 @@ * Version: $Id$ */ +#if defined _functions_included + #endinput +#endif +#define _functions_included + #define SP_PARAMFLAG_BYREF (1<<0) /**< Internal use only. */ /** diff --git a/env/include/halflife.inc b/env/include/halflife.inc index 2b9811e..c02cc55 100644 --- a/env/include/halflife.inc +++ b/env/include/halflife.inc @@ -40,7 +40,9 @@ #define SOURCE_SDK_DARKMESSIAH 15 /**< Modified version of original engine used by Dark Messiah (no SDK) */ #define SOURCE_SDK_EPISODE1 20 /**< SDK+Engine released after Episode 1 */ #define SOURCE_SDK_EPISODE2 30 /**< SDK+Engine released after Episode 2/Orange Box */ +#define SOURCE_SDK_EPISODE2VALVE 35 /**< SDK+Engine released after Episode 2/Orange Box */ #define SOURCE_SDK_LEFT4DEAD 40 /**< Engine released after Left 4 Dead (no SDK yet) */ +#define SOURCE_SDK_LEFT4DEAD2 50 /**< Engine released after Left 4 Dead 2 (no SDK yet) */ #define MOTDPANEL_TYPE_TEXT 0 /**< Treat msg as plain text */ #define MOTDPANEL_TYPE_INDEX 1 /**< Msg is auto determined by the engine */ @@ -56,6 +58,8 @@ enum DialogType DialogType_AskConnect /**< ask the client to connect to a specified IP */ }; +#define INVALID_ENT_REFERENCE 0xFFFFFFFF + /** * Logs a generic message to the HL2 logs. * @@ -269,10 +273,9 @@ native PrintToChat(client, const String:format[], any:...); */ stock PrintToChatAll(const String:format[], any:...) { - new maxClients = GetMaxClients(); decl String:buffer[192]; - for (new i = 1; i <= maxClients; i++) + for (new i = 1; i <= MaxClients; i++) { if (IsClientInGame(i)) { @@ -303,10 +306,9 @@ native PrintCenterText(client, const String:format[], any:...); */ stock PrintCenterTextAll(const String:format[], any:...) { - new maxClients = GetMaxClients(); decl String:buffer[192]; - for (new i = 1; i <= maxClients; i++) + for (new i = 1; i <= MaxClients; i++) { if (IsClientInGame(i)) { @@ -337,10 +339,9 @@ native PrintHintText(client, const String:format[], any:...); */ stock PrintHintTextToAll(const String:format[], any:...) { - new maxClients = GetMaxClients(); decl String:buffer[192]; - for (new i = 1; i <= maxClients; i++) + for (new i = 1; i <= MaxClients; i++) { if (IsClientInGame(i)) { @@ -544,3 +545,28 @@ stock DisplayAskConnectBox(client, Float:time, const String:ip[]) CreateDialog(client, Kv, DialogType_AskConnect); CloseHandle(Kv); } + +/** + * Converts an entity index into a serial encoded entity reference. + * + * @param entity Entity index. + * @return Entity reference. + */ +native EntIndexToEntRef(entity); + +/** + * Retrieves the entity index from a reference. + * + * @param ref Entity reference. + * @return Entity index. + */ +native EntRefToEntIndex(ref); + +/** + * Converts a reference into a backwards compatible version. + * + * @param ref Entity reference. + * @return Bcompat reference. + */ +native MakeCompatEntRef(ref); + diff --git a/env/include/helpers.inc b/env/include/helpers.inc index 31c4c3b..3b70165 100644 --- a/env/include/helpers.inc +++ b/env/include/helpers.inc @@ -99,7 +99,6 @@ stock Handle:FindPluginByFile(const String:filename[]) #pragma deprecated Use FindTarget() or ProcessTargetString() stock SearchForClients(const String:pattern[], clients[], maxClients) { - new maxclients = GetMaxClients(); new total = 0; if (maxClients == 0) @@ -113,7 +112,7 @@ stock SearchForClients(const String:pattern[], clients[], maxClients) if (!input) { decl String:name[65] - for (new i=1; i<=maxclients; i++) + for (new i=1; i<=MaxClients; i++) { if (!IsClientInGame(i)) { @@ -137,7 +136,7 @@ stock SearchForClients(const String:pattern[], clients[], maxClients) } decl String:name[65] - for (new i=1; i<=maxclients; i++) + for (new i=1; i<=MaxClients; i++) { if (!IsClientInGame(i)) { diff --git a/env/include/menus.inc b/env/include/menus.inc index 3ed4e9f..8ff1d69 100644 --- a/env/include/menus.inc +++ b/env/include/menus.inc @@ -490,11 +490,10 @@ native bool:VoteMenu(Handle:menu, clients[], numClients, time, flags=0); */ stock VoteMenuToAll(Handle:menu, time, flags=0) { - new num = GetMaxClients(); new total; - decl players[num]; + decl players[MaxClients]; - for (new i=1; i<=num; i++) + for (new i=1; i<=MaxClients; i++) { if (!IsClientInGame(i)) { diff --git a/env/include/sdktools.inc b/env/include/sdktools.inc index 9963539..573a9d0 100644 --- a/env/include/sdktools.inc +++ b/env/include/sdktools.inc @@ -48,6 +48,7 @@ #include #include #include +#include enum SDKCallType { diff --git a/env/include/sdktools_hooks.inc b/env/include/sdktools_hooks.inc new file mode 100644 index 0000000..0f8d20e --- /dev/null +++ b/env/include/sdktools_hooks.inc @@ -0,0 +1,49 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod (C)2004-2009 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This file is part of the SourceMod/SourcePawn SDK. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#if defined _sdktools_hooks_included + #endinput +#endif +#define _sdktools_hooks_included + +/** + * @brief Called when a clients movement buttons are being processed + * + * @param client Index of the client. + * @param buttons Copyback buffer containing the current commands (as bitflags - see entity_prop_stocks.inc). + * @param impulse Copyback buffer containing the current impulse command. + * @param vel Players desired velocity. + * @param angles Players desired view angles. + * @param weapon Entity index of the new weapon if player switches weapon, 0 otherwise. + * @return Plugin_Handled to block the commands from being processed, Plugin_Continue otherwise. + */ +forward Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon); \ No newline at end of file diff --git a/env/include/sdktools_sound.inc b/env/include/sdktools_sound.inc index a8a9f99..dc9e099 100644 --- a/env/include/sdktools_sound.inc +++ b/env/include/sdktools_sound.inc @@ -403,11 +403,10 @@ stock EmitSoundToAll(const String:sample[], bool:updatePos = true, Float:soundtime = 0.0) { - new maxClients = GetMaxClients(); - new clients[maxClients]; + new clients[MaxClients]; new total = 0; - for (new i=1; i<=maxClients; i++) + for (new i=1; i<=MaxClients; i++) { if (IsClientInGame(i)) { diff --git a/env/include/sdktools_tempents.inc b/env/include/sdktools_tempents.inc index 1224e0e..9b980c2 100644 --- a/env/include/sdktools_tempents.inc +++ b/env/include/sdktools_tempents.inc @@ -197,10 +197,9 @@ stock TE_WriteEncodedEnt(const String:prop[], value) */ stock TE_SendToAll(Float:delay=0.0) { - new maxClients = GetMaxClients(); new total = 0; - new clients[maxClients]; - for (new i=1; i<=maxClients; i++) + new clients[MaxClients]; + for (new i=1; i<=MaxClients; i++) { if (IsClientInGame(i)) { diff --git a/env/include/sdktools_trace.inc b/env/include/sdktools_trace.inc index ac715e1..845a566 100644 --- a/env/include/sdktools_trace.inc +++ b/env/include/sdktools_trace.inc @@ -365,3 +365,10 @@ native TR_GetHitGroup(Handle:hndl=INVALID_HANDLE); */ native TR_GetPlaneNormal(Handle:hndl, Float:normal[3]); +/** + * Tests a point to see if it's outside any playable area + * + * @param pos Vector buffer to store data in. + * @return True if outside world, otherwise false. + */ +native TR_PointOutsideWorld(Float:pos[3]); \ No newline at end of file diff --git a/env/include/sdktools_voice.inc b/env/include/sdktools_voice.inc index 19ed4ec..ef27180 100644 --- a/env/include/sdktools_voice.inc +++ b/env/include/sdktools_voice.inc @@ -49,6 +49,13 @@ * @endsection */ +enum ListenOverride +{ + Listen_Default = 0, /**< Leave it up to the game */ + Listen_No, /**< Can't hear */ + Listen_Yes, /**< Can hear */ +}; + /** * Set the client listening flags. * @@ -73,6 +80,7 @@ native GetClientListeningFlags(client); * @param iSender The sender index. * @return True if successful otherwise false. */ +#pragma deprecated Use SetListenOverride() instead native bool:SetClientListening(iReceiver, iSender, bool:bListen); /** @@ -82,4 +90,34 @@ native bool:SetClientListening(iReceiver, iSender, bool:bListen); * @param iSender The sender index. * @return True if successful otherwise false. */ -native bool:GetClientListening(iReceiver, iSender); \ No newline at end of file +#pragma deprecated GetListenOverride() instead +native bool:GetClientListening(iReceiver, iSender); + +/** + * Override the receiver's ability to listen to the sender. + * + * @param iReceiver The listener index. + * @param iSender The sender index. + * @param override + * @return True if successful otherwise false. + */ +native bool:SetListenOverride(iReceiver, iSender, ListenOverride:override); + +/** + * Retrieves the override of the receiver's ability to listen to the sender. + * + * @param iReceiver The listener index. + * @param iSender The sender index. + * @return The override value. + */ +native ListenOverride:GetListenOverride(iReceiver, iSender); + +/** + * Retrieves if the muter has muted the mutee. + * + * @param iMuter The muter index. + * @param iMutee The mutee index. + * @return True if muter has muted mutee, false otherwise. + */ +native bool:IsClientMuted(iMuter, iMutee); + diff --git a/env/include/sourcemod.inc b/env/include/sourcemod.inc index 5af90f6..bf27516 100644 --- a/env/include/sourcemod.inc +++ b/env/include/sourcemod.inc @@ -74,6 +74,13 @@ struct Plugin #include #include +enum APLRes +{ + APLRes_Success = 0, /**< Plugin should load */ + APLRes_Failure, /**< Plugin shouldn't load and should display an error */ + APLRes_SilentFailure /**< Plugin shouldn't load but do so silently */ +}; + /** * Declare this as a struct in your plugin to expose its information. * Example: @@ -101,26 +108,35 @@ public Plugin:myinfo; * @noreturn */ forward OnPluginStart(); - + +/** + * @deprecated Use AskPluginLoad2() instead. + * If a plugin contains both AskPluginLoad() and AskPluginLoad2(), the former will + * not be called, but old plugins with only AskPluginLoad() will work. + */ +#pragma deprecated Use AskPluginLoad2() instead +forward bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max); + /** * Called before OnPluginStart, in case the plugin wants to check for load failure. * This is called even if the plugin type is "private." Any natives from modules are * not available at this point. Thus, this forward should only be used for explicit - * pre-emptive things, such as adding dynamic natives, or setting certain types of load filters. + * pre-emptive things, such as adding dynamic natives, setting certain types of load + * filters (such as not loading the plugin for certain games). * * @note It is not safe to call externally resolved natives until OnPluginStart(). * @note Any sort of RTE in this function will cause the plugin to fail loading. - * @note You MUST remember to return SOMETHING here. The act of not returning is - * equivalent to returning 0 (false). If you forgot to return, it will - * cause your plugin to not load with a very strange error message. + * @note If you do not return anything, it is treated like returning success. + * @note If a plugin has an AskPluginLoad2(), AskPluginLoad() will not be called. + * * * @param myself Handle to the plugin. * @param late Whether or not the plugin was loaded "late" (after map load). * @param error Error message buffer in case load failed. * @param err_max Maximum number of characters for error message buffer. - * @return True if load success, false otherwise. + * @return APLRes_Success for load success, APLRes_Failure or APLRes_SilentFailure otherwise */ -forward bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max); +forward APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max); /** * Called when the plugin is about to be unloaded. @@ -394,16 +410,6 @@ native GetSysTickCount(); */ native AutoExecConfig(bool:autoCreate=true, const String:name[]="", const String:folder[]="sourcemod"); -/** - * Sets a native as optional, such that if it is unloaded, removed, - * or otherwise non-existent, the plugin will still work. Calling - * removed natives results in a run-time error. - * - * @param name Native name. - * @noreturn - */ -native MarkNativeAsOptional(const String:name[]); - /** * Registers a library name for identifying as a dependency to * other plugins. @@ -549,6 +555,81 @@ forward bool:OnClientFloodCheck(client); */ forward OnClientFloodResult(client, bool:blocked); +/** + * Feature types. + */ +enum FeatureType +{ + /** + * A native function call. + */ + FeatureType_Native, + + /** + * A named capability. This is distinctly different from checking for a + * native, because the underlying functionality could be enabled on-demand + * to improve loading time. Thus a native may appear to exist, but it might + * be part of a set of features that are not compatible with the current game + * or version of SourceMod. + */ + FeatureType_Capability +}; + +/** + * Feature statuses. + */ +enum FeatureStatus +{ + /** + * Feature is available for use. + */ + FeatureStatus_Available, + + /** + * Feature is not available. + */ + FeatureStatus_Unavailable, + + /** + * Feature is not known at all. + */ + FeatureStatus_Unknown +}; + +/** + * Returns whether "GetFeatureStatus" will work. Using this native + * or this function will not cause SourceMod to fail loading on older versions, + * however, GetFeatureStatus will only work if this function returns true. + * + * @return True if GetFeatureStatus will work, false otherwise. + */ +stock bool:CanTestFeatures() +{ + return LibraryExists("__CanTestFeatures__"); +} + +/** + * Returns whether a feature exists, and if so, whether it is usable. + * + * @param type Feature type. + * @param name Feature name. + * @return Feature status. + */ +native FeatureStatus:GetFeatureStatus(FeatureType:type, const String:name[]); + +/** + * Requires that a given feature is available. If it is not, SetFailState() + * is called with the given message. + * + * @param type Feature type. + * @param name Feature name. + * @param fmt Message format string, or empty to use default. + * @param ... Message format parameters, if any. + * @noreturn + */ +native RequireFeature(FeatureType:type, const String:name[], + const String:fmt[]="", any:...); + #include #include #include diff --git a/env/include/tf2.inc b/env/include/tf2.inc index 34007a6..d8b0068 100644 --- a/env/include/tf2.inc +++ b/env/include/tf2.inc @@ -35,6 +35,20 @@ #endif #define _tf2_included +#define TF_STUNFLAG_SLOWDOWN (1 << 0) // activates slowdown modifier +#define TF_STUNFLAG_BONKSTUCK (1 << 1) // bonk sound, stuck +#define TF_STUNFLAG_LIMITMOVEMENT (1 << 2) // disable forward/backward movement +#define TF_STUNFLAG_CHEERSOUND (1 << 3) // cheering sound +#define TF_STUNFLAG_NOSOUNDOREFFECT (1 << 5) // no sound or particle +#define TF_STUNFLAG_THIRDPERSON (1 << 6) // panic animation +#define TF_STUNFLAG_GHOSTEFFECT (1 << 7) // ghost particles + +#define TF_STUNFLAGS_LOSERSTATE TF_STUNFLAG_SLOWDOWN|TF_STUNFLAG_NOSOUNDOREFFECT|TF_STUNFLAG_THIRDPERSON +#define TF_STUNFLAGS_GHOSTSCARE TF_STUNFLAG_GHOSTEFFECT|TF_STUNFLAG_THIRDPERSON +#define TF_STUNFLAGS_SMALLBONK TF_STUNFLAG_THIRDPERSON|TF_STUNFLAG_SLOWDOWN +#define TF_STUNFLAGS_NORMALBONK TF_STUNFLAG_BONKSTUCK +#define TF_STUNFLAGS_BIGBONK TF_STUNFLAG_CHEERSOUND|TF_STUNFLAG_BONKSTUCK + enum TFClassType { TFClass_Unknown = 0, @@ -57,6 +71,41 @@ enum TFTeam TFTeam_Blue = 3 }; +enum TFCond +{ + TFCond_Slowed = 0, + TFCond_Zoomed, + TFCond_Disguising, + TFCond_Disguised, + TFCond_Cloaked, + TFCond_Ubercharged, + TFCond_TeleportedGlow, + TFCond_Taunting, + TFCond_UberchargeFading, + TFCond_Unknown1, + TFCond_Teleporting, + TFCond_Kritzkrieged, + TFCond_Unknown2, + TFCond_DeadRingered, + TFCond_Bonked, + TFCond_Dazed, + TFCond_Buffed, + TFCond_Charging, + TFCond_DemoBuff, + TFCond_CritCola, + TFCond_Healing, + TFCond_OnFire, + TFCond_Overhealed, + TFCond_Jarated +}; + +enum TFHoliday +{ + TFHoliday_None = 1, + TFHoliday_Halloween, + TFHoliday_Birthday +}; + /** * Sets a client on fire for 10 seconds. * @@ -75,6 +124,46 @@ native TF2_IgnitePlayer(client, target); */ native TF2_RespawnPlayer(client); +/** + * Regenerates a client's health and ammunition + * + * @param client Player's index. + * @noreturn + * @error Invalid client index, client not in game, or no mod support. + */ +native TF2_RegeneratePlayer(client); + +/** + * Adds a condition to a player + * + * @param client Player's index. + * @param condition Integer identifier of condition to apply. + * @param duration Duration of condition (does not apply to all conditions). + * @noreturn + * @error Invalid client index, client not in game, or no mod support. + */ +native TF2_AddCondition(client, TFCond:condition, Float:duration); + +/** + * Removes a condition from a player + * + * @param client Player's index. + * @param condition Integer identifier of condition to remove. + * @noreturn + * @error Invalid client index, client not in game, or no mod support. + */ +native TF2_RemoveCondition(client, TFCond:condition); + +/** + * Enables/disables PowerPlay mode on a player. + * + * @param client Player's index. + * @param enabled Whether to enable or disable PowerPlay on player. + * @noreturn + * @error Invalid client index, client not in game, or no mod support. + */ +native TF2_SetPlayerPowerPlay(client, bool:enabled); + /** * Disguises a client to the given model and team. Only has an effect on spies. * @@ -97,6 +186,19 @@ native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class); */ native TF2_RemovePlayerDisguise(client); +/** + * Stuns a client + * + * @param client Player's index. + * @param float Duration of stun. + * @param float Slowdown percent (as decimal, 0.00-1.00) + * (ignored if TF_STUNFLAG_SLOWDOWN is not set. + * @param int Stun flags. + * @param attacker Attacker's index (0 is allowed for world). + * @noreturn + */ +native TF2_StunPlayer(client, Float:duration, Float:slowdown=0.0, stunflags, attacker=0); + /** * Retrieves the entity index of the CPlayerResource entity * @@ -129,6 +231,16 @@ native TFClassType:TF2_GetClass(const String:classname[]); */ forward Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &bool:result); +/** + * Called when the game checks to see if the current day is one of its tracked holidays + * + * @note Change the value of holiday and return Plugin_Changed to override. + * Return Plugin_Continue for no change. + * + * @param holiday Current Holiday + */ +forward Action:TF2_OnGetHoliday(&TFHoliday:holiday); + /** * Do not edit below this line! */ @@ -136,10 +248,27 @@ public Extension:__ext_tf2 = { name = "TF2 Tools", file = "game.tf2.ext", - autoload = 1, + autoload = 0, #if defined REQUIRE_EXTENSIONS required = 1, #else required = 0, #endif }; + +#if !defined REQUIRE_EXTENSIONS +public __ext_tf2_SetNTVOptional() +{ + MarkNativeAsOptional("TF2_IgnitePlayer"); + MarkNativeAsOptional("TF2_RespawnPlayer"); + MarkNativeAsOptional("TF2_RegeneratePlayer"); + MarkNativeAsOptional("TF2_AddCondition"); + MarkNativeAsOptional("TF2_RemoveCondition"); + MarkNativeAsOptional("TF2_SetPlayerPowerPlay"); + MarkNativeAsOptional("TF2_DisguisePlayer"); + MarkNativeAsOptional("TF2_RemovePlayerDisguise"); + MarkNativeAsOptional("TF2_StunPlayer"); + MarkNativeAsOptional("TF2_GetResourceEntity"); + MarkNativeAsOptional("TF2_GetClass"); +} +#endif diff --git a/env/include/tf2_stocks.inc b/env/include/tf2_stocks.inc index a7c63ca..cfa13c8 100644 --- a/env/include/tf2_stocks.inc +++ b/env/include/tf2_stocks.inc @@ -38,6 +38,37 @@ #include #include +#define TF_CONDFLAG_NONE 0 +#define TF_CONDFLAG_SLOWED (1 << 0) +#define TF_CONDFLAG_ZOOMED (1 << 1) +#define TF_CONDFLAG_DISGUISING (1 << 2) +#define TF_CONDFLAG_DISGUISED (1 << 3) +#define TF_CONDFLAG_CLOAKED (1 << 4) +#define TF_CONDFLAG_UBERCHARGED (1 << 5) +#define TF_CONDFLAG_TELEPORTGLOW (1 << 6) +#define TF_CONDFLAG_TAUNTING (1 << 7) +#define TF_CONDFLAG_UBERCHARGEFADE (1 << 8) +#define TF_CONDFLAG_TELEPORTING (1 << 10) +#define TF_CONDFLAG_KRITZKRIEGED (1 << 11) +#define TF_CONDFLAG_DEADRINGERED (1 << 13) +#define TF_CONDFLAG_BONKED (1 << 14) +#define TF_CONDFLAG_DAZED (1 << 15) +#define TF_CONDFLAG_BUFFED (1 << 16) +#define TF_CONDFLAG_CHARGING (1 << 17) +#define TF_CONDFLAG_DEMOBUFF (1 << 18) +#define TF_CONDFLAG_CRITCOLA (1 << 19) +#define TF_CONDFLAG_HEALING (1 << 20) +#define TF_CONDFLAG_ONFIRE (1 << 21) +#define TF_CONDFLAG_OVERHEALED (1 << 22) +#define TF_CONDFLAG_JARATED (1 << 23) + +#define TF_DEATHFLAG_KILLERDOMINATION (1 << 0) +#define TF_DEATHFLAG_ASSISTERDOMINATION (1 << 1) +#define TF_DEATHFLAG_KILLERREVENGE (1 << 2) +#define TF_DEATHFLAG_ASSISTERREVENGE (1 << 3) +#define TF_DEATHFLAG_FIRSTBLOOD (1 << 4) +#define TF_DEATHFLAG_DEADRINGER (1 << 5) + enum TFResourceType { TFResource_Ping, @@ -217,3 +248,13 @@ stock TF2_RemoveAllWeapons(client) } } +/** + * Gets a player's condition bits + * + * @param client Player's index. + * @return Player's condition bits + */ +stock TF2_GetPlayerConditionFlags(client) +{ + return GetEntProp(client, Prop_Send, "m_nPlayerCond"); +} diff --git a/env/include/usermessages.inc b/env/include/usermessages.inc index ff27f9d..b960de3 100644 --- a/env/include/usermessages.inc +++ b/env/include/usermessages.inc @@ -170,10 +170,9 @@ native UnhookUserMessage(UserMsg:msg_id, MsgHook:hook, bool:intercept=false); */ stock Handle:StartMessageAll(String:msgname[], flags=0) { - new maxClients = GetMaxClients(); new total = 0; - new clients[maxClients]; - for (new i=1; i<=maxClients; i++) + new clients[MaxClients]; + for (new i=1; i<=MaxClients; i++) { if (IsClientConnected(i)) { diff --git a/env/include/version.inc b/env/include/version.inc index 762471d..fe346f3 100644 --- a/env/include/version.inc +++ b/env/include/version.inc @@ -36,7 +36,7 @@ #define _version_included #define SOURCEMOD_V_MAJOR 1 /**< SourceMod Major version */ -#define SOURCEMOD_V_MINOR 2 /**< SourceMod Minor version */ -#define SOURCEMOD_V_RELEASE 1 /**< SourceMod Release version */ +#define SOURCEMOD_V_MINOR 3 /**< SourceMod Minor version */ +#define SOURCEMOD_V_RELEASE 4 /**< SourceMod Release version */ -#define SOURCEMOD_VERSION "1.2.1" /**< SourceMod version string (major.minor.release.build) */ +#define SOURCEMOD_VERSION "1.3.4" /**< SourceMod version string (major.minor.release.build) */ diff --git a/env/linux/bin/spcomp b/env/linux/bin/spcomp deleted file mode 100755 index 904911d..0000000 Binary files a/env/linux/bin/spcomp and /dev/null differ diff --git a/env/linux/bin/spcomp-1.3.4 b/env/linux/bin/spcomp-1.3.4 new file mode 100755 index 0000000..0410aee Binary files /dev/null and b/env/linux/bin/spcomp-1.3.4 differ diff --git a/env/readme.txt b/env/readme.txt index d0d59c8..636cbad 100644 --- a/env/readme.txt +++ b/env/readme.txt @@ -1,7 +1,7 @@ Compiling: - Windows: Use compile.bat in the source code repository. -- Linux: Use the makefile. +- Linux: Use the Makefile script. The binary will be made in /build. diff --git a/env/win32/bin/spcomp-1.3.4.exe b/env/win32/bin/spcomp-1.3.4.exe new file mode 100644 index 0000000..c3aaf89 Binary files /dev/null and b/env/win32/bin/spcomp-1.3.4.exe differ diff --git a/env/win32/bin/spcomp.exe b/env/win32/bin/spcomp.exe deleted file mode 100644 index d0842b0..0000000 Binary files a/env/win32/bin/spcomp.exe and /dev/null differ