├── .gitignore ├── ACS.sp ├── AI_HardSI.sp ├── AI_HardSI ├── AI_Boomer.sp ├── AI_Charger.sp ├── AI_Hunter.sp ├── AI_Jockey.sp ├── AI_Smoker.sp ├── AI_Spitter.sp ├── AI_Tank.sp ├── AI_Witch.sp └── hardcoop_util.sp ├── CommandShortcut.sp ├── HunterSkeetSound.sp ├── all4dead2.sp ├── autoadmin.sp ├── autowipe.sp ├── challenge.sp ├── confogl_autoloader.sp ├── difficulty_adjustment_system.sp ├── include ├── admin.inc ├── adminmenu.inc ├── adt.inc ├── adt_array.inc ├── adt_stack.inc ├── adt_trie.inc ├── banning.inc ├── basecomm.inc ├── bitbuffer.inc ├── builtinvotes.inc ├── caster_system.inc ├── clientprefs.inc ├── clients.inc ├── code_patcher.inc ├── collisionhook.inc ├── colors.inc ├── commandfilters.inc ├── commandline.inc ├── confogl.inc ├── connect.inc ├── console.inc ├── convars.inc ├── core.inc ├── cstrike.inc ├── datapack.inc ├── dbi.inc ├── dhooks.inc ├── entity.inc ├── entity_prop_stocks.inc ├── events.inc ├── files.inc ├── float.inc ├── functions.inc ├── gamerules.inc ├── geoip.inc ├── godframecontrol.inc ├── halflife.inc ├── handles.inc ├── helpers.inc ├── holdout_bonus.inc ├── implodeexplode.inc ├── keyvalues.inc ├── l4d2_boss_percents.inc ├── l4d2_changelevel.inc ├── l4d2_direct.inc ├── l4d2_health_temp_bonus.inc ├── l4d2_hittable_control.inc ├── l4d2_hybrid_scoremod.inc ├── l4d2_penalty_bonus.inc ├── l4d2_playstats.inc ├── l4d2_saferoom_detect.inc ├── l4d2_scoremod.inc ├── l4d2_sequence.txt ├── l4d2_skill_detect.inc ├── l4d2d_internals.inc ├── l4d2d_timers.inc ├── l4d2director.inc ├── l4d2lib.inc ├── l4d2timers.inc ├── l4d2util.inc ├── l4d2util_constants.inc ├── l4d2util_infected.inc ├── l4d2util_rounds.inc ├── l4d2util_stocks.inc ├── l4d2util_survivors.inc ├── l4d2util_tanks.inc ├── l4d2util_weapons.inc ├── l4d2weapons.inc ├── l4d_boss_vote.inc ├── l4d_tank_control_eq.inc ├── lang.inc ├── left4dhooks.inc ├── left4dhooks_anim.inc ├── left4dhooks_lux_library.inc ├── left4dhooks_silver.inc ├── left4dhooks_stocks.inc ├── left4downtown.inc ├── left4framework.inc ├── lerpmonitor.inc ├── lgofnoc.inc ├── logging.inc ├── mapchooser.inc ├── mapinfo.inc ├── menus.inc ├── morecolors.inc ├── multicolors.inc ├── multicolors │ ├── colors.inc │ └── morecolors.inc ├── nativevotes.inc ├── nextmap.inc ├── pause.inc ├── profiler.inc ├── protobuf.inc ├── readyup.inc ├── regex.inc ├── rounds.inc ├── rounds_l4d2util.inc ├── sceneprocessor.inc ├── sdkhooks.inc ├── sdktools.inc ├── sdktools_client.inc ├── sdktools_engine.inc ├── sdktools_entinput.inc ├── sdktools_entoutput.inc ├── sdktools_functions.inc ├── sdktools_gamerules.inc ├── sdktools_hooks.inc ├── sdktools_sound.inc ├── sdktools_stocks.inc ├── sdktools_stringtables.inc ├── sdktools_tempents.inc ├── sdktools_tempents_stocks.inc ├── sdktools_trace.inc ├── sdktools_variant_t.inc ├── sdktools_voice.inc ├── smac.inc ├── smac_cvars.inc ├── smac_stocks.inc ├── smac_wallhack.inc ├── smlib.inc ├── smlib │ ├── arrays.inc │ ├── clients.inc │ ├── colors.inc │ ├── concommands.inc │ ├── convars.inc │ ├── crypt.inc │ ├── debug.inc │ ├── dynarrays.inc │ ├── edicts.inc │ ├── effects.inc │ ├── entities.inc │ ├── files.inc │ ├── game.inc │ ├── general.inc │ ├── math.inc │ ├── menus.inc │ ├── server.inc │ ├── sql.inc │ ├── strings.inc │ ├── teams.inc │ ├── vehicles.inc │ ├── weapons.inc │ └── world.inc ├── smrcon.inc ├── socket.inc ├── sorting.inc ├── sourcemod.inc ├── sourcescramble.inc ├── string.inc ├── survivors.inc ├── tanks.inc ├── tanks_l4d2util.inc ├── testing.inc ├── textparse.inc ├── tf2.inc ├── tf2_stocks.inc ├── timers.inc ├── topmenus.inc ├── usermessages.inc ├── vector.inc ├── version.inc ├── version_auto.inc ├── vscript_replacer.inc ├── weapons.inc └── witch_and_tankifier.inc ├── jointeam.sp ├── jointeam_hunter.sp ├── l4d2_bot_spit_ignite_gascan.sp ├── l4d2_drop.sp ├── l4d2_highlight_entity.sp ├── l4d2_jockey_teleport.sp ├── l4d2_sniper_stats.sp ├── l4d2_votetospec.sp ├── l4d2_wave_spawner.sp ├── l4d_boss_percent.sp ├── l4d_boss_percent_hunter.sp ├── l4d_boss_vote_hunter.sp ├── l4d_drop.sp ├── l4d_swimming.sp ├── mob_interval_limit.sp ├── nativevotes ├── data-keyvalues.sp └── game.sp ├── pause_coop.sp ├── pills_giver.sp ├── script_reloader.sp ├── server.sp ├── survivor_mvp.sp ├── unlimit_spawn.sp ├── versus2coop.sp ├── vote.sp ├── weapon_slowdown.sp ├── wingman.sp └── 全局versus.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | sourcemod.code-workspace 3 | .vscode/ 4 | .directory 5 | compiled/ -------------------------------------------------------------------------------- /AI_HardSI/AI_Charger.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #define DEBUG_CHARGER_TARGET 0 4 | 5 | // custom convar 6 | Handle hCvarChargeProximity; 7 | Handle hCvarAimOffsetSensitivityCharger; 8 | Handle hCvarHealthThresholdCharger; 9 | int bShouldCharge[MAXPLAYERS]; // manual tracking of charge cooldown 10 | 11 | public void Charger_OnModuleStart() { 12 | // Charge proximity 13 | hCvarChargeProximity = CreateConVar("ai_charge_proximity", "300", "How close a charger will approach before charging"); 14 | // Aim offset sensitivity 15 | hCvarAimOffsetSensitivityCharger = CreateConVar("ai_aim_offset_sensitivity_charger", 16 | "20", 17 | "If the charger has a target, it will not straight pounce if the target's aim on the horizontal axis is within this radius", 18 | FCVAR_NONE, 19 | true, 0.0, true, 179.0); 20 | // Health threshold 21 | hCvarHealthThresholdCharger = CreateConVar("ai_health_threshold_charger", "350", "Charger will charge if its health drops to this level"); 22 | } 23 | 24 | public void Charger_OnModuleEnd() { 25 | } 26 | 27 | /*********************************************************************************************************************************************************************************** 28 | 29 | KEEP CHARGE ON COOLDOWN UNTIL WITHIN PROXIMITY 30 | 31 | ***********************************************************************************************************************************************************************************/ 32 | 33 | // Initialise spawned chargers 34 | public Action Charger_OnSpawn(int botCharger) { 35 | bShouldCharge[botCharger] = false; 36 | return Plugin_Handled; 37 | } 38 | 39 | public Action Charger_OnPlayerRunCmd(int charger, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon) { 40 | // prevent charge until survivors are within the defined proximity 41 | float chargerPos[3]; 42 | GetClientAbsOrigin(charger, chargerPos); 43 | int target = GetClientAimTarget(charger); 44 | int iSurvivorProximity = GetSurvivorProximity(chargerPos, target); // invalid(=-1) target will cause GetSurvivorProximity() to return distance to closest survivor 45 | int chargerHealth = GetEntProp(charger, Prop_Send, "m_iHealth"); 46 | //new String:sweapon[32]; 47 | //if (!target) return Plugin_Handled; 48 | //GetClientWeapon(target, sweapon, sizeof(sweapon)); 49 | //PrintToChatAll("Charger 的目标正在使用的武器:%s", sweapon); 50 | if( (chargerHealth > GetConVarInt(hCvarHealthThresholdCharger) && iSurvivorProximity > GetConVarInt(hCvarChargeProximity)) ) { 51 | if( !bShouldCharge[charger] ) { 52 | BlockCharge(charger); 53 | return Plugin_Changed; 54 | } 55 | } else { 56 | bShouldCharge[charger] = true; 57 | } 58 | return Plugin_Continue; 59 | } 60 | 61 | void BlockCharge(int charger) { 62 | int chargeEntity = GetEntPropEnt(charger, Prop_Send, "m_customAbility"); 63 | if (chargeEntity > 0) { // charger entity persists for a short while after death; check ability entity is valid 64 | SetEntPropFloat(chargeEntity, Prop_Send, "m_timestamp", GetGameTime() + 0.1); // keep extending end of cooldown period 65 | } 66 | } 67 | 68 | void Charger_OnCharge(int charger) { 69 | // Assign charger a new survivor target if they are not specifically targetting anybody with their charge or their target is watching 70 | int aimTarget = GetClientAimTarget(charger); 71 | if( !IsSurvivor(aimTarget) || IsTargetWatchingAttacker(charger, GetConVarInt(hCvarAimOffsetSensitivityCharger)) ) { 72 | float chargerPos[3]; 73 | GetClientAbsOrigin(charger, chargerPos); 74 | int newTarget = GetClosestSurvivor(chargerPos, aimTarget); // try and find another closeby survivor 75 | if( newTarget != -1 && GetSurvivorProximity(chargerPos, newTarget) <= GetConVarInt(hCvarChargeProximity) ) { 76 | aimTarget = newTarget; // might be the same survivor if there were no other survivors within configured charge proximity 77 | 78 | #if DEBUG_CHARGER_TARGET 79 | new String:targetName[32]; 80 | GetClientName(newTarget, targetName, sizeof(targetName)); 81 | PrintToChatAll("Charger forced to charge survivor %s", targetName); 82 | #endif 83 | 84 | } 85 | 86 | ChargePrediction(charger, aimTarget); 87 | } 88 | } 89 | 90 | void ChargePrediction(int charger, int survivor) { 91 | if( !IsBotCharger(charger) || !IsSurvivor(survivor) ) { 92 | return; 93 | } 94 | float survivorPos[3]; 95 | float chargerPos[3]; 96 | float attackDirection[3]; 97 | float attackAngle[3]; 98 | // Add some fancy schmancy trignometric prediction here; as a placeholder charger will face survivor directly 99 | GetClientAbsOrigin(charger, chargerPos); 100 | GetClientAbsOrigin(survivor, survivorPos); 101 | MakeVectorFromPoints( chargerPos, survivorPos, attackDirection ); 102 | GetVectorAngles(attackDirection, attackAngle); 103 | TeleportEntity(charger, NULL_VECTOR, attackAngle, NULL_VECTOR); 104 | } -------------------------------------------------------------------------------- /AI_HardSI/AI_Smoker.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | // #define SMOKER_TONGUE_DELAY 0.0 // 默认 1.0 3 | 4 | // new Handle:hCvarTongueDelay; 5 | // new Handle:hCvarSmokerHealth; 6 | // new Handle:hCvarChokeDamageInterrupt; 7 | 8 | // public Smoker_OnModuleStart() { 9 | // // Smoker health 10 | // hCvarSmokerHealth = FindConVar("z_gas_health"); 11 | // HookConVarChange(hCvarSmokerHealth, ConVarChanged:OnSmokerHealthChanged); 12 | 13 | // // Damage required to kill a smoker that is pulling someone 14 | // hCvarChokeDamageInterrupt = FindConVar("tongue_break_from_damage_amount"); 15 | // SetConVarInt(hCvarChokeDamageInterrupt, GetConVarInt(hCvarSmokerHealth)); // default 50 16 | // HookConVarChange(hCvarChokeDamageInterrupt, ConVarChanged:OnTongueCvarChange); 17 | 18 | // // Delay before smoker shoots its tongue 19 | // hCvarTongueDelay = FindConVar("smoker_tongue_delay"); 20 | // SetConVarFloat(hCvarTongueDelay, SMOKER_TONGUE_DELAY); // default 1.5 21 | // HookConVarChange(hCvarTongueDelay, ConVarChanged:OnTongueCvarChange); 22 | // } 23 | 24 | // public Smoker_OnModuleEnd() { 25 | // ResetConVar(hCvarChokeDamageInterrupt); 26 | // ResetConVar(hCvarTongueDelay); 27 | // } 28 | 29 | // // Game tries to reset these cvars 30 | // public OnTongueCvarChange() { 31 | // SetConVarFloat(hCvarTongueDelay, SMOKER_TONGUE_DELAY); 32 | // SetConVarInt(hCvarChokeDamageInterrupt, GetConVarInt(hCvarSmokerHealth)); 33 | // } 34 | 35 | // // Update choke damage interrupt to match smoker max health 36 | // public Action:OnSmokerHealthChanged() { 37 | // SetConVarInt(hCvarChokeDamageInterrupt, GetConVarInt(hCvarSmokerHealth)); 38 | // } 39 | 40 | public Action Smoker_OnPlayerRunCmd( int smoker, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon ) { 41 | float Pos[3]; 42 | GetClientAbsOrigin(smoker, Pos); 43 | int iSurvivorsProximity = GetSurvivorProximity(Pos); 44 | //new bool:bHasSight = bool:GetEntProp(smoker, Prop_Send, "m_hasVisibleThreats"); //Line of sight to survivors 45 | 46 | // Get Angle of Smoker 47 | //decl Float:clientEyeAngles[3]; 48 | //GetClientEyeAngles(smoker, clientEyeAngles); 49 | 50 | if (iSurvivorsProximity < 100) { 51 | buttons |= IN_ATTACK; 52 | buttons |= IN_ATTACK2; 53 | } 54 | return Plugin_Changed; 55 | } -------------------------------------------------------------------------------- /AI_HardSI/AI_Spitter.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | public void Spitter_OnModuleStart() { 4 | } 5 | 6 | public void Spitter_OnModuleEnd() { 7 | } 8 | /* 9 | public Action:Boomer_OnPlayerRunCmd( boomer, &buttons, Float:vel[3], Float:angles[3] ) { 10 | 11 | } */ -------------------------------------------------------------------------------- /AI_HardSI/AI_Witch.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | public void Witch_OnModuleStart() { 4 | } 5 | 6 | public void Witch_OnModuleEnd() { 7 | } 8 | -------------------------------------------------------------------------------- /CommandShortcut.sp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | public Plugin:myinfo = 4 | { 5 | name = "Chat command", 6 | author = "Arkarr", 7 | description = "Execute a command depend of what the user type.", 8 | version = "1.1", 9 | url = "http://www.sourcemod.net" 10 | }; 11 | 12 | public OnPluginStart() 13 | { 14 | AddCommandListener(HookPlayerChat, "say"); 15 | AddCommandListener(HookPlayerChat, "say_team"); 16 | AddCommandListener(HookPlayerChat, "say2"); 17 | } 18 | 19 | public Action:HookPlayerChat(client, const String:command[], args) 20 | { 21 | decl String:strChat[255]; 22 | decl String:strCommand[255]; 23 | decl String:strFlag[255]; 24 | decl String:player_text[300]; 25 | decl String:player_final[50]; 26 | new player_id; 27 | 28 | new Handle:kv = CreateKeyValues("ChatCommand"); 29 | FileToKeyValues(kv, "addons/sourcemod/configs/ChatCommand.cfg"); 30 | 31 | if (!KvGotoFirstSubKey(kv)) { 32 | return; 33 | } 34 | 35 | do { 36 | KvGetString(kv, "chat", strChat, sizeof(strChat)); 37 | KvGetString(kv, "command", strCommand, sizeof(strCommand)); 38 | KvGetString(kv, "flag", strFlag, sizeof(strFlag)); 39 | new flag = ReadFlagString(strFlag); 40 | 41 | if(CheckCommandAccess(client, "sm_admin", flag, true) && GetClientTeam(client) == 2) 42 | { 43 | GetCmdArgString(player_text, sizeof(player_text)); 44 | StripQuotes(player_text); 45 | if(StrEqual(player_text, strChat, true)) 46 | { 47 | player_id = GetClientUserId(client); 48 | Format(player_final, sizeof(player_final), "#%d", player_id); 49 | ReplaceString(strCommand, sizeof(strCommand), "[PLAYER_NAME]", player_final); 50 | ServerCommand(strCommand); 51 | } 52 | } 53 | 54 | } while (KvGotoNextKey(kv)); 55 | 56 | CloseHandle(kv); 57 | } 58 | -------------------------------------------------------------------------------- /HunterSkeetSound.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /** 8 | * 装逼是游戏第一动力。 9 | * 受落子视频的启发,爆 ht 带嘟嘟音效,实际打起来也非常带感。 10 | * 这个也没什么好说的。 11 | */ 12 | 13 | public void OnMapStart() 14 | { 15 | PrecacheSound("ui/bigreward.wav"); 16 | } 17 | 18 | public void OnSkeet(int survivor, int hunter) 19 | { 20 | PlaySkeetSoundToClient(survivor); 21 | } 22 | 23 | public void OnSkeetMelee(int survivor, int hunter) 24 | { 25 | PlaySkeetSoundToClient(survivor); 26 | } 27 | 28 | public void OnSkeetGL(int survivor, int hunter) 29 | { 30 | PlaySkeetSoundToClient(survivor); 31 | } 32 | 33 | public void OnSkeetSniper(int survivor, int hunter) 34 | { 35 | PlaySkeetSoundToClient(survivor); 36 | } 37 | 38 | public void OnSkeetHurt(int survivor, int hunter) 39 | { 40 | PlaySkeetSoundToClient(survivor); 41 | } 42 | 43 | public void OnSkeetMeleeHurt(int survivor, int hunter) 44 | { 45 | PlaySkeetSoundToClient(survivor); 46 | } 47 | 48 | public void OnSkeetSniperHurt(int survivor, int hunter) 49 | { 50 | PlaySkeetSoundToClient(survivor); 51 | } 52 | 53 | stock void PlaySkeetSoundToClient(int client) { 54 | if ( !IsClientAndInGame(client) ) return; 55 | EmitSoundToClient(client, "ui/bigreward.wav", client); 56 | } 57 | 58 | stock bool IsClientAndInGame(int index) { 59 | return ( index > 0 && index <= MaxClients + 1 && IsClientInGame(index) ); 60 | } 61 | -------------------------------------------------------------------------------- /autoadmin.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | public Plugin myinfo = { 5 | name = "Add non-admins to admin group public", 6 | author = "Bacardi", 7 | description = "Automatically add non-admins to admin group public", 8 | version = "0.1", 9 | url = "-" 10 | }; 11 | 12 | public void OnClientPostAdminCheck(int client) 13 | { 14 | if (!IsFakeClient(client) && GetUserAdmin(client) == INVALID_ADMIN_ID) 15 | { 16 | GroupId id = FindAdmGroup("public"); // Need create admin group called "public" in admin_groups.cfg 17 | 18 | if (id == INVALID_GROUP_ID) 19 | { 20 | // Didn't find admin group "public" from admin_groups.cfg 21 | return; 22 | } 23 | 24 | AdminId admin = CreateAdmin(); 25 | SetUserAdmin(client, admin, true); 26 | AdminInheritGroup(admin, id); 27 | } 28 | } -------------------------------------------------------------------------------- /confogl_autoloader.sp: -------------------------------------------------------------------------------- 1 | // Thanks to Thraka 2 | 3 | #include 4 | #pragma semicolon 1 5 | #pragma newdecls required 6 | 7 | #define PLUGIN_VERSION "1.2" 8 | 9 | public Plugin myinfo = 10 | { 11 | name = "Confogl Autoloader", 12 | author = "D4rKr0W, 海洋空氣", 13 | description = "Executes confogl whenever a versus/teamversus lobby connects or the gamemode is switched to versus/teamversus", 14 | version = PLUGIN_VERSION, 15 | url = "http://code.google.com/p/confogl" 16 | } 17 | 18 | ConVar hAutoloaderConfig; 19 | ConVar hCurrentConfig; 20 | 21 | public void OnPluginStart() 22 | { 23 | CreateConVar("confogl_loader_ver", PLUGIN_VERSION, "Version of confogl autoloader plugin.", FCVAR_SPONLY|FCVAR_NOTIFY); 24 | hAutoloaderConfig = CreateConVar("confogl_autoloader_config", "", "Config to launch with the autoloader"); 25 | hCurrentConfig = CreateConVar("confogl_current_config", "", "Current config"); 26 | } 27 | 28 | public void OnMapStart() 29 | { 30 | ExecuteConfig(); 31 | } 32 | 33 | void ExecuteConfig() 34 | { 35 | char sConfigBuffer[PLATFORM_MAX_PATH]; 36 | hAutoloaderConfig.GetString(sConfigBuffer, sizeof(sConfigBuffer)); 37 | char sCurrentConfig[PLATFORM_MAX_PATH]; 38 | hCurrentConfig.GetString(sCurrentConfig, sizeof(sCurrentConfig)); 39 | 40 | if (strlen(sCurrentConfig) != 0 || strlen(sConfigBuffer) == 0) return; 41 | 42 | ServerCommand("sm_forcematch %s", sConfigBuffer); 43 | } -------------------------------------------------------------------------------- /include/adminmenu.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _adminmenu_included 34 | #endinput 35 | #endif 36 | #define _adminmenu_included 37 | 38 | /* Decide whether topmenus should be required */ 39 | #if !defined REQUIRE_PLUGIN 40 | #if defined REQUIRE_EXTENSIONS 41 | #define TEMP_REQUIRE_EXTENSIONS 42 | #undef REQUIRE_EXTENSIONS 43 | #endif 44 | #endif 45 | 46 | #include 47 | 48 | /* Restore old REQUIRE_EXTENSIONS value if necessary */ 49 | #if defined TEMP_REQUIRE_EXTENSIONS 50 | #define REQUIRE_EXTENSIONS 51 | #undef TEMP_REQUIRE_EXTENSIONS 52 | #endif 53 | 54 | /** Category for player commands. */ 55 | #define ADMINMENU_PLAYERCOMMANDS "PlayerCommands" 56 | /** Category for server commands. */ 57 | #define ADMINMENU_SERVERCOMMANDS "ServerCommands" 58 | /** Category for voting commands. */ 59 | #define ADMINMENU_VOTINGCOMMANDS "VotingCommands" 60 | 61 | /** 62 | * Called when the admin menu is created and 3rd party plugins can grab 63 | * the Handle or add categories. 64 | * 65 | * @param topmenu Handle to the admin menu's TopMenu. 66 | */ 67 | forward void OnAdminMenuCreated(Handle topmenu); 68 | 69 | /** 70 | * Called when the admin menu is ready to have items added. 71 | * 72 | * @param topmenu Handle to the admin menu's TopMenu. 73 | */ 74 | forward void OnAdminMenuReady(Handle topmenu); 75 | 76 | /** 77 | * Retrieves the Handle to the admin top menu. 78 | * 79 | * @return Handle to the admin menu's TopMenu, 80 | * or INVALID_HANDLE if not created yet. 81 | */ 82 | native TopMenu GetAdminTopMenu(); 83 | 84 | /** 85 | * Adds targets to an admin menu. 86 | * 87 | * Each client is displayed as: name (userid) 88 | * Each item contains the userid as a string for its info. 89 | * 90 | * @param menu Menu Handle. 91 | * @param source_client Source client, or 0 to ignore immunity. 92 | * @param in_game_only True to only select in-game players. 93 | * @param alive_only True to only select alive players. 94 | * @return Number of clients added. 95 | */ 96 | native int AddTargetsToMenu(Handle menu, 97 | int source_client, 98 | bool in_game_only=true, 99 | bool alive_only=false); 100 | 101 | /** 102 | * Adds targets to an admin menu. 103 | * 104 | * Each client is displayed as: name (userid) 105 | * Each item contains the userid as a string for its info. 106 | * 107 | * @param menu Menu Handle. 108 | * @param source_client Source client, or 0 to ignore immunity. 109 | * @param flags COMMAND_FILTER flags from commandfilters.inc. 110 | * @return Number of clients added. 111 | */ 112 | native int AddTargetsToMenu2(Handle menu, int source_client, int flags); 113 | 114 | /** 115 | * Re-displays the admin menu to a client after selecting an item. 116 | * Auto-aborts if the Handle is invalid. 117 | * 118 | * @param topmenu TopMenu Handle. 119 | * @param client Client index. 120 | * @return True on success, false on failure. 121 | */ 122 | stock bool RedisplayAdminMenu(Handle topmenu, int client) 123 | { 124 | if (topmenu == INVALID_HANDLE) 125 | { 126 | return false; 127 | } 128 | 129 | return DisplayTopMenu(topmenu, client, TopMenuPosition_LastCategory); 130 | } 131 | 132 | /* DO NOT EDIT BELOW THIS LINE */ 133 | 134 | public SharedPlugin __pl_adminmenu = 135 | { 136 | name = "adminmenu", 137 | file = "adminmenu.smx", 138 | #if defined REQUIRE_PLUGIN 139 | required = 1, 140 | #else 141 | required = 0, 142 | #endif 143 | }; 144 | 145 | #if !defined REQUIRE_PLUGIN 146 | public void __pl_adminmenu_SetNTVOptional() 147 | { 148 | MarkNativeAsOptional("GetAdminTopMenu"); 149 | MarkNativeAsOptional("AddTargetsToMenu"); 150 | MarkNativeAsOptional("AddTargetsToMenu2"); 151 | } 152 | #endif 153 | -------------------------------------------------------------------------------- /include/adt.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _adt_included 34 | #endinput 35 | #endif 36 | #define _adt_included 37 | 38 | #include 39 | #include 40 | #include 41 | -------------------------------------------------------------------------------- /include/basecomm.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2011 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _basecomm_included 34 | #endinput 35 | #endif 36 | #define _basecomm_included 37 | 38 | /** 39 | * Called when a client is muted or unmuted 40 | * 41 | * @param client Client index 42 | * @param muteState True if client was muted, false otherwise 43 | */ 44 | forward void BaseComm_OnClientMute(int client, bool muteState); 45 | 46 | /** 47 | * Called when a client is gagged or ungagged 48 | * 49 | * @param client Client index 50 | * @param gagState True if client was gaged, false otherwise 51 | */ 52 | forward void BaseComm_OnClientGag(int client, bool gagState); 53 | 54 | /** 55 | * Returns whether or not a client is gagged 56 | * 57 | * @param client Client index. 58 | * @return True if client is gagged, false otherwise. 59 | */ 60 | native bool BaseComm_IsClientGagged(int client); 61 | 62 | /** 63 | * Returns whether or not a client is muted 64 | * 65 | * @param client Client index. 66 | * @return True if client is muted, false otherwise. 67 | */ 68 | native bool BaseComm_IsClientMuted(int client); 69 | 70 | /** 71 | * Sets a client's gag state 72 | * 73 | * @param client Client index. 74 | * @param gagState True to gag client, false to ungag. 75 | * @return True if this caused a change in gag state, false otherwise. 76 | */ 77 | native bool BaseComm_SetClientGag(int client, bool gagState); 78 | 79 | /** 80 | * Sets a client's mute state 81 | * 82 | * @param client Client index. 83 | * @param muteState True to mute client, false to unmute. 84 | * @return True if this caused a change in mute state, false otherwise. 85 | */ 86 | native bool BaseComm_SetClientMute(int client, bool muteState); 87 | 88 | /* DO NOT EDIT BELOW THIS LINE */ 89 | 90 | public SharedPlugin __pl_basecomm = 91 | { 92 | name = "basecomm", 93 | file = "basecomm.smx", 94 | #if defined REQUIRE_PLUGIN 95 | required = 1, 96 | #else 97 | required = 0, 98 | #endif 99 | }; 100 | 101 | #if !defined REQUIRE_PLUGIN 102 | public void __pl_basecomm_SetNTVOptional() 103 | { 104 | MarkNativeAsOptional("BaseComm_IsClientGagged"); 105 | MarkNativeAsOptional("BaseComm_IsClientMuted"); 106 | MarkNativeAsOptional("BaseComm_SetClientGag"); 107 | MarkNativeAsOptional("BaseComm_SetClientMute"); 108 | } 109 | #endif 110 | -------------------------------------------------------------------------------- /include/caster_system.inc: -------------------------------------------------------------------------------- 1 | #if defined _caster_system_included 2 | #endinput 3 | #endif 4 | #define _caster_system_included 5 | 6 | /** 7 | * If this in-game and fully connected client is a caster or not 8 | * 9 | * @return True if this is a registered caster 10 | */ 11 | native bool IsClientCaster(int client); 12 | 13 | /** 14 | * If this Steam ID is a registered caster or not 15 | * 16 | * @param String containing the user's auth id 17 | * @return True if this is a registered caster 18 | */ 19 | native bool IsIDCaster(const char[] AuthID); 20 | 21 | public SharedPlugin __pl_caster_system = 22 | { 23 | name = "caster_system", 24 | file = "caster_system.smx", 25 | #if defined REQUIRE_PLUGIN 26 | required = 1, 27 | #else 28 | required = 0, 29 | #endif 30 | }; 31 | 32 | #if !defined REQUIRE_PLUGIN 33 | public void __pl_caster_system_SetNTVOptional() 34 | { 35 | MarkNativeAsOptional("IsClientCaster"); 36 | MarkNativeAsOptional("IsIDCaster"); 37 | } 38 | #endif -------------------------------------------------------------------------------- /include/code_patcher.inc: -------------------------------------------------------------------------------- 1 | #if defined codepatcher_inc_ 2 | #endinput 3 | #endif 4 | #define codepatcher_inc_ 5 | 6 | native bool IsPatchApplied(const char[] name); 7 | 8 | native Address GetPatchAddress(const char[] name); 9 | 10 | native bool IsPlatformWindows(); 11 | 12 | forward void OnPatchApplied(const char[] name); 13 | 14 | public SharedPlugin __pl_code_patcher = 15 | { 16 | name = "code_patcher", 17 | file = "code_patcher.smx", 18 | #if defined REQUIRE_PLUGIN 19 | required = 1, 20 | #else 21 | required = 0, 22 | #endif 23 | }; 24 | 25 | #if !defined REQUIRE_PLUGIN 26 | public void __pl_code_patcher_SetNTVOptional() 27 | { 28 | MarkNativeAsOptional("IsPatchApplied"); 29 | MarkNativeAsOptional("GetPatchAddress"); 30 | MarkNativeAsOptional("IsPlatformWindows"); 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /include/collisionhook.inc: -------------------------------------------------------------------------------- 1 | #if defined _collisionhook_included 2 | #endinput 3 | #endif 4 | #define _collisionhook_included 5 | 6 | 7 | // called when the game is performing vphysics collision checks between entities 8 | // return something other than Plugin_Continue to have the game use the result parameter 9 | forward Action CH_ShouldCollide(int ent1, int ent2, bool &result); 10 | 11 | // called when the game performs collision checks through traces (only for traces using filters) 12 | // return something other than Plugin_Continue to have the game use the result parameter 13 | // note: any code in this forward should be very performant, the game will use many filtered traces per player per game frame 14 | forward Action CH_PassFilter(int ent1, int ent2, bool &result); 15 | 16 | 17 | public Extension __ext_collisionhook = 18 | { 19 | name = "CollisionHook", 20 | file = "collisionhook.ext", 21 | 22 | #if defined AUTOLOAD_EXTENSIONS 23 | autoload = 1, 24 | #else 25 | autoload = 0, 26 | #endif 27 | #if defined REQUIRE_EXTENSIONS 28 | required = 1, 29 | #else 30 | required = 0, 31 | #endif 32 | 33 | }; -------------------------------------------------------------------------------- /include/commandline.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _commandline_included_ 34 | #endinput 35 | #endif 36 | #define _commandline_included_ 37 | 38 | /** 39 | * Gets the full command line the server was launched with. 40 | * 41 | * @param commandLine Buffer to store the command line in. 42 | * @param maxlen Maximum length of the command line buffer. 43 | * @return True if the command line is valid; otherwise, false. 44 | * @error No command line available, or no mod support. 45 | */ 46 | native bool GetCommandLine(char[] commandLine, int maxlen); 47 | 48 | /** 49 | * Gets the value of a command line parameter the server was launched with. 50 | * 51 | * @param param The command line parameter to get the value of. 52 | * @param value Buffer to store the parameter value in. 53 | * @param maxlen Maximum length of the value buffer. 54 | * @param defValue The default value to return if the parameter wasn't specified. 55 | * @error No command line available, or no mod support. 56 | */ 57 | native void GetCommandLineParam(const char[] param, char[] value, int maxlen, const char[] defValue=""); 58 | 59 | /** 60 | * Gets the value of a command line parameter the server was launched with. 61 | * 62 | * @param param The command line parameter to get the value of. 63 | * @param defValue The default value to return if the parameter wasn't specified. 64 | * @return The integer value of the command line parameter value. 65 | * @error No command line available, or no mod support. 66 | */ 67 | native int GetCommandLineParamInt(const char[] param, int defValue=0); 68 | 69 | /** 70 | * Gets the value of a command line parameter the server was launched with. 71 | * 72 | * @param param The command line parameter to get the value of. 73 | * @param defValue The default value to return if the parameter wasn't specified. 74 | * @return The floating point value of the command line parameter value. 75 | * @error No command line available, or no mod support. 76 | */ 77 | native float GetCommandLineParamFloat(const char[] param, float defValue=0.0); 78 | 79 | /** 80 | * Determines if a specific command line parameter is present. 81 | * 82 | * @param param The command line parameter to test. 83 | * @return True if the command line parameter is specified; otherwise, false. 84 | * @error No command line available, or no mod support. 85 | */ 86 | native bool FindCommandLineParam(const char[] param); 87 | -------------------------------------------------------------------------------- /include/connect.inc: -------------------------------------------------------------------------------- 1 | #if defined _connect_included 2 | #endinput 3 | #endif 4 | #define _connect_included 5 | 6 | forward bool OnClientPreConnectEx(const char[] name, char password[255], const char[] ip, const char[] steamID, char rejectReason[255]); 7 | 8 | public Extension __ext_Connect = 9 | { 10 | name = "Connect", 11 | file = "connect.ext", 12 | #if defined AUTOLOAD_EXTENSIONS 13 | autoload = 1, 14 | #else 15 | autoload = 0, 16 | #endif 17 | #if defined REQUIRE_EXTENSIONS 18 | required = 1, 19 | #else 20 | required = 0, 21 | #endif 22 | } -------------------------------------------------------------------------------- /include/gamerules.inc: -------------------------------------------------------------------------------- 1 | #if defined _gamerules_included 2 | #endinput 3 | #endif 4 | #define _gamerules_included 5 | 6 | enum RoundState { 7 | // initialize the game, create teams 8 | RoundState_Init, 9 | 10 | //Before players have joined the game. Periodically checks to see if enough players are ready 11 | //to start a game. Also reverts to this when there are no active players 12 | RoundState_Pregame, 13 | 14 | //The game is about to start, wait a bit and spawn everyone 15 | RoundState_StartGame, 16 | 17 | //All players are respawned, frozen in place 18 | RoundState_Preround, 19 | 20 | //Round is on, playing normally 21 | RoundState_RoundRunning, 22 | 23 | //Someone has won the round 24 | RoundState_TeamWin, 25 | 26 | //Noone has won, manually restart the game, reset scores 27 | RoundState_Restart, 28 | 29 | //Noone has won, restart the game 30 | RoundState_Stalemate, 31 | 32 | //Game is over, showing the scoreboard etc 33 | RoundState_GameOver, 34 | 35 | //Game is over, doing bonus round stuff 36 | RoundState_Bonus, 37 | }; 38 | 39 | /* 40 | * Gets or Sets a GameRules prop. 41 | * size is auto-detected. paramter is only used if auto-detection fails 42 | * element is element number in array if prop is array 43 | * changeState when setting will propagate change over net to clients 44 | */ 45 | native GameRules_GetProp(const String:prop[], size=4, element=0); 46 | native Float:GameRules_GetPropFloat(const String:prop[], element=0); 47 | 48 | native GameRules_SetProp(const String:prop[], value, size=4, element=0, bool:changeState=false); 49 | native GameRules_SetPropFloat(const String:prop[], Float:value, element=0, bool:changeState=false); 50 | 51 | stock bool:GameRules_GetPropBool(const String:prop[], element=0) 52 | { 53 | return bool:(GameRules_GetProp(prop, 1, element) & 1); 54 | } 55 | 56 | stock GameRules_SetPropBool(const String:prop[], bool:value, element=0, bool:changeState=false) 57 | { 58 | GameRules_SetProp(prop, _:value, 1, element, changeState); 59 | } 60 | 61 | // For 'teamplayroundbased' games (ex. not-CS:S) 62 | stock RoundState:GameRules_GetRoundState() 63 | { 64 | return RoundState:GameRules_GetProp("m_iRoundState"); 65 | } 66 | 67 | stock Float:GameRules_GetTimeUntilRndReset() 68 | { 69 | new Float:flRestartTime = GameRules_GetPropFloat("m_flRestartRoundTime"); 70 | if (flRestartTime == -1.0) 71 | return flRestartTime; 72 | 73 | return flRestartTime - GetGameTime(); 74 | } 75 | 76 | stock Float:GameRules_GetTimeBetweenSpawns(team) 77 | { 78 | return GameRules_GetPropFloat("m_TeamRespawnWaveTimes", team); 79 | } 80 | 81 | stock Float:GameRules_GetNextSpawnTime(team) 82 | { 83 | return GameRules_GetPropFloat("m_flNextRespawnWave", team); 84 | } 85 | 86 | stock GameRules_SetTimeBetweenSpawns(team, Float:time) 87 | { 88 | GameRules_SetPropFloat("m_TeamRespawnWaveTimes", time, team, true); 89 | } 90 | 91 | stock GameRules_SetNextSpawnTime(team, Float:time) 92 | { 93 | GameRules_SetPropFloat("m_flNextRespawnWave", time, team, true); 94 | } 95 | 96 | public Extension:__ext_gamerules = 97 | { 98 | name = "GameRules Tools", 99 | file = "gamerules.ext", 100 | #if defined REQUIRE_EXTENSIONS 101 | required = 1, 102 | #else 103 | required = 0, 104 | #endif 105 | #if defined AUTOLOAD_EXTENSIONS 106 | autoload = 1, 107 | #else 108 | autoload = 0, 109 | #endif 110 | }; 111 | 112 | #if !defined REQUIRE_EXTENSIONS 113 | public __ext_gamerules_SetNTVOptional() 114 | { 115 | MarkNativeAsOptional("GameRules_GetProp"); 116 | MarkNativeAsOptional("GameRules_GetPropFloat"); 117 | MarkNativeAsOptional("GameRules_SetProp"); 118 | MarkNativeAsOptional("GameRules_SetPropFloat"); 119 | } 120 | #endif 121 | -------------------------------------------------------------------------------- /include/godframecontrol.inc: -------------------------------------------------------------------------------- 1 | #if defined _godframecontrol_included_ 2 | #endinput 3 | #endif 4 | #define _godframecontrol_included_ 5 | 6 | /** 7 | * Gives a specified client god frames for x amount of time 8 | * 9 | * @param client The client to give godframes to. 10 | * @param time Amount of times the godframes will last. 11 | * @param time The ZClass of the attacker. 12 | * @return True if successful, false otherwise. 13 | */ 14 | native void GiveClientGodFrames(int client, float time, int zclass); 15 | 16 | public SharedPlugin __pl_godframecontrol = 17 | { 18 | name = "l4d2_godframes_control_merge", 19 | file = "l4d2_godframes_control_merge.smx", 20 | #if defined REQUIRE_PLUGIN 21 | required = 1, 22 | #else 23 | required = 0, 24 | #endif 25 | }; 26 | 27 | #if !defined REQUIRE_PLUGIN 28 | public void __pl_godframecontrol_SetNTVOptional() 29 | { 30 | MarkNativeAsOptional("GiveClientGodFrames"); 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /include/handles.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _handles_included 34 | #endinput 35 | #endif 36 | #define _handles_included 37 | 38 | /** 39 | * Preset Handle values. 40 | */ 41 | enum Handle // Tag disables introducing "Handle" as a symbol. 42 | { 43 | INVALID_HANDLE = 0 44 | }; 45 | 46 | 47 | /** 48 | * Closes a Handle. If the handle has multiple copies open, 49 | * it is not destroyed unless all copies are closed. 50 | * 51 | * @note Closing a Handle has a different meaning for each Handle type. Make 52 | * sure you read the documentation on whatever provided the Handle. 53 | * 54 | * @param hndl Handle to close. 55 | * @error Invalid handles will cause a run time error. 56 | */ 57 | native void CloseHandle(Handle hndl); 58 | 59 | /** 60 | * Clones a Handle. When passing handles in between plugins, caching handles 61 | * can result in accidental invalidation when one plugin releases the Handle, or is its owner 62 | * is unloaded from memory. To prevent this, the Handle may be "cloned" with a new owner. 63 | * 64 | * @note Usually, you will be cloning Handles for other plugins. This means that if you clone 65 | * the Handle without specifying the new owner, it will assume the identity of your original 66 | * calling plugin, which is not very useful. You should either specify that the receiving 67 | * plugin should clone the handle on its own, or you should explicitly clone the Handle 68 | * using the receiving plugin's identity Handle. 69 | * 70 | * @param hndl Handle to clone/duplicate. 71 | * @param plugin Optional Handle to another plugin to mark as the new owner. 72 | * If no owner is passed, the owner becomes the calling plugin. 73 | * @return Handle on success, INVALID_HANDLE if not cloneable. 74 | * @error Invalid handles will cause a run time error. 75 | */ 76 | native Handle CloneHandle(Handle hndl, Handle plugin=INVALID_HANDLE); 77 | 78 | using __intrinsics__.Handle; 79 | 80 | /** 81 | * Do not use this function. Returns if a Handle and its contents 82 | * are readable, whereas INVALID_HANDLE only checks for the absence 83 | * of a Handle. 84 | * 85 | * This function is intended only for tests where the validity of a 86 | * Handle can absolutely not be known. 87 | * 88 | * Do not use this to check the return values of functions, or to 89 | * check if timers should be closed (except in very rare cases). 90 | * This function is for very specific usage and using it for general 91 | * purpose routines can and will hide very subtle bugs. 92 | * 93 | * @param hndl Handle to test for validity. 94 | * @return True if handle is valid, false otherwise. 95 | * @deprecated Do not use this function. 96 | */ 97 | #pragma deprecated Do not use this function. 98 | native bool IsValidHandle(Handle hndl); 99 | -------------------------------------------------------------------------------- /include/holdout_bonus.inc: -------------------------------------------------------------------------------- 1 | #if defined _holdoutbonus_included_ 2 | #endinput 3 | #endif 4 | #define _holdoutbonus_included_ 5 | 6 | 7 | /** 8 | * Called when a holdout bonus is set up for the round. This will be 9 | * called once for each versus roundhalf, when the round goes live (or 10 | * survivors leave saferoom). 11 | * 12 | * @param int bonus the amount of points in the total bonus 13 | * @param int distance the (new) distance for the map 14 | * @param int time the time duration of the event in seconds 15 | * @param bool distanceChanged whether the distance has been altered by holdout_bonus 16 | */ 17 | forward OnHoldOutBonusSet( bonus, distance, time, bool:distanceChanged ); 18 | 19 | /** 20 | * Called whenever a holdout bonus event starts. 21 | * 22 | * @param int time the total time duration of the event in seconds 23 | */ 24 | forward OnHoldOutBonusStart( time ); 25 | 26 | /** 27 | * Called whenever a holdout bonus event ends. This can be either due to the 28 | * survivors surviving the event, or by them wiping during it. 29 | * 30 | * @param int bonus the actual bonus awarded to the survivors 31 | * @param int time the time the survivors managed to survive 32 | */ 33 | forward OnHoldOutBonusEnd( bonus, time ); 34 | 35 | 36 | 37 | public SharedPlugin:__pl_holdoutbonus = 38 | { 39 | name = "holdout_bonus", 40 | file = "holdout_bonus.smx", 41 | #if defined REQUIRE_PLUGIN 42 | required = 1, 43 | #else 44 | required = 0, 45 | #endif 46 | }; -------------------------------------------------------------------------------- /include/l4d2_boss_percents.inc: -------------------------------------------------------------------------------- 1 | /* 2 | ** https://github.com/spoon-l4d2/Plugins 3 | */ 4 | 5 | #if defined _l4d2_boss_percents_included 6 | #endinput 7 | #endif 8 | #define _l4d2_boss_percents_included 9 | 10 | /** 11 | * @brief Set the tank as "disabled" on the ready up, and when the !boss command is used. 12 | * @remarks YOU NEED TO SET THIS EVERY MAP. 13 | * 14 | * @param disable Boolean to set 15 | * 16 | * @noreturn 17 | */ 18 | native void SetTankDisabled(bool disable); 19 | 20 | /** 21 | * @brief Set the witch as "disabled" on the ready up, and when the !boss command is used. 22 | * @remarks YOU NEED TO SET THIS EVERY MAP. 23 | * 24 | * @param disable Boolean to set 25 | * 26 | * @noreturn 27 | */ 28 | native void SetWitchDisabled(bool disable); 29 | 30 | /** 31 | * @brief Update the boss percentages. 32 | * 33 | * @noreturn 34 | */ 35 | native void UpdateBossPercents(); 36 | 37 | /** 38 | * @brief Get the stored tank percent. 39 | * 40 | * @return Integer of the percentage, 0 if spawn disabled or spawn static, -1 if unsupported game. 41 | */ 42 | native int GetStoredTankPercent(); 43 | 44 | /** 45 | * @brief Get the stored witch percent. 46 | * 47 | * @return Integer of the percentage, 0 if spawn disabled or spawn static, -1 if unsupported game. 48 | */ 49 | native int GetStoredWitchPercent(); 50 | 51 | /** 52 | * @brief Get the ready footer index of the boss percents. 53 | * @remarks Safe to use no matter readyup is available or not. 54 | * 55 | * @return Index of the ready up footer, -1 if readyup is not available. 56 | */ 57 | native int GetReadyUpFooterIndex(); 58 | 59 | /** 60 | * @brief Refresh the boss percents on the ready up. 61 | * @remarks All hooks are removed on map change. 62 | * 63 | * @return True on success, false if readyup is not available. 64 | */ 65 | native bool RefreshBossPercentReadyUp(); 66 | 67 | /** 68 | * @brief Check if the current map is Dark Carnival: Remix. 69 | * @remarks Dark Carnival: Remix uses built-in custom boss system, which is not the usual way that the game performs. 70 | * 71 | * @return True if current map is Dark Carnival: Remix, false otherwise. 72 | */ 73 | native bool IsDarkCarniRemix(); 74 | 75 | 76 | public SharedPlugin __pl_l4d2_boss_percents = 77 | { 78 | name = "l4d_boss_percent", 79 | file = "l4d_boss_percent.smx", 80 | #if defined REQUIRE_PLUGIN 81 | required = 1, 82 | #else 83 | required = 0, 84 | #endif 85 | }; 86 | 87 | #if !defined REQUIRE_PLUGIN 88 | public void __pl_l4d2_boss_percents_SetNTVOptional() 89 | { 90 | MarkNativeAsOptional("SetTankDisabled"); 91 | MarkNativeAsOptional("SetWitchDisabled"); 92 | MarkNativeAsOptional("UpdateBossPercents"); 93 | MarkNativeAsOptional("GetStoredTankPercent"); 94 | MarkNativeAsOptional("GetStoredWitchPercent"); 95 | MarkNativeAsOptional("GetReadyUpFooterIndex"); 96 | MarkNativeAsOptional("RefreshBossPercentReadyUp"); 97 | MarkNativeAsOptional("IsDarkCarniRemix"); 98 | } 99 | #endif -------------------------------------------------------------------------------- /include/l4d2_changelevel.inc: -------------------------------------------------------------------------------- 1 | /* 2 | * https://github.com/LuxLuma/Left-4-fix 3 | */ 4 | 5 | #if defined _l4d2_changelevel_included 6 | #endinput 7 | #endif 8 | #define _l4d2_changelevel_included 9 | 10 | /** 11 | * @param sMapName Map String without .bsp 12 | * @param bShouldResetScores Reset all scores in all gamemodes 13 | * @noreturn 14 | */ 15 | native void L4D2_ChangeLevel(const char[] sMapName, bool bShouldResetScores=true); 16 | 17 | public SharedPlugin __pl_l4d2_changelevel = 18 | { 19 | name = "l4d2_changelevel", 20 | file = "l4d2_changelevel.smx", 21 | #if defined REQUIRE_PLUGIN 22 | required = 1, 23 | #else 24 | required = 0, 25 | #endif 26 | }; 27 | 28 | #if !defined REQUIRE_PLUGIN 29 | public void __pl_l4d2_changelevel_SetNTVOptional() 30 | { 31 | MarkNativeAsOptional("L4D2_ChangeLevel"); 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /include/l4d2_health_temp_bonus.inc: -------------------------------------------------------------------------------- 1 | #if defined _l4d2_health_temp_bonus_included 2 | #endinput 3 | #endif 4 | #define _l4d2_health_temp_bonus_included 5 | 6 | native int SMNext_GetPermBonus(); 7 | native int SMNext_GetTempBonus(); 8 | native int SMNext_GetPillsBonus(); 9 | native int SMNext_GetMaxPermBonus(); 10 | native int SMNext_GetMaxTempBonus(); 11 | native int SMNext_GetMaxPillsBonus(); 12 | 13 | public SharedPlugin __pl_l4d2_health_temp_bonus = 14 | { 15 | name = "l4d2_health_temp_bonus", 16 | file = "l4d2_health_temp_bonus.smx", 17 | #if defined REQUIRE_PLUGIN 18 | required = 1, 19 | #else 20 | required = 0, 21 | #endif 22 | }; 23 | 24 | #if !defined REQUIRE_PLUGIN 25 | public void __pl_l4d2_health_temp_bonus_SetNTVOptional() 26 | { 27 | MarkNativeAsOptional("SMNext_GetPermBonus"); 28 | MarkNativeAsOptional("SMNext_GetTempBonus"); 29 | MarkNativeAsOptional("SMNext_GetPillsBonus"); 30 | MarkNativeAsOptional("SMNext_GetMaxPermBonus"); 31 | MarkNativeAsOptional("SMNext_GetMaxTempBonus"); 32 | MarkNativeAsOptional("SMNext_GetMaxPillsBonus"); 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /include/l4d2_hittable_control.inc: -------------------------------------------------------------------------------- 1 | #if defined _l4d2_hittable_control_included 2 | #endinput 3 | #endif 4 | #define _l4d2_hittable_control_included 5 | 6 | /** 7 | * @brief Returns if forklifts are set to be unbreakable 8 | * 9 | * @return True on forklifts set to not break, false otherwise. 10 | */ 11 | native bool AreForkliftsUnbreakable(); 12 | 13 | public SharedPlugin __pl_l4d2_hittable_control = 14 | { 15 | name = "l4d2_hittable_control", 16 | file = "l4d2_hittable_control.smx", 17 | #if defined REQUIRE_PLUGIN 18 | required = 1, 19 | #else 20 | required = 0, 21 | #endif 22 | }; 23 | 24 | #if !defined REQUIRE_PLUGIN 25 | public void __pl_l4d2_hittable_control_SetNTVOptional() 26 | { 27 | MarkNativeAsOptional("AreForkliftsUnbreakable"); 28 | } 29 | #endif -------------------------------------------------------------------------------- /include/l4d2_hybrid_scoremod.inc: -------------------------------------------------------------------------------- 1 | #if defined _l4d2_hybrid_scoremod 2 | #endinput 3 | #endif 4 | #define _l4d2_hybrid_scoremod 5 | 6 | native int SMPlus_GetHealthBonus(); 7 | native int SMPlus_GetDamageBonus(); 8 | native int SMPlus_GetPillsBonus(); 9 | native int SMPlus_GetMaxHealthBonus(); 10 | native int SMPlus_GetMaxDamageBonus(); 11 | native int SMPlus_GetMaxPillsBonus(); 12 | 13 | public SharedPlugin __pl_l4d2_hybrid_scoremod = 14 | { 15 | name = "l4d2_hybrid_scoremod", 16 | file = "l4d2_hybrid_scoremod.smx", 17 | #if defined REQUIRE_PLUGIN 18 | required = 1, 19 | #else 20 | required = 0, 21 | #endif 22 | }; 23 | 24 | #if !defined REQUIRE_PLUGIN 25 | public void __pl_l4d2_hybrid_scoremod_SetNTVOptional() 26 | { 27 | MarkNativeAsOptional("SMPlus_GetHealthBonus"); 28 | MarkNativeAsOptional("SMPlus_GetDamageBonus"); 29 | MarkNativeAsOptional("SMPlus_GetPillsBonus"); 30 | MarkNativeAsOptional("SMPlus_GetMaxHealthBonus"); 31 | MarkNativeAsOptional("SMPlus_GetMaxDamageBonus"); 32 | MarkNativeAsOptional("SMPlus_GetMaxPillsBonus"); 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /include/l4d2_penalty_bonus.inc: -------------------------------------------------------------------------------- 1 | /* 2 | Includes for Penalty bonus system (l4d2_penalty_bonus) 3 | ------------------------------------------------------ 4 | */ 5 | 6 | /** 7 | * Called when a round is about to end. 8 | * The update value is passed by reference and increased by any plugin using this forward 9 | * before the next. Do an update += and return the new update. 10 | * PBonus will apply the last value of that update to the round's penalty bonus (without reporting). 11 | * 12 | * @param int update (by reference) the value of the cumulative update PBonus needs to know 13 | * @return int the update value to add to the round's bonus 14 | */ 15 | forward OnHoldOutBonusSet( &update ); 16 | 17 | 18 | // Get the bonus for the current round 19 | // returns int 20 | native PBONUS_GetRoundBonus(); 21 | 22 | // Resets the bonus for the current round to 0 (does not do a change-report!) 23 | native PBONUS_ResetRoundBonus(); 24 | 25 | // Set the bonus for the current round 26 | native PBONUS_SetRoundBonus(bonus); 27 | 28 | // Adds points to the bonus for the current round 29 | native PBONUS_AddRoundBonus(bonus, bool:bNoReport=false); 30 | 31 | // Get the amount of defibs used in the current round 32 | // returns int 33 | native PBONUS_GetDefibsUsed(); 34 | 35 | // Set the (current) defib penalty 36 | native PBONUS_SetDefibPenalty(penalty); 37 | -------------------------------------------------------------------------------- /include/l4d2_playstats.inc: -------------------------------------------------------------------------------- 1 | #if defined _playstats_included_ 2 | #endinput 3 | #endif 4 | #define _playstats_included_ 5 | 6 | native void PLAYSTATS_BroadcastRoundStats(); 7 | native void PLAYSTATS_BroadcastGameStats(); 8 | 9 | public SharedPlugin __pl_l4d2lib = 10 | { 11 | name = "l4d2_playstats", 12 | file = "l4d2_playstats.smx", 13 | #if defined REQUIRE_PLUGIN 14 | required = 1, 15 | #else 16 | required = 0, 17 | #endif 18 | }; 19 | 20 | #if !defined REQUIRE_PLUGIN 21 | public void __pl_l4d2lib_SetNTVOptional() 22 | { 23 | MarkNativeAsOptional("PLAYSTATS_BroadcastRoundStats"); 24 | MarkNativeAsOptional("PLAYSTATS_BroadcastGameStats"); 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /include/l4d2_saferoom_detect.inc: -------------------------------------------------------------------------------- 1 | /* 2 | SourcePawn is Copyright (C) 2006-2008 AlliedModders LLC. All rights reserved. 3 | SourceMod is Copyright (C) 2006-2008 AlliedModders LLC. All rights reserved. 4 | Pawn and SMALL are Copyright (C) 1997-2008 ITB CompuPhase. 5 | Source is Copyright (C) Valve Corporation. 6 | All trademarks are property of their respective owners. 7 | 8 | This program is free software: you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the 10 | Free Software Foundation, either version 3 of the License, or (at your 11 | option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program. If not, see . 20 | */ 21 | #if defined l4d2_saferoom_detect_inc_ 22 | #endinput 23 | #endif 24 | #define l4d2_saferoom_detect_inc_ 25 | 26 | /* 27 | Check if entity is in a saferoom 28 | returns bool (errors/incorrect data returns false) 29 | */ 30 | native bool SAFEDETECT_IsEntityInStartSaferoom(int entity); 31 | native bool SAFEDETECT_IsEntityInEndSaferoom(int entity); 32 | 33 | /* 34 | Check if player (client) is in a saferoom 35 | returns bool (errors/incorrect data returns false) 36 | */ 37 | native bool SAFEDETECT_IsPlayerInStartSaferoom(int client); 38 | native bool SAFEDETECT_IsPlayerInEndSaferoom(int client); 39 | 40 | public SharedPlugin __pl_l4d2_saferoom_detect = 41 | { 42 | name = "l4d2_saferoom_detect", 43 | file = "l4d2_saferoom_detect.smx", 44 | #if defined REQUIRE_PLUGIN 45 | required = 1, 46 | #else 47 | required = 0, 48 | #endif 49 | }; 50 | 51 | #if !defined REQUIRE_PLUGIN 52 | public void __pl_l4d2_saferoom_detect_SetNTVOptional() 53 | { 54 | MarkNativeAsOptional("SAFEDETECT_IsEntityInStartSaferoom"); 55 | MarkNativeAsOptional("SAFEDETECT_IsEntityInEndSaferoom"); 56 | MarkNativeAsOptional("SAFEDETECT_IsPlayerInStartSaferoom"); 57 | MarkNativeAsOptional("SAFEDETECT_IsPlayerInEndSaferoom"); 58 | } 59 | #endif 60 | -------------------------------------------------------------------------------- /include/l4d2_scoremod.inc: -------------------------------------------------------------------------------- 1 | #if defined _l4d2_scoremod_included 2 | #endinput 3 | #endif 4 | #define _l4d2_scoremod_included 5 | 6 | native int HealthBonus(); 7 | 8 | public SharedPlugin __pl_l4d2_scoremod = 9 | { 10 | name = "l4d2_scoremod", 11 | file = "l4d2_scoremod.smx", 12 | #if defined REQUIRE_PLUGIN 13 | required = 1, 14 | #else 15 | required = 0, 16 | #endif 17 | }; 18 | 19 | #if !defined REQUIRE_PLUGIN 20 | public void __pl_l4d2_scoremod_SetNTVOptional() 21 | { 22 | MarkNativeAsOptional("HealthBonus"); 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /include/l4d2_sequence.txt: -------------------------------------------------------------------------------- 1 | "Games" 2 | { 3 | "left4dead2" 4 | { 5 | "Offsets" 6 | { 7 | "CTerrorPlayer::SelectWeightedSequence" 8 | { 9 | "windows" "207" 10 | "linux" "208" 11 | } 12 | "CTerrorPlayer::DoAnimationEvent" 13 | { 14 | "windows" "510" 15 | "linux" "511" 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /include/l4d2director.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * Left 4 Downtown 2 SourceMod Extension 5 | * Copyright (C) 2010 Michael "ProdigySim" Busby 6 | * ============================================================================= 7 | * 8 | * This program is free software; you can redistribute it and/or modify it under 9 | * the terms of the GNU General Public License, version 3.0, as published by the 10 | * Free Software Foundation. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 15 | * details. 16 | * 17 | * You should have received a copy of the GNU General Public License along with 18 | * this program. If not, see . 19 | * 20 | * As a special exception, AlliedModders LLC gives you permission to link the 21 | * code of this program (as well as its derivative works) to "Half-Life 2," the 22 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 23 | * by the Valve Corporation. You must obey the GNU General Public License in 24 | * all respects for all other code used. Additionally, AlliedModders LLC grants 25 | * this exception to all derivative works. AlliedModders LLC defines further 26 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 27 | * or . 28 | * 29 | * Version: $Id$ 30 | */ 31 | 32 | #if defined _l4d2director_included 33 | #endinput 34 | #endif 35 | #define _l4d2director_included 36 | 37 | /** 38 | * @brief Gets the number of tanks currently in play. 39 | * @remarks This value is tracked by the director, and should be a good 40 | * indicator that a tank is in play 41 | * 42 | * @return current tank count 43 | */ 44 | native int L4D2_GetTankCount(); 45 | 46 | /** 47 | * @brief Gets the number of witches currently in play. 48 | * @remarks This value is tracked by the director, and should be a good 49 | * indicator that a witch is in play 50 | * 51 | * @return current witch count 52 | */ 53 | native int L4D2_GetWitchCount(); 54 | 55 | /** 56 | * @brief Gets the campaign scores stored in the Versus Director 57 | * @remarks These are the actual values used for campaign scores--not proxies 58 | * 59 | * @param scores Array to store the campaign scores in 60 | * @noreturn 61 | */ 62 | native void L4D2_GetVersusCampaignScores(int scores[2]); 63 | 64 | /** 65 | * @brief Sets the campaign scores stored in the Versus Director 66 | * @remarks These are the actual values used for campaign scores--not proxies 67 | * 68 | * @param scores Array of campaign scores to set the director's values to. 69 | * @noreturn 70 | */ 71 | native void L4D2_SetVersusCampaignScores(const int scores[2]); 72 | 73 | /** 74 | * @brief Gets the flow percent for tank spawns for both versus rounds. 75 | * @remarks These values are checked against as the survivors move through the 76 | * map. Once they are passed, the tank spawns. Note that this is flow 77 | * as a percent of the map's flow, not flow distance. 78 | * 79 | * @param tankFlows Array to store the Tank Spawn Flow percents in 80 | * @noreturn 81 | */ 82 | native void L4D2_GetVersusTankFlowPercent(float tankFlows[2]); 83 | 84 | /** 85 | * @brief Sets the flow percent for tank spawns for both versus rounds. 86 | * @remarks These values are checked against as the survivors move through the 87 | * map. Once they are passed, the tank spawns. Note that this is flow 88 | * as a percent of the map's flow, not flow distance. 89 | * 90 | * @param tankFlows Array of Tank Spawn Flow percents to store in director 91 | * @noreturn 92 | */ 93 | native void L4D2_SetVersusTankFlowPercent(const float tankFlows[2]); 94 | 95 | /** 96 | * @brief Gets the flow percent for witch spawns for both versus rounds. 97 | * @remarks These values are checked against as the survivors move through the 98 | * map. Once they are passed, the witch spawns. Note that this is flow 99 | * as a percent of the map's flow, not flow distance. 100 | * 101 | * @param witchFlows Array to store the Witch Spawn Flow percents in 102 | * @noreturn 103 | */ 104 | native void L4D2_GetVersusWitchFlowPercent(float witchFlows[2]); 105 | 106 | /** 107 | * @brief Sets the flow percent for witch spawns for both versus rounds. 108 | * @remarks These values are checked against as the survivors move through the 109 | * map. Once they are passed, the witch spawns. Note that this is flow 110 | * as a percent of the map's flow, not flow distance. 111 | * 112 | * @param witchFlows Array of Witch Spawn Flow percents to store in director 113 | * @noreturn 114 | */ 115 | native void L4D2_SetVersusWitchFlowPercent(const float witchFlows[2]); 116 | 117 | -------------------------------------------------------------------------------- /include/l4d2util.inc: -------------------------------------------------------------------------------- 1 | #if defined l4d2util_inc_ 2 | #endinput 3 | #endif 4 | #define l4d2util_inc_ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | -------------------------------------------------------------------------------- /include/l4d2util_rounds.inc: -------------------------------------------------------------------------------- 1 | #if defined l4d2util_rounds_inc_ 2 | #endinput 3 | #endif 4 | #define l4d2util_rounds_inc_ 5 | 6 | #include 7 | 8 | /** 9 | * Is the second round of this map currently being played? 10 | * 11 | * @return bool 12 | */ 13 | stock bool InSecondHalfOfRound() 14 | { 15 | return view_as(GameRules_GetProp("m_bInSecondHalfOfRound")); 16 | } 17 | -------------------------------------------------------------------------------- /include/l4d2util_stocks.inc: -------------------------------------------------------------------------------- 1 | #if defined l4d2util_stocks_inc_ 2 | #endinput 3 | #endif 4 | #define l4d2util_stocks_inc_ 5 | 6 | #include 7 | 8 | //Author - A1m` 9 | 10 | stock bool IsValidClientIndex(int client) 11 | { 12 | return (client > 0 && client <= MaxClients); 13 | } 14 | 15 | stock int L4D2Util_GetMin(int a, int b) 16 | { 17 | return (a < b) ? a : b; 18 | } 19 | 20 | stock int L4D2Util_GetMax(int a, int b) 21 | { 22 | return (a > b) ? a : b; 23 | } 24 | 25 | stock float L4D2Util_GetMinFloat(float a, float b) 26 | { 27 | return (a < b) ? a : b; 28 | } 29 | 30 | stock float L4D2Util_GetMaxFloat(float a, float b) 31 | { 32 | return (a > b) ? a : b; 33 | } 34 | 35 | stock float L4D2Util_ClampFloat(float inc, float low, float high) 36 | { 37 | return (inc > high) ? high : ((inc < low) ? low : inc); 38 | } 39 | 40 | stock int L4D2Util_Clamp(int inc, int low, int high) 41 | { 42 | return (inc > high) ? high : ((inc < low) ? low : inc); 43 | } 44 | 45 | stock int L4D2Util_IntToPercentInt(int iVar, int iVarMax) 46 | { 47 | if (iVar > iVarMax) { 48 | return 100; 49 | } else if (iVar < 1) { 50 | return 0; 51 | } 52 | 53 | return RoundToNearest((float(iVar) / float(iVarMax)) * 100.0); 54 | } 55 | 56 | stock float L4D2Util_IntToPercentFloat(int iVar, int iVarMax) 57 | { 58 | if (iVar > iVarMax) { 59 | return 100.0; 60 | } else if (iVar < 1) { 61 | return 0.0; 62 | } 63 | 64 | return ((float(iVar) / float(iVarMax)) * 100.0); 65 | } 66 | 67 | stock float L4D2Util_FloatToPercentFloat(float iVar, float iVarMax) 68 | { 69 | if (iVar > iVarMax) { 70 | return 100.0; 71 | } else if (iVar < 1) { 72 | return 0.0; 73 | } 74 | 75 | return ((iVar / iVarMax) * 100.0); 76 | } 77 | 78 | stock int L4D2Util_FloatToPercentInt(float iVar, float iVarMax) 79 | { 80 | if (iVar > iVarMax) { 81 | return 100; 82 | } else if (iVar < 1) { 83 | return 0; 84 | } 85 | 86 | return RoundToNearest((iVar / iVarMax) * 100.0); 87 | } 88 | 89 | stock void String_ToLower(char[] str, const int MaxSize) 90 | { 91 | int iSize = strlen(str); //Сounts string length to zero terminator 92 | 93 | for (int i = 0; i < iSize && i < MaxSize; i++) { //more security, so that the cycle is not endless 94 | if (IsCharUpper(str[i])) { 95 | str[i] = CharToLower(str[i]); 96 | } 97 | } 98 | 99 | str[iSize] = '\0'; 100 | } 101 | 102 | stock void HitgroupToString(int iHitGroup, char[] sDestination, const int iMaxLength) 103 | { 104 | char sBuffer[32] = "GENERIC"; 105 | switch (iHitGroup) { 106 | case HITGROUP_GENERIC: { //0 107 | sBuffer = "generic"; 108 | } 109 | case HITGROUP_HEAD: { //1 110 | sBuffer = "head"; 111 | } 112 | case HITGROUP_CHEST: { //2 113 | sBuffer = "chest"; 114 | } 115 | case HITGROUP_STOMACH: { //3 116 | sBuffer = "stomach"; 117 | } 118 | case HITGROUP_LEFTARM: { //4 119 | sBuffer = "left arm"; 120 | } 121 | case HITGROUP_RIGHTARM: { //5 122 | sBuffer = "right arm"; 123 | } 124 | case HITGROUP_LEFTLEG: { //6 125 | sBuffer = "left leg"; 126 | } 127 | case HITGROUP_RIGHTLEG: { //7 128 | sBuffer = "right leg"; 129 | } 130 | case HITGROUP_GEAR: { //10 131 | sBuffer = "gear"; 132 | } 133 | } 134 | 135 | strcopy(sDestination, iMaxLength, sBuffer); 136 | } 137 | -------------------------------------------------------------------------------- /include/l4d2util_tanks.inc: -------------------------------------------------------------------------------- 1 | #if defined l4d2util_tanks_inc_ 2 | #endinput 3 | #endif 4 | #define l4d2util_tanks_inc_ 5 | 6 | #include 7 | 8 | /** 9 | * Is the player the tank? 10 | * 11 | * @param client client ID 12 | * @return bool 13 | */ 14 | stock bool IsTank(int client) 15 | { 16 | return (IsClientInGame(client) 17 | && GetClientTeam(client) == L4D2Team_Infected 18 | && GetEntProp(client, Prop_Send, "m_zombieClass") == L4D2Infected_Tank); 19 | } 20 | 21 | stock bool IsValidTank(int client) 22 | { 23 | return (IsValidClientIndex(client) && IsTank(client)); 24 | } 25 | 26 | /** 27 | * Is the tank able to punch the entity with the tank for instant incaps? 28 | * 29 | * @param iEntity entity ID 30 | * @return bool 31 | */ 32 | stock bool IsTankHittable(int iEntity) 33 | { 34 | if (!IsValidEntity(iEntity)) { 35 | return false; 36 | } 37 | 38 | char className[64]; 39 | GetEdictClassname(iEntity, className, sizeof(className)); 40 | 41 | if (strcmp(className, "prop_physics") == 0) { 42 | if (GetEntProp(iEntity, Prop_Send, "m_hasTankGlow", 1)) { 43 | return true; 44 | } 45 | } else if (strcmp(className, "prop_car_alarm") == 0) { 46 | return true; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Tanks frustation level in the range 0-100, where 100 is when the rage meter 54 | * is full. 55 | * 56 | * @param iTankClient tank's client ID 57 | * @return frustration level 58 | */ 59 | stock int GetTankFrustration(int iTankClient) 60 | { 61 | int iFrustration = 100 - GetEntProp(iTankClient, Prop_Send, "m_frustration"); 62 | 63 | return iFrustration; 64 | } 65 | 66 | /** 67 | * Sets the tank's frustration level. 68 | * 69 | * @param iTankClient tank's client ID 70 | * @param iFrustration frustration level (0-100) 71 | * @noreturn 72 | */ 73 | stock void SetTankFrustration(int iTankClient, int iFrustration) 74 | { 75 | if (iFrustration < 0 || iFrustration > 100) { 76 | ThrowError("Native SetTankFrustration. Invalid parameter passed: %d", iFrustration); 77 | } 78 | 79 | int iSetFrustration = 100 - iFrustration; 80 | SetEntProp(iTankClient, Prop_Send, "m_frustration", iSetFrustration); 81 | } 82 | 83 | /** 84 | * Returns true if the entity or player is on fire. 85 | * 86 | * @param entity entity index 87 | * @return bool 88 | */ 89 | stock bool IsEntityOnFire(int entity) 90 | { 91 | return ((GetEntityFlags(entity) & FL_ONFIRE) != 0); 92 | } 93 | 94 | /** 95 | * Searches for a player who is in control of a tank. 96 | * 97 | * @param iTankClient client index to begin searching from 98 | * @return client ID or -1 if not found 99 | */ 100 | stock int FindTankClient(int iTankClient) 101 | { 102 | int i = (iTankClient < 0) ? 1 : iTankClient + 1; 103 | 104 | for (; i <= MaxClients; i++) { 105 | if (IsTank(i)) { 106 | return i; 107 | } 108 | } 109 | 110 | return -1; 111 | } 112 | 113 | /** 114 | * Searches for a live player who is in control of a tank. 115 | * 116 | * @param iTankClient client index to begin searching from 117 | * @return client ID or -1 if not found 118 | */ 119 | stock int FindAliveTankClient() 120 | { 121 | for (int i = 1; i <= MaxClients; i++) { 122 | if (IsTank(i) && IsPlayerAlive(i)) { 123 | return i; 124 | } 125 | } 126 | 127 | return -1; 128 | } 129 | 130 | /** 131 | * Is there a tank currently in play? 132 | * 133 | * @return bool 134 | */ 135 | stock bool IsTankInPlay() 136 | { 137 | return (FindTankClient(-1) != -1); 138 | } 139 | 140 | /** 141 | * Counts the number of tanks currently in play. 142 | * 143 | * @return number of tanks in play 144 | */ 145 | stock int NumTanksInPlay() 146 | { 147 | int count = 0; 148 | for (int i = 1; i <= MaxClients; i++) { 149 | if (IsTank(i)) { 150 | count++; 151 | } 152 | } 153 | 154 | return count; 155 | } 156 | -------------------------------------------------------------------------------- /include/l4d_boss_vote.inc: -------------------------------------------------------------------------------- 1 | #if defined _l4d_boss_vote_included 2 | #endinput 3 | #endif 4 | #define _l4d_boss_vote_included 5 | 6 | /** 7 | * @brief Called when the boss percents are updated. 8 | * @remarks Triggered via boss votes, force tanks, force witches. 9 | * @remarks Special value: -1 indicates ignored in change, 0 disabled (no spawn). 10 | */ 11 | forward void OnUpdateBosses(int iTankFlow, int iWitchFlow); 12 | 13 | public SharedPlugin __pl_l4d_boss_vote = 14 | { 15 | name = "l4d_boss_vote", 16 | file = "l4d_boss_vote.smx", 17 | #if defined REQUIRE_PLUGIN 18 | required = 1, 19 | #else 20 | required = 0, 21 | #endif 22 | }; -------------------------------------------------------------------------------- /include/l4d_tank_control_eq.inc: -------------------------------------------------------------------------------- 1 | #if defined _l4d_tank_control_eq_included 2 | #endinput 3 | #endif 4 | #define _l4d_tank_control_eq_included 5 | 6 | /** 7 | * @brief Retrieves the selected tank's client index. 8 | * 9 | * @return Client id of the selected tank, -1 if no one is selected. 10 | */ 11 | native int GetTankSelection(); 12 | 13 | public SharedPlugin __pl_l4d_tank_control_eq = 14 | { 15 | name = "l4d_tank_control_eq", 16 | file = "l4d_tank_control_eq.smx", 17 | #if defined REQUIRE_PLUGIN 18 | required = 1, 19 | #else 20 | required = 0, 21 | #endif 22 | }; 23 | 24 | #if !defined REQUIRE_PLUGIN 25 | public void __pl_l4d_tank_control_eq_SetNTVOptional() 26 | { 27 | MarkNativeAsOptional("GetTankSelection"); 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /include/lang.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _lang_included 34 | #endinput 35 | #endif 36 | #define _lang_included 37 | 38 | #define LANG_SERVER 0 /**< Translate using the server's language */ 39 | 40 | /** 41 | * Loads a translation file for the plugin calling this native. 42 | * If no extension is specified, .txt is assumed. 43 | * 44 | * @param file Translation file. 45 | */ 46 | native void LoadTranslations(const char[] file); 47 | 48 | /** 49 | * Sets the global language target. This is useful for creating functions 50 | * that will be compatible with the %t format specifier. Note that invalid 51 | * indexes can be specified but the error will occur during translation, 52 | * not during this function call. 53 | * 54 | * @param client Client index or LANG_SERVER. 55 | */ 56 | native void SetGlobalTransTarget(int client); 57 | 58 | /** 59 | * Retrieves the language number of a client. 60 | * 61 | * @param client Client index. 62 | * @return Language number client is using. 63 | * @error Invalid client index or client not connected. 64 | */ 65 | native int GetClientLanguage(int client); 66 | 67 | /** 68 | * Retrieves the server's language. 69 | * 70 | * @return Language number server is using. 71 | */ 72 | native int GetServerLanguage(); 73 | 74 | /** 75 | * Returns the number of languages known in languages.cfg. 76 | * 77 | * @return Language count. 78 | */ 79 | native int GetLanguageCount(); 80 | 81 | /** 82 | * Retrieves info about a given language number. 83 | * 84 | * @param language Language number. 85 | * @param code Language code buffer (2-3 characters usually). 86 | * @param codeLen Maximum length of the language code buffer. 87 | * @param name Language name buffer. 88 | * @param nameLen Maximum length of the language name buffer. 89 | * @error Invalid language number. 90 | */ 91 | native void GetLanguageInfo(int language, char[] code="", int codeLen=0, char[] name="", int nameLen=0); 92 | 93 | /** 94 | * Sets the language number of a client. 95 | * 96 | * @param client Client index. 97 | * @param language Language number. 98 | * @error Invalid client index or client not connected. 99 | */ 100 | native void SetClientLanguage(int client, int language); 101 | 102 | /** 103 | * Retrieves the language number from a language code. 104 | * 105 | * @param code Language code (2-3 characters usually). 106 | * @return Language number. -1 if not found. 107 | */ 108 | native int GetLanguageByCode(const char[] code); 109 | 110 | /** 111 | * Retrieves the language number from a language name. 112 | * 113 | * @param name Language name (case insensitive). 114 | * @return Language number. -1 if not found. 115 | */ 116 | native int GetLanguageByName(const char[] name); 117 | 118 | /** 119 | * Determines if the specified phrase exists within the plugin's 120 | * translation cache. 121 | * 122 | * @param phrase Phrase to look for. 123 | * @return True if phrase exists. 124 | */ 125 | native bool TranslationPhraseExists(const char[] phrase); 126 | 127 | /** 128 | * Determines if there is a translation for the specified language. 129 | * 130 | * @param phrase Phrase to check. 131 | * @param language Language number. 132 | * @return True if translation exists. 133 | */ 134 | native bool IsTranslatedForLanguage(const char[] phrase, int language); 135 | -------------------------------------------------------------------------------- /include/left4framework.inc: -------------------------------------------------------------------------------- 1 | #if defined __LEFT4FRAMEWORK_INCLUDED 2 | #endinput 3 | #endif 4 | #define __LEFT4FRAMEWORK_INCLUDED 5 | 6 | // This include is needed to support the compile of plugins on both left4downtown and left4dhooks 7 | 8 | #define LEFT4DHOOKS 1 9 | #define LEFT4DOWNTOWN 2 10 | 11 | #define FRAMEWORK_VERSION LEFT4DHOOKS 12 | 13 | #if FRAMEWORK_VERSION == LEFT4DHOOKS 14 | #if !defined LEFT4FRAMEWORK_GAMEDATA_ONLY 15 | #include 16 | #endif 17 | 18 | #define LEFT4FRAMEWORK_GAMEDATA "left4dhooks.l4d2" 19 | #define LEFT4DIRECT_GAMEDATA LEFT4FRAMEWORK_GAMEDATA 20 | #else 21 | #if !defined LEFT4FRAMEWORK_GAMEDATA_ONLY 22 | #if defined LEFT4FRAMEWORK_INCLUDE 23 | #include 24 | #endif 25 | 26 | #if defined L4D2_DIRECT_INCLUDE 27 | #include 28 | #endif 29 | #endif 30 | 31 | #define LEFT4FRAMEWORK_GAMEDATA "left4downtown.l4d2" 32 | #define LEFT4DIRECT_GAMEDATA "l4d2_direct" 33 | #endif 34 | -------------------------------------------------------------------------------- /include/lerpmonitor.inc: -------------------------------------------------------------------------------- 1 | #if defined _lerpmonitor 2 | #endinput 3 | #endif 4 | #define _lerpmonitor 5 | 6 | /** 7 | * @brief Get the player's saved lerp value 8 | * @param client Client index 9 | * 10 | * @return -1.0 if the current lerp time has not been saved, otherwise current lerp value 11 | * @error If the client is not connected or the index is invalid. 12 | */ 13 | native float LM_GetLerpTime(int client); 14 | 15 | /** 16 | * @brief Get the player's current lerp 17 | * @param client Client index 18 | * 19 | * @return Current lerp value 20 | * @error Invalid client index, or client not connected. 21 | */ 22 | native float LM_GetCurrentLerpTime(int client); 23 | 24 | public SharedPlugin __lerpmonitor = 25 | { 26 | name = "LerpMonitor++", 27 | file = "lerpmonitor.smx", 28 | #if defined REQUIRE_PLUGIN 29 | required = 1 30 | #else 31 | required = 0 32 | #endif 33 | }; 34 | 35 | #if !defined REQUIRE_PLUGIN 36 | public void __pl_lerpmonitor_SetNTVOptional() 37 | { 38 | MarkNativeAsOptional("NM_GetLerpTime"); 39 | MarkNativeAsOptional("LM_GetCurrentLerpTime"); 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /include/logging.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sm_logging_included 34 | #endinput 35 | #endif 36 | #define _sm_logging_included 37 | 38 | /** 39 | * Logs a plugin message to the SourceMod logs. The log message will be 40 | * prefixed by the plugin's logtag (filename). 41 | * 42 | * @param format String format. 43 | * @param ... Format arguments. 44 | */ 45 | native void LogMessage(const char[] format, any ...); 46 | 47 | /** 48 | * Logs a message to any file. The log message will be in the normal 49 | * SourceMod format, with the plugin logtag prepended. 50 | * 51 | * @param file File to write the log message in. 52 | * @param format String format. 53 | * @param ... Format arguments. 54 | * @error File could not be opened/written. 55 | */ 56 | native void LogToFile(const char[] file, const char[] format, any ...); 57 | 58 | /** 59 | * Same as LogToFile(), except no plugin logtag is prepended. 60 | * 61 | * @param file File to write the log message in. 62 | * @param format String format. 63 | * @param ... Format arguments. 64 | * @error File could not be opened/written. 65 | */ 66 | native void LogToFileEx(const char[] file, const char[] format, any ...); 67 | 68 | /** 69 | * Logs an action from a command or event whereby interception and routing may 70 | * be important. This is intended to be a logging version of ShowActivity(). 71 | * 72 | * @param client Client performing the action, 0 for server, or -1 if not 73 | * applicable. 74 | * @param target Client being targetted, or -1 if not applicable. 75 | * @param message Message format. 76 | * @param ... Message formatting parameters. 77 | */ 78 | native void LogAction(int client, int target, const char[] message, any ...); 79 | 80 | /** 81 | * Logs a plugin error message to the SourceMod logs. 82 | * 83 | * @param format String format. 84 | * @param ... Format arguments. 85 | */ 86 | native void LogError(const char[] format, any ...); 87 | 88 | /** 89 | * Called when an action is going to be logged. 90 | * 91 | * @param source Handle to the object logging the action, or INVALID_HANDLE 92 | * if Core is logging the action. 93 | * @param ident Type of object logging the action (plugin, ext, or core). 94 | * @param client Client the action is from; 0 for server, -1 if not applicable. 95 | * @param target Client the action is targetting, or -1 if not applicable. 96 | * @param message Message that is being logged. 97 | * @return Plugin_Continue will perform the default logging behavior. 98 | * Plugin_Handled will stop Core from logging the message. 99 | * Plugin_Stop is the same as Handled, but prevents any other 100 | * plugins from handling the message. 101 | */ 102 | forward Action OnLogAction(Handle source, 103 | Identity ident, 104 | int client, 105 | int target, 106 | const char[] message); 107 | 108 | /** 109 | * Called when a game log message is received. 110 | * 111 | * Any Log*() functions called within this callback will not recursively 112 | * pass through. That is, they will log directly, bypassing this callback. 113 | * 114 | * Note that this does not capture log messages from the engine. It only 115 | * captures log messages being sent from the game/mod itself. 116 | * 117 | * @param message Message contents. 118 | * @return Plugin_Handled or Plugin_Stop will prevent the message 119 | * from being written to the log file. 120 | */ 121 | typedef GameLogHook = function Action (const char[] message); 122 | 123 | /** 124 | * Adds a game log hook. 125 | * 126 | * @param hook Hook function. 127 | */ 128 | native void AddGameLogHook(GameLogHook hook); 129 | 130 | /** 131 | * Removes a game log hook. 132 | * 133 | * @param hook Hook function. 134 | */ 135 | native void RemoveGameLogHook(GameLogHook hook); 136 | -------------------------------------------------------------------------------- /include/nextmap.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2014 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _nextmap_included_ 34 | #endinput 35 | #endif 36 | #define _nextmap_included_ 37 | 38 | /** 39 | * Sets SourceMod's internal nextmap. 40 | * Equivalent to changing sm_nextmap but with an added validity check. 41 | * 42 | * @param map Next map to set. 43 | * @return True if the nextmap was set, false if map was invalid. 44 | */ 45 | native bool SetNextMap(const char[] map); 46 | 47 | /** 48 | * Returns SourceMod's internal nextmap. 49 | * 50 | * @param map Buffer to store the nextmap name. 51 | * @param maxlen Maximum length of the map buffer. 52 | * @return True if a Map was found and copied, false if no nextmap is set (map will be unchanged). 53 | */ 54 | native bool GetNextMap(char[] map, int maxlen); 55 | 56 | /** 57 | * Changes the current map and records the reason for the change with maphistory 58 | * 59 | * @param map Map to change to. 60 | * @param reason Reason for change. 61 | */ 62 | native void ForceChangeLevel(const char[] map, const char[] reason); 63 | 64 | /** 65 | * Gets the current number of maps in the map history 66 | * 67 | * @return Number of maps. 68 | */ 69 | native int GetMapHistorySize(); 70 | 71 | /** 72 | * Retrieves a map from the map history list. 73 | * 74 | * @param item Item number. Must be 0 or greater and less than GetMapHistorySize(). 75 | * @param map Buffer to store the map name. 76 | * @param mapLen Length of map buffer. 77 | * @param reason Buffer to store the change reason. 78 | * @param reasonLen Length of the reason buffer. 79 | * @param startTime Time the map started. 80 | * @error Invalid item number. 81 | */ 82 | native void GetMapHistory(int item, char[] map, int mapLen, char[] reason, int reasonLen, int &startTime); 83 | -------------------------------------------------------------------------------- /include/pause.inc: -------------------------------------------------------------------------------- 1 | /* 2 | SourcePawn is Copyright (C) 2006-2008 AlliedModders LLC. All rights reserved. 3 | SourceMod is Copyright (C) 2006-2008 AlliedModders LLC. All rights reserved. 4 | Pawn and SMALL are Copyright (C) 1997-2008 ITB CompuPhase. 5 | Source is Copyright (C) Valve Corporation. 6 | All trademarks are property of their respective owners. 7 | 8 | This program is free software: you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the 10 | Free Software Foundation, either version 3 of the License, or (at your 11 | option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program. If not, see . 20 | */ 21 | #if defined _pause_included_ 22 | #endinput 23 | #endif 24 | #define _pause_included_ 25 | 26 | /** 27 | * Called when a pause starts 28 | * If delayed pauses are on this will be called when the delay ends and the 29 | * pause actually begins 30 | */ 31 | forward void OnPause(); 32 | 33 | /** 34 | * Called when the pause ends and the round goes live 35 | */ 36 | forward void OnUnpause(); 37 | 38 | /** 39 | * Returns if the game is currently paused from this pause plugin. 40 | * This can't tell you if it is paused from another plugin on manual pause 41 | * 42 | * @return Current pause state 43 | */ 44 | native bool IsInPause(); 45 | 46 | public SharedPlugin __pl_pause = 47 | { 48 | name = "pause", 49 | file = "pause.smx", 50 | #if defined REQUIRE_PLUGIN 51 | required = 1, 52 | #else 53 | required = 0, 54 | #endif 55 | }; 56 | 57 | #if !defined REQUIRE_PLUGIN 58 | public void __pl_pause_SetNTVOptional() 59 | { 60 | MarkNativeAsOptional("IsInPause"); 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /include/profiler.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2018 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _profiler_included 34 | #endinput 35 | #endif 36 | #define _profiler_included 37 | 38 | /** 39 | * ONLY AVAILABLE ON WINDOWS RIGHT NOW K. 40 | */ 41 | 42 | methodmap Profiler < Handle 43 | { 44 | // Creates a new profile object. The Handle must be freed 45 | // using delete or CloseHandle(). 46 | // 47 | // @return A new Profiler Handle. 48 | public native Profiler(); 49 | 50 | // Starts a cycle for profiling. 51 | public native void Start(); 52 | 53 | // Stops a cycle for profiling. 54 | // 55 | // @error Profiler was never started. 56 | public native void Stop(); 57 | 58 | // Returns the amount of high-precision time in seconds 59 | // that passed during the profiler's last start/stop 60 | // cycle. 61 | // 62 | // @return Time elapsed in seconds. 63 | property float Time { 64 | public native get(); 65 | } 66 | }; 67 | 68 | /** 69 | * Creates a new profile object. The Handle must be freed 70 | * using delete or CloseHandle(). 71 | * 72 | * @return Handle to the profiler object. 73 | */ 74 | native Profiler CreateProfiler(); 75 | 76 | /** 77 | * Starts profiling. 78 | * 79 | * @param prof Profiling object. 80 | * @error Invalid Handle. 81 | */ 82 | native void StartProfiling(Handle prof); 83 | 84 | /** 85 | * Stops profiling. 86 | * 87 | * @param prof Profiling object. 88 | * @error Invalid Handle or profiling was never started. 89 | */ 90 | native void StopProfiling(Handle prof); 91 | 92 | /** 93 | * Returns the amount of high-precision time in seconds 94 | * that passed during the profiler's last start/stop 95 | * cycle. 96 | * 97 | * @param prof Profiling object. 98 | * @return Time elapsed in seconds. 99 | * @error Invalid Handle. 100 | */ 101 | native float GetProfilerTime(Handle prof); 102 | 103 | /** 104 | * Mark the start of a profiling event. 105 | * 106 | * @param group Budget group. This can be "all" for a default, or a short 107 | * description like "Timers" or "Events". 108 | * @param name A name to attribute to this profiling event. 109 | */ 110 | native void EnterProfilingEvent(const char[] group, const char[] name); 111 | 112 | /** 113 | * Mark the end of the last profiling event. This must be called in the same 114 | * stack frame as StartProfilingEvent(). Not doing so, or throwing errors, 115 | * will make the resulting profile very wrong. 116 | */ 117 | native void LeaveProfilingEvent(); 118 | 119 | /** 120 | * Returns true if the global profiler is enabled; false otherwise. It is 121 | * not necessary to call this before Enter/LeaveProfilingEvent. 122 | */ 123 | native bool IsProfilingActive(); 124 | -------------------------------------------------------------------------------- /include/readyup.inc: -------------------------------------------------------------------------------- 1 | /* 2 | SourcePawn is Copyright (C) 2006-2008 AlliedModders LLC. All rights reserved. 3 | SourceMod is Copyright (C) 2006-2008 AlliedModders LLC. All rights reserved. 4 | Pawn and SMALL are Copyright (C) 1997-2008 ITB CompuPhase. 5 | Source is Copyright (C) Valve Corporation. 6 | All trademarks are property of their respective owners. 7 | 8 | This program is free software: you can redistribute it and/or modify it 9 | under the terms of the GNU General Public License as published by the 10 | Free Software Foundation, either version 3 of the License, or (at your 11 | option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program. If not, see . 20 | */ 21 | #if defined _readyup_included_ 22 | #endinput 23 | #endif 24 | #define _readyup_included_ 25 | 26 | /** 27 | * Called before ready up is initiated 28 | */ 29 | forward void OnReadyUpInitiatePre(); 30 | 31 | /** 32 | * Called when ready up is initiated 33 | */ 34 | forward void OnReadyUpInitiate(); 35 | 36 | /** 37 | * Called before the live countdown starts 38 | */ 39 | forward void OnRoundLiveCountdownPre(); 40 | 41 | /** 42 | * Called when the live countdown starts 43 | */ 44 | forward void OnRoundLiveCountdown(); 45 | 46 | /** 47 | * Called before the live countdown ends and the round goes live 48 | */ 49 | forward void OnRoundIsLivePre(); 50 | 51 | /** 52 | * Called when the live countdown ends and the round goes live 53 | */ 54 | forward void OnRoundIsLive(); 55 | 56 | /** 57 | * Returns the index of a item in the footer array. 58 | * Does not have to be exact. The footer only needs to contain the input, does not need to match. 59 | * 60 | * @param index Index of string 61 | * @param buffer Where to store result 62 | * @param maxlength Max length of buffer 63 | * @return String at specified index 64 | */ 65 | native int GetFooterStringAtIndex(int index, char[] buffer, int maxlength); 66 | 67 | /** 68 | * Returns the index of a item in the footer array. 69 | * Does not have to be exact. The footer only needs to contain the input, does not need to match. 70 | * 71 | * @param string String to search for 72 | * @return Int index of string 73 | */ 74 | native int FindIndexOfFooterString(const char[] string); 75 | 76 | /** 77 | * Edits a footer string on the ready-up panel at the specified index. 78 | * 79 | * @param index Index of string to edit 80 | * @param string String to add to the footer 81 | * @return True if the string was added, false otherwise 82 | */ 83 | native bool EditFooterStringAtIndex(int index, const char[] string); 84 | 85 | /** 86 | * Adds the string to the bottom of the ready-up panel. 87 | * String must be <=65 characters including the null byte. 88 | * String will be entirely added or not added, no truncation. 89 | * 90 | * @param footer String to add to the footer 91 | * @return Int Index of string in footer. 92 | */ 93 | native int AddStringToReadyFooter(const char[] footer); 94 | 95 | /** 96 | * Whether or not the game is currently waiting for players to ready up. 97 | * 98 | * @return True if the game is currently in the ready-up phase. 99 | */ 100 | native bool IsInReady(); 101 | 102 | /** 103 | * @brief Toggle ready panel of one target or all clients. 104 | * @remarks Always return false if currently not in ready-up phase. 105 | * 106 | * @return True if no target if specified, or previous ready panel state of target. 107 | */ 108 | native bool ToggleReadyPanel(bool show, int target = 0); 109 | 110 | public SharedPlugin __pl_readyup = 111 | { 112 | name = "readyup", 113 | file = "readyup.smx", 114 | #if defined REQUIRE_PLUGIN 115 | required = 1, 116 | #else 117 | required = 0, 118 | #endif 119 | }; 120 | 121 | #if !defined REQUIRE_PLUGIN 122 | public void __pl_readyup_SetNTVOptional() 123 | { 124 | MarkNativeAsOptional("GetFooterStringAtIndex"); 125 | MarkNativeAsOptional("FindIndexOfFooterString"); 126 | MarkNativeAsOptional("EditFooterStringAtIndex"); 127 | MarkNativeAsOptional("AddStringToReadyFooter"); 128 | MarkNativeAsOptional("IsInReady"); 129 | MarkNativeAsOptional("ToggleReadyPanel"); 130 | } 131 | #endif -------------------------------------------------------------------------------- /include/rounds.inc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined __rounds__ 4 | #endinput 5 | #endif 6 | #define __rounds__ 7 | 8 | /* Global Vars */ 9 | new Handle:hFwdRoundStart; 10 | new Handle:hFwdRoundEnd; 11 | 12 | 13 | static iRoundNumber=0; 14 | static bool:bInRound; 15 | 16 | Rounds_OnRoundStart_Update() 17 | { 18 | if(!bInRound) 19 | { 20 | bInRound=true; 21 | iRoundNumber++; 22 | Call_StartForward(hFwdRoundStart); 23 | Call_PushCell(iRoundNumber); 24 | Call_Finish(); 25 | 26 | } 27 | } 28 | 29 | Rounds_OnRoundEnd_Update() 30 | { 31 | if(bInRound) 32 | { 33 | bInRound=false; 34 | Call_StartForward(hFwdRoundEnd); 35 | Call_PushCell(iRoundNumber); 36 | Call_Finish(); 37 | } 38 | } 39 | 40 | 41 | Rounds_OnMapEnd_Update() 42 | { 43 | iRoundNumber=0; 44 | bInRound=false; 45 | } 46 | 47 | GetCurrentRound() 48 | { 49 | return iRoundNumber; 50 | } 51 | 52 | bool:CurrentlyInRound() 53 | { 54 | return bInRound; 55 | } 56 | -------------------------------------------------------------------------------- /include/rounds_l4d2util.inc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | new bool:bInRound = false; 4 | 5 | static Handle:hFwdOnRoundStart; 6 | static Handle:hFwdOnRoundEnd; 7 | 8 | L4D2Util_Rounds_OnMapEnd() { 9 | bInRound = false; 10 | } 11 | 12 | L4D2Util_Rounds_OnRoundStart() { 13 | if (!bInRound) { 14 | bInRound = true; 15 | Call_StartForward(hFwdOnRoundStart); 16 | Call_Finish(); 17 | } 18 | } 19 | 20 | L4D2Util_Rounds_OnRoundEnd() { 21 | if (bInRound) { 22 | bInRound = false; 23 | Call_StartForward(hFwdOnRoundEnd); 24 | Call_Finish(); 25 | } 26 | } 27 | 28 | L4D2Util_Rounds_CreateForwards() { 29 | hFwdOnRoundStart = CreateGlobalForward("OnRoundStart", ET_Ignore); 30 | hFwdOnRoundEnd = CreateGlobalForward("OnRoundEnd", ET_Ignore); 31 | } 32 | -------------------------------------------------------------------------------- /include/sdktools_client.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_client_included 34 | #endinput 35 | #endif 36 | #define _sdktools_client_included 37 | 38 | /** 39 | * Sets the client to an inactive state waiting for a new map 40 | * 41 | * @param client The client index 42 | * @error Invalid client index. 43 | */ 44 | native void InactivateClient(int client); 45 | 46 | /** 47 | * Reconnect a client without dropping the netchannel 48 | * 49 | * @param client The client index 50 | * @error Invalid client index. 51 | */ 52 | native void ReconnectClient(int client); 53 | -------------------------------------------------------------------------------- /include/sdktools_engine.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_engine_included 34 | #endinput 35 | #endif 36 | #define _sdktools_engine_included 37 | 38 | #define MAX_LIGHTSTYLES 64 39 | 40 | /** 41 | * Sets a client's "viewing entity." 42 | * 43 | * @param client Client index. 44 | * @param entity Entity index. 45 | * @error Invalid client or entity, lack of mod support, or client not in 46 | * game. 47 | */ 48 | native void SetClientViewEntity(int client, int entity); 49 | 50 | /** 51 | * Sets a light style. 52 | * 53 | * @param style Light style (from 0 to MAX_LIGHTSTYLES-1) 54 | * @param value Light value string (see world.cpp/light.cpp in dlls) 55 | * @error Light style index is out of range. 56 | */ 57 | native void SetLightStyle(int style, const char[] value); 58 | 59 | /** 60 | * Returns the client's eye position. 61 | * 62 | * @param client Player's index. 63 | * @param pos Destination vector to store the client's eye position. 64 | * @error Invalid client index, client not in game, or no mod support. 65 | */ 66 | native void GetClientEyePosition(int client, float pos[3]); 67 | -------------------------------------------------------------------------------- /include/sdktools_entinput.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2017 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_entinput_included 34 | #endinput 35 | #endif 36 | #define _sdktools_entinput_included 37 | 38 | /** 39 | * Invokes a named input method on an entity. 40 | * 41 | * After completion (successful or not), the current global variant is re-initialized. 42 | * 43 | * @param dest Destination entity index. 44 | * @param input Input action. 45 | * @param activator Entity index which initiated the sequence of actions (-1 for a NULL entity). 46 | * @param caller Entity index from which this event is sent (-1 for a NULL entity). 47 | * @param outputid Unknown. 48 | * @return True if successful otherwise false. 49 | * @error Invalid entity index or no mod support. 50 | */ 51 | native bool AcceptEntityInput(int dest, const char[] input, int activator=-1, int caller=-1, int outputid=0); 52 | -------------------------------------------------------------------------------- /include/sdktools_entoutput.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2017 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_entoutput_included 34 | #endinput 35 | #endif 36 | #define _sdktools_entoutput_included 37 | 38 | /** 39 | * Called when an entity output is fired. 40 | * 41 | * @param output Name of the output that fired. 42 | * @param caller Entity index of the caller. 43 | * @param activator Entity index of the activator. 44 | * @param delay Delay in seconds? before the event gets fired. 45 | * @return Anything other than Plugin_Continue will supress this event, 46 | * returning Plugin_Continue will allow it to propagate the results 47 | * of this output to any entity inputs. 48 | */ 49 | typeset EntityOutput 50 | { 51 | function void (const char[] output, int caller, int activator, float delay); 52 | function Action (const char[] output, int caller, int activator, float delay); 53 | }; 54 | 55 | /** 56 | * Add an entity output hook on a entity classname 57 | * 58 | * @param classname The classname to hook. 59 | * @param output The output name to hook. 60 | * @param callback An EntityOutput function pointer. 61 | * @error Entity Outputs disabled. 62 | */ 63 | native void HookEntityOutput(const char[] classname, const char[] output, EntityOutput callback); 64 | 65 | /** 66 | * Remove an entity output hook. 67 | * @param classname The classname to hook. 68 | * @param output The output name to hook. 69 | * @param callback An EntityOutput function pointer. 70 | * @return True on success, false if no valid hook was found. 71 | * @error Entity Outputs disabled. 72 | */ 73 | native bool UnhookEntityOutput(const char[] classname, const char[] output, EntityOutput callback); 74 | 75 | /** 76 | * Add an entity output hook on a single entity instance 77 | * 78 | * @param entity The entity on which to add a hook. 79 | * @param output The output name to hook. 80 | * @param callback An EntityOutput function pointer. 81 | * @param once Only fire this hook once and then remove itself. 82 | * @error Entity Outputs disabled or Invalid Entity index. 83 | */ 84 | native void HookSingleEntityOutput(int entity, const char[] output, EntityOutput callback, bool once=false); 85 | 86 | /** 87 | * Remove a single entity output hook. 88 | * 89 | * @param entity The entity on which to remove the hook. 90 | * @param output The output name to hook. 91 | * @param callback An EntityOutput function pointer. 92 | * @return True on success, false if no valid hook was found. 93 | * @error Entity Outputs disabled or Invalid Entity index. 94 | */ 95 | native bool UnhookSingleEntityOutput(int entity, const char[] output, EntityOutput callback); 96 | 97 | /** 98 | * Fire a named output on an entity. 99 | * 100 | * After completion (successful or not), the current global variant is re-initialized. 101 | * 102 | * @param caller Entity index from where the output is fired. 103 | * @param output Output name. 104 | * @param activator Entity index which initiated the sequence of actions (-1 for a NULL entity). 105 | * @param delay Delay before firing the output. 106 | * @error Invalid entity index or no mod support. 107 | */ 108 | native void FireEntityOutput(int caller, const char[] output, int activator=-1, float delay=0.0); 109 | -------------------------------------------------------------------------------- /include/sdktools_stocks.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_stocks_included 34 | #endinput 35 | #endif 36 | #define _sdktools_stocks_included 37 | 38 | /** 39 | * Given a partial team name, attempts to find a matching team. 40 | * 41 | * The search is performed case insensitively and only against the 42 | * first N characters of the team names, where N is the number of 43 | * characters in the search pattern. 44 | * 45 | * @param name Partial or full team name. 46 | * @return A valid team index on success. 47 | * -1 if no team matched. 48 | * -2 if more than one team matched. 49 | */ 50 | stock int FindTeamByName(const char[] name) 51 | { 52 | int name_len = strlen(name); 53 | int num_teams = GetTeamCount(); 54 | char team_name[32]; 55 | int found_team = -1; 56 | 57 | for (int i = 0; i < num_teams; i++) 58 | { 59 | GetTeamName(i, team_name, sizeof(team_name)); 60 | 61 | if (strncmp(team_name, name, name_len, false) == 0) 62 | { 63 | if (found_team >= 0) 64 | { 65 | return -2; 66 | } 67 | else 68 | { 69 | found_team = i; 70 | } 71 | } 72 | } 73 | 74 | return found_team; 75 | } 76 | -------------------------------------------------------------------------------- /include/sdktools_variant_t.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2017 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_variant_t_included 34 | #endinput 35 | #endif 36 | #define _sdktools_variant_t_included 37 | 38 | /** 39 | * Sets a bool value in the global variant object. 40 | * 41 | * @param val Input value. 42 | */ 43 | native void SetVariantBool(bool val); 44 | 45 | /** 46 | * Sets a string in the global variant object. 47 | * 48 | * @param str Input string. 49 | */ 50 | native void SetVariantString(const char[] str); 51 | 52 | /** 53 | * Sets an integer value in the global variant object. 54 | * 55 | * @param val Input value. 56 | */ 57 | native void SetVariantInt(int val); 58 | 59 | /** 60 | * Sets a floating point value in the global variant object. 61 | * 62 | * @param val Input value. 63 | */ 64 | native void SetVariantFloat(float val); 65 | 66 | /** 67 | * Sets a 3D vector in the global variant object. 68 | * 69 | * @param vec Input vector. 70 | */ 71 | native void SetVariantVector3D(const float vec[3]); 72 | 73 | /** 74 | * Sets a 3D position vector in the global variant object. 75 | * 76 | * @param vec Input position vector. 77 | */ 78 | native void SetVariantPosVector3D(const float vec[3]); 79 | 80 | /** 81 | * Sets a color in the global variant object. 82 | * 83 | * @param color Input color. 84 | */ 85 | native void SetVariantColor(const int color[4]); 86 | 87 | /** 88 | * Sets an entity in the global variant object. 89 | * 90 | * @param entity Entity index. 91 | * @error Invalid entity index. 92 | */ 93 | native void SetVariantEntity(int entity); 94 | -------------------------------------------------------------------------------- /include/sdktools_voice.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _sdktools_voice_included 34 | #endinput 35 | #endif 36 | #define _sdktools_voice_included 37 | 38 | /** 39 | * @section voice flags. 40 | */ 41 | #define VOICE_NORMAL 0 /**< Allow the client to listen and speak normally. */ 42 | #define VOICE_MUTED 1 /**< Mutes the client from speaking to everyone. */ 43 | #define VOICE_SPEAKALL 2 /**< Allow the client to speak to everyone. */ 44 | #define VOICE_LISTENALL 4 /**< Allow the client to listen to everyone. */ 45 | #define VOICE_TEAM 8 /**< Allow the client to always speak to team, even when dead. */ 46 | #define VOICE_LISTENTEAM 16 /**< Allow the client to always hear teammates, including dead ones. */ 47 | 48 | /** 49 | * @endsection 50 | */ 51 | 52 | enum ListenOverride 53 | { 54 | Listen_Default = 0, /**< Leave it up to the game */ 55 | Listen_No, /**< Can't hear */ 56 | Listen_Yes /**< Can hear */ 57 | }; 58 | 59 | /** 60 | * Called when a client is speaking. 61 | * 62 | * @param client The client index 63 | */ 64 | forward void OnClientSpeaking(int client); 65 | 66 | /** 67 | * Called once a client speaking end. 68 | * 69 | * @param client The client index 70 | */ 71 | forward void OnClientSpeakingEnd(int client); 72 | 73 | /** 74 | * Set the client listening flags. 75 | * 76 | * @param client The client index 77 | * @param flags The voice flags 78 | * @error Invalid client index or client not connected. 79 | */ 80 | native void SetClientListeningFlags(int client, int flags); 81 | 82 | /** 83 | * Retrieve the client current listening flags. 84 | * 85 | * @param client The client index 86 | * @return The current voice flags 87 | * @error Invalid client index or client not connected. 88 | */ 89 | native int GetClientListeningFlags(int client); 90 | 91 | /** 92 | * Set the receiver ability to listen to the sender. 93 | * 94 | * @param iReceiver The listener index. 95 | * @param iSender The sender index. 96 | * @param bListen True if the receiver can listen to the sender, false otherwise. 97 | * @return True if successful otherwise false. 98 | * @deprecated Use SetListenOverride() instead. 99 | */ 100 | #pragma deprecated Use SetListenOverride() instead 101 | native bool SetClientListening(int iReceiver, int iSender, bool bListen); 102 | 103 | /** 104 | * Retrieves if the receiver can listen to the sender. 105 | * 106 | * @param iReceiver The listener index. 107 | * @param iSender The sender index. 108 | * @return True if successful otherwise false. 109 | * @deprecated GetListenOverride() instead. 110 | */ 111 | #pragma deprecated GetListenOverride() instead 112 | native bool GetClientListening(int iReceiver, int iSender); 113 | 114 | /** 115 | * Override the receiver's ability to listen to the sender. 116 | * 117 | * @param iReceiver The listener index. 118 | * @param iSender The sender index. 119 | * @param override The override of the receiver's ability to listen to the sender. 120 | * @return True if successful otherwise false. 121 | * @error Listener or sender client index is invalid or not connected. 122 | */ 123 | native bool SetListenOverride(int iReceiver, int iSender, ListenOverride override); 124 | 125 | /** 126 | * Retrieves the override of the receiver's ability to listen to the sender. 127 | * 128 | * @param iReceiver The listener index. 129 | * @param iSender The sender index. 130 | * @return The override value. 131 | * @error Listener or sender client index is invalid or not connected. 132 | */ 133 | native ListenOverride GetListenOverride(int iReceiver, int iSender); 134 | 135 | /** 136 | * Retrieves if the muter has muted the mutee. 137 | * 138 | * @param iMuter The muter index. 139 | * @param iMutee The mutee index. 140 | * @return True if muter has muted mutee, false otherwise. 141 | * @error Muter or mutee client index is invalid or not connected. 142 | */ 143 | native bool IsClientMuted(int iMuter, int iMutee); 144 | -------------------------------------------------------------------------------- /include/smac.inc: -------------------------------------------------------------------------------- 1 | /* 2 | SourceMod Anti-Cheat 3 | Copyright (C) 2011-2016 SMAC Development Team 4 | Copyright (C) 2007-2011 CodingDirect LLC 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #if defined _smac_included 21 | #endinput 22 | #endif 23 | #define _smac_included 24 | 25 | #include 26 | 27 | /* Globals */ 28 | #define SMAC_VERSION "0.8.7.3" 29 | #define SMAC_URL "https://github.com/Silenci0/SMAC" 30 | #define SMAC_AUTHOR "SMAC Development Team" 31 | #define SMAC_MOD_ERROR "This module will not work for this mod and should be removed." 32 | 33 | enum GameType 34 | { 35 | Game_Unknown = 0, 36 | Game_CSS, 37 | Game_TF2, 38 | Game_DODS, 39 | Game_INS, 40 | Game_L4D, 41 | Game_L4D2, 42 | Game_HL2DM, 43 | Game_FOF, 44 | Game_HL2CTF, 45 | Game_HIDDEN, 46 | Game_ND, 47 | Game_CSGO, 48 | Game_ZPS, 49 | Game_ZMR, 50 | Game_BM 51 | }; 52 | 53 | enum DetectionType 54 | { 55 | Detection_Unknown = 0, 56 | 57 | // smac_aimbot 58 | Detection_Aimbot = 100, 59 | 60 | // smac_autotrigger 61 | Detection_AutoTrigger = 200, 62 | 63 | // smac_client 64 | Detection_NameChangeSpam = 300, 65 | 66 | // smac_commands 67 | Detection_CommandSpamming = 400, 68 | Detection_BannedCommand, 69 | 70 | // smac_cvars 71 | Detection_CvarViolation = 500, 72 | 73 | // smac_eyetest 74 | Detection_UserCmdReuse = 600, 75 | Detection_UserCmdTamperingTickcount, 76 | Detection_UserCmdTamperingButtons, 77 | Detection_Eyeangles, 78 | 79 | // smac_speedhack 80 | Detection_Speedhack = 700, 81 | 82 | // smac_spinhack 83 | Detection_Spinhack = 800, 84 | 85 | // smac_eac_banlist 86 | Detection_GlobalBanned_EAC = 900, 87 | 88 | // smac_esea_banlist 89 | Detection_GlobalBanned_ESEA = 1000, 90 | 91 | // smac_hl2dm_fixes 92 | Detection_GravityGunExploit = 1100, 93 | }; 94 | 95 | /* Natives */ 96 | native GameType SMAC_GetGameType(); 97 | native void SMAC_Log(const char[] format, any ...); 98 | native void SMAC_LogAction(int client, const char[] format, any ...); 99 | native void SMAC_Ban(int client, const char[] reason, any ...); 100 | native void SMAC_PrintAdminNotice(const char[] format, any ...); 101 | native ConVar SMAC_CreateConVar(const char[] name, const char[] defaultValue, const char[] description="",int flags = 0, bool hasMin = false, float min = 0.0, bool hasMax = false, float max = 0.0); 102 | native Action SMAC_CheatDetected(int client, DetectionType type = Detection_Unknown, Handle info = INVALID_HANDLE); 103 | 104 | /* Forwards */ 105 | forward Action SMAC_OnCheatDetected(int client, const char[] module, DetectionType type, Handle info); 106 | 107 | public SharedPlugin __pl_smac = 108 | { 109 | name = "smac", 110 | file = "smac.smx", 111 | #if defined REQUIRE_PLUGIN 112 | required = 1, 113 | #else 114 | required = 0, 115 | #endif 116 | }; 117 | 118 | #if !defined REQUIRE_PLUGIN 119 | public void __pl_smac_SetNTVOptional() 120 | { 121 | MarkNativeAsOptional("SMAC_GetGameType"); 122 | MarkNativeAsOptional("SMAC_Log"); 123 | MarkNativeAsOptional("SMAC_LogAction"); 124 | MarkNativeAsOptional("SMAC_Ban"); 125 | MarkNativeAsOptional("SMAC_PrintAdminNotice"); 126 | MarkNativeAsOptional("SMAC_CreateConVar"); 127 | MarkNativeAsOptional("SMAC_CheatDetected"); 128 | } 129 | #endif 130 | -------------------------------------------------------------------------------- /include/smac_wallhack.inc: -------------------------------------------------------------------------------- 1 | /* 2 | SourceMod Anti-Cheat 3 | Copyright (C) 2011-2016 SMAC Development Team 4 | Copyright (C) 2007-2011 CodingDirect LLC 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | #if defined _smac_wallhack_included 20 | #endinput 21 | #endif 22 | #define _smac_wallhack_included 23 | 24 | /** 25 | * Sets whether to ignore a client from visibility tests. 26 | * Processing time for anti-wallhack will decrease with every ignored client. 27 | * 28 | * @param client Client index. 29 | * @param bIgnore If true, client will not undergo visibility tests. If false, results in default behavior. 30 | * @noreturn 31 | * @error If the client is not InGame or the index is invalid. 32 | */ 33 | native void SMAC_WH_SetClientIgnore(int client, bool bIgnore); 34 | 35 | /** 36 | * Returns whether a client is ignored from visibility tests. 37 | * 38 | * @param client Client index. 39 | * @return True if client is ignored from visibility tests, false otherwise. 40 | * @error If the client is not connected or the index is invalid. 41 | */ 42 | native bool SMAC_WH_GetClientIgnore(int client); 43 | 44 | 45 | public SharedPlugin:__pl_smac_wallhack = 46 | { 47 | name = "smac_wallhack", 48 | file = "smac_wallhack.smx", 49 | #if defined REQUIRE_PLUGIN 50 | required = 1, 51 | #else 52 | required = 0, 53 | #endif 54 | }; 55 | 56 | #if !defined REQUIRE_PLUGIN 57 | public __pl_smac_wallhack_SetNTVOptional() 58 | { 59 | MarkNativeAsOptional("SMAC_WH_SetClientIgnore"); 60 | MarkNativeAsOptional("SMAC_WH_GetClientIgnore"); 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /include/smlib.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_included 2 | #endinput 3 | #endif 4 | #define _smlib_included 5 | 6 | #define SMLIB_VERSION "0.9.7" 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | //#include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | -------------------------------------------------------------------------------- /include/smlib/arrays.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_array_included 2 | #endinput 3 | #endif 4 | #define _smlib_array_included 5 | 6 | #include 7 | 8 | /** 9 | * Returns the index for the first occurance of the given value. 10 | * If the value cannot be found, -1 will be returned. 11 | * 12 | * @param array Static Array. 13 | * @param size Size of the Array. 14 | * @param value Value to search for. 15 | * @param start Optional: Offset where to start (0 - (size-1)). 16 | * @return Array index, or -1 if the value couldn't be found. 17 | */ 18 | stock int Array_FindValue(const any[] array, int size, any value, int start=0) 19 | { 20 | if (start < 0) { 21 | start = 0; 22 | } 23 | 24 | for (int i=start; i < size; i++) { 25 | 26 | if (array[i] == value) { 27 | return i; 28 | } 29 | } 30 | 31 | return -1; 32 | } 33 | 34 | /** 35 | * Searchs for the first occurance of a string in the array. 36 | * If the value cannot be located, -1 will be returned. 37 | * 38 | * @param array Static Array. 39 | * @param size Size of the Array. 40 | * @param value String to search for. 41 | * @param start Optional: Offset where to start(0 - (size-1)). 42 | * @return Array index, or -1 if the value couldn't be found. 43 | */ 44 | stock int Array_FindString(const char[][] array, int size, const char[] str, bool caseSensitive=true, int start=0) 45 | { 46 | if (start < 0) { 47 | start = 0; 48 | } 49 | 50 | for (int i=start; i < size; i++) { 51 | 52 | if (StrEqual(array[i], str, caseSensitive)) { 53 | return i; 54 | } 55 | } 56 | 57 | return -1; 58 | } 59 | 60 | /** 61 | * Returns the Index of the Lowest value in the array 62 | * 63 | * @param array Static Array. 64 | * @param size Size of the Array. 65 | * @param start Optional: Offset where to start (0 - (size-1)). 66 | * @return Array index. 67 | */ 68 | stock int Array_FindLowestValue(const any[] array, int size, int start=0) 69 | { 70 | if (start < 0) { 71 | start = 0; 72 | } 73 | 74 | any value = array[start]; 75 | any tempValue; 76 | int x = start; 77 | 78 | for (int i=start; i < size; i++) { 79 | 80 | tempValue = array[i]; 81 | 82 | if (tempValue < value) { 83 | value = tempValue; 84 | x = i; 85 | } 86 | 87 | } 88 | 89 | return x; 90 | } 91 | 92 | /** 93 | * Returns the Index of the Highest value in the array 94 | * 95 | * @param array Static Array. 96 | * @param size Size of the Array. 97 | * @param start Optional: Offset where to start (0 - (size-1)). 98 | * @return Array index. 99 | */ 100 | stock int Array_FindHighestValue(const any[] array, int size, int start=0) 101 | { 102 | if (start < 0) { 103 | start = 0; 104 | } 105 | 106 | any value = array[start]; 107 | any tempValue; 108 | int x = start; 109 | 110 | for (int i=start; i < size; i++) { 111 | 112 | tempValue = array[i]; 113 | 114 | if (tempValue > value) { 115 | value = tempValue; 116 | x = i; 117 | } 118 | 119 | } 120 | 121 | return x; 122 | } 123 | 124 | /** 125 | * Fills an array with a given value in a 1 dimensional static array. 126 | * You can specify the amount of cells to be written. 127 | * 128 | * @param array Static Array. 129 | * @param size Number of cells to write (eg. the array's size) 130 | * @param value Fill value. 131 | * @param start Optional: Offset where to start (0 - (size-1)). 132 | */ 133 | stock void Array_Fill(any[] array, int size, any value, int start=0) 134 | { 135 | if (start < 0) { 136 | start = 0; 137 | } 138 | 139 | for (int i=start; i < size; i++) { 140 | array[i] = value; 141 | } 142 | } 143 | 144 | /** 145 | * Copies a 1 dimensional static array. 146 | * 147 | * @param array Static Array to copy from. 148 | * @param newArray New Array to copy to. 149 | * @param size Size of the array (or number of cells to copy) 150 | * @noreturn 151 | */ 152 | stock void Array_Copy(const any[] array, any[] newArray, int size) 153 | { 154 | for (int i=0; i < size; i++) { 155 | newArray[i] = array[i]; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /include/smlib/concommands.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_concommands_included 2 | #endinput 3 | #endif 4 | #define _smlib_concommands_included 5 | 6 | #include 7 | #include 8 | 9 | /** 10 | * Checks if a ConCommand has one or more flags set. 11 | * 12 | * @param command ConCommand name. 13 | * @param flags Flags to check. 14 | * @return True if flags are set, false otherwise. 15 | */ 16 | stock bool ConCommand_HasFlags(const char[] command, int flags) 17 | { 18 | return GetCommandFlags(command) & flags > 0; 19 | } 20 | 21 | /** 22 | * Adds one or more flags to a ConCommand. 23 | * 24 | * @param command ConCommand name. 25 | * @param flags Flags to add. 26 | */ 27 | stock void ConCommand_AddFlags(const char[] command, int flags) 28 | { 29 | int newFlags = GetCommandFlags(command); 30 | newFlags |= flags; 31 | SetCommandFlags(command, newFlags); 32 | } 33 | 34 | /** 35 | * Removes one ore more flags from a ConCommand. 36 | * 37 | * @param command ConCommand name. 38 | * @param flags Flags to remove 39 | */ 40 | stock void ConCommand_RemoveFlags(const char[] command, int flags) 41 | { 42 | int newFlags = GetCommandFlags(command); 43 | newFlags &= ~flags; 44 | SetCommandFlags(command, newFlags); 45 | } 46 | -------------------------------------------------------------------------------- /include/smlib/convars.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_convars_included 2 | #endinput 3 | #endif 4 | #define _smlib_convars_included 5 | 6 | #include 7 | 8 | /** 9 | * Checks if a ConVar has one or more flags set. 10 | * 11 | * @param convar ConVar Handle. 12 | * @param flags Flags to check. 13 | * @return True if flags are set, false otherwise. 14 | */ 15 | stock bool Convar_HasFlags(ConVar convar, int flags) 16 | { 17 | return convar.Flags & flags > 0; 18 | } 19 | 20 | /** 21 | * Adds one or more flags to a ConVar. 22 | * 23 | * @param convar ConVar Handle. 24 | * @param flags Flags to add. 25 | */ 26 | stock void Convar_AddFlags(ConVar convar, int flags) 27 | { 28 | int newFlags = convar.Flags; 29 | newFlags |= flags; 30 | convar.Flags = newFlags; 31 | } 32 | 33 | /** 34 | * Removes one ore more flags from a ConVar. 35 | * 36 | * @param convar ConVar Handle. 37 | * @param flags Flags to remove 38 | * @noreturn 39 | */ 40 | stock void Convar_RemoveFlags(ConVar convar, int flags) 41 | { 42 | int newFlags = convar.Flags; 43 | newFlags &= ~flags; 44 | convar.Flags = newFlags; 45 | } 46 | 47 | /** 48 | * Checks if a String is a valid ConVar or 49 | * Console Command name. 50 | * 51 | * @param name String Name. 52 | * @return True if the name specified is a valid ConVar or console command name, false otherwise. 53 | */ 54 | stock bool Convar_IsValidName(const char[] name) 55 | { 56 | if (name[0] == '\0') { 57 | return false; 58 | } 59 | 60 | int n=0; 61 | while (name[n] != '\0') { 62 | 63 | if (!IsValidConVarChar(name[n])) { 64 | return false; 65 | } 66 | 67 | n++; 68 | } 69 | 70 | return true; 71 | } 72 | -------------------------------------------------------------------------------- /include/smlib/debug.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_debug_included 2 | #endinput 3 | #endif 4 | #define _smlib_debug_included 5 | 6 | #include 7 | 8 | /** 9 | * Prints the values of a static Float-Array to the server console. 10 | * 11 | * @param array Static Float-Array. 12 | * @param size Size of the Array. 13 | */ 14 | stock void Debug_FloatArray(const float[] array, int size=3) 15 | { 16 | char output[64] = ""; 17 | 18 | for (int i=0; i < size; ++i) { 19 | 20 | if (i > 0 && i < size) { 21 | StrCat(output, sizeof(output), ", "); 22 | } 23 | 24 | Format(output, sizeof(output), "%s%f", output, array[i]); 25 | } 26 | 27 | PrintToServer("[DEBUG] Vector[%d] = { %s }", size, output); 28 | } 29 | -------------------------------------------------------------------------------- /include/smlib/dynarrays.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_dynarray_included 2 | #endinput 3 | #endif 4 | #define _smlib_dynarray_included 5 | 6 | #include 7 | 8 | /** 9 | * Retrieves a cell value from an array. 10 | * This is a wrapper around the Sourcemod Function GetArrayCell, 11 | * but it casts the result as bool 12 | * 13 | * @param array Array Handle. 14 | * @param index Index in the array. 15 | * @param block Optionally specify which block to read from 16 | * (useful if the blocksize > 0). 17 | * @param asChar Optionally read as a byte instead of a cell. 18 | * @return Value read. 19 | * @error Invalid Handle, invalid index, or invalid block. 20 | */ 21 | stock bool DynArray_GetBool(ArrayList array, int index, int block=0, bool asChar=false) 22 | { 23 | return array.Get(index, block, asChar) != 0; 24 | } 25 | -------------------------------------------------------------------------------- /include/smlib/edicts.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_edicts_included 2 | #endinput 3 | #endif 4 | #define _smlib_edicts_included 5 | 6 | #include 7 | #include 8 | 9 | /* 10 | * Finds an edict by it's name 11 | * It only finds the first occurence. 12 | * 13 | * @param name Name of the entity you want so search. 14 | * @return Edict Index or INVALID_ENT_REFERENCE if no entity was found. 15 | */ 16 | stock int Edict_FindByName(const char[] name) 17 | { 18 | int maxEntities = GetMaxEntities(); 19 | for (int edict=0; edict < maxEntities; edict++) { 20 | 21 | if (!IsValidEdict(edict)) { 22 | continue; 23 | } 24 | 25 | if (Entity_NameMatches(edict, name)) { 26 | return edict; 27 | } 28 | } 29 | 30 | return INVALID_ENT_REFERENCE; 31 | } 32 | 33 | /* 34 | * Finds an edict by its HammerID. 35 | * The newer version of Valve's Hammer editor 36 | * sets a unique ID for each entity in a map. 37 | * It only finds the first occurence. 38 | * 39 | * @param hammerId Hammer editor ID 40 | * @return Edict Index or INVALID_ENT_REFERENCE if no entity was found. 41 | */ 42 | stock int Edict_FindByHammerId(int hammerId) 43 | { 44 | int maxEntities = GetMaxEntities(); 45 | for (int edict=0; edict < maxEntities; edict++) { 46 | 47 | if (!IsValidEdict(edict)) { 48 | continue; 49 | } 50 | 51 | if (Entity_GetHammerId(edict) == hammerId) { 52 | return edict; 53 | } 54 | } 55 | 56 | return INVALID_ENT_REFERENCE; 57 | } 58 | 59 | /** 60 | * Searches for the closest edict in relation to the given origin 61 | * 62 | * @param vecOrigin_center 3 dimensional origin array 63 | * @param clientsOnly True if you only want to search for clients 64 | * @param ignoreEntity Ignore this entity 65 | * @return Edict Index or INVALID_ENT_REFERENCE if no entity was found. 66 | */ 67 | stock int Edict_GetClosest(float vecOrigin_center[3], bool clientsOnly=false, int ignoreEntity=-1) 68 | { 69 | float vecOrigin_edict[3]; 70 | float smallestDistance = 0.0; 71 | int closestEdict = INVALID_ENT_REFERENCE; 72 | 73 | int maxEntities; 74 | 75 | if (clientsOnly) { 76 | maxEntities = MaxClients; 77 | } 78 | else { 79 | maxEntities = GetMaxEntities(); 80 | } 81 | 82 | for (int edict=1; edict <= maxEntities; edict++) { 83 | 84 | if (!IsValidEdict(edict)) { 85 | continue; 86 | } 87 | 88 | if (ignoreEntity >= 0 && edict == ignoreEntity) { 89 | continue; 90 | } 91 | 92 | if (GetEntSendPropOffs(edict, "m_vecOrigin") == -1) { 93 | continue; 94 | } 95 | 96 | Entity_GetAbsOrigin(edict, vecOrigin_edict); 97 | 98 | float edict_distance = GetVectorDistance(vecOrigin_center, vecOrigin_edict, true); 99 | 100 | if (edict_distance < smallestDistance || smallestDistance == 0.0) { 101 | smallestDistance = edict_distance; 102 | closestEdict = edict; 103 | } 104 | } 105 | 106 | return closestEdict; 107 | } 108 | 109 | /** 110 | * Searches for the closest edict in relation to the given edict. 111 | * 112 | * @param edict Edict index 113 | * @param clientsOnly True if you only want to search for clients 114 | * @return The closest edict or INVALID_ENT_REFERENCE 115 | */ 116 | stock int Edict_GetClosestToEdict(int edict, bool clientsOnly=false) 117 | { 118 | float vecOrigin[3]; 119 | 120 | if (!HasEntProp(edict, Prop_Send, "m_vecOrigin")) { 121 | return INVALID_ENT_REFERENCE; 122 | } 123 | 124 | Entity_GetAbsOrigin(edict, vecOrigin); 125 | 126 | return Edict_GetClosest(vecOrigin, clientsOnly, edict); 127 | } 128 | -------------------------------------------------------------------------------- /include/smlib/game.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_game_included 2 | #endinput 3 | #endif 4 | #define _smlib_game_included 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /* 11 | * End's the game and displays the scoreboard with intermission time. 12 | * 13 | * @return True on success, false otherwise 14 | */ 15 | stock bool Game_End() 16 | { 17 | int game_end = FindEntityByClassname(-1, "game_end"); 18 | 19 | if (game_end == -1) { 20 | game_end = CreateEntityByName("game_end"); 21 | 22 | if (game_end == -1) { 23 | ThrowError("Unable to find or create entity \"game_end\""); 24 | } 25 | } 26 | 27 | return AcceptEntityInput(game_end, "EndGame"); 28 | } 29 | 30 | /* 31 | * End's the current round, allows specifying the winning 32 | * team and more. 33 | * This function currently works in TF2 only (it uses the game_round_win entity). 34 | * 35 | * @param team The winning Team, pass 0 for Sudden Death mode (no winning team) 36 | * @param forceMapReset If to force the map to reset during the force respawn after the round is over. 37 | * @param switchTeams If to switch the teams when the game is going to be reset. 38 | * @return True on success, false otherwise 39 | */ 40 | stock bool Game_EndRound(int team=0, bool forceMapReset=false, bool switchTeams=false) 41 | { 42 | int game_round_win = FindEntityByClassname(-1, "game_round_win"); 43 | 44 | if (game_round_win == -1) { 45 | game_round_win = CreateEntityByName("game_round_win"); 46 | 47 | if (game_round_win == -1) { 48 | ThrowError("Unable to find or create entity \"game_round_win\""); 49 | } 50 | } 51 | 52 | DispatchKeyValue(game_round_win, "TeamNum" , (team ? "true" : "false")); 53 | DispatchKeyValue(game_round_win, "force_map_reset" , (forceMapReset? "true" : "false")); 54 | DispatchKeyValue(game_round_win, "switch_teams" , (switchTeams ? "true" : "false")); 55 | 56 | return AcceptEntityInput(game_round_win, "RoundWin"); 57 | } 58 | -------------------------------------------------------------------------------- /include/smlib/menus.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_menus_included 2 | #endinput 3 | #endif 4 | #define _smlib_menus_included 5 | 6 | #include 7 | #include 8 | 9 | /** 10 | * Adds an option to a menu with a String display but an integer 11 | * identifying the option. 12 | * 13 | * @param menu Handle to the menu 14 | * @param value Integer value for the option 15 | * @param display Display text for the menu 16 | */ 17 | stock void Menu_AddIntItem(Menu menu, any value, char[] display) 18 | { 19 | char buffer[INT_MAX_DIGITS + 1]; 20 | IntToString(value, buffer, sizeof(buffer)); 21 | menu.AddItem(buffer, display); 22 | } 23 | 24 | /** 25 | * Retrieves an integer-value choice from a menu, where the 26 | * menu's information strings were created as integers. 27 | * 28 | * @param menu Handle to the menu 29 | * @param param2 The item position selected from the menu. 30 | * @return Integer choice from the menu, or 0 if the integer could not be parsed. 31 | */ 32 | stock any Menu_GetIntItem(Menu menu, any param2) 33 | { 34 | char buffer[INT_MAX_DIGITS + 1]; 35 | menu.GetItem(param2, buffer, sizeof(buffer)); 36 | return StringToInt(buffer); 37 | } 38 | -------------------------------------------------------------------------------- /include/smlib/server.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_server_included 2 | #endinput 3 | #endif 4 | #define _smlib_server_included 5 | 6 | #include 7 | #include 8 | 9 | /* 10 | * Gets the server's public/external (default) or 11 | * private/local (usually server's behind a NAT) IP. 12 | * If your server is behind a NAT Router, you need the SteamTools 13 | * extension available at http://forums.alliedmods.net/showthread.php?t=129763 14 | * to get the public IP. has to be included BEFORE . 15 | * If the server is not behind NAT, the public IP is the same as the private IP. 16 | * 17 | * @param public Set to true to retrieve the server's public/external IP, false otherwise. 18 | * @return Long IP or 0 if the IP couldn't be retrieved. 19 | */ 20 | stock int Server_GetIP(bool public_=true) 21 | { 22 | int ip = 0; 23 | 24 | static ConVar cvHostip = null; 25 | 26 | if (cvHostip == INVALID_HANDLE) { 27 | cvHostip = FindConVar("hostip"); 28 | MarkNativeAsOptional("Steam_GetPublicIP"); 29 | } 30 | 31 | if (cvHostip != INVALID_HANDLE) { 32 | ip = cvHostip.IntValue; 33 | } 34 | 35 | if (ip != 0 && IsIPLocal(ip) == public_) { 36 | ip = 0; 37 | } 38 | 39 | #if defined _steamtools_included 40 | if (ip == 0) { 41 | if (CanTestFeatures() && GetFeatureStatus(FeatureType_Native, "Steam_GetPublicIP") == FeatureStatus_Available) { 42 | int octets[4]; 43 | Steam_GetPublicIP(octets); 44 | 45 | ip = 46 | octets[0] << 24 | 47 | octets[1] << 16 | 48 | octets[2] << 8 | 49 | octets[3]; 50 | 51 | if (IsIPLocal(ip) == public_) { 52 | ip = 0; 53 | } 54 | } 55 | } 56 | #endif 57 | 58 | return ip; 59 | } 60 | 61 | /* 62 | * Gets the server's public/external (default) or 63 | * private/local (usually server's behind a NAT) as IP String in dotted format. 64 | * If your server is behind a NAT Router, you need the SteamTools 65 | * extension available at http://forums.alliedmods.net/showthread.php?t=129763 66 | * to get the public IP. has to be included BEFORE . 67 | * If the public IP couldn't be found, an empty String is returned. 68 | * If the server is not behind NAT, the public IP is the same as the private IP. 69 | * 70 | * @param buffer String buffer (size=16) 71 | * @param size String buffer size. 72 | * @param public Set to true to retrieve the server's public/external IP, false otherwise. 73 | * @return True on success, false otherwise. 74 | */ 75 | stock bool Server_GetIPString(char[] buffer, int size, bool public_=true) 76 | { 77 | int ip; 78 | 79 | if ((ip = Server_GetIP(public_)) == 0) { 80 | buffer[0] = '\0'; 81 | return false; 82 | } 83 | 84 | LongToIP(ip, buffer, size); 85 | 86 | return true; 87 | } 88 | 89 | /* 90 | * Gets the server's local port. 91 | * 92 | * @noparam 93 | * @return The server's port, 0 if there is no port. 94 | */ 95 | stock int Server_GetPort() 96 | { 97 | static ConVar cvHostport = null; 98 | 99 | if (cvHostport == INVALID_HANDLE) { 100 | cvHostport = FindConVar("hostport"); 101 | } 102 | 103 | if (cvHostport == INVALID_HANDLE) { 104 | return 0; 105 | } 106 | 107 | int port = cvHostport.IntValue; 108 | 109 | return port; 110 | } 111 | 112 | /* 113 | * Gets the server's hostname 114 | * 115 | * @param hostname String buffer 116 | * @param size String buffer size 117 | * @return True on success, false otherwise. 118 | */ 119 | stock bool Server_GetHostName(char[] buffer, int size) 120 | { 121 | static ConVar cvHostname = null; 122 | 123 | if (cvHostname == INVALID_HANDLE) { 124 | cvHostname = FindConVar("hostname"); 125 | } 126 | 127 | if (cvHostname == INVALID_HANDLE) { 128 | buffer[0] = '\0'; 129 | return false; 130 | } 131 | 132 | cvHostname.GetString(buffer, size); 133 | 134 | return true; 135 | } 136 | -------------------------------------------------------------------------------- /include/smlib/sql.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_sql_included 2 | #endinput 3 | #endif 4 | #define _smlib_sql_included 5 | 6 | #include 7 | #include 8 | 9 | /** 10 | * Executes a threaded SQL Query (See: SQL_TQuery) 11 | * This function supports the printf Syntax. 12 | * 13 | * 14 | * @param database A database Handle. 15 | * @param callback Callback; database is in "owner" and the query Handle is passed in "hndl". 16 | * @param data Extra data value to pass to the callback. 17 | * @param format Query string, printf syntax supported 18 | * @param priority Priority queue to use 19 | * @param ... Variable number of format parameters. 20 | */ 21 | stock void SQL_TQueryF(Database database, SQLTCallback callback, any data, DBPriority priority=DBPrio_Normal, const char[] format, any ...) { 22 | 23 | if (!database) { 24 | ThrowError("[SMLIB] Error: Invalid database handle."); 25 | return; 26 | } 27 | 28 | char query[16384]; 29 | VFormat(query, sizeof(query), format, 6); 30 | 31 | SQL_TQuery(database, callback, query, data, priority); 32 | } 33 | 34 | /** 35 | * Fetches an integer from a field in the current row of a result set (See: SQL_FetchInt) 36 | * 37 | * @param query A query (or statement) Handle. 38 | * @param field The field index (starting from 0). 39 | * @param result Optional variable to store the status of the return value. 40 | * @return An integer value. 41 | * @error Invalid query Handle or field index, invalid 42 | * type conversion requested from the database, 43 | * or no current result set. 44 | */ 45 | stock int SQL_FetchIntByName(DBResultSet query, const char[] fieldName, DBResult &result=DBVal_Error) { 46 | 47 | int fieldNum; 48 | SQL_FieldNameToNum(query, fieldName, fieldNum); 49 | 50 | return SQL_FetchInt(query, fieldNum, result); 51 | } 52 | 53 | /** 54 | * Fetches a bool from a field in the current row of a result set (See: SQL_FetchInt) 55 | * 56 | * @param query A query (or statement) Handle. 57 | * @param field The field index (starting from 0). 58 | * @param result Optional variable to store the status of the return value. 59 | * @return A bool value. 60 | * @error Invalid query Handle or field index, invalid 61 | * type conversion requested from the database, 62 | * or no current result set. 63 | */ 64 | stock bool SQL_FetchBoolByName(DBResultSet query, const char[] fieldName, DBResult &result=DBVal_Error) { 65 | 66 | return SQL_FetchIntByName(query, fieldName, result) != 0; 67 | } 68 | 69 | /** 70 | * Fetches a float from a field in the current row of a result set. (See: SQL_FetchFloat) 71 | * 72 | * @param query A query (or statement) Handle. 73 | * @param field The field index (starting from 0). 74 | * @param result Optional variable to store the status of the return value. 75 | * @return A float value. 76 | * @error Invalid query Handle or field index, invalid 77 | * type conversion requested from the database, 78 | * or no current result set. 79 | */ 80 | stock float SQL_FetchFloatByName(DBResultSet query, const char[] fieldName, DBResult &result=DBVal_Error) { 81 | 82 | int fieldNum; 83 | SQL_FieldNameToNum(query, fieldName, fieldNum); 84 | 85 | return SQL_FetchFloat(query, fieldNum, result); 86 | } 87 | 88 | /** 89 | * Fetches a string from a field in the current row of a result set. (See: SQL_FetchString) 90 | * 91 | * @param query A query (or statement) Handle. 92 | * @param field The field index (starting from 0). 93 | * @param buffer String buffer. 94 | * @param maxlength Maximum size of the string buffer. 95 | * @param result Optional variable to store the status of the return value. 96 | * @return Number of bytes written. 97 | * @error Invalid query Handle or field index, invalid 98 | * type conversion requested from the database, 99 | * or no current result set. 100 | */ 101 | stock int SQL_FetchStringByName(DBResultSet query, const char[] fieldName, char[] buffer, int maxlength, DBResult &result=DBVal_Error) { 102 | 103 | int fieldNum; 104 | SQL_FieldNameToNum(query, fieldName, fieldNum); 105 | 106 | return SQL_FetchString(query, fieldNum, buffer, maxlength, result); 107 | } 108 | -------------------------------------------------------------------------------- /include/smlib/vehicles.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_vehicles_included 2 | #endinput 3 | #endif 4 | #define _smlib_vehicles_included 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * Returns the vehicle's driver. 13 | * If there is no driver in the vehicle, -1 is returned. 14 | * 15 | * @param vehicle Entity index. 16 | * @return Client index, or -1 if there is no driver. 17 | */ 18 | stock int Vehicle_GetDriver(int vehicle) 19 | { 20 | int m_hVehicle = GetEntPropEnt(vehicle, Prop_Send, "m_hPlayer"); 21 | 22 | return m_hVehicle; 23 | } 24 | 25 | /** 26 | * Returns whether there is a driver in the vehicle or not. 27 | * 28 | * @param vehicle Entity index. 29 | * @return True if the vehicle has a driver, false otherwise 30 | */ 31 | stock bool Vehicle_HasDriver(int vehicle) 32 | { 33 | return Vehicle_GetDriver(vehicle) != -1; 34 | } 35 | 36 | /** 37 | * Kicks the driver ouf of the vehicle 38 | * 39 | * @param vehicle Entity index. 40 | * @return True on success, false otherwise. 41 | */ 42 | stock bool Vehicle_ExitDriver(int vehicle) 43 | { 44 | if (!Vehicle_HasDriver(vehicle)) { 45 | return false; 46 | } 47 | 48 | return AcceptEntityInput(vehicle, "ExitVehicle"); 49 | } 50 | 51 | /** 52 | * Start's the vehicle's engine 53 | * 54 | * @param vehicle Entity index. 55 | * @return True on success, false otherwise. 56 | */ 57 | stock bool Vehicle_TurnOn(int vehicle) 58 | { 59 | return AcceptEntityInput(vehicle, "TurnOn"); 60 | } 61 | 62 | /** 63 | * Shuts down the vehicle's engine 64 | * 65 | * @param vehicle Entity index. 66 | * @return True on success, false otherwise. 67 | */ 68 | stock bool Vehicle_TurnOff(int vehicle) 69 | { 70 | return AcceptEntityInput(vehicle, "TurnOff"); 71 | } 72 | 73 | /** 74 | * Locks the vehicle. 75 | * 76 | * @param vehicle Entity index. 77 | * @return True on success, false otherwise. 78 | */ 79 | stock bool Vehicle_Lock(int vehicle) 80 | { 81 | return AcceptEntityInput(vehicle, "Lock"); 82 | } 83 | 84 | /** 85 | * Unlocks the vehicle. 86 | * 87 | * @param vehicle Entity index. 88 | * @return True on success, false otherwise. 89 | */ 90 | stock bool Vehicle_Unlock(int vehicle) 91 | { 92 | return AcceptEntityInput(vehicle, "Unlock"); 93 | } 94 | 95 | /** 96 | * Returns wether the entity is a valid vehicle or not. 97 | * 98 | * @param vehicle Entity index. 99 | * @return True if it is a valid vehicle, false otherwise. 100 | */ 101 | stock bool Vehicle_IsValid(int vehicle) 102 | { 103 | if (!Entity_IsValid(vehicle)) { 104 | return false; 105 | } 106 | 107 | return Entity_ClassNameMatches(vehicle, "prop_vehicle", true); 108 | } 109 | 110 | /** 111 | * Reads the vehicle script from a vehicle. 112 | * This script contains all the vehicle settings like its speed 113 | * and that stuff. 114 | * 115 | * @param vehicle Entity index. 116 | * @param buffer String Buffer. 117 | * @param size String Buffer size. 118 | * @noreturn 119 | */ 120 | stock void Vehicle_GetScript(int vehicle, char[] buffer, int size) 121 | { 122 | GetEntPropString(vehicle, Prop_Data, "m_vehicleScript", buffer, size); 123 | } 124 | 125 | /** 126 | * Sets the script of a vehicle. 127 | * This script contains all the vehicle settings like its speed 128 | * and that stuff. 129 | * 130 | * @param vehicle Entity index. 131 | * @param buffer Vehicle Script path. 132 | * @noreturn 133 | */ 134 | stock void Vehicle_SetScript(int vehicle, char[] script) 135 | { 136 | DispatchKeyValue(vehicle, "vehiclescript", script); 137 | } 138 | -------------------------------------------------------------------------------- /include/smlib/world.inc: -------------------------------------------------------------------------------- 1 | #if defined _smlib_world_included 2 | #endinput 3 | #endif 4 | #define _smlib_world_included 5 | 6 | #include 7 | 8 | /* 9 | * Gets the world's max size 10 | * 11 | * @param vec Vector buffer 12 | */ 13 | stock void World_GetMaxs(float vec[3]) { 14 | 15 | GetEntPropVector(0, Prop_Data, "m_WorldMaxs", vec); 16 | } 17 | -------------------------------------------------------------------------------- /include/smrcon.inc: -------------------------------------------------------------------------------- 1 | #if defined _smrcon_included 2 | #endinput 3 | #endif 4 | #define _smrcon_included 5 | 6 | /** 7 | * @brief Called when an RCon session auth is processed 8 | * 9 | * @param rconId RCon listener ID, unique per session. 10 | * @param address Originating IP address. 11 | * @param password Password sent by RCon client. 12 | * @param allow True to grant auth, false otherwise. 13 | * @return Plugin_Changed to use given allow value, Plugin_Continue to let engine process. 14 | */ 15 | forward Action SMRCon_OnAuth(int rconId, const char[] address, const char[] password, bool &allow); 16 | 17 | /** 18 | * @brief Called when an RCon command is processed. 19 | * 20 | * @note Rejection here does not count as a bad password attempt; 21 | * however, the RCon log line will be annotated in the form 22 | * of 'command (rejected) "%s"' rather than just 'command "%s"' 23 | * 24 | * @param rconId RCon listener ID, unique per session. 25 | * @param address Originating IP address. 26 | * @param command Command sent by RCon client. 27 | * @param allow True to allow command to be processed, false otherwise. 28 | * @return Plugin_Changed to use given allow value, Plugin_Continue to let engine process. 29 | */ 30 | forward Action SMRCon_OnCommand(int rconId, const char[] address, const char[] command, bool &allow); 31 | 32 | /** 33 | * @brief Called when an RCon session is disconnected. 34 | * 35 | * @param rconId RCon listener ID, unique per session. 36 | */ 37 | forward void SMRCon_OnDisconnect(int rconId); 38 | 39 | /** 40 | * @brief Called when an RCon log line is written 41 | * 42 | * @param rconId RCon listener ID, unique per session. 43 | * @param address Originating IP address. 44 | * @param logdata Log data (usually either "Bad Password" or "command" 45 | * followed by the command. 46 | * @return Plugin_Continue to log, Plugin_Handled to block. 47 | */ 48 | forward Action SMRCon_OnLog(int rconId, const char[] address, const char[] logdata); 49 | 50 | /** 51 | * @brief Determines whether current server command originated from an RCon session. 52 | * 53 | * @return True if command originated from RCon session, false if from console or not in server command callback. 54 | */ 55 | native bool SMRCon_IsCmdFromRCon(); 56 | 57 | 58 | /** Do Not Edit Below This Line **/ 59 | 60 | public Extension __ext_smrcon = 61 | { 62 | name = "smrcon", 63 | file = "smrcon.ext", 64 | #if defined AUTOLOAD_EXTENSIONS 65 | autoload = 1, 66 | #else 67 | autoload = 0, 68 | #endif 69 | #if defined REQUIRE_EXTENSIONS 70 | required = 1, 71 | #else 72 | required = 0, 73 | #endif 74 | }; 75 | 76 | #if !defined REQUIRE_EXTENSIONS 77 | public void __ext_smrcon_SetNTVOptional() 78 | { 79 | MarkNativeAsOptional("SMRCon_IsCmdFromRCon"); 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /include/sourcescramble.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * Memory patching utilities. 3 | */ 4 | 5 | #if defined __sourcescramble_ext_included 6 | #endinput 7 | #endif 8 | 9 | #define __sourcescramble_ext_included 10 | 11 | methodmap MemoryPatch < Handle { 12 | /** 13 | * Loads a memory patch from a game config handle. 14 | */ 15 | public static native MemoryPatch CreateFromConf(Handle gameconf, const char[] name); 16 | 17 | /** 18 | * Returns true if the contents at the memory location for the patch matches the contents 19 | * specified in the game config. If the game config does not specify any verify section, 20 | * this always returns true. 21 | */ 22 | public native bool Validate(); 23 | 24 | /** 25 | * Enables the memory patch. Returns false if the validation check fails or the patch has 26 | * already been applied. 27 | */ 28 | public native bool Enable(); 29 | 30 | /** 31 | * Disables a memory patch. 32 | */ 33 | public native void Disable(); 34 | 35 | /** 36 | * Returns the starting address of the patch, equivalent to the address of the patch's 37 | * dependent signature plus the patch offset. 38 | */ 39 | property Address Address { 40 | public native get(); 41 | } 42 | }; 43 | 44 | methodmap MemoryBlock < Handle { 45 | /** 46 | * Allocates a fixed amount of memory, initializing the contents to zero. 47 | * Size is in bytes. 48 | */ 49 | public native MemoryBlock(int size); 50 | 51 | /** 52 | * Disowns the associated memory block, allowing it to remain allocated even when the handle 53 | * is deleted. Disowning the memory does not invalidate the handle. 54 | * 55 | * Only use this if you are certain that something else will free (or has freed) the memory 56 | * block. 57 | */ 58 | public native void Disown(); 59 | 60 | /** 61 | * Returns the address of the allocated memory block. 62 | */ 63 | property Address Address { 64 | public native get(); 65 | } 66 | 67 | /** 68 | * Returns the size of the allocated memory block. 69 | */ 70 | property int Size { 71 | public native get(); 72 | } 73 | 74 | /** 75 | * Load up to 4 bytes from an offset to the memory block, performing bounds checks to ensure 76 | * reads are contained within the block. 77 | */ 78 | public int LoadFromOffset(int offset, NumberType size) { 79 | if (offset < 0 || offset + GetNumberTypeByteSize(size) > this.Size) { 80 | ThrowError("Cannot perform MemoryBlock access of %d bytes at offset %d (limit %d)", 81 | GetNumberTypeByteSize(size), offset, this.Size); 82 | } 83 | return LoadFromAddress(this.Address + view_as
(offset), size); 84 | } 85 | 86 | /** 87 | * Store up to 4 bytes to an offset to the memory block, performing bounds checks to ensure 88 | * writes are contained within the block. 89 | */ 90 | public void StoreToOffset(int offset, int data, NumberType size) { 91 | if (offset < 0 || offset + GetNumberTypeByteSize(size) > this.Size) { 92 | ThrowError("Cannot perform MemoryBlock access of %d bytes at offset %d (limit %d)", 93 | GetNumberTypeByteSize(size), offset, this.Size); 94 | } 95 | StoreToAddress(this.Address + view_as
(offset), data, size); 96 | } 97 | }; 98 | 99 | static stock int GetNumberTypeByteSize(NumberType size) { 100 | switch (size) { 101 | case NumberType_Int8: return 1; 102 | case NumberType_Int16: return 2; 103 | case NumberType_Int32: return 4; 104 | } 105 | ThrowError("Unknown NumberType %d. Did the SourceMod developers add some new ones?", size); 106 | return 1; // maybe `return (1 << size);` ? 107 | } 108 | 109 | /** 110 | * Returns the physical memory address of a given SourcePawn cell reference. 111 | */ 112 | native Address GetAddressOfCell(any& cell); 113 | 114 | /** 115 | * Returns the physical memory address of a given string. 116 | */ 117 | native Address GetAddressOfString(char[] array); 118 | 119 | public Extension __ext_sourcescramble = { 120 | name = "Source Scramble", 121 | file = "sourcescramble.ext", 122 | #if defined AUTOLOAD_EXTENSIONS 123 | autoload = 1, 124 | #else 125 | autoload = 0, 126 | #endif 127 | #if defined REQUIRE_EXTENSIONS 128 | required = 1, 129 | #else 130 | required = 0, 131 | #endif 132 | }; 133 | 134 | #if !defined REQUIRE_EXTENSIONS 135 | public void __ext_sourcescramble_SetNTVOptional() { 136 | } 137 | #endif 138 | -------------------------------------------------------------------------------- /include/survivors.inc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined __survs__ 4 | #endinput 5 | #endif 6 | #define __survs__ 7 | 8 | /* Global Vars */ 9 | static iSurvivorIndex[MAXPLAYERS + 1]; 10 | static iSurvivorCount = 0; 11 | 12 | 13 | Survivors_RebuildArray_Delay() 14 | { 15 | CreateTimer(0.3, BuildArray_Timer); 16 | } 17 | 18 | public Action:BuildArray_Timer(Handle:timer) 19 | { 20 | Survivors_RebuildArray(); 21 | } 22 | 23 | Survivors_RebuildArray() 24 | { 25 | if (!IsServerProcessing()) return; 26 | iSurvivorCount = 0; 27 | 28 | for (new i = 0; i <= MAXPLAYERS; i++) iSurvivorIndex[i] = 0; 29 | 30 | for (new i = 1; i <= MaxClients; i++) 31 | { 32 | if (IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) 33 | { 34 | iSurvivorIndex[iSurvivorCount] = i; 35 | iSurvivorCount++; 36 | } 37 | } 38 | } 39 | 40 | stock GetSurvivorCount() return iSurvivorCount; 41 | 42 | stock GetSurvivorOfIndex(index) return iSurvivorIndex[index]; -------------------------------------------------------------------------------- /include/tanks.inc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined __tanks__ 4 | #endinput 5 | #endif 6 | #define __tanks__ 7 | 8 | /* Global Vars */ 9 | new Handle:hFwdFirstTankSpawn; 10 | new Handle:hFwdTankPassControl; 11 | new Handle:hFwdTankDeath; 12 | new Handle:hTankDeathTimer; 13 | 14 | static bool:bIsTankActive; 15 | static iTankClient = -1; 16 | static iTankPassCount = 0; 17 | 18 | ResetStatus() 19 | { 20 | bIsTankActive = false; 21 | iTankClient = -1; 22 | iTankPassCount = 0; 23 | 24 | if (hTankDeathTimer != INVALID_HANDLE) 25 | { 26 | KillTimer(hTankDeathTimer); 27 | hTankDeathTimer = INVALID_HANDLE; 28 | } 29 | } 30 | 31 | Tanks_OnMapStart() 32 | { 33 | ResetStatus(); 34 | } 35 | 36 | Tanks_RoundStart() 37 | { 38 | ResetStatus(); 39 | } 40 | 41 | Tanks_TankSpawn(Handle:event) 42 | { 43 | if (bIsTankActive) return; 44 | bIsTankActive = true; 45 | 46 | iTankClient = GetClientOfUserId(GetEventInt(event, "userid")); 47 | 48 | Call_StartForward(hFwdFirstTankSpawn); 49 | Call_PushCell(iTankClient); 50 | Call_Finish(); 51 | } 52 | 53 | Tanks_ItemPickup(Handle:event) 54 | { 55 | if (!bIsTankActive) return; 56 | 57 | decl String:item[64]; 58 | GetEventString(event, "item", item, sizeof(item)); 59 | 60 | if (StrEqual(item, "tank_claw")) 61 | { 62 | new iPrevTank = iTankClient; 63 | iTankClient = GetClientOfUserId(GetEventInt(event, "userid")); 64 | if (hTankDeathTimer != INVALID_HANDLE) 65 | { 66 | KillTimer(hTankDeathTimer); 67 | hTankDeathTimer = INVALID_HANDLE; 68 | } 69 | Call_StartForward(hFwdTankPassControl); 70 | Call_PushCell(iPrevTank); 71 | Call_PushCell(iTankClient); 72 | Call_PushCell(iTankPassCount); 73 | Call_Finish(); 74 | iTankPassCount++; 75 | } 76 | } 77 | 78 | Tanks_PlayerDeath(Handle:event) 79 | { 80 | if (!bIsTankActive) return; 81 | new client = GetClientOfUserId(GetEventInt(event, "userid")); 82 | if (client != iTankClient) return; 83 | hTankDeathTimer = CreateTimer(0.5, TankDeath_Timer); 84 | } 85 | 86 | public Action:TankDeath_Timer(Handle:timer) 87 | { 88 | Call_StartForward(hFwdTankDeath); 89 | Call_PushCell(iTankClient); 90 | Call_Finish(); 91 | ResetStatus(); 92 | } -------------------------------------------------------------------------------- /include/tanks_l4d2util.inc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static Handle:hFwdOnTankPunchHittable; 5 | static Handle:hFwdOnTankSpawn; 6 | static Handle:hFwdOnTankPass; 7 | static Handle:hFwdOnTankDeath; 8 | 9 | static Handle:hTankClients; 10 | 11 | static AddTankToArray(client) { 12 | PushArrayCell(hTankClients, client); 13 | } 14 | 15 | static RemoveTankFromArray(client) { 16 | for (new i = 0; i < GetArraySize(hTankClients); ++i) { 17 | if (GetArrayCell(hTankClients, i) == client) { 18 | RemoveFromArray(hTankClients, i); 19 | } 20 | } 21 | } 22 | 23 | static bool:FindTankInArray(client) { 24 | for (new i = 0; i < GetArraySize(hTankClients); ++i) { 25 | if (GetArrayCell(hTankClients, i) == client) { 26 | return true; 27 | } 28 | } 29 | 30 | return false; 31 | } 32 | 33 | L4D2Util_Tanks_Init() { 34 | hTankClients = CreateArray(); 35 | } 36 | 37 | L4D2Util_Tanks_OnRoundStart() { 38 | ClearArray(hTankClients); 39 | CreateTimer(0.1, L4D2Util_Tanks_HookProps); 40 | } 41 | 42 | public Action:L4D2Util_Tanks_HookProps(Handle:hTimer) { 43 | new iEntity = -1; 44 | 45 | while ((iEntity = FindEntityByClassname(iEntity, "prop_physics")) != -1) { 46 | if (IsTankHittable(iEntity)) { 47 | HookSingleEntityOutput(iEntity, "OnHitByTank", TankHittablePunched); 48 | } 49 | } 50 | 51 | iEntity = -1; 52 | 53 | while ((iEntity = FindEntityByClassname(iEntity, "prop_alarm_car")) != -1) { 54 | HookSingleEntityOutput(iEntity, "OnHitByTank", TankHittablePunched); 55 | } 56 | } 57 | 58 | public TankHittablePunched(const String:output[], caller, activator, Float:delay) { 59 | Call_StartForward(hFwdOnTankPunchHittable); 60 | Call_PushCell(activator); 61 | Call_PushCell(caller); 62 | Call_Finish(); 63 | } 64 | 65 | // The tank_spawn hook is called when the tanks spawns(!), but also when the 66 | // tank passes from AI to a player or from a player to AI. 67 | L4D2Util_Tanks_TankSpawn(client) { 68 | new iNumTanks = NumTanksInPlay(); 69 | 70 | if (GetArraySize(hTankClients) < iNumTanks) { 71 | AddTankToArray(client); 72 | Call_StartForward(hFwdOnTankSpawn); 73 | Call_PushCell(client); 74 | Call_Finish(); 75 | } 76 | } 77 | 78 | L4D2Util_Tanks_PlayerDeath(client) { 79 | if (client == 0) { 80 | return; 81 | } 82 | 83 | if (!IsTank(client)) { 84 | return; 85 | } 86 | 87 | CreateTimer(0.1, L4D2Util_Tanks_TankDeathDelay, client); 88 | } 89 | 90 | public Action:L4D2Util_Tanks_TankDeathDelay(Handle:hTimer, any:iOldTankClient) { 91 | new iTankClient = -1; 92 | new client = -1; 93 | 94 | while ((client = FindTankClient(client)) != -1) { 95 | if (!FindTankInArray(client)) { 96 | iTankClient = client; 97 | break; 98 | } 99 | } 100 | 101 | RemoveTankFromArray(iOldTankClient); 102 | 103 | if (iTankClient != -1) { 104 | AddTankToArray(client); 105 | Call_StartForward(hFwdOnTankPass); 106 | Call_PushCell(iTankClient); 107 | Call_PushCell(iOldTankClient); 108 | Call_Finish(); 109 | return; 110 | } 111 | 112 | Call_StartForward(hFwdOnTankDeath); 113 | Call_PushCell(iOldTankClient); 114 | Call_Finish(); 115 | } 116 | 117 | L4D2Util_Tanks_CreateForwards() { 118 | hFwdOnTankPunchHittable = CreateGlobalForward("OnTankPunchHittable", ET_Ignore, Param_Cell, Param_Cell); 119 | hFwdOnTankSpawn = CreateGlobalForward("OnTankSpawn", ET_Ignore, Param_Cell); 120 | hFwdOnTankPass = CreateGlobalForward("OnTankPass", ET_Ignore, Param_Cell, Param_Cell); 121 | hFwdOnTankDeath = CreateGlobalForward("OnTankDeath", ET_Ignore, Param_Cell); 122 | } 123 | -------------------------------------------------------------------------------- /include/testing.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2014 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | static int TestNumber = 0; 34 | static char TestContext[255]; 35 | 36 | stock void SetTestContext(const char[] context) 37 | { 38 | strcopy(TestContext, sizeof(TestContext), context); 39 | } 40 | 41 | stock void AssertEq(const char[] text, int cell1, int cell2) 42 | { 43 | TestNumber++; 44 | if (cell1 == cell2) 45 | { 46 | PrintToServer("[%d] %s: %s == %d OK", TestNumber, TestContext, text, cell2); 47 | } 48 | else 49 | { 50 | PrintToServer("[%d] %s FAIL: %s should be %d, got %d", TestNumber, TestContext, text, cell2, cell1); 51 | ThrowError("test %d (%s in %s) failed", TestNumber, text, TestContext); 52 | } 53 | } 54 | 55 | stock void AssertFalse(const char[] text, bool value) 56 | { 57 | TestNumber++; 58 | if (!value) 59 | { 60 | PrintToServer("[%d] %s: %s == false OK", TestNumber, TestContext, text, value); 61 | } 62 | else 63 | { 64 | PrintToServer("[%d] %s FAIL: %s should be false, got true", TestNumber, TestContext, text); 65 | ThrowError("test %d (%s in %s) failed", TestNumber, text, TestContext); 66 | } 67 | } 68 | 69 | stock void AssertTrue(const char[] text, bool value) 70 | { 71 | TestNumber++; 72 | if (value) 73 | { 74 | PrintToServer("[%d] %s: %s == true OK", TestNumber, TestContext, text, value); 75 | } 76 | else 77 | { 78 | PrintToServer("[%d] %s FAIL: %s should be true, got false", TestNumber, TestContext, text); 79 | ThrowError("test %d (%s in %s) failed", TestNumber, text, TestContext); 80 | } 81 | } 82 | 83 | stock void AssertStrEq(const char[] text, const char[] value, const char[] expected) 84 | { 85 | TestNumber++; 86 | if (StrEqual(value, expected)) 87 | { 88 | PrintToServer("[%d] %s: '%s' == '%s' OK", TestNumber, TestContext, text, expected); 89 | } 90 | else 91 | { 92 | PrintToServer("[%d] %s FAIL: %s should be '%s', got '%s'", TestNumber, TestContext, text, expected, value); 93 | ThrowError("test %d (%s in %s) failed", TestNumber, text, TestContext); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /include/version.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. 5 | * ============================================================================= 6 | * 7 | * This file is part of the SourceMod/SourcePawn SDK. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it under 10 | * the terms of the GNU General Public License, version 3.0, as published by the 11 | * Free Software Foundation. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU General Public License along with 19 | * this program. If not, see . 20 | * 21 | * As a special exception, AlliedModders LLC gives you permission to link the 22 | * code of this program (as well as its derivative works) to "Half-Life 2," the 23 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 24 | * by the Valve Corporation. You must obey the GNU General Public License in 25 | * all respects for all other code used. Additionally, AlliedModders LLC grants 26 | * this exception to all derivative works. AlliedModders LLC defines further 27 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 28 | * or . 29 | * 30 | * Version: $Id$ 31 | */ 32 | 33 | #if defined _version_included 34 | #endinput 35 | #endif 36 | #define _version_included 37 | 38 | #tryinclude 39 | 40 | #if !defined _auto_version_included 41 | #define SOURCEMOD_V_TAG "manual" 42 | #define SOURCEMOD_V_REV 0 43 | #define SOURCEMOD_V_CSET "0" 44 | #define SOURCEMOD_V_MAJOR 1 /**< SourceMod Major version */ 45 | #define SOURCEMOD_V_MINOR 11 /**< SourceMod Minor version */ 46 | #define SOURCEMOD_V_RELEASE 0 /**< SourceMod Release version */ 47 | 48 | #define SOURCEMOD_VERSION "1.11.0-manual" /**< SourceMod version string (major.minor.release-tag) */ 49 | #endif 50 | -------------------------------------------------------------------------------- /include/version_auto.inc: -------------------------------------------------------------------------------- 1 | 2 | #if defined _auto_version_included 3 | #endinput 4 | #endif 5 | #define _auto_version_included 6 | 7 | #define SOURCEMOD_V_TAG "" 8 | #define SOURCEMOD_V_CSET "aec89ccd" 9 | #define SOURCEMOD_V_MAJOR 1 10 | #define SOURCEMOD_V_MINOR 11 11 | #define SOURCEMOD_V_RELEASE 0 12 | #define SOURCEMOD_V_REV 6913 13 | 14 | #define SOURCEMOD_VERSION "1.11.0.6913" 15 | -------------------------------------------------------------------------------- /include/vscript_replacer.inc: -------------------------------------------------------------------------------- 1 | /* 2 | * VScript File Replacer 3 | * Copyright (C) 2022 Silvers 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #if defined _vscript_replacer_included 20 | #endinput 21 | #endif 22 | #define _vscript_replacer_included 23 | 24 | 25 | 26 | public SharedPlugin __pl_vscript_replacer = 27 | { 28 | name = "vscript_replacer", 29 | file = "vscript_replacer.smx", 30 | #if defined REQUIRE_PLUGIN 31 | required = 1, 32 | #else 33 | required = 0, 34 | #endif 35 | }; 36 | 37 | 38 | 39 | /** 40 | * Triggered when a VScript is being executed, allowing you to block or change filename. 41 | * All script names will use lowercase letters. 42 | * 43 | * @param sScript VScript filename being executed. Does not include the .nuc or .nut extension. 44 | * @param sOverride VScript being used to override the original script when override is true. 45 | * @param bOverride True when the sScript is being overwritten by the sOverride value. 46 | * 47 | * @return Plugin_Handled to block the script from being executed. 48 | * Plugin_Changed to change the script and use your provided sOverride value. 49 | * Plugin_Continue to continue without changes. 50 | */ 51 | forward Action OnVScriptExecuted(const char[] sScript, char sOverride[PLATFORM_MAX_PATH], bool bOverride); -------------------------------------------------------------------------------- /include/witch_and_tankifier.inc: -------------------------------------------------------------------------------- 1 | #if defined _witch_and_tankifier_included 2 | #endinput 3 | #endif 4 | #define _witch_and_tankifier_included 5 | 6 | /** 7 | * @brief Check if the current map contains a static witch spawn. 8 | * @remarks Map string will be converted to lowercase internally. 9 | * 10 | * @param map Specific map to query, or current map if empty. 11 | * 12 | * @return True on contains a static spawn, false otherwise. 13 | */ 14 | native bool IsStaticWitchMap(const char[] map = ""); 15 | 16 | /** 17 | * @brief Check if the current map contains a static tank spawn. 18 | * @remarks Map string will be converted to lowercase internally. 19 | * 20 | * @param map Specific map to query, or current map if empty. 21 | * 22 | * @return True on contains a static spawn, false otherwise. 23 | */ 24 | native bool IsStaticTankMap(const char[] map = ""); 25 | 26 | /** 27 | * @brief Validate the flow percentage of tank on current map. 28 | * @remarks Passing 0 is allowed and considered disabling. 29 | * 30 | * @param percent Flow percentage to check. 31 | * 32 | * @return True on valid, false otherwise. 33 | */ 34 | native bool IsTankPercentValid(int percent); 35 | 36 | /** 37 | * @brief Validate the flow percentage of witch on current map. 38 | * @remarks Passing 0 is allowed and considered disabling. 39 | * 40 | * @param percent Flow percentage to check. 41 | * @param ignoreBlock Ignore percent block due to tank percent. 42 | * 43 | * @return True on valid, false otherwise. 44 | */ 45 | native bool IsWitchPercentValid(int percent, bool ignoreBlock = false); 46 | 47 | /** 48 | * @brief Check if the flow percentage of witch is blocked due to current tank percent. 49 | * @remarks The blocked range covers as much as the value of convar "sm_witch_avoid_tank_spawn", 50 | * taking current tank percent as middle point. 51 | * 52 | * @param percent Flow percentage to check. 53 | * 54 | * @return True on blocked, false otherwise. 55 | */ 56 | native bool IsWitchPercentBlockedForTank(int percent); 57 | 58 | /** 59 | * @brief Set the flow percentage of tank on current map. 60 | * @remarks Passing 0 is allowed and will disable flow tank. 61 | * 62 | * @param percent Flow percentage to check. 63 | * 64 | * @return True on success, false otherwise. 65 | */ 66 | native bool SetTankPercent(int percent); 67 | 68 | /** 69 | * @brief Set the flow percentage of witch on current map. 70 | * @remarks Passing 0 is allowed and will disable flow witch. 71 | * 72 | * @param percent Flow percentage to check. 73 | * 74 | * @return True on success, false otherwise. 75 | */ 76 | native bool SetWitchPercent(int percent); 77 | 78 | public SharedPlugin __pl_witch_and_tankifier = 79 | { 80 | name = "witch_and_tankifier", 81 | file = "witch_and_tankifier.smx", 82 | #if defined REQUIRE_PLUGIN 83 | required = 1, 84 | #else 85 | required = 0, 86 | #endif 87 | }; 88 | 89 | #if !defined REQUIRE_PLUGIN 90 | public void __pl_witch_and_tankifier_SetNTVOptional() 91 | { 92 | MarkNativeAsOptional("IsStaticWitchMap"); 93 | MarkNativeAsOptional("IsStaticTankMap"); 94 | MarkNativeAsOptional("IsTankPercentValid"); 95 | MarkNativeAsOptional("IsWitchPercentValid"); 96 | MarkNativeAsOptional("SetTankPercent"); 97 | MarkNativeAsOptional("SetWitchPercent"); 98 | } 99 | #endif -------------------------------------------------------------------------------- /l4d2_bot_spit_ignite_gascan.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define L4D2UTIL_STOCKS_ONLY 1 4 | #include 5 | 6 | #pragma newdecls required 7 | 8 | #define TICK_TIME 0.199951 9 | 10 | ConVar cvarSpitCanHarmGascan; 11 | 12 | Handle hGascanIgnite; 13 | int g_iTickCount = 0; 14 | 15 | public Plugin myinfo = 16 | { 17 | name = "[L4D2] Allow Bot Spitter Ignite Gascan", 18 | author = "海洋空氣", 19 | description = "", 20 | version = "1.0", 21 | url = "https://steamcommunity.com/id/larkspur2017/" 22 | }; 23 | 24 | public void OnPluginStart() 25 | { 26 | cvarSpitCanHarmGascan = CreateConVar("coop_spit_can_harm_gascan", "1", ""); 27 | } 28 | 29 | public void L4D2_CInsectSwarm_CanHarm_Post(int acid, int spitter, int entity) 30 | { 31 | int weaponId = IdentifyWeapon(entity); 32 | if (weaponId == WEPID_GASCAN) { 33 | if (GetConVarBool(cvarSpitCanHarmGascan)) { 34 | float time = GetConVarFloat(FindConVar("gascan_spit_time")); 35 | 36 | g_iTickCount++; 37 | if (hGascanIgnite == INVALID_HANDLE) { 38 | hGascanIgnite = CreateTimer(time, Timer_GascanIgnite, entity); 39 | } 40 | } 41 | } 42 | } 43 | 44 | public Action Timer_GascanIgnite(Handle timer, int entity) 45 | { 46 | float time = GetConVarFloat(FindConVar("gascan_spit_time")); 47 | float igniteTick = time / TICK_TIME; 48 | if (g_iTickCount >= igniteTick) { 49 | // Ignite 50 | SetEntProp(entity, Prop_Data, "m_iHealth", 0); 51 | } 52 | CloseHandle(hGascanIgnite); 53 | g_iTickCount = 0; 54 | return Plugin_Continue; 55 | } -------------------------------------------------------------------------------- /l4d2_drop.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #define PLUGIN_VERSION "1.5.0" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | bool GameStarted; 12 | Handle hDropMeleeUnsafe; 13 | 14 | float PressTime[MAXPLAYERS+1]; 15 | 16 | int MODEL_DEFIB; 17 | char WeaponNames[][] = 18 | { 19 | "weapon_pumpshotgun", 20 | "weapon_autoshotgun", 21 | "weapon_rifle", 22 | "weapon_smg", 23 | "weapon_hunting_rifle", 24 | "weapon_sniper_scout", 25 | "weapon_sniper_military", 26 | "weapon_sniper_awp", 27 | "weapon_smg_silenced", 28 | "weapon_smg_mp5", 29 | "weapon_shotgun_spas", 30 | "weapon_shotgun_chrome", 31 | "weapon_rifle_sg552", 32 | "weapon_rifle_desert", 33 | "weapon_rifle_ak47", 34 | "weapon_grenade_launcher", 35 | "weapon_rifle_m60", //0-16 36 | "weapon_pistol", 37 | "weapon_pistol_magnum", 38 | "weapon_chainsaw", 39 | "weapon_melee", //17-20 40 | "weapon_pipe_bomb", 41 | "weapon_molotov", 42 | "weapon_vomitjar", //21-23 43 | "weapon_first_aid_kit", 44 | "weapon_defibrillator", 45 | "weapon_upgradepack_explosive", 46 | "weapon_upgradepack_incendiary", //24-27 47 | "weapon_pain_pills", 48 | "weapon_adrenaline", //28-29 49 | "weapon_gascan", 50 | "weapon_propanetank", 51 | "weapon_oxygentank", 52 | "weapon_gnome", 53 | "weapon_cola_bottles", 54 | "weapon_fireworkcrate" //30-35 55 | }; 56 | 57 | public Plugin myinfo = 58 | { 59 | name = "[L4D2] Weapon Drop", 60 | author = "Machine, dcx2, Electr000999", 61 | description = "Allows players to drop the weapon they are holding", 62 | version = PLUGIN_VERSION, 63 | url = "www.AlliedMods.net" 64 | }; 65 | 66 | public void OnPluginStart() 67 | { 68 | CreateConVar("sm_drop_version", PLUGIN_VERSION, "[L4D2] Weapon Drop Version", FCVAR_SPONLY|FCVAR_REPLICATED); 69 | hDropMeleeUnsafe = CreateConVar("sm_drop_melee_unsafe", "1", "Enable drop melee weapon out unsafe area."); 70 | 71 | HookEvent("mission_lost", Event_MissionLost); 72 | HookEvent("round_end", Event_MissionLost); 73 | HookEvent("map_transition", Event_MissionLost); 74 | 75 | LoadTranslations("common.phrases"); 76 | } 77 | 78 | public void OnMapStart() 79 | { 80 | GameStarted = false; 81 | MODEL_DEFIB = PrecacheModel("models/w_models/weapons/w_eq_defibrillator.mdl", true); 82 | } 83 | 84 | public Action L4D_OnFirstSurvivorLeftSafeArea(int client) 85 | { 86 | GameStarted = true; 87 | } 88 | 89 | public void Event_MissionLost(Handle event, char[] name, bool dontBroadcast) 90 | { 91 | GameStarted = false; 92 | } 93 | 94 | public Action OnPlayerRunCmd(int client, int& buttons, int& impuls, float vel[3], float angles[3], int& weapon) 95 | { 96 | if (impuls == 201) { 97 | if(GetClientTeam(client) == 2 && !IsFakeClient(client) && IsPlayerAlive(client)) 98 | { 99 | float time = GetEngineTime(); 100 | if(time - PressTime[client] < 0.3) 101 | { 102 | Command_Drop(client, 0); 103 | PressTime[client] = 0.0; 104 | } 105 | else PressTime[client]=time; 106 | } 107 | } 108 | } 109 | 110 | public Action Command_Drop(int client, int args) 111 | { 112 | int slot; 113 | char weapon[32]; 114 | GetClientWeapon(client, weapon, sizeof(weapon)); 115 | for (int count = 0; count <= 35; count++) 116 | { 117 | switch(count) 118 | { 119 | case 17: slot = 1; 120 | case 21: slot = 2; 121 | case 24: slot = 3; 122 | case 28: slot = 4; 123 | case 30: slot = 5; 124 | } 125 | 126 | if (GameStarted) { 127 | if ( GetConVarBool(hDropMeleeUnsafe) ) { 128 | if (slot != 1) continue; 129 | } 130 | else continue; 131 | } 132 | 133 | if (StrEqual(weapon, WeaponNames[count])) 134 | { 135 | DropSlot(client, slot); 136 | } 137 | } 138 | return Plugin_Handled; 139 | } 140 | 141 | public void DropSlot(int client, int slot) 142 | { 143 | if (client > 0 && IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == 2) 144 | { 145 | if (GetPlayerWeaponSlot(client, slot) > 0) 146 | { 147 | int weapon = GetPlayerWeaponSlot(client, slot); 148 | SDKCallWeaponDrop(client, weapon); 149 | } 150 | } 151 | } 152 | 153 | stock void SDKCallWeaponDrop(int client, int weapon) 154 | { 155 | char classname[32]; 156 | float vecAngles[3], vecTarget[3], vecVelocity[3]; 157 | 158 | if (GetPlayerEye(client, vecTarget)) 159 | { 160 | GetClientEyeAngles(client, vecAngles); 161 | GetAngleVectors(vecAngles, vecVelocity, NULL_VECTOR, NULL_VECTOR); 162 | vecVelocity[0] *= 300.0; 163 | vecVelocity[1] *= 300.0; 164 | vecVelocity[2] *= 300.0; 165 | 166 | SDKHooks_DropWeapon(client, weapon, NULL_VECTOR, NULL_VECTOR); 167 | 168 | TeleportEntity(weapon, NULL_VECTOR, NULL_VECTOR, vecVelocity); 169 | GetEdictClassname(weapon, classname, sizeof(classname)); 170 | if (StrEqual(classname,"weapon_defibrillator")) 171 | { 172 | SetEntProp(weapon, Prop_Send, "m_iWorldModelIndex", MODEL_DEFIB); 173 | } 174 | } 175 | } 176 | stock bool GetPlayerEye(int client, float vecTarget[3]) 177 | { 178 | float Origin[3], Angles[3]; 179 | GetClientEyePosition(client, Origin); 180 | GetClientEyeAngles(client, Angles); 181 | 182 | Handle trace = TR_TraceRayFilterEx(Origin, Angles, MASK_SHOT, RayType_Infinite, TraceEntityFilterPlayer); 183 | if (TR_DidHit(trace)) 184 | { 185 | TR_GetEndPosition(vecTarget, trace); 186 | CloseHandle(trace); 187 | return true; 188 | } 189 | CloseHandle(trace); 190 | return false; 191 | } 192 | 193 | public bool TraceEntityFilterPlayer(int entity, int contentsMask) 194 | { 195 | return entity > MaxClients || !entity; 196 | } 197 | -------------------------------------------------------------------------------- /l4d2_jockey_teleport.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #include 5 | #include 6 | 7 | float pos1[MAXPLAYERS][3]; 8 | float pos2[MAXPLAYERS][3]; 9 | bool bride[MAXPLAYERS]; 10 | 11 | // 被猴子套,一秒内移动距离超过一定值时,将猴子和生还者瞬移到前一秒的位置 12 | // shabi bug,不知道什么原因导致的,非常怀疑是 The Last Stand 更新后传送机制的 bug,因为是用的游戏自带的传送机制,其他插件应该不太可能会出现这个问题。 13 | // !fuck jockey,建议加入此指令。 14 | // 对策插件也是无奈之举,如果有人能发现是什么原因并修复就可以把这个插件给删了。 15 | // 至于为什么不用插件版的传送,主要还是难度问题。 16 | 17 | 18 | public void OnPluginStart() 19 | { 20 | HookEvent("jockey_ride", Event_JockeyRide, EventHookMode_PostNoCopy); 21 | HookEvent("jockey_ride_end", Event_JockeyRideEnd, EventHookMode_PostNoCopy); 22 | } 23 | 24 | public Action Event_JockeyRide(Handle event, const char[] name, bool dontBroadcast) 25 | { 26 | int jockey = GetClientOfUserId(GetEventInt(event, "userid")); 27 | int victim = GetClientOfUserId(GetEventInt(event, "victim")); 28 | 29 | if ( !isClientValid(jockey) || !isClientValid(victim) ) return; 30 | 31 | bride[victim] = true; 32 | // PrintToChatAll("jockey_ride, %d ride %d", jockey, victim); 33 | 34 | GetClientAbsOrigin(victim, pos1[victim]); 35 | // PrintToChatAll("victim origin position: %f, %f, %f", pos1[victim][0], pos1[victim][1], pos1[victim][2]); 36 | 37 | CreateTimer(1.0, Timer_CheckPos, victim, TIMER_REPEAT); 38 | } 39 | 40 | public Action Timer_CheckPos(Handle timer, int victim) 41 | { 42 | if (!isClientValid(victim)) return Plugin_Stop; 43 | if ( !bride[victim] ) return Plugin_Stop; 44 | 45 | GetClientAbsOrigin(victim, pos2[victim]); 46 | // PrintToChatAll("victim second position: %f, %f, %f", pos2[victim][0], pos2[victim][1], pos2[victim][2]); 47 | float distance = GetVectorDistance(pos1[victim], pos2[victim], false); 48 | if (distance > 500.0) { 49 | // Normal distance on ground is 200, consider about gravity and other factors, add it to 500; 50 | // PrintToChatAll("%N has been ridden away, distance: %f", victim, distance); 51 | TeleportEntity(victim, pos1[victim], NULL_VECTOR, NULL_VECTOR); 52 | } else { 53 | // PrintToChatAll("normal condition, distance: %f", distance); 54 | pos1[victim] = pos2[victim]; 55 | } 56 | return Plugin_Continue; 57 | } 58 | 59 | public Action Event_JockeyRideEnd(Handle event, const char[] name, bool dontBroadcast) 60 | { 61 | int victim = GetClientOfUserId(GetEventInt(event, "victim")); 62 | bride[victim] = false; 63 | // PrintToChatAll("jockey ride end."); 64 | } 65 | 66 | bool isClientValid(int client) 67 | { if (client <= 0 || client > MaxClients) return false; 68 | if (!IsClientConnected(client)) return false; 69 | if (!IsClientInGame(client)) return false; 70 | return true; 71 | } -------------------------------------------------------------------------------- /l4d2_sniper_stats.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * Wingman 配套插件,想法也很简单:提高玩家打狙的积极性 + 装逼是第一动力。 3 | * 有遇到一个问题,击杀 tank 的时候会触发好几次 player_hurt,所以加了 oldShots 来判断。 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #pragma semicolon 1 13 | #pragma newdecls required 14 | 15 | #define HITGROUP_GENERIC 0 16 | #define HITGROUP_HEAD 1 17 | #define HITGROUP_CHEST 2 18 | #define HITGROUP_STOMACH 3 19 | #define HITGROUP_LEFTARM 4 20 | #define HITGROUP_RIGHTARM 5 21 | #define HITGROUP_LEFTLEG 6 22 | #define HITGROUP_RIGHTLEG 7 23 | #define HITGROUP_GEAR 10 24 | 25 | bool GameStarted; 26 | 27 | int iShots[MAXPLAYERS + 1] = 0; // [总共开枪] 28 | int oldShots[MAXPLAYERS + 1] = 0; 29 | int iHitsSI[MAXPLAYERS + 1] = 0; // [命中特感] 30 | int iHeadShotsSI[MAXPLAYERS + 1] = 0; // [爆头特感] 31 | int iHitsCI[MAXPLAYERS + 1] = 0; // [命中特感] 32 | int iHeadShotsCI[MAXPLAYERS + 1] = 0; // [爆头特感] 33 | 34 | public Plugin myinfo = 35 | { 36 | name = "[L4D2] Shot & Hit Counter", 37 | author = "海洋空氣", 38 | description = "", 39 | version = "0.1", 40 | url = "https://steamcommunity.com/id/larkspur2017/" 41 | }; 42 | 43 | public void OnPluginStart() { 44 | HookEvent("player_hurt", Event_PlayerHurt, EventHookMode_Post); 45 | HookEvent("infected_hurt",Event_InfectedHurt, EventHookMode_Post); 46 | HookEvent("weapon_fire", Event_WeaponFire); 47 | HookEvent("mission_lost", Event_MissionLost); 48 | HookEvent("round_end", Event_MissionLost); 49 | HookEvent("map_transition", Event_MissionLost); 50 | } 51 | 52 | public void OnMapStart() 53 | { 54 | GameStarted = false; 55 | } 56 | 57 | public Action L4D_OnFirstSurvivorLeftSafeArea(int client) 58 | { 59 | GameStarted = true; 60 | } 61 | 62 | public void Event_MissionLost(Handle event, const char[] name, bool dontBroadcast) 63 | { 64 | GameStarted = false; 65 | 66 | for (int client = 1; client <= MaxClients; client++) { 67 | if (bIsSurvivor(client) && iShots[client] > 0) { 68 | CPrintToChatAll("{default}[Wingman] {olive}%N {default}在本回合一共开了 {olive}%d {default}枪, {olive}%d{red}[%d]{default}发命中特感, {olive}%d{red}[%d]{default}发命中小僵尸.", client, iShots[client], iHitsSI[client], iHeadShotsSI[client], iHitsCI[client], iHeadShotsCI[client]); 69 | } 70 | iShots[client] = 0; 71 | iHitsSI[client] = 0; 72 | iHeadShotsSI[client] = 0; 73 | iHitsCI[client] = 0; 74 | iHeadShotsCI[client] = 0; 75 | } 76 | } 77 | 78 | public void Event_PlayerHurt(Handle event, const char[] name, bool dontBroadcast) 79 | { 80 | int victimId = GetClientOfUserId(GetEventInt(event, "userid")); 81 | int attackerId = GetClientOfUserId(GetEventInt(event, "attacker")); 82 | if (!bIsSurvivor(attackerId) || !bIsInfected(victimId)) return; 83 | char weapon[64]; 84 | GetEventString(event, "weapon", weapon, sizeof(weapon)); 85 | int hitgroup = GetEventInt(event, "hitgroup"); 86 | 87 | if (GameStarted && (StrContains(weapon, "pistol", false) >= 0 || StrContains(weapon, "sniper", false) >= 0 || StrContains(weapon, "hunting", false) >= 0)) { 88 | if (iShots[attackerId] != oldShots[attackerId]) { 89 | iHitsSI[attackerId]++; 90 | oldShots[attackerId] = iShots[attackerId]; 91 | } 92 | if (hitgroup == HITGROUP_HEAD) { 93 | iHeadShotsSI[attackerId]++; 94 | } 95 | } 96 | } 97 | 98 | public void Event_InfectedHurt(Handle event, const char[] name, bool dontBroadcast) 99 | { 100 | int attackerId = GetClientOfUserId(GetEventInt(event, "attacker")); 101 | if (!bIsSurvivor(attackerId)) return; 102 | int hitgroup = GetEventInt(event, "hitgroup"); 103 | char weapon[64]; 104 | GetClientWeapon(attackerId, weapon, sizeof(weapon)); 105 | 106 | if (GameStarted && (StrContains(weapon, "pistol", false) >= 0 || StrContains(weapon, "sniper", false) >= 0 || StrContains(weapon, "hunting", false) >= 0)) { 107 | if (iShots[attackerId] != oldShots[attackerId]) { 108 | iHitsCI[attackerId]++; 109 | oldShots[attackerId] = iShots[attackerId]; 110 | } 111 | if (hitgroup == HITGROUP_HEAD) { 112 | iHeadShotsCI[attackerId]++; 113 | } 114 | } 115 | } 116 | 117 | public void Event_WeaponFire(Handle event, const char[] name, bool dontBroadcast) 118 | { 119 | int client = GetClientOfUserId(GetEventInt(event, "userid")); 120 | int count = GetEventInt(event, "count"); 121 | 122 | if (GameStarted && bIsSurvivor(client)) { 123 | char weapon[64]; 124 | GetEventString(event, "weapon", weapon, sizeof(weapon)); 125 | if (StrContains(weapon, "pistol", false) >= 0 || StrContains(weapon, "sniper", false) >= 0) 126 | iShots[client] += count; 127 | } 128 | } 129 | 130 | bool bIsSurvivor(int client) { 131 | return client > 0 && client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client) && GetClientTeam(client) == 2; 132 | } 133 | 134 | bool bIsInfected(int client) { 135 | return client > 0 && client <= MaxClients && GetClientTeam(client) == 3; 136 | } -------------------------------------------------------------------------------- /l4d2_votetospec.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int SpecClient; 9 | Handle g_hVote = INVALID_HANDLE; 10 | 11 | public void OnPluginStart() 12 | { 13 | RegConsoleCmd("sm_votespec", VoteSpec, "Vote player to spectator."); 14 | } 15 | 16 | public Action VoteSpec(int client, int args) 17 | { 18 | draw_function(client); 19 | } 20 | 21 | public Action draw_function(int client) 22 | { 23 | // 创建面板 24 | Handle menu = CreateMenu(MenuHandler); 25 | SetMenuTitle(menu, "投票将玩家移至旁观"); 26 | SetMenuExitBackButton(menu, true); 27 | SetMenuExitButton(menu, true); 28 | char userid[12]; 29 | char name[32]; 30 | for (int i = 1; i <= MaxClients; i++) { 31 | if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i)) { 32 | if (GetClientTeam(i) == 2) { 33 | IntToString(GetClientUserId(i), userid, sizeof(userid)); 34 | GetClientName(i, name, sizeof(name)); 35 | AddMenuItem(menu, userid, name); 36 | } 37 | } 38 | } 39 | DisplayMenu(menu, client, 15); 40 | return Plugin_Handled; 41 | } 42 | 43 | public int MenuHandler(Handle menu, MenuAction action, int cindex, int itempos) 44 | { 45 | if (action == MenuAction_Select) { 46 | char sInfo[64]; 47 | GetMenuItem(menu, itempos, sInfo, 64); 48 | SpecClient = GetClientOfUserId(StringToInt(sInfo, 10)); 49 | CallVote(cindex); 50 | } 51 | } 52 | 53 | public void CallVote(int client) 54 | { 55 | if ( IsNewBuiltinVoteAllowed() ) { 56 | int iNumPlayers; 57 | int iPlayers[MAXPLAYERS]; 58 | for (int i = 1; i <= MaxClients; i++) { 59 | if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) != 2)) { 60 | continue; 61 | } 62 | iPlayers[iNumPlayers++] = i; 63 | } 64 | 65 | char sBuffer[64]; 66 | Format(sBuffer, sizeof(sBuffer), "将 %N 移至旁观", SpecClient); 67 | 68 | g_hVote = CreateBuiltinVote(VoteSpecHandler, BuiltinVoteType_Custom_YesNo, BuiltinVoteAction_Cancel | BuiltinVoteAction_VoteEnd | BuiltinVoteAction_End); 69 | SetBuiltinVoteArgument(g_hVote, sBuffer); 70 | SetBuiltinVoteInitiator(g_hVote, client); 71 | SetBuiltinVoteResultCallback(g_hVote, VoteResultHandler); 72 | DisplayBuiltinVote(g_hVote, iPlayers, iNumPlayers, 15); 73 | } 74 | } 75 | 76 | public int VoteResultHandler(Handle vote, int num_votes, int num_clients, const int[][] client_info, int num_items, const int[][] item_info) 77 | { 78 | for (int i = 0; i < num_items; i++) { 79 | if (item_info[i][BUILTINVOTEINFO_ITEM_INDEX] == BUILTINVOTES_VOTE_YES) { 80 | if (item_info[i][BUILTINVOTEINFO_ITEM_VOTES] > (num_votes / 2)) { 81 | char sBuffer[64]; 82 | Format(sBuffer, sizeof(sBuffer), "已将 %N 移至旁观", SpecClient); 83 | DisplayBuiltinVotePass(vote, sBuffer); 84 | ChangeClientTeam(SpecClient, 1); 85 | return; 86 | } 87 | } 88 | } 89 | DisplayBuiltinVoteFail(vote, BuiltinVoteFail_Loses); 90 | } 91 | 92 | public int VoteSpecHandler(Handle vote, BuiltinVoteAction action, int param1, int param2) 93 | { 94 | switch (action) { 95 | case BuiltinVoteAction_End: { 96 | g_hVote = INVALID_HANDLE; 97 | CloseHandle(vote); 98 | } 99 | case BuiltinVoteAction_Cancel: { 100 | DisplayBuiltinVoteFail(vote, view_as(param1) ); 101 | } 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /l4d2_wave_spawner.sp: -------------------------------------------------------------------------------- 1 | #pragma newdecls required 2 | 3 | #include 4 | #include 5 | 6 | Handle hSpawnStarted; 7 | 8 | bool bIsRoundStarted = false; 9 | 10 | public void OnPluginStart() 11 | { 12 | RegConsoleCmd("starttest", starttest); 13 | RegConsoleCmd("stoptest", stoptest); 14 | 15 | hSpawnStarted = CreateConVar("wave_spawn_start", "0"); 16 | 17 | HookEvent("versus_round_start", Event_VSRoundStart, EventHookMode_PostNoCopy); 18 | HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy); 19 | HookEvent("map_transition", Event_RoundEnd, EventHookMode_PostNoCopy); 20 | } 21 | 22 | public Action starttest(int client,int args) 23 | { 24 | CheatCommand("script_reload_code", "versus.nut"); 25 | CheatCommand("script_reload_code", "coop.nut"); 26 | } 27 | 28 | public Action stoptest(int client,int args) 29 | { 30 | CheatCommand("script_reload_code", "versus.nut"); 31 | CheatCommand("script_reload_code", "coop.nut"); 32 | } 33 | 34 | public Action Event_VSRoundStart(Handle event, char[] name, bool dontBroadcast) 35 | { 36 | hSpawnStarted 37 | } 38 | 39 | public Action Event_RoundEnd(Handle event, char[] name, bool dontBroadcast) 40 | { 41 | 42 | } 43 | 44 | public Action Timer_Toggle(Handle timer, int limit) 45 | { 46 | SetConVarBool(hSpawnStarted, !GetConVarBool(hSpawnStarted)); 47 | } 48 | 49 | public void CheatCommand(char[] strCommand, char[] strParam1) 50 | { 51 | for (int client = 1; client <= MaxClients; ++client) 52 | { 53 | if (IsClientInGame(client)) 54 | { 55 | int flags = GetCommandFlags(strCommand); 56 | SetCommandFlags(strCommand, flags & ~FCVAR_CHEAT); 57 | FakeClientCommand(client, "%s %s", strCommand, strParam1); 58 | SetCommandFlags(strCommand, flags); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /mob_interval_limit.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #include 5 | #include 6 | 7 | ConVar hMobLimitEnabled; 8 | ConVar hMobInterval; 9 | ConVar hDebug; 10 | ConVar hMegaMobSize; 11 | ConVar hMobSpawnMinSize; 12 | ConVar hMobSpawnMaxSize; 13 | int iMegaMobSize; 14 | int iMobSpawnMinSize; 15 | int iMobSpawnMaxSize; 16 | bool bAllowSpawnMobs = true; 17 | bool bAllowMobsChange = true; 18 | 19 | public void OnPluginStart() 20 | { 21 | hMobLimitEnabled = CreateConVar("mob_spawn_limit_enabled", "0"); 22 | hMobInterval = CreateConVar("mob_spawn_block_interval", "8.0"); 23 | hDebug = CreateConVar("mob_spawn_debug", "0"); 24 | 25 | RegServerCmd("sm_mob_lock", LockMobs); 26 | RegServerCmd("sm_mob_unlock", UnlockMobs); 27 | 28 | hMegaMobSize = FindConVar("z_mega_mob_size"); 29 | hMobSpawnMinSize = FindConVar("z_mob_spawn_min_size"); 30 | hMobSpawnMaxSize = FindConVar("z_mob_spawn_max_size"); 31 | 32 | HookConVarChange(hMegaMobSize, OnMobChanged); 33 | HookConVarChange(hMobSpawnMinSize, OnMobChanged); 34 | HookConVarChange(hMobSpawnMaxSize, OnMobChanged); 35 | } 36 | 37 | public Action L4D_OnSpawnMob(int &amount) 38 | { 39 | if (!hMobLimitEnabled) return Plugin_Continue; 40 | 41 | int mobSize = GetConVarInt(FindConVar("z_mega_mob_size")); 42 | float mobInterval = GetConVarFloat(hMobInterval); 43 | bool iDebug = GetConVarBool(hDebug); 44 | if (iDebug) { 45 | PrintToChatAll("mob original amount: %d", amount); 46 | } 47 | if (bAllowSpawnMobs) { 48 | if (amount > mobSize) { 49 | amount = mobSize; 50 | } 51 | bAllowSpawnMobs = false; 52 | if (iDebug) { 53 | PrintToChatAll("mob altered amount: %d", amount); 54 | } 55 | CreateTimer(mobInterval, MobsIntervalTimer); 56 | return Plugin_Changed; 57 | } else { 58 | return Plugin_Handled; 59 | } 60 | } 61 | 62 | public Action MobsIntervalTimer(Handle timer, int client) 63 | { 64 | bAllowSpawnMobs = true; 65 | } 66 | 67 | public Action LockMobs(int args) 68 | { 69 | bAllowMobsChange = false; 70 | 71 | iMegaMobSize = GetConVarInt(hMegaMobSize); 72 | iMobSpawnMinSize = GetConVarInt(hMobSpawnMinSize); 73 | iMobSpawnMaxSize = GetConVarInt(hMobSpawnMaxSize); 74 | } 75 | 76 | public Action UnlockMobs(int args) 77 | { 78 | bAllowMobsChange = true; 79 | } 80 | 81 | public void OnMobChanged(ConVar convar, const char[] oldValue, const char[] newValue) 82 | { 83 | if (!bAllowMobsChange) { 84 | SetConVarInt(hMegaMobSize, iMegaMobSize); 85 | SetConVarInt(hMobSpawnMinSize, iMobSpawnMinSize); 86 | SetConVarInt(hMobSpawnMaxSize, iMobSpawnMaxSize); 87 | } 88 | } -------------------------------------------------------------------------------- /pills_giver.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #include 5 | #include 6 | #define L4D2UTIL_STOCKS_ONLY 1 7 | #include 8 | 9 | Handle hPillsEnabled; 10 | Handle hPillsSurvivor; 11 | Handle hPillsTeam; 12 | Handle hPillsMapKill; 13 | Handle hPillsDelay; 14 | 15 | int gavePillsSurvivorCount[MAXPLAYERS]; 16 | char clientModel[MAXPLAYERS][64]; 17 | 18 | public Plugin myinfo = 19 | { 20 | name = "Pills Giver", 21 | author = "海洋空氣", 22 | description = "give more pills to survivors", 23 | version = "1.1", 24 | url = "https://steamcommunity.com/id/larkspur2017/" 25 | }; 26 | 27 | public void OnPluginStart() 28 | { 29 | hPillsEnabled = CreateConVar("ast_pills_enabled", "0", "发药开关", FCVAR_PROTECTED, true, 0.0, false); 30 | hPillsSurvivor = CreateConVar("ast_pills_survivor", "1", "个人发药次数,-1 不限制,0 不发药", FCVAR_PROTECTED, true, 0.0, false); 31 | hPillsTeam = CreateConVar("ast_pills_team", "4", "团队发药次数,-1 不限制,0 不发药", FCVAR_PROTECTED, true, 0.0, false); 32 | hPillsMapKill = CreateConVar("ast_pills_map_kill", "0", "删除地图刷的药", FCVAR_PROTECTED, true, 0.0, false); 33 | hPillsDelay = CreateConVar("ast_pills_delay", "5.0", "发药延迟时间", FCVAR_PROTECTED, true, 0.0, false); 34 | 35 | HookEvent("round_start", Event_RoundStart, EventHookMode_Post); 36 | HookEvent("weapon_drop", Event_WeaponDrop, EventHookMode_Post); 37 | } 38 | 39 | public Action Event_WeaponDrop(Handle event, const char[] name, bool dontBroadcast) 40 | { 41 | if (GetConVarInt(hPillsEnabled)) 42 | { 43 | int client = GetClientOfUserId(GetEventInt(event, "userid")); 44 | if (!isSurvivor(client)) return Plugin_Handled; 45 | 46 | char weapon[32]; 47 | GetEventString(event, "item", weapon, sizeof(weapon)); 48 | GetClientModel(client, clientModel[client], sizeof(clientModel)); 49 | 50 | if (StrEqual(weapon, "pain_pills", false)) 51 | { 52 | CreateTimer(0.1, Timer_DoubleCheck, client); 53 | } 54 | } 55 | return Plugin_Handled; 56 | } 57 | 58 | public Action Timer_DoubleCheck(Handle timer, int client) 59 | { 60 | if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) return Plugin_Handled; 61 | float delay = GetConVarFloat(hPillsDelay) - 0.1; // 减去 double check 的延迟 62 | CreateTimer(delay, Timer_GivePill, client); 63 | return Plugin_Handled; 64 | } 65 | 66 | public Action Timer_GivePill(Handle timer, int client) 67 | { 68 | // 检测模型 69 | char model[64]; 70 | GetClientModel(client, model, sizeof(model)); 71 | // 如果模型没变化,则直接进入发药流程,否则需要寻找模型当前使用者 72 | if (!StrEqual(clientModel[client], model)) { 73 | for (int i = 1; i <= MaxClients; i++) { 74 | if (!isSurvivor(i)) continue; 75 | 76 | char iModel[64]; 77 | GetClientModel(i, iModel, sizeof(iModel)); 78 | if (StrEqual(clientModel[client], iModel)) { 79 | client = i; 80 | break; 81 | } 82 | } 83 | } 84 | 85 | int currentSlotItem = GetPlayerWeaponSlot(client, 4); 86 | if ( ( GetConVarInt(hPillsSurvivor) == -1 || gavePillsSurvivorCount[client] < GetConVarInt(hPillsSurvivor) ) && // 个人发药次数无限 或 个人发药次数未达上限 87 | ( GetConVarInt(hPillsTeam) == -1 || GetGavePillsTeamCount() < GetConVarInt(hPillsTeam) ) && // 团队发药次数无限 或 团队发药次数未达上限 88 | currentSlotItem == -1 && IsPlayerAlive(client)) { 89 | int pill = CreateEntityByName("weapon_pain_pills"); 90 | float clientOrigin[3]; 91 | GetClientAbsOrigin(client, clientOrigin); 92 | clientOrigin[2] += 10.0; 93 | TeleportEntity(pill, clientOrigin, NULL_VECTOR, NULL_VECTOR); 94 | DispatchSpawn(pill); 95 | EquipPlayerWeapon(client, pill); 96 | gavePillsSurvivorCount[client]++; 97 | 98 | // Call Event 99 | Handle hFakeEvent = CreateEvent("weapon_given"); 100 | SetEventInt(hFakeEvent, "userid", GetClientUserId(client)); 101 | SetEventInt(hFakeEvent, "giver", GetClientUserId(client)); 102 | SetEventInt(hFakeEvent, "weapon", view_as(15)); 103 | SetEventInt(hFakeEvent, "weaponentid", pill); 104 | 105 | FireEvent(hFakeEvent); 106 | } 107 | return Plugin_Handled; 108 | } 109 | 110 | public int GetGavePillsTeamCount() 111 | { 112 | int count = 0; 113 | for (int client = 1; client <= MaxClients; client++) { 114 | if (IsClientInGame(client) && GetClientTeam(client) == 2) { 115 | count += gavePillsSurvivorCount[client]; 116 | } 117 | } 118 | return count; 119 | } 120 | 121 | public Action Event_RoundStart(Handle event, const char[] name, bool dontBroadcast) 122 | { 123 | for (int client = 1; client <= MaxClients; client++) { 124 | gavePillsSurvivorCount[client] = 0; 125 | } 126 | 127 | if ( GetConVarBool(hPillsMapKill) ) { 128 | CreateTimer(5.0, Timer_KillMapPills, _, TIMER_FLAG_NO_MAPCHANGE); 129 | } 130 | return Plugin_Handled; 131 | } 132 | 133 | // 来自 weaponrules 134 | Action Timer_KillMapPills(Handle timer) 135 | { 136 | int entcnt = GetEntityCount(); 137 | for (int ent = 1; ent <= entcnt; ent++) { 138 | int source = IdentifyWeapon(ent); 139 | if (source == WEPID_PAIN_PILLS) { 140 | AcceptEntityInput(ent, "kill"); 141 | } 142 | } 143 | return Plugin_Handled; 144 | } 145 | 146 | bool isSurvivor(int client) 147 | { 148 | if (client <= 0 || client > MaxClients) return false; 149 | if (!IsClientConnected(client)) return false; 150 | if (!IsClientInGame(client)) return false; 151 | return GetClientTeam(client) == 2; 152 | } -------------------------------------------------------------------------------- /script_reloader.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #include 5 | #include 6 | 7 | public void OnPluginStart() 8 | { 9 | RegConsoleCmd("sm_reloadscript", Cmd_Reload, "Reload Script"); 10 | } 11 | 12 | // From vscript_replacer by SilverShot 13 | public Action Cmd_Reload(int client, int args) 14 | { 15 | if( args != 1 ) 16 | { 17 | ReplyToCommand(client, "[SM] Usage: sm_reloadscript "); 18 | return Plugin_Handled; 19 | } 20 | 21 | // Games inbuilt method to execute VScripts. In L4D2 "script_execute" causes a memory leak, so using an entity instead. 22 | // Using an entity would probably prevent the script executing during hibernation, not sure if command would work then either though. 23 | 24 | int entity = CreateEntityByName("logic_script"); 25 | if( entity != -1 ) 26 | { 27 | char sFile[PLATFORM_MAX_PATH]; 28 | GetCmdArg(1, sFile, sizeof(sFile)); 29 | DispatchSpawn(entity); 30 | SetVariantString(sFile); 31 | AcceptEntityInput(entity, "RunScriptFile"); 32 | RemoveEdict(entity); 33 | } 34 | 35 | return Plugin_Handled; 36 | } -------------------------------------------------------------------------------- /server.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #include 3 | 4 | Handle emptyChangeMap = INVALID_HANDLE; 5 | float lastDisconnectTime; 6 | char g_strCampaignFirstMap[13][32]; 7 | 8 | #define RESTART_DELAY_EMPTY_SERVER 3.0 9 | 10 | public void OnPluginStart() 11 | { 12 | emptyChangeMap = CreateConVar("sv_emptychangemap", "1", "0|1"); 13 | RegAdminCmd("sv_restart", RestartServer, ADMFLAG_ROOT); 14 | } 15 | 16 | // 服务器没人时自动刷新 17 | public void OnClientDisconnect(int client) 18 | { 19 | if (IsClientInGame(client) && IsFakeClient(client)) return; 20 | float currenttime = GetGameTime(); 21 | if (lastDisconnectTime == currenttime) return; 22 | CreateTimer(RESTART_DELAY_EMPTY_SERVER, IsNobodyConnected, currenttime); 23 | lastDisconnectTime = currenttime; 24 | } 25 | 26 | public Action IsNobodyConnected(Handle timer, float timerDisconnectTime) 27 | { 28 | if (timerDisconnectTime != lastDisconnectTime) 29 | { 30 | return Plugin_Stop; 31 | } 32 | for (int i = 1; i <= MaxClients; i++) 33 | { 34 | if (IsClientConnected(i) && !IsFakeClient(i)) 35 | { 36 | return Plugin_Stop; 37 | } 38 | } 39 | if (GetConVarBool(emptyChangeMap)) 40 | { 41 | SetupMapStrings(); 42 | ServerCommand("changelevel %s", g_strCampaignFirstMap[RadomMap()]); 43 | } 44 | return Plugin_Stop; 45 | } 46 | 47 | public int RadomMap() 48 | { 49 | new RandomInt = GetRandomInt(0, 12); 50 | return RandomInt; 51 | } 52 | 53 | public void SetupMapStrings() 54 | { 55 | Format(g_strCampaignFirstMap[0], 32, "c1m1_hotel"); 56 | Format(g_strCampaignFirstMap[1], 32, "c14m1_junkyard"); 57 | Format(g_strCampaignFirstMap[2], 32, "c3m1_plankcountry"); 58 | Format(g_strCampaignFirstMap[3], 32, "c4m1_milltown_a"); 59 | Format(g_strCampaignFirstMap[4], 32, "c5m1_waterfront"); 60 | Format(g_strCampaignFirstMap[5], 32, "c6m1_riverbank"); 61 | Format(g_strCampaignFirstMap[6], 32, "c7m1_docks"); 62 | Format(g_strCampaignFirstMap[7], 32, "c8m1_apartment"); 63 | Format(g_strCampaignFirstMap[8], 32, "c9m1_alleys"); 64 | Format(g_strCampaignFirstMap[9], 32, "c10m1_caves"); 65 | Format(g_strCampaignFirstMap[10], 32, "c11m1_greenhouse"); 66 | Format(g_strCampaignFirstMap[11], 32, "c12m1_hilltop"); 67 | Format(g_strCampaignFirstMap[12], 32, "c13m1_alpinecreek"); 68 | } 69 | 70 | public Action RestartServer(int client, int args) { 71 | ServerCommand("sv_cheats 1;sv_crash;sv_cheats 0"); 72 | } -------------------------------------------------------------------------------- /unlimit_spawn.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma newdecls required 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | public Action L4D_OnIsTeamFull(int team, bool &full) 9 | { 10 | if (team == 3) { 11 | PrintToChatAll("L4D_OnIsTeamFull, 3"); 12 | full = false; 13 | return Plugin_Changed; 14 | } 15 | return Plugin_Continue; 16 | } -------------------------------------------------------------------------------- /versus2coop.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * 启发于 Anne 的对抗模式战役机制,之前也是用他的那套,后来因为想公开插件,他这套东西是不公开的,所以自己写了这个东西。 3 | * 带来了不少的 bug,但也都能解决,比较麻烦而已,典型的就是 第一回合是 versus,后面几个回合都是 coop,所以 stripper 写起来会很麻烦, 4 | * 有些地图是对抗和战役两套模式,像闪电突袭2的 m2,一张战役图,一张对抗图,要在 m1 战役模式下也把换图给定向对抗的 m2。 5 | * 总的来说利大于弊,但是更希望以后能有直接在战役模式下使用对抗特性。 6 | * 对抗特性有:tank 一拍多,打中人后没有捶胸口捶地板的动作,口水点油(这个 AI 特感好像不能实现),推 ht 猴子 fov 等。 7 | * 8 | * 战役 Tank 一拍多:https://github.com/Target5150/MoYu_Server_Stupid_Plugins/tree/master/The%20Last%20Stand/l4d_sweep_fist_patch 9 | * 战役 Tank 打人后无庆祝动作:https://forums.alliedmods.net/showthread.php?t=319029 10 | * 口水点油:forward Action L4D2_CInsectSwarm_CanHarm(int acid, int spitter, int entity) 11 | * fov for coop: 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #pragma newdecls required 18 | 19 | ConVar hGameMode; 20 | 21 | public Plugin myinfo = 22 | { 23 | name = "[L4D2] Versus-Like coop", 24 | author = "海洋空氣", 25 | description = "", 26 | version = "1.1", 27 | url = "https://steamcommunity.com/id/larkspur2017/" 28 | }; 29 | 30 | public void OnPluginStart() 31 | { 32 | hGameMode = FindConVar("mp_gamemode"); 33 | 34 | HookEvent("round_start", Event_RoundStart, EventHookMode_Pre); 35 | } 36 | 37 | public Action L4D2_OnEndVersusModeRound(bool countSurvivors) 38 | { 39 | SetConVarString(hGameMode, "coop"); 40 | return Plugin_Continue; 41 | } 42 | 43 | public Action Event_RoundStart(Handle event, const char[] name, bool dontBroadcast) 44 | { 45 | SetConVarString(hGameMode, "versus"); 46 | return Plugin_Continue; 47 | } -------------------------------------------------------------------------------- /weapon_slowdown.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * Wingman 配套插件,功能也很简单,要改部分武器的最大行走速度就直接使用 weapon attributes,不用额外加 cvar。 3 | */ 4 | 5 | #pragma semicolon 1 6 | #pragma newdecls required 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | Handle hEnable; 14 | Handle hSpeedUpEnable; 15 | Handle hSpeedUpInterval; 16 | 17 | float fSpeedUpTimer[MAXPLAYERS]; 18 | 19 | public Plugin myinfo = 20 | { 21 | name = "Weapon Slowdown", 22 | author = "海洋空氣", 23 | description = "Player will get different speed when they equip different weapon.", 24 | version = "1.0", 25 | url = "https://steamcommunity.com/id/larkspur2017/" 26 | } 27 | 28 | public void OnPluginStart() 29 | { 30 | hEnable = CreateConVar("weaponslowdown_enable","1", "持枪减速开关。"); 31 | hSpeedUpEnable = CreateConVar("weaponslowdown_kill_speedup_enable","1", "击杀特感恢复原速度。"); 32 | hSpeedUpInterval = CreateConVar("weaponslowdown_kill_speedup_interval","10.0", "击杀特感恢复原速度的时长。"); 33 | 34 | HookEvent("player_death", Event_PlayerDeath, EventHookMode_PostNoCopy); 35 | } 36 | 37 | public void OnClientPutInServer(int client) 38 | { 39 | SDKHook(client, SDKHook_WeaponSwitchPost, OnWeaponSwitchPost); 40 | } 41 | 42 | public void OnWeaponSwitchPost(int client, int weapon) 43 | { 44 | if (!GetConVarBool(hEnable) || !IsSurvivor(client)) return; 45 | if (fSpeedUpTimer[client] > 0.0) return; // 加速状态,停止减速 46 | char sWeaponName[64]; 47 | float fWeaponSpeed; 48 | float fFactor; 49 | GetClientWeapon(client, sWeaponName, sizeof(sWeaponName)); 50 | 51 | if (!L4D2_IsValidWeapon(sWeaponName)) return; 52 | 53 | fWeaponSpeed = GetWeaponMaxPlayerSpeed(sWeaponName); 54 | fFactor = CalculateFactor(fWeaponSpeed); 55 | SetPlayerSpeedFactor(client, fFactor); 56 | } 57 | 58 | public Action Event_PlayerDeath(Handle event, const char[] name, bool dontBroadcast) 59 | { 60 | if(!hSpeedUpEnable) return; 61 | int victim = GetClientOfUserId(GetEventInt(event, "userid")); 62 | int attacker = GetClientOfUserId(GetEventInt(event, "attacker")); 63 | if (IsSurvivor(attacker) && IsInfected(victim)) { 64 | SetPlayerSpeedFactor(attacker, 1.0); 65 | fSpeedUpTimer[attacker] = GetConVarFloat(hSpeedUpInterval); 66 | CreateTimer(1.0, Timer_ResetSpeed, attacker, TIMER_REPEAT); 67 | } 68 | } 69 | 70 | public Action Timer_ResetSpeed(Handle timer, int client) 71 | { 72 | if (fSpeedUpTimer[client] <= 0.0) { 73 | char sWeaponName[64]; 74 | float fWeaponSpeed; 75 | float fFactor; 76 | GetClientWeapon(client, sWeaponName, sizeof(sWeaponName)); 77 | 78 | if (!L4D2_IsValidWeapon(sWeaponName)) return Plugin_Stop; 79 | 80 | fWeaponSpeed = GetWeaponMaxPlayerSpeed(sWeaponName); 81 | fFactor = CalculateFactor(fWeaponSpeed); 82 | SetPlayerSpeedFactor(client, fFactor); 83 | return Plugin_Stop; 84 | } else { 85 | fSpeedUpTimer[client]--; 86 | return Plugin_Continue; 87 | } 88 | } 89 | 90 | float GetWeaponMaxPlayerSpeed(char[] sWeaponName) 91 | { 92 | return L4D2_GetFloatWeaponAttribute(sWeaponName, L4D2FWA_MaxPlayerSpeed) - 30.0; 93 | } 94 | 95 | float CalculateFactor(float fWeaponSpeed) 96 | { 97 | // return FloatDiv(fWeaponSpeed, 220.0); 98 | return fWeaponSpeed / 220.0; 99 | } 100 | 101 | void SetPlayerSpeedFactor(int client, float factor) 102 | { 103 | SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", factor); 104 | SetEntityGravity(client, 2 - factor); 105 | } 106 | 107 | bool IsSurvivor(int client) 108 | { 109 | if (client < 1 || client > MaxClients) return false; 110 | if (!IsClientConnected(client)) return false; 111 | if (!IsClientInGame(client)) return false; 112 | if (GetClientTeam(client) != 2) return false; 113 | return true; 114 | } 115 | 116 | bool IsInfected(int client) 117 | { 118 | if (client < 1 || client > MaxClients) return false; 119 | if (!IsClientConnected(client)) return false; 120 | if (!IsClientInGame(client)) return false; 121 | if (GetClientTeam(client) != 3) return false; 122 | return true; 123 | } --------------------------------------------------------------------------------