mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-05 16:03:21 +00:00
update
This commit is contained in:
parent
3c88c010ad
commit
3a26dffd7a
10 changed files with 214 additions and 141 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
plugins/misc.smx
Normal file
BIN
plugins/misc.smx
Normal file
Binary file not shown.
|
@ -74,15 +74,24 @@ public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroa
|
|||
}
|
||||
public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client > 0 && g_iAttackerTarget[client] > 0) {
|
||||
int target = GetClientOfUserId(g_iAttackerTarget[client]);
|
||||
gInstaSpecialMagnet[target]--;
|
||||
if(gInstaSpecialMagnet[target] == 0) {
|
||||
PrintToServer("[FTT] gInstaSpecialMagnet dropped below 0");
|
||||
gInstaSpecialMagnet[target] = 0;
|
||||
if(client > 0) {
|
||||
if(g_iAttackerTarget[client] > 0) {
|
||||
int target = GetClientOfUserId(g_iAttackerTarget[client]);
|
||||
gInstaSpecialMagnet[target]--;
|
||||
if(gInstaSpecialMagnet[target] == 0) {
|
||||
PrintToServer("[FTT] gInstaSpecialMagnet dropped below 0");
|
||||
gInstaSpecialMagnet[target] = 0;
|
||||
}
|
||||
g_iAttackerTarget[client] = 0;
|
||||
} else {
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(g_iAttackerTarget[i] == client) {
|
||||
g_iAttackerTarget[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g_iAttackerTarget[client] = 0;
|
||||
}
|
||||
public Action Event_WeaponReload(int weapon) {
|
||||
int client = GetEntPropEnt(weapon, Prop_Send, "m_hOwner");
|
||||
|
@ -136,7 +145,7 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
} else if(class == L4D2Infected_Tank && (!IsPlayerIncapped(existingTarget) || hMagnetTargetMode.IntValue & 2) && WillMagnetRun(Trolls[tankMagnetID], existingTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}else if((!IsPlayerIncapped(existingTarget) || hMagnetTargetMode.IntValue & 1) && WillMagnetRun(Trolls[spMagnetID], existingTarget)) {
|
||||
}else if(class != L4D2Infected_Tank && (!IsPlayerIncapped(existingTarget) || hMagnetTargetMode.IntValue & 1) && WillMagnetRun(Trolls[spMagnetID], existingTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
|
@ -148,16 +157,13 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
int closestClient = -1;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
//Ignore incapped players if turned on:
|
||||
|
||||
|
||||
if(class == L4D2Infected_Tank && Trolls[tankMagnetID].IsActive(i) || (class != L4D2Infected_Tank && Trolls[spMagnetID].IsActive(i))) {
|
||||
if(class == L4D2Infected_Tank) {
|
||||
if(!WillMagnetRun(Trolls[tankMagnetID], i)) return Plugin_Continue;
|
||||
} else if(!WillMagnetRun(Trolls[spMagnetID], i)) return Plugin_Continue;
|
||||
if(!WillMagnetRun(Trolls[tankMagnetID], i)) continue;
|
||||
} else if(!WillMagnetRun(Trolls[spMagnetID], i)) continue;
|
||||
|
||||
if(IsPlayerIncapped(i)) {
|
||||
if((class == L4D2Infected_Tank && hMagnetTargetMode.IntValue & 2) || (class != L4D2Infected_Tank && hMagnetTargetMode.IntValue & 1)) continue;
|
||||
if((class == L4D2Infected_Tank && hMagnetTargetMode.IntValue & 2 == 0) || (class != L4D2Infected_Tank && hMagnetTargetMode.IntValue & 1 == 0)) continue;
|
||||
}
|
||||
|
||||
GetClientAbsOrigin(i, survPos);
|
||||
|
@ -173,6 +179,7 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
if(closestClient > 0) {
|
||||
g_iAttackerTarget[attacker] = GetClientUserId(closestClient);
|
||||
curTarget = closestClient;
|
||||
PrintToConsoleAll("[FTT] New target for %d: %N", attacker, curTarget);
|
||||
return Plugin_Changed;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
|
@ -475,7 +482,7 @@ public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float&
|
|||
//Stop FF from marked:
|
||||
static int reverseFF;
|
||||
if(reverseFF == 0) reverseFF = GetTrollID("Reverse FF");
|
||||
if(GetClientTeam(attacker) == 4 && IsFakeClient(attacker)) return Plugin_Stop;
|
||||
if(attacker > 0 && attacker <= MaxClients && GetClientTeam(attacker) == 4 && IsFakeClient(attacker)) return Plugin_Stop;
|
||||
if(attacker > 0 && victim <= MaxClients && attacker <= MaxClients && IsClientInGame(attacker) && IsPlayerAlive(attacker)) {
|
||||
if(shootAtTarget[attacker] == victim) return Plugin_Continue;
|
||||
if(g_PendingBanTroll[attacker] > 0 && GetClientTeam(attacker) == 2 && GetClientTeam(victim) == 2) {
|
||||
|
|
|
@ -51,9 +51,9 @@ public void OnPluginStart() {
|
|||
hSuicideAction = CreateConVar("l4d2_suicide_action", "3", "How should a suicider be punished?\n0 = No action (No message), 1 = Kick, 2 = Instant Ban, 3 = Ban on disconnect", FCVAR_NONE, true, 0.0, true, 3.0);
|
||||
hSuicideLimit = CreateConVar("l4d2_suicide_limit", "1", "How many attempts does a new joined player have until action is taken for suiciding?", FCVAR_NONE, true, 0.0);
|
||||
// Reverse FF Auto Scale
|
||||
hFFAutoScaleAmount = CreateConVar("l4d2_tk_auto_ff_rate", "0.01", "The rate at which auto reverse-ff is scaled by.", FCVAR_NONE, true, 0.0);
|
||||
hFFAutoScaleAmount = CreateConVar("l4d2_tk_auto_ff_rate", "0.02", "The rate at which auto reverse-ff is scaled by.", FCVAR_NONE, true, 0.0);
|
||||
hFFAutoScaleMaxRatio = CreateConVar("l4d2_tk_auto_ff_max_ratio", "5.0", "The maximum amount that the reverse ff can go. 0.0 for unlimited", FCVAR_NONE, true, 0.0);
|
||||
hFFAutoScaleForgivenessAmount = CreateConVar("l4d2_tk_auto_ff_forgive_rate", "0.02", "This amount times amount of minutes since last ff is removed from ff rate", FCVAR_NONE, true, 0.0);
|
||||
hFFAutoScaleForgivenessAmount = CreateConVar("l4d2_tk_auto_ff_forgive_rate", "0.03", "This amount times amount of minutes since last ff is removed from ff rate", FCVAR_NONE, true, 0.0);
|
||||
hFFAutoScaleIgnoreAdmins = CreateConVar("l4d2_tk_auto_ff_ignore_admins", "1", "Should automatic reverse ff ignore admins? 0 = Admins are subjected\n1 = Admins are excempt", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
|
||||
AutoExecConfig(true, "l4d2_tkstopper");
|
||||
|
@ -186,7 +186,7 @@ public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroa
|
|||
public Action Event_OnTakeDamage(int victim, int& attacker, int& inflictor, float& damage, int& damagetype, int& weapon, float damageForce[3], float damagePosition[3]) {
|
||||
if(damage > 0.0 && victim <= MaxClients && attacker <= MaxClients && attacker > 0 && victim > 0 && attacker != victim) {
|
||||
if(GetClientTeam(victim) != GetClientTeam(attacker) || attacker == victim) return Plugin_Continue;
|
||||
else if(damagetype & DMG_BURN && IsFakeClient(attacker)) {
|
||||
else if(damagetype & DMG_BURN && IsFakeClient(attacker) && GetClientTeam(attacker) == 2) {
|
||||
// Ignore damage from fire caused by bots (players who left after causing fire)
|
||||
damage = 0.0;
|
||||
return Plugin_Changed;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define DEBUG_LEVEL DEBUG_GENERIC
|
||||
#define EXTRA_PLAYER_HUD_UPDATE_INTERVAL 0.8
|
||||
//Sets abmExtraCount to this value if set
|
||||
// #define DEBUG_FORCE_PLAYERS 5
|
||||
// #define DEBUG_FORCE_PLAYERS 7
|
||||
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
|
@ -71,15 +71,21 @@ public Plugin myinfo =
|
|||
url = ""
|
||||
};
|
||||
|
||||
static ConVar hExtraItemBasePercentage, hAddExtraKits, hMinPlayers, hUpdateMinPlayers, hMinPlayersSaferoomDoor, hSaferoomDoorWaitSeconds, hSaferoomDoorAutoOpen, hEPIHudState, hExtraFinaleTank;
|
||||
static ConVar hExtraItemBasePercentage, hAddExtraKits, hMinPlayers, hUpdateMinPlayers, hMinPlayersSaferoomDoor, hSaferoomDoorWaitSeconds, hSaferoomDoorAutoOpen, hEPIHudState, hExtraFinaleTank, cvDropDisconnectTime;
|
||||
static int extraKitsAmount, extraKitsStarted, abmExtraCount, firstSaferoomDoorEntity, playersLoadedIn, playerstoWaitFor;
|
||||
static int isBeingGivenKit[MAXPLAYERS+1];
|
||||
static int finaleStage;
|
||||
static bool isCheckpointReached, isLateLoaded, firstGiven, isFailureRound;
|
||||
static ArrayList ammoPacks;
|
||||
static Handle updateHudTimer;
|
||||
static char gamemode[32];
|
||||
|
||||
enum struct PlayerData {
|
||||
bool itemGiven; //Is player being given an item (such that the next pickup event is ignored)
|
||||
bool isUnderAttack; //Is the player under attack (by any special)
|
||||
bool active;
|
||||
}
|
||||
|
||||
PlayerData playerData[MAXPLAYERS+1];
|
||||
|
||||
static StringMap weaponMaxClipSizes;
|
||||
|
||||
static char HUD_SCRIPT[] = "ExtraPlayerHUD <- { Fields = { players = { slot = g_ModeScript.HUD_RIGHT_BOT, dataval = \"%s\", flags = g_ModeScript.HUD_FLAG_ALIGN_LEFT | g_ModeScript.HUD_FLAG_TEAM_SURVIVORS | g_ModeScript.HUD_FLAG_NOBG } } }; HUDSetLayout( ExtraPlayerHUD ); HUDPlace( g_ModeScript.HUD_RIGHT_BOT, 0.72, 0.78, 0.3, 0.3 ); g_ModeScript";
|
||||
|
@ -89,9 +95,10 @@ enum struct Cabinet {
|
|||
int id;
|
||||
int items[CABINET_ITEM_BLOCKS];
|
||||
}
|
||||
|
||||
static Cabinet cabinets[10]; //Store 10 cabinets
|
||||
|
||||
//// Definitions complete
|
||||
|
||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) {
|
||||
if(late) isLateLoaded = true;
|
||||
return APLRes_Success;
|
||||
|
@ -118,6 +125,24 @@ public void OnPluginStart() {
|
|||
HookEvent("round_freeze_end", Event_RoundFreezeEnd);
|
||||
HookEvent("tank_spawn", Event_TankSpawn);
|
||||
|
||||
//Special Event Tracking
|
||||
HookEvent("player_disconnect", Event_PlayerDisconnect);
|
||||
|
||||
HookEvent("charger_carry_start", Event_ChargerCarry);
|
||||
HookEvent("charger_carry_end", Event_ChargerCarry);
|
||||
|
||||
HookEvent("lunge_pounce", Event_HunterPounce);
|
||||
HookEvent("pounce_end", Event_HunterPounce);
|
||||
HookEvent("pounce_stopped", Event_HunterPounce);
|
||||
|
||||
HookEvent("choke_start", Event_SmokerChoke);
|
||||
HookEvent("choke_end", Event_SmokerChoke);
|
||||
HookEvent("choke_stopped", Event_SmokerChoke);
|
||||
|
||||
HookEvent("jockey_ride", Event_JockeyRide);
|
||||
HookEvent("jockey_ride_end", Event_JockeyRide);
|
||||
|
||||
|
||||
hExtraItemBasePercentage = CreateConVar("l4d2_extraitems_chance", "0.056", "The base chance (multiplied by player count) of an extra item being spawned.", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hAddExtraKits = CreateConVar("l4d2_extraitems_kitmode", "0", "Decides how extra kits should be added.\n0 -> Overwrites previous extra kits, 1 -> Adds onto previous extra kits", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hUpdateMinPlayers = CreateConVar("l4d2_extraitems_updateminplayers", "1", "Should the plugin update abm\'s cvar min_players convar to the player count?\n 0 -> NO, 1 -> YES", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
|
@ -126,6 +151,7 @@ public void OnPluginStart() {
|
|||
hSaferoomDoorAutoOpen = CreateConVar("l4d2_extraitems_doorunlock_open", "0", "Controls when the door automatically opens after unlocked. Add bits together.\n0 = Never, 1 = When timer expires, 2 = When all players loaded in", FCVAR_NONE, true, 0.0);
|
||||
hEPIHudState = CreateConVar("l4d2_extraitems_hudstate", "1", "Controls when the hud displays.\n0 -> OFF, 1 = When 5+ players, 2 = ALWAYS", FCVAR_NONE, true, 0.0, true, 2.0);
|
||||
hExtraFinaleTank = CreateConVar("l4d2_extraitems_extra_finale_tank", "1", "0 = Normal tank spawning, 1 = Two tanks spawn on second stage (half health)", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
cvDropDisconnectTime = CreateConVar("l4d2_extraitems_disconnect_time", "120", "The amount of seconds after a player has actually disconnected, where their character slot will be void. 0 to disable", FCVAR_NONE, true, 0.0);
|
||||
|
||||
hEPIHudState.AddChangeHook(Cvar_HudStateChange);
|
||||
|
||||
|
@ -172,6 +198,40 @@ public void OnPluginStart() {
|
|||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Special Infected Events
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
public Action Event_ChargerCarry(Event event, const char[] name, bool dontBroadcast) {
|
||||
int victim = GetClientOfUserId(event.GetInt("victim"));
|
||||
if(victim) {
|
||||
playerData[victim].isUnderAttack = StrEqual(name, "charger_carry_start");
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_HunterPounce(Event event, const char[] name, bool dontBroadcast) {
|
||||
int victim = GetClientOfUserId(event.GetInt("victim"));
|
||||
if(victim) {
|
||||
playerData[victim].isUnderAttack = StrEqual(name, "lunge_pounce");
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_SmokerChoke(Event event, const char[] name, bool dontBroadcast) {
|
||||
int victim = GetClientOfUserId(event.GetInt("victim"));
|
||||
if(victim) {
|
||||
playerData[victim].isUnderAttack = StrEqual(name, "choke_start");
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
public Action Event_JockeyRide(Event event, const char[] name, bool dontBroadcast) {
|
||||
int victim = GetClientOfUserId(event.GetInt("victim"));
|
||||
if(victim) {
|
||||
playerData[victim].isUnderAttack = StrEqual(name, "jockey_ride");
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public void Event_GamemodeChange(ConVar cvar, const char[] oldValue, const char[] newValue) {
|
||||
cvar.GetString(gamemode, sizeof(gamemode));
|
||||
}
|
||||
|
@ -275,55 +335,85 @@ public Action Command_RunExtraItems(int client, int args) {
|
|||
#define FINALE_HORDE 7
|
||||
#define FINALE_WAIT 10
|
||||
|
||||
enum FinaleStage {
|
||||
Stage_Inactive = 0,
|
||||
Stage_FinaleActive = 1,
|
||||
Stage_FinaleTank1 = 2,
|
||||
Stage_FinaleTank2 = 3,
|
||||
Stage_FinaleDuplicatePending = 4,
|
||||
Stage_TankSplit = 5,
|
||||
Stage_InactiveFinale = -1
|
||||
}
|
||||
int extraTankHP;
|
||||
FinaleStage finaleStage;
|
||||
|
||||
public Action L4D2_OnChangeFinaleStage(int &finaleType, const char[] arg) {
|
||||
if(finaleType == FINALE_STARTED && abmExtraCount > 4 && hExtraFinaleTank.BoolValue) {
|
||||
finaleStage = 1;
|
||||
finaleStage = Stage_FinaleActive;
|
||||
PrintToConsoleAll("[EPI] Finale started and over threshold");
|
||||
} else if(finaleType == FINALE_TANK) {
|
||||
if(finaleStage == 1) {
|
||||
finaleStage = 2;
|
||||
if(finaleStage == Stage_FinaleActive) {
|
||||
finaleStage = Stage_FinaleTank1;
|
||||
PrintToConsoleAll("[EPI] First tank stage has started");
|
||||
} else if(finaleStage == 2) {
|
||||
finaleStage = 3;
|
||||
} else if(finaleStage == Stage_FinaleTank1) {
|
||||
finaleStage = Stage_FinaleTank2;
|
||||
PrintToConsoleAll("[EPI] Second stage started, waiting for tank");
|
||||
} else {
|
||||
PrintToConsoleAll("invalid");
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public void Event_TankSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||
int user = GetEventInt(event, "userid");
|
||||
int user = event.GetInt("userid");
|
||||
int tank = GetClientOfUserId(user);
|
||||
if(finaleStage == 3) {
|
||||
PrintToConsoleAll("[EPI] Second tank spawned, setting health.");
|
||||
if(tank > 0 && IsFakeClient(tank)) {
|
||||
if(tank > 0 && IsFakeClient(tank) && abmExtraCount > 4 && hExtraFinaleTank.BoolValue) {
|
||||
if(finaleStage == Stage_FinaleTank2) {
|
||||
PrintToConsoleAll("[EPI] Second tank spawned, setting health.");
|
||||
// Sets health in half, sets finaleStage to health
|
||||
CreateTimer(5.0, Timer_SplitTank, user);
|
||||
CreateTimer(5.0, Timer_SpawnFinaleTank, user);
|
||||
} else if(finaleStage == Stage_FinaleDuplicatePending) {
|
||||
PrintToConsoleAll("[EPI] Third & final tank spawned");
|
||||
RequestFrame(Frame_SetExtraTankHealth, user);
|
||||
} else if(finaleStage == Stage_Inactive && GetSurvivorsCount() > 6) {
|
||||
PrintToConsoleAll("[EPI] Creating a split tank");
|
||||
finaleStage = Stage_TankSplit;
|
||||
// Half their HP, assign half to self and for next tank
|
||||
int hp = GetEntProp(tank, Prop_Send, "m_iHealth") / 2;
|
||||
SetEntProp(tank, Prop_Send, "m_iHealth", hp);
|
||||
extraTankHP = hp;
|
||||
CreateTimer(11.0, Timer_SplitTank, user);
|
||||
// Then, summon the next tank
|
||||
} else if(finaleStage == Stage_TankSplit) {
|
||||
|
||||
}
|
||||
} else if(finaleStage > 3) {
|
||||
PrintToConsoleAll("[EPI] Third & final tank spawned, setting health.");
|
||||
RequestFrame(Frame_SetExtraTankHealth, user);
|
||||
}
|
||||
}
|
||||
public Action Timer_SpawnFinaleTank(Handle t, int user) {
|
||||
if(finaleStage == Stage_TankSplit) {
|
||||
ServerCommand("sm_forcespecial tank");
|
||||
finaleStage = Stage_Inactive;
|
||||
}
|
||||
}
|
||||
public Action Timer_SplitTank(Handle t, int user) {
|
||||
int tank = GetClientOfUserId(user);
|
||||
if(tank > 0) {
|
||||
if(tank > 0 && finaleStage == Stage_Inactive) {
|
||||
finaleStage = Stage_TankSplit;
|
||||
// Half their HP, assign half to self and for next tank
|
||||
int hp = GetEntProp(tank, Prop_Send, "m_iHealth") / 2;
|
||||
SetEntProp(tank, Prop_Send, "m_iHealth", hp);
|
||||
finaleStage = hp;
|
||||
extraTankHP = hp;
|
||||
// Then, summon the next tank
|
||||
ServerCommand("sm_forcespecial tank");
|
||||
} else {
|
||||
finaleStage = Stage_Inactive;
|
||||
}
|
||||
}
|
||||
|
||||
public void Frame_SetExtraTankHealth(int user) {
|
||||
int tank = GetClientOfUserId(user);
|
||||
if(tank > 0) {
|
||||
SetEntProp(tank, Prop_Send, "m_iHealth", finaleStage);
|
||||
finaleStage = 0;
|
||||
if(tank > 0 && finaleStage == Stage_FinaleDuplicatePending) {
|
||||
SetEntProp(tank, Prop_Send, "m_iHealth", extraTankHP);
|
||||
finaleStage = Stage_InactiveFinale;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,6 +426,10 @@ public void OnGetWeaponsInfo(int pThis, const char[] classname) {
|
|||
weaponMaxClipSizes.SetValue(classname, maxClipSize);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//// PLAYER STATE MANAGEMENT
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
//Called on the first spawn in a mission.
|
||||
public Action Event_GameStart(Event event, const char[] name, bool dontBroadcast) {
|
||||
firstGiven = false;
|
||||
|
@ -349,35 +443,40 @@ public Action Event_GameStart(Event event, const char[] name, bool dontBroadcast
|
|||
|
||||
public Action Event_PlayerFirstSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(GetClientTeam(client) == 2 && !IsFakeClient(client)) {
|
||||
if(L4D_IsFirstMapInScenario() && !firstGiven) {
|
||||
//Check if all clients are ready, and survivor count is > 4.
|
||||
if(AreAllClientsReady()) {
|
||||
abmExtraCount = GetRealSurvivorsCount();
|
||||
if(abmExtraCount > 4) {
|
||||
firstGiven = true;
|
||||
//Set the initial value ofhMinPlayers
|
||||
if(hUpdateMinPlayers.BoolValue && hMinPlayers != null) {
|
||||
hMinPlayers.IntValue = abmExtraCount;
|
||||
if(GetClientTeam(client) == 2) {
|
||||
CreateTimer(1.5, Timer_RemoveInvincibility, client);
|
||||
SDKHook(client, SDKHook_OnTakeDamage, OnInvincibleDamageTaken);
|
||||
if(!IsFakeClient(client)) {
|
||||
playerData[client].active = true;
|
||||
if(L4D_IsFirstMapInScenario() && !firstGiven) {
|
||||
//Check if all clients are ready, and survivor count is > 4.
|
||||
if(AreAllClientsReady()) {
|
||||
abmExtraCount = GetRealSurvivorsCount();
|
||||
if(abmExtraCount > 4) {
|
||||
firstGiven = true;
|
||||
//Set the initial value ofhMinPlayers
|
||||
if(hUpdateMinPlayers.BoolValue && hMinPlayers != null) {
|
||||
hMinPlayers.IntValue = abmExtraCount;
|
||||
}
|
||||
PopulateItems();
|
||||
CreateTimer(1.0, Timer_GiveKits);
|
||||
}
|
||||
if(firstSaferoomDoorEntity > 0 && IsValidEntity(firstSaferoomDoorEntity)) {
|
||||
UnlockDoor(firstSaferoomDoorEntity, 2);
|
||||
}
|
||||
PopulateItems();
|
||||
CreateTimer(1.0, Timer_GiveKits);
|
||||
}
|
||||
if(firstSaferoomDoorEntity > 0 && IsValidEntity(firstSaferoomDoorEntity)) {
|
||||
UnlockDoor(firstSaferoomDoorEntity, 2);
|
||||
} else {
|
||||
// New client has connected, not on first map.
|
||||
// TODO: Check if Timer_UpdateMinPlayers is needed, or if this works:
|
||||
// Never decrease abmExtraCount
|
||||
int newCount = GetRealSurvivorsCount();
|
||||
if(newCount > abmExtraCount) {
|
||||
abmExtraCount = newCount;
|
||||
}
|
||||
// If 5 survivors, then set them up, TP them.
|
||||
if(abmExtraCount > 4) {
|
||||
RequestFrame(Frame_SetupNewClient, client);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// New client has connected, not on first map.
|
||||
// TODO: Check if Timer_UpdateMinPlayers is needed, or if this works:
|
||||
// Never decrease abmExtraCount
|
||||
int newCount = GetRealSurvivorsCount();
|
||||
if(newCount > abmExtraCount) {
|
||||
abmExtraCount = newCount;
|
||||
}
|
||||
// If 5 survivors, then set them up, TP them.
|
||||
if(abmExtraCount > 4) {
|
||||
RequestFrame(Frame_SetupNewClient, client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -417,6 +516,32 @@ public Action Event_PlayerSpawn(Event event, const char[] name, bool dontBroadca
|
|||
|
||||
}
|
||||
|
||||
public void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroadcast) {
|
||||
int userid = event.GetInt("userid");
|
||||
int client = GetClientOfUserId(userid);
|
||||
if(client > 0 && !IsFakeClient(client)) {
|
||||
DataPack pack = new DataPack();
|
||||
pack.WriteCell(userid);
|
||||
pack.WriteCell(client);
|
||||
CreateDataTimer(cvDropDisconnectTime.FloatValue, Timer_DropSurvivor, pack);
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_DropSurvivor(Handle h, DataPack pack) {
|
||||
int userid = pack.ReadCell();
|
||||
int client = GetClientOfUserId(userid);
|
||||
// Check if player is not connected, if not, drop their existing status
|
||||
if(client == 0) {
|
||||
client = pack.ReadCell();
|
||||
if(client == 0) //In the case that someone took their client index, don't inactivate them:
|
||||
playerData[client].active = false;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
/////// Events
|
||||
/////////////////////////////////////////
|
||||
|
||||
public Action Event_ItemPickup(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client > 0) {
|
||||
|
@ -440,12 +565,10 @@ public void Frame_SetupNewClient(int client) {
|
|||
int item = GivePlayerItem(client, "weapon_first_aid_kit");
|
||||
EquipPlayerWeapon(client, item);
|
||||
}
|
||||
static float spawnPos[3];
|
||||
// TODO: Fix null
|
||||
if(GetIdealPositionInSurvivorFlow(client, spawnPos))
|
||||
TeleportEntity(client, spawnPos, NULL_VECTOR, NULL_VECTOR);
|
||||
CreateTimer(1.5, Timer_RemoveInvincibility, client);
|
||||
SDKHook(client, SDKHook_OnTakeDamage, OnInvincibleDamageTaken);
|
||||
|
||||
// static float spawnPos[3];
|
||||
// if(GetIdealPositionInSurvivorFlow(client, spawnPos))
|
||||
// TeleportEntity(client, spawnPos, NULL_VECTOR, NULL_VECTOR);
|
||||
}
|
||||
public Action Timer_RemoveInvincibility(Handle h, int client) {
|
||||
SDKUnhook(client, SDKHook_OnTakeDamage, OnInvincibleDamageTaken);
|
||||
|
@ -530,7 +653,7 @@ public void OnMapStart() {
|
|||
HookEntityOutput("trigger_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom);
|
||||
|
||||
playersLoadedIn = 0;
|
||||
finaleStage = 0;
|
||||
finaleStage = Stage_Inactive;
|
||||
}
|
||||
|
||||
|
||||
|
@ -605,7 +728,7 @@ public Action Event_Pickup(int client, int weapon) {
|
|||
static char name[32];
|
||||
GetEntityClassname(weapon, name, sizeof(name));
|
||||
if(StrEqual(name, "weapon_first_aid_kit", true)) {
|
||||
if(isBeingGivenKit[client]) return Plugin_Continue;
|
||||
if(playerData[client].itemGiven) return Plugin_Continue;
|
||||
if((L4D_IsInFirstCheckpoint(client) || L4D_IsInLastCheckpoint(client)) && UseExtraKit(client)) {
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
@ -625,62 +748,6 @@ public void OnEntityCreated(int entity, const char[] classname) {
|
|||
}
|
||||
}
|
||||
|
||||
int tankChooseVictimTicks[MAXPLAYERS+1]; //Per tank
|
||||
int totalTankDamage[MAXPLAYERS+1]; //Per survivor
|
||||
|
||||
public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
||||
if(abmExtraCount <= 4) return Plugin_Continue;
|
||||
int class = GetEntProp(attacker, Prop_Send, "m_zombieClass");
|
||||
if(class != TANK_CLASS_ID) return Plugin_Continue;
|
||||
|
||||
//Find a new victim
|
||||
if(++tankChooseVictimTicks[attacker] > 200) {
|
||||
tankChooseVictimTicks[attacker] = 0;
|
||||
ArrayList clients = new ArrayList(2);
|
||||
float tankPos[3], clientPos[3];
|
||||
GetClientAbsOrigin(attacker, tankPos);
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
//If a player does less than 50 damage, and has green health add them to list
|
||||
if(totalTankDamage[i] < 100 && GetClientHealth(i) > 40) {
|
||||
GetClientAbsOrigin(i, clientPos);
|
||||
float dist = GetVectorDistance(clientPos, tankPos);
|
||||
// Only add targets who are far enough away from tank
|
||||
if(dist > 5000) {
|
||||
PrintDebug(DEBUG_ANY, "Adding player %N to possible victim list. Dist=%f, Dmg=%d", i, dist, totalTankDamage[i]);
|
||||
int index = clients.Push(i);
|
||||
clients.Set(index, dist, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(clients.Length == 0) return Plugin_Continue;
|
||||
|
||||
clients.SortCustom(Sort_TankTargetter);
|
||||
/*curTarget = clients.Get(0);*/
|
||||
PrintDebug(DEBUG_ANY, "Player Selected to target: %N", curTarget);
|
||||
//TODO: Possibly clear totalTankDamage
|
||||
delete clients;
|
||||
//return Plugin_Changed;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
int Sort_TankTargetter(int index1, int index2, Handle array, Handle hndl) {
|
||||
int client1 = GetArrayCell(array, index1);
|
||||
int client2 =GetArrayCell(array, index2);
|
||||
float distance1 = GetArrayCell(array, index2, 0);
|
||||
float distance2 = GetArrayCell(array, index2, 1);
|
||||
/*500 units away, 0 damage vs 600 units away, 0 damage
|
||||
-> target closest 500
|
||||
500 units away, 10 damage, vs 600 units away 0 damage
|
||||
500 - 10 = 450 vs 600
|
||||
*/
|
||||
return (totalTankDamage[client1] + RoundFloat(distance1)) - (totalTankDamage[client2] + RoundFloat(distance2));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hooks
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -808,6 +875,7 @@ public Action Timer_OpenSaferoomDoor(Handle h) {
|
|||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
|
||||
void UnlockDoor(int entity, int flag) {
|
||||
PrintDebug(DEBUG_GENERIC, "Door unlocked, flag %d", flag);
|
||||
if(IsValidEntity(entity)) {
|
||||
|
@ -1001,10 +1069,10 @@ stock bool DoesClientHaveKit(int client) {
|
|||
|
||||
stock bool UseExtraKit(int client) {
|
||||
if(extraKitsAmount > 0) {
|
||||
isBeingGivenKit[client] = true;
|
||||
playerData[client].itemGiven = true;
|
||||
int ent = GivePlayerItem(client, "weapon_first_aid_kit");
|
||||
EquipPlayerWeapon(client, ent);
|
||||
isBeingGivenKit[client] = false;
|
||||
playerData[client].itemGiven = false;
|
||||
if(--extraKitsAmount <= 0) {
|
||||
extraKitsAmount = 0;
|
||||
}
|
||||
|
@ -1135,7 +1203,7 @@ stock void RunVScriptLong(const char[] sCode, any ...) {
|
|||
// Gets a position (from a nav area)
|
||||
stock bool GetIdealPositionInSurvivorFlow(int target, float pos[3]) {
|
||||
static float ang[3];
|
||||
int client = GetHighestFlowSurvivor(target);
|
||||
int client = GetLowestFlowSurvivor(target);
|
||||
if(client > 0) {
|
||||
GetClientAbsOrigin(client, pos);
|
||||
GetClientAbsAngles(client, ang);
|
||||
|
|
|
@ -64,7 +64,7 @@ public void OnPluginStart() {
|
|||
hAutoPunish = CreateConVar("sm_ftt_autopunish_action", "0", "Setup automatic punishment of players. Add bits together\n0=Disabled, 1=Tank magnet, 2=Special magnet, 4=Swarm, 8=InstantVomit", FCVAR_NONE, true, 0.0);
|
||||
hAutoPunishExpire = CreateConVar("sm_ftt_autopunish_expire", "0", "How many minutes of gametime until autopunish is turned off? 0 for never.", FCVAR_NONE, true, 0.0);
|
||||
hMagnetChance = CreateConVar("sm_ftt_magnet_chance", "1.0", "% of the time that the magnet will work on a player.", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hMagnetTargetMode = CreateConVar("sm_ftt_magnet_targetting", "6", "How does the specials target players. Add bits together\n0=Incapped are ignored, 1=Specials targets incapped, 2=Tank targets incapped 4=Witch targets incapped");
|
||||
hMagnetTargetMode = CreateConVar("sm_ftt_magnet_targetting", "4", "How does the specials target players. Add bits together\n0=Incapped are ignored, 1=Specials targets incapped, 2=Tank targets incapped 4=Witch targets incapped");
|
||||
hShoveFailChance = CreateConVar("sm_ftt_shove_fail_chance", "0.65", "The % chance that a shove fails", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hBadThrowHitSelf = CreateConVar("sm_ftt_badthrow_fail_chance", "1", "The % chance that on a throw, they will instead hit themselves. 0 to disable", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hBotReverseFFDefend = CreateConVar("sm_ftt_bot_defend", "1", "Should bots defend themselves?\n0 = OFF\n1 = Will retaliate against non-admins\n2 = Anyone", FCVAR_NONE, true, 0.0, true, 2.0);
|
||||
|
|
|
@ -67,17 +67,15 @@ public Action Cmd_VGag(int client, int args) {
|
|||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE, /* Only allow alive players */
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
/* This function replies to the admin with a failure message */
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
for (int i = 0; i < target_count; i++)
|
||||
{
|
||||
for (int i = 0; i < target_count; i++) {
|
||||
int playerIndex = gaggedPlayers[client].FindValue(target_list[i]);
|
||||
if(playerIndex > -1) {
|
||||
gaggedPlayers[client].Erase(playerIndex);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue