Skip to content

Commit

Permalink
Integrate various in-progress spectating improvements from Nuclide
Browse files Browse the repository at this point in the history
  • Loading branch information
eukara committed Jan 8, 2024
1 parent 1c3fc2c commit bc4bd88
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 150 deletions.
84 changes: 6 additions & 78 deletions src/client/hud.qc
Original file line number Diff line number Diff line change
Expand Up @@ -751,89 +751,17 @@ HUD_Draw(void)
HUD_PlayerNames();
}

/* specatator main entry */
string g_specmodes[] = {
"Free Camera",
"Third Person",
"First Person"
};

#define SPEC_SEP_COL [0.204,0.196,0.114]
#define SPEC_FG_COL [0.561,0.561,0.212]
void
HUD_DrawSpectator(void)
{
vector vecPos = g_vec_null;
float flSep;
string strText;
int iMinutes, iSeconds;

Textmenu_Draw();
Obituary_Draw();

Textmenu_Draw();
if (!g_specHUD)
g_specHUD = spawn(CSSpectateHUD);

g_specHUD.SetPos(video_mins);
g_specHUD.SetSize(video_res);
g_specHUD.Draw();

/* parts on top and bottom */
drawfill(video_mins, [video_res[0], 32], [0,0,0], 0.75f, DRAWFLAG_NORMAL);
drawfill(video_mins + [0, video_res[1]-32], [video_res[0], 32], [0,0,0], 0.75f, DRAWFLAG_NORMAL);

/* tracking player box */
drawrect(g_hudmins + [(g_hudres[0] / 2) - 111, g_hudres[1]-26], [222,20], 1.0f, SPEC_SEP_COL, 1.0f, DRAWFLAG_NORMAL);
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
strText = strcat(HUD_GetChatColorHEX(getplayerkeyfloat(spec.spec_ent - 1, "*team")), getplayerkeyvalue(spec.spec_ent - 1, "name"));
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [12,12]) / 2);
vecPos[1] = g_hudres[1]-21;
drawstring(vecPos, strText, [12,12], [1,1,1], 1.0f, DRAWFLAG_NORMAL);

/* tracking mode box */
drawrect(g_hudmins + [(g_hudres[0] / 2) + 128, g_hudres[1]-26], [172,20], 1.0f, SPEC_SEP_COL, 1.0f, DRAWFLAG_NORMAL);
strText = g_specmodes[spec.spec_mode];
vecPos[0] = (g_hudmins[0] + (g_hudres[0] / 2) + 214) - (stringwidth(strText, TRUE, [12,12]) / 2);
vecPos[1] = g_hudres[1]-21;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

if (spec.spec_mode == SPECMODE_FIRSTPERSON) {
entity oself = self;
self = findfloat(world, ::entnum, spec.spec_ent);
if (self)
Cstrike_DrawCrosshair();
self = oself;
}

/* money */
strText = sprintf("$ %i", getstati(STAT_MONEY));
flSep = stringwidth(strText, TRUE, [12,12]);

if (flSep < 42)
flSep = 42;

flSep = g_hudmins[0] + (g_hudres[0] - flSep) - 10;

vecPos[0] = flSep + 8;
vecPos[1] = g_hudmins[1] + 3;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

/* score/money separator */
drawfill([flSep,1], [4,30], SPEC_SEP_COL, 1.0f, DRAWFLAG_NORMAL);

/* team scores */
drawfont = Font_GetID(FONT_CON);
strText = sprintf("Terrorist Forces: %s", serverkey("teamscore_1"));
vecPos[0] = flSep - stringwidth(strText, TRUE, [12,12]) - 2;
vecPos[1] = g_hudmins[1] + 3;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

strText = sprintf("CT Forces: %s", serverkey("teamscore_2"));
vecPos[0] = flSep - stringwidth(strText, TRUE, [12,12]) - 2;
vecPos[1] = g_hudmins[1] + 16;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

/* time display */
drawpic([flSep + 8, 15], "gfx/vgui/640_timer", [14, 14], [1,1,1], 1.0f, DRAWFLAG_NORMAL);
iMinutes = getstatf(STAT_GAMETIME) / 60;
iSeconds = getstatf(STAT_GAMETIME) - 60 * iMinutes;
strText = sprintf("%i:%02i", iMinutes, iSeconds);
vecPos[0] = flSep + 8 + 17;
vecPos[1] = g_hudmins[1] + 17;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);
}
1 change: 1 addition & 0 deletions src/client/progs.src
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ crosshair.qc
../../../valve/src/client/obituary.qc
../../../valve/src/client/hud_dmgnotify.qc
hud_ammonotify.qc
vgui_spectator.qc
hud.qc
hud_weaponselect.qc
../../../valve/src/client/hud_sprite.qc
Expand Down
2 changes: 1 addition & 1 deletion src/client/vgui_chooseteam.qc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ VGUI_ChooseTeam(void)
}

