Merge branch 'master' of github.com:Jackzmc/sourcemod-plugins

This commit is contained in:
Jackz 2023-07-20 20:15:48 -05:00
commit 2c99586be1
No known key found for this signature in database
GPG key ID: E0BBD94CF657F603
6 changed files with 116 additions and 253 deletions

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}