Skip to content

Instantly share code, notes, and snippets.

@kimoto
Created September 24, 2010 02:40
Show Gist options
  • Select an option

  • Save kimoto/594769 to your computer and use it in GitHub Desktop.

Select an option

Save kimoto/594769 to your computer and use it in GitHub Desktop.
//
// spectator hud
// Usage:
// say !spectator_hud
// say !spechud2
//
// original: confoglcompmod
// source code base: http://phoenix.skullsaba.jp/hg/confogl218-hud/file/0cebaac0d041/modules/SpectatorHud.sp
// modified/customized by kimoto
//
// LICENCED BY GNU General Public License version 3
//
#include <sourcemod>
#include <sdktools>
#define SI_SMOKER 1
#define SI_BOOMER 2
#define SI_HUNTER 3
#define SI_SPITTER 4
#define SI_JOCKEY 5
#define SI_CHARGER 6
#define SI_WITCH 7
#define SI_TANK 8
#define SI_NOTINFECTED 9
#define TEAM_SPECTATORS 1
#define TEAM_SURVIVORS 2
#define TEAM_INFECTED 3
#define SH_INFECTED 5
const Float: SPECHUD_UPDATEINTERVAL = 0.5;
const NUM_OF_SURVIVORS = 4;
new SH_SurvivorIndex[NUM_OF_SURVIVORS] = 0;
new SH_InfectedIndex[SH_INFECTED] = 0;
new Handle: g_hSH_SpecHUD;
new bool: g_bSH_SpecHUD_ShowPanel[MAXPLAYERS+1] = true;
new bool: g_bSH_SpecHUD_ShowHint[MAXPLAYERS+1] = true;
new bool:bDebug = false;
#define CVAR_PREFIX "confogl_"
#define CVAR_FLAGS FCVAR_PLUGIN
new bool:bIsPluginEnabled = false;
Handle:CreateConVarEx(const String:name[], const String:defaultValue[], const String:description[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0)
{
decl String:sBuffer[128], Handle:cvar;
Format(sBuffer,sizeof(sBuffer),"%s%s",CVAR_PREFIX,name);
flags = flags | CVAR_FLAGS;
cvar = CreateConVar(sBuffer,defaultValue,description,flags,hasMin,min,hasMax,max);
return cvar;
}
Handle:FindConVarEx(const String:name[])
{
decl String:sBuffer[128];
Format(sBuffer,sizeof(sBuffer),"%s%s",CVAR_PREFIX,name);
return FindConVar(sBuffer);
}
bool:IsHumansOnServer()
{
for(new i=1;i<=MaxClients;i++)
{
if(IsClientConnected(i) && !IsFakeClient(i))
{
return true;
}
}
return false;
}
bool:IsVersus()
{
decl String:GameMode[32];
GetConVarString(FindConVar("mp_gamemode"), GameMode, sizeof(GameMode));
if(StrContains(GameMode, "versus", false) != -1)
{
return true;
}
return false;
}
bool:IsScavenge()
{
decl String:GameMode[32];
GetConVarString(FindConVar("mp_gamemode"), GameMode, sizeof(GameMode));
if(StrContains(GameMode, "scavenge", false) != -1)
{
return true;
}
return false;
}
bool:IsPluginEnabled(bool:bSetStatus=false,bool:bStatus=false)
{
if(bSetStatus)
{
bIsPluginEnabled = bStatus;
}
return bIsPluginEnabled;
}
stock GetSurvivorPermanentHealth(client)
{
return GetEntProp(client, Prop_Send, "m_iHealth");
}
stock GetSurvivorTempHealth(client)
{
new temphp = RoundToCeil(GetEntPropFloat(client, Prop_Send, "m_healthBuffer") - ((GetGameTime() - GetEntPropFloat(client, Prop_Send, "m_healthBufferTime")) * GetConVarFloat(FindConVar("pain_pills_decay_rate")))) - 1;
return temphp > 0 ? temphp : 0;
}
stock GetSurvivorIncapCount(client)
{
return GetEntProp(client, Prop_Send, "m_currentReviveCount");
}
stock bool:IsSurvivor(client)
{
return IsClientInGame(client) && GetClientTeam(client) == 2;
}
/**
* Finds the first occurrence of a pattern in another string.
*
* @param str String to search in.
* @param pattern String pattern to search for
* @param reverse False (default) to search forward, true to search
* backward.
* @return The index of the first character of the first
* occurrence of the pattern in the string, or -1 if the
* character was not found.
*/
stock FindPatternInString(const String:str[], const String:pattern[], bool:reverse = false)
{
new i, c, len;
len = strlen(pattern);
c = pattern[0];
while(i < len && (i = FindCharInString(str[i], c, reverse)) != -1)
if(strncmp(str[i], pattern, len))
return i;
return -1;
}
/**
* Counts the number of occurences of pattern in another string.
*
* @param str String to search in.
* @param pattern String pattern to search for
* @param overlap False (default) to count only non-overlapping
* occurences, true to count matches within other
* occurences.
* @return The number of occurences of the pattern in the string
*/
stock CountPatternsInString(const String:str[], const String:pattern[], bool:overlap=false)
{
new off, i, delta, cnt, len = strlen(str);
delta = overlap ? strlen(pattern) : 1;
while(i < len && (off = FindPatternInString(str[i], pattern)) != -1)
{
cnt++;
i+=off+delta;
}
return cnt;
}
/**
* Counts the number of occurences of pattern in another string.
*
* @param str String to search in.
* @param c Character to search for.
* @return The number of occurences of the pattern in the string
*/
stock CountCharsInString(const String:str[], c)
{
new off, i, cnt, len = strlen(str);
while(i < len && (off = FindCharInString(str[i], c)) != -1)
{
cnt++;
i+=off+1;
}
return cnt;
}
public OnPluginStart() {
Sub_DebugPrint("****************** ON PLUGIN START ***********************");
RegConsoleCmd("spechud2", SH_SpecHUD_Command, "Toggles Confogl\'s Spectator HUD");
RegConsoleCmd("spectator_hud", SH_SpecHUD_Command, "Toggles Confogl\'s Spectator HUD");
CreateTimer(SPECHUD_UPDATEINTERVAL, SH_SpecHUD_Timer, INVALID_HANDLE, TIMER_REPEAT);
}
public Action:SH_SpecHUD_Timer(Handle:timer) {
SH_BuildClientIndex();
SH_SpecHUD_Draw();
SH_SpecHUD_Update();
return Plugin_Continue;
}
public Sub_DebugPrint(const String:Message[], any:...)
{
if(bDebug){
decl String:DebugBuff[128];
VFormat(DebugBuff, sizeof(DebugBuff), Message, 2);
LogMessage(DebugBuff);
}
}
public Action:SH_SpecHUD_Command(client,args) {
// if true set to false, if false set to true
g_bSH_SpecHUD_ShowPanel[client] = !g_bSH_SpecHUD_ShowPanel[client];
if(g_bSH_SpecHUD_ShowPanel[client]) {
ReplyToCommand(client,"[Confogl] Spectator HUD is now enabled.");
} else {
ReplyToCommand(client,"[Confogl] Spectator HUD is now disabled.");
}
}
SH_OnClientDisconnect(client) {
g_bSH_SpecHUD_ShowPanel[client] = true;
g_bSH_SpecHUD_ShowHint[client] = true;
}
SH_BuildClientIndex() {
new isurvivors = 0;
new iinfected = 0;
// 初期化している
for(new i = 0; i < NUM_OF_SURVIVORS;i++)
SH_SurvivorIndex[i] = 0;
for(new i = 0; i < SH_INFECTED; i++)
SH_InfectedIndex[i] = 0;
// すべてのクライアントを対象に
for (new client = 1; client <= MaxClients; client++) {
// in gameまたは、spectatorのときは何もしない
if (!IsClientInGame(client) || GetClientTeam(client) == TEAM_SPECTATORS) {
continue;
}
// 生存者なら、生存者の配列に代入
if (GetClientTeam(client) == TEAM_SURVIVORS) {
SH_SurvivorIndex[isurvivors] = client;
isurvivors++;
} else {
// 感染者なら感染者の配列に代入
SH_InfectedIndex[iinfected] = client;
iinfected++;
}
}
}
SH_SpecHUD_Update() {
// すべてのクライアントを対象に
for(new client = 1;client < MaxClients+1;client++) {
// in gameじゃなくて、specでもなく、hudがenableでもなく、にせものクライアントのときはなにもしない
if(!IsClientInGame(client) || GetClientTeam(client) != TEAM_SPECTATORS || !g_bSH_SpecHUD_ShowPanel[client] || IsFakeClient(client)){continue;}
Sub_DebugPrint("********** Send panel to client: %d", client);
SendPanelToClient(g_hSH_SpecHUD, client, SH_SpecHUD_MenuHandler, 3);
if(g_bSH_SpecHUD_ShowHint[client]) {
g_bSH_SpecHUD_ShowHint[client] = false;
PrintToChat(client,"[Confogl] Type !spechud2 into chat to toggle the HUD.");
}
}
}
SH_SpecHUD_Draw() {
if(g_hSH_SpecHUD != INVALID_HANDLE) {
CloseHandle(g_hSH_SpecHUD);
}
Sub_DebugPrint("************************* START DRAWING SPECHUD2");
g_hSH_SpecHUD = CreatePanel();
decl String:sTempString[512], String:sWeaponString[64], String:sNameString[MAX_NAME_LENGTH+1];
new SIclass, survivorhealth, survivordown;
DrawPanelText(g_hSH_SpecHUD, "Confogl's Spectator HUD");
DrawPanelText(g_hSH_SpecHUD, "-------------------------------");
//start with survivor team first
for(new survivors = 0; survivors < NUM_OF_SURVIVORS; survivors++) {
//just incase
if(SH_SurvivorIndex[survivors] == 0) continue;
Sub_DebugPrint("*************** DRAWING: %d", survivors);
GetClientName(SH_SurvivorIndex[survivors],sNameString,sizeof(sNameString));
if(strlen(sNameString) > 25)
{
sNameString[22] = '.';
sNameString[23] = '.';
sNameString[24] = '.';
sNameString[25] = 0;
}
if(IsPlayerAlive(SH_SurvivorIndex[survivors])) {
GetClientWeapon(SH_SurvivorIndex[survivors],sWeaponString,sizeof(sWeaponString));
} else {
Format(sWeaponString, sizeof(sWeaponString), "Dead");
}
survivorhealth = GetSurvivorPermanentHealth(SH_SurvivorIndex[survivors]) + GetSurvivorTempHealth(SH_SurvivorIndex[survivors]);
survivordown = GetSurvivorIncapCount(SH_SurvivorIndex[survivors]);
if(survivordown != 0) {
Format(sTempString, sizeof(sTempString), "%s(%d): %s", sNameString, survivorhealth, sWeaponString);
} else {
Format(sTempString, sizeof(sTempString), "%s(%d Down, %d): %s", sNameString, survivordown, survivorhealth, sWeaponString);
}
DrawPanelText(g_hSH_SpecHUD, sTempString);
Sub_DebugPrint("**************** %s", sTempString);
}
DrawPanelText(g_hSH_SpecHUD, "\n");
//infected team
for(new infected = 0; infected < SH_INFECTED; infected++) {
//this is required
if(SH_InfectedIndex[infected] == 0) continue;
if(!IsFakeClient(SH_InfectedIndex[infected])) {
GetClientName(SH_InfectedIndex[infected],sNameString,sizeof(sNameString));
if(strlen(sNameString) > 25) {
sNameString[22] = '.';
sNameString[23] = '.';
sNameString[24] = '.';
sNameString[25] = 0;
}
} else {
Format(sNameString, sizeof(sNameString), "AI");
}
if(!IsPlayerAlive(SH_InfectedIndex[infected])) {
Format(sTempString, sizeof(sTempString), "%s: Dead", sNameString);
} else {
SIclass = GetEntProp(SH_InfectedIndex[infected], Prop_Send, "m_zombieClass");
//get name for SI
switch (SIclass) {
case SI_SMOKER:
{
Format(sWeaponString, sizeof(sWeaponString), "Smoker");
}
case SI_BOOMER:
{
Format(sWeaponString, sizeof(sWeaponString), "Boomer");
}
case SI_HUNTER:
{
Format(sWeaponString, sizeof(sWeaponString), "Hunter");
}
case SI_SPITTER:
{
Format(sWeaponString, sizeof(sWeaponString), "Spitter");
}
case SI_JOCKEY:
{
Format(sWeaponString, sizeof(sWeaponString), "Jockey");
}
case SI_CHARGER:
{
Format(sWeaponString, sizeof(sWeaponString), "Charger");
}
case SI_TANK:
{
Format(sWeaponString, sizeof(sWeaponString), "Tank");
}
default:
{
Format(sWeaponString, sizeof(sWeaponString), "Unknown");
}
}
if(GetEntProp(SH_InfectedIndex[infected], Prop_Send, "m_isGhost")) {
Format(sTempString, sizeof(sTempString), "%s: Spawning(%s)", sNameString, sWeaponString);
} else {
if(GetEntityFlags(SH_InfectedIndex[infected]) & FL_ONFIRE) {
Format(sTempString, sizeof(sTempString), "%s: %s(Burning: %d)", sNameString, sWeaponString, GetClientHealth(SH_InfectedIndex[infected]));
} else {
Format(sTempString, sizeof(sTempString), "%s: %s(%d)", sNameString, sWeaponString, GetClientHealth(SH_InfectedIndex[infected]));
}
}
}
DrawPanelText(g_hSH_SpecHUD, sTempString);
Sub_DebugPrint("***************** %s", sTempString);
}
Sub_DebugPrint("************************* END DRAWING SPECHUD2");
}
public SH_SpecHUD_MenuHandler(Handle:menu, MenuAction:action, param1, param2) {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment