diff --git a/src/client/draw.qc b/src/client/draw.qc index 57d1868..07fcd19 100644 --- a/src/client/draw.qc +++ b/src/client/draw.qc @@ -44,8 +44,11 @@ ClientGame_PostDraw(void) { player pl = (player)pSeat->m_ePlayer; - if (serverkeyfloat("areadefs") == 1) - Font_DrawText([16,16], getplayerkeyvalue(player_localnum, "*areadef"), FONT_CON); + if (serverkeyfloat("areadefs") == 1) { + 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) { vector vecGoalItemPos; diff --git a/src/client/vgui_changeclass.qc b/src/client/vgui_changeclass.qc index 6e381c6..e6bbbbc 100644 --- a/src/client/vgui_changeclass.qc +++ b/src/client/vgui_changeclass.qc @@ -14,76 +14,243 @@ * 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; - void(void) ptr; -} btnarr_t; + g_classDescrScout = textfile_to_string("classes/short_scout.txt"); + g_classDescrSniper = textfile_to_string("classes/short_sniper.txt"); + 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 -VGUI_ClassJoin(float i) +TFClassButton::TFClassButton(void) { - sendevent("ClassJoin", "f", i); +} + +void +TFClassButton::OnMouseUp(void) +{ + int tag = GetTag(); + 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 -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); } -void VGUI_JoinSniper (void) { VGUI_ClassJoin(2); } -void VGUI_JoinSoldier (void) { VGUI_ClassJoin(3); } -void VGUI_JoinDemoman (void) { VGUI_ClassJoin(4); } -void VGUI_JoinMedic (void) { VGUI_ClassJoin(5); } -void VGUI_JoinHwguy (void) { VGUI_ClassJoin(6); } -void VGUI_JoinPyro (void) { VGUI_ClassJoin(7); } -void VGUI_JoinSpy (void) { VGUI_ClassJoin(8); } -void VGUI_JoinEngineer (void) { VGUI_ClassJoin(9); } - -btnarr_t g_tfc_vgui_classlist[] = { - {"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 } +string g_classnames [] = { + "SCOUT", + "SNIPER", + "SOLDIER", + "DEMOMAN", + "MEDIC", + "HWGUY", + "PYRO", + "SPY", + "ENGINEER", + "RANDOM" }; void VGUI_ChooseClass(void) { static int initialized; - static CUIButton *btns; + static TFClassButton *btns; + static VGUILabel lblSelectClass; + static VGUIFrame frmClassInfo; if (!initialized) { - vector btnpos = [16,0]; + vector btnpos = [40,80]; 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); - for (int i = 0; i < g_tfc_vgui_classlist.length; i++) { - btnpos[1] += 30; - if (g_tfc_vgui_classlist[i].ptr == __NULL__) { - continue; - } - btns[i] = spawn(CUIButton); - btns[i].SetTitle(g_tfc_vgui_classlist[i].str); + TFCClass_Init(); + + winClassSelection = spawn(VGUIWindow); + winClassSelection.SetSize([640, 480]); + winClassSelection.SetStyleMask(VGUIWindowBorderless | VGUIWindowFullscreen); + + lblSelectClass = spawn(VGUILabel); + 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].SetFunc(g_tfc_vgui_classlist[i].ptr); + btns[i].SetTag(i); winClassSelection.Add(btns[i]); + btnpos[1] += 32; } } diff --git a/src/client/vgui_chooseteam.qc b/src/client/vgui_chooseteam.qc index 1be1999..79c45b8 100644 --- a/src/client/vgui_chooseteam.qc +++ b/src/client/vgui_chooseteam.qc @@ -14,96 +14,140 @@ * 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 -VGUI_ChooseTeam_Blue(void) +TFTeamButton::TFTeamButton(void) { - localcmd("changeclass\n"); - sendevent("TeamJoin", "f", 1); - winChooseTeam.Hide(); } void -VGUI_ChooseTeam_Red(void) +TFTeamButton::OnMouseUp(void) { + int tag = GetTag(); + localcmd("changeclass\n"); - sendevent("TeamJoin", "f", 2); + sendevent("TeamJoin", "f", (float)tag); winChooseTeam.Hide(); } -void -VGUI_ChooseTeam_Green(void) -{ - localcmd("changeclass\n"); - sendevent("TeamJoin", "f", 3); - winChooseTeam.Hide(); -} -void -VGUI_ChooseTeam_Yellow(void) +string +VGUI_ChooseTeam_MapInfo(void) { - localcmd("changeclass\n"); - sendevent("TeamJoin", "f", 4); - winChooseTeam.Hide(); -} + static string mapinfo = __NULL__; -void -VGUI_GoSpectator(void) -{ - //VGUI_TeamJoin(0); - sendevent("TeamJoin", "f", 0); - winChooseTeam.Hide(); + if (mapinfo != __NULL__) + return mapinfo; + + filestream fileMap = fopen(strcat("maps/", mapname, ".txt"), FILE_READ); + string temp; + + if (fileMap != -1) { + while ((temp = fgets(fileMap))) { + mapinfo = strcat(mapinfo, temp, "\n"); + } + } else { + mapinfo = "No map info available."; + } + + return mapinfo; } void VGUI_ChooseTeam(void) { 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) { - vector btnpos = [16,48]; + vector btnpos = [40,80]; initialized = TRUE; - winChooseTeam = spawn(CUIWindow); - winChooseTeam.SetTitle("Choose Team"); - winChooseTeam.SetSize('420 320'); + winChooseTeam = spawn(VGUIWindow); + winChooseTeam.SetSize('640 480'); + 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++) { - CUIButton btnForTeam; + TFTeamButton btnForTeam; string team_name = serverkey(sprintf("team_%i", t)); - btnForTeam = spawn(CUIButton); - btnForTeam.SetTitle(team_name); + btnForTeam = spawn(TFTeamButton); + btnForTeam.SetTitle(strtoupper(team_name)); btnForTeam.SetPos(btnpos); + btnForTeam.SetSize('124 24'); switch (team_name) { case "Blue": - btnForTeam.SetFunc(VGUI_ChooseTeam_Blue); + btnForTeam.SetTag(1); break; case "Red": - btnForTeam.SetFunc(VGUI_ChooseTeam_Red); + btnForTeam.SetTag(2); break; case "Green": - btnForTeam.SetFunc(VGUI_ChooseTeam_Green); + btnForTeam.SetTag(3); break; case "Yellow": - btnForTeam.SetFunc(VGUI_ChooseTeam_Yellow); + btnForTeam.SetTag(4); break; } 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.SetTitle("Spectator"); - btnGoSpectator.SetPos('8 252'); - btnGoSpectator.SetFunc(VGUI_GoSpectator); + btnGoSpectator = spawn(VGUIButton); + btnGoSpectator.SetTitle("SPECTATE"); + btnGoSpectator.SetPos(btnpos); + btnGoSpectator.SetSize('124 24'); + //btnGoSpectator.SetFunc(VGUI_GoSpectator); g_uiDesktop.Add(winChooseTeam); + winChooseTeam.Add(frmMapInfo); + winChooseTeam.Add(lblSelectTeam); + winChooseTeam.Add(lblMapName); + winChooseTeam.Add(lblMapInfo); + winChooseTeam.Add(btnAutoAssign); winChooseTeam.Add(btnGoSpectator); } diff --git a/src/server/info_tfgoal.qc b/src/server/info_tfgoal.qc index 3dbc064..10eae5a 100644 --- a/src/server/info_tfgoal.qc +++ b/src/server/info_tfgoal.qc @@ -300,6 +300,12 @@ info_tfgoal::SpawnKey(string strKey, string strValue) break; case "mdl": model = strValue; + + if (serverkeyfloat("*bspversion") == 0) { + model = strreplace("progs", "models", model); + model = strreplace("tf_stan", "flag", model); + } + break; case "goal_state": m_tfgState = stof(strValue); diff --git a/src/server/item_tfgoal.qc b/src/server/item_tfgoal.qc index 7ba092d..51c35cd 100644 --- a/src/server/item_tfgoal.qc +++ b/src/server/item_tfgoal.qc @@ -139,6 +139,8 @@ item_tfgoal::Touch(entity eToucher) player pl = (player)eToucher; +/* not in standard TFC, make cvar? */ +#if 0 /* if it's dropped, just let the other team return it... otherwise let the other teams pick it up as normal */ if (m_status == GISTATUS_DROPPED) { @@ -147,6 +149,7 @@ item_tfgoal::Touch(entity eToucher) return; } } +#endif /* team filter */ if (m_iTeamUses) @@ -250,6 +253,11 @@ item_tfgoal::SpawnKey(string strKey, string strValue) break; case "mdl": model = strValue; + + if (serverkeyfloat("*bspversion") == BSPVER_Q1) { + model = strreplace("progs", "models", model); + model = strreplace("tf_stan", "flag", model); + } break; case "goal_no": m_dItemID = stof(strValue); diff --git a/src/server/nades.qc b/src/server/nades.qc index 9284091..4a916e1 100644 --- a/src/server/nades.qc +++ b/src/server/nades.qc @@ -289,15 +289,71 @@ TFCNade_ThrowMIRV(player pl) void 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 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 diff --git a/src/server/sentry.qc b/src/server/sentry.qc index 428f99c..426d04d 100644 --- a/src/server/sentry.qc +++ b/src/server/sentry.qc @@ -27,7 +27,8 @@ TFCSentry::Think(void) if (vlen(origin - p.origin) > 1024) continue; - print(sprintf("Is Facing? %d\n", IsFacing(p))); + if (team == p.team) + continue; if (IsFacing(p) == false) continue; @@ -62,12 +63,13 @@ TFCSentry::Think(void) m_state = SENTRY_SEARCHING; else { 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_eHead.SetBoneControl1(m_flCurrAngle); + print(sprintf("head: %f; want: %f\n", m_flCurrAngle, m_flWantAngle)); /* 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); } } @@ -87,6 +89,7 @@ TFCSentry::Place(NSClientPlayer pl) ScheduleThink(FinishPlacing, 5.0f); real_owner = pl; colormap = pl.colormap; + team = pl.team; env_message_single(real_owner, "#Engineer_building"); Sound_Play(this, CHAN_BODY, "engineer.build"); diff --git a/src/server/spawn.qc b/src/server/spawn.qc index 2d73c86..d085c1d 100644 --- a/src/server/spawn.qc +++ b/src/server/spawn.qc @@ -50,14 +50,23 @@ CSEv_TeamJoin_f(float f) } } - - +/** Called by the client-side VGUI menu when we choose a class. */ void CSEv_ClassJoin_f(float f) { 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 */ if (pl.team == 0) { return; diff --git a/src/shared/animations_tfc.h b/src/shared/animations_tfc.h index 644074c..5f614a6 100644 --- a/src/shared/animations_tfc.h +++ b/src/shared/animations_tfc.h @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2016-2022 Marco Cawthorne + * + * 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 { TFCANIM_DIEGUTSHOT = ANIM_DIEGUTSHOT, diff --git a/src/shared/defs.h b/src/shared/defs.h index a59543b..b76ab48 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -28,6 +28,19 @@ typedef enum } classtype_e; 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/sniper/sniper2.mdl", @@ -39,3 +52,26 @@ string g_teammodels[] = { "models/player/spy/spy2.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]; +} \ No newline at end of file diff --git a/src/shared/player.qc b/src/shared/player.qc index 35f8b48..2e756e0 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -436,42 +436,32 @@ player::ReceiveEntity ================= */ void -player::ReceiveEntity(float new, float fl) +player::ReceiveEntity(float new, float flChanged) { /* the generic client attributes */ - NSClientPlayer::ReceiveEntity(new, fl); + super::ReceiveEntity(new, flChanged); /* animation */ - if (fl & PLAYER_TOPFRAME) { - anim_top = readbyte(); - anim_top_time = readfloat(); - anim_top_delay = readfloat(); - } - if (fl & PLAYER_BOTTOMFRAME) { - anim_bottom = readbyte(); - anim_bottom_time = readfloat(); - } + READENTITY_BYTE(anim_top, PLAYER_TOPFRAME) + READENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME) + READENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME) + READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME) + READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME) - if (fl & PLAYER_AMMO1) { - mag_sbs = readbyte(); - mag_dbs = readbyte(); - mag_rpg = readbyte(); - 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(); - } + READENTITY_BYTE(mag_sbs, PLAYER_AMMO1) + READENTITY_BYTE(mag_dbs, PLAYER_AMMO1) + READENTITY_BYTE(mag_rpg, PLAYER_AMMO1) + READENTITY_BYTE(mag_glauncher, PLAYER_AMMO1) - if (fl & PLAYER_AMMO3) { - mode_tempstate = readbyte(); - classtype = readbyte(); - } + READENTITY_BYTE(m_iAmmoRockets, PLAYER_AMMO2) + READENTITY_BYTE(m_iAmmoNails, PLAYER_AMMO2) + 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); @@ -481,15 +471,15 @@ player::ReceiveEntity(float new, float fl) return; /* do not notify us of updates when spawning initially */ - if (fl == UPDATE_ALL) + if (flChanged == UPDATE_ALL) PredictPreFrame(); - if (fl & PLAYER_AMMO1 || fl & PLAYER_AMMO2 || fl & PLAYER_AMMO3) { + if (flChanged & PLAYER_AMMO1 || flChanged & PLAYER_AMMO2 || flChanged & PLAYER_AMMO3) { Weapons_AmmoUpdate(this); HUD_AmmoNotify_Check(this); } - if (fl & PLAYER_ITEMS || fl & PLAYER_HEALTH) + if (flChanged & PLAYER_ITEMS || flChanged & PLAYER_HEALTH) HUD_ItemNotify_Check(this); } @@ -507,26 +497,26 @@ player::PredictPreFrame(void) /* the generic client attributes */ NSClientPlayer::PredictPreFrame(); - SAVE_STATE(anim_top); - SAVE_STATE(anim_top_delay); - SAVE_STATE(anim_top_time); - SAVE_STATE(anim_bottom); - SAVE_STATE(anim_bottom_time); + SAVE_STATE(anim_top) + SAVE_STATE(anim_top_delay) + SAVE_STATE(anim_top_time) + SAVE_STATE(anim_bottom) + SAVE_STATE(anim_bottom_time) - SAVE_STATE(mag_sbs); - SAVE_STATE(mag_dbs); - SAVE_STATE(mag_rpg); - SAVE_STATE(mag_glauncher); + 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(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(mode_tempstate) + SAVE_STATE(classtype) } /* @@ -542,26 +532,26 @@ player::PredictPostFrame(void) /* the generic client attributes */ NSClientPlayer::PredictPostFrame(); - ROLL_BACK(anim_top); - ROLL_BACK(anim_top_delay); - ROLL_BACK(anim_top_time); - ROLL_BACK(anim_bottom); - ROLL_BACK(anim_bottom_time); + ROLL_BACK(anim_top) + ROLL_BACK(anim_top_delay) + ROLL_BACK(anim_top_time) + ROLL_BACK(anim_bottom) + ROLL_BACK(anim_bottom_time) - ROLL_BACK(mag_sbs); - ROLL_BACK(mag_dbs); - ROLL_BACK(mag_rpg); - ROLL_BACK(mag_glauncher); + ROLL_BACK(mag_sbs) + ROLL_BACK(mag_dbs) + ROLL_BACK(mag_rpg) + ROLL_BACK(mag_glauncher) - ROLL_BACK(m_iAmmoRockets); - ROLL_BACK(m_iAmmoNails); - ROLL_BACK(m_iAmmoCells); - ROLL_BACK(m_iAmmoShells); - ROLL_BACK(m_iAmmoDetpack); - ROLL_BACK(m_iAmmoMedikit); + ROLL_BACK(m_iAmmoRockets) + ROLL_BACK(m_iAmmoNails) + ROLL_BACK(m_iAmmoCells) + ROLL_BACK(m_iAmmoShells) + ROLL_BACK(m_iAmmoDetpack) + ROLL_BACK(m_iAmmoMedikit) - ROLL_BACK(mode_tempstate); - ROLL_BACK(classtype); + ROLL_BACK(mode_tempstate) + ROLL_BACK(classtype) } #else @@ -580,61 +570,26 @@ player::EvaluateEntity(void) NSClientPlayer::EvaluateEntity(); /* animation */ - if (ATTR_CHANGED(anim_bottom) || ATTR_CHANGED(anim_bottom_time)) - SendFlags |= PLAYER_BOTTOMFRAME; - if (ATTR_CHANGED(anim_top) || ATTR_CHANGED(anim_top_time) || ATTR_CHANGED(anim_top_delay)) - SendFlags |= PLAYER_TOPFRAME; + EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME) + EVALUATE_FIELD(anim_top_time, PLAYER_TOPFRAME) + EVALUATE_FIELD(anim_top_delay, PLAYER_TOPFRAME) + EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME) + EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME) - /* ammo 1 type updates */ - if (ATTR_CHANGED(mag_sbs)) - SendFlags |= PLAYER_AMMO1; - else if (ATTR_CHANGED(mag_dbs)) - SendFlags |= PLAYER_AMMO1; - else if (ATTR_CHANGED(mag_rpg)) - SendFlags |= PLAYER_AMMO1; - else if (ATTR_CHANGED(mag_glauncher)) - SendFlags |= PLAYER_AMMO1; + EVALUATE_FIELD(mag_sbs, PLAYER_AMMO1) + EVALUATE_FIELD(mag_dbs, PLAYER_AMMO1) + EVALUATE_FIELD(mag_rpg, PLAYER_AMMO1) + EVALUATE_FIELD(mag_glauncher, PLAYER_AMMO1) - /* ammo 2 type updates */ - if (ATTR_CHANGED(m_iAmmoRockets)) - SendFlags |= PLAYER_AMMO2; - else if (ATTR_CHANGED(m_iAmmoNails)) - SendFlags |= PLAYER_AMMO2; - else if (ATTR_CHANGED(m_iAmmoCells)) - 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; + EVALUATE_FIELD(m_iAmmoRockets, PLAYER_AMMO2) + EVALUATE_FIELD(m_iAmmoNails, PLAYER_AMMO2) + EVALUATE_FIELD(m_iAmmoCells, PLAYER_AMMO2) + EVALUATE_FIELD(m_iAmmoShells, PLAYER_AMMO2) + EVALUATE_FIELD(m_iAmmoDetpack, PLAYER_AMMO2) + EVALUATE_FIELD(m_iAmmoMedikit, PLAYER_AMMO2) - if (ATTR_CHANGED(mode_tempstate)) - SendFlags |= 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); + EVALUATE_FIELD(mode_tempstate, PLAYER_AMMO3) + EVALUATE_FIELD(classtype, PLAYER_AMMO3) } void @@ -674,7 +629,7 @@ player::MakeClass(classtype_e class) viewzoom = 1.0; /* select our class model */ - model = g_teammodels[classtype]; + model = TFC_GetModelForClasstype(classtype); setmodel(this, model); setsize(this, VEC_HULL_MIN, VEC_HULL_MAX); velocity = [0,0,0]; @@ -883,36 +838,26 @@ player::SendEntity(entity ePEnt, float flChanged) /* the generic client attributes */ NSClientPlayer::SendEntity(ePEnt, flChanged); - if (flChanged & PLAYER_TOPFRAME) { - WriteByte(MSG_ENTITY, anim_top); - WriteFloat(MSG_ENTITY, anim_top_time); - WriteFloat(MSG_ENTITY, anim_top_delay); - } - if (flChanged & PLAYER_BOTTOMFRAME) { - WriteByte(MSG_ENTITY, anim_bottom); - WriteFloat(MSG_ENTITY, anim_bottom_time); - } + SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME) + SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME) + SENDENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME) + SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME) + SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME) - if (flChanged & PLAYER_AMMO1) { - WriteByte(MSG_ENTITY, mag_sbs); - WriteByte(MSG_ENTITY, mag_dbs); - WriteByte(MSG_ENTITY, mag_rpg); - WriteByte(MSG_ENTITY, mag_glauncher); - } + SENDENTITY_BYTE(mag_sbs, PLAYER_AMMO1) + SENDENTITY_BYTE(mag_dbs, PLAYER_AMMO1) + SENDENTITY_BYTE(mag_rpg, PLAYER_AMMO1) + SENDENTITY_BYTE(mag_glauncher, PLAYER_AMMO1) - if (flChanged & PLAYER_AMMO2) { - WriteByte(MSG_ENTITY, m_iAmmoRockets); - WriteByte(MSG_ENTITY, m_iAmmoNails); - WriteByte(MSG_ENTITY, m_iAmmoCells); - WriteByte(MSG_ENTITY, m_iAmmoShells); - WriteByte(MSG_ENTITY, m_iAmmoDetpack); - WriteByte(MSG_ENTITY, m_iAmmoMedikit); - } + SENDENTITY_BYTE(m_iAmmoRockets, PLAYER_AMMO2) + SENDENTITY_BYTE(m_iAmmoNails, PLAYER_AMMO2) + SENDENTITY_BYTE(m_iAmmoCells, PLAYER_AMMO2) + SENDENTITY_BYTE(m_iAmmoShells, PLAYER_AMMO2) + SENDENTITY_BYTE(m_iAmmoDetpack, PLAYER_AMMO2) + SENDENTITY_BYTE(m_iAmmoMedikit, PLAYER_AMMO2) - if (flChanged & PLAYER_AMMO3) { - WriteByte(MSG_ENTITY, mode_tempstate); - WriteByte(MSG_ENTITY, classtype); - } + SENDENTITY_BYTE(mode_tempstate, PLAYER_AMMO3) + SENDENTITY_BYTE(classtype, PLAYER_AMMO3) return (1); } diff --git a/src/shared/pmove.qc b/src/shared/pmove.qc index 1410f6e..c4b0dfc 100644 --- a/src/shared/pmove.qc +++ b/src/shared/pmove.qc @@ -53,7 +53,7 @@ player::Physics_Jump(void) float player::Physics_MaxSpeed(void) { - float desiredspeed; + float desiredspeed = 300.0f; /* values courtesy of https://wiki.teamfortress.com/ */ switch (classtype) { diff --git a/src/shared/w_autorifle.qc b/src/shared/w_autorifle.qc index aa297cf..3602ba6 100644 --- a/src/shared/w_autorifle.qc +++ b/src/shared/w_autorifle.qc @@ -84,7 +84,7 @@ w_autorifle_aimanim(player pl) void 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) { case AUTO_FIRE_FAILED: diff --git a/src/shared/w_sniper.qc b/src/shared/w_sniper.qc index 4163c13..25ca2bb 100644 --- a/src/shared/w_sniper.qc +++ b/src/shared/w_sniper.qc @@ -44,7 +44,7 @@ w_sniper_updateammo(player pl) string w_sniper_wmodel(void) { - return; + return ""; } string w_sniper_pmodel(player pl) @@ -80,7 +80,7 @@ w_sniper_release(player pl) if (pl.mode_tempstate > 0) { 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); if (pl.flags & FL_CROUCHING)