mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-08 07:53:20 +00:00
Merge branch 'master' of github.com:Jackzmc/sourcemod-plugins
This commit is contained in:
commit
2c99586be1
6 changed files with 116 additions and 253 deletions
87
README.md
87
README.md
|
@ -1,7 +1,8 @@
|
|||
# sourcemod-plugins
|
||||
This is a collection of all the sourcemod plugins I've created, most are just used for my own servers and some for very specific needs.
|
||||
This is a collection of sourcemod plugins, most are used on my servers. The majority of the plugins are created by me, but some are modifications of other plugins.
|
||||
Some of the plugins / changes are very specific, but may be useful to someone.
|
||||
|
||||
Not always the latest versions, if you have any interest with plugins I can make sure to upload the latest.
|
||||
Not always the latest versions. If you have any interest with a plugin, I can make sure to upload the latest.
|
||||
|
||||
Useful things:
|
||||
1. Netprop viewer https://jackz.me/netprops/l4d2
|
||||
|
@ -16,33 +17,34 @@ Useful things:
|
|||
* [l4d2-manual-director](#l4d2-manual-director) - Spawn specials on demand via director or at your cursor
|
||||
* [l4d2-info-cmd](#l4d2-info-cmd) - Prints a full state of all survivors, useful for external information
|
||||
* [AutoWarpBot](#autowarpbot) - Abandoned
|
||||
* [L4D2FFKickProtection](#l4d2ffkickprotection) - Prevents friendly firing from players being voted off and admins from being kicked
|
||||
* [l4d2_avoid_minigun](#l4d2_avoid_minigun) - Makes bots avoid being infront of any in use miniguns. Useful for spawned miniguns
|
||||
* [L4D2FFKickProtection](#l4d2ffkickprotection) - Prevents players being voted off from friendly firing and prevents admins from being kicked
|
||||
* [l4d2_avoid_minigun](#l4d2_avoid_minigun) - Makes bots avoid being infront of any in-use miniguns. Useful for spawned miniguns
|
||||
* [l4d2_ai_minigun](#l4d2_ai_minigun) - Based off [Silver's Survivor Bot Holdout plugin](https://forums.alliedmods.net/showthread.php?p=1741099), allows you to spawn survivor bots but with no limit.
|
||||
* [L4D2Tools](#l4d2tools) - A collection of utilities, mostly just used with [l4d_survivor_identity_fix](#l4d_survivor_identity_fix) and the /model command
|
||||
* [l4d2_swarm](#l4d2_swarm) - Uses vscript RushVictim to make all zombies target a player, like a more subtle vomitplayer
|
||||
* [l4d2_feedthetrolls](#l4d2_feedthetrolls) - Full collection of tools to troll your friends or troll the trolls
|
||||
* [l4d2_autobotcrown](#l4d2_autobotcrown) - Bots will auto crown
|
||||
* [l4d2_extraplayeritems](#l4d2_extraplayeritems) - Includes tons of utilities for 5+ games, such as 5+ player hud, extra kit spawning, and more
|
||||
* [l4d2_autobotcrown](#l4d2_autobotcrown) - Bots will auto crown
|
||||
* [l4d2_extraplayeritems](#l4d2_extraplayeritems) - Includes tons of utilities for 5+ games, such as 5+ player hud, extra kit / item spawning, and more
|
||||
* [l4d2_population_control](#l4d2_population_control) - Allows you to custom the type of zombies that spawn (% of clowns, mud men, etc..)
|
||||
* [globalbans](#globalbans) - Bans synced via mysql, way lighter than the sourcebans cesspool.
|
||||
* [l4d2_rollback](#l4d2_rollback) - Abandoned but makes periodic backup of all player's items
|
||||
* [l4d2_autorestart](#l4d2_autorestart) - Restarts server if it's been on for a certain uptime or when empty with just bots
|
||||
* [l4d2_TKStopper](#l4d2_tkstopper) - All the teamkiller and shitty aim player punishments. Auto increasing reverse ff and teamkill detection
|
||||
* [l4d2_crescendo_control](#l4d2_crescendo_control) - Prevents players from running far ahead and starting events & logs button presses
|
||||
* [l4d2_rollback](#l4d2_rollback) - Abandoned and broken, but makes periodic backup of all player's items
|
||||
* [l4d2_autorestart](#l4d2_autorestart) - Restarts server if it's been on for a certain uptime or when empty with just bots.
|
||||
* [l4d2_TKStopper](#l4d2_tkstopper) - All the teamkiller and shitty-aim player punishments. Auto increasing reverse ff and teamkill detection
|
||||
* [l4d2_crescendo_control](#l4d2_crescendo_control) - Prevents players from running far ahead and starting events, and logs button presses
|
||||
* [l4d2_vocalize_control](#l4d2_vocalize_control) - Allows you to locally mute someone from vocalizing
|
||||
* [l4d2_guesswho](#l4d2_guesswho) - Garrys mod's guess who in l4d2, inspired by hide and seek
|
||||
* [l4d2_guesswho](#l4d2_guesswho) - Garry's Mod's Guess Who in l4d2, inspired by hide and seek
|
||||
* [l4d2_hideandseek](#l4d2_hideandseek) - An enhancement to the base hide and seek mutation
|
||||
* [l4d2_hats](#l4d2_hats) - Entity Hats & Entity editing
|
||||
* [l4d2_prophunt](#l4d2_prophunt) - Garry's mod inspired prop hunt, inspired by hide and seek
|
||||
* [l4d2_prophunt](#l4d2_prophunt) - Garry's Mod inspired prop hunt, inspired by hide and seek
|
||||
* [sm_namespamblock](#sm_namespamblock) - Basic plugin that bans players if they change their name in rapid succession
|
||||
* [l4d2-stats-plugin](https://github.com/jackzmc/l4d2-stats-plugin) - Custom stats recorder, see https://stats.jackz.me
|
||||
* [l4d2-ai-tweaks](#l4d2_ai_tweaks) - Very minor tweaks to survivor bots' behavior
|
||||
|
||||
### Modified Others
|
||||
* [200IQBots_FlyYouFools](#200iqbots_flyyoufools) - Improved code to make it support multiple tanks and work better
|
||||
* [l4d_survivor_identity_fix](#l4d_survivor_identity_fix) - Use with [L4D2Tools](#l4d2tools) to change models, some fixes
|
||||
* [BetterWitchAvoidance](#betterwitchavoidance)
|
||||
* l4d_anti_rush - Modified plugin to add a forward, so other plugins (like feedthetrolls) can do something and use highest flow value achieved for players (fixes issue when admins go back and players who haven't moved suddenly get punished)
|
||||
* l4d_anti_rush - Modified plugin to add a forward, so other plugins (like feedthetrolls) can do something. In addition, use highest flow value achieved for players (fixes issue when admins go back and players who haven't moved suddenly get punished)
|
||||
* [l4d2_sb_fix](#l4d2_sb_fix) - Updated to 1.11 & latest sourcepawn syntax & removed the FCVAR_NOTIFY from all cvars (why is that added?)
|
||||
* GrabEnt - Improved version that prevents moving certain entities (such as invisual walls, ragdolls, etc) and improved some code
|
||||
|
||||
|
@ -55,7 +57,7 @@ Check the plugin info for an exact list.
|
|||
|
||||
### Development Dependencies
|
||||
Most L4D2 plugins use my own include: jutils.inc, it's provided in this repo.
|
||||
Some do require newer includes by modified plugins (such as my improved survivor identity fix)
|
||||
Some do require newer includes for my modified plugins (such as my improved survivor identity fix)
|
||||
|
||||
## Descriptions
|
||||
|
||||
|
@ -68,7 +70,7 @@ On knife kill, gives the player 100 HP (configurable)
|
|||
|
||||
|
||||
### l4d2-manual-director
|
||||
Probably going to be posted publicly sometime. allows you to spawn specials on cursor, or via director, forcefully, bypassing limits
|
||||
~~Probably going to be posted publicly sometime.~~ Allows you to spawn specials on cursor, or via director, forcefully, bypassing limits
|
||||
* **Convars:**
|
||||
* `manual_director_version|mandirector_version` - ... gets version
|
||||
* `mandirector_notify_spawn <1/0>` - Should spawning specials notify on use?
|
||||
|
@ -102,7 +104,7 @@ Technically 'l4d2 game info', haven't changed name. Just prints general informat
|
|||
|
||||
|
||||
### AutoWarpBot
|
||||
Simple l4d2 plugin that will auto teleport everyone to checkpoint once all real players have reached the saferoom.
|
||||
Simple l4d2 plugin that will auto teleport bots to checkpoint once all real players have reached the saferoom.
|
||||
Doesn't really work well. Abandoned.
|
||||
|
||||
|
||||
|
@ -119,7 +121,8 @@ Inspired by the 200IQBots_FlyYouFools. Bots avoid witch if its over 40% anger wh
|
|||
|
||||
### L4D2FFKickProtection
|
||||
Simple plugin that prevents a player that is being vote-kicked from doing any ff damage to teammates.
|
||||
It also prevents vote kicking of admins, instead will kick the player and notify admins.
|
||||
It also prevents vote kicking of admins, instead will notify admins.
|
||||
It also makes any vote kicks created by an admin to instantly be accepted by all players
|
||||
|
||||
* **Convars:**
|
||||
* `sm_votekick_force_threshold <#>` - The threshold of damage where the offending player is just immediately kicked. 0 -> Any attempted damage, -1 -> No auto kick.
|
||||
|
@ -165,10 +168,10 @@ A collection of small tools:
|
|||
* Notification of when someone picks up laser sights (only the first user, includes bots),
|
||||
* Record time it takes for a finale or gauntlet run to be completed.
|
||||
* Record the amount of friendly fire damage done
|
||||
* Set the survivor models of any survivor with updating [l4d_survivor_identity_fix](#l4d_survivor_identity_fix)
|
||||
* Automatically gives melee weapons that an idle bot dropped once no longer idle
|
||||
* Set the survivor models of any survivor with updated [l4d_survivor_identity_fix](#l4d_survivor_identity_fix)
|
||||
* Automatically returns melee weapons that an idle bot dropped once no longer idle
|
||||
* Automatically make players go idle when ping spikes
|
||||
* Slowly kill any zombies attacking survivor bot's blind spots (Fixes bots stuck taking damage and brain dead)
|
||||
* Slowly kill any zombies attacking survivor bot's blind spots (Fixes brain dead bots stuck taking damage and not killing them)
|
||||
|
||||
* **Convars:**
|
||||
* `sm_laser_use_notice <0/1>` - Enable notification of when a laser box was used first
|
||||
|
@ -202,7 +205,7 @@ This really only affects wandering zombies, mobs and panic events, but it may wo
|
|||
Requires:
|
||||
* [Left4Dhooks](https://forums.alliedmods.net/showthread.php?t=321696)
|
||||
* (Optional) [Scene Processor](https://forums.alliedmods.net/showthread.php?p=2147410)
|
||||
* (Optional) [L4D2 Behavior](https://forums.alliedmods.net/showthread.php?p=2752139) - To be replaced with [Actions](https://forums.alliedmods.net/showthread.php?t=336374)
|
||||
* (Optional) [Actions](https://forums.alliedmods.net/showthread.php?t=336374)
|
||||
* (Optional) [Modified L4D Antirush](#l4d_anti_rush)
|
||||
|
||||
This plugin allows you to enact certain troll modes on any player, some are subtle some are less so. Either way, it works great to deal with a rusher, an asshole or even your friends.
|
||||
|
@ -218,23 +221,25 @@ https://admin.jackz.me/docs/ftt
|
|||
* `sm_ftt_magnet_chance <0.0 - 1.0>` - % of the time that the magnet will work on a player."
|
||||
* `sm_ftt_shove_fail_chance <0.0 - 1.0>` - The % chance that a shove fails
|
||||
* **Commands:**
|
||||
* `sm_fta [player]` - Opens a menu to select a troll to apply, with modifiers and flags
|
||||
* `sm_fta [player]` - The main command, opens a menu to select a troll to apply, with modifiers and flags
|
||||
* `sm_ftr [player]` - Removes all active trolls from a player
|
||||
* `sm_ftc [player]` - Opens a menu to select a combo of trolls
|
||||
* `sm_ftl` - Lists all players that have a mode applied.
|
||||
* `sm_ftm` - Lists all troll options & their descriptions
|
||||
* `sm_mark` - Toggles marking a player to be banned when they fully disconnect
|
||||
* `sm_insta [player] [special]` - (No arguments opens menu) - Spawns a special via director that will only target the victim
|
||||
* `sm_inface [player] [special]` - Identical to above, but special will be spawned as close as possible to survivor. Boomers auto explode.
|
||||
* `sm_bots_attack <player> [target health]` - Slightly broken, but makes all bots shoot at player until they hit X health or a timeout is reached.
|
||||
* `sm_insta [player] [special]` - (No arguments opens menu) - Spawns a special via the director that will only target the victim
|
||||
* `sm_inface [player] [special]` - Identical to above, but special will be spawned as close as possible to survivor. Boomers auto explode, jockeys on their head, etc.
|
||||
* `sm_bots_attack <player> [target health]` - Slightly broken, but makes all bots shoot at player until they hit X health or a timeout is reached. Turn on `sb_friendlyfire` for it to be effective.
|
||||
* `sm_stagger <player>` - Makes a player stagger, shortcut to the Stagger troll
|
||||
* `sm_witch_attack <player>` - Makes all witches agro on the player
|
||||
* `sm_scharge <player> [timeout seconds]` - Will wait till there's no obstructions and players in the way and then spawns a charger to charge them.
|
||||
* `sm_healbots <player> [# bots or 0 default]` - Makes n amount of bots chase a player down to heal them. Won't stop until they are healed or die.
|
||||
* `sm_scharge <player> [timeout seconds]` - Will wait till there's no obstructions and players in the way, then spawns a charger behind them to charge them.
|
||||
* `sm_healbots <player> [# bots or 0 default]` - Makes n amount of bots chase a player down to heal them. Won't stop until they are healed, they die, or you run command again.
|
||||
|
||||
|
||||
### l4d2_autobotcrown
|
||||
Makes any suitable bot (> 40 hp, has shotgun) automatically crown a witch. Supports multiple bots and witches, but only one bot can crown one witch at a time. Plugin is obviously disabled in realism, and is really on suitable for coop or versus. Even works with idle players.
|
||||
Makes any suitable bot (> 40 hp, has shotgun) automatically crown a witch. Supports multiple bots and witches, but only one bot can crown one witch at a time. Plugin is disabled in realism, and is really on suitable for coop or versus. Even works with idle players.
|
||||
|
||||
Bots do sometimes miss, but sometimes still manage to kill witch. They also don't care if there is danger in the way (fire, acid, angry witch).
|
||||
|
||||
* **Convars:**
|
||||
* `l4d2_autocrown_allowed_difficulty <default: 7>` - The difficulties the plugin is active on. 1=Easy, 2=Normal 4=Advanced 8=Expert. Add numbers together.
|
||||
|
@ -253,7 +258,8 @@ Features:
|
|||
* Automatically giving extra kits for each extra player in saferooms
|
||||
* Increasing item count for items randomly depending on player count
|
||||
* Fix same-models survivors having to fight over ammo pack usage
|
||||
* Automatically lock the exit saferoom door until a threshold of players or time has passed
|
||||
* Automatically lock the first saferoom door for every chapter, until a threshold of players or time has passed
|
||||
* Includes a HUD that shows all the survivors and their items, and optionally their ping
|
||||
|
||||
* **Convars:**
|
||||
* `l4d2_extraitem_chance` - The base chance (multiplied by player count) of an extra item being spawned. Default: 0.056
|
||||
|
@ -276,7 +282,7 @@ Requires:
|
|||
|
||||
A fork of [Survivor Identity Fix plugin](https://forums.alliedmods.net/showthread.php?t=280539) that adds support for other plugins to update the model cache. This is used by [L4D2Tools](#L4D2Tools) to update the identity when someone changes their model with `sm_model`. It also will clear the memory of model when a player disconnects entirely or on a new map.
|
||||
|
||||
In addition, has a fix for the passing finale, and will automatically move L4D characters to L4D2 until finale starts preventing game messing up their characters.
|
||||
In addition, has a fix for the passing finale, and will automatically temporarily change L4D characters to L4D2 until finale starts preventing game messing up their characters.
|
||||
|
||||
|
||||
### l4d2_population_control
|
||||
|
@ -328,7 +334,7 @@ Currently auto triggers:
|
|||
|
||||
### l4d2_autorestart
|
||||
Plugin that automatically restarts server when the server is NOT hibernating, with bots around and no players.
|
||||
This fixes an issue with (shitty) custom maps that force sb_all_bot_game to 1 and disable hibernation
|
||||
This fixes an issue with custom maps that force sb_all_bot_game to 1 and disable hibernation.
|
||||
|
||||
### l4d2_TKStopper
|
||||
Requires:
|
||||
|
@ -345,7 +351,7 @@ Any survivor that attacks another survivor
|
|||
See https://admin.jackz.me/docs/plugins#tkstopper for some more implementation information
|
||||
|
||||
|
||||
During any of the above three conditions, if they deal (or attempt to deal) over 75 HP in 15 seconds they will be instantly banned for a set period of time (60 minutes). If they are for sure a team killer, it can be extended to a permanent ban.
|
||||
During any of the above three conditions, if they deal (or attempt to deal) over 75 HP in 15 seconds (configurable) they will be instantly banned for a set period of time (60 minutes). If they are for sure a team killer, it can be extended to a permanent ban.
|
||||
|
||||
* **Cvars:**
|
||||
* `l4d2_tk_forgiveness_time <#>` - The minimum amount of seconds to pass (in seconds) where a player's previous accumulated FF is forgive. Default is 15s
|
||||
|
@ -361,7 +367,7 @@ Requires:
|
|||
|
||||
This plugin prevents the activation of buttons ahead of the team. It will prevent players from starting crescendos (and some small other activities as a side effect) until a certain threshold of the team has reached the area.
|
||||
|
||||
_This plugin is currently in **development.**_ Current implementation may be lacking.
|
||||
_This plugin is not perfect, sometimes it may trigger early, or not trigger at all depending on the map. Sometimes you need to as admins, move forward to allow non-admins to activate events._
|
||||
|
||||
|
||||
* **Cvars:**
|
||||
|
@ -373,7 +379,7 @@ _This plugin is currently in **development.**_ Current implementation may be lac
|
|||
A very small plugin that simply allows a player to mute another player's vocalizations only for them.
|
||||
|
||||
* **Commands:**
|
||||
* `sm_vgag <player(s)>` - Vocalize gag or ungags selected player(s)
|
||||
* `sm_vgag <player(s)>` - Vocalize gag or ungags selected player(s) for the command activator only
|
||||
|
||||
### l4d2_sb_fix
|
||||
A fork of https://forums.alliedmods.net/showthread.php?p=2757330
|
||||
|
@ -388,6 +394,7 @@ Requires:
|
|||
|
||||
A sourcemod extenstion of the vscript gamemode (https://steamcommunity.com/sharedfiles/filedetails/?id=2467133506)
|
||||
- Player blockers, portals, and props to change and control the maps
|
||||
- Optional climbable infected ladders, and heart beat when seeker nearby
|
||||
- Some quality of life (winner messages, change seeker mid game, change map time)
|
||||
- and a lot more
|
||||
|
||||
|
@ -403,7 +410,7 @@ Vscript required for hud & mutation
|
|||
|
||||
Gamemode: https://steamcommunity.com/sharedfiles/filedetails/?id=2823719841
|
||||
|
||||
Requires l4dtoolz and left4dhooks, and optioanlly skip intro cutscene
|
||||
Requires l4dtoolz and left4dhooks, and optionally skip intro cutscene
|
||||
|
||||
### l4d2_prophunt
|
||||
Requires:
|
||||
|
@ -418,7 +425,7 @@ Vscript required for hud & mutation
|
|||
|
||||
* Demo Map: https://steamcommunity.com/sharedfiles/filedetails/?id=2855027013 (makes most prop_static -> prop_dynamic)
|
||||
|
||||
Requires l4dtoolz and left4dhooks, and optioanlly skip intro cutscene
|
||||
Requires l4dtoolz and left4dhooks, and optionally skip intro cutscene
|
||||
|
||||
### l4d2_hats
|
||||
|
||||
|
@ -436,3 +443,11 @@ Requires recompile to change.
|
|||
* **Commands:**
|
||||
* `status2` - Shitty name, but shows all non-admin players, sorted by last joined ascending (up top). Shows steamid and the first name they joined the server as
|
||||
* `sm_status2` - Same command, but allows /status2 in chat
|
||||
|
||||
### l4d2_ai_tweaks
|
||||
|
||||
Simply, prevents an idle bot (that is a bot for an idle player) from healing another player unless:
|
||||
1. The target is black and white
|
||||
2. The player has been idle for over **ALLOW_HEALING_MIN_IDLE_TIME** (a \#define) seconds (default is 3 minutes)
|
||||
|
||||
Requires recompile to change.
|
||||
|
|
|
@ -158,8 +158,9 @@ public Action Timer_PushLogs(Handle h) {
|
|||
static char query[1024];
|
||||
static Log log;
|
||||
int length = logs.Length;
|
||||
Transaction transaction = new Transaction();
|
||||
|
||||
if(length > 0) {
|
||||
Transaction transaction = new Transaction();
|
||||
for(int i = 0; i < length; i++) {
|
||||
logs.GetArray(i, log, sizeof(log));
|
||||
g_db.Format(query, sizeof(query), "INSERT INTO `activity_log` (`timestamp`, `server`, `type`, `client`, `target`, `message`) VALUES (%d, NULLIF('%s', ''), '%s', NULLIF('%s', ''), NULLIF('%s', ''), NULLIF('%s', ''))",
|
||||
|
@ -173,11 +174,11 @@ public Action Timer_PushLogs(Handle h) {
|
|||
transaction.AddQuery(query);
|
||||
}
|
||||
logs.Resize(logs.Length - length);
|
||||
g_db.Execute(transaction, _, SQL_TransactionFailed, length, DBPrio_Low);
|
||||
}
|
||||
g_db.Execute(transaction, _, SQL_TransactionFailed, length, DBPrio_Low);
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public void SQL_TransactionFailed(Database db, any data, int numQueries, const char[] error, int failIndex, any[] queryData) {
|
||||
void SQL_TransactionFailed(Database db, any data, int numQueries, const char[] error, int failIndex, any[] queryData) {
|
||||
LogError("Push transaction failed: %s at query %d/%d", error, failIndex, numQueries);
|
||||
}
|
||||
|
||||
|
@ -301,4 +302,4 @@ public any Native_AddLog(Handle plugin, int numParams) {
|
|||
if(GetNativeString(4, message, sizeof(message)) != SP_ERROR_NONE) return false;
|
||||
AddLog(type, clientName, targetName, message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -347,6 +347,8 @@ public Action Event_OnTakeDamage(int victim, int& attacker, int& inflictor, flo
|
|||
float pos[3];
|
||||
GetNearestPlayerPosition(victim, pos);
|
||||
PrintToConsoleAdmins("%N within join time (%d min), attempted to fall");
|
||||
TeleportEntity(victim, pos, NULL_VECTOR, NULL_VECTOR);
|
||||
damage = 0.0;
|
||||
if(pData[victim].jumpAttempts > hSuicideLimit.IntValue) {
|
||||
if(hSuicideAction.IntValue == 1) {
|
||||
LogMessage("[NOTICE] Kicking %N for suicide attempts", victim, hBanTime.IntValue);
|
||||
|
@ -362,50 +364,52 @@ public Action Event_OnTakeDamage(int victim, int& attacker, int& inflictor, flo
|
|||
pData[victim].isTroll = true;
|
||||
}
|
||||
}
|
||||
return Plugin_Stop;
|
||||
}
|
||||
if(attacker == victim) return Plugin_Continue;
|
||||
|
||||
// Forgive player based on threshold, resetting accumlated damage
|
||||
// Forgive player teamkill based on threshold, resetting accumlated damage
|
||||
if(time - pData[attacker].lastFFTime > hForgivenessTime.IntValue) {
|
||||
pData[attacker].TKDamageBuffer = 0.0;
|
||||
}
|
||||
|
||||
pData[attacker].TKDamageBuffer += damage;
|
||||
pData[attacker].totalDamageFF += damage;
|
||||
pData[attacker].totalFFCount++;
|
||||
pData[attacker].ffCount++;
|
||||
|
||||
// Auto reverse ff logic
|
||||
// If not immune to RFF, damage is direct, _or admin shit_
|
||||
if(~pData[attacker].immunityFlags & Immune_RFF && isDamageDirect) {
|
||||
if(isDamageDirect) {
|
||||
// Decrease the RFF scale based on how long since their last FF and an amount
|
||||
float minutesSinceiLastFFTime = (time - pData[attacker].lastFFTime) / 60.0;
|
||||
pData[attacker].autoRFFScaleFactor -= minutesSinceiLastFFTime * hFFAutoScaleForgivenessAmount.FloatValue;
|
||||
if(pData[attacker].autoRFFScaleFactor < 0.0) {
|
||||
pData[attacker].autoRFFScaleFactor = 0.0;
|
||||
}
|
||||
|
||||
// Decrement any accumlated ff 'counts'
|
||||
int ffCountMinutes = RoundFloat(minutesSinceiLastFFTime / 10.0);
|
||||
pData[attacker].ffCount -= (ffCountMinutes * 2);
|
||||
if(pData[attacker].ffCount < 0) {
|
||||
pData[attacker].ffCount = 0;
|
||||
}
|
||||
// Decrement any forgiven ratio (computed on demand)
|
||||
if(pData[attacker].autoRFFScaleFactor < 0.0) {
|
||||
pData[attacker].autoRFFScaleFactor = 0.0;
|
||||
}
|
||||
// Then calculate a new reverse ff ratio
|
||||
|
||||
// Calculate a new reverse ff ratio based on scale threshold + damage dealt + # of recent friendly fires events
|
||||
pData[attacker].autoRFFScaleFactor += hFFAutoScaleAmount.FloatValue * damage * (pData[attacker].ffCount*0.25);
|
||||
if(pData[attacker].isTroll) {
|
||||
pData[attacker].autoRFFScaleFactor *= 2;
|
||||
}
|
||||
|
||||
// Cap max damage only for non-trolls
|
||||
if(!pData[attacker].isTroll && hFFAutoScaleMaxRatio.FloatValue > 0.0 && pData[attacker].autoRFFScaleFactor > hFFAutoScaleMaxRatio.FloatValue) {
|
||||
} else if(hFFAutoScaleMaxRatio.FloatValue > 0.0 && pData[attacker].autoRFFScaleFactor > hFFAutoScaleMaxRatio.FloatValue) {
|
||||
// Cap it to the max - if they aren't marked as troll
|
||||
pData[attacker].autoRFFScaleFactor = hFFAutoScaleMaxRatio.FloatValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int prevFFTime = pData[attacker].lastFFTime;
|
||||
pData[attacker].lastFFTime = time;
|
||||
|
||||
// Check for excessive friendly fire damage in short timespan
|
||||
// If not immune to TK, if over TK threshold, not when escaping, and direct damage
|
||||
if(~pData[attacker].immunityFlags & Immune_TK
|
||||
if(~pData[attacker].immunityFlags & Immune_TK
|
||||
&& pData[attacker].TKDamageBuffer > hThreshold.IntValue
|
||||
&& !isFinaleEnding
|
||||
&& isDamageDirect
|
||||
|
@ -441,9 +445,9 @@ public Action Event_OnTakeDamage(int victim, int& attacker, int& inflictor, flo
|
|||
}
|
||||
|
||||
// Modify damages based on criteria
|
||||
if(pData[victim].jumpAttempts > 0
|
||||
|| L4D_IsInFirstCheckpoint(victim) || L4D_IsInLastCheckpoint(victim)
|
||||
|| time - pData[attacker].joinTime <= hJoinTime.IntValue * 60
|
||||
if(pData[victim].jumpAttempts > 0 // If they've attempted suicide, we just incase, disable their ff damage
|
||||
|| L4D_IsInFirstCheckpoint(victim) || L4D_IsInLastCheckpoint(victim) // No FF damage in saferooms
|
||||
|| time - pData[attacker].joinTime <= hJoinTime.IntValue * 60 // No FF damage within first X minutes
|
||||
) {
|
||||
/*
|
||||
If the amount of seconds since they joined is <= the minimum join time cvar (min) threshold
|
||||
|
@ -456,14 +460,14 @@ public Action Event_OnTakeDamage(int victim, int& attacker, int& inflictor, flo
|
|||
}else if(isFinaleEnding) {
|
||||
// Keep admins immune if escape vehicle out, or if victim is a bot
|
||||
if(isAdmin || IsFakeClient(victim)) return Plugin_Continue;
|
||||
// We ignore FF for fire/molotovs, can be accidental / non-issue
|
||||
if(isDamageDirect)
|
||||
SDKHooks_TakeDamage(attacker, attacker, attacker, damage * 2.0);
|
||||
damage = 0.0;
|
||||
return Plugin_Changed;
|
||||
}else if(isDamageDirect && pData[attacker].autoRFFScaleFactor > 0.3) { // Ignore fire and propane damage, mistakes can happen
|
||||
}else if(isDamageDirect && pData[attacker].autoRFFScaleFactor > 0.18) { // 0.18 buffer to ignore fire and propane damage, mistakes can happen
|
||||
// Apply their reverse ff damage, and have victim take a decreasing amount
|
||||
if(pData[attacker].isTroll) return Plugin_Stop;
|
||||
else if(pData[attacker].immunityFlags & Immune_RFF) return Plugin_Continue;
|
||||
|
||||
SDKHooks_TakeDamage(attacker, attacker, attacker, pData[attacker].autoRFFScaleFactor * damage);
|
||||
if(pData[attacker].autoRFFScaleFactor > 1.0)
|
||||
|
|
|
@ -21,7 +21,7 @@ public Plugin myinfo = {
|
|||
url = "https://github.com/Jackzmc/sourcemod-plugins"
|
||||
};
|
||||
|
||||
ConVar noHibernate;
|
||||
ConVar cvar_hibernateWhenEmpty;
|
||||
|
||||
public void OnPluginStart() {
|
||||
startupTime = GetTime();
|
||||
|
@ -31,7 +31,7 @@ public void OnPluginStart() {
|
|||
SetFailState("This plugin is for L4D/L4D2 only.");
|
||||
}
|
||||
|
||||
noHibernate = FindConVar("sv_hibernate_when_empty");
|
||||
cvar_hibernateWhenEmpty = FindConVar("sv_hibernate_when_empty");
|
||||
|
||||
RegAdminCmd("sm_request_restart", Command_RequestRestart, ADMFLAG_GENERIC);
|
||||
|
||||
|
@ -60,7 +60,7 @@ public Action Timer_Check(Handle h) {
|
|||
} else if(GetTime() - startupTime > MAX_TIME_ONLINE_SECONDS) {
|
||||
LogAction(0, -1, "Server has passed max online time threshold, will restart if remains empty");
|
||||
pendingRestart = true;
|
||||
noHibernate.BoolValue = true;
|
||||
cvar_hibernateWhenEmpty.BoolValue = false;
|
||||
if(IsServerEmpty()) {
|
||||
if(++triesEmpty > 4) {
|
||||
LogAction(0, -1, "Server has passed max online time threshold and is empty after %d tries, restarting now", triesEmpty);
|
||||
|
@ -78,7 +78,7 @@ public Action Timer_Check(Handle h) {
|
|||
public void OnConfigsExecuted() {
|
||||
// Reset no hibernate setting when level changes:
|
||||
if(pendingRestart) {
|
||||
noHibernate.BoolValue = true;
|
||||
cvar_hibernateWhenEmpty.BoolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
#define HIT_1 "weapons/golf_club/wpn_golf_club_melee_01.wav"
|
||||
#define HIT_2 "weapons/golf_club/wpn_golf_club_melee_02.wav"
|
||||
|
||||
ConVar sv_melee_force_projectile, sv_melee_radius_projectile, sv_melee_force_boost_projectile_up;
|
||||
int g_iLaser, g_iGlow;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "[L4D2] Baseball",
|
||||
author = "BHaType",
|
||||
description = "Melee weapons can now deflect projectile",
|
||||
version = "0.0",
|
||||
url = ""
|
||||
}
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
sv_melee_force_projectile = CreateConVar("sv_melee_force_projectile", "0.6");
|
||||
sv_melee_force_boost_projectile_up = CreateConVar("sv_melee_force_boost_projectile_up", "250.0");
|
||||
sv_melee_radius_projectile = CreateConVar("sv_melee_radius_projectile", "75.0");
|
||||
|
||||
AutoExecConfig(true, "l4d2_baseball");
|
||||
|
||||
HookEvent("weapon_fire", weapon_fire);
|
||||
HookEvent("entity_shoved", entity_shoved);
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
PrecacheSound(HIT_1, true);
|
||||
PrecacheSound(HIT_2, true);
|
||||
|
||||
g_iLaser = PrecacheModel("materials/sprites/laserbeam.vmt");
|
||||
g_iGlow = PrecacheModel("materials/sprites/glow.vmt");
|
||||
}
|
||||
|
||||
public void entity_shoved (Event event, const char[] name, bool dontbroadcast)
|
||||
{
|
||||
int entity = event.GetInt("entityid");
|
||||
|
||||
static char szName[36];
|
||||
GetEntityClassname(entity, szName, sizeof szName);
|
||||
|
||||
if ( StrContains(szName, "_projectile") != -1 )
|
||||
{
|
||||
float vVelocity[3];
|
||||
vVelocity = CalculateBaseForce(entity);
|
||||
vVelocity[2] += sv_melee_force_boost_projectile_up.FloatValue;
|
||||
|
||||
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
public void weapon_fire (Event event, const char[] name, bool dontbroadcast)
|
||||
{
|
||||
static char szName[36];
|
||||
event.GetString("weapon", szName, sizeof szName);
|
||||
|
||||
if ( strcmp(szName, "melee") != 0 )
|
||||
return;
|
||||
|
||||
int client = event.GetInt("userid");
|
||||
timer (CreateTimer(0.1, timer, client, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE), client);
|
||||
}
|
||||
|
||||
public Action timer (Handle timer, int client)
|
||||
{
|
||||
client = GetClientOfUserId(client);
|
||||
|
||||
if ( !client )
|
||||
return Plugin_Stop;
|
||||
|
||||
int weapon = GetPlayerWeaponSlot(client, 1);
|
||||
|
||||
if ( weapon == -1 || GetEntPropFloat(weapon, Prop_Send, "m_flNextPrimaryAttack") <= GetGameTime())
|
||||
return Plugin_Stop;
|
||||
|
||||
float vAngles[3], vOrigin[3], vVector[3], vEnd[3];
|
||||
|
||||
GetClientEyePosition(client, vOrigin);
|
||||
|
||||
GetClientEyeAngles(client, vAngles);
|
||||
GetAngleVectors(vAngles, vVector, NULL_VECTOR, NULL_VECTOR);
|
||||
ScaleVector(vVector, sv_melee_radius_projectile.FloatValue);
|
||||
AddVectors(vOrigin, vVector, vEnd);
|
||||
|
||||
GetClientEyePosition(client, vOrigin);
|
||||
|
||||
#define hull 10.0
|
||||
static const float vMaxs[3] = { hull, hull, hull };
|
||||
static const float vMins[3] = { -hull, -hull, -hull };
|
||||
|
||||
TR_TraceHullFilter(vOrigin, vEnd, vMins, vMaxs, MASK_SOLID, TraceFilter, client);
|
||||
float vHit[3];
|
||||
TR_GetEndPosition(vHit);
|
||||
|
||||
if ( TR_DidHit () )
|
||||
{
|
||||
int entity = TR_GetEntityIndex();
|
||||
|
||||
if ( entity != 0 )
|
||||
{
|
||||
static char szName[36];
|
||||
GetEntityClassname(entity, szName, sizeof szName);
|
||||
|
||||
if ( StrContains(szName, "_projectile") != -1 )
|
||||
{
|
||||
float vVelocity[3], vVec[3];
|
||||
|
||||
vVelocity = CalculateBaseForce(entity, client);
|
||||
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", vOrigin);
|
||||
|
||||
MakeVectorFromPoints(vHit, vOrigin, vVec);
|
||||
ScaleVector(vVec, 1.0 - sv_melee_force_projectile.FloatValue * sv_melee_radius_projectile.FloatValue);
|
||||
AddVectors(vVec, vVector, vVec);
|
||||
AddVectors(vVec, vVelocity, vVelocity);
|
||||
|
||||
TE_SetupSparks(vHit, vVelocity, 1, 1);
|
||||
TE_SendToAll();
|
||||
|
||||
NegateVector(vVelocity);
|
||||
|
||||
vVelocity[2] += sv_melee_force_boost_projectile_up.FloatValue;
|
||||
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vVelocity);
|
||||
|
||||
int color[4] = { 255, ... };
|
||||
for (int i; i <= 2; i++)
|
||||
color[i] = GetRandomInt(0, 255);
|
||||
|
||||
TE_SetupBeamFollow(entity, g_iLaser, g_iGlow, 4.6, 0.8, 0.8, 1, color);
|
||||
TE_SendToAll();
|
||||
|
||||
EmitSoundToAll((GetRandomInt(0, 1) == 0 ? HIT_1 : HIT_2), SOUND_FROM_WORLD, .origin = vHit);
|
||||
|
||||
// PrintToChatAll("\x04%N \x03baseballed projectile for \x04%.2f \x03velocity!", client, GetVectorLength(vVelocity));
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
float[] CalculateBaseForce (int victim, int attacker = 0)
|
||||
{
|
||||
float m_vecBaseVelocity[3], m_vecVelocity[3], vAngles[3];
|
||||
|
||||
if ( attacker )
|
||||
{
|
||||
GetEntPropVector(attacker, Prop_Send, "m_vecBaseVelocity", m_vecBaseVelocity);
|
||||
GetClientEyeAngles(attacker, vAngles);
|
||||
}
|
||||
|
||||
GetEntPropVector(victim, Prop_Data, "m_vecVelocity", m_vecVelocity);
|
||||
AddVectors(m_vecBaseVelocity, m_vecVelocity, m_vecVelocity);
|
||||
|
||||
ScaleVector(m_vecVelocity, sv_melee_force_projectile.FloatValue);
|
||||
|
||||
return m_vecVelocity;
|
||||
}
|
||||
|
||||
public bool TraceFilter (int entity, int mask, int data)
|
||||
{
|
||||
return entity != data;
|
||||
}
|
|
@ -61,8 +61,8 @@ public void OnPluginStart() {
|
|||
LoadTranslations("common.phrases");
|
||||
HookEvent("player_entered_checkpoint", OnEnterSaferoom);
|
||||
HookEvent("player_left_checkpoint", OnLeaveSaferoom);
|
||||
HookEvent("player_bot_replace", Event_PlayerOutOfIdle );
|
||||
HookEvent("bot_player_replace", Event_PlayerToIdle);
|
||||
HookEvent("player_bot_replace", Event_PlayerToIdle);
|
||||
HookEvent("bot_player_replace", Event_PlayerOutOfIdle);
|
||||
|
||||
RegConsoleCmd("sm_hat", Command_DoAHat, "Hats");
|
||||
RegAdminCmd("sm_hatf", Command_DoAHat, ADMFLAG_ROOT, "Hats");
|
||||
|
@ -470,28 +470,45 @@ void ChooseRandomPosition(float pos[3], int ignoreClient = 0) {
|
|||
|
||||
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) {
|
||||
float tick = GetGameTime();
|
||||
//////////////////////////////
|
||||
// OnPlayerRunCmd :: HATS
|
||||
/////////////////////////////
|
||||
if(IsHatsEnabled(client)) {
|
||||
int entity = GetHat(client);
|
||||
int visibleEntity = EntRefToEntIndex(hatData[client].visibleEntity);
|
||||
///#HAT PROCESS
|
||||
if(entity > 0) {
|
||||
// try to tp hat to itys own pos
|
||||
// Crash prevention: Prevent hat from touching ladder as that can cause server crashes
|
||||
if(!onLadder[client] && GetEntityMoveType(client) == MOVETYPE_LADDER) {
|
||||
onLadder[client] = true;
|
||||
ClearParent(entity);
|
||||
// Hide hat temporarily in void:
|
||||
|
||||
// If hat is not a player, we teleport them to the void (0, 0, 0)
|
||||
// Otherwise, we just simply dismount the player while hatter is on ladder
|
||||
if(entity >= MaxClients)
|
||||
|
||||
TeleportEntity(entity, EMPTY_ANG, NULL_VECTOR, NULL_VECTOR);
|
||||
if(visibleEntity > 0) {
|
||||
hatData[client].visibleEntity = INVALID_ENT_REFERENCE;
|
||||
RemoveEntity(visibleEntity);
|
||||
}
|
||||
} else if(onLadder[client] && GetEntityMoveType(client) != MOVETYPE_LADDER) {
|
||||
}
|
||||
// Player is no longer on ladder, restore hat:
|
||||
else if(onLadder[client] && GetEntityMoveType(client) != MOVETYPE_LADDER) {
|
||||
onLadder[client] = false;
|
||||
EquipHat(client, entity);
|
||||
}
|
||||
|
||||
// Do the same crash protection for the hat itself, just to be safe:
|
||||
if(entity <= MaxClients) {
|
||||
if(!onLadder[entity] && GetEntityMoveType(entity) == MOVETYPE_LADDER) {
|
||||
onLadder[entity] = true;
|
||||
ClearParent(entity);
|
||||
} else if(onLadder[entity] && GetEntityMoveType(entity) != MOVETYPE_LADDER) {
|
||||
onLadder[entity] = false;
|
||||
EquipHat(client, entity);
|
||||
}
|
||||
}
|
||||
|
||||
// Rainbow hat processing
|
||||
if(HasFlag(client, HAT_RAINBOW)) {
|
||||
// Decrement and flip, possibly when rainbowticks
|
||||
if(hatData[client].rainbowReverse) {
|
||||
|
@ -515,24 +532,18 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
EquipHat(client, entity);
|
||||
}
|
||||
|
||||
if(entity <= MaxClients) {
|
||||
if(!onLadder[entity] && GetEntityMoveType(entity) == MOVETYPE_LADDER) {
|
||||
onLadder[entity] = true;
|
||||
ClearParent(entity);
|
||||
} else if(onLadder[entity] && GetEntityMoveType(entity) != MOVETYPE_LADDER) {
|
||||
onLadder[entity] = false;
|
||||
EquipHat(client, entity);
|
||||
}
|
||||
}
|
||||
// If bot is commandable and reversed (player reverse-hat common/survivor), change position:
|
||||
if(HasFlag(client, HAT_COMMANDABLE | HAT_REVERSED) && tickcount % 200 == 0) {
|
||||
float pos[3];
|
||||
ChooseRandomPosition(pos, client);
|
||||
L4D2_CommandABot(entity, client, BOT_CMD_MOVE, pos);
|
||||
}
|
||||
}
|
||||
// Detect E + R to offset hat or place down
|
||||
if(buttons & IN_USE && buttons & IN_RELOAD) {
|
||||
if(entity > 0) {
|
||||
if(buttons & IN_ZOOM) {
|
||||
// Offset controls:
|
||||
if(buttons & IN_JUMP) hatData[client].offset[2] += 1.0;
|
||||
if(buttons & IN_DUCK) hatData[client].offset[2] -= 1.0;
|
||||
if(buttons & IN_FORWARD) hatData[client].offset[0] += 1.0;
|
||||
|
@ -542,7 +553,7 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
TeleportEntity(entity, hatData[client].offset, angles, vel);
|
||||
return Plugin_Handled;
|
||||
} else if(tick - cmdThrottle[client] > 0.25) {
|
||||
if(buttons & IN_ATTACK) {
|
||||
if(buttons & IN_ATTACK) { // doesn't work reliably for some reason
|
||||
ClientCommand(client, "sm_hat y");
|
||||
} else if(buttons & IN_DUCK) {
|
||||
ClientCommand(client, "sm_hat p");
|
||||
|
@ -558,7 +569,9 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
}
|
||||
}
|
||||
|
||||
///#WALL BUILDER PROCESS
|
||||
//////////////////////////////
|
||||
// OnPlayerRunCmd :: ENTITY EDITOR
|
||||
/////////////////////////////
|
||||
if(WallBuilder[client].IsActive() && WallBuilder[client].CheckEntity(client)) {
|
||||
if(buttons & IN_USE && buttons & IN_RELOAD) {
|
||||
ClientCommand(client, "sm_wall done");
|
||||
|
@ -578,6 +591,7 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
if(buttons & IN_ATTACK) WallBuilder[client].CycleAxis(client, tick);
|
||||
else if(buttons & IN_ATTACK2) WallBuilder[client].CycleSnapAngle(client, tick);
|
||||
|
||||
// Rotation control:
|
||||
if(tick - cmdThrottle[client] > 0.20) {
|
||||
if(WallBuilder[client].axis == 0) {
|
||||
if(mouse[1] > 10) WallBuilder[client].angles[0] += WallBuilder[client].snapAngle;
|
||||
|
@ -876,4 +890,4 @@ stock bool GetCursorLimited2(int client, float distance, float endPos[3], TraceE
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue