mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 00:43:20 +00:00
work on prophunt
This commit is contained in:
parent
9010b630d5
commit
c68fac6359
6 changed files with 323 additions and 168 deletions
Binary file not shown.
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
|
@ -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];
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue