Client: Some misc VGUI related improvements.

This commit is contained in:
Marco Cawthorne 2023-04-03 11:15:23 -07:00
parent df6cec18d0
commit 04a11d6317
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
14 changed files with 542 additions and 249 deletions

View File

@ -44,8 +44,11 @@ ClientGame_PostDraw(void)
{ {
player pl = (player)pSeat->m_ePlayer; player pl = (player)pSeat->m_ePlayer;
if (serverkeyfloat("areadefs") == 1) if (serverkeyfloat("areadefs") == 1) {
Font_DrawText([16,16], getplayerkeyvalue(player_localnum, "*areadef"), FONT_CON); string strArea = getplayerkeyvalue(player_localnum, "*areadef");
float flOffset = Font_StringWidth(strArea, TRUE, FONT_20) / 2;
Font_DrawText_A([g_hudmins[0] + 16, g_hudmins[1] + g_hudres[1] - 70], strArea, 0.75, FONT_20);
}
if (pl.g_items & ITEM_GOALITEM) { if (pl.g_items & ITEM_GOALITEM) {
vector vecGoalItemPos; vector vecGoalItemPos;

View File

@ -14,76 +14,243 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
static CUIWindow winClassSelection; static string g_classDescrScout;
static string g_classDescrSniper;
static string g_classDescrSoldier;
static string g_classDescrDemoman;
static string g_classDescrMedic;
static string g_classDescrHWGuy;
static string g_classDescrPyro;
static string g_classDescrSpy;
static string g_classDescrEngineer;
static string g_classDescrRandomPC;
typedef struct static void
TFCClass_Init(void)
{ {
string str; g_classDescrScout = textfile_to_string("classes/short_scout.txt");
void(void) ptr; g_classDescrSniper = textfile_to_string("classes/short_sniper.txt");
} btnarr_t; g_classDescrSoldier = textfile_to_string("classes/short_soldier.txt");
g_classDescrDemoman = textfile_to_string("classes/short_demoman.txt");
g_classDescrMedic = textfile_to_string("classes/short_medic.txt");
g_classDescrHWGuy = textfile_to_string("classes/short_hwguy.txt");
g_classDescrPyro = textfile_to_string("classes/short_pyro.txt");
g_classDescrSpy = textfile_to_string("classes/short_spy.txt");
g_classDescrEngineer = textfile_to_string("classes/short_engineer.txt");
g_classDescrRandomPC = textfile_to_string("classes/short_randompc.txt");
}
static VGUIWindow winClassSelection;
static VGUIPic imgClassPreview;
static VGUILabel lblClassTitle;
static VGUILabel lblClassDescription;
static VGUILabel lblClassCounter;
class TFClassButton:VGUIButton
{
void TFClassButton(void);
virtual void OnMouseUp(void);
virtual void OnMouseEntered(void);
};
void void
VGUI_ClassJoin(float i) TFClassButton::TFClassButton(void)
{ {
sendevent("ClassJoin", "f", i); }
void
TFClassButton::OnMouseUp(void)
{
int tag = GetTag();
winClassSelection.Hide(); winClassSelection.Hide();
int classSelection = GetTag();
switch (classSelection) {
case 0:
sendevent("ClassJoin", "f", 1);
break;
case 1:
sendevent("ClassJoin", "f", 2);
break;
case 2:
sendevent("ClassJoin", "f", 3);
break;
case 3:
sendevent("ClassJoin", "f", 4);
break;
case 4:
sendevent("ClassJoin", "f", 5);
break;
case 5:
sendevent("ClassJoin", "f", 6);
break;
case 6:
sendevent("ClassJoin", "f", 7);
break;
case 7:
sendevent("ClassJoin", "f", 8);
break;
case 8:
sendevent("ClassJoin", "f", 9);
break;
case 9:
sendevent("ClassJoin", "f", 0);
break;
}
} }
void void
VGUI_TeamBack(void) TFClassButton::OnMouseEntered(void)
{ {
int classSelection = GetTag();
string teamName = "blue";
switch (getplayerkeyfloat(player_localnum, "*team")) {
case 1:
teamName = "blue";
break;
case 2:
teamName = "red";
break;
case 3:
teamName = "blue"; /* TFC doesn't ship with a real green. */
break;
case 4:
teamName = "red"; /* TFC doesn't ship with a real yellow either. */
break;
}
switch (classSelection) {
case 0:
lblClassTitle.SetTitle("Scout");
imgClassPreview.SetImage(strcat("gfx/vgui/640_scout", teamName));
lblClassDescription.SetTitle(g_classDescrScout);
break;
case 1:
lblClassTitle.SetTitle("Sniper");
imgClassPreview.SetImage(strcat("gfx/vgui/640_sniper", teamName));
lblClassDescription.SetTitle(g_classDescrSniper);
break;
case 2:
lblClassTitle.SetTitle("Soldier");
imgClassPreview.SetImage(strcat("gfx/vgui/640_soldier", teamName));
lblClassDescription.SetTitle(g_classDescrSoldier);
break;
case 3:
lblClassTitle.SetTitle("Demoman");
imgClassPreview.SetImage(strcat("gfx/vgui/640_demoman", teamName));
lblClassDescription.SetTitle(g_classDescrDemoman);
break;
case 4:
lblClassTitle.SetTitle("Medic");
imgClassPreview.SetImage(strcat("gfx/vgui/640_medic", teamName));
lblClassDescription.SetTitle(g_classDescrMedic);
break;
case 5:
lblClassTitle.SetTitle("Heavy Weapons Guy");
imgClassPreview.SetImage(strcat("gfx/vgui/640_hwguy", teamName));
lblClassDescription.SetTitle(g_classDescrHWGuy);
break;
case 6:
lblClassTitle.SetTitle("Pyro");
imgClassPreview.SetImage(strcat("gfx/vgui/640_pyro", teamName));
lblClassDescription.SetTitle(g_classDescrPyro);
break;
case 7:
lblClassTitle.SetTitle("Spy");
imgClassPreview.SetImage(strcat("gfx/vgui/640_spy", teamName));
lblClassDescription.SetTitle(g_classDescrSpy);
break;
case 8:
lblClassTitle.SetTitle("Engineer");
imgClassPreview.SetImage(strcat("gfx/vgui/640_engineer", teamName));
lblClassDescription.SetTitle(g_classDescrEngineer);
break;
case 9:
lblClassTitle.SetTitle("Random");
imgClassPreview.SetImage(strcat("gfx/vgui/640_randompc", teamName));
lblClassDescription.SetTitle(g_classDescrRandomPC);
break;
}
} }
void VGUI_JoinScout (void) { VGUI_ClassJoin(1); } string g_classnames [] = {
void VGUI_JoinSniper (void) { VGUI_ClassJoin(2); } "SCOUT",
void VGUI_JoinSoldier (void) { VGUI_ClassJoin(3); } "SNIPER",
void VGUI_JoinDemoman (void) { VGUI_ClassJoin(4); } "SOLDIER",
void VGUI_JoinMedic (void) { VGUI_ClassJoin(5); } "DEMOMAN",
void VGUI_JoinHwguy (void) { VGUI_ClassJoin(6); } "MEDIC",
void VGUI_JoinPyro (void) { VGUI_ClassJoin(7); } "HWGUY",
void VGUI_JoinSpy (void) { VGUI_ClassJoin(8); } "PYRO",
void VGUI_JoinEngineer (void) { VGUI_ClassJoin(9); } "SPY",
"ENGINEER",
btnarr_t g_tfc_vgui_classlist[] = { "RANDOM"
{"SCOUT", VGUI_JoinScout },
{"SNIPER", VGUI_JoinSniper },
{"SOLDIER", VGUI_JoinSoldier },
{"DEMOMAN", VGUI_JoinDemoman },
{"MEDIC", VGUI_JoinMedic },
{"HWGUY", VGUI_JoinHwguy },
{"PYRO", VGUI_JoinPyro },
{"SPY", VGUI_JoinSpy },
{"ENGINEER", VGUI_JoinEngineer },
{__NULL__, __NULL__ },
{"< Back", VGUI_TeamBack }
}; };
void void
VGUI_ChooseClass(void) VGUI_ChooseClass(void)
{ {
static int initialized; static int initialized;
static CUIButton *btns; static TFClassButton *btns;
static VGUILabel lblSelectClass;
static VGUIFrame frmClassInfo;
if (!initialized) { if (!initialized) {
vector btnpos = [16,0]; vector btnpos = [40,80];
initialized = TRUE; initialized = TRUE;
winClassSelection = spawn(CUIWindow);
winClassSelection.SetTitle("Choose Skin");
winClassSelection.SetSize([420,320]);
g_uiDesktop.Add(winClassSelection);
btns = memalloc(sizeof(btnarr_t) * g_tfc_vgui_classlist.length); TFCClass_Init();
for (int i = 0; i < g_tfc_vgui_classlist.length; i++) {
btnpos[1] += 30; winClassSelection = spawn(VGUIWindow);
if (g_tfc_vgui_classlist[i].ptr == __NULL__) { winClassSelection.SetSize([640, 480]);
continue; winClassSelection.SetStyleMask(VGUIWindowBorderless | VGUIWindowFullscreen);
}
btns[i] = spawn(CUIButton); lblSelectClass = spawn(VGUILabel);
btns[i].SetTitle(g_tfc_vgui_classlist[i].str); lblSelectClass.SetTitle("SELECT YOUR CLASS");
lblSelectClass.SetTextSize(19);
lblSelectClass.SetPos([40, 38]);
lblSelectClass.SetSize([400, 24]);
frmClassInfo = spawn(VGUIFrame);
frmClassInfo.SetPos([176, 80]);
frmClassInfo.SetSize([424, 312]);
imgClassPreview = spawn(VGUIPic);
imgClassPreview.SetPos([190, 90]);
lblClassTitle = spawn(VGUILabel);
lblClassTitle.SetPos([338, 90]);
lblClassTitle.SetTextSize(19);
lblClassTitle.SetSize([320, 24]);
lblClassCounter = spawn(VGUILabel);
lblClassCounter.SetPos([338, 90 + 32]);
lblClassCounter.SetSize([320, 18]);
lblClassDescription = spawn(VGUILabel);
lblClassDescription.SetPos([338, 90 + 32 + 32]);
lblClassDescription.SetSize([250, 240]);
g_uiDesktop.Add(winClassSelection);
winClassSelection.Add(lblSelectClass);
winClassSelection.Add(frmClassInfo);
winClassSelection.Add(imgClassPreview);
winClassSelection.Add(lblClassTitle);
winClassSelection.Add(lblClassCounter);
winClassSelection.Add(lblClassDescription);
btns = memalloc(sizeof(TFClassButton) * g_classnames.length);
for (int i = 0; i < g_classnames.length; i++) {
btns[i] = spawn(TFClassButton);
btns[i].SetTitle(g_classnames[i]);
btns[i].SetSize([124, 24]);
btns[i].SetPos(btnpos); btns[i].SetPos(btnpos);
btns[i].SetFunc(g_tfc_vgui_classlist[i].ptr); btns[i].SetTag(i);
winClassSelection.Add(btns[i]); winClassSelection.Add(btns[i]);
btnpos[1] += 32;
} }
} }

View File

@ -14,96 +14,140 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
static CUIWindow winChooseTeam; static VGUIWindow winChooseTeam;
class TFTeamButton:VGUIButton
{
void TFTeamButton(void);
virtual void OnMouseUp(void);
};
void void
VGUI_ChooseTeam_Blue(void) TFTeamButton::TFTeamButton(void)
{ {
localcmd("changeclass\n");
sendevent("TeamJoin", "f", 1);
winChooseTeam.Hide();
} }
void void
VGUI_ChooseTeam_Red(void) TFTeamButton::OnMouseUp(void)
{ {
int tag = GetTag();
localcmd("changeclass\n"); localcmd("changeclass\n");
sendevent("TeamJoin", "f", 2); sendevent("TeamJoin", "f", (float)tag);
winChooseTeam.Hide(); winChooseTeam.Hide();
} }
void
VGUI_ChooseTeam_Green(void)
{
localcmd("changeclass\n");
sendevent("TeamJoin", "f", 3);
winChooseTeam.Hide();
}
void string
VGUI_ChooseTeam_Yellow(void) VGUI_ChooseTeam_MapInfo(void)
{ {
localcmd("changeclass\n"); static string mapinfo = __NULL__;
sendevent("TeamJoin", "f", 4);
winChooseTeam.Hide();
}
void if (mapinfo != __NULL__)
VGUI_GoSpectator(void) return mapinfo;
{
//VGUI_TeamJoin(0); filestream fileMap = fopen(strcat("maps/", mapname, ".txt"), FILE_READ);
sendevent("TeamJoin", "f", 0); string temp;
winChooseTeam.Hide();
if (fileMap != -1) {
while ((temp = fgets(fileMap))) {
mapinfo = strcat(mapinfo, temp, "\n");
}
} else {
mapinfo = "No map info available.";
}
return mapinfo;
} }
void void
VGUI_ChooseTeam(void) VGUI_ChooseTeam(void)
{ {
static int initialized; static int initialized;
static CUIButton btnGoSpectator; static VGUIButton btnAutoAssign;
static VGUIButton btnGoSpectator;
static VGUIFrame frmMapInfo;
static VGUILabel lblSelectTeam;
static VGUILabel lblMapName;
static VGUILabel lblMapInfo;
if (!initialized) { if (!initialized) {
vector btnpos = [16,48]; vector btnpos = [40,80];
initialized = TRUE; initialized = TRUE;
winChooseTeam = spawn(CUIWindow); winChooseTeam = spawn(VGUIWindow);
winChooseTeam.SetTitle("Choose Team"); winChooseTeam.SetSize('640 480');
winChooseTeam.SetSize('420 320'); winChooseTeam.SetStyleMask(VGUIWindowBorderless | VGUIWindowFullscreen);
lblSelectTeam = spawn(VGUILabel);
lblSelectTeam.SetTitle("SELECT YOUR TEAM");
lblSelectTeam.SetTextSize(19);
lblSelectTeam.SetPos([40, 38]);
lblSelectTeam.SetSize('400 24');
frmMapInfo = spawn(VGUIFrame);
frmMapInfo.SetPos('176 80');
frmMapInfo.SetSize('424 312');
lblMapName = spawn(VGUILabel);
lblMapName.SetTitle(mapname);
lblMapName.SetTextSize(19);
lblMapName.SetPos('194 105');
lblMapName.SetSize('250 312');
lblMapInfo = spawn(VGUILabel);
lblMapInfo.SetTitle(VGUI_ChooseTeam_MapInfo());
lblMapInfo.SetPos('194 129');
lblMapInfo.SetSize('375 250');
for (int t = 1; t <= serverkeyfloat("teams"); t++) { for (int t = 1; t <= serverkeyfloat("teams"); t++) {
CUIButton btnForTeam; TFTeamButton btnForTeam;
string team_name = serverkey(sprintf("team_%i", t)); string team_name = serverkey(sprintf("team_%i", t));
btnForTeam = spawn(CUIButton); btnForTeam = spawn(TFTeamButton);
btnForTeam.SetTitle(team_name); btnForTeam.SetTitle(strtoupper(team_name));
btnForTeam.SetPos(btnpos); btnForTeam.SetPos(btnpos);
btnForTeam.SetSize('124 24');
switch (team_name) { switch (team_name) {
case "Blue": case "Blue":
btnForTeam.SetFunc(VGUI_ChooseTeam_Blue); btnForTeam.SetTag(1);
break; break;
case "Red": case "Red":
btnForTeam.SetFunc(VGUI_ChooseTeam_Red); btnForTeam.SetTag(2);
break; break;
case "Green": case "Green":
btnForTeam.SetFunc(VGUI_ChooseTeam_Green); btnForTeam.SetTag(3);
break; break;
case "Yellow": case "Yellow":
btnForTeam.SetFunc(VGUI_ChooseTeam_Yellow); btnForTeam.SetTag(4);
break; break;
} }
winChooseTeam.Add(btnForTeam); winChooseTeam.Add(btnForTeam);
btnpos[1] += 30; btnpos[1] += 32;
} }
btnAutoAssign = spawn(VGUIButton);
btnAutoAssign.SetTitle("AUTO ASSIGN");
btnAutoAssign.SetPos(btnpos);
btnAutoAssign.SetSize('124 24');
//btnAutoAssign.SetFunc(VGUI_AutoAssign);
btnpos[1] += 32;
btnGoSpectator = spawn(CUIButton); btnGoSpectator = spawn(VGUIButton);
btnGoSpectator.SetTitle("Spectator"); btnGoSpectator.SetTitle("SPECTATE");
btnGoSpectator.SetPos('8 252'); btnGoSpectator.SetPos(btnpos);
btnGoSpectator.SetFunc(VGUI_GoSpectator); btnGoSpectator.SetSize('124 24');
//btnGoSpectator.SetFunc(VGUI_GoSpectator);
g_uiDesktop.Add(winChooseTeam); g_uiDesktop.Add(winChooseTeam);
winChooseTeam.Add(frmMapInfo);
winChooseTeam.Add(lblSelectTeam);
winChooseTeam.Add(lblMapName);
winChooseTeam.Add(lblMapInfo);
winChooseTeam.Add(btnAutoAssign);
winChooseTeam.Add(btnGoSpectator); winChooseTeam.Add(btnGoSpectator);
} }

View File

@ -300,6 +300,12 @@ info_tfgoal::SpawnKey(string strKey, string strValue)
break; break;
case "mdl": case "mdl":
model = strValue; model = strValue;
if (serverkeyfloat("*bspversion") == 0) {
model = strreplace("progs", "models", model);
model = strreplace("tf_stan", "flag", model);
}
break; break;
case "goal_state": case "goal_state":
m_tfgState = stof(strValue); m_tfgState = stof(strValue);

View File

@ -139,6 +139,8 @@ item_tfgoal::Touch(entity eToucher)
player pl = (player)eToucher; player pl = (player)eToucher;
/* not in standard TFC, make cvar? */
#if 0
/* if it's dropped, just let the other team return it... /* if it's dropped, just let the other team return it...
otherwise let the other teams pick it up as normal */ otherwise let the other teams pick it up as normal */
if (m_status == GISTATUS_DROPPED) { if (m_status == GISTATUS_DROPPED) {
@ -147,6 +149,7 @@ item_tfgoal::Touch(entity eToucher)
return; return;
} }
} }
#endif
/* team filter */ /* team filter */
if (m_iTeamUses) if (m_iTeamUses)
@ -250,6 +253,11 @@ item_tfgoal::SpawnKey(string strKey, string strValue)
break; break;
case "mdl": case "mdl":
model = strValue; model = strValue;
if (serverkeyfloat("*bspversion") == BSPVER_Q1) {
model = strreplace("progs", "models", model);
model = strreplace("tf_stan", "flag", model);
}
break; break;
case "goal_no": case "goal_no":
m_dItemID = stof(strValue); m_dItemID = stof(strValue);

View File

@ -289,15 +289,71 @@ TFCNade_ThrowMIRV(player pl)
void void
TFCNade_ThrowNapalm(player pl) TFCNade_ThrowNapalm(player pl)
{ {
vector vecNadeVelocity;
float flTimer;
print("Throwing Napalm grenade!\n"); static void TFCNade_ThrowConcussion_Touch(void) {
Sound_Play(self, CHAN_BODY, "weapon_handgrenade.bounce");
if (!vlen(self.velocity))
self.avelocity = g_vec_null;
}
static void TFCNade_ThrowConcussion_Explode(void) {
NSEntity::Destroy();
}
Weapons_MakeVectors(pl);
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
NSRenderableEntity eNade = spawn(NSRenderableEntity);
eNade.SetModel("models/napalm.mdl");
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
eNade.SetOwner(pl);
eNade.SetMovetype(MOVETYPE_BOUNCE);
eNade.SetSolid(SOLID_BBOX);
eNade.SetGravity(1.0f);
eNade.SetVelocity(vecNadeVelocity);
eNade.SetAngularVelocity([0, 600, 0]);
eNade.touch = TFCNade_ThrowConcussion_Touch;
eNade.ScheduleThink(TFCNade_ThrowConcussion_Explode, flTimer);
} }
void void
TFCNade_ThrowHallucination(player pl) TFCNade_ThrowHallucination(player pl)
{ {
vector vecNadeVelocity;
float flTimer;
print("Throwing Hallucination grenade!\n"); static void TFCNade_ThrowConcussion_Touch(void) {
Sound_Play(self, CHAN_BODY, "weapon_handgrenade.bounce");
if (!vlen(self.velocity))
self.avelocity = g_vec_null;
}
static void TFCNade_ThrowConcussion_Explode(void) {
NSEntity::Destroy();
}
Weapons_MakeVectors(pl);
vecNadeVelocity = v_forward * 600 + v_up * 200 + crandom() * v_right * 10 + crandom() * v_up * 10;
flTimer = max(0.0, pl.gren2.GetNextThinkTime() - time);
NSRenderableEntity eNade = spawn(NSRenderableEntity);
eNade.SetModel("models/spy_grenade.mdl");
eNade.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 14) + (v_up * -4) + (v_right * 2));
eNade.SetOwner(pl);
eNade.SetMovetype(MOVETYPE_BOUNCE);
eNade.SetSolid(SOLID_BBOX);
eNade.SetGravity(1.0f);
eNade.SetVelocity(vecNadeVelocity);
eNade.SetAngularVelocity([0, 600, 0]);
eNade.touch = TFCNade_ThrowConcussion_Touch;
eNade.ScheduleThink(TFCNade_ThrowConcussion_Explode, flTimer);
} }
void void

View File

@ -27,7 +27,8 @@ TFCSentry::Think(void)
if (vlen(origin - p.origin) > 1024) if (vlen(origin - p.origin) > 1024)
continue; continue;
print(sprintf("Is Facing? %d\n", IsFacing(p))); if (team == p.team)
continue;
if (IsFacing(p) == false) if (IsFacing(p) == false)
continue; continue;
@ -62,12 +63,13 @@ TFCSentry::Think(void)
m_state = SENTRY_SEARCHING; m_state = SENTRY_SEARCHING;
else { else {
makevectors([0, angles[1], 0]); makevectors([0, angles[1], 0]);
m_flWantAngle = dotproduct(normalize(origin - t.origin), v_right); m_flWantAngle = dotproduct((origin - t.origin), v_right);
m_flCurrAngle = Math_Lerp(m_flCurrAngle, m_flWantAngle, 0.25f); m_flCurrAngle = Math_Lerp(m_flCurrAngle, m_flWantAngle, 0.25f);
m_eHead.SetBoneControl1(m_flCurrAngle); m_eHead.SetBoneControl1(m_flCurrAngle);
print(sprintf("head: %f; want: %f\n", m_flCurrAngle, m_flWantAngle));
/* fire bullets */ /* fire bullets */
v_angle = vectoangles(normalize(origin - t.origin)); input_angles = v_angle = vectoangles(origin - t.origin);
TraceAttack_FireBullets(1, origin, 5, [0.025,0.025], WEAPON_NONE); TraceAttack_FireBullets(1, origin, 5, [0.025,0.025], WEAPON_NONE);
} }
} }
@ -87,6 +89,7 @@ TFCSentry::Place(NSClientPlayer pl)
ScheduleThink(FinishPlacing, 5.0f); ScheduleThink(FinishPlacing, 5.0f);
real_owner = pl; real_owner = pl;
colormap = pl.colormap; colormap = pl.colormap;
team = pl.team;
env_message_single(real_owner, "#Engineer_building"); env_message_single(real_owner, "#Engineer_building");
Sound_Play(this, CHAN_BODY, "engineer.build"); Sound_Play(this, CHAN_BODY, "engineer.build");

View File

@ -50,14 +50,23 @@ CSEv_TeamJoin_f(float f)
} }
} }
/** Called by the client-side VGUI menu when we choose a class. */
void void
CSEv_ClassJoin_f(float f) CSEv_ClassJoin_f(float f)
{ {
player pl = (player)self; player pl = (player)self;
/* choose a random class. */
if (f == 0) {
float newClass = 0;
while (newClass == 0 || newClass == pl.classtype)
newClass = floor(random(CLASS_SCOUT, CLASS_ENGINEER + 1));
f = newClass;
}
/* invalid */ /* invalid */
if (pl.team == 0) { if (pl.team == 0) {
return; return;

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2016-2022 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.
*/
enum enum
{ {
TFCANIM_DIEGUTSHOT = ANIM_DIEGUTSHOT, TFCANIM_DIEGUTSHOT = ANIM_DIEGUTSHOT,

View File

@ -28,6 +28,19 @@ typedef enum
} classtype_e; } classtype_e;
string g_teammodels[] = { string g_teammodels[] = {
"",
"models/player/scout/scout.mdl",
"models/player/sniper/sniper.mdl",
"models/player/soldier/soldier.mdl",
"models/player/demo/demo.mdl",
"models/player/medic/medic.mdl",
"models/player/hvyweapon/hvyweapon.mdl",
"models/player/pyro/pyro.mdl",
"models/player/spy/spy.mdl",
"models/player/engineer/engineer.mdl"
};
string g_teammodels_hd[] = {
"", "",
"models/player/scout/scout2.mdl", "models/player/scout/scout2.mdl",
"models/player/sniper/sniper2.mdl", "models/player/sniper/sniper2.mdl",
@ -39,3 +52,26 @@ string g_teammodels[] = {
"models/player/spy/spy2.mdl", "models/player/spy/spy2.mdl",
"models/player/engineer/engineer2.mdl" "models/player/engineer/engineer2.mdl"
}; };
/* are we using a later build of TF? */
bool
TFC_IsLaterBuild(void)
{
if (whichpack(g_teammodels_hd[1]))
return true;
return false;
}
/* stuff */
string
TFC_GetModelForClasstype(classtype_e type)
{
if (TFC_IsLaterBuild() == true)
if (autocvar(tfc_newmodels, 0) == 1)
return g_teammodels[type]; /* on later versions, the old names are the HD ones */
else
return g_teammodels_hd[type];
return g_teammodels[type];
}

View File

@ -436,42 +436,32 @@ player::ReceiveEntity
================= =================
*/ */
void void
player::ReceiveEntity(float new, float fl) player::ReceiveEntity(float new, float flChanged)
{ {
/* the generic client attributes */ /* the generic client attributes */
NSClientPlayer::ReceiveEntity(new, fl); super::ReceiveEntity(new, flChanged);
/* animation */ /* animation */
if (fl & PLAYER_TOPFRAME) { READENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
anim_top = readbyte(); READENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
anim_top_time = readfloat(); READENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME)
anim_top_delay = readfloat(); READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME)
} READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME)
if (fl & PLAYER_BOTTOMFRAME) {
anim_bottom = readbyte();
anim_bottom_time = readfloat();
}
if (fl & PLAYER_AMMO1) { READENTITY_BYTE(mag_sbs, PLAYER_AMMO1)
mag_sbs = readbyte(); READENTITY_BYTE(mag_dbs, PLAYER_AMMO1)
mag_dbs = readbyte(); READENTITY_BYTE(mag_rpg, PLAYER_AMMO1)
mag_rpg = readbyte(); READENTITY_BYTE(mag_glauncher, PLAYER_AMMO1)
mag_glauncher = readbyte();
}
if (fl & PLAYER_AMMO2) {
m_iAmmoRockets = readbyte();
m_iAmmoNails = readbyte();
m_iAmmoCells = readbyte();
m_iAmmoShells = readbyte();
m_iAmmoDetpack = readbyte();
m_iAmmoMedikit = readbyte();
}
if (fl & PLAYER_AMMO3) { READENTITY_BYTE(m_iAmmoRockets, PLAYER_AMMO2)
mode_tempstate = readbyte(); READENTITY_BYTE(m_iAmmoNails, PLAYER_AMMO2)
classtype = readbyte(); READENTITY_BYTE(m_iAmmoCells, PLAYER_AMMO2)
} READENTITY_BYTE(m_iAmmoShells, PLAYER_AMMO2)
READENTITY_BYTE(m_iAmmoDetpack, PLAYER_AMMO2)
READENTITY_BYTE(m_iAmmoMedikit, PLAYER_AMMO2)
READENTITY_BYTE(mode_tempstate, PLAYER_AMMO3)
READENTITY_BYTE(classtype, PLAYER_AMMO3)
setorigin(this, origin); setorigin(this, origin);
@ -481,15 +471,15 @@ player::ReceiveEntity(float new, float fl)
return; return;
/* do not notify us of updates when spawning initially */ /* do not notify us of updates when spawning initially */
if (fl == UPDATE_ALL) if (flChanged == UPDATE_ALL)
PredictPreFrame(); PredictPreFrame();
if (fl & PLAYER_AMMO1 || fl & PLAYER_AMMO2 || fl & PLAYER_AMMO3) { if (flChanged & PLAYER_AMMO1 || flChanged & PLAYER_AMMO2 || flChanged & PLAYER_AMMO3) {
Weapons_AmmoUpdate(this); Weapons_AmmoUpdate(this);
HUD_AmmoNotify_Check(this); HUD_AmmoNotify_Check(this);
} }
if (fl & PLAYER_ITEMS || fl & PLAYER_HEALTH) if (flChanged & PLAYER_ITEMS || flChanged & PLAYER_HEALTH)
HUD_ItemNotify_Check(this); HUD_ItemNotify_Check(this);
} }
@ -507,26 +497,26 @@ player::PredictPreFrame(void)
/* the generic client attributes */ /* the generic client attributes */
NSClientPlayer::PredictPreFrame(); NSClientPlayer::PredictPreFrame();
SAVE_STATE(anim_top); SAVE_STATE(anim_top)
SAVE_STATE(anim_top_delay); SAVE_STATE(anim_top_delay)
SAVE_STATE(anim_top_time); SAVE_STATE(anim_top_time)
SAVE_STATE(anim_bottom); SAVE_STATE(anim_bottom)
SAVE_STATE(anim_bottom_time); SAVE_STATE(anim_bottom_time)
SAVE_STATE(mag_sbs); SAVE_STATE(mag_sbs)
SAVE_STATE(mag_dbs); SAVE_STATE(mag_dbs)
SAVE_STATE(mag_rpg); SAVE_STATE(mag_rpg)
SAVE_STATE(mag_glauncher); SAVE_STATE(mag_glauncher)
SAVE_STATE(m_iAmmoRockets); SAVE_STATE(m_iAmmoRockets)
SAVE_STATE(m_iAmmoNails); SAVE_STATE(m_iAmmoNails)
SAVE_STATE(m_iAmmoCells); SAVE_STATE(m_iAmmoCells)
SAVE_STATE(m_iAmmoShells); SAVE_STATE(m_iAmmoShells)
SAVE_STATE(m_iAmmoDetpack); SAVE_STATE(m_iAmmoDetpack)
SAVE_STATE(m_iAmmoMedikit); SAVE_STATE(m_iAmmoMedikit)
SAVE_STATE(mode_tempstate); SAVE_STATE(mode_tempstate)
SAVE_STATE(classtype); SAVE_STATE(classtype)
} }
/* /*
@ -542,26 +532,26 @@ player::PredictPostFrame(void)
/* the generic client attributes */ /* the generic client attributes */
NSClientPlayer::PredictPostFrame(); NSClientPlayer::PredictPostFrame();
ROLL_BACK(anim_top); ROLL_BACK(anim_top)
ROLL_BACK(anim_top_delay); ROLL_BACK(anim_top_delay)
ROLL_BACK(anim_top_time); ROLL_BACK(anim_top_time)
ROLL_BACK(anim_bottom); ROLL_BACK(anim_bottom)
ROLL_BACK(anim_bottom_time); ROLL_BACK(anim_bottom_time)
ROLL_BACK(mag_sbs); ROLL_BACK(mag_sbs)
ROLL_BACK(mag_dbs); ROLL_BACK(mag_dbs)
ROLL_BACK(mag_rpg); ROLL_BACK(mag_rpg)
ROLL_BACK(mag_glauncher); ROLL_BACK(mag_glauncher)
ROLL_BACK(m_iAmmoRockets); ROLL_BACK(m_iAmmoRockets)
ROLL_BACK(m_iAmmoNails); ROLL_BACK(m_iAmmoNails)
ROLL_BACK(m_iAmmoCells); ROLL_BACK(m_iAmmoCells)
ROLL_BACK(m_iAmmoShells); ROLL_BACK(m_iAmmoShells)
ROLL_BACK(m_iAmmoDetpack); ROLL_BACK(m_iAmmoDetpack)
ROLL_BACK(m_iAmmoMedikit); ROLL_BACK(m_iAmmoMedikit)
ROLL_BACK(mode_tempstate); ROLL_BACK(mode_tempstate)
ROLL_BACK(classtype); ROLL_BACK(classtype)
} }
#else #else
@ -580,61 +570,26 @@ player::EvaluateEntity(void)
NSClientPlayer::EvaluateEntity(); NSClientPlayer::EvaluateEntity();
/* animation */ /* animation */
if (ATTR_CHANGED(anim_bottom) || ATTR_CHANGED(anim_bottom_time)) EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME)
SendFlags |= PLAYER_BOTTOMFRAME; EVALUATE_FIELD(anim_top_time, PLAYER_TOPFRAME)
if (ATTR_CHANGED(anim_top) || ATTR_CHANGED(anim_top_time) || ATTR_CHANGED(anim_top_delay)) EVALUATE_FIELD(anim_top_delay, PLAYER_TOPFRAME)
SendFlags |= PLAYER_TOPFRAME; EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME)
EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME)
/* ammo 1 type updates */ EVALUATE_FIELD(mag_sbs, PLAYER_AMMO1)
if (ATTR_CHANGED(mag_sbs)) EVALUATE_FIELD(mag_dbs, PLAYER_AMMO1)
SendFlags |= PLAYER_AMMO1; EVALUATE_FIELD(mag_rpg, PLAYER_AMMO1)
else if (ATTR_CHANGED(mag_dbs)) EVALUATE_FIELD(mag_glauncher, PLAYER_AMMO1)
SendFlags |= PLAYER_AMMO1;
else if (ATTR_CHANGED(mag_rpg))
SendFlags |= PLAYER_AMMO1;
else if (ATTR_CHANGED(mag_glauncher))
SendFlags |= PLAYER_AMMO1;
/* ammo 2 type updates */ EVALUATE_FIELD(m_iAmmoRockets, PLAYER_AMMO2)
if (ATTR_CHANGED(m_iAmmoRockets)) EVALUATE_FIELD(m_iAmmoNails, PLAYER_AMMO2)
SendFlags |= PLAYER_AMMO2; EVALUATE_FIELD(m_iAmmoCells, PLAYER_AMMO2)
else if (ATTR_CHANGED(m_iAmmoNails)) EVALUATE_FIELD(m_iAmmoShells, PLAYER_AMMO2)
SendFlags |= PLAYER_AMMO2; EVALUATE_FIELD(m_iAmmoDetpack, PLAYER_AMMO2)
else if (ATTR_CHANGED(m_iAmmoCells)) EVALUATE_FIELD(m_iAmmoMedikit, PLAYER_AMMO2)
SendFlags |= PLAYER_AMMO2;
else if (ATTR_CHANGED(m_iAmmoShells))
SendFlags |= PLAYER_AMMO2;
else if (ATTR_CHANGED(m_iAmmoDetpack))
SendFlags |= PLAYER_AMMO2;
else if (ATTR_CHANGED(m_iAmmoMedikit))
SendFlags |= PLAYER_AMMO2;
if (ATTR_CHANGED(mode_tempstate)) EVALUATE_FIELD(mode_tempstate, PLAYER_AMMO3)
SendFlags |= PLAYER_AMMO3; EVALUATE_FIELD(classtype, PLAYER_AMMO3)
if (ATTR_CHANGED(classtype))
SendFlags |= PLAYER_AMMO3;
SAVE_STATE(mag_sbs);
SAVE_STATE(mag_dbs);
SAVE_STATE(mag_rpg);
SAVE_STATE(mag_glauncher);
SAVE_STATE(m_iAmmoRockets);
SAVE_STATE(m_iAmmoNails);
SAVE_STATE(m_iAmmoCells);
SAVE_STATE(m_iAmmoShells);
SAVE_STATE(m_iAmmoDetpack);
SAVE_STATE(m_iAmmoMedikit);
SAVE_STATE(mode_tempstate);
SAVE_STATE(classtype);
SAVE_STATE(anim_top);
SAVE_STATE(anim_top_delay);
SAVE_STATE(anim_top_time);
SAVE_STATE(anim_bottom);
SAVE_STATE(anim_bottom_time);
} }
void void
@ -674,7 +629,7 @@ player::MakeClass(classtype_e class)
viewzoom = 1.0; viewzoom = 1.0;
/* select our class model */ /* select our class model */
model = g_teammodels[classtype]; model = TFC_GetModelForClasstype(classtype);
setmodel(this, model); setmodel(this, model);
setsize(this, VEC_HULL_MIN, VEC_HULL_MAX); setsize(this, VEC_HULL_MIN, VEC_HULL_MAX);
velocity = [0,0,0]; velocity = [0,0,0];
@ -883,36 +838,26 @@ player::SendEntity(entity ePEnt, float flChanged)
/* the generic client attributes */ /* the generic client attributes */
NSClientPlayer::SendEntity(ePEnt, flChanged); NSClientPlayer::SendEntity(ePEnt, flChanged);
if (flChanged & PLAYER_TOPFRAME) { SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
WriteByte(MSG_ENTITY, anim_top); SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
WriteFloat(MSG_ENTITY, anim_top_time); SENDENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME)
WriteFloat(MSG_ENTITY, anim_top_delay); SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME)
} SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME)
if (flChanged & PLAYER_BOTTOMFRAME) {
WriteByte(MSG_ENTITY, anim_bottom);
WriteFloat(MSG_ENTITY, anim_bottom_time);
}
if (flChanged & PLAYER_AMMO1) { SENDENTITY_BYTE(mag_sbs, PLAYER_AMMO1)
WriteByte(MSG_ENTITY, mag_sbs); SENDENTITY_BYTE(mag_dbs, PLAYER_AMMO1)
WriteByte(MSG_ENTITY, mag_dbs); SENDENTITY_BYTE(mag_rpg, PLAYER_AMMO1)
WriteByte(MSG_ENTITY, mag_rpg); SENDENTITY_BYTE(mag_glauncher, PLAYER_AMMO1)
WriteByte(MSG_ENTITY, mag_glauncher);
}
if (flChanged & PLAYER_AMMO2) { SENDENTITY_BYTE(m_iAmmoRockets, PLAYER_AMMO2)
WriteByte(MSG_ENTITY, m_iAmmoRockets); SENDENTITY_BYTE(m_iAmmoNails, PLAYER_AMMO2)
WriteByte(MSG_ENTITY, m_iAmmoNails); SENDENTITY_BYTE(m_iAmmoCells, PLAYER_AMMO2)
WriteByte(MSG_ENTITY, m_iAmmoCells); SENDENTITY_BYTE(m_iAmmoShells, PLAYER_AMMO2)
WriteByte(MSG_ENTITY, m_iAmmoShells); SENDENTITY_BYTE(m_iAmmoDetpack, PLAYER_AMMO2)
WriteByte(MSG_ENTITY, m_iAmmoDetpack); SENDENTITY_BYTE(m_iAmmoMedikit, PLAYER_AMMO2)
WriteByte(MSG_ENTITY, m_iAmmoMedikit);
}
if (flChanged & PLAYER_AMMO3) { SENDENTITY_BYTE(mode_tempstate, PLAYER_AMMO3)
WriteByte(MSG_ENTITY, mode_tempstate); SENDENTITY_BYTE(classtype, PLAYER_AMMO3)
WriteByte(MSG_ENTITY, classtype);
}
return (1); return (1);
} }

