From c68fac63590c8aff2cfee81238987a96e65b969a Mon Sep 17 00:00:00 2001 From: Jackz Date: Wed, 24 Aug 2022 22:37:03 -0500 Subject: [PATCH] work on prophunt --- plugins/l4d2_prophunt.smx | Bin 8376 -> 33976 bytes scripting/include/prophunt/phcmds.inc | 59 ++++-- scripting/include/prophunt/phents.inc | 5 + scripting/include/prophunt/phgame.inc | 129 +++++-------- scripting/include/prophunt/phtimers.inc | 52 ++--- scripting/l4d2_prophunt.sp | 246 ++++++++++++++++++++---- 6 files changed, 323 insertions(+), 168 deletions(-) diff --git a/plugins/l4d2_prophunt.smx b/plugins/l4d2_prophunt.smx index afcdef1a06aa43af88f0348da62657e9e14d9a60..2265ef1969be9724a51ff68dc0211514822711b2 100644 GIT binary patch literal 33976 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 VZ&){}T$&fcA+UnNTpHXX{D1apR!9H< literal 8376 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 diff --git a/scripting/include/prophunt/phcmds.inc b/scripting/include/prophunt/phcmds.inc index 6399ca5..a26d0b0 100644 --- a/scripting/include/prophunt/phcmds.inc +++ b/scripting/include/prophunt/phcmds.inc @@ -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; } diff --git a/scripting/include/prophunt/phents.inc b/scripting/include/prophunt/phents.inc index 670c13e..e46bcee 100644 --- a/scripting/include/prophunt/phents.inc +++ b/scripting/include/prophunt/phents.inc @@ -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"); +} \ No newline at end of file diff --git a/scripting/include/prophunt/phgame.inc b/scripting/include/prophunt/phgame.inc index f5f6d6f..d58f3b1 100644 --- a/scripting/include/prophunt/phgame.inc +++ b/scripting/include/prophunt/phgame.inc @@ -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]; \ No newline at end of file diff --git a/scripting/include/prophunt/phtimers.inc b/scripting/include/prophunt/phtimers.inc index 1a37392..ff1e165 100644 --- a/scripting/include/prophunt/phtimers.inc +++ b/scripting/include/prophunt/phtimers.inc @@ -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; } diff --git a/scripting/l4d2_prophunt.sp b/scripting/l4d2_prophunt.sp index c8624ca..3147d3a 100644 --- a/scripting/l4d2_prophunt.sp +++ b/scripting/l4d2_prophunt.sp @@ -4,12 +4,14 @@ //#define DEBUG #define PLUGIN_VERSION "1.0" +#define BLIND_TIME 30 +#define DEFAULT_GAME_TIME 600 #include #include #include -#include -#include +#include + 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 +#include + 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; + } }