work on prophunt

This commit is contained in:
Jackz 2022-08-24 22:37:03 -05:00
parent 9010b630d5
commit c68fac6359
No known key found for this signature in database
GPG key ID: E0BBD94CF657F603
6 changed files with 323 additions and 168 deletions

Binary file not shown.

View file

@ -166,13 +166,13 @@ public Action Command_PropHunt(int client, int args) {
return Plugin_Handled;
} else if(StrEqual(subcmd, "pos", false)) {
float pos[3];
GetAbsOrigin(client, pos);
GetClientAbsOrigin(client, pos);
ReplyToCommand(client, "\"origin\" \"%f %f %f\"", pos[0], pos[1], pos[2]);
GetClientEyeAngles(client, pos);
ReplyToCommand(client, "\"rotation\" \"%f %f %f\"", pos[0], pos[1], pos[2]);
} else if(StrEqual(subcmd, "prop", false)) {
float pos[3];
GetAbsOrigin(client, pos);
GetClientAbsOrigin(client, pos);
ReplyToCommand(client, "\"MYPROP\"");
ReplyToCommand(client, "{");
ReplyToCommand(client, "\t\"origin\" \"%f %f %f\"", pos[0], pos[1], pos[2]);
@ -220,10 +220,36 @@ public Action Command_PropHunt(int client, int args) {
ReplyToTargetError(client, target_count);
return Plugin_Handled;
}
Game.ForceSetSeeker(target_list[0]);
ReplyToCommand(client, "Set the current seeker to %N", target_list[0]);
Game.SetSeeker(target_list[0], true);
ReplyToCommand(client, "Made %N a seeker", target_list[0]);
} else {
ReplyToCommand(client, "The current seeker is: %N", Game.Seeker);
ReplyToCommand(client, "Specify a player to make a seeker");
}
} else if(StrEqual(subcmd, "prop")) {
if(args == 2) {
char arg1[32];
GetCmdArg(2, 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,
1,
0,
target_name,
sizeof(target_name),
tn_is_ml)) <= 0
|| target_list[0] <= 0){
/* This function replies to the admin with a failure message */
ReplyToTargetError(client, target_count);
return Plugin_Handled;
}
Game.SetSeeker(target_list[0], false);
ReplyToCommand(client, "Made %N a prop", target_list[0]);
} else {
ReplyToCommand(client, "Specify a player to make a prop");
}
} else if(StrEqual(subcmd, "debug")) {
ReplyToCommand(client, "- Game Info -");
@ -236,9 +262,6 @@ public Action Command_PropHunt(int client, int args) {
else
ReplyToCommand(client, "Has Spawnpoint: no (possibly map spawn %f %f %f)", mapConfig.spawnpoint[0], mapConfig.spawnpoint[1], mapConfig.spawnpoint[2]);
ReplyToCommand(client, "Map Time: %d", mapConfig.mapTime);
ReplyToCommand(client, "Flow Bounds: (%f, %f)", movePoints.MinFlow, movePoints.MaxFlow);
} else if(StrEqual(subcmd, "test")) {
} else {
ReplyToCommand(client, "Unknown option. Leave blank for help");
}
@ -266,12 +289,18 @@ public Action Command_PropHunt(int client, int args) {
public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) {
if(isEnabled) {
if(!StrEqual(command, "say")) { //Is team message
if(currentSeeker <= 0 || currentSeeker == client) {
return Plugin_Continue;
}
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i) && i != currentSeeker)
PrintToChat(i, "[Hiders] %N: %s", client, sArgs);
if(Game.IsSeeker(client)) {
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i) && Game.IsSeeker(i)) {
PrintToChat(i, "[Seekers] %N: %s", client, sArgs);
}
}
} else {
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i) && !Game.IsSeeker(i)) {
PrintToChat(i, "[Hiders] %N: %s", client, sArgs);
}
}
}
return Plugin_Handled;
}
@ -316,7 +345,7 @@ public Action Command_Join(int client, int args) {
}
ReplyToCommand(client, "Joined %s", target_name);
} else {
if(currentSeeker == client) {
if(Game.IsSeeker(client)) {
ReplyToCommand(client, "You are already in-game as a seeker.");
return Plugin_Handled;
}

View file

@ -126,3 +126,8 @@ void SetupEntities(bool blockers = true, bool props = true, bool portals = true)
}
}
stock int Entity_GetHammerId(int entity)
{
return GetEntProp(entity, Prop_Data, "m_iHammerID");
}

View file

@ -42,11 +42,10 @@ bool FindSpawnPosition(float pos[3], bool includePlayers = true) {
static char buffer[128];
bool isSeeker[MAXPLAYERS+1];
methodmap PropHuntGame < BaseGame {
property int Seekers {
property int SeekersCount {
public get() {
int count = 0;
for(int i = 1; i <= MaxClients; i++) {
@ -55,13 +54,25 @@ methodmap PropHuntGame < BaseGame {
return count;
}
}
property int PropsCount {
public get() {
int count = 0;
for(int i = 1; i <= MaxClients; i++) {
if(!isSeeker[i]) count++;
}
return count;
}
}
public bool IsSeeker(int client) {
return isSeeker[client];
}
public void SetSeeker(int client, bool value) {
public bool SetSeeker(int client, bool value) {
isSeeker[client] = value;
hasBeenSeeker[client] = true;
DispatchKeyValue(client, "rendercolor", value ? WHITE : TRANSPARENT);
return true;
}
public void ClearSeekers() {
@ -135,36 +146,6 @@ methodmap PropHuntGame < BaseGame {
DeleteCustomEnts();
}
public int _FindSeeker() {
if(!isEnabled) return -1;
L4D2_GetVScriptOutput("g_ModeScript.MutationState.CurrentSeeker && \"GetPlayerUserId\" in g_ModeScript.MutationState.CurrentSeeker ? g_ModeScript.MutationState.CurrentSeeker.GetPlayerUserId() : -1", buffer, sizeof(buffer));
int uid = StringToInt(buffer);
if(uid > 0) {
return GetClientOfUserId(uid);
} else {
Game.Debug("Mutation has no seeker, manually attempting to find seeker");
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i)) {
int entity = GetPlayerWeaponSlot(i, 1);
if(entity > -1 && GetEntityClassname(entity, buffer, sizeof(buffer)) && StrEqual(buffer, "melee")) {
GetEntPropString(entity, Prop_Data, "m_strMapSetScriptName", buffer, sizeof(buffer));
if(StrEqual(buffer, "smg")) {
return i;
}
}
}
}
}
Game.Debug("All attempts to find a seeker failed");
return -1;
}
public void ForceSetSeeker(int client, bool ignoreBalance = false) {
ignoreSeekerBalance = true;
this.Seeker = client;
}
public bool TeleportToSpawn(int client) {
if(mapConfig.hasSpawnpoint) {
TeleportEntity(client, mapConfig.spawnpoint, NULL_VECTOR, NULL_VECTOR);
@ -193,11 +174,22 @@ methodmap PropHuntGame < BaseGame {
}
// Ignores seeker
property int AlivePlayers {
property int PropsAlive {
public get() {
int amount = 0;
for(int i = 1; i <= MaxClients; i++) {
if(!this.IsSeeker(i) && IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && !IsFakeClient(i)) {
if(!isSeeker[i] && IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) > 1 && IsPlayerAlive(i) && !IsFakeClient(i)) {
amount++;
}
}
return amount;
}
}
property int SeekersAlive {
public get() {
int amount = 0;
for(int i = 1; i <= MaxClients; i++) {
if(!isSeeker[i] && IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) > 1 && IsPlayerAlive(i) && !IsFakeClient(i)) {
amount++;
}
}
@ -205,20 +197,35 @@ methodmap PropHuntGame < BaseGame {
}
}
public void SetupInventory(int client) {
ClearInventory(client);
if(this.IsSeeker(client)) {
CheatCommand(client, "give", "smg");
}
public void SetupProp(int client) {
PrintToChatAll("SetupProp");
int propIndex = GetURandomInt() % MAX_VALID_MODELS;
propData[client].prop = CreatePropInternal(VALID_MODELS[propIndex]);
DispatchKeyValue(client, "rendercolor", TRANSPARENT);
SDKHook(client, SDKHook_SetTransmit, OnPlayerTransmit);
}
public void SetupSeeker(int client) {
CheatCommand(client, "give", "smg");
}
public void SetupPlayer(int client) {
this.SetupInventory(client);
ClearInventory(client);
ChangeClientTeam(client, 2);
SetEntProp(client, Prop_Send, "m_survivorCharacter", GetURandomInt() % 7);
SDKHook(client, SDKHook_OnTakeDamageAlive, OnTakeDamageAlive);
}
public void UnsetupPlayer(int client) {
DispatchKeyValue(client, "rendercolor", WHITE);
SDKUnhook(client, SDKHook_OnTakeDamageAlive, OnTakeDamageAlive);
hasBeenSeeker[client] = false;
isSeeker[client] = false;
SDKUnhook(client, SDKHook_OnTakeDamageAlive, OnTakeDamageAlive);
SetPlayerBlind(client, 0);
SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", 1.0);
}
}
@ -348,43 +355,3 @@ static char AUTO_VOCALIZATIONS[MAX_AUTO_VOCALIZATIONS][] = {
"ResponseSoftDispleasureSwear",
"PlayerAreaClear"
};
enum struct HiderDistQueue {
int index;
float list[HIDER_DISTANCE_MAX_SIZE];
int lastVocalize;
void AddPos(const float pos[3]) {
this.list[this.index] = GetVectorDistance(seekerPos, pos);
if(++this.index == HIDER_DISTANCE_MAX_SIZE) {
this.index = 0;
}
}
void Clear() {
for(int i = 0; i < HIDER_DISTANCE_MAX_SIZE; i++) {
this.list[i] = 0.0;
}
}
float GetAverage() {
float sum = 0.0;
for(int i = 0; i < HIDER_DISTANCE_MAX_SIZE; i++) {
sum += this.list[i];
}
return sum / float(HIDER_DISTANCE_MAX_SIZE);
}
void Check(int i) {
if(this.GetAverage() > HIDER_MIN_AVG_DISTANCE_AUTO_VOCALIZE) {
int time = GetTime();
if(time - this.lastVocalize > HIDER_AUTO_VOCALIZE_GRACE_TIME) {
this.lastVocalize = time;
int index = GetRandomInt(0, MAX_AUTO_VOCALIZATIONS - 1);
PerformScene(i, AUTO_VOCALIZATIONS[index]);
}
}
}
}
HiderDistQueue distQueue[MAXPLAYERS+1];

View file

@ -1,23 +1,3 @@
Action Timer_RecordPoints(Handle h, int i) {
if(GetEntityFlags(i) & FL_ONGROUND && IsPlayerAlive(i)) {
LocationMeta meta;
GetClientAbsOrigin(i, meta.pos);
GetClientEyeAngles(i, meta.ang);
if(meta.pos[0] != vecLastLocation[i][0] || meta.pos[1] != vecLastLocation[i][1] || meta.pos[2] != vecLastLocation[i][2]) {
if(movePoints.AddPoint(meta)) {
recordTimer = null;
return Plugin_Stop;
}
Effect_DrawBeamBoxRotatableToClient(i, meta.pos, DEBUG_POINT_VIEW_MIN, DEBUG_POINT_VIEW_MAX, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 150.0, 0.1, 0.1, 0, 0.0, {0, 0, 255, 64}, 0);
vecLastLocation[i] = meta.pos;
}
}
PrintHintText(i, "Points: %d / %d", movePoints.Length, MAX_VALID_LOCATIONS);
return Plugin_Continue;
}
bool firstCheckDone = false;
Action Timer_WaitForPlayers(Handle h) {
if(!isEnabled) return Plugin_Stop;
if(!ArePlayersJoining()) {
@ -36,27 +16,25 @@ Action Timer_WaitForPlayers(Handle h) {
}
Action Timer_CheckHiders(Handle h) {
static float pos[3];
static char classname[16];
Action Timer_StartGame(Handle h) {
Game.State = State_Active;
Game.MapTime = DEFAULT_GAME_TIME;
Game.Tick = 0;
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) {
GetClientAbsOrigin(i, pos);
distQueue[i].AddPos(pos);
distQueue[i].Check(i);
int activeWeapon = GetEntPropEnt(i, Prop_Send, "m_hActiveWeapon");
if(IsValidEntity(activeWeapon)) {
GetEntityClassname(activeWeapon, classname, sizeof(classname));
if(i == currentSeeker) {
if(StrEqual(classname, "weapon_melee")) continue;
Game.SetupInventory(i);
} else if(StrEqual(classname, "weapon_gnome")) continue;
if(IsClientConnected(i) && IsClientInGame(i)) {
if(Game.IsSeeker(i)) {
Game.SetupSeeker(i);
}
Game.SetupInventory(i);
SetPlayerBlind(i, 0);
SetEntPropFloat(i, Prop_Send, "m_flLaggedMovementValue", 1.0);
}
}
Game.CleanupGnomes(true);
Game.Broadcast("Get ready here they come");
return Plugin_Continue;
}
Action Timer_TimesUp(Handle h) {
Game.End(State_PropsWin);
return Plugin_Continue;
}

View file

@ -4,12 +4,14 @@
//#define DEBUG
#define PLUGIN_VERSION "1.0"
#define BLIND_TIME 30
#define DEFAULT_GAME_TIME 600
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <gamemodes/base>
#include <gamemodes/ents>
#include <left4dhooks>
enum GameState {
State_Unknown = 0,
@ -20,12 +22,11 @@ enum GameState {
}
#define MAX_VALID_MODELS 2
static char VALID_MODELS[MAX_VALID_MODELS][] = {
char VALID_MODELS[MAX_VALID_MODELS][] = {
"models/props_crates/static_crate_40.mdl",
"models/props_junk/gnome.mdl"
};
static float EMPTY_ANG[3];
#define TRANSPARENT "255 255 255 0"
#define WHITE "255 255 255 255"
@ -34,8 +35,22 @@ enum struct PropData {
bool rotationLock;
}
UserMsg g_FadeUserMsgId;
PropData propData[MAXPLAYERS+1];
bool isSeeker[MAXPLAYERS+1];
bool hasBeenSeeker[MAXPLAYERS+1];
bool isStarting, firstCheckDone;
Handle timesUpTimer;
Handle waitTimer;
PropHuntGame Game;
#include <gamemodes/base>
#include <prophunt/phcore>
public Plugin myinfo =
{
name = "Prophunt",
@ -50,13 +65,174 @@ public void OnPluginStart() {
if(g_Game != Engine_Left4Dead2) {
SetFailState("This plugin is for L4D2 only.");
}
Game.Init("PropHunt");
g_FadeUserMsgId = GetUserMessageId("Fade");
RegConsoleCmd("sm_game", Command_Test);
RegAdminCmd("sm_prophunt", Command_PropHunt, ADMFLAG_KICK);
RegAdminCmd("sm_ph", Command_PropHunt, ADMFLAG_KICK);
ConVar hGamemode = FindConVar("mp_gamemode");
hGamemode.AddChangeHook(Event_GamemodeChange);
Event_GamemodeChange(hGamemode, gamemode, gamemode);
}
public void OnPluginEnd() {
OnMapEnd();
}
void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) {
waitTimer = CreateTimer(firstCheckDone ? 2.5 : 6.0, Timer_WaitForPlayers, _, TIMER_REPEAT);
}
void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) {
// Skip the check, everyone's loaded in
firstCheckDone = true;
}
public void OnClientPutInServer(int client) {
if(!isEnabled) return;
if(IsFakeClient(client)) {
KickClient(client, "ph: Remove Special Infected");
} else {
ChangeClientTeam(client, 1);
isPendingPlay[client] = true;
Game.Broadcast("%N will play next round", client);
Game.TeleportToSpawn(client);
}
}
public void OnClientDisconnect(int client) {
if(!isEnabled) return;
ResetPlayerData(client);
if(Game.IsSeeker(client)) {
if(Game.SeekersAlive == 0) {
Game.Broadcast("All seekers have disconnected, Props win");
Game.End(State_PropsWin);
}
} else if(Game.PropsAlive == 0) {
Game.Broadcast("All hiders have disconnected, Seekers win");
Game.End(State_SeekerWin);
}
}
public void Event_GamemodeChange(ConVar cvar, const char[] oldValue, const char[] newValue) {
cvar.GetString(gamemode, sizeof(gamemode));
bool shouldEnable = StrEqual(gamemode, "prophunt", false);
if(isEnabled == shouldEnable) return;
firstCheckDone = false;
if(shouldEnable) {
Game.Broadcast("Gamemode is starting");
HookEvent("round_start", Event_RoundStart);
HookEvent("round_end", Event_RoundEnd);
HookEvent("player_death", Event_PlayerDeath);
} else if(!lateLoaded) {
UnhookEvent("round_start", Event_RoundStart);
UnhookEvent("round_end", Event_RoundEnd);
UnhookEvent("player_death", Event_PlayerDeath);
Game.Cleanup();
}
isEnabled = shouldEnable;
}
public void OnMapStart() {
for(int i = 0; i < MAX_VALID_MODELS; i++) {
PrecacheModel(VALID_MODELS[i]);
}
isStarting = false;
if(!isEnabled) return;
char map[128];
GetCurrentMap(map, sizeof(map));
if(!StrEqual(g_currentMap, map)) {
firstCheckDone = false;
strcopy(g_currentSet, sizeof(g_currentSet), "default");
ReloadMapDB();
strcopy(g_currentMap, sizeof(g_currentMap), map);
}
if(lateLoaded) {
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i)) {
Game.SetupPlayer(i);
}
}
InitGamemode();
}
Game.State = State_Unknown;
}
void InitGamemode() {
if(isStarting && Game.State != State_Unknown) {
Game.Warn("InitGamemode() called in an incorrect state (%d)", Game.State);
return;
}
SetupEntities();
Game.DebugConsole("InitGamemode(): activating");
ArrayList validPlayerIds = new ArrayList();
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i)) {
if(IsFakeClient(i)) {
KickClient(i);
} else {
Game.SetupPlayer(i);
if(!IsPlayerAlive(i)) {
L4D_RespawnPlayer(i);
}
if(!hasBeenSeeker[i])
validPlayerIds.Push(GetClientUserId(i));
}
}
}
if(validPlayerIds.Length == 0) {
Game.Warn("Ignoring InitGamemode() with no valid survivors");
return;
}
int numberOfSeekers = RoundToCeil(float(validPlayerIds.Length) / 3.0);
int timeout = 0;
while(numberOfSeekers > 0 && timeout < 2) {
int newSeeker = GetClientOfUserId(validPlayerIds.Get(GetURandomInt() % validPlayerIds.Length));
if(newSeeker > 0) {
hasBeenSeeker[newSeeker] = true;
Game.SetSeeker(newSeeker, true);
Game.Broadcast("%N is a seeker", newSeeker);
numberOfSeekers--;
SetPlayerBlind(newSeeker, 255);
SetEntPropFloat(newSeeker, Prop_Send, "m_flLaggedMovementValue", 0.0);
} else {
timeout++;
}
}
delete validPlayerIds;
Game.TeleportAllToStart();
Game.MapTime = BLIND_TIME;
Game.Tick = 0;
Game.State = State_Hiding;
for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i) && !Game.IsSeeker(i)) {
PrintToChatAll("setting up non seeker %N", i);
Game.SetupProp(i);
}
}
CreateTimer(float(BLIND_TIME), Timer_StartGame);
}
void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
int client = GetClientOfUserId(event.GetInt("userid"));
int attacker = GetClientOfUserId(event.GetInt("attacker"));
if(client > 0 && Game.State == State_Active) {
if(Game.SeekersAlive == 0) {
Game.Broadcast("All seekers have perished. Hiders win!");
Game.End(State_PropsWin);
} else if(Game.PropsAlive == 0) {
Game.Broadcast("Seekers win!");
Game.End(State_SeekerWin);
}
}
}
void ResetPlayerData(int client) {
@ -71,33 +247,28 @@ public void OnMapEnd() {
for(int i = 1; i <= MaxClients; i++) {
ResetPlayerData(i);
if(IsClientConnected(i) && IsClientInGame(i)) {
DispatchKeyValue(i, "rendercolor", WHITE);
Game.UnsetupPlayer(i);
}
}
}
public void OnClientDisconnect(int client) {
ResetPlayerData(client);
void ClearInventory(int client) {
for(int i = 0; i <= 5; i++) {
int item = GetPlayerWeaponSlot(client, i);
if(item > 0) {
AcceptEntityInput(item, "Kill");
}
}
}
public Action Command_Test(int client, int args) {
int prop = CreatePropInternal(VALID_MODELS[0]);
if(prop <= 0) {
ReplyToCommand(client, "Failed to spawn prop");
return Plugin_Handled;
}
float pos[3];
propData[client].prop = prop;
DispatchKeyValue(client, "rendercolor", TRANSPARENT);
// SetParent(prop, client);
// SetParentAttachment(prop, "eyes", true);
// TeleportEntity(prop, pos, EMPTY_ANG, NULL_VECTOR);
// SetParentAttachment(prop, "eyes", true);
SDKHook(client, SDKHook_SetTransmit, OnPlayerTransmit);
ReplyToCommand(client, "Game!");
InitGamemode();
return Plugin_Handled;
}
Action OnPropTransmit(int entity, int client) {
return propData[client].prop == entity ? Plugin_Stop : Plugin_Continue;
}
Action OnPlayerTransmit(int entity, int client) {
return entity == client ? Plugin_Continue : Plugin_Stop;
@ -116,12 +287,19 @@ int CreatePropInternal(const char[] model) {
}
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) {
// if(!isEnabled) return Plugin_Continue;
int oldButtons = GetEntProp(client, Prop_Data, "m_nOldButtons");
if(buttons & IN_RELOAD && !(oldButtons & IN_RELOAD)) {
propData[client].rotationLock = !propData[client].rotationLock;
PrintHintText(client, "Rotation lock now %s", propData[client].rotationLock ? "enabled" : "disabled");
return Plugin_Continue;
}
if(propData[client].prop > 0) {
static float pos[3], ang[3];
GetClientAbsOrigin(client, pos);
TeleportEntity(client, pos, NULL_VECTOR, NULL_VECTOR);
if(propData[client].rotationLock)
TeleportEntity(propData[client].prop, NULL_VECTOR, angles, NULL_VECTOR);
TeleportEntity(propData[client].prop, pos, NULL_VECTOR, NULL_VECTOR);
else {
ang[0] = 0.0;
ang[1] = angles[1];
@ -133,19 +311,17 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
}
Action OnTakeDamageAlive(int victim, int& attacker, int& inflictor, float& damage, int& damagetype) {
/*if(attacker == currentSeeker) {
damage = 100.0;
ClearInventory(victim);
if(attacker > 0 && attacker <= MaxClients && IsFakeClient(victim)) {
PrintToChat(attacker, "That was a bot! -%.0f health", cvar_seekerFailDamageAmount.FloatValue);
SDKHooks_TakeDamage(attacker, 0, 0, cvar_seekerFailDamageAmount.FloatValue, DMG_DIRECT);
if(Game.IsSeeker(attacker)) {
if(victim <= MaxClients && victim > 0) {
damage = 10.0;
return Plugin_Changed;
} else {
SDKHooks_TakeDamage(attacker, 0, 0, 10.0, DMG_DIRECT);
damage = 0.0;
return Plugin_Handled;
}
return Plugin_Changed;
} else if(attacker > 0 && attacker <= MaxClients) {
damage = 0.0;
return Plugin_Changed;
} else {
return Plugin_Continue;
}*/
return Plugin_Continue;
damage = 0.0;
return Plugin_Handled;
}
}