View File

@ -53,7 +53,7 @@ player::Physics_Jump(void)
float float
player::Physics_MaxSpeed(void) player::Physics_MaxSpeed(void)
{ {
float desiredspeed; float desiredspeed = 300.0f;
/* values courtesy of https://wiki.teamfortress.com/ */ /* values courtesy of https://wiki.teamfortress.com/ */
switch (classtype) { switch (classtype) {

View File

@ -84,7 +84,7 @@ w_autorifle_aimanim(player pl)
void void
w_autorifle_primary(player pl) w_autorifle_primary(player pl)
{ {
int s = w_baseauto_fire(pl, player::m_iAmmoShells, 8, [0,0]); int s = w_baseauto_fire(WEAPON_AUTORIFLE, player::m_iAmmoShells, 8, [0,0]);
switch (s) { switch (s) {
case AUTO_FIRE_FAILED: case AUTO_FIRE_FAILED:

View File

@ -44,7 +44,7 @@ w_sniper_updateammo(player pl)
string string
w_sniper_wmodel(void) w_sniper_wmodel(void)
{ {
return; return "";
} }
string string
w_sniper_pmodel(player pl) w_sniper_pmodel(player pl)
@ -80,7 +80,7 @@ w_sniper_release(player pl)
if (pl.mode_tempstate > 0) { if (pl.mode_tempstate > 0) {
float dmg = bound(75, (pl.mode_tempstate/2) * 75, 375); float dmg = bound(75, (pl.mode_tempstate/2) * 75, 375);
w_baseauto_fire(pl, player::m_iAmmoShells, dmg, [0,0]); w_baseauto_fire(WEAPON_SNIPER, player::m_iAmmoShells, dmg, [0,0]);
Weapons_ViewAnimation(pl, SNIPER_FIRE); Weapons_ViewAnimation(pl, SNIPER_FIRE);
if (pl.flags & FL_CROUCHING) if (pl.flags & FL_CROUCHING)