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; return Plugin_Handled;
} else if(StrEqual(subcmd, "pos", false)) { } else if(StrEqual(subcmd, "pos", false)) {
float pos[3]; float pos[3];
GetAbsOrigin(client, pos); GetClientAbsOrigin(client, pos);
ReplyToCommand(client, "\"origin\" \"%f %f %f\"", pos[0], pos[1], pos[2]); ReplyToCommand(client, "\"origin\" \"%f %f %f\"", pos[0], pos[1], pos[2]);
GetClientEyeAngles(client, pos); GetClientEyeAngles(client, pos);
ReplyToCommand(client, "\"rotation\" \"%f %f %f\"", pos[0], pos[1], pos[2]); ReplyToCommand(client, "\"rotation\" \"%f %f %f\"", pos[0], pos[1], pos[2]);
} else if(StrEqual(subcmd, "prop", false)) { } else if(StrEqual(subcmd, "prop", false)) {
float pos[3]; float pos[3];
GetAbsOrigin(client, pos); GetClientAbsOrigin(client, pos);
ReplyToCommand(client, "\"MYPROP\""); ReplyToCommand(client, "\"MYPROP\"");
ReplyToCommand(client, "{"); ReplyToCommand(client, "{");
ReplyToCommand(client, "\t\"origin\" \"%f %f %f\"", pos[0], pos[1], pos[2]); 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); ReplyToTargetError(client, target_count);
return Plugin_Handled; return Plugin_Handled;
} }
Game.ForceSetSeeker(target_list[0]); Game.SetSeeker(target_list[0], true);
ReplyToCommand(client, "Set the current seeker to %N", target_list[0]); ReplyToCommand(client, "Made %N a seeker", target_list[0]);
} else { } 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")) { } else if(StrEqual(subcmd, "debug")) {
ReplyToCommand(client, "- Game Info -"); ReplyToCommand(client, "- Game Info -");
@ -236,9 +262,6 @@ public Action Command_PropHunt(int client, int args) {
else else
ReplyToCommand(client, "Has Spawnpoint: no (possibly map spawn %f %f %f)", mapConfig.spawnpoint[0], mapConfig.spawnpoint[1], mapConfig.spawnpoint[2]); 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, "Map Time: %d", mapConfig.mapTime);
ReplyToCommand(client, "Flow Bounds: (%f, %f)", movePoints.MinFlow, movePoints.MaxFlow);
} else if(StrEqual(subcmd, "test")) {
} else { } else {
ReplyToCommand(client, "Unknown option. Leave blank for help"); 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) { public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) {
if(isEnabled) { if(isEnabled) {
if(!StrEqual(command, "say")) { //Is team message if(!StrEqual(command, "say")) { //Is team message
if(currentSeeker <= 0 || currentSeeker == client) { if(Game.IsSeeker(client)) {
return Plugin_Continue; for(int i = 1; i <= MaxClients; i++) {
} if(IsClientConnected(i) && IsClientInGame(i) && Game.IsSeeker(i)) {
for(int i = 1; i <= MaxClients; i++) { PrintToChat(i, "[Seekers] %N: %s", client, sArgs);
if(IsClientConnected(i) && IsClientInGame(i) && i != currentSeeker) }
PrintToChat(i, "[Hiders] %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; return Plugin_Handled;
} }
@ -316,7 +345,7 @@ public Action Command_Join(int client, int args) {
} }
ReplyToCommand(client, "Joined %s", target_name); ReplyToCommand(client, "Joined %s", target_name);
} else { } else {
if(currentSeeker == client) { if(Game.IsSeeker(client)) {
ReplyToCommand(client, "You are already in-game as a seeker."); ReplyToCommand(client, "You are already in-game as a seeker.");
return Plugin_Handled; 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]; static char buffer[128];
bool isSeeker[MAXPLAYERS+1];
methodmap PropHuntGame < BaseGame { methodmap PropHuntGame < BaseGame {
property int Seekers { property int SeekersCount {
public get() { public get() {
int count = 0; int count = 0;
for(int i = 1; i <= MaxClients; i++) { for(int i = 1; i <= MaxClients; i++) {
@ -55,13 +54,25 @@ methodmap PropHuntGame < BaseGame {
return count; 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) { public bool IsSeeker(int client) {
return isSeeker[client]; return isSeeker[client];
} }
public void SetSeeker(int client, bool value) { public bool SetSeeker(int client, bool value) {
isSeeker[client] = value; isSeeker[client] = value;
hasBeenSeeker[client] = true;
DispatchKeyValue(client, "rendercolor", value ? WHITE : TRANSPARENT);
return true;
} }
public void ClearSeekers() { public void ClearSeekers() {
@ -135,36 +146,6 @@ methodmap PropHuntGame < BaseGame {
DeleteCustomEnts(); 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) { public bool TeleportToSpawn(int client) {
if(mapConfig.hasSpawnpoint) { if(mapConfig.hasSpawnpoint) {
TeleportEntity(client, mapConfig.spawnpoint, NULL_VECTOR, NULL_VECTOR); TeleportEntity(client, mapConfig.spawnpoint, NULL_VECTOR, NULL_VECTOR);
@ -193,11 +174,22 @@ methodmap PropHuntGame < BaseGame {
} }
// Ignores seeker // Ignores seeker
property int AlivePlayers { property int PropsAlive {
public get() { public get() {
int amount = 0; int amount = 0;
for(int i = 1; i <= MaxClients; i++) { 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++; amount++;
} }
} }
@ -205,20 +197,35 @@ methodmap PropHuntGame < BaseGame {
} }
} }
public void SetupInventory(int client) { public void SetupProp(int client) {
ClearInventory(client); PrintToChatAll("SetupProp");
if(this.IsSeeker(client)) { int propIndex = GetURandomInt() % MAX_VALID_MODELS;
CheatCommand(client, "give", "smg");
} 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) { 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); SDKHook(client, SDKHook_OnTakeDamageAlive, OnTakeDamageAlive);
} }
public void UnsetupPlayer(int client) { public void UnsetupPlayer(int client) {
DispatchKeyValue(client, "rendercolor", WHITE);
SDKUnhook(client, SDKHook_OnTakeDamageAlive, OnTakeDamageAlive); 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", "ResponseSoftDispleasureSwear",
"PlayerAreaClear" "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) { Action Timer_WaitForPlayers(Handle h) {
if(!isEnabled) return Plugin_Stop; if(!isEnabled) return Plugin_Stop;
if(!ArePlayersJoining()) { if(!ArePlayersJoining()) {
@ -36,27 +16,25 @@ Action Timer_WaitForPlayers(Handle h) {
} }
Action Timer_CheckHiders(Handle h) { Action Timer_StartGame(Handle h) {
static float pos[3]; Game.State = State_Active;
static char classname[16]; Game.MapTime = DEFAULT_GAME_TIME;
Game.Tick = 0;
for(int i = 1; i <= MaxClients; i++) { for(int i = 1; i <= MaxClients; i++) {
if(IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i)) { if(IsClientConnected(i) && IsClientInGame(i)) {
GetClientAbsOrigin(i, pos); if(Game.IsSeeker(i)) {
distQueue[i].AddPos(pos); Game.SetupSeeker(i);
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;
} }
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; return Plugin_Continue;
} }

View file

@ -4,12 +4,14 @@
//#define DEBUG //#define DEBUG
#define PLUGIN_VERSION "1.0" #define PLUGIN_VERSION "1.0"
#define BLIND_TIME 30
#define DEFAULT_GAME_TIME 600
#include <sourcemod> #include <sourcemod>
#include <sdktools> #include <sdktools>
#include <sdkhooks> #include <sdkhooks>
#include <gamemodes/base> #include <left4dhooks>
#include <gamemodes/ents>
enum GameState { enum GameState {
State_Unknown = 0, State_Unknown = 0,
@ -20,12 +22,11 @@ enum GameState {
} }
#define MAX_VALID_MODELS 2 #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_crates/static_crate_40.mdl",
"models/props_junk/gnome.mdl" "models/props_junk/gnome.mdl"
}; };
static float EMPTY_ANG[3];
#define TRANSPARENT "255 255 255 0" #define TRANSPARENT "255 255 255 0"
#define WHITE "255 255 255 255" #define WHITE "255 255 255 255"
@ -34,8 +35,22 @@ enum struct PropData {
bool rotationLock; bool rotationLock;
} }
UserMsg g_FadeUserMsgId;
PropData propData[MAXPLAYERS+1]; 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 = public Plugin myinfo =
{ {
name = "Prophunt", name = "Prophunt",
@ -50,13 +65,174 @@ public void OnPluginStart() {
if(g_Game != Engine_Left4Dead2) { if(g_Game != Engine_Left4Dead2) {
SetFailState("This plugin is for L4D2 only."); SetFailState("This plugin is for L4D2 only.");
} }
Game.Init("PropHunt");
g_FadeUserMsgId = GetUserMessageId("Fade");
RegConsoleCmd("sm_game", Command_Test); 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() { public void OnMapStart() {
for(int i = 0; i < MAX_VALID_MODELS; i++) { for(int i = 0; i < MAX_VALID_MODELS; i++) {
PrecacheModel(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) { void ResetPlayerData(int client) {
@ -71,33 +247,28 @@ public void OnMapEnd() {
for(int i = 1; i <= MaxClients; i++) { for(int i = 1; i <= MaxClients; i++) {
ResetPlayerData(i); ResetPlayerData(i);
if(IsClientConnected(i) && IsClientInGame(i)) { if(IsClientConnected(i) && IsClientInGame(i)) {
DispatchKeyValue(i, "rendercolor", WHITE); Game.UnsetupPlayer(i);
} }
} }
} }
public void OnClientDisconnect(int client) { void ClearInventory(int client) {
ResetPlayerData(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) { public Action Command_Test(int client, int args) {
int prop = CreatePropInternal(VALID_MODELS[0]); InitGamemode();
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!");
return Plugin_Handled; return Plugin_Handled;
} }
Action OnPropTransmit(int entity, int client) {
return propData[client].prop == entity ? Plugin_Stop : Plugin_Continue;
}
Action OnPlayerTransmit(int entity, int client) { Action OnPlayerTransmit(int entity, int client) {
return entity == client ? Plugin_Continue : Plugin_Stop; 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]) { 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) { if(propData[client].prop > 0) {
static float pos[3], ang[3]; static float pos[3], ang[3];
GetClientAbsOrigin(client, pos); GetClientAbsOrigin(client, pos);
TeleportEntity(client, pos, NULL_VECTOR, NULL_VECTOR); TeleportEntity(client, pos, NULL_VECTOR, NULL_VECTOR);
if(propData[client].rotationLock) if(propData[client].rotationLock)
TeleportEntity(propData[client].prop, NULL_VECTOR, angles, NULL_VECTOR); TeleportEntity(propData[client].prop, pos, NULL_VECTOR, NULL_VECTOR);
else { else {
ang[0] = 0.0; ang[0] = 0.0;
ang[1] = angles[1]; 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) { Action OnTakeDamageAlive(int victim, int& attacker, int& inflictor, float& damage, int& damagetype) {
/*if(attacker == currentSeeker) { if(Game.IsSeeker(attacker)) {
damage = 100.0; if(victim <= MaxClients && victim > 0) {
ClearInventory(victim); damage = 10.0;
if(attacker > 0 && attacker <= MaxClients && IsFakeClient(victim)) { return Plugin_Changed;
PrintToChat(attacker, "That was a bot! -%.0f health", cvar_seekerFailDamageAmount.FloatValue); } else {
SDKHooks_TakeDamage(attacker, 0, 0, cvar_seekerFailDamageAmount.FloatValue, DMG_DIRECT); 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 { } else {
return Plugin_Continue; damage = 0.0;
}*/ return Plugin_Handled;
return Plugin_Continue; }
} }