static void VGUI_ChooseTeam_Spec(void) {
//sendevent("JoinAuto", "");
sendevent("JoinSpectator", "");
winChooseTeam.Hide();
}

Expand Down
108 changes: 108 additions & 0 deletions src/client/vgui_spectator.qc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#define SPEC_SEP_COL [0.204,0.196,0.114]
#define SPEC_FG_COL [0.561,0.561,0.212]

class
CSSpectateHUD:VGUIWidget
{
void CSSpectateHUD(void);

virtual void Draw(void);
};
CSSpectateHUD g_specHUD;

void
CSSpectateHUD::CSSpectateHUD(void)
{

}

void
CSSpectateHUD::Draw(void)
{
vector vecPos = g_vec_null;
float flSep;
string strText;
int iMinutes, iSeconds;
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;

/* parts on top and bottom */
drawfill(m_vecOrigin, [m_vecSize[0], 32], [0,0,0], 0.75f, DRAWFLAG_NORMAL);
drawfill(m_vecOrigin + [0, m_vecSize[1]-32], [m_vecSize[0], 32], [0,0,0], 0.75f, DRAWFLAG_NORMAL);

/* tracking player box */
drawrect(g_hudmins + [(g_hudres[0] / 2) - 111, g_hudres[1]-26], [222,20], 1.0f, SPEC_SEP_COL, 1.0f, DRAWFLAG_NORMAL);
strText = strcat(HUD_GetChatColorHEX(getplayerkeyfloat(spec.spec_ent - 1, "*team")), getplayerkeyvalue(spec.spec_ent - 1, "name"));
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [12,12]) / 2);
vecPos[1] = g_hudres[1]-21;
drawstring(vecPos, strText, [12,12], [1,1,1], 1.0f, DRAWFLAG_NORMAL);

/* tracking mode box */
drawrect(g_hudmins + [(g_hudres[0] / 2) + 128, g_hudres[1]-26], [172,20], 1.0f, SPEC_SEP_COL, 1.0f, DRAWFLAG_NORMAL);
strText = g_specmodes[spec.spec_mode];
vecPos[0] = (g_hudmins[0] + (g_hudres[0] / 2) + 214) - (stringwidth(strText, TRUE, [12,12]) / 2);
vecPos[1] = g_hudres[1]-21;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

#if 0
if (spec.spec_mode == SPECMODE_FIRSTPERSON) {
entity oself = self;
self = findfloat(world, ::entnum, spec.spec_ent);
if (self)
Cstrike_DrawCrosshair();
self = oself;
}
#endif

/* money */
strText = sprintf("$ %i", getstati(STAT_MONEY));
flSep = stringwidth(strText, TRUE, [12,12]);

if (flSep < 42)
flSep = 42;

flSep = g_hudmins[0] + (g_hudres[0] - flSep) - 10;

vecPos[0] = flSep + 8;
vecPos[1] = g_hudmins[1] + 3;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

/* score/money separator */
drawfill([flSep,1], [4,30], SPEC_SEP_COL, 1.0f, DRAWFLAG_NORMAL);

/* team scores */
drawfont = Font_GetID(FONT_CON);
strText = sprintf("Terrorist Forces: %s", serverkey("teamscore_1"));
vecPos[0] = flSep - stringwidth(strText, TRUE, [12,12]) - 2;
vecPos[1] = g_hudmins[1] + 3;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

strText = sprintf("CT Forces: %s", serverkey("teamscore_2"));
vecPos[0] = flSep - stringwidth(strText, TRUE, [12,12]) - 2;
vecPos[1] = g_hudmins[1] + 16;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);

/* time display */
drawpic([flSep + 8, 15], "gfx/vgui/640_timer", [14, 14], [1,1,1], 1.0f, DRAWFLAG_NORMAL);
iMinutes = getstatf(STAT_GAMETIME) / 60;
iSeconds = getstatf(STAT_GAMETIME) - 60 * iMinutes;
strText = sprintf("%i:%02i", iMinutes, iSeconds);
vecPos[0] = flSep + 8 + 17;
vecPos[1] = g_hudmins[1] + 17;
drawstring(vecPos, strText, [12,12], SPEC_FG_COL, 1.0f, DRAWFLAG_NORMAL);
}
71 changes: 12 additions & 59 deletions src/server/gamerules_deathmatch.qc
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

const string mp_teamlist_fallback = "robo;hgrunt";
var string autocvar_mp_teamlist = mp_teamlist_fallback;

string
CSDeathmatchRules::Title(void)
{
Expand Down Expand Up @@ -60,25 +57,11 @@ CSDeathmatchRules::InitPostEnts(void)
forceinfokey(world, "scorepoints", "0");

if (IsTeamplay() == true) {
int c;

/* get the segments from our cvar */
m_strTeamList = autocvar_mp_teamlist;
c = tokenizebyseparator(m_strTeamList, ";");

/* if we've got less than 2 teams, use the fallback... */
if (c < 2) {
m_strTeamList = mp_teamlist_fallback;
c = tokenizebyseparator(m_strTeamList, ";");
}

forceinfokey(world, "teams", itos(c));

/* initialize all dem teams */
for (int i = 0; i < c; i++) {
forceinfokey(world, sprintf("team_%i", i+1i), argv(i));
forceinfokey(world, sprintf("teamscore_%i", i+1i), "0");
}
forceinfokey(world, "teams", "2");
forceinfokey(world, "team_1", "Counter-Terrorist");
forceinfokey(world, "teamscore_1", "0");
forceinfokey(world, "team_2", "Terrorist");
forceinfokey(world, "teamscore_2", "0");
} else {
forceinfokey(world, "teams", "0");
}
Expand Down Expand Up @@ -167,7 +150,6 @@ void
CSDeathmatchRules::PlayerSpawn(NSClientPlayer pp)
{
player pl = (player)pp;
string playerModel;
/* this is where the mods want to deviate */
entity spot;

Expand All @@ -190,11 +172,13 @@ CSDeathmatchRules::PlayerSpawn(NSClientPlayer pp)
/* TODO: this should sort us into the lowest team */
if (playerTeam == 0) {
playerTeam = 1i + (int)floor(random(0, (float)teamCount)); /* teams start at 1 after all */
pl.SetTeam(playerTeam);
pl.SetTeam(random() < 0.5 ? TEAM_CT : TEAM_T);
}

/* assign our player model */
playerModel = sprintf("models/player/%s/%s.mdl", argv(playerTeam - 1i), argv(playerTeam - 1i));
if (playerTeam == TEAM_T)
pl.charmodel = floor(random(1,5));
else
pl.charmodel = floor(random(5,9));
} else {
pl.charmodel = rint(random(1,9));
}
Expand Down Expand Up @@ -228,12 +212,8 @@ CSDeathmatchRules::PlayerSpawn(NSClientPlayer pp)
pl.model = "models/player/vip/vip.mdl";
}

/* fallback is always models/player.mdl for Half-Life */
if not (whichpack(playerModel)) {
playerModel = "models/player.mdl";
}

pl.SetModel(playerModel);
pl.SetModel(pl.model);
pl.SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
pl.ClearVelocity();
pl.gravity = __NULL__;
Expand Down Expand Up @@ -306,31 +286,4 @@ CSDeathmatchRules::CSDeathmatchRules(void)
/* these lines do nothing but tell the server to register those cvars */
autocvar(timelimit, 15, "Timelimit for multiplayer rounds");
autocvar(fraglimit, 15, "Points limit for multiplayer rounds");
}

void
CSEv_HLDM_Chooseteam_s(string teamName)
{
CSGameRules rules = (CSGameRules)g_grMode;
player pl = (player)self;

if (!teamName)
return;
if (rules.IsMultiplayer() == false)
return;
if (rules.IsTeamplay() == false)
return;
if (pl.IsDead() == true)
return;

CSDeathmatchRules mprules = (CSDeathmatchRules)rules;
int c = tokenizebyseparator(mprules.m_strTeamList, ";");

for (int i = 0; i < c; i++) {
if (argv(i) == teamName) {
pl.SetTeam((float)i + 1);
Damage_Apply(pl, pl, 100, 0, DMG_SKIP_ARMOR);
return;
}
}
}
}
Loading

0 comments on commit bc4bd88

Please sign in to comment.