mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 14:33:21 +00:00
updates
This commit is contained in:
parent
a1b239f394
commit
6c0e7bc1f2
23 changed files with 726 additions and 108 deletions
Binary file not shown.
Binary file not shown.
BIN
plugins/l4d2_ai_tweaks.smx
Normal file
BIN
plugins/l4d2_ai_tweaks.smx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -82,7 +82,7 @@ public Action VoteStart(int client, const char[] command, int argc) {
|
|||
|
||||
if(strlen(option) > 1) { //empty userid/console can't call votes
|
||||
int target = GetClientOfUserId(StringToInt(option));
|
||||
if(target == 0) return Plugin_Continue; //invalid, pass it through
|
||||
if(target == 0 || target >= MaxClients || !IsClientConnected(target)) return Plugin_Continue; //invalid, pass it through
|
||||
AdminId callerAdmin = GetUserAdmin(client);
|
||||
AdminId targetAdmin = GetUserAdmin(target);
|
||||
if(targetAdmin != INVALID_ADMIN_ID) { //Only run if vote is against an admin
|
||||
|
|
|
@ -113,6 +113,7 @@ public Action OnBanIdentity(const char[] identity, int time, int flags, const ch
|
|||
|
||||
g_db.Format(query, sizeof(query), "SELECT `flags` FROM `bans` WHERE `expired` = 0 AND `steamid` LIKE 'STEAM_%%:%%:%s' OR ip = '%s'", identity[10], identity);
|
||||
g_db.Query(DB_OnBanPreCheck, query, key);
|
||||
PrintToServer("Adding %s to OnBanClient queue. Key: %d", identity, key);
|
||||
|
||||
}else if(flags == BANFLAG_IP) {
|
||||
LogMessage("Cannot save IP without steamid: %s [Source: %s]", identity, source);
|
||||
|
@ -120,6 +121,9 @@ public Action OnBanIdentity(const char[] identity, int time, int flags, const ch
|
|||
return Plugin_Continue;
|
||||
}
|
||||
public Action OnBanClient(int client, int time, int flags, const char[] reason, const char[] kick_message, const char[] command, any source) {
|
||||
if(GetUserAdmin(client) != INVALID_ADMIN_ID) return Plugin_Stop;
|
||||
|
||||
|
||||
char executor[32], identity[32], ip[32];
|
||||
GetClientAuthId(client, AuthId_Steam2, identity, sizeof(identity));
|
||||
|
||||
|
@ -132,10 +136,7 @@ public Action OnBanClient(int client, int time, int flags, const char[] reason,
|
|||
executor = "CONSOLE";
|
||||
}
|
||||
|
||||
if(GetUserAdmin(client) != INVALID_ADMIN_ID) return Plugin_Stop;
|
||||
|
||||
GetClientIP(client, ip, sizeof(ip));
|
||||
|
||||
char query[255];
|
||||
|
||||
static char expiresDate[64];
|
||||
|
@ -162,10 +163,11 @@ public Action OnBanClient(int client, int time, int flags, const char[] reason,
|
|||
IntToString(key, strKey, sizeof(strKey));
|
||||
pendingInsertQueries.SetString(strKey, query);
|
||||
|
||||
|
||||
g_db.Format(query, sizeof(query), "SELECT `flags` FROM `bans` WHERE `expired` = 0 AND `steamid` LIKE 'STEAM_%%:%%:%s' OR ip = '%s'", identity[10], identity);
|
||||
g_db.Query(DB_OnBanPreCheck, query, key);
|
||||
|
||||
PrintToServer("Adding %N to OnBanClient queue. Key: %d", client, key);
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
|
@ -196,11 +198,13 @@ public void DB_OnBanPreCheck(Database db, DBResultSet results, const char[] erro
|
|||
} else {
|
||||
if(results.FetchRow()) {
|
||||
int flags = results.FetchInt(0);
|
||||
if(~flags & BANFLAG_SUSPENDED)
|
||||
LogMessage("Ban Pre-check: Found existing ban, ignoring ban attempt. [Query: %s]", query);
|
||||
} else {
|
||||
g_db.Query(DB_OnBanQuery, query);
|
||||
if(~flags & BANFLAG_SUSPENDED) {
|
||||
LogMessage("Ban Pre-check: Found existing non-suspended ban, ignoring ban attempt. [Query: %s]", query);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_db.Query(DB_OnBanQuery, query);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -318,6 +318,7 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
static Troll troll;
|
||||
int trollIndex = GetTroll(name, troll);
|
||||
if(trollIndex == -1) {
|
||||
ReplyToCommand(activator, "Unknown troll \"%s\"", name);
|
||||
PrintToServer("[FTT] %N attempted to apply unknown troll: %s", activator, name);
|
||||
return;
|
||||
}
|
||||
|
@ -349,17 +350,23 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
}
|
||||
}
|
||||
|
||||
bool isActive = IsTrollActive(victim, troll.name);
|
||||
|
||||
// Toggle on flags for client, if it's not a single run.
|
||||
if(modifier & TrollMod_Constant) {
|
||||
Trolls[troll.id].activeFlagClients[victim] = isActive ? -1 : flags;
|
||||
}
|
||||
|
||||
// Applies any custom logic needed for a troll, mostly only used for TrollMod_Instant
|
||||
if(!ApplyAffect(victim, troll, activator, modifier, flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Log all actions, indicating if constant or single-fire, and if any flags
|
||||
bool isActive = IsTrollActive(victim, troll.name);
|
||||
if(!silent) {
|
||||
if(isActive) {
|
||||
ShowActivityEx(activator, "[FTT] ", "deactivated \"%s\" on %N. ", troll.name, victim);
|
||||
LogAction(activator, victim, "\"%L\" deactivated \"%s\" on \"%L\"", activator, troll.name, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "deactivated {green}\"%s\"{default} on %N. ", troll.name, victim);
|
||||
LogAction(activator, victim, "\"%L\" deactivated {green}\"%s\"{default} on \"%L\"", activator, troll.name, victim);
|
||||
} else {
|
||||
static char flagName[MAX_TROLL_FLAG_LENGTH];
|
||||
flagName[0] = '\0';
|
||||
|
@ -380,29 +387,25 @@ void ApplyTroll(int victim, const char[] name, int activator, trollModifier modi
|
|||
if(modifier & TrollMod_Constant) {
|
||||
if(flags > 0) {
|
||||
if(flagName[0] != '\0') {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant \"%s\" (%s) for %N. ", troll.name, flagName, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "activated constant {green}\"%s\"{default} ({yellow}%s{default}) for %N. ", troll.name, flagName, victim);
|
||||
} else {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant \"%s\" (%d) for %N. ", troll.name, flags, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "activated constant {green}\"%s\"{default} ({yellow}%d{default}) for %N. ", troll.name, flags, victim);
|
||||
}
|
||||
} else
|
||||
ShowActivityEx(activator, "[FTT] ", "activated constant \"%s\" for %N. ", troll.name, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "activated constant {green}\"%s\"{default} for %N. ", troll.name, victim);
|
||||
} else if(flags > 0) {
|
||||
if(flagName[0] != '\0') {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated \"%s\" (%s) for %N. ", troll.name, flagName, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "activated {green}\"%s\"{default} ({yellow}%s{default}) for %N. ", troll.name, flagName, victim);
|
||||
} else {
|
||||
ShowActivityEx(activator, "[FTT] ", "activated \"%s\" (%d) for %N. ", troll.name, flags, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "activated {green}\"%s\"{default} ({yellow}%d{default}) for %N. ", troll.name, flags, victim);
|
||||
}
|
||||
} else
|
||||
ShowActivityEx(activator, "[FTT] ", "activated \"%s\" for %N. ", troll.name, victim);
|
||||
CShowActivityEx(activator, "[FTT] ", "activated {green}\"%s\"{default} for %N. ", troll.name, victim);
|
||||
|
||||
LogAction(activator, victim, "\"%L\" activated \"%s\" (%d) for \"%L\"", activator, troll.name, flags, victim);
|
||||
LogAction(activator, victim, "\"%L\" activated {green}\"%s\"{default} ({yellow}%d{default}) for \"%L\"", activator, troll.name, flags, victim);
|
||||
}
|
||||
} else {
|
||||
ReplyToCommand(activator, "ftt: Applied \"%s\" on %N with flags=%d", troll.name, victim, flags);
|
||||
}
|
||||
// Toggle on flags for client, if it's not a single run.
|
||||
if(modifier & TrollMod_Constant) {
|
||||
Trolls[troll.id].activeFlagClients[victim] = isActive ? -1 : flags;
|
||||
CReplyToCommand(activator, "ftt: Applied {green}\"%s\"{default} on %N with flags=%d", troll.name, victim, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -573,3 +573,43 @@ public Action Command_Stagger(int client, int args) {
|
|||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action Command_SmartCharge(int client, int args) {
|
||||
if(args > 0) {
|
||||
static char arg1[32], arg2[8];
|
||||
GetCmdArg(1, arg1, sizeof(arg1));
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
int timeout = StringToInt(arg2);
|
||||
if(timeout == 0) timeout = 15;
|
||||
|
||||
int target_list[1], target_count;
|
||||
static char target_name[MAX_TARGET_LENGTH];
|
||||
bool tn_is_ml;
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg1,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
COMMAND_FILTER_ALIVE | COMMAND_FILTER_NO_MULTI,
|
||||
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;
|
||||
}
|
||||
if(g_iSmartChargeActivator[target_list[0]]) {
|
||||
ReplyToCommand(client, "Target already has auto smart charge enabled");
|
||||
} else {
|
||||
g_iSmartChargeAttempts[target_list[0]] = 0;
|
||||
g_iSmartChargeMaxAttempts[target_list[0]] = timeout;
|
||||
g_iSmartChargeActivator[target_list[0]] = GetClientUserId(client);
|
||||
CreateTimer(1.0, Timer_CheckForChargerOpportunity, GetClientUserId(target_list[0]), TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
ShowActivity(client, "Enabling smart auto-charge on %N for %d seconds", target_list[0], timeout);
|
||||
}
|
||||
} else {
|
||||
ReplyToCommand(client, "syntax: sm_smartcharge <target player> [timeout or default 10s]");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
|
@ -179,7 +179,7 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
if(existingTarget > 0) {
|
||||
if(IsPlayerAlive(existingTarget)) {
|
||||
// Insta-specials ALWAYS target, if target has any attackers remaining
|
||||
if(g_iSpecialAttackFlags[attacker] & SPI_AlwaysTarget) {
|
||||
if(g_iSpecialAttackFlags[attacker] & view_as<int>(SPI_AlwaysTarget)) {
|
||||
curTarget = existingTarget;
|
||||
return Plugin_Changed;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ public Action L4D2_OnChooseVictim(int attacker, int &curTarget) {
|
|||
}
|
||||
// If found, set, else just let game decide
|
||||
if(closestClient > 0) {
|
||||
PrintToConsoleAll("[FTT/Debug] infected %N -> attack -> %N", attacker, closetClient);
|
||||
PrintToConsoleAll("[FTT/Debug] infected %N -> attack -> %N", attacker, closestClient);
|
||||
g_iAttackerTarget[attacker] = GetClientUserId(closestClient);
|
||||
curTarget = closestClient;
|
||||
return Plugin_Changed;
|
||||
|
@ -529,7 +529,7 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
if(GetClientAimTarget(client, true) == shootAtTarget[client]) {
|
||||
if(!IsActorBusy(client))
|
||||
PerformScene(client, "PlayerLaugh");
|
||||
buttons |= IN_ATTACK;
|
||||
buttons |= IN_ATTACK &~ (IN_RELOAD);
|
||||
return Plugin_Changed;
|
||||
} else {
|
||||
if(!IsClientConnected(shootAtTarget[client])) {
|
||||
|
@ -541,8 +541,6 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
}
|
||||
|
||||
// Inverted control code:
|
||||
static int invertedTrollIndex;
|
||||
if(invertedTrollIndex == 0) invertedTrollIndex = GetTrollID("Inverted Controls");
|
||||
if(Trolls[invertedTrollIndex].IsActive(client)) {
|
||||
if(buttons & IN_MOVELEFT || buttons & IN_MOVERIGHT) {
|
||||
vel[1] = -vel[1];
|
||||
|
@ -795,7 +793,7 @@ public bool TraceEntityFilterPlayer(int entity, int mask, any data) {
|
|||
|
||||
float iLastAntiRushEvent[MAXPLAYERS+1];
|
||||
public Action OnAntiRush(int client, int &type, float distance) {
|
||||
if(client && client <= MaxClients && type == 3 && IsPlayerAlive(client) && !IsPlayerIncapped(client)) {
|
||||
if(client && client > 0 && client <= MaxClients && type == 3 && IsPlayerAlive(client) && !IsPlayerIncapped(client)) {
|
||||
if(GetGameTime() - iLastAntiRushEvent[client] > 30.0) {
|
||||
SpecialType special = view_as<SpecialType>(GetRandomInt(1,6));
|
||||
iLastAntiRushEvent[client] = GetGameTime();
|
||||
|
@ -825,13 +823,17 @@ public void Event_EnteredSpit(Event event, const char[] name, bool dontBroadcast
|
|||
}
|
||||
|
||||
public void Event_BotPlayerSwap(Event event, const char[] name, bool dontBroadcast) {
|
||||
//Player replaced a bot
|
||||
//Player replaced their idle bot
|
||||
int client = GetClientOfUserId(event.GetInt("player"));
|
||||
if(client) {
|
||||
bool debug_hadTroll = false;
|
||||
for(int i = 1; i <= MAX_TROLLS; i++) {
|
||||
if(Trolls[i].IsActive(client) && Trolls[i].HasMod(TrollMod_Constant)) { //Add activeFlagClients >= 0 check possibly?
|
||||
ApplyAffect(client, Trolls[i], -1, TrollMod_Constant, Trolls[i].activeFlagClients[client]);
|
||||
debug_hadTroll = true;
|
||||
}
|
||||
}
|
||||
if(debug_hadTroll)
|
||||
PrintToServer("[FTT] Re-applied trolls for was-idle player %N", client);
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ stock bool SpawnSpecialForTarget(SpecialType specialType, int target, SpecialSpa
|
|||
}
|
||||
|
||||
// Target is optional
|
||||
stock bool SpawnSpecialAtPosition(SpecialType special, const float destination[3], const float angle[3], int target = 0, int flags) {
|
||||
stock bool SpawnSpecialAtPosition(SpecialType special, const float destination[3], const float angle[3], int target = 0, int flags = 0) {
|
||||
SpecialSpawnRequest request;
|
||||
request.type = special;
|
||||
if(target)
|
||||
|
|
|
@ -46,6 +46,10 @@ int shootAtTarget[MAXPLAYERS+1];
|
|||
int shootAtTargetLoops[MAXPLAYERS+1];
|
||||
int shootAtTargetHP[MAXPLAYERS+1];
|
||||
|
||||
int g_iSmartChargeAttempts[MAXPLAYERS+1];
|
||||
int g_iSmartChargeMaxAttempts[MAXPLAYERS+1];
|
||||
int g_iSmartChargeActivator[MAXPLAYERS+1];
|
||||
|
||||
bool spIsActive;
|
||||
enum SpecialSpawnFlags {
|
||||
Special_Anywhere = 0,
|
||||
|
|
|
@ -132,16 +132,14 @@ stock int CreateProp(const char[] entClass, const char[] model, const float pos[
|
|||
return -1;
|
||||
}
|
||||
|
||||
stock int CreateDummy(const char[] model, const float pos[3], const float ang[3]) {
|
||||
stock int CreateDummy(const char[] model, const char[] anim, const float pos[3], const float ang[3] = NULL_VECTOR) {
|
||||
int entity = StartPropCreate("commentary_dummy", model, pos, ang);
|
||||
if(entity == -1) return -1;
|
||||
DispatchKeyValue(entity, "LookAtPlayers", "Yes");
|
||||
DispatchKeyValue(entity, "StartingWeapons", "weapon_rifle_ak47");
|
||||
DispatchKeyValue(entity, "StartingAnim", "hit_by_tankpunch"); //idle_calm_rifle
|
||||
DispatchKeyValue(entity, "StartingAnim", anim); //idle_calm_rifle
|
||||
DispatchKeyValueFloat(entity, "LookAtPlayers", 40.0);
|
||||
DispatchSpawn(entity);
|
||||
SetVariantString("idle_unabletoreachtarget_01a");
|
||||
AcceptEntityInput(entity, "SetAnimation");
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
@ -188,24 +186,56 @@ stock void EntFire(const char[] name, const char[] input) {
|
|||
#endif
|
||||
int len = SplitString(input, " ", cmd, sizeof(cmd));
|
||||
if(len > -1) SetVariantString(input[len]);
|
||||
|
||||
int hammerId = name[0] == '!' ? StringToInt(name[1]) : 0;
|
||||
bool setTeam = StrEqual(cmd, "_setteam");
|
||||
for(int i = MaxClients + 1; i <= 4096; i++) {
|
||||
if(IsValidEntity(i) && (IsValidEdict(i) || EntIndexToEntRef(i) != -1)) {
|
||||
GetEntPropString(i, Prop_Data, "m_iName", targetname, sizeof(targetname));
|
||||
if(StrEqual(targetname, name, false)) {
|
||||
if(len > -1) AcceptEntityInput(i, cmd);
|
||||
else AcceptEntityInput(i, input);
|
||||
} /*else {
|
||||
GetEntityClassname(targetname, sizeof(targetname));
|
||||
if(StrEqual(targetname, name, false)) {
|
||||
if(len > -1) AcceptEntityInput(i, cmd);
|
||||
if(hammerId > 0) {
|
||||
if(hammerId == GetHammerId(i)) {
|
||||
if(setTeam) {
|
||||
SDKHook(i, SDKHook_TraceAttackPost, Hook_OnAttackPost);
|
||||
SetEntProp(i, Prop_Send, "m_iTeamNum", 0);
|
||||
} else if(len > -1) AcceptEntityInput(i, cmd);
|
||||
else AcceptEntityInput(i, input);
|
||||
}
|
||||
}*/
|
||||
} else {
|
||||
GetEntPropString(i, Prop_Data, "m_iName", targetname, sizeof(targetname));
|
||||
if(StrEqual(targetname, name, false)) {
|
||||
if(setTeam) {
|
||||
SDKHook(i, SDKHook_TraceAttackPost, Hook_OnAttackPost);
|
||||
SetEntProp(i, Prop_Send, "m_iTeamNum", 0);
|
||||
} else if(len > -1) AcceptEntityInput(i, cmd);
|
||||
else AcceptEntityInput(i, input);
|
||||
|
||||
} else {
|
||||
GetEntityClassname(i, targetname, sizeof(targetname));
|
||||
if(StrEqual(targetname, name, false)) {
|
||||
if(len > -1) AcceptEntityInput(i, cmd);
|
||||
else AcceptEntityInput(i, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GetHammerId(int entity) {
|
||||
return HasEntProp(entity, Prop_Data, "m_iHammerID") ? GetEntProp(entity, Prop_Data, "m_iHammerID") : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SetupEntities(bool blockers = true, bool props = true, bool portals = true) {
|
||||
#if defined DEBUG_BLOCKERS
|
||||
if(mapConfig.hasSpawnpoint) {
|
||||
PrecacheModel("survivors/survivor_teenangst.mdl", true);
|
||||
int dummy = CreateDummy("models/survivors/survivor_teenangst.mdl", "idle", mapConfig.spawnpoint, NULL_VECTOR);
|
||||
SetEntProp(dummy, Prop_Data, "m_nSolidType", 0);
|
||||
SetEntProp(dummy, Prop_Send, "m_CollisionGroup", 0);
|
||||
SetEntProp(dummy, Prop_Send, "movetype", MOVETYPE_NONE);
|
||||
}
|
||||
#endif
|
||||
if(mapConfig.entities != null) {
|
||||
PrintToServer("[H&S] Deploying %d custom entities (Set: %s) (blockers:%b props:%b portals:%b)", mapConfig.entities.Length, currentSet, blockers, props, portals);
|
||||
for(int i = 0; i < mapConfig.entities.Length; i++) {
|
||||
|
@ -243,7 +273,7 @@ void SetupEntities(bool blockers = true, bool props = true, bool portals = true)
|
|||
}
|
||||
}
|
||||
} else if(StrEqual(config.type, "_dummy")) {
|
||||
if(CreateDummy(config.model, config.origin, config.rotation) == -1) {
|
||||
if(CreateDummy(config.model, "hitby_tankpunch", config.origin, config.rotation) == -1) {
|
||||
PrintToServer("[H&S:WARN] Failed to spawn dummy [model=%s] at (%.1f,%.1f, %.1f)", config.model, config.origin[0], config.origin[1], config.origin[2]);
|
||||
}
|
||||
}else if(props) {
|
||||
|
|
|
@ -628,3 +628,32 @@ stock int GetRealClient(int client) {
|
|||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
stock int FindIdleBot(int client) {
|
||||
for(int i = 1; i <= MaxClients; i++ ) {
|
||||
if(IsClientConnected(i) && HasEntProp(i, Prop_Send, "m_humanSpectatorUserID")) {
|
||||
int realPlayer = GetClientOfUserId(GetEntProp(i, Prop_Send, "m_humanSpectatorUserID"));
|
||||
if(realPlayer == client) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
stock void SetParent(int child, int parent) {
|
||||
SetVariantString("!activator");
|
||||
AcceptEntityInput(child, "SetParent", parent);
|
||||
}
|
||||
|
||||
stock void SetParentAttachment(int child, const char[] attachment, bool withOffset = false) {
|
||||
SetVariantString(attachment);
|
||||
if(withOffset)
|
||||
AcceptEntityInput(child, "SetParentAttachmentMaintainOffset");
|
||||
else
|
||||
AcceptEntityInput(child, "SetParentAttachment");
|
||||
}
|
||||
|
||||
stock void ClearParent(int child) {
|
||||
AcceptEntityInput(child, "ClearParent");
|
||||
}
|
|
@ -58,16 +58,16 @@
|
|||
|
||||
|
||||
|
||||
// Natives: 222
|
||||
// Natives: 226
|
||||
// L4D1 = 29 [left4downtown] + 47 [l4d_direct] + 15 [l4d2addresses] + 43 [silvers - mine!] + 4 [anim] = 132
|
||||
// L4D2 = 59 [left4downtown] + 61 [l4d_direct] + 26 [l4d2addresses] + 75 [silvers - mine!] + 4 [anim] = 219
|
||||
// L4D2 = 59 [left4downtown] + 61 [l4d_direct] + 26 [l4d2addresses] + 79 [silvers - mine!] + 4 [anim] = 223
|
||||
|
||||
// Forwards: 117
|
||||
// L4D1 = 85;
|
||||
// L4D2 = 115;
|
||||
// Forwards: 144
|
||||
// L4D1 = 109;
|
||||
// L4D2 = 142;
|
||||
|
||||
// Stocks: 157 (L4D1 = 107, L4D2 = 153)
|
||||
// left4dhooks_silver 40 stocks (L4D1 = 33, L4D2 = 40)
|
||||
// left4dhooks_silver 41 stocks (L4D1 = 34, L4D2 = 41)
|
||||
// left4dhooks_stocks 83 stocks (L4D1 = 44, L4D2 = 79)
|
||||
// left4dhooks_lux_library 34 stocks (L4D1 = 30, L4D2 = 34)
|
||||
|
||||
|
@ -327,6 +327,10 @@ public void __pl_l4dh_SetNTVOptional()
|
|||
// l4d2addresses.txt
|
||||
// =========================
|
||||
MarkNativeAsOptional("L4D_CTerrorPlayer_OnVomitedUpon");
|
||||
MarkNativeAsOptional("L4D2_Charger_ThrowImpactedSurvivor");
|
||||
MarkNativeAsOptional("L4D2_Charger_StartCarryingVictim");
|
||||
MarkNativeAsOptional("L4D2_Charger_PummelVictim");
|
||||
MarkNativeAsOptional("L4D2_Charger_EndPummel");
|
||||
MarkNativeAsOptional("L4D_CancelStagger");
|
||||
MarkNativeAsOptional("L4D_CreateRescuableSurvivors");
|
||||
MarkNativeAsOptional("L4D_ReviveSurvivor");
|
||||
|
@ -541,6 +545,21 @@ forward Action L4D_OnSpawnSpecial(int &zombieClass, const float vecPos[3], const
|
|||
*/
|
||||
forward void L4D_OnSpawnSpecial_Post(int client, int zombieClass, const float vecPos[3], const float vecAng[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnSpecial(ZombieClassType,Vector&,QAngle&) is invoked
|
||||
* @remarks Only used for bot special spawns (not players)
|
||||
* @remarks zombieClass: 1=Smoker, 2=Boomer, 3=Hunter, 4=Spitter, 5=Jockey, 6=Charger
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client The client index who spawned. Can be 0 if spawning failed
|
||||
* @param zombieClass Zombie class that will be spawned
|
||||
* @param vecPos Vector coordinate where special will be spawned
|
||||
* @param vecAng QAngle where special will be facing
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnSpawnSpecial_PostHandled(int client, int zombieClass, const float vecPos[3], const float vecAng[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnTank(Vector&,QAngle&) is invoked
|
||||
* @remarks Not invoked if z_spawn tank is used and it gives a ghosted/dead player tank
|
||||
|
@ -565,6 +584,19 @@ forward Action L4D_OnSpawnTank(const float vecPos[3], const float vecAng[3]);
|
|||
*/
|
||||
forward void L4D_OnSpawnTank_Post(int client, const float vecPos[3], const float vecAng[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnTank(Vector&,QAngle&) is invoked
|
||||
* @remarks Not invoked if z_spawn tank is used and it gives a ghosted/dead player tank
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client The client index who spawned (can be 0 if blocked in pre hook)
|
||||
* @param vecPos Vector coordinate where tank is spawned
|
||||
* @param vecAng QAngle where tank will be facing
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnSpawnTank_PostHandled(int client, const float vecPos[3], const float vecAng[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnWitch(Vector&,QAngle&) is invoked
|
||||
* @brief Called when a Witch spawns
|
||||
|
@ -589,6 +621,19 @@ forward Action L4D_OnSpawnWitch(const float vecPos[3], const float vecAng[3]);
|
|||
*/
|
||||
forward void L4D_OnSpawnWitch_Post(int entity, const float vecPos[3], const float vecAng[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnWitch(Vector&,QAngle&) is invoked
|
||||
* @brief Called when a Witch spawns
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param entity Entity index that spawned
|
||||
* @param vecPos Vector coordinate where witch is spawned
|
||||
* @param vecAng QAngle where witch will be facing
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnSpawnWitch_PostHandled(int entity, const float vecPos[3], const float vecAng[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnWitchBride(Vector&,QAngle&) is invoked
|
||||
* @brief Called when a Witch Bride spawns
|
||||
|
@ -637,6 +682,17 @@ forward Action L4D_OnMobRushStart();
|
|||
*/
|
||||
forward void L4D_OnMobRushStart_Post();
|
||||
|
||||
/**
|
||||
* @brief Called whenever CDirector::OnMobRushStart(void) is invoked
|
||||
* @remarks called on random hordes, mini and finale hordes, and boomer hordes, causes Zombies to attack
|
||||
* Not called on "z_spawn mob", hook the console command and check arguments to catch plugin mobs
|
||||
* This function is used to reset the Director's natural horde timer.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnMobRushStart_PostHandled();
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnITMob(int) is invoked
|
||||
* @remarks called on boomer hordes, increases Zombie Spawn Queue
|
||||
|
@ -659,6 +715,17 @@ forward Action L4D_OnSpawnITMob(int &amount);
|
|||
*/
|
||||
forward void L4D_OnSpawnITMob_Post(int amount);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnITMob(int) is invoked
|
||||
* @remarks called on boomer hordes, increases Zombie Spawn Queue
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param amount Amount of Zombies to add to Queue
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnSpawnITMob_PostHandled(int amount);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnMob(int) is invoked
|
||||
* @remarks called on natural hordes & z_spawn mob, increases Zombie Spawn
|
||||
|
@ -684,6 +751,19 @@ forward Action L4D_OnSpawnMob(int &amount);
|
|||
*/
|
||||
forward void L4D_OnSpawnMob_Post(int amount);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::SpawnMob(int) is invoked
|
||||
* @remarks called on natural hordes & z_spawn mob, increases Zombie Spawn
|
||||
* Queue, triggers player OnMobSpawned (vocalizations), sets horde
|
||||
* direction, and plays horde music.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param amount Amount of Zombies to add to Queue
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnSpawnMob_PostHandled(int amount);
|
||||
|
||||
/**
|
||||
* @brief Called when a witch has been startled by someone
|
||||
*
|
||||
|
@ -736,6 +816,17 @@ forward Action L4D_OnEnterGhostStatePre(int client);
|
|||
*/
|
||||
forward void L4D_OnEnterGhostState(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnEnterGhostState(CTerrorPlayer*) is invoked
|
||||
* @remarks This happens when a player enters ghost mode (or in finales auto-materialized)
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client the client that has entered ghost mode
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnEnterGhostState_PostHandled(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::MaterializeFromGhost is invoked
|
||||
* @remarks Called when a Special Infected spawns out of ghost mode.
|
||||
|
@ -757,6 +848,17 @@ forward Action L4D_OnMaterializeFromGhostPre(int client);
|
|||
*/
|
||||
forward void L4D_OnMaterializeFromGhost(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::MaterializeFromGhost is invoked
|
||||
* @remarks Called when a Special Infected spawns out of ghost mode.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param victim the client who spawned
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnMaterializeFromGhost_PostHandled(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever IsTeamFull is invoked.
|
||||
* @remarks called when bots or players are joining a team
|
||||
|
@ -841,6 +943,18 @@ forward Action L4D_OnFirstSurvivorLeftSafeArea(int client);
|
|||
*/
|
||||
forward void L4D_OnFirstSurvivorLeftSafeArea_Post(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CDirector::OnFirstSurvivorLeftSafeArea is invoked
|
||||
* @remarks A versus round is started when survivors leave the safe room, or force started
|
||||
* after 90 seconds regardless.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client the survivor that left the safe area first
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnFirstSurvivorLeftSafeArea_PostHandled(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::GetCrouchTopSpeed() is invoked
|
||||
* @remarks Constantly called to get players max Crouch speed
|
||||
|
@ -982,6 +1096,20 @@ forward Action L4D_OnGetMissionVSBossSpawning(float &spawn_pos_min, float &spawn
|
|||
*/
|
||||
forward void L4D_OnGetMissionVSBossSpawning_Post(float spawn_pos_min, float spawn_pos_max, float tank_chance, float witch_chance);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CDirectorVersusMode::GetMissionVersusBossSpawning() is invoked
|
||||
* @remarks Passed values are from the map's Mission Keyvalues. If those keyvalues don't exist, they are from cvar and other globals
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param spawn_pos_min Minimum spawn position (percent of flow distance) for bosses
|
||||
* @param spawn_pos_max Maximum spawn position (percent of flow distance) for bosses
|
||||
* @param tank_chance Chance for a tank to spawn on this map
|
||||
* @param witch_chance Chance for a witch to spawn on this map
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnGetMissionVSBossSpawning_PostHandled(float spawn_pos_min, float spawn_pos_max, float tank_chance, float witch_chance);
|
||||
|
||||
/**
|
||||
* @brief Called whenever ZombieManager::ReplaceTank(CTerrorPlayer *,CTerrorPlayer *) is invoked
|
||||
* @remarks Not invoked if tank is bot
|
||||
|
@ -998,7 +1126,7 @@ forward void L4D_OnReplaceTank(int tank, int newtank);
|
|||
* @remarks When a tank is swinging to punch.
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param claw the claw entity index
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -1009,7 +1137,7 @@ forward void L4D_TankClaw_DoSwing_Pre(int tank, int claw);
|
|||
* @remarks When a tank is swinging to punch.
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param claw the claw entity index
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -1022,7 +1150,7 @@ forward void L4D_TankClaw_DoSwing_Post(int tank, int claw);
|
|||
* @remarks The forwards "L4D_TankClaw_DoSwing_Pre" and "L4D_TankClaw_DoSwing_Post" can trigger after this
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param claw the claw entity index
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -1036,7 +1164,7 @@ forward void L4D_TankClaw_GroundPound_Pre(int tank, int claw);
|
|||
* @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param claw the claw entity index
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -1047,7 +1175,8 @@ forward void L4D_TankClaw_GroundPound_Post(int tank, int claw);
|
|||
* @remarks When a tank swings and punches a player.
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param claw the claw entity index
|
||||
* @param player the player being hit
|
||||
*
|
||||
* @return Plugin_Handled to block the target player from being stumbled, Plugin_Continue otherwise.
|
||||
*/
|
||||
|
@ -1059,13 +1188,26 @@ forward Action L4D_TankClaw_OnPlayerHit_Pre(int tank, int claw, int player);
|
|||
* @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param claw the claw entity index
|
||||
* @param player the player being hit
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_TankClaw_OnPlayerHit_Post(int tank, int claw, int player);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTankClaw::OnPlayerHit(CTerrorPlayer*, bool) is invoked
|
||||
* @remarks When a tank swings and punches a player.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param tank tank client index
|
||||
* @param rock the claw entity index
|
||||
* @param player the player being hit
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_TankClaw_OnPlayerHit_PostHandled(int tank, int claw, int player);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTankRock::Detonate() is invoked
|
||||
* @remarks When a tank rock hits something and explodes.
|
||||
|
@ -1106,7 +1248,7 @@ forward Action L4D_TankRock_OnRelease(int tank, int rock, float vecPos[3], float
|
|||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_TankRock_OnRelease_Post(int tank, int rock, float vecPos[3], float vecAng[3], float vecVel[3], float vecRot[3]);
|
||||
forward void L4D_TankRock_OnRelease_Post(int tank, int rock, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CDirector::TryOfferingTankBot is invoked
|
||||
|
@ -1131,6 +1273,18 @@ forward Action L4D_OnTryOfferingTankBot(int tank_index, bool &enterStasis);
|
|||
*/
|
||||
forward void L4D_OnTryOfferingTankBot_Post(int tank_index, bool enterStasis);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CDirector::TryOfferingTankBot is invoked
|
||||
* @remarks Is used for displaying the "X gets Tank" window and transferring Tank control
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param tank_index Client index of the tank
|
||||
* @param enterStasis Is the tank in stasis
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnTryOfferingTankBot_PostHandled(int tank_index, bool enterStasis);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CThrow::ActivateAbility(void) is invoked
|
||||
* @remarks Called when a tank throws a rock. Blocking this call will keep the tank from throwing a rock
|
||||
|
@ -1152,6 +1306,17 @@ forward Action L4D_OnCThrowActivate(int ability);
|
|||
*/
|
||||
forward void L4D_OnCThrowActivate_Post(int ability);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CThrow::ActivateAbility(void) is invoked
|
||||
* @remarks Called when a tank throws a rock. Blocking this call will keep the tank from throwing a rock
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param ability ability_throw entity index
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnCThrowActivate_PostHandled(int ability);
|
||||
|
||||
/**
|
||||
* @brief Called when CBaseAnimating::SelectWeightedSequence(int Activity) is invoked with tank attack activity
|
||||
* @remarks Called whenever a tank uses his primary (punch) or secondary (throw) attack (uses ACT_* activity numbers)
|
||||
|
@ -1296,6 +1461,16 @@ forward Action L4D2_OnEndVersusModeRound(bool countSurvivors);
|
|||
*/
|
||||
forward void L4D2_OnEndVersusModeRound_Post();
|
||||
|
||||
/**
|
||||
* @brief Called after CDirectorVersusMode::EndVersusModeRound(bool)
|
||||
* @remarks Called after all score calculations are complete and the scoreboard shows
|
||||
* @remarks Called after all score calculations inside CDirectorVersusMode::EndVersusModeRound(bool). This good forward to replace standard "round_end" hook.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D2_OnEndVersusModeRound_PostHandled();
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnLedgeGrabbed(CTerrorPlayer *this, const Vector *) is invoked
|
||||
* @remarks Called when a player is about to grab a ledge
|
||||
|
@ -1317,6 +1492,17 @@ forward Action L4D_OnLedgeGrabbed(int client);
|
|||
*/
|
||||
forward void L4D_OnLedgeGrabbed_Post(int client);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnLedgeGrabbed(CTerrorPlayer *this, const Vector *) is invoked
|
||||
* @remarks Called when a player is about to grab a ledge
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client client grabbing the ledge
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnLedgeGrabbed_PostHandled(int client);
|
||||
|
||||
/**
|
||||
* @brief Called when CTerrorPlayer::OnRevived(void) is invoked
|
||||
* @remarks Called post-revive so all data values are post-revive status.
|
||||
|
@ -1354,7 +1540,6 @@ forward Action L4D_OnShovedBySurvivor(int client, int victim, const float vecDir
|
|||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnShovedBySurvivor(CTerrorPlayer, Vector&) is invoked
|
||||
* @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
* @remarks L4D2 only uses this on Special Infected
|
||||
* @remarks Blocks hunter dead stop
|
||||
* @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
|
@ -1367,6 +1552,20 @@ forward Action L4D_OnShovedBySurvivor(int client, int victim, const float vecDir
|
|||
*/
|
||||
forward void L4D_OnShovedBySurvivor_Post(int client, int victim, const float vecDir[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnShovedBySurvivor(CTerrorPlayer, Vector&) is invoked
|
||||
* @remarks L4D2 only uses this on Special Infected
|
||||
* @remarks Blocks hunter dead stop
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client the client that did the shoving
|
||||
* @param victim the client that was shoved (CAUTION retrieved from function pointer, don't meddle with it)
|
||||
* @param vecDir Vector Angle of Shoveforce
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnShovedBySurvivor_PostHandled(int client, int victim, const float vecDir[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorWeapon::OnHit(CGameTrace &, Vector const&, bool) is invoked
|
||||
* @remarks Called for every single shovable and even some of the unshovable entities in the game
|
||||
|
@ -1396,7 +1595,23 @@ forward Action L4D2_OnEntityShoved(int client, int entity, int weapon, float vec
|
|||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D2_OnEntityShoved_Post(int client, int entity, int weapon, float vecDir[3], bool bIsHighPounce);
|
||||
forward void L4D2_OnEntityShoved_Post(int client, int entity, int weapon, const float vecDir[3], bool bIsHighPounce);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorWeapon::OnHit(CGameTrace &, Vector const&, bool) is invoked
|
||||
* @remarks Called for every single shovable and even some of the unshovable entities in the game
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client survivor who did the shoving
|
||||
* @param entity entity that is about to get shoved
|
||||
* @param weapon weapon that has been held while shoving
|
||||
* @param vecDir stagger direction
|
||||
* @param bIsHighPounce a boolean to determine if it was a pounce from a height or not; reliable to a certain degree and should only be considered for hunters
|
||||
* @param bIsHighPounce sometimes reset to 0 when punched before the detour retrieves the information.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D2_OnEntityShoved_PostHandled(int client, int entity, int weapon, const float vecDir[3], bool bIsHighPounce);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnStaggered(CBaseEntity *, Vector const *) is invoked
|
||||
|
@ -1421,6 +1636,18 @@ forward Action L4D2_OnStagger(int target, int source);
|
|||
*/
|
||||
forward void L4D2_OnStagger_Post(int target, int source);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnStaggered(CBaseEntity *, Vector const *) is invoked
|
||||
* @remarks Source is always null for Charger impacts (Valve)
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param target the client that is about to get staggered
|
||||
* @param source the client that is about to stagger the target
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D2_OnStagger_PostHandled(int target, int source);
|
||||
|
||||
/**
|
||||
* @brief Called when CTerrorPlayer::Fling(Vector const&, PlayerAnimEvent_t, CBaseCombatCharacter*, float) is invoked.
|
||||
* @remarks Called when a player is flung to the ground.
|
||||
|
@ -1447,7 +1674,22 @@ forward Action L4D2_OnPlayerFling(int client, int attacker, float vecDir[3]);
|
|||
* @noreturn
|
||||
**/
|
||||
// L4D2 only.
|
||||
forward void L4D2_OnPlayerFling_Post(int client, int attacker, float vecDir[3]);
|
||||
forward void L4D2_OnPlayerFling_Post(int client, int attacker, const float vecDir[3]);
|
||||
|
||||
/**
|
||||
* @brief Called when CTerrorPlayer::Fling(Vector const&, PlayerAnimEvent_t, CBaseCombatCharacter*, float) is invoked.
|
||||
* @remarks Called when a player is flung to the ground.
|
||||
* @remarks This will not trigger if the fling is being blocked by other plugins
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client Client index of the player.
|
||||
* @param attacker Client index of the attacker.
|
||||
* @param vecDir Vector direction of the fling.
|
||||
*
|
||||
* @noreturn
|
||||
**/
|
||||
// L4D2 only.
|
||||
forward void L4D2_OnPlayerFling_PostHandled(int client, int attacker, const float vecDir[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnShovedByPounceLanding(CTerrorPlayer*) is invoked
|
||||
|
@ -1471,6 +1713,17 @@ forward Action L4D2_OnPounceOrLeapStumble(int victim, int attacker);
|
|||
*/
|
||||
forward void L4D2_OnPounceOrLeapStumble_Post(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnShovedByPounceLanding(CTerrorPlayer*) is invoked
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param victim the survivor that is about to get stumbled as a result of "attacker" capping someone in close proximity
|
||||
* @param attacker the SI that is about to cause a stumble as a result of capping someone in close proximity to a survivor
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D2_OnPounceOrLeapStumble_PostHandled(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Called when CTerrorPlayer::OnKnockedDown(CTerrorPlayer*) is invoked.
|
||||
* @remarks Called when someone is about to be hit by a Tank rock or lunged by a Hunter
|
||||
|
@ -1497,6 +1750,19 @@ forward Action L4D_OnKnockedDown(int client, int reason);
|
|||
**/
|
||||
forward void L4D_OnKnockedDown_Post(int client, int reason);
|
||||
|
||||
/**
|
||||
* @brief Called when CTerrorPlayer::OnKnockedDown(CTerrorPlayer*) is invoked.
|
||||
* @remarks Called when someone is about to be hit by a Tank rock or lunged by a Hunter
|
||||
* @remarks Called multiple times when someone is about to be has been pounced by a Hunter
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param victim Client index of the victim.
|
||||
* @param reason The Knockdown reason type. 1=Hunter lunge, 2=Tank rock.
|
||||
*
|
||||
* @noreturn
|
||||
**/
|
||||
forward void L4D_OnKnockedDown_PostHandled(int client, int reason);
|
||||
|
||||
/**
|
||||
* @brief Called when ThrowImpactedSurvivor(CTerrorPlayer *, CTerrorPlayer *, float, bool) is invoked.
|
||||
* @remarks Called when a player is about to be flung by a Charger impact.
|
||||
|
@ -1522,6 +1788,19 @@ forward Action L4D2_OnThrowImpactedSurvivor(int attacker, int victim);
|
|||
// L4D2 only.
|
||||
forward void L4D2_OnThrowImpactedSurvivor_Post(int attacker, int victim);
|
||||
|
||||
/**
|
||||
* @brief Called when ThrowImpactedSurvivor(CTerrorPlayer *, CTerrorPlayer *, float, bool) is invoked.
|
||||
* @remarks Called when a player is flung by a Charger impact.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param attacker Client index of the attacker.
|
||||
* @param victim Client index of the victim.
|
||||
*
|
||||
* @noreturn
|
||||
**/
|
||||
// L4D2 only.
|
||||
forward void L4D2_OnThrowImpactedSurvivor_PostHandled(int attacker, int victim);
|
||||
|
||||
/**
|
||||
* @brief Called when CDeathFallCamera::Enable(CBasePlayer*) is invoked.
|
||||
* @remarks Called when a player is falling in a fatal zone.
|
||||
|
@ -1529,6 +1808,7 @@ forward void L4D2_OnThrowImpactedSurvivor_Post(int attacker, int victim);
|
|||
* @remarks Use this forward to check if the current map has death fall cameras (fatal falls).
|
||||
*
|
||||
* @param client Client index of the player.
|
||||
* @param camera Death fall camera index.
|
||||
*
|
||||
* @return Plugin_Handled to block the death fall camera, Plugin_Continue to allow.
|
||||
**/
|
||||
|
@ -1614,6 +1894,18 @@ forward Action L4D_OnPouncedOnSurvivor(int victim, int attacker);
|
|||
*/
|
||||
forward void L4D_OnPouncedOnSurvivor_Post(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnPouncedOnSurvivor() is invoked
|
||||
* @remarks Called when a Survivor player is about to be pounced on by a Hunter
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param victim the client who's being pounced
|
||||
* @param attacker the Hunter pouncing on someone
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnPouncedOnSurvivor_PostHandled(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::Extinguish() is invoked
|
||||
* @remarks Called when a player (Survivor or Special Infected) is about to be extinguished
|
||||
|
@ -1647,6 +1939,18 @@ forward Action L4D_OnGrabWithTongue(int victim, int attacker);
|
|||
*/
|
||||
forward void L4D_OnGrabWithTongue_Post(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::GrabVictimWithTongue() is invoked
|
||||
* @remarks Called when a Survivor player is grabbed by a Smoker
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param victim the client who's being grabbed
|
||||
* @param attacker the Smoker grabbing someone
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnGrabWithTongue_PostHandled(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnLeptOnSurvivor() is invoked
|
||||
* @remarks Called when a Survivor player is about to be ridden by a Jockey
|
||||
|
@ -1727,6 +2031,19 @@ forward Action L4D2_OnPummelVictim(int attacker, int victim);
|
|||
// L4D2 only.
|
||||
forward void L4D2_OnPummelVictim_Post(int attacker, int victim);
|
||||
|
||||
/**
|
||||
* @brief Called when CTerrorPlayer::QueuePummelVictim is invoked.
|
||||
* @remarks Called when a player is about to be pummelled by a Charger.
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param attacker Client index of the attacker.
|
||||
* @param victim Client index of the victim.
|
||||
*
|
||||
* @noreturn
|
||||
**/
|
||||
// L4D2 only.
|
||||
forward void L4D2_OnPummelVictim_PostHandled(int attacker, int victim);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnVomitedUpon is invoked
|
||||
* @remarks Called when a Survivor player is covered in Boomer bile, or when using "Bile the World" plugin by "AtomicStryker"
|
||||
|
@ -1752,6 +2069,19 @@ forward Action L4D_OnVomitedUpon(int victim, int &attacker, bool &boomerExplosio
|
|||
*/
|
||||
forward void L4D_OnVomitedUpon_Post(int victim, int attacker, bool boomerExplosion);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnVomitedUpon is invoked
|
||||
* @remarks Called when a Survivor player is covered in Boomer bile, or when using "Bile the World" plugin by "AtomicStryker"
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param victim the client who's now it
|
||||
* @param attacker the attacker who caused the vomit (can be 0)
|
||||
* @param boomerExplosion true if triggered by a boommer explosion
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_OnVomitedUpon_PostHandled(int victim, int attacker, bool boomerExplosion);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CTerrorPlayer::OnHitByVomitJar is invoked
|
||||
* @remarks Called when a Special Infected is about to be hit from a Bilejar explosion
|
||||
|
@ -1805,7 +2135,23 @@ forward Action L4D_PipeBombProjectile_Pre(int client, float vecPos[3], float vec
|
|||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_PipeBombProjectile_Post(int client, int projectile, float vecPos[3], float vecAng[3], float vecVel[3], float vecRot[3]);
|
||||
forward void L4D_PipeBombProjectile_Post(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CPipeBombProjectile::Create is invoked
|
||||
* @remarks Called when a PipeBomb projectile has been created
|
||||
* @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled
|
||||
*
|
||||
* @param client the client who is throwing the grenade (can be 0)
|
||||
* @param projectile the projectile entity index (can be 0 if blocked in the pre hook)
|
||||
* @param vecPos the position vector of the projectile
|
||||
* @param vecAng the angle vector of the projectile
|
||||
* @param vecVel the velocity vector of the projectile
|
||||
* @param vecRot the rotation vector of the projectile
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward void L4D_PipeBombProjectile_PostHandled(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]);
|
||||
|
||||
/**
|
||||
* @brief Called whenever CInsectSwarm::CanHarm() is invoked
|
||||
|
@ -2211,7 +2557,7 @@ native bool L4D_GetRandomPZSpawnPosition(int client, int zombieClass, int attemp
|
|||
*
|
||||
* @return The NavArea value, or 0 on failure probably
|
||||
*/
|
||||
native int L4D_GetNearestNavArea(const float vecPos[3]);
|
||||
native any L4D_GetNearestNavArea(const float vecPos[3]);
|
||||
|
||||
/**
|
||||
* @brief Returns the nav address of the last known area.
|
||||
|
@ -2220,7 +2566,7 @@ native int L4D_GetNearestNavArea(const float vecPos[3]);
|
|||
*
|
||||
* @return The nav area adress or 0 on fail
|
||||
*/
|
||||
native int L4D_GetLastKnownArea(int client);
|
||||
native any L4D_GetLastKnownArea(int client);
|
||||
|
||||
/**
|
||||
* @brief Gets the maximum flow distance any survivor has achieved.
|
||||
|
@ -2446,7 +2792,7 @@ native void L4D2_UseAdrenaline(int client, float fTime = 15.0, bool heal = true)
|
|||
* @remarks Resets players stats for kills etc.
|
||||
* @remarks To preserve stats please view the code in "[L4D1 & L4D2] SM Respawn Improved" plugin by "Dragokas": https://forums.alliedmods.net/showthread.php?t=323220
|
||||
*
|
||||
* @param client Client ID of the person to affect
|
||||
* @param client Client ID of the person to respawn
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -2455,20 +2801,27 @@ native void L4D_RespawnPlayer(int client);
|
|||
/**
|
||||
* @brief To takeover a Survivor bot. First use "ChangeClientTeam" and change them to 0. Then call "L4D_SetHumanSpec" then call "L4D_TakeOverBot".
|
||||
*
|
||||
* @param bot Bot ID of the person to set spectator
|
||||
* @param client Client ID of the spectator
|
||||
*
|
||||
* @return True or false
|
||||
*/
|
||||
native int L4D_SetHumanSpec(int bot, int client);
|
||||
native bool L4D_SetHumanSpec(int bot, int client);
|
||||
|
||||
/**
|
||||
* @brief To takeover a Survivor bot. First use "ChangeClientTeam" and change them to 0. Then call "L4D_SetHumanSpec" then call "L4D_TakeOverBot".
|
||||
*
|
||||
* @param client Client ID of who should takeover
|
||||
*
|
||||
* @return True or false
|
||||
*/
|
||||
native int L4D_TakeOverBot(int client);
|
||||
native bool L4D_TakeOverBot(int client);
|
||||
|
||||
/**
|
||||
* @brief Returns true when the "You will enter Spawn Mode in X seconds" text appears on the screen.
|
||||
*
|
||||
* @param client Client ID to check
|
||||
*
|
||||
* @return True or false
|
||||
*/
|
||||
native bool L4D_CanBecomeGhost(int client);
|
||||
|
@ -2497,7 +2850,7 @@ native bool L4D_IsFinaleEscapeInProgress();
|
|||
* @return finaleType stage value
|
||||
*/
|
||||
// L4D2 only.
|
||||
native int L4D2_GetCurrentFinaleStage();
|
||||
native any L4D2_GetCurrentFinaleStage();
|
||||
|
||||
/**
|
||||
* @brief Forces the ScriptedMode stage to advance to the next stage.
|
||||
|
@ -2631,6 +2984,7 @@ native bool L4D_IsVersusMode();
|
|||
|
||||
|
||||
|
||||
|
||||
// ====================================================================================================
|
||||
// NATIVES - Silvers - VSCRIPT WRAPPERS
|
||||
// ====================================================================================================
|
||||
|
@ -2651,6 +3005,7 @@ native int L4D2_VScriptWrapper_GetMapNumber();
|
|||
* @remarks Team 3 returns true when hurt by Common Infected.
|
||||
*
|
||||
* @param client Client to test
|
||||
* @param team Team to test
|
||||
*
|
||||
* @return Number of maps played
|
||||
*/
|
||||
|
@ -2668,6 +3023,8 @@ native float L4D2_VScriptWrapper_GetAliveDuration(int client);
|
|||
/**
|
||||
* @brief Returns true when a player is dead and can spectate others.
|
||||
*
|
||||
* @param client Client to test
|
||||
*
|
||||
* @return True if dead, false if not or script error.
|
||||
*/
|
||||
// L4D2 only.
|
||||
|
@ -2716,12 +3073,12 @@ native bool L4D2_VScriptWrapper_ReviveFromIncap(int client);
|
|||
/**
|
||||
* @brief Get the current bits for the bot sense flags: BOT_CANT_SEE, BOT_CANT_HEAR, BOT_CANT_FEEL.
|
||||
*
|
||||
* @param client Bot to check
|
||||
* @param bot Bot to check
|
||||
*
|
||||
* @return Current sense flags
|
||||
*/
|
||||
// L4D2 only.
|
||||
native int L4D2_VScriptWrapper_GetSenseFlags(int client);
|
||||
native any L4D2_VScriptWrapper_GetSenseFlags(int bot);
|
||||
|
||||
/**
|
||||
* @brief Test two vector positions if they can be reached (only returns false if a location has no valid NavArea, out-of-bounds can be valid).
|
||||
|
@ -2729,7 +3086,7 @@ native int L4D2_VScriptWrapper_GetSenseFlags(int client);
|
|||
* @return Returns true if a path exists, false if not or on script error.
|
||||
*/
|
||||
// L4D2 only.
|
||||
native bool L4D2_VScriptWrapper_NavAreaBuildPath(float startPos[3], float endPos[3], float flMaxPathLength, bool checkLOS, bool checkGround, int teamID, bool ignoreNavBlockers);
|
||||
native bool L4D2_VScriptWrapper_NavAreaBuildPath(const float startPos[3], const float endPos[3], float flMaxPathLength, bool checkLOS, bool checkGround, int teamID, bool ignoreNavBlockers);
|
||||
|
||||
/**
|
||||
* @brief Compute distance between two areas.
|
||||
|
@ -2738,7 +3095,7 @@ native bool L4D2_VScriptWrapper_NavAreaBuildPath(float startPos[3], float endPos
|
|||
*/
|
||||
// L4D2 only.
|
||||
// Added as a demonstration and test, SDKCall is available, use "L4D2_NavAreaTravelDistance" instead.
|
||||
native float L4D2_VScriptWrapper_NavAreaTravelDistance(float startPos[3], float endPos[3], float flMaxPathLength, bool checkLOS, bool checkGround);
|
||||
native float L4D2_VScriptWrapper_NavAreaTravelDistance(const float startPos[3], const float endPos[3], float flMaxPathLength, bool checkLOS, bool checkGround);
|
||||
|
||||
|
||||
|
||||
|
@ -2768,6 +3125,8 @@ native void L4D_ResetMobTimer();
|
|||
* @brief Get the remaining spawn time for an SI
|
||||
* @remarks This is meant for Special infected in ghost mode in versus.
|
||||
*
|
||||
* @param player Player ID to get time
|
||||
*
|
||||
* @return Time (seconds) until the SI will spawn.
|
||||
*/
|
||||
// L4D2 only.
|
||||
|
@ -2842,15 +3201,16 @@ native bool L4D_IsMissionFinalMap();
|
|||
native void L4D_NotifyNetworkStateChanged();
|
||||
|
||||
/**
|
||||
* @brief Trigger's a target player's stagger behavior
|
||||
* @brief Trigger's a target player's stagger behaviour
|
||||
* @remarks Works on any CTerrorPlayer--survivor or infected.
|
||||
*
|
||||
* @param target Player to stagger
|
||||
* @param source_ent Source of the stagger (another player, etc)
|
||||
* @param vecSource Source location of the stagger. If NULL_VECTOR, origins of source_ent is used.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void L4D_StaggerPlayer(int target, int source_ent, float vecSource[3]);
|
||||
native void L4D_StaggerPlayer(int target, int source_ent, const float vecSource[3]);
|
||||
|
||||
/**
|
||||
* @brief Calls CDirectorScriptedEventManager::SendInRescueVehicle(void)
|
||||
|
@ -2873,7 +3233,7 @@ native void L4D2_SendInRescueVehicle();
|
|||
* @noreturn
|
||||
*/
|
||||
// L4D2 only.
|
||||
native void L4D2_ChangeFinaleStage(int finaleType, const char[] arg);
|
||||
native void L4D2_ChangeFinaleStage(any finaleType, const char[] arg);
|
||||
|
||||
/**
|
||||
* @brief Calls ZombieManager::ReplaceTank(CTerrorPlayer *,CTerrorPlayer *)
|
||||
|
@ -2945,8 +3305,8 @@ native bool L4D_LobbyIsReserved();
|
|||
/**
|
||||
* @brief Returns the lobby reservation ID
|
||||
*
|
||||
* @reservation String to store the reservation ID to
|
||||
* @maxlength Maximum length of the string to store to
|
||||
* @param reservation String to store the reservation ID to
|
||||
* @param maxlength Maximum length of the string to store to
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -2955,7 +3315,7 @@ native void L4D_GetLobbyReservation(char [] reservation, int maxlength);
|
|||
/**
|
||||
* @brief Sets the lobby reservation ID
|
||||
*
|
||||
* @reservation The reservation ID to set
|
||||
* @param reservation The reservation ID to set
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -3607,7 +3967,7 @@ native int L4D2Direct_GetTankPassedCount();
|
|||
* @note The initial pass from AI to a player counts as a pass.
|
||||
* @note As this is global on the director weird things could potentially happen if more than one tank is alive at a time with z_frustration 1.
|
||||
*
|
||||
* @param New number of passes value
|
||||
* @param passes New number of passes value
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -3961,7 +4321,7 @@ native void L4D2Direct_SetInfernoMaxFlames(int entity, int flames);
|
|||
* @return Address pointer
|
||||
*/
|
||||
// L4D2 only.
|
||||
native int L4D2Direct_GetScriptedEventManager();
|
||||
native any L4D2Direct_GetScriptedEventManager();
|
||||
|
||||
/**
|
||||
* Get the TerrorNavArea which holds a specific position.
|
||||
|
@ -4010,8 +4370,8 @@ native float L4D2Direct_GetFlowDistance(int client);
|
|||
* @note The event argument is NOT the same as the sequence numbers found in the model viewer
|
||||
* @note You can get the number for your animation by looking at the disasm for virtual calls to DoAnimationEvent
|
||||
*
|
||||
* @param client
|
||||
* @param event PlayerAnimEvent_t
|
||||
* @param client Client ID to do animation
|
||||
* @param event Animation index (PlayerAnimEvent_t)
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
|
@ -4023,6 +4383,7 @@ native void L4D2Direct_DoAnimationEvent(int client, int event);
|
|||
* @note Survivors health bonuses are 0 until CTerrorPlayer:RecalculateVersusScore(void) calculates it.
|
||||
*
|
||||
* @param client Client id whose health bonus is to be returned.
|
||||
*
|
||||
* @return Int value of the survivors health bonus.
|
||||
*/
|
||||
// L4D1 only.
|
||||
|
@ -4290,7 +4651,7 @@ native void L4D2_Infected_OnHitByVomitJar(int entity, int attacker);
|
|||
* @noreturn
|
||||
*/
|
||||
// L4D2 only.
|
||||
native void L4D2_CTerrorPlayer_Fling(int client, int attacker, float vecDir[3]);
|
||||
native void L4D2_CTerrorPlayer_Fling(int client, int attacker, const float vecDir[3]);
|
||||
|
||||
/**
|
||||
* @brief Cancels a player staggering
|
||||
|
@ -4301,6 +4662,49 @@ native void L4D2_CTerrorPlayer_Fling(int client, int attacker, float vecDir[3]);
|
|||
*/
|
||||
native void L4D_CancelStagger(int client);
|
||||
|
||||
/**
|
||||
* @brief Flings a Survivor like when they're flung by a nearby Charger impact
|
||||
* @remarks attacker can be the same client index as victim
|
||||
*
|
||||
* @param victim Client index of the Survivor affect
|
||||
* @param attacker Client index of the client attacking the Survivor
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void L4D2_Charger_ThrowImpactedSurvivor(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Makes a Charger carry a Survivor
|
||||
* @remarks The Survivor is teleported after 0.3 seconds to position in the Chargers arms, the position is not perfect and could do with tweaking.
|
||||
* @remarks It seems like the Survivor is colliding with the Charger. If anyone fixes this please report the changes required.
|
||||
*
|
||||
* @param victim Client index of the Survivor to affect
|
||||
* @param attacker Client index of the Charger attacking the Survivor
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void L4D2_Charger_StartCarryingVictim(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Makes a Charger pummel a Survivor
|
||||
*
|
||||
* @param victim Client index of the Survivor to affect
|
||||
* @param attacker Client index of the Charger attacking the Survivor
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void L4D2_Charger_PummelVictim(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Makes a Charger stop pummelling a Survivor
|
||||
*
|
||||
* @param victim Client index of the Survivor to affect
|
||||
* @param attacker Client index of the Charger attacking the Survivor
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void L4D2_Charger_EndPummel(int victim, int attacker);
|
||||
|
||||
/**
|
||||
* @brief Spawns all dead survivors in rescuable rooms.
|
||||
* @remarks L4D1: Any survivor must not be in the starting area for it to work.
|
||||
|
@ -4416,7 +4820,7 @@ native bool L4D_BecomeGhost(int client);
|
|||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void L4D_State_Transition(int client, int state);
|
||||
native void L4D_State_Transition(int client, any state);
|
||||
|
||||
/**
|
||||
* @brief Swaps the teams in Versus
|
||||
|
|
|
@ -323,8 +323,8 @@ stock int L4D_SpawnCommonInfected(float vPos[3], float vAng[3] = { 0.0, 0.0, 0.0
|
|||
int entity = CreateEntityByName("infected");
|
||||
if( entity != -1 )
|
||||
{
|
||||
DispatchSpawn(entity);
|
||||
TeleportEntity(entity, vPos, vAng, NULL_VECTOR);
|
||||
DispatchSpawn(entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
|
@ -660,6 +660,19 @@ stock bool L4D_IsPlayerPinned(int client)
|
|||
return L4D_GetPinnedInfected(client) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns if a Survivor is being attacked in the Smokers arms
|
||||
*
|
||||
* @param client Client ID of the player to check
|
||||
*
|
||||
* @return Returns true if player has reached the Smoker, false otherwise
|
||||
*/
|
||||
stock bool L4D_HasReachedSmoker(int client)
|
||||
{
|
||||
// m_isHangingFromTongue sometimes returns 1 when still being dragged, using this instead
|
||||
return GetEntProp(client, Prop_Send, "m_reachedTongueOwner", 1) == 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==================================================
|
||||
|
|
|
@ -237,7 +237,7 @@ stock void L4D1_SetPlayerZombieClass(int client, L4D1ZombieClassType class)
|
|||
* @error Invalid client index.
|
||||
*/
|
||||
// L4D2 only.
|
||||
stock L4D2ZombieClassType L4D2_GetPlayerZombieClass(int client)
|
||||
stock any L4D2_GetPlayerZombieClass(int client)
|
||||
{
|
||||
return view_as<L4D2ZombieClassType>(GetEntProp(client, Prop_Send, "m_zombieClass"));
|
||||
}
|
||||
|
|
49
scripting/l4d2_ai_tweaks.sp
Normal file
49
scripting/l4d2_ai_tweaks.sp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <actions>
|
||||
//#include <sdkhooks>
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "L4D2 AI Tweaks",
|
||||
author = "jackzmc",
|
||||
description = "",
|
||||
version = PLUGIN_VERSION,
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart() {
|
||||
EngineVersion g_Game = GetEngineVersion();
|
||||
if(g_Game != Engine_Left4Dead2) {
|
||||
SetFailState("This plugin is for L4D2 only.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnActionCreated( BehaviorAction action, int actor, const char[] name ) {
|
||||
/* Hooking friend healing action (when bot wants to heal someone) */
|
||||
if ( strcmp(name, "SurvivorHealFriend") == 0 )
|
||||
action.OnStartPost = OnFriendAction;
|
||||
}
|
||||
|
||||
public Action OnFriendAction( BehaviorAction action, int actor, BehaviorAction priorAction, ActionResult result ) {
|
||||
// Do not allow idle bots to heal another player, unless they are black and white.
|
||||
// Do not let idle bots heal non-idle bots
|
||||
int target = action.Get(0x34) & 0xFFF;
|
||||
if(GetEntProp(actor, Prop_Send, "m_humanSpectatorUserID") > 0) { // If idle bot
|
||||
// If target is a bot AND is a non-idle bot OR target is black and white, stop the heal.
|
||||
if(IsFakeClient(target) && (GetEntProp(target, Prop_Send, "m_humanSpectatorUserID") == 0 || !GetEntProp(target, Prop_Send, "m_bIsOnThirdStrike"))) {
|
||||
PrintToServer("Preventing %N from healing %N", actor, target);
|
||||
result.type = DONE;
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
|
@ -36,8 +36,8 @@ public void OnPluginStart()
|
|||
}
|
||||
|
||||
hEnabled = CreateConVar("l4d2_crescendo_control", "1", "Should plugin be active?", FCVAR_NONE, true, 0.0, true, 1.0);
|
||||
hPercent = CreateConVar("l4d2_crescendo_percent", "0.75", "The percent of players needed to be in range for crescendo to start", FCVAR_NONE);
|
||||
hRange = CreateConVar("l4d2_crescendo_range", "200.0", "How many units away something range brain no work", FCVAR_NONE);
|
||||
hPercent = CreateConVar("l4d2_crescendo_percent", "0.5", "The percent of players needed to be in range for crescendo to start", FCVAR_NONE);
|
||||
hRange = CreateConVar("l4d2_crescendo_range", "250.0", "How many units away something range brain no work", FCVAR_NONE);
|
||||
|
||||
ConVar hGamemode = FindConVar("mp_gamemode");
|
||||
hGamemode.GetString(gamemode, sizeof(gamemode));
|
||||
|
@ -80,6 +80,7 @@ public Action Timer_GetFlows(Handle h) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Event_ButtonPress(const char[] output, int entity, int client, float delay) {
|
||||
|
@ -97,7 +98,6 @@ public Action Event_ButtonPress(const char[] output, int entity, int client, flo
|
|||
float activatorFlow = L4D2Direct_GetFlowDistance(client);
|
||||
|
||||
PrintToConsoleAll("[CC] Button Press by %N", client);
|
||||
|
||||
if(!IsActivationAllowed(activatorFlow, 1500.0)) {
|
||||
ClientCommand(client, "play ui/menu_invalid.wav");
|
||||
PrintToChat(client, "Please wait for players to catch up.");
|
||||
|
@ -130,6 +130,9 @@ public void Frame_ResetButton(int entity) {
|
|||
// [Debug] Percentage of far players: 0.625000% | Average 4222.518066
|
||||
|
||||
stock bool IsActivationAllowed(float flowmax, float threshold) {
|
||||
// Broken behavior, just short circuit true
|
||||
if(flowmax == 0.0) return true;
|
||||
|
||||
int farSurvivors, totalSurvivors;
|
||||
float totalFlow;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
|
|
|
@ -664,7 +664,8 @@ public Action L4D_OnIsTeamFull(int team, bool &full) {
|
|||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
char TIER1_WEAPONS[5][] = {
|
||||
#define TIER1_WEAPON_COUNT 5
|
||||
char TIER1_WEAPONS[TIER1_WEAPON_COUNT][] = {
|
||||
"shotgun_chrome",
|
||||
"pumpshotgun",
|
||||
"smg",
|
||||
|
@ -672,6 +673,7 @@ char TIER1_WEAPONS[5][] = {
|
|||
"smg_mp5"
|
||||
};
|
||||
|
||||
#define TIER2_WEAPON_COUNT 9
|
||||
char TIER2_WEAPONS[9][] = {
|
||||
"autoshotgun",
|
||||
"rifle_ak47",
|
||||
|
@ -690,19 +692,52 @@ public void Frame_SetupNewClient(int client) {
|
|||
EquipPlayerWeapon(client, item);
|
||||
}
|
||||
|
||||
static char weapon[32];
|
||||
if(currentChapter == 1 || (currentChapter == 2 && GetRandomFloat() < 0.3)) {
|
||||
Format(weapon, sizeof(weapon), "weapon_%s", TIER1_WEAPONS[GetRandomInt(0,4)]);
|
||||
} else {
|
||||
Format(weapon, sizeof(weapon), "weapon_%s", TIER2_WEAPONS[GetRandomInt(0,8)]);
|
||||
int lowestClient = -1;
|
||||
float lowestIntensity;
|
||||
char weaponName[64];
|
||||
|
||||
ArrayList tier2Weapons = new ArrayList(ByteCountToCells(32));
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
|
||||
int wpn = GetPlayerWeaponSlot(client, 0);
|
||||
if(wpn > 0) {
|
||||
GetEntityClassname(wpn, weaponName, sizeof(weaponName));
|
||||
for(int j = 0; j < TIER2_WEAPON_COUNT; j++) {
|
||||
if(StrEqual(TIER2_WEAPONS[j], weaponName[j])) {
|
||||
tier2Weapons.PushString(weaponName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float intensity = L4D_GetPlayerIntensity(i);
|
||||
if(intensity < lowestIntensity || lowestClient == -1) {
|
||||
lowestIntensity = intensity;
|
||||
lowestClient = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find a suitable weapon to spawn with
|
||||
if(tier2Weapons.Length > 0) {
|
||||
tier2Weapons.GetString(GetRandomInt(0, tier2Weapons.Length), weaponName, sizeof(weaponName));
|
||||
Format(weaponName, sizeof(weaponName), "weapon_%s", weaponName);
|
||||
} else {
|
||||
Format(weaponName, sizeof(weaponName), "weapon_%s", TIER1_WEAPONS[GetRandomInt(0, TIER1_WEAPON_COUNT)]);
|
||||
}
|
||||
int item = GivePlayerItem(client, weaponName);
|
||||
if(lowestClient > 0) {
|
||||
float pos[3];
|
||||
GetClientAbsOrigin(lowestClient, pos);
|
||||
TeleportEntity(client, pos, NULL_VECTOR, NULL_VECTOR);
|
||||
}
|
||||
delete tier2Weapons;
|
||||
|
||||
|
||||
// static float spawnPos[3];
|
||||
// if(GetIdealPositionInSurvivorFlow(client, spawnPos))
|
||||
// TeleportEntity(client, spawnPos, NULL_VECTOR, NULL_VECTOR);
|
||||
if(item) {
|
||||
GetEdictClassname(item, weaponName, sizeof(item));
|
||||
SetEntProp(item, Prop_Send, "m_iClip1", L4D2_GetIntWeaponAttribute(weaponName, L4D2IWA_ClipSize));
|
||||
EquipPlayerWeapon(client, item);
|
||||
} else LogError("EPI Failed to give new late player weapon: %s", weaponName);
|
||||
}
|
||||
public Action Timer_RemoveInvincibility(Handle h, int client) {
|
||||
SDKUnhook(client, SDKHook_OnTakeDamage, OnInvincibleDamageTaken);
|
||||
|
@ -820,6 +855,7 @@ public void OnMapEnd() {
|
|||
}
|
||||
ammoPacks.Clear();
|
||||
playersLoadedIn = 0;
|
||||
abmExtraCount = 4;
|
||||
}
|
||||
|
||||
public void Event_RoundFreezeEnd(Event event, const char[] name, bool dontBroadcast) {
|
||||
|
|
|
@ -91,6 +91,7 @@ public void OnPluginStart() {
|
|||
RegAdminCmd("sm_instaface", Command_InstaSpecialFace, ADMFLAG_KICK, "Spawns a special that targets them, right in their face.");
|
||||
RegAdminCmd("sm_inface", Command_InstaSpecialFace, ADMFLAG_KICK, "Spawns a special that targets them, right in their face.");
|
||||
RegAdminCmd("sm_bots_attack", Command_BotsAttack, ADMFLAG_CHEATS, "Instructs all bots to attack a player until they have X health.");
|
||||
RegAdminCmd("sm_scharge", Command_SmartCharge, ADMFLAG_CHEATS, "Auto Smart charge");
|
||||
|
||||
HookEvent("player_spawn", Event_PlayerSpawn);
|
||||
HookEvent("player_disconnect", Event_PlayerDisconnect);
|
||||
|
|
|
@ -96,7 +96,7 @@ public Action OnClientSayCommand(int client, const char[] command, const char[]
|
|||
|
||||
public Action Command_AddNote(int client, int args) {
|
||||
if(args < 2) {
|
||||
ReplyToCommand(client, "Syntax: sm_note <player> <note> or if they have disconnected use sm_notedisconnected");
|
||||
ReplyToCommand(client, "Syntax: sm_note <player> \"note in quotes\" or if they left, use sm_notedisconnected");
|
||||
} else {
|
||||
static char target_name[MAX_TARGET_LENGTH];
|
||||
GetCmdArg(1, target_name, sizeof(target_name));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue