mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 03:03:21 +00:00
Update updated part of README.md
This commit is contained in:
parent
73fa3ea30f
commit
f1ad9f3865
21 changed files with 4934 additions and 89 deletions
|
@ -166,7 +166,7 @@ This really only affects wandering zombies, mobs and panic events, but it may wo
|
||||||
### l4d2_feedthetrolls
|
### l4d2_feedthetrolls
|
||||||
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.
|
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.
|
||||||
|
|
||||||
Troll Modes: (updated 1/2/2021)
|
Troll Modes: (updated 4/20/2021)
|
||||||
|
|
||||||
1. **SlowSpeed** (0.8 < 1.0 base) - Slows down a user
|
1. **SlowSpeed** (0.8 < 1.0 base) - Slows down a user
|
||||||
2. **HigherGravity** (1.3 > 1.0) - Adds more gravity to a user
|
2. **HigherGravity** (1.3 > 1.0) - Adds more gravity to a user
|
||||||
|
|
BIN
plugins/BumpMineGiver.smx
Normal file
BIN
plugins/BumpMineGiver.smx
Normal file
Binary file not shown.
BIN
plugins/L4D2PreventBotMovement.smx
Normal file
BIN
plugins/L4D2PreventBotMovement.smx
Normal file
Binary file not shown.
BIN
plugins/l4d2_drop_secondary.smx
Normal file
BIN
plugins/l4d2_drop_secondary.smx
Normal file
Binary file not shown.
BIN
plugins/l4d2_skill_detect.smx
Normal file
BIN
plugins/l4d2_skill_detect.smx
Normal file
Binary file not shown.
BIN
plugins/l4d2_target_test.smx
Normal file
BIN
plugins/l4d2_target_test.smx
Normal file
Binary file not shown.
Binary file not shown.
BIN
plugins/l4d_target_override.smx
Normal file
BIN
plugins/l4d_target_override.smx
Normal file
Binary file not shown.
BIN
plugins/l4dunreservelobby.smx
Normal file
BIN
plugins/l4dunreservelobby.smx
Normal file
Binary file not shown.
BIN
plugins/left4dhooks.smx
Normal file
BIN
plugins/left4dhooks.smx
Normal file
Binary file not shown.
BIN
plugins/sceneprocessor.smx
Normal file
BIN
plugins/sceneprocessor.smx
Normal file
Binary file not shown.
|
@ -24,7 +24,7 @@ public Plugin myinfo =
|
||||||
url = PLUGIN_URL
|
url = PLUGIN_URL
|
||||||
};
|
};
|
||||||
|
|
||||||
bool g_EnteredCheckpoint = false;
|
ConVar g_EnteredCheckpoint;
|
||||||
|
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
{
|
{
|
||||||
|
@ -34,28 +34,31 @@ public void OnPluginStart()
|
||||||
SetFailState("This plugin is for L4D/L4D2 only.");
|
SetFailState("This plugin is for L4D/L4D2 only.");
|
||||||
}
|
}
|
||||||
HookEvent("player_entered_checkpoint", Event_PlayerEnteredCheckpoint);
|
HookEvent("player_entered_checkpoint", Event_PlayerEnteredCheckpoint);
|
||||||
HookEvent("round_start",Event_RoundStart);
|
HookEvent("player_left_start_area",Event_RoundStart);
|
||||||
|
g_EnteredCheckpoint = CreateConVar("awb_status", "0", "Get status of plugin", FCVAR_SPONLY | FCVAR_DONTRECORD, true, 0.0, true, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
|
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
|
||||||
g_EnteredCheckpoint = false;
|
if(g_EnteredCheckpoint.BoolValue) g_EnteredCheckpoint.BoolValue = false;
|
||||||
}
|
}
|
||||||
public void Event_PlayerEnteredCheckpoint(Event event, const char[] name, bool dontBroadcast) {
|
public void Event_PlayerEnteredCheckpoint(Event event, const char[] name, bool dontBroadcast) {
|
||||||
if(!g_EnteredCheckpoint) {
|
PrintToChatAll("boolvalue %d | client %d", g_EnteredCheckpoint.BoolValue, GetClientOfUserId(event.GetInt("userid")));
|
||||||
|
if(!g_EnteredCheckpoint.BoolValue) {
|
||||||
|
|
||||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
bool playersLeft = false;
|
bool playersLeft = false;
|
||||||
for (int i = 1; i < MaxClients;i++) {
|
for (int i = 1; i < MaxClients;i++) {
|
||||||
if (client == i)continue;
|
if (client == i) continue;
|
||||||
if (!IsClientConnected(i)) continue;
|
if (!IsClientInGame(i)) continue;
|
||||||
if (GetClientTeam(i) != 2) continue;
|
if (GetClientTeam(i) != 2) continue;
|
||||||
|
PrintToChatAll("playersLeft: %d . clientr %d", playersLeft, i);
|
||||||
if(!IsFakeClient(i)) {
|
if(!IsFakeClient(i)) {
|
||||||
playersLeft = true;
|
playersLeft = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!playersLeft) {
|
if(!playersLeft) {
|
||||||
g_EnteredCheckpoint = true;
|
g_EnteredCheckpoint.BoolValue = true;
|
||||||
CheatCommand(client,"warp_all_survivors_to_checkpoint","","");
|
CheatCommand(client,"warp_all_survivors_to_checkpoint","","");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
114
scripting/BumpMineGiver.sp
Normal file
114
scripting/BumpMineGiver.sp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#pragma semicolon 1
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
|
#define PLUGIN_AUTHOR ""
|
||||||
|
#define PLUGIN_VERSION "0.00"
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <cstrike>
|
||||||
|
//#include <sdkhooks>
|
||||||
|
|
||||||
|
#pragma newdecls required
|
||||||
|
|
||||||
|
ConVar g_bmgTTeam, g_bmgEnabled, g_bmgCmdLimit;
|
||||||
|
|
||||||
|
int g_bmgBumpsGiven[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "BumpMineGiver",
|
||||||
|
author = PLUGIN_AUTHOR,
|
||||||
|
description = "",
|
||||||
|
version = PLUGIN_VERSION,
|
||||||
|
url = ""
|
||||||
|
};
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
EngineVersion g_Game = GetEngineVersion();
|
||||||
|
if(g_Game != Engine_CSGO && g_Game != Engine_CSS)
|
||||||
|
{
|
||||||
|
SetFailState("This plugin is for CSGO/CSS only.");
|
||||||
|
}
|
||||||
|
g_bmgEnabled = CreateConVar("bmg_enabled", "1", "Should BumpMineGiver be enabled?", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||||
|
g_bmgTTeam = CreateConVar("bmg_restrict_team", "0", "Should BumpMineGiver be restricted to a team? 0 - All, 1 - Terrorists, 2 - CounterTerrorists", FCVAR_NONE, true, 0.0, true, 3.0);
|
||||||
|
g_bmgCmdLimit = CreateConVar("bmg_cmdlimit", "0", "Limit of amount of bumpmines to be given with !bmp. 0: Disabled, -1: Infinity", FCVAR_NONE);
|
||||||
|
HookEvent("round_start", Event_RoundStart);
|
||||||
|
HookEvent("player_spawn", Event_PlayerSpawn);
|
||||||
|
|
||||||
|
RegConsoleCmd("sm_bmp", Command_GiveBMP, "Give yourself a bump mine");
|
||||||
|
RegConsoleCmd("sm_bmg", Command_GiveBMP, "Give yourself a bump mine");
|
||||||
|
RegAdminCmd("sm_givebmp", Command_GiveOthersBMP, ADMFLAG_CHEATS, "Give someone x amount of bump mines. Usage: sm_givebmp <user>");
|
||||||
|
AutoExecConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
|
||||||
|
for (int i = 0; i < sizeof(g_bmgBumpsGiven); i++) {
|
||||||
|
g_bmgBumpsGiven[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||||
|
if(g_bmgEnabled.BoolValue) {
|
||||||
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
|
int wpn_id = GetPlayerWeaponSlot(client, 4);
|
||||||
|
int team = GetClientTeam(client);
|
||||||
|
if(g_bmgTTeam.IntValue > 0) { //1 or 2
|
||||||
|
if (team != g_bmgTTeam.IntValue) return;
|
||||||
|
}
|
||||||
|
if(wpn_id == -1) {
|
||||||
|
GivePlayerItem(client, "weapon_bumpmine");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_GiveBMP(int client, int args) {
|
||||||
|
if(g_bmgCmdLimit.IntValue == 0) {
|
||||||
|
ReplyToCommand(client, "You have hit the limit of bumpmines");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
//limit is enabled, check
|
||||||
|
if(g_bmgCmdLimit.IntValue > 0) {
|
||||||
|
if(g_bmgBumpsGiven[client] > g_bmgCmdLimit.IntValue) {
|
||||||
|
ReplyToCommand(client, "You have hit the limit of bumpmines");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GivePlayerItem(client, "weapon_bumpmine");
|
||||||
|
g_bmgBumpsGiven[client]++;
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_GiveOthersBMP(int client, int args) {
|
||||||
|
if(args < 1) {
|
||||||
|
ReplyToCommand(client, "Usage: sm_givebmp <user>");
|
||||||
|
}else{
|
||||||
|
char arg1[32];
|
||||||
|
GetCmdArg(1, arg1, sizeof(arg1));
|
||||||
|
char target_name[MAX_TARGET_LENGTH];
|
||||||
|
int target_list[MAXPLAYERS], target_count;
|
||||||
|
bool tn_is_ml;
|
||||||
|
if ((target_count = ProcessTargetString(
|
||||||
|
arg1,
|
||||||
|
client,
|
||||||
|
target_list,
|
||||||
|
MAXPLAYERS,
|
||||||
|
COMMAND_FILTER_ALIVE, /* Only allow alive players */
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
GivePlayerItem(target_list[i], "weapon_bumpmine");
|
||||||
|
LogAction(client, target_list[i], "\"%L\" gave \"%L\" a bumpmine", client, target_list[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
57
scripting/L4D2PreventBotMovement.sp
Normal file
57
scripting/L4D2PreventBotMovement.sp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#pragma semicolon 1
|
||||||
|
#pragma newdecls required
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
#define PLUGIN_NAME "L4D2 Prevent Bot Movement"
|
||||||
|
#define PLUGIN_DESCRIPTION "Prevents bots from moving in the beginning of the round for a set period of time."
|
||||||
|
#define PLUGIN_AUTHOR "jackzmc"
|
||||||
|
#define PLUGIN_VERSION "1.0"
|
||||||
|
#define PLUGIN_URL ""
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
//#include <sdkhooks>
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = PLUGIN_NAME,
|
||||||
|
author = PLUGIN_AUTHOR,
|
||||||
|
description = PLUGIN_DESCRIPTION,
|
||||||
|
version = PLUGIN_VERSION,
|
||||||
|
url = PLUGIN_URL
|
||||||
|
};
|
||||||
|
|
||||||
|
static ConVar hSBStop, hStopTime;
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
EngineVersion g_Game = GetEngineVersion();
|
||||||
|
if(g_Game != Engine_Left4Dead && g_Game != Engine_Left4Dead2)
|
||||||
|
{
|
||||||
|
SetFailState("This plugin is for L4D/L4D2 only.");
|
||||||
|
}
|
||||||
|
HookEvent("round_start",Event_RoundStart);
|
||||||
|
|
||||||
|
hStopTime = CreateConVar("sm_freeze_bot_time","20.0","How long should the bots be frozen for on beginning of round? 0 to disable",FCVAR_NONE,true,0.0);
|
||||||
|
hSBStop = FindConVar("sb_stop");
|
||||||
|
}
|
||||||
|
public void OnMapStart() {
|
||||||
|
if(hStopTime.IntValue != 0) {
|
||||||
|
PrintToChatAll("round start");
|
||||||
|
hSBStop.BoolValue = true;
|
||||||
|
CreateTimer(hStopTime.FloatValue, ResumeBots);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
|
||||||
|
if(hStopTime.IntValue != 0) {
|
||||||
|
PrintToChatAll("round start");
|
||||||
|
hSBStop.BoolValue = true;
|
||||||
|
CreateTimer(hStopTime.FloatValue, ResumeBots);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Action ResumeBots(Handle timer) {
|
||||||
|
PrintToChatAll("Resuming bots");
|
||||||
|
hSBStop.BoolValue = false;
|
||||||
|
}
|
60
scripting/csgo-misc.sp
Normal file
60
scripting/csgo-misc.sp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#pragma semicolon 1
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
|
#define PLUGIN_AUTHOR ""
|
||||||
|
#define PLUGIN_VERSION "0.00"
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <cstrike>
|
||||||
|
//#include <sdkhooks>
|
||||||
|
|
||||||
|
#pragma newdecls required
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "",
|
||||||
|
author = PLUGIN_AUTHOR,
|
||||||
|
description = "",
|
||||||
|
version = PLUGIN_VERSION,
|
||||||
|
url = ""
|
||||||
|
};
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
EngineVersion g_Game = GetEngineVersion();
|
||||||
|
if(g_Game != Engine_CSGO && g_Game != Engine_CSS)
|
||||||
|
{
|
||||||
|
SetFailState("This plugin is for CSGO/CSS only.");
|
||||||
|
}
|
||||||
|
RegConsoleCmd("sm_first", Command_FirstPov, "Go back to first person");
|
||||||
|
RegConsoleCmd("sm_third", Command_ThirdPov, "Go to third person");
|
||||||
|
}
|
||||||
|
public Action Command_FirstPov(int client, int args) {
|
||||||
|
if(client == 0) {
|
||||||
|
ReplyToCommand(client, "This command is for clients only");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
CheatCommand(client, "firstperson", "", "");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
public Action Command_ThirdPov(int client, int args) {
|
||||||
|
if(client == 0) {
|
||||||
|
ReplyToCommand(client, "This command is for clients only");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
CheatCommand(client, "thirdperson", "", "");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
stock void CheatCommand(int client, char[] command, char[] argument1, char[] argument2)
|
||||||
|
{
|
||||||
|
int userFlags = GetUserFlagBits(client);
|
||||||
|
SetUserFlagBits(client, ADMFLAG_ROOT);
|
||||||
|
int flags = GetCommandFlags(command);
|
||||||
|
SetCommandFlags(command, flags & ~FCVAR_CHEAT);
|
||||||
|
FakeClientCommand(client, "%s %s %s", command, argument1, argument2);
|
||||||
|
SetCommandFlags(command, flags);
|
||||||
|
SetUserFlagBits(client, userFlags);
|
||||||
|
}
|
233
scripting/l4d2_drop_secondary.sp
Normal file
233
scripting/l4d2_drop_secondary.sp
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
#pragma semicolon 1
|
||||||
|
#pragma newdecls required //強制1.7以後的新語法
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
|
||||||
|
#define MODEL_V_FIREAXE "models/weapons/melee/v_fireaxe.mdl"
|
||||||
|
#define MODEL_V_FRYING_PAN "models/weapons/melee/v_frying_pan.mdl"
|
||||||
|
#define MODEL_V_MACHETE "models/weapons/melee/v_machete.mdl"
|
||||||
|
#define MODEL_V_BASEBALL_BAT "models/weapons/melee/v_bat.mdl"
|
||||||
|
#define MODEL_V_CROWBAR "models/weapons/melee/v_crowbar.mdl"
|
||||||
|
#define MODEL_V_CRICKET_BAT "models/weapons/melee/v_cricket_bat.mdl"
|
||||||
|
#define MODEL_V_TONFA "models/weapons/melee/v_tonfa.mdl"
|
||||||
|
#define MODEL_V_KATANA "models/weapons/melee/v_katana.mdl"
|
||||||
|
#define MODEL_V_ELECTRIC_GUITAR "models/weapons/melee/v_electric_guitar.mdl"
|
||||||
|
#define MODEL_V_GOLFCLUB "models/weapons/melee/v_golfclub.mdl"
|
||||||
|
#define MODEL_V_SHIELD "models/weapons/melee/v_riotshield.mdl"
|
||||||
|
#define MODEL_V_KNIFE "models/v_models/v_knife_t.mdl"
|
||||||
|
#define MODEL_V_SHOVEL "models/weapons/melee/v_shovel.mdl"
|
||||||
|
#define MODEL_V_PITCHFORK "models/weapons/melee/v_pitchfork.mdl"
|
||||||
|
|
||||||
|
static g_PlayerSecondaryWeapons[MAXPLAYERS + 1];
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "L4D2 Drop Secondary",
|
||||||
|
author = "Jahze, Visor, NoBody & HarryPotter",
|
||||||
|
version = "1.8",
|
||||||
|
description = "Survivor players will drop their secondary weapon when they die",
|
||||||
|
url = "https://github.com/Attano/Equilibrium"
|
||||||
|
};
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy);
|
||||||
|
HookEvent("player_use", OnPlayerUse, EventHookMode_Post);
|
||||||
|
HookEvent("player_bot_replace", player_bot_replace);
|
||||||
|
HookEvent("bot_player_replace", bot_player_replace);
|
||||||
|
HookEvent("player_death", OnPlayerDeath, EventHookMode_Pre);
|
||||||
|
HookEvent("weapon_drop", OnWeaponDrop);
|
||||||
|
HookEvent("item_pickup", OnItemPickUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnRoundStart(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
g_PlayerSecondaryWeapons[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnPlayerUse(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
|
|
||||||
|
if(client == 0 || !IsClientInGame(client) || GetClientTeam(client) != 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int weapon = GetPlayerWeaponSlot(client, 1);
|
||||||
|
|
||||||
|
g_PlayerSecondaryWeapons[client] = (weapon == -1 ? weapon : EntIndexToEntRef(weapon));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action bot_player_replace(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
int bot = GetClientOfUserId(event.GetInt("bot"));
|
||||||
|
int client = GetClientOfUserId(event.GetInt("player"));
|
||||||
|
|
||||||
|
g_PlayerSecondaryWeapons[client] = g_PlayerSecondaryWeapons[bot];
|
||||||
|
g_PlayerSecondaryWeapons[bot] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action player_bot_replace(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
int client = GetClientOfUserId(event.GetInt("player"));
|
||||||
|
int bot = GetClientOfUserId(event.GetInt("bot"));
|
||||||
|
|
||||||
|
g_PlayerSecondaryWeapons[bot] = g_PlayerSecondaryWeapons[client];
|
||||||
|
g_PlayerSecondaryWeapons[client] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnItemPickUp(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
|
if(client == 0 || !IsClientInGame(client) || GetClientTeam(client) != 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int weapon = GetPlayerWeaponSlot(client, 1);
|
||||||
|
|
||||||
|
g_PlayerSecondaryWeapons[client] = (weapon == -1 ? weapon : EntIndexToEntRef(weapon));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnWeaponDrop(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
CreateTimer(0.1, ColdDown, event.GetInt("userid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action ColdDown(Handle timer, int client)
|
||||||
|
{
|
||||||
|
client = GetClientOfUserId(client);
|
||||||
|
if(client && IsClientInGame(client) && GetClientTeam(client) == 2)
|
||||||
|
{
|
||||||
|
int weapon = GetPlayerWeaponSlot(client, 1);
|
||||||
|
|
||||||
|
g_PlayerSecondaryWeapons[client] = (weapon == -1 ? weapon : EntIndexToEntRef(weapon));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnPlayerDeath(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
|
|
||||||
|
if(client == 0 || !IsClientInGame(client) || GetClientTeam(client) != 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int weapon = EntRefToEntIndex(g_PlayerSecondaryWeapons[client]);
|
||||||
|
|
||||||
|
if(weapon == INVALID_ENT_REFERENCE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char sWeapon[32];
|
||||||
|
int clip;
|
||||||
|
GetEdictClassname(weapon, sWeapon, 32);
|
||||||
|
|
||||||
|
int index = CreateEntityByName(sWeapon);
|
||||||
|
float origin[3];
|
||||||
|
float ang[3];
|
||||||
|
if (strcmp(sWeapon, "weapon_melee") == 0)
|
||||||
|
{
|
||||||
|
char melee[150];
|
||||||
|
GetEntPropString(weapon , Prop_Data, "m_ModelName", melee, sizeof(melee));
|
||||||
|
if (strcmp(melee, MODEL_V_FIREAXE) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "fireaxe");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_FRYING_PAN) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "frying_pan");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_MACHETE) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "machete");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_BASEBALL_BAT) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "baseball_bat");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_CROWBAR) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "crowbar");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_CRICKET_BAT) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "cricket_bat");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_TONFA) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "tonfa");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_KATANA) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "katana");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_ELECTRIC_GUITAR) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "electric_guitar");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_GOLFCLUB) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "golfclub");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_SHIELD) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "riotshield");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_KNIFE) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "knife");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_SHOVEL) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "shovel");
|
||||||
|
}
|
||||||
|
else if (strcmp(melee, MODEL_V_PITCHFORK) == 0)
|
||||||
|
{
|
||||||
|
DispatchKeyValue(index, "melee_script_name", "pitchfork");
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
else if (strcmp(sWeapon, "weapon_chainsaw") == 0)
|
||||||
|
{
|
||||||
|
clip = GetEntProp(weapon, Prop_Send, "m_iClip1");
|
||||||
|
}
|
||||||
|
else if (strcmp(sWeapon, "weapon_pistol") == 0 && (GetEntProp(weapon, Prop_Send, "m_isDualWielding") > 0))
|
||||||
|
{
|
||||||
|
int indexC = CreateEntityByName(sWeapon);
|
||||||
|
GetClientEyePosition(client,origin);
|
||||||
|
GetClientEyeAngles(client, ang);
|
||||||
|
GetAngleVectors(ang, ang, NULL_VECTOR,NULL_VECTOR);
|
||||||
|
NormalizeVector(ang,ang);
|
||||||
|
ScaleVector(ang, 90.0);
|
||||||
|
|
||||||
|
DispatchSpawn(indexC);
|
||||||
|
TeleportEntity(indexC, origin, NULL_VECTOR, ang);
|
||||||
|
}
|
||||||
|
else if (strcmp(sWeapon, "weapon_pistol_magnum") == 0)
|
||||||
|
{
|
||||||
|
clip = GetEntProp(weapon, Prop_Send, "m_iClip1");
|
||||||
|
}
|
||||||
|
|
||||||
|
RemovePlayerItem(client, weapon);
|
||||||
|
RemoveEntity(weapon);
|
||||||
|
|
||||||
|
GetClientEyePosition(client,origin);
|
||||||
|
GetClientEyeAngles(client, ang);
|
||||||
|
GetAngleVectors(ang, ang, NULL_VECTOR,NULL_VECTOR);
|
||||||
|
NormalizeVector(ang,ang);
|
||||||
|
ScaleVector(ang, 90.0);
|
||||||
|
|
||||||
|
DispatchSpawn(index);
|
||||||
|
TeleportEntity(index, origin, NULL_VECTOR, ang);
|
||||||
|
|
||||||
|
if (strcmp(sWeapon, "weapon_chainsaw") == 0 || strcmp(sWeapon, "weapon_pistol") == 0 || strcmp(sWeapon, "weapon_pistol_magnum") == 0)
|
||||||
|
{
|
||||||
|
SetEntProp(index, Prop_Send, "m_iClip1", clip);
|
||||||
|
}
|
||||||
|
}
|
3125
scripting/l4d2_skill_detect.sp
Normal file
3125
scripting/l4d2_skill_detect.sp
Normal file
File diff suppressed because it is too large
Load diff
136
scripting/l4d2_target_test.sp
Normal file
136
scripting/l4d2_target_test.sp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
#pragma semicolon 1
|
||||||
|
#pragma newdecls required
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
#define PLUGIN_VERSION "1.0"
|
||||||
|
#define GAMEDATA "l4d_target_override"
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <left4dhooks>
|
||||||
|
|
||||||
|
enum L4D2Infected
|
||||||
|
{
|
||||||
|
L4D2Infected_None = 0,
|
||||||
|
L4D2Infected_Smoker = 1,
|
||||||
|
L4D2Infected_Boomer = 2,
|
||||||
|
L4D2Infected_Hunter = 3,
|
||||||
|
L4D2Infected_Spitter = 4,
|
||||||
|
L4D2Infected_Jockey = 5,
|
||||||
|
L4D2Infected_Charger = 6,
|
||||||
|
L4D2Infected_Witch = 7,
|
||||||
|
L4D2Infected_Tank = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "L4D2 target poo",
|
||||||
|
author = "jackzmc",
|
||||||
|
description = "",
|
||||||
|
version = PLUGIN_VERSION,
|
||||||
|
url = ""
|
||||||
|
};
|
||||||
|
|
||||||
|
bool g_bIsVictim[MAXPLAYERS+1];
|
||||||
|
Handle g_hDetour;
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
EngineVersion g_Game = GetEngineVersion();
|
||||||
|
if(g_Game != Engine_Left4Dead2)
|
||||||
|
{
|
||||||
|
SetFailState("This plugin is for L4D2 only.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RegAdminCmd("sm_set_victim", Cmd_SetVictim, ADMFLAG_CHEATS);
|
||||||
|
|
||||||
|
HookEvent("player_death", Event_PlayerDeath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnPluginEnd()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Cmd_SetVictim(int client, int args) {
|
||||||
|
if(args == 0) {
|
||||||
|
ReplyToCommand(client, "Please enter a player to target");
|
||||||
|
}else{
|
||||||
|
char arg1[32];
|
||||||
|
GetCmdArg(1, arg1, sizeof(arg1));
|
||||||
|
|
||||||
|
char target_name[MAX_TARGET_LENGTH];
|
||||||
|
int target_list[1], target_count;
|
||||||
|
bool tn_is_ml;
|
||||||
|
|
||||||
|
if ((target_count = ProcessTargetString(
|
||||||
|
arg1,
|
||||||
|
client,
|
||||||
|
target_list,
|
||||||
|
MAXPLAYERS,
|
||||||
|
COMMAND_FILTER_ALIVE, /* Only allow alive players */
|
||||||
|
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++) {
|
||||||
|
int victim = target_list[i];
|
||||||
|
//g_iSITargets
|
||||||
|
g_bIsVictim[victim] = !g_bIsVictim[victim];
|
||||||
|
ReplyToCommand(client, "Successfully toggled %N victim status to: %b", victim, g_bIsVictim[victim]);
|
||||||
|
ShowActivity(client, "toggled special infected victim status for %N to %b", victim, g_bIsVictim[victim]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int b_attackerTarget[MAXPLAYERS+1];
|
||||||
|
public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
||||||
|
// =========================
|
||||||
|
// OVERRIDE VICTIM
|
||||||
|
// =========================
|
||||||
|
L4D2Infected class = view_as<L4D2Infected>(GetEntProp(attacker, Prop_Send, "m_zombieClass"));
|
||||||
|
if(class != L4D2Infected_Tank) {
|
||||||
|
int existingTarget = GetClientOfUserId(b_attackerTarget[attacker]);
|
||||||
|
if(existingTarget > 0) {
|
||||||
|
curTarget = existingTarget;
|
||||||
|
return Plugin_Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
float closestDistance, survPos[3], spPos[3];
|
||||||
|
GetClientAbsOrigin(attacker, spPos);
|
||||||
|
int closestClient = -1;
|
||||||
|
for(int i = 1; i <= MaxClients; i++) {
|
||||||
|
if(g_bIsVictim[i] && IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2) {
|
||||||
|
GetClientAbsOrigin(i, survPos);
|
||||||
|
float dist = GetVectorDistance(survPos, spPos, true);
|
||||||
|
if(closestClient == -1 || dist < closestDistance) {
|
||||||
|
closestDistance = dist;
|
||||||
|
closestClient = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(closestClient > 0) {
|
||||||
|
PrintToConsoleAll("Attacker %N new target: %N", attacker, closestClient);
|
||||||
|
b_attackerTarget[attacker] = GetClientUserId(closestClient);
|
||||||
|
curTarget = closestClient;
|
||||||
|
return Plugin_Changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
|
||||||
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
|
b_attackerTarget[client] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientDisconnect(int client) {
|
||||||
|
b_attackerTarget[client] = 0;
|
||||||
|
}
|
|
@ -2,11 +2,24 @@
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
Change Log:
|
Change Log:
|
||||||
|
|
||||||
|
1.0.6 (12-February-2021)
|
||||||
|
- Fixed custom model cvar typo. (thanks "weffer" for reporting)
|
||||||
|
|
||||||
|
1.0.5 (11-February-2021)
|
||||||
|
- Fixed a bug not rendering custom sprites right after turning it on.
|
||||||
|
- Added one more custom sprite option with an alpha background filling the bar.
|
||||||
|
|
||||||
|
1.0.4 (11-February-2021)
|
||||||
|
- Added custom sprite option.
|
||||||
|
|
||||||
|
1.0.3 (08-February-2021)
|
||||||
|
- Fixed missing client in-game in visibility check. (thanks to "Krufftys Killers" and "Striker black")
|
||||||
|
|
||||||
1.0.2 (08-February-2021)
|
1.0.2 (08-February-2021)
|
||||||
- Fixed wrong value on max health calculation.
|
- Fixed wrong value on max health calculation.
|
||||||
- Fixed sprite hiding behind tank rocks.
|
- Fixed sprite hiding behind tank rocks.
|
||||||
- Fixed sprite hiding while tank throws rocks (ability use).
|
- Fixed sprite hiding while tank throws rocks (ability use).
|
||||||
- Moved visibility logic to timer.
|
- Moved visibility logic to timer handle.
|
||||||
|
|
||||||
1.0.1 (30-January-2021)
|
1.0.1 (30-January-2021)
|
||||||
- Public release.
|
- Public release.
|
||||||
|
@ -23,7 +36,7 @@ Change Log:
|
||||||
#define PLUGIN_NAME "[L4D1 & L4D2] Tank HP Sprite"
|
#define PLUGIN_NAME "[L4D1 & L4D2] Tank HP Sprite"
|
||||||
#define PLUGIN_AUTHOR "Mart"
|
#define PLUGIN_AUTHOR "Mart"
|
||||||
#define PLUGIN_DESCRIPTION "Shows a sprite at the tank head that goes from green to red based on its HP"
|
#define PLUGIN_DESCRIPTION "Shows a sprite at the tank head that goes from green to red based on its HP"
|
||||||
#define PLUGIN_VERSION "1.0.2"
|
#define PLUGIN_VERSION "1.0.5"
|
||||||
#define PLUGIN_URL "https://forums.alliedmods.net/showthread.php?t=330370"
|
#define PLUGIN_URL "https://forums.alliedmods.net/showthread.php?t=330370"
|
||||||
|
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
|
@ -66,6 +79,7 @@ public Plugin myinfo =
|
||||||
// Defines
|
// Defines
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
#define CLASSNAME_ENV_SPRITE "env_sprite"
|
#define CLASSNAME_ENV_SPRITE "env_sprite"
|
||||||
|
#define CLASSNAME_ENV_TEXTURETOGGLE "env_texturetoggle"
|
||||||
#define CLASSNAME_TANK_ROCK "tank_rock"
|
#define CLASSNAME_TANK_ROCK "tank_rock"
|
||||||
|
|
||||||
#define TEAM_SPECTATOR 1
|
#define TEAM_SPECTATOR 1
|
||||||
|
@ -102,6 +116,9 @@ static ConVar g_hCvar_DeadAlpha;
|
||||||
static ConVar g_hCvar_DeadScale;
|
static ConVar g_hCvar_DeadScale;
|
||||||
static ConVar g_hCvar_DeadColor;
|
static ConVar g_hCvar_DeadColor;
|
||||||
static ConVar g_hCvar_Team;
|
static ConVar g_hCvar_Team;
|
||||||
|
static ConVar g_hCvar_CustomModel;
|
||||||
|
static ConVar g_hCvar_CustomModelVMT;
|
||||||
|
static ConVar g_hCvar_CustomModelVTF;
|
||||||
static ConVar g_hCvar_AllSpecials;
|
static ConVar g_hCvar_AllSpecials;
|
||||||
|
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
|
@ -115,6 +132,7 @@ static bool g_bCvar_Sight;
|
||||||
static bool g_bCvar_AttackDelay;
|
static bool g_bCvar_AttackDelay;
|
||||||
static bool g_bCvar_AliveShow;
|
static bool g_bCvar_AliveShow;
|
||||||
static bool g_bCvar_DeadShow;
|
static bool g_bCvar_DeadShow;
|
||||||
|
static bool g_bCvar_CustomModel;
|
||||||
|
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
// int - Plugin Variables
|
// int - Plugin Variables
|
||||||
|
@ -147,11 +165,14 @@ static char g_sCvar_DeadAlpha[4];
|
||||||
static char g_sCvar_DeadScale[5];
|
static char g_sCvar_DeadScale[5];
|
||||||
static char g_sCvar_DeadColor[12];
|
static char g_sCvar_DeadColor[12];
|
||||||
static char g_sCvar_FadeDistance[5];
|
static char g_sCvar_FadeDistance[5];
|
||||||
|
static char g_sCvar_CustomModelVMT[100];
|
||||||
|
static char g_sCvar_CustomModelVTF[100];
|
||||||
|
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
// client - Plugin Variables
|
// client - Plugin Variables
|
||||||
// ====================================================================================================
|
// ====================================================================================================
|
||||||
static int gc_iTankSpriteRef[MAXPLAYERS+1] = { INVALID_ENT_REFERENCE, ... };
|
static int gc_iTankSpriteRef[MAXPLAYERS+1] = { INVALID_ENT_REFERENCE, ... };
|
||||||
|
static int gc_iTankSpriteFrameRef[MAXPLAYERS+1] = { INVALID_ENT_REFERENCE, ... };
|
||||||
static bool gc_bVisible[MAXPLAYERS+1][MAXPLAYERS+1];
|
static bool gc_bVisible[MAXPLAYERS+1][MAXPLAYERS+1];
|
||||||
static float gc_fLastAttack[MAXPLAYERS+1][MAXPLAYERS+1];
|
static float gc_fLastAttack[MAXPLAYERS+1][MAXPLAYERS+1];
|
||||||
|
|
||||||
|
@ -185,21 +206,24 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
{
|
{
|
||||||
CreateConVar("l4d_tank_hp_sprite_version", PLUGIN_VERSION, PLUGIN_DESCRIPTION, CVAR_FLAGS_PLUGIN_VERSION);
|
CreateConVar("l4d_tank_hp_sprite_version", PLUGIN_VERSION, PLUGIN_DESCRIPTION, CVAR_FLAGS_PLUGIN_VERSION);
|
||||||
g_hCvar_Enabled = CreateConVar("l4d_tank_hp_sprite_enable", "1", "Enable/Disable the plugin.\n0 = Disable, 1 = Enable", CVAR_FLAGS, true, 0.0, true, 1.0);
|
g_hCvar_Enabled = CreateConVar("l4d_tank_hp_sprite_enable", "1", "Enable/Disable the plugin.\n0 = Disable, 1 = Enable.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
||||||
g_hCvar_ZAxis = CreateConVar("l4d_tank_hp_sprite_z_axis", "92", "Additional Z distance based on the tank position.", CVAR_FLAGS, true, 0.0);
|
g_hCvar_ZAxis = CreateConVar("l4d_tank_hp_sprite_z_axis", "92", "Additional Z distance based on the tank position.", CVAR_FLAGS, true, 0.0);
|
||||||
g_hCvar_FadeDistance = CreateConVar("l4d_tank_hp_sprite_fade_distance", "-1", "Minimum distance that a client must be from the tank to see the sprite (both alive and dead sprites).\n-1 = Always visible.", CVAR_FLAGS, true, -1.0, true, 9999.0);
|
g_hCvar_FadeDistance = CreateConVar("l4d_tank_hp_sprite_fade_distance", "-1", "Minimum distance that a client must be from the tank to see the sprite (both alive and dead sprites).\n-1 = Always visible.", CVAR_FLAGS, true, -1.0, true, 9999.0);
|
||||||
g_hCvar_Sight = CreateConVar("l4d_tank_hp_sprite_sight", "1", "Show the sprite to the survivor only if the Tank is on sight.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
g_hCvar_Sight = CreateConVar("l4d_tank_hp_sprite_sight", "1", "Show the sprite to the survivor only if the Tank is on sight.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
||||||
g_hCvar_AttackDelay = CreateConVar("l4d_tank_hp_sprite_attack_delay", "0.0", "Show the sprite to the survivor attacker, by this amount of time in seconds, after hitting the Tank.\n0 = OFF.", CVAR_FLAGS, true, 0.0);
|
g_hCvar_AttackDelay = CreateConVar("l4d_tank_hp_sprite_attack_delay", "0.0", "Show the sprite to the survivor attacker, by this amount of time in seconds, after hitting the Tank.\n0 = OFF.", CVAR_FLAGS, true, 0.0);
|
||||||
g_hCvar_AliveShow = CreateConVar("l4d_tank_hp_sprite_alive_show", "1", "Show the alive sprite while tank is alive.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
g_hCvar_AliveShow = CreateConVar("l4d_tank_hp_sprite_alive_show", "1", "Show the alive sprite while tank is alive.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
||||||
g_hCvar_AliveModel = CreateConVar("l4d_tank_hp_sprite_alive_model", "materials/vgui/healthbar_white.vmt", "Model of alive tank sprite.");
|
g_hCvar_AliveModel = CreateConVar("l4d_tank_hp_sprite_alive_model", "materials/vgui/healthbar_white.vmt", "Model of alive tank sprite.");
|
||||||
g_hCvar_AliveAlpha = CreateConVar("l4d_tank_hp_sprite_alive_alpha", "200", "Alpha of alive tank sprite.\n0 = Invisible, 255 = Fully Visible", CVAR_FLAGS, true, 0.0, true, 255.0);
|
g_hCvar_AliveAlpha = CreateConVar("l4d_tank_hp_sprite_alive_alpha", "200", "Alpha of alive tank sprite.\n0 = Invisible, 255 = Fully Visible", CVAR_FLAGS, true, 0.0, true, 255.0);
|
||||||
g_hCvar_AliveScale = CreateConVar("l4d_tank_hp_sprite_alive_scale", "0.25", "Scale of alive tank sprite (increases both height and width).\nNote: Some range values maintain the same size. (e.g. from 0.0 to 0.38 the size doesn't change).", CVAR_FLAGS, true, 0.0);
|
g_hCvar_AliveScale = CreateConVar("l4d_tank_hp_sprite_alive_scale", "0.25", "Scale of alive tank sprite (increases both height and width).\nNote: Some range values maintain the same size. (e.g. from 0.0 to 0.38 the size doesn't change).", CVAR_FLAGS, true, 0.0);
|
||||||
g_hCvar_DeadShow = CreateConVar("l4d_tank_hp_sprite_dead_show", "1", "Show the dead sprite when a tank dies.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
g_hCvar_DeadShow = CreateConVar("l4d_tank_hp_sprite_dead_show", "1", "Show the dead sprite when a tank dies.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
||||||
g_hCvar_DeadModel = CreateConVar("l4d_tank_hp_sprite_dead_model", "materials/sprites/death_icon.vmt", "Model of dead tank sprite.");
|
g_hCvar_DeadModel = CreateConVar("l4d_tank_hp_sprite_dead_model", "materials/sprites/death_icon.vmt", "Model of dead tank sprite.");
|
||||||
g_hCvar_DeadAlpha = CreateConVar("l4d_tank_hp_sprite_dead_alpha", "200", "Alpha of dead tank sprite.\n0 = Invisible, 255 = Fully Visible", CVAR_FLAGS, true, 0.0, true, 255.0);
|
g_hCvar_DeadAlpha = CreateConVar("l4d_tank_hp_sprite_dead_alpha", "200", "Alpha of dead tank sprite.\n0 = Invisible, 255 = Fully Visible", CVAR_FLAGS, true, 0.0, true, 255.0);
|
||||||
g_hCvar_DeadScale = CreateConVar("l4d_tank_hp_sprite_dead_scale", "0.25", "Scale of dead tank sprite (increases both height and width).\nSome range values maintain the size the same.", CVAR_FLAGS, true, 0.0);
|
g_hCvar_DeadScale = CreateConVar("l4d_tank_hp_sprite_dead_scale", "0.25", "Scale of dead tank sprite (increases both height and width).\nSome range values maintain the size the same.", CVAR_FLAGS, true, 0.0);
|
||||||
g_hCvar_DeadColor = CreateConVar("l4d_tank_hp_sprite_dead_color", "225 0 0", "Color of dead tank sprite.\nUse three values between 0-255 separated by spaces (\"<0-255> <0-255> <0-255>\").", CVAR_FLAGS);
|
g_hCvar_DeadColor = CreateConVar("l4d_tank_hp_sprite_dead_color", "225 0 0", "Color of dead tank sprite.\nUse three values between 0-255 separated by spaces (\"<0-255> <0-255> <0-255>\").", CVAR_FLAGS);
|
||||||
g_hCvar_Team = CreateConVar("l4d_tank_hp_sprite_team", "3", "Which teams should the sprite be visible.\n0 = NONE, 1 = SURVIVOR, 2 = INFECTED, 4 = SPECTATOR, 8 = HOLDOUT.\nAdd numbers greater than 0 for multiple options.\nExample: \"3\", enables for SURVIVOR and INFECTED.", CVAR_FLAGS, true, 0.0, true, 15.0);
|
g_hCvar_Team = CreateConVar("l4d_tank_hp_sprite_team", "3", "Which teams should the sprite be visible.\n0 = NONE, 1 = SURVIVOR, 2 = INFECTED, 4 = SPECTATOR, 8 = HOLDOUT.\nAdd numbers greater than 0 for multiple options.\nExample: \"3\", enables for SURVIVOR and INFECTED.", CVAR_FLAGS, true, 0.0, true, 15.0);
|
||||||
|
g_hCvar_CustomModel = CreateConVar("l4d_tank_hp_sprite_custom_model", "0", "Use a custom sprite for the alive model\nNote: This requires the client downloading the custom model (.vmt and .vtf) to work.\nSearch for FastDL for more info.\n0 = OFF, 1 = ON.", CVAR_FLAGS, true, 0.0, true, 1.0);
|
||||||
|
g_hCvar_CustomModelVMT = CreateConVar("l4d_tank_hp_sprite_custom_model_vmt", "materials/mart/mart_custombar.vmt", "Custom sprite VMT path.");
|
||||||
|
g_hCvar_CustomModelVTF = CreateConVar("l4d_tank_hp_sprite_custom_model_vtf", "materials/mart/mart_custombar.vtf", "Custom sprite VTF path.");
|
||||||
g_hCvar_AllSpecials = CreateConVar("l4d_tank_hp_sprite_all_specials", "1", "Should all specials have healthbar or only tanks\n0 = Tanks Only, 1 = All Specials", CVAR_FLAGS, true, 0.0, true, 1.0);
|
g_hCvar_AllSpecials = CreateConVar("l4d_tank_hp_sprite_all_specials", "1", "Should all specials have healthbar or only tanks\n0 = Tanks Only, 1 = All Specials", CVAR_FLAGS, true, 0.0, true, 1.0);
|
||||||
|
|
||||||
g_hCvar_Enabled.AddChangeHook(Event_ConVarChanged);
|
g_hCvar_Enabled.AddChangeHook(Event_ConVarChanged);
|
||||||
|
@ -217,6 +241,9 @@ public void OnPluginStart()
|
||||||
g_hCvar_DeadScale.AddChangeHook(Event_ConVarChanged);
|
g_hCvar_DeadScale.AddChangeHook(Event_ConVarChanged);
|
||||||
g_hCvar_DeadColor.AddChangeHook(Event_ConVarChanged);
|
g_hCvar_DeadColor.AddChangeHook(Event_ConVarChanged);
|
||||||
g_hCvar_Team.AddChangeHook(Event_ConVarChanged);
|
g_hCvar_Team.AddChangeHook(Event_ConVarChanged);
|
||||||
|
g_hCvar_CustomModel.AddChangeHook(Event_ConVarChanged);
|
||||||
|
g_hCvar_CustomModelVMT.AddChangeHook(Event_ConVarChanged);
|
||||||
|
g_hCvar_CustomModelVTF.AddChangeHook(Event_ConVarChanged);
|
||||||
|
|
||||||
// Load plugin configs from .cfg
|
// Load plugin configs from .cfg
|
||||||
AutoExecConfig(true, CONFIG_FILENAME);
|
AutoExecConfig(true, CONFIG_FILENAME);
|
||||||
|
@ -234,7 +261,7 @@ public void OnPluginStart()
|
||||||
public void OnPluginEnd()
|
public void OnPluginEnd()
|
||||||
{
|
{
|
||||||
int entity;
|
int entity;
|
||||||
char targetname[64];
|
char targetname[19];
|
||||||
|
|
||||||
entity = INVALID_ENT_REFERENCE;
|
entity = INVALID_ENT_REFERENCE;
|
||||||
while ((entity = FindEntityByClassname(entity, CLASSNAME_ENV_SPRITE)) != INVALID_ENT_REFERENCE)
|
while ((entity = FindEntityByClassname(entity, CLASSNAME_ENV_SPRITE)) != INVALID_ENT_REFERENCE)
|
||||||
|
@ -285,7 +312,6 @@ public void GetCvars()
|
||||||
g_bCvar_AliveShow = g_hCvar_AliveShow.BoolValue;
|
g_bCvar_AliveShow = g_hCvar_AliveShow.BoolValue;
|
||||||
g_hCvar_AliveModel.GetString(g_sCvar_AliveModel, sizeof(g_sCvar_AliveModel));
|
g_hCvar_AliveModel.GetString(g_sCvar_AliveModel, sizeof(g_sCvar_AliveModel));
|
||||||
TrimString(g_sCvar_AliveModel);
|
TrimString(g_sCvar_AliveModel);
|
||||||
PrecacheModel(g_sCvar_AliveModel, true);
|
|
||||||
g_iCvar_AliveAlpha = g_hCvar_AliveAlpha.IntValue;
|
g_iCvar_AliveAlpha = g_hCvar_AliveAlpha.IntValue;
|
||||||
FormatEx(g_sCvar_AliveAlpha, sizeof(g_sCvar_AliveAlpha), "%i", g_iCvar_AliveAlpha);
|
FormatEx(g_sCvar_AliveAlpha, sizeof(g_sCvar_AliveAlpha), "%i", g_iCvar_AliveAlpha);
|
||||||
g_fCvar_AliveScale = g_hCvar_AliveScale.FloatValue;
|
g_fCvar_AliveScale = g_hCvar_AliveScale.FloatValue;
|
||||||
|
@ -293,7 +319,6 @@ public void GetCvars()
|
||||||
g_bCvar_DeadShow = g_hCvar_DeadShow.BoolValue;
|
g_bCvar_DeadShow = g_hCvar_DeadShow.BoolValue;
|
||||||
g_hCvar_DeadModel.GetString(g_sCvar_DeadModel, sizeof(g_sCvar_DeadModel));
|
g_hCvar_DeadModel.GetString(g_sCvar_DeadModel, sizeof(g_sCvar_DeadModel));
|
||||||
TrimString(g_sCvar_DeadModel);
|
TrimString(g_sCvar_DeadModel);
|
||||||
PrecacheModel(g_sCvar_DeadModel, true);
|
|
||||||
g_iCvar_DeadAlpha = g_hCvar_DeadAlpha.IntValue;
|
g_iCvar_DeadAlpha = g_hCvar_DeadAlpha.IntValue;
|
||||||
FormatEx(g_sCvar_DeadAlpha, sizeof(g_sCvar_DeadAlpha), "%i", g_iCvar_DeadAlpha);
|
FormatEx(g_sCvar_DeadAlpha, sizeof(g_sCvar_DeadAlpha), "%i", g_iCvar_DeadAlpha);
|
||||||
g_fCvar_DeadScale = g_hCvar_DeadScale.FloatValue;
|
g_fCvar_DeadScale = g_hCvar_DeadScale.FloatValue;
|
||||||
|
@ -301,6 +326,28 @@ public void GetCvars()
|
||||||
g_hCvar_DeadColor.GetString(g_sCvar_DeadColor, sizeof(g_sCvar_DeadColor));
|
g_hCvar_DeadColor.GetString(g_sCvar_DeadColor, sizeof(g_sCvar_DeadColor));
|
||||||
TrimString(g_sCvar_DeadColor);
|
TrimString(g_sCvar_DeadColor);
|
||||||
g_iCvar_Team = g_hCvar_Team.IntValue;
|
g_iCvar_Team = g_hCvar_Team.IntValue;
|
||||||
|
g_bCvar_CustomModel = g_hCvar_CustomModel.BoolValue;
|
||||||
|
g_hCvar_CustomModelVMT.GetString(g_sCvar_CustomModelVMT, sizeof(g_sCvar_CustomModelVMT));
|
||||||
|
TrimString(g_sCvar_CustomModelVMT);
|
||||||
|
g_hCvar_CustomModelVTF.GetString(g_sCvar_CustomModelVTF, sizeof(g_sCvar_CustomModelVTF));
|
||||||
|
TrimString(g_sCvar_CustomModelVTF);
|
||||||
|
|
||||||
|
if (g_bCvar_AliveShow)
|
||||||
|
{
|
||||||
|
if (g_bCvar_CustomModel)
|
||||||
|
{
|
||||||
|
AddFileToDownloadsTable(g_sCvar_CustomModelVMT);
|
||||||
|
AddFileToDownloadsTable(g_sCvar_CustomModelVTF);
|
||||||
|
PrecacheModel(g_sCvar_CustomModelVMT, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrecacheModel(g_sCvar_AliveModel, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_bCvar_DeadShow)
|
||||||
|
PrecacheModel(g_sCvar_DeadModel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************************/
|
/****************************************************************************************************/
|
||||||
|
@ -309,8 +356,10 @@ public void LateLoad()
|
||||||
{
|
{
|
||||||
for (int client = 1; client <= MaxClients; client++)
|
for (int client = 1; client <= MaxClients; client++)
|
||||||
{
|
{
|
||||||
if (IsPlayerSpecialInfected(client))
|
if (!IsPlayerTank(client))
|
||||||
TankSprite(client);
|
continue;
|
||||||
|
|
||||||
|
TankSprite(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +371,7 @@ public void OnClientDisconnect(int client)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gc_iTankSpriteRef[client] = INVALID_ENT_REFERENCE;
|
gc_iTankSpriteRef[client] = INVALID_ENT_REFERENCE;
|
||||||
|
gc_iTankSpriteFrameRef[client] = INVALID_ENT_REFERENCE;
|
||||||
|
|
||||||
for (int target = 1; target <= MaxClients; target++)
|
for (int target = 1; target <= MaxClients; target++)
|
||||||
{
|
{
|
||||||
|
@ -372,6 +422,7 @@ public void HookEvents(bool hook)
|
||||||
{
|
{
|
||||||
g_bEventsHooked = true;
|
g_bEventsHooked = true;
|
||||||
|
|
||||||
|
HookEvent("tank_spawn", Event_TankSpawn);
|
||||||
HookEvent("player_hurt", Event_PlayerHurt);
|
HookEvent("player_hurt", Event_PlayerHurt);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -381,6 +432,7 @@ public void HookEvents(bool hook)
|
||||||
{
|
{
|
||||||
g_bEventsHooked = false;
|
g_bEventsHooked = false;
|
||||||
|
|
||||||
|
UnhookEvent("tank_spawn", Event_TankSpawn);
|
||||||
UnhookEvent("player_hurt", Event_PlayerHurt);
|
UnhookEvent("player_hurt", Event_PlayerHurt);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -389,27 +441,37 @@ public void HookEvents(bool hook)
|
||||||
|
|
||||||
/****************************************************************************************************/
|
/****************************************************************************************************/
|
||||||
|
|
||||||
|
public void Event_TankSpawn(Event event, const char[] name, bool dontBroadcast)
|
||||||
|
{
|
||||||
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
|
|
||||||
public void OnClientPutInServer(int client) {
|
if (!IsValidClient(client))
|
||||||
if(GetClientTeam(client) == TEAM_INFECTED) {
|
return;
|
||||||
//If all specials turned off and not tank; ignore.
|
|
||||||
if(!g_hCvar_AllSpecials.BoolValue && GetZombieClass(client) != g_iTankClass) return;
|
TankSprite(client);
|
||||||
TankSprite(client);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************************/
|
/****************************************************************************************************/
|
||||||
|
|
||||||
public void Event_PlayerHurt(Event event, const char[] name, bool dontBroadcast) {
|
public void Event_PlayerHurt(Event event, const char[] name, bool dontBroadcast)
|
||||||
int tank = GetClientOfUserId(event.GetInt("userid"));
|
{
|
||||||
if (IsPlayerSpecialInfected(tank)) {
|
if (!g_bCvar_AttackDelay)
|
||||||
TankSprite(tank);
|
return;
|
||||||
if(g_bCvar_AttackDelay) {
|
|
||||||
int attacker = GetClientOfUserId(event.GetInt("attacker"));
|
int target = GetClientOfUserId(event.GetInt("userid"));
|
||||||
if (IsValidClient(attacker) && GetClientTeam(attacker) != TEAM_SURVIVOR)
|
|
||||||
gc_fLastAttack[tank][attacker] = GetGameTime();
|
if (!IsPlayerTank(target))
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
|
int attacker = GetClientOfUserId(event.GetInt("attacker"));
|
||||||
|
|
||||||
|
if (!IsValidClient(attacker))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GetClientTeam(attacker) != TEAM_SURVIVOR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gc_fLastAttack[target][attacker] = GetGameTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************************/
|
/****************************************************************************************************/
|
||||||
|
@ -419,21 +481,26 @@ public Action TimerKill(Handle timer)
|
||||||
if (!g_bConfigLoaded)
|
if (!g_bConfigLoaded)
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
|
|
||||||
for (int client = 1; client <= MaxClients; client++)
|
for (int target = 1; target <= MaxClients; target++)
|
||||||
{
|
{
|
||||||
if (gc_iTankSpriteRef[client] != INVALID_ENT_REFERENCE && !IsPlayerSpecialInfected(client)) {
|
if (gc_iTankSpriteRef[target] == INVALID_ENT_REFERENCE)
|
||||||
int entity = EntRefToEntIndex(gc_iTankSpriteRef[client]);
|
continue;
|
||||||
|
|
||||||
if (entity != INVALID_ENT_REFERENCE)
|
if (g_bCvar_Enabled && IsPlayerTank(target))
|
||||||
AcceptEntityInput(entity, "Kill");
|
continue;
|
||||||
|
|
||||||
gc_iTankSpriteRef[client] = INVALID_ENT_REFERENCE;
|
int entity = EntRefToEntIndex(gc_iTankSpriteRef[target]);
|
||||||
|
|
||||||
for (int client2 = 1; client2 <= MaxClients; client2++)
|
if (entity != INVALID_ENT_REFERENCE)
|
||||||
{
|
AcceptEntityInput(entity, "Kill");
|
||||||
gc_bVisible[client][client2] = false;
|
|
||||||
gc_fLastAttack[client][client2] = 0.0;
|
gc_iTankSpriteRef[target] = INVALID_ENT_REFERENCE;
|
||||||
}
|
gc_iTankSpriteFrameRef[target] = INVALID_ENT_REFERENCE;
|
||||||
|
|
||||||
|
for (int client = 1; client <= MaxClients; client++)
|
||||||
|
{
|
||||||
|
gc_bVisible[target][client] = false;
|
||||||
|
gc_fLastAttack[target][client] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,38 +522,31 @@ public Action TimerVisible(Handle timer)
|
||||||
if (gc_iTankSpriteRef[target] == INVALID_ENT_REFERENCE)
|
if (gc_iTankSpriteRef[target] == INVALID_ENT_REFERENCE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!IsClientConnected(target))
|
if (!IsClientInGame(target))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int client = 1; client <= MaxClients; client++)
|
for (int client = 1; client <= MaxClients; client++)
|
||||||
{
|
{
|
||||||
if (!IsClientConnected(client))
|
gc_bVisible[target][client] = false;
|
||||||
|
|
||||||
|
if (!IsClientInGame(client))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (IsFakeClient(client))
|
if (IsFakeClient(client))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(GetClientTeamFlag(client) & g_iCvar_Team))
|
if (!(GetTeamFlag(GetClientTeam(client)) & g_iCvar_Team))
|
||||||
{
|
|
||||||
gc_bVisible[target][client] = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (g_bCvar_AttackDelay || g_bCvar_Sight)
|
if (g_bCvar_AttackDelay || g_bCvar_Sight)
|
||||||
{
|
{
|
||||||
if (GetClientTeam(client) == TEAM_SURVIVOR || GetClientTeam(client) == TEAM_HOLDOUT)
|
if (GetClientTeam(client) == TEAM_SURVIVOR || GetClientTeam(client) == TEAM_HOLDOUT)
|
||||||
{
|
{
|
||||||
if (g_bCvar_AttackDelay && (GetGameTime() - gc_fLastAttack[target][client] > g_fCvar_AttackDelay))
|
if (g_bCvar_AttackDelay && (GetGameTime() - gc_fLastAttack[target][client] > g_fCvar_AttackDelay))
|
||||||
{
|
|
||||||
gc_bVisible[target][client] = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (g_bCvar_Sight && !IsVisibleTo(client, target))
|
if (g_bCvar_Sight && !IsVisibleTo(client, target))
|
||||||
{
|
|
||||||
gc_bVisible[target][client] = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +569,7 @@ public Action TimerRender(Handle timer)
|
||||||
|
|
||||||
for (int target = 1; target <= MaxClients; target++)
|
for (int target = 1; target <= MaxClients; target++)
|
||||||
{
|
{
|
||||||
if (!IsPlayerSpecialInfected(target))
|
if (!IsPlayerTank(target))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TankSprite(target);
|
TankSprite(target);
|
||||||
|
@ -529,14 +589,43 @@ public void TankSprite(int client)
|
||||||
|
|
||||||
if (entity == INVALID_ENT_REFERENCE)
|
if (entity == INVALID_ENT_REFERENCE)
|
||||||
{
|
{
|
||||||
|
char targetname[22];
|
||||||
|
FormatEx(targetname, sizeof(targetname), "%s-%i", "l4d_tank_hp_sprite", client);
|
||||||
|
|
||||||
entity = CreateEntityByName(CLASSNAME_ENV_SPRITE);
|
entity = CreateEntityByName(CLASSNAME_ENV_SPRITE);
|
||||||
DispatchKeyValue(entity, "targetname", "l4d_tank_hp_sprite");
|
ge_iOwner[entity] = client;
|
||||||
|
gc_iTankSpriteRef[client] = EntIndexToEntRef(entity);
|
||||||
|
DispatchKeyValue(entity, "targetname", targetname);
|
||||||
DispatchKeyValue(entity, "spawnflags", "1");
|
DispatchKeyValue(entity, "spawnflags", "1");
|
||||||
DispatchKeyValue(entity, "fademindist", g_sCvar_FadeDistance);
|
DispatchKeyValue(entity, "fademindist", g_sCvar_FadeDistance);
|
||||||
SetEntProp(entity, Prop_Data, "m_iHammerID", -1);
|
SetEntProp(entity, Prop_Data, "m_iHammerID", -1);
|
||||||
SDKHook(entity, SDKHook_SetTransmit, OnSetTransmit);
|
SDKHook(entity, SDKHook_SetTransmit, OnSetTransmit);
|
||||||
ge_iOwner[entity] = client;
|
}
|
||||||
gc_iTankSpriteRef[client] = EntIndexToEntRef(entity);
|
|
||||||
|
if (g_bCvar_CustomModel)
|
||||||
|
{
|
||||||
|
int entityFrame = INVALID_ENT_REFERENCE;
|
||||||
|
|
||||||
|
if (gc_iTankSpriteFrameRef[client] != INVALID_ENT_REFERENCE)
|
||||||
|
entityFrame = EntRefToEntIndex(gc_iTankSpriteFrameRef[client]);
|
||||||
|
|
||||||
|
if (entityFrame == INVALID_ENT_REFERENCE)
|
||||||
|
{
|
||||||
|
char targetname[22];
|
||||||
|
FormatEx(targetname, sizeof(targetname), "%s-%i", "l4d_tank_hp_sprite", client);
|
||||||
|
|
||||||
|
entityFrame = CreateEntityByName(CLASSNAME_ENV_TEXTURETOGGLE);
|
||||||
|
gc_iTankSpriteFrameRef[client] = EntIndexToEntRef(entityFrame);
|
||||||
|
DispatchKeyValue(entityFrame, "targetname", "l4d_tank_hp_sprite");
|
||||||
|
DispatchKeyValue(entityFrame, "target", targetname);
|
||||||
|
|
||||||
|
TeleportEntity(entityFrame, g_fVPos, NULL_VECTOR, NULL_VECTOR);
|
||||||
|
DispatchSpawn(entityFrame);
|
||||||
|
ActivateEntity(entityFrame);
|
||||||
|
|
||||||
|
SetVariantString("!activator");
|
||||||
|
AcceptEntityInput(entityFrame, "SetParent", entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPlayerIncapacitated(client))
|
if (IsPlayerIncapacitated(client))
|
||||||
|
@ -547,12 +636,15 @@ public void TankSprite(int client)
|
||||||
DispatchKeyValue(entity, "rendercolor", g_sCvar_DeadColor);
|
DispatchKeyValue(entity, "rendercolor", g_sCvar_DeadColor);
|
||||||
DispatchKeyValue(entity, "renderamt", g_sCvar_DeadAlpha); // If renderamt goes before rendercolor, it doesn't render
|
DispatchKeyValue(entity, "renderamt", g_sCvar_DeadAlpha); // If renderamt goes before rendercolor, it doesn't render
|
||||||
DispatchKeyValue(entity, "scale", g_sCvar_DeadScale);
|
DispatchKeyValue(entity, "scale", g_sCvar_DeadScale);
|
||||||
|
|
||||||
|
TeleportEntity(entity, g_fVPos, NULL_VECTOR, NULL_VECTOR);
|
||||||
DispatchSpawn(entity);
|
DispatchSpawn(entity);
|
||||||
|
ActivateEntity(entity);
|
||||||
|
|
||||||
SetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity", client);
|
SetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity", client);
|
||||||
SetVariantString("!activator");
|
SetVariantString("!activator");
|
||||||
AcceptEntityInput(entity, "SetParent", client);
|
AcceptEntityInput(entity, "SetParent", client);
|
||||||
AcceptEntityInput(entity, "ShowSprite");
|
AcceptEntityInput(entity, "ShowSprite");
|
||||||
TeleportEntity(entity, g_fVPos, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -568,9 +660,7 @@ public void TankSprite(int client)
|
||||||
int currentHealth = GetClientHealth(client);
|
int currentHealth = GetClientHealth(client);
|
||||||
|
|
||||||
float percentageHealth;
|
float percentageHealth;
|
||||||
if (maxHealth == 0)
|
if (maxHealth > 0)
|
||||||
percentageHealth = 0.0;
|
|
||||||
else
|
|
||||||
percentageHealth = (float(currentHealth) / float(maxHealth));
|
percentageHealth = (float(currentHealth) / float(maxHealth));
|
||||||
|
|
||||||
bool halfHealth = (percentageHealth <= 0.5);
|
bool halfHealth = (percentageHealth <= 0.5);
|
||||||
|
@ -578,16 +668,35 @@ public void TankSprite(int client)
|
||||||
char sRenderColor[12];
|
char sRenderColor[12];
|
||||||
Format(sRenderColor, sizeof(sRenderColor), "%i %i 0", halfHealth ? 255 : RoundFloat(255.0 * ((1.0 - percentageHealth) * 2)), halfHealth ? RoundFloat(255.0 * (percentageHealth) * 2) : 255);
|
Format(sRenderColor, sizeof(sRenderColor), "%i %i 0", halfHealth ? 255 : RoundFloat(255.0 * ((1.0 - percentageHealth) * 2)), halfHealth ? RoundFloat(255.0 * (percentageHealth) * 2) : 255);
|
||||||
|
|
||||||
DispatchKeyValue(entity, "model", g_sCvar_AliveModel);
|
DispatchKeyValue(entity, "model", g_bCvar_CustomModel ? g_sCvar_CustomModelVMT : g_sCvar_AliveModel);
|
||||||
DispatchKeyValue(entity, "rendercolor", sRenderColor);
|
DispatchKeyValue(entity, "rendercolor", sRenderColor);
|
||||||
DispatchKeyValue(entity, "renderamt", g_sCvar_AliveAlpha); // If renderamt goes before rendercolor, it doesn't render
|
DispatchKeyValue(entity, "renderamt", g_sCvar_AliveAlpha); // If renderamt goes before rendercolor, it doesn't render
|
||||||
DispatchKeyValue(entity, "scale", g_sCvar_AliveScale);
|
DispatchKeyValue(entity, "scale", g_sCvar_AliveScale);
|
||||||
|
|
||||||
|
TeleportEntity(entity, g_fVPos, NULL_VECTOR, NULL_VECTOR);
|
||||||
DispatchSpawn(entity);
|
DispatchSpawn(entity);
|
||||||
|
ActivateEntity(entity);
|
||||||
|
|
||||||
SetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity", client);
|
SetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity", client);
|
||||||
SetVariantString("!activator");
|
SetVariantString("!activator");
|
||||||
AcceptEntityInput(entity, "SetParent", client);
|
AcceptEntityInput(entity, "SetParent", client);
|
||||||
AcceptEntityInput(entity, "ShowSprite");
|
AcceptEntityInput(entity, "ShowSprite");
|
||||||
TeleportEntity(entity, g_fVPos, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
|
if (!g_bCvar_CustomModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int entityFrame = EntRefToEntIndex(gc_iTankSpriteFrameRef[client]);
|
||||||
|
|
||||||
|
if (entityFrame == INVALID_ENT_REFERENCE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int frame = RoundFloat(percentageHealth * 100);
|
||||||
|
|
||||||
|
char input[38];
|
||||||
|
FormatEx(input, sizeof(input), "OnUser1 !self:SetTextureIndex:%i:0:1", frame);
|
||||||
|
SetVariantString(input);
|
||||||
|
AcceptEntityInput(entityFrame, "AddOutput");
|
||||||
|
AcceptEntityInput(entityFrame, "FireUser1");
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************************************/
|
/****************************************************************************************************/
|
||||||
|
@ -612,14 +721,14 @@ bool IsVisibleTo(int client, int target)
|
||||||
float vClientPos[3];
|
float vClientPos[3];
|
||||||
float vEntityPos[3];
|
float vEntityPos[3];
|
||||||
float vLookAt[3];
|
float vLookAt[3];
|
||||||
float vAngles[3];
|
float vAng[3];
|
||||||
|
|
||||||
GetClientEyePosition(client, vClientPos);
|
GetClientEyePosition(client, vClientPos);
|
||||||
GetClientEyePosition(target, vEntityPos);
|
GetClientEyePosition(target, vEntityPos);
|
||||||
MakeVectorFromPoints(vClientPos, vEntityPos, vLookAt);
|
MakeVectorFromPoints(vClientPos, vEntityPos, vLookAt);
|
||||||
GetVectorAngles(vLookAt, vAngles);
|
GetVectorAngles(vLookAt, vAng);
|
||||||
|
|
||||||
Handle trace = TR_TraceRayFilterEx(vClientPos, vAngles, MASK_PLAYERSOLID, RayType_Infinite, TraceFilter, target);
|
Handle trace = TR_TraceRayFilterEx(vClientPos, vAng, MASK_PLAYERSOLID, RayType_Infinite, TraceFilter, target);
|
||||||
|
|
||||||
bool isVisible;
|
bool isVisible;
|
||||||
|
|
||||||
|
@ -682,6 +791,9 @@ public Action CmdPrintCvars(int client, int args)
|
||||||
PrintToConsole(client, "l4d_tank_hp_sprite_dead_scale : %.2f", g_fCvar_DeadScale);
|
PrintToConsole(client, "l4d_tank_hp_sprite_dead_scale : %.2f", g_fCvar_DeadScale);
|
||||||
PrintToConsole(client, "l4d_tank_hp_sprite_dead_color : \"%s\"", g_sCvar_DeadColor);
|
PrintToConsole(client, "l4d_tank_hp_sprite_dead_color : \"%s\"", g_sCvar_DeadColor);
|
||||||
PrintToConsole(client, "l4d_tank_hp_sprite_team : %i", g_iCvar_Team);
|
PrintToConsole(client, "l4d_tank_hp_sprite_team : %i", g_iCvar_Team);
|
||||||
|
PrintToConsole(client, "l4d_tank_hp_sprite_custom_model : %b (%s)", g_bCvar_CustomModel, g_bCvar_CustomModel ? "true" : "false");
|
||||||
|
PrintToConsole(client, "l4d_tank_hp_sprite_custom_model_vmt : \"%s\"", g_sCvar_CustomModelVMT);
|
||||||
|
PrintToConsole(client, "l4d_tank_hp_sprite_custom_model_vtf : \"%s\"", g_sCvar_CustomModelVTF);
|
||||||
PrintToConsole(client, "");
|
PrintToConsole(client, "");
|
||||||
PrintToConsole(client, "======================================================================");
|
PrintToConsole(client, "======================================================================");
|
||||||
PrintToConsole(client, "");
|
PrintToConsole(client, "");
|
||||||
|
@ -777,7 +889,8 @@ bool IsPlayerIncapacitated(int client)
|
||||||
* @param client Client index.
|
* @param client Client index.
|
||||||
* @return True if client is a tank, false otherwise.
|
* @return True if client is a tank, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool IsPlayerSpecialInfected(int client) {
|
bool IsPlayerTank(int client)
|
||||||
|
{
|
||||||
bool isValid = IsValidClient(client) && GetClientTeam(client) == TEAM_INFECTED && IsPlayerAlive(client) && !IsPlayerGhost(client);
|
bool isValid = IsValidClient(client) && GetClientTeam(client) == TEAM_INFECTED && IsPlayerAlive(client) && !IsPlayerGhost(client);
|
||||||
if(!g_hCvar_AllSpecials.BoolValue && GetZombieClass(client) != g_iTankClass)
|
if(!g_hCvar_AllSpecials.BoolValue && GetZombieClass(client) != g_iTankClass)
|
||||||
return false;
|
return false;
|
||||||
|
@ -788,14 +901,14 @@ bool IsPlayerSpecialInfected(int client) {
|
||||||
/****************************************************************************************************/
|
/****************************************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the team flag from a client.
|
* Returns the team flag from a team.
|
||||||
*
|
*
|
||||||
* @param client Client index.
|
* @param team Team index.
|
||||||
* @return Client team flag.
|
* @return Team flag.
|
||||||
*/
|
*/
|
||||||
int GetClientTeamFlag(int client)
|
int GetTeamFlag(int team)
|
||||||
{
|
{
|
||||||
switch (GetClientTeam(client))
|
switch (team)
|
||||||
{
|
{
|
||||||
case TEAM_SURVIVOR:
|
case TEAM_SURVIVOR:
|
||||||
return FLAG_TEAM_SURVIVOR;
|
return FLAG_TEAM_SURVIVOR;
|
||||||
|
|
149
scripting/l4dunreservelobby.sp
Normal file
149
scripting/l4dunreservelobby.sp
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <left4dhooks>
|
||||||
|
|
||||||
|
#define UNRESERVE_VERSION "1.1.1"
|
||||||
|
|
||||||
|
#define UNRESERVE_DEBUG 0
|
||||||
|
#define UNRESERVE_DEBUG_LOG 0
|
||||||
|
|
||||||
|
#define L4D_MAXCLIENTS MaxClients
|
||||||
|
#define L4D_MAXCLIENTS_PLUS1 (L4D_MAXCLIENTS + 1)
|
||||||
|
|
||||||
|
#define L4D_MAXHUMANS_LOBBY_VERSUS 8
|
||||||
|
#define L4D_MAXHUMANS_LOBBY_OTHER 4
|
||||||
|
|
||||||
|
new Handle:cvarGameMode = INVALID_HANDLE;
|
||||||
|
|
||||||
|
public Plugin:myinfo =
|
||||||
|
{
|
||||||
|
name = "L4D1/2 Remove Lobby Reservation",
|
||||||
|
author = "Downtown1",
|
||||||
|
description = "Removes lobby reservation when server is full",
|
||||||
|
version = UNRESERVE_VERSION,
|
||||||
|
url = "http://forums.alliedmods.net/showthread.php?t=87759"
|
||||||
|
}
|
||||||
|
|
||||||
|
new Handle:cvarUnreserve = INVALID_HANDLE;
|
||||||
|
|
||||||
|
public OnPluginStart()
|
||||||
|
{
|
||||||
|
LoadTranslations("common.phrases");
|
||||||
|
|
||||||
|
RegAdminCmd("sm_unreserve", Command_Unreserve, ADMFLAG_BAN, "sm_unreserve - manually force removes the lobby reservation");
|
||||||
|
|
||||||
|
cvarUnreserve = CreateConVar("l4d_unreserve_full", "1", "Automatically unreserve server after a full lobby joins", FCVAR_SPONLY|FCVAR_NOTIFY);
|
||||||
|
CreateConVar("l4d_unreserve_version", UNRESERVE_VERSION, "Version of the Lobby Unreserve plugin.", FCVAR_SPONLY|FCVAR_NOTIFY);
|
||||||
|
|
||||||
|
cvarGameMode = FindConVar("mp_gamemode");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool:IsScavengeMode()
|
||||||
|
{
|
||||||
|
decl String:sGameMode[32];
|
||||||
|
GetConVarString(cvarGameMode, sGameMode, sizeof(sGameMode));
|
||||||
|
if (StrContains(sGameMode, "scavenge") > -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool:IsVersusMode()
|
||||||
|
{
|
||||||
|
decl String:sGameMode[32];
|
||||||
|
GetConVarString(cvarGameMode, sGameMode, sizeof(sGameMode));
|
||||||
|
if (StrContains(sGameMode, "versus") > -1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IsServerLobbyFull()
|
||||||
|
{
|
||||||
|
new humans = GetHumanCount();
|
||||||
|
|
||||||
|
DebugPrintToAll("IsServerLobbyFull : humans = %d", humans);
|
||||||
|
|
||||||
|
if(IsVersusMode() || IsScavengeMode())
|
||||||
|
{
|
||||||
|
return humans >= L4D_MAXHUMANS_LOBBY_VERSUS;
|
||||||
|
}
|
||||||
|
return humans >= L4D_MAXHUMANS_LOBBY_OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnClientPutInServer(client)
|
||||||
|
{
|
||||||
|
DebugPrintToAll("Client put in server %N", client);
|
||||||
|
|
||||||
|
if(GetConVarBool(cvarUnreserve) && /*L4D_LobbyIsReserved() &&*/ IsServerLobbyFull())
|
||||||
|
{
|
||||||
|
//PrintToChatAll("[SM] A full lobby has connected, automatically unreserving the server.");
|
||||||
|
L4D_LobbyUnreserve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action:Command_Unreserve(client, args)
|
||||||
|
{
|
||||||
|
/*if(!L4D_LobbyIsReserved())
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "[SM] Server is already unreserved.");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
L4D_LobbyUnreserve();
|
||||||
|
PrintToChatAll("[SM] Lobby reservation has been removed.");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//client is in-game and not a bot
|
||||||
|
stock bool:IsClientInGameHuman(client)
|
||||||
|
{
|
||||||
|
return IsClientInGame(client) && !IsFakeClient(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
stock GetHumanCount()
|
||||||
|
{
|
||||||
|
new humans = 0;
|
||||||
|
|
||||||
|
new i;
|
||||||
|
for(i = 1; i < L4D_MAXCLIENTS_PLUS1; i++)
|
||||||
|
{
|
||||||
|
if(IsClientInGameHuman(i))
|
||||||
|
{
|
||||||
|
humans++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return humans;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugPrintToAll(const String:format[], any:...)
|
||||||
|
{
|
||||||
|
#if UNRESERVE_DEBUG || UNRESERVE_DEBUG_LOG
|
||||||
|
decl String:buffer[192];
|
||||||
|
|
||||||
|
VFormat(buffer, sizeof(buffer), format, 2);
|
||||||
|
|
||||||
|
#if UNRESERVE_DEBUG
|
||||||
|
PrintToChatAll("[UNRESERVE] %s", buffer);
|
||||||
|
PrintToConsole(0, "[UNRESERVE] %s", buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LogMessage("%s", buffer);
|
||||||
|
#else
|
||||||
|
//suppress "format" never used warning
|
||||||
|
if(format[0])
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
855
scripting/sceneprocessor.sp
Normal file
855
scripting/sceneprocessor.sp
Normal file
|
@ -0,0 +1,855 @@
|
||||||
|
#define PLUGIN_VERSION "1.33.2"
|
||||||
|
|
||||||
|
#pragma semicolon 1
|
||||||
|
#pragma newdecls required
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <sdktools>
|
||||||
|
#include <sdkhooks>
|
||||||
|
|
||||||
|
#include <sceneprocessor>
|
||||||
|
|
||||||
|
int iSkippedFrames;
|
||||||
|
char sVocalizeScene[MAXPLAYERS+1][MAX_VOCALIZE_LENGTH];
|
||||||
|
bool bSceneHasInitiator[MAXPLAYERS+1], bScenesUnprocessed, bUnvocalizedCommands, bJailbreakVocalize, bIsL4D;
|
||||||
|
|
||||||
|
float fStartTimeStamp, fVocalizePreDelay[MAXPLAYERS+1], fVocalizePitch[MAXPLAYERS+1];
|
||||||
|
Handle hSceneStageForward, hVocalizeCommandForward;
|
||||||
|
|
||||||
|
ArrayList alVocalize;
|
||||||
|
ArrayStack asScene;
|
||||||
|
|
||||||
|
enum struct SceneData
|
||||||
|
{
|
||||||
|
SceneStages ssDataBit;
|
||||||
|
bool bInFakePostSpawn;
|
||||||
|
float fTimeStampData;
|
||||||
|
int iActorData;
|
||||||
|
int iInitiatorData;
|
||||||
|
char sFileData[MAX_SCENEFILE_LENGTH];
|
||||||
|
char sVocalizeData[MAX_VOCALIZE_LENGTH];
|
||||||
|
float fPreDelayData;
|
||||||
|
float fPitchData;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneData nSceneData[2048];
|
||||||
|
int iScenePlaying[MAXPLAYERS+1], iVocalizeTick[MAXPLAYERS+1], iVocalizeInitiator[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
||||||
|
{
|
||||||
|
EngineVersion evGame = GetEngineVersion();
|
||||||
|
if (evGame == Engine_Left4Dead)
|
||||||
|
{
|
||||||
|
bIsL4D = true;
|
||||||
|
}
|
||||||
|
else if (evGame != Engine_Left4Dead2)
|
||||||
|
{
|
||||||
|
strcopy(error, err_max, "[SP] Plugin Supports L4D And L4D2 Only!");
|
||||||
|
return APLRes_Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateNative("GetSceneStage", SP_GetSceneStage);
|
||||||
|
CreateNative("GetSceneStartTimeStamp", SP_GetSceneStartTimeStamp);
|
||||||
|
CreateNative("GetActorFromScene", SP_GetSceneActor);
|
||||||
|
CreateNative("GetSceneFromActor", SP_GetActorScene);
|
||||||
|
CreateNative("GetSceneInitiator", SP_GetSceneInitiator);
|
||||||
|
CreateNative("GetSceneFile", SP_GetSceneFile);
|
||||||
|
CreateNative("GetSceneVocalize", SP_GetSceneVocalize);
|
||||||
|
CreateNative("GetScenePreDelay", SP_GetScenePreDelay);
|
||||||
|
CreateNative("SetScenePreDelay", SP_SetScenePreDelay);
|
||||||
|
CreateNative("GetScenePitch", SP_GetScenePitch);
|
||||||
|
CreateNative("SetScenePitch", SP_SetScenePitch);
|
||||||
|
CreateNative("CancelScene", SP_CancelScene);
|
||||||
|
CreateNative("PerformScene", SP_PerformScene);
|
||||||
|
CreateNative("PerformSceneEx", SP_PerformSceneEx);
|
||||||
|
|
||||||
|
RegPluginLibrary("sceneprocessor");
|
||||||
|
return APLRes_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public any SP_GetSceneStage(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return SceneStage_Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (scene < 1 || scene > 2048 || !IsValidEntity(scene))
|
||||||
|
{
|
||||||
|
return SceneStage_Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSceneData[scene].ssDataBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public any SP_GetSceneStartTimeStamp(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSceneData[scene].fTimeStampData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_GetActorScene(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return INVALID_ENT_REFERENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iActor = GetNativeCell(1);
|
||||||
|
if (iActor < 1 || iActor > MaxClients || !IsClientInGame(iActor) || GetClientTeam(iActor) != 2 || !IsPlayerAlive(iActor))
|
||||||
|
{
|
||||||
|
return INVALID_ENT_REFERENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iScenePlaying[iActor];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_GetSceneActor(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSceneData[scene].iActorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_GetSceneInitiator(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSceneData[scene].iInitiatorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_GetSceneFile(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams != 3)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = GetNativeCell(3);
|
||||||
|
|
||||||
|
int bytesWritten;
|
||||||
|
SetNativeString(2, nSceneData[scene].sFileData, len, _, bytesWritten);
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_GetSceneVocalize(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams != 3)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = GetNativeCell(3);
|
||||||
|
|
||||||
|
int bytesWritten;
|
||||||
|
SetNativeString(2, nSceneData[scene].sVocalizeData, len, _, bytesWritten);
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
public any SP_GetScenePreDelay(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSceneData[scene].fPreDelayData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_SetScenePreDelay(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams != 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fPreDelay = GetNativeCell(2);
|
||||||
|
|
||||||
|
SetEntPropFloat(scene, Prop_Data, "m_flPreDelay", fPreDelay);
|
||||||
|
nSceneData[scene].fPreDelayData = fPreDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public any SP_GetScenePitch(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSceneData[scene].fPitchData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_SetScenePitch(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams != 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (!IsValidScene(scene))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fPitch = GetNativeCell(2);
|
||||||
|
|
||||||
|
SetEntPropFloat(scene, Prop_Data, "m_fPitch", fPitch);
|
||||||
|
nSceneData[scene].fPitchData = fPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_CancelScene(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scene = GetNativeCell(1);
|
||||||
|
if (scene < 1 || scene > 2048 || !IsValidEntity(scene))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneStages ssBit = nSceneData[scene].ssDataBit;
|
||||||
|
if (ssBit == SceneStage_Unknown)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (ssBit == SceneStage_Started || (ssBit == SceneStage_SpawnedPost && nSceneData[scene].bInFakePostSpawn))
|
||||||
|
{
|
||||||
|
AcceptEntityInput(scene, "Cancel");
|
||||||
|
}
|
||||||
|
else if (ssBit != SceneStage_Cancelled && ssBit != SceneStage_Completion && ssBit != SceneStage_Killed)
|
||||||
|
{
|
||||||
|
AcceptEntityInput(scene, "Kill");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_PerformScene(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams < 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client = GetNativeCell(1);
|
||||||
|
|
||||||
|
if (client < 1 || client > MaxClients || !IsClientInGame(client) || GetClientTeam(client) != 2 || !IsPlayerAlive(client))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char sVocalize[MAX_VOCALIZE_LENGTH], sFile[MAX_SCENEFILE_LENGTH];
|
||||||
|
float fPreDelay = DEFAULT_SCENE_PREDELAY, fPitch = DEFAULT_SCENE_PITCH;
|
||||||
|
int iInitiator = SCENE_INITIATOR_PLUGIN;
|
||||||
|
|
||||||
|
if (GetNativeString(2, sVocalize, MAX_VOCALIZE_LENGTH) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Unknown Vocalize Parameter!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 3)
|
||||||
|
{
|
||||||
|
if (GetNativeString(3, sFile, MAX_SCENEFILE_LENGTH) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Unknown File Parameter!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 4)
|
||||||
|
{
|
||||||
|
fPreDelay = GetNativeCell(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 5)
|
||||||
|
{
|
||||||
|
fPitch = GetNativeCell(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 6)
|
||||||
|
{
|
||||||
|
iInitiator = GetNativeCell(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene_Perform(client, sVocalize, sFile, fPreDelay, fPitch, iInitiator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SP_PerformSceneEx(Handle plugin, int numParams)
|
||||||
|
{
|
||||||
|
if (numParams < 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client = GetNativeCell(1);
|
||||||
|
if (client < 1 || client > MaxClients || !IsClientInGame(client) || GetClientTeam(client) != 2 || !IsPlayerAlive(client))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char sVocalize[MAX_VOCALIZE_LENGTH], sFile[MAX_SCENEFILE_LENGTH];
|
||||||
|
float fPreDelay = DEFAULT_SCENE_PREDELAY, fPitch = DEFAULT_SCENE_PITCH;
|
||||||
|
int iInitiator = SCENE_INITIATOR_PLUGIN;
|
||||||
|
|
||||||
|
if (GetNativeString(2, sVocalize, MAX_VOCALIZE_LENGTH) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Unknown Vocalize Parameter!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 3)
|
||||||
|
{
|
||||||
|
if (GetNativeString(3, sFile, MAX_SCENEFILE_LENGTH) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
ThrowNativeError(SP_ERROR_NATIVE, "Unknown File Parameter!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 4)
|
||||||
|
{
|
||||||
|
fPreDelay = GetNativeCell(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 5)
|
||||||
|
{
|
||||||
|
fPitch = GetNativeCell(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numParams >= 6)
|
||||||
|
{
|
||||||
|
iInitiator = GetNativeCell(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene_Perform(client, sVocalize, sFile, fPreDelay, fPitch, iInitiator, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin myinfo =
|
||||||
|
{
|
||||||
|
name = "Scene Processor",
|
||||||
|
author = "Buster \"Mr. Zero\" Nielsen (Fork by cravenge & Dragokas)",
|
||||||
|
description = "Provides Forwards and Natives For Scenes' Manipulation.",
|
||||||
|
version = PLUGIN_VERSION,
|
||||||
|
url = "https://forums.alliedmods.net/showthread.php?t=241585"
|
||||||
|
};
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
hSceneStageForward = CreateGlobalForward("OnSceneStageChanged", ET_Ignore, Param_Cell, Param_Cell);
|
||||||
|
hVocalizeCommandForward = CreateGlobalForward("OnVocalizeCommand", ET_Hook, Param_Cell, Param_String, Param_Cell);
|
||||||
|
|
||||||
|
CreateConVar("sceneprocessor_version", PLUGIN_VERSION, "Scene Processor Version", FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD);
|
||||||
|
if (!bIsL4D)
|
||||||
|
{
|
||||||
|
ConVar spJailbreakVocalize = CreateConVar("sceneprocessor_jailbreak_vocalize", "1", "Enable/Disable Jailbreak Vocalizations", FCVAR_SPONLY|FCVAR_NOTIFY);
|
||||||
|
spJailbreakVocalize.AddChangeHook(OnSPCVarChanged);
|
||||||
|
bJailbreakVocalize = spJailbreakVocalize.BoolValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddCommandListener(OnVocalizeCmd, "vocalize");
|
||||||
|
|
||||||
|
asScene = new ArrayStack();
|
||||||
|
alVocalize = new ArrayList(MAX_VOCALIZE_LENGTH);
|
||||||
|
|
||||||
|
for (int i = 1; i < 2049; i++)
|
||||||
|
{
|
||||||
|
if (IsValidEntity(i) && IsValidEdict(i))
|
||||||
|
{
|
||||||
|
SceneData_SetStage(i, SceneStage_Unknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsClientInGame(i))
|
||||||
|
{
|
||||||
|
ResetClientVocalizeData(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSPCVarChanged(ConVar cvar, const char[] sOldValue, const char[] sNewValue)
|
||||||
|
{
|
||||||
|
bJailbreakVocalize = cvar.BoolValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action OnVocalizeCmd(int client, const char[] command, int args)
|
||||||
|
{
|
||||||
|
if (client == 0 || args == 0)
|
||||||
|
{
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsClientInGame(client))
|
||||||
|
{
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char sVocalize[128];
|
||||||
|
GetCmdArg(1, sVocalize, sizeof(sVocalize));
|
||||||
|
|
||||||
|
if (!bIsL4D && args != 2)
|
||||||
|
{
|
||||||
|
if (bJailbreakVocalize)
|
||||||
|
{
|
||||||
|
JailbreakVocalize(client, sVocalize);
|
||||||
|
}
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iTick = GetGameTickCount();
|
||||||
|
|
||||||
|
if (!bSceneHasInitiator[client] || (iVocalizeTick[client] > 0 && iVocalizeTick[client] != iTick))
|
||||||
|
{
|
||||||
|
iVocalizeInitiator[client] = client;
|
||||||
|
|
||||||
|
if (!bIsL4D && args > 1 && StrEqual(sVocalize, "smartlook", false))
|
||||||
|
{
|
||||||
|
static char sTime[32];
|
||||||
|
GetCmdArg(2, sTime, sizeof(sTime));
|
||||||
|
if (StrEqual(sTime, "auto", false))
|
||||||
|
{
|
||||||
|
iVocalizeInitiator[client] = SCENE_INITIATOR_WORLD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcopy(sVocalizeScene[client], MAX_VOCALIZE_LENGTH, sVocalize);
|
||||||
|
iVocalizeTick[client] = iTick;
|
||||||
|
|
||||||
|
Action aResult = Plugin_Continue;
|
||||||
|
|
||||||
|
Call_StartForward(hVocalizeCommandForward);
|
||||||
|
Call_PushCell(client);
|
||||||
|
Call_PushString(sVocalize);
|
||||||
|
Call_PushCell(iVocalizeInitiator[client]);
|
||||||
|
Call_Finish(aResult);
|
||||||
|
|
||||||
|
return (aResult == Plugin_Stop) ? Plugin_Handled : Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnPluginEnd()
|
||||||
|
{
|
||||||
|
RemoveCommandListener(OnVocalizeCmd, "vocalize");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMapStart()
|
||||||
|
{
|
||||||
|
iSkippedFrames = 0;
|
||||||
|
fStartTimeStamp = GetGameTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEntityCreated(int entity, const char[] classname)
|
||||||
|
{
|
||||||
|
if (entity < 1 || entity > 2048)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrEqual(classname, "instanced_scripted_scene"))
|
||||||
|
{
|
||||||
|
SDKHook(entity, SDKHook_SpawnPost, OnSpawnPost);
|
||||||
|
SceneData_SetStage(entity, SceneStage_Created);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSpawnPost(int entity)
|
||||||
|
{
|
||||||
|
int iActor = GetEntPropEnt(entity, Prop_Data, "m_hOwner");
|
||||||
|
nSceneData[entity].iActorData = iActor;
|
||||||
|
|
||||||
|
static char sFile[MAX_SCENEFILE_LENGTH];
|
||||||
|
GetEntPropString(entity, Prop_Data, "m_iszSceneFile", sFile, MAX_SCENEFILE_LENGTH);
|
||||||
|
|
||||||
|
strcopy(nSceneData[entity].sFileData, MAX_SCENEFILE_LENGTH, sFile);
|
||||||
|
nSceneData[entity].fPitchData = GetEntPropFloat(entity, Prop_Data, "m_fPitch");
|
||||||
|
|
||||||
|
if (iActor > 0 && iActor <= MaxClients && IsClientInGame(iActor))
|
||||||
|
{
|
||||||
|
if (iVocalizeTick[iActor] == GetGameTickCount())
|
||||||
|
{
|
||||||
|
strcopy(nSceneData[entity].sVocalizeData, MAX_VOCALIZE_LENGTH, sVocalizeScene[iActor]);
|
||||||
|
|
||||||
|
nSceneData[entity].iInitiatorData = iVocalizeInitiator[iActor];
|
||||||
|
nSceneData[entity].fPreDelayData = fVocalizePreDelay[iActor];
|
||||||
|
nSceneData[entity].fPitchData = fVocalizePitch[iActor];
|
||||||
|
}
|
||||||
|
ResetClientVocalizeData(iActor);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEntPropFloat(entity, Prop_Data, "m_fPitch", nSceneData[entity].fPitchData);
|
||||||
|
SetEntPropFloat(entity, Prop_Data, "m_flPreDelay", nSceneData[entity].fPreDelayData);
|
||||||
|
|
||||||
|
asScene.Push(entity);
|
||||||
|
bScenesUnprocessed = true;
|
||||||
|
|
||||||
|
HookSingleEntityOutput(entity, "OnStart", OnSceneStart_EntOutput);
|
||||||
|
HookSingleEntityOutput(entity, "OnCanceled", OnSceneCanceled_EntOutput);
|
||||||
|
|
||||||
|
SceneData_SetStage(entity, SceneStage_Spawned);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSceneStart_EntOutput(const char[] output, int caller, int activator, float delay)
|
||||||
|
{
|
||||||
|
if (caller < 1 || caller > 2048 || !IsValidEntity(caller))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char sFile[MAX_SCENEFILE_LENGTH];
|
||||||
|
strcopy(sFile, MAX_SCENEFILE_LENGTH, nSceneData[caller].sFileData);
|
||||||
|
if (!sFile[0])
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nSceneData[caller].fTimeStampData = GetEngineTime();
|
||||||
|
|
||||||
|
if (nSceneData[caller].ssDataBit == SceneStage_Spawned)
|
||||||
|
{
|
||||||
|
nSceneData[caller].bInFakePostSpawn = true;
|
||||||
|
SceneData_SetStage(caller, SceneStage_SpawnedPost);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nSceneData[caller].ssDataBit == SceneStage_SpawnedPost)
|
||||||
|
{
|
||||||
|
int iActor = nSceneData[caller].iActorData;
|
||||||
|
if (iActor > 0 && iActor <= MaxClients && IsClientInGame(iActor))
|
||||||
|
{
|
||||||
|
iScenePlaying[iActor] = caller;
|
||||||
|
}
|
||||||
|
SceneData_SetStage(caller, SceneStage_Started);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSceneCanceled_EntOutput(const char[] output, int caller, int activator, float delay)
|
||||||
|
{
|
||||||
|
if (caller < 1 || caller > 2048 || !IsValidEntity(caller))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (iScenePlaying[i] == caller)
|
||||||
|
{
|
||||||
|
iScenePlaying[i] = INVALID_ENT_REFERENCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneData_SetStage(caller, SceneStage_Cancelled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEntityDestroyed(int entity)
|
||||||
|
{
|
||||||
|
if (entity < 1 || entity > 2048 || !IsValidEdict(entity))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char sEntityClass[64];
|
||||||
|
GetEdictClassname(entity, sEntityClass, sizeof(sEntityClass));
|
||||||
|
if (!StrEqual(sEntityClass, "instanced_scripted_scene"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDKUnhook(entity, SDKHook_SpawnPost, OnSpawnPost);
|
||||||
|
|
||||||
|
SceneStages ssBit = nSceneData[entity].ssDataBit;
|
||||||
|
if (ssBit != SceneStage_Unknown)
|
||||||
|
{
|
||||||
|
if (ssBit == SceneStage_Started)
|
||||||
|
{
|
||||||
|
SceneData_SetStage(entity, SceneStage_Completion);
|
||||||
|
}
|
||||||
|
SceneData_SetStage(entity, SceneStage_Killed);
|
||||||
|
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (!IsClientInGame(i) || iScenePlaying[i] != entity)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
iScenePlaying[i] = INVALID_ENT_REFERENCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneData_SetStage(entity, SceneStage_Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientDisconnect(int client)
|
||||||
|
{
|
||||||
|
if (client == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iScenePlaying[client] = INVALID_ENT_REFERENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnGameFrame()
|
||||||
|
{
|
||||||
|
iSkippedFrames += 1;
|
||||||
|
if (iSkippedFrames < 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iSkippedFrames = 1;
|
||||||
|
if (bScenesUnprocessed)
|
||||||
|
{
|
||||||
|
bScenesUnprocessed = false;
|
||||||
|
|
||||||
|
int dScene;
|
||||||
|
while (!asScene.Empty)
|
||||||
|
{
|
||||||
|
asScene.Pop(dScene);
|
||||||
|
if (dScene < 1 || dScene > 2048 || !IsValidEntity(dScene))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nSceneData[dScene].ssDataBit != SceneStage_Spawned)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nSceneData[dScene].fPreDelayData = GetEntPropFloat(dScene, Prop_Data, "m_flPreDelay");
|
||||||
|
nSceneData[dScene].bInFakePostSpawn = false;
|
||||||
|
|
||||||
|
SceneData_SetStage(dScene, SceneStage_SpawnedPost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bUnvocalizedCommands)
|
||||||
|
{
|
||||||
|
int iArraySize = alVocalize.Length,
|
||||||
|
iCurrentTick = GetGameTickCount();
|
||||||
|
|
||||||
|
static char sVocalize[MAX_VOCALIZE_LENGTH];
|
||||||
|
float fPreDelay, fPitch;
|
||||||
|
int client, dInitiator, dTick;
|
||||||
|
|
||||||
|
for (int i = 0; i < iArraySize; i += 6)
|
||||||
|
{
|
||||||
|
dTick = alVocalize.Get(i + 5);
|
||||||
|
if (iCurrentTick != dTick)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
client = alVocalize.Get(i + 0);
|
||||||
|
alVocalize.GetString(i + 1, sVocalize, MAX_VOCALIZE_LENGTH);
|
||||||
|
fPreDelay = view_as<float>(alVocalize.Get(i + 2));
|
||||||
|
fPitch = view_as<float>(alVocalize.Get(i + 3));
|
||||||
|
dInitiator = alVocalize.Get(i + 4);
|
||||||
|
|
||||||
|
Scene_Perform(client, sVocalize, _, fPreDelay, fPitch, dInitiator, true);
|
||||||
|
|
||||||
|
for (int j = 0; j < 6; j++)
|
||||||
|
{
|
||||||
|
alVocalize.Erase(i);
|
||||||
|
iArraySize -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iArraySize < 1)
|
||||||
|
{
|
||||||
|
alVocalize.Clear();
|
||||||
|
bUnvocalizedCommands = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMapEnd()
|
||||||
|
{
|
||||||
|
iSkippedFrames = 0;
|
||||||
|
|
||||||
|
bScenesUnprocessed = false;
|
||||||
|
bUnvocalizedCommands = false;
|
||||||
|
|
||||||
|
while (!asScene.Empty)
|
||||||
|
{
|
||||||
|
PopStack(asScene);
|
||||||
|
}
|
||||||
|
alVocalize.Clear();
|
||||||
|
|
||||||
|
for (int i = 1; i < 2049; i++)
|
||||||
|
{
|
||||||
|
if (IsValidEntity(i) && IsValidEdict(i))
|
||||||
|
{
|
||||||
|
SceneData_SetStage(i, SceneStage_Unknown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsClientInGame(i))
|
||||||
|
{
|
||||||
|
iScenePlaying[i] = INVALID_ENT_REFERENCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetClientVocalizeData(int client)
|
||||||
|
{
|
||||||
|
iVocalizeTick[client] = 0;
|
||||||
|
sVocalizeScene[client] = "\0";
|
||||||
|
bSceneHasInitiator[client] = false;
|
||||||
|
iVocalizeInitiator[client] = SCENE_INITIATOR_WORLD;
|
||||||
|
fVocalizePreDelay[client] = DEFAULT_SCENE_PREDELAY;
|
||||||
|
fVocalizePitch[client] = DEFAULT_SCENE_PITCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneData_SetStage(int scene, SceneStages stage)
|
||||||
|
{
|
||||||
|
nSceneData[scene].ssDataBit = stage;
|
||||||
|
|
||||||
|
if (stage != SceneStage_Unknown)
|
||||||
|
{
|
||||||
|
Call_StartForward(hSceneStageForward);
|
||||||
|
Call_PushCell(scene);
|
||||||
|
Call_PushCell(stage);
|
||||||
|
Call_Finish();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nSceneData[scene].bInFakePostSpawn = false;
|
||||||
|
nSceneData[scene].fTimeStampData = 0.0;
|
||||||
|
nSceneData[scene].iActorData = 0;
|
||||||
|
nSceneData[scene].iInitiatorData = 0;
|
||||||
|
strcopy(nSceneData[scene].sFileData, MAX_SCENEFILE_LENGTH, "\0");
|
||||||
|
strcopy(nSceneData[scene].sVocalizeData, MAX_VOCALIZE_LENGTH, "\0");
|
||||||
|
nSceneData[scene].fPreDelayData = DEFAULT_SCENE_PREDELAY;
|
||||||
|
nSceneData[scene].fPitchData = DEFAULT_SCENE_PITCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene_Perform(int client, const char[] sVocalizeParam, const char[] sFileParam = "", float fScenePreDelay = DEFAULT_SCENE_PREDELAY, float fScenePitch = DEFAULT_SCENE_PITCH, int iSceneInitiator = SCENE_INITIATOR_PLUGIN, bool bVocalizeNow = false)
|
||||||
|
{
|
||||||
|
if (sFileParam[0] && FileExists(sFileParam, true))
|
||||||
|
{
|
||||||
|
int iScene = CreateEntityByName("instanced_scripted_scene");
|
||||||
|
DispatchKeyValue(iScene, "SceneFile", sFileParam);
|
||||||
|
|
||||||
|
SetEntPropEnt(iScene, Prop_Data, "m_hOwner", client);
|
||||||
|
nSceneData[iScene].iActorData = client;
|
||||||
|
SetEntPropFloat(iScene, Prop_Data, "m_flPreDelay", fScenePreDelay);
|
||||||
|
nSceneData[iScene].fPreDelayData = fScenePreDelay;
|
||||||
|
SetEntPropFloat(iScene, Prop_Data, "m_fPitch", fScenePitch);
|
||||||
|
nSceneData[iScene].fPitchData = fScenePitch;
|
||||||
|
|
||||||
|
nSceneData[iScene].iInitiatorData = iSceneInitiator;
|
||||||
|
strcopy(nSceneData[iScene].sVocalizeData, MAX_VOCALIZE_LENGTH, sVocalizeParam);
|
||||||
|
|
||||||
|
DispatchSpawn(iScene);
|
||||||
|
ActivateEntity(iScene);
|
||||||
|
|
||||||
|
AcceptEntityInput(iScene, "Start", client, client);
|
||||||
|
}
|
||||||
|
else if (sVocalizeParam[0])
|
||||||
|
{
|
||||||
|
if (bVocalizeNow)
|
||||||
|
{
|
||||||
|
iVocalizeInitiator[client] = iSceneInitiator;
|
||||||
|
bSceneHasInitiator[client] = true;
|
||||||
|
fVocalizePreDelay[client] = fScenePreDelay;
|
||||||
|
fVocalizePitch[client] = fScenePitch;
|
||||||
|
|
||||||
|
if (bIsL4D)
|
||||||
|
{
|
||||||
|
FakeClientCommandEx(client, "vocalize %s", sVocalizeParam);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JailbreakVocalize(client, sVocalizeParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alVocalize.Push(client);
|
||||||
|
alVocalize.PushString(sVocalizeParam);
|
||||||
|
alVocalize.Push(fScenePreDelay);
|
||||||
|
alVocalize.Push(fScenePitch);
|
||||||
|
alVocalize.Push(iSceneInitiator);
|
||||||
|
alVocalize.Push(GetGameTickCount() + 10 - 1);
|
||||||
|
|
||||||
|
bUnvocalizedCommands = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JailbreakVocalize(int client, const char[] sVocalize)
|
||||||
|
{
|
||||||
|
char sBuffer[2][32];
|
||||||
|
FloatToString((GetGameTime() - fStartTimeStamp) + 2.0, sBuffer[0], 32);
|
||||||
|
ExplodeString(sBuffer[0], ".", sBuffer, 2, 32);
|
||||||
|
|
||||||
|
Format(sBuffer[1], 2, "%s\0", sBuffer[1][0]);
|
||||||
|
FakeClientCommandEx(client, "vocalize %s #%s%s", sVocalize, sBuffer[0], sBuffer[1]);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue