From 93c42b06cc54f547150a2b0b00f78a2f7678b45e Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Mon, 23 Jan 2023 02:22:59 -0800 Subject: [PATCH] Started work on implementing various primary and secondary grenades --- src/client/cmds.qc | 13 ++ src/server/nades.qc | 291 +++++++++++++++++++++++++++++++++++++++++++ src/server/progs.src | 1 + src/shared/flags.h | 4 +- src/shared/player.qc | 129 +++++++++++++++++++ 5 files changed, 436 insertions(+), 2 deletions(-) create mode 100644 src/server/nades.qc diff --git a/src/client/cmds.qc b/src/client/cmds.qc index 7579061..20c973f 100644 --- a/src/client/cmds.qc +++ b/src/client/cmds.qc @@ -34,6 +34,19 @@ ClientGame_ConsoleCommand(void) case "changeteam": VGUI_ChooseTeam(); break; + + case "+gren1": + pSeat->m_iInputExtra1 = TRUE; + break; + case "-gren1": + pSeat->m_iInputExtra1 = FALSE; + break; + case "+gren2": + pSeat->m_iInputExtra2 = TRUE; + break; + case "-gren2": + pSeat->m_iInputExtra2 = FALSE; + break; default: return (0); } diff --git a/src/server/nades.qc b/src/server/nades.qc new file mode 100644 index 0000000..d5fa4d6 --- /dev/null +++ b/src/server/nades.qc @@ -0,0 +1,291 @@ +void +TFCNade_ThrowCaltrop(player pl) +{ + vector vecNadeVelocity; + + static void TFCNade_ThrowHandGrenade_Touch(void) { + + if (!vlen(self.velocity)) + self.avelocity = g_vec_null; + } + + static void TFCNade_ThrowHandGrenade_Explode(void) { + float dmg = 100; + FX_Explosion(self.origin); + Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER); + sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); + NSEntity::Destroy(); + } + + for (int i = 0; i < 6; i++) { + makevectors([0, random() * 360, 0]); + vecNadeVelocity = v_forward * 50 + v_up * 150 + crandom() * v_right * 10 + crandom() * v_up * 10; + + NSRenderableEntity eNade = spawn(NSRenderableEntity); + eNade.SetModel("models/caltrop.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_TRIGGER); + eNade.SetSize([-6,-6,-6], [6,6,6]); + eNade.SetGravity(1.0f); + eNade.SetVelocity(vecNadeVelocity); + eNade.SetAngularVelocity([300, 300, 300]); + + eNade.touch = TFCNade_ThrowHandGrenade_Touch; + } +} + +void +TFCNade_ThrowHandGrenade(player pl) +{ + vector vecNadeVelocity; + float flTimer; + + static void TFCNade_ThrowHandGrenade_Touch(void) { + Sound_Play(self, CHAN_BODY, "weapon_handgrenade.bounce"); + + if (!vlen(self.velocity)) + self.avelocity = g_vec_null; + } + + static void TFCNade_ThrowHandGrenade_Explode(void) { + float dmg = 100; + FX_Explosion(self.origin); + Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER); + sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); + 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. gren1.GetNextThinkTime() - time); + + NSRenderableEntity eNade = spawn(NSRenderableEntity); + eNade.SetModel("models/w_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([300, 300, 300]); + eNade.SetAngles(vectoangles(eNade.GetVelocity())); + + eNade.touch = TFCNade_ThrowHandGrenade_Touch; + eNade.ScheduleThink(TFCNade_ThrowHandGrenade_Explode, flTimer); +} + +void +TFCNade_ThrowConcussion(player pl) +{ + vector vecNadeVelocity; + float flTimer; + + 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/conc_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 +TFCNade_ThrowNail(player pl) +{ + + print("Throwing Nail grenade!\n"); +} + +void +TFCNade_ThrowMIRVBomblet(NSEntity bomb) +{ + vector vecNadeVelocity; + + static void TFCNade_ThrowMIRVBomblet_Touch(void) { + + if (!vlen(self.velocity)) + self.avelocity = g_vec_null; + } + + static void TFCNade_ThrowMIRVBomblet_Explode(void) { + float dmg = 100; + FX_Explosion(self.origin); + Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER); + sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); + NSEntity::Destroy(); + } + + player pl = (player)bomb.owner; + + makevectors([0, random() * 360, 0]); + vecNadeVelocity = v_forward * 100 + v_up * 350 + crandom() * v_right * 10 + crandom() * v_up * 10; + + NSRenderableEntity eNade = spawn(NSRenderableEntity); + eNade.SetModel("models/bomblet.mdl"); + eNade.SetOrigin(bomb.origin + (v_forward * 14) + (v_up * -4) + (v_right * 2)); + eNade.SetOwner(pl); + eNade.SetMovetype(MOVETYPE_BOUNCE); + eNade.SetSolid(SOLID_TRIGGER); + eNade.SetSize([-6,-6,-6], [6,6,6]); + eNade.SetGravity(1.0f); + eNade.SetVelocity(vecNadeVelocity); + eNade.SetAngularVelocity([300, 300, 300]); + eNade.SetAngles(vectoangles(eNade.GetVelocity())); + + eNade.touch = TFCNade_ThrowMIRVBomblet_Touch; + eNade.ScheduleThink(TFCNade_ThrowMIRVBomblet_Explode, 1.5f + random()); +} + +void +TFCNade_ThrowMIRV(player pl) +{ + vector vecNadeVelocity; + float flTimer; + + static void TFCNade_ThrowMIRV_Touch(void) { + Sound_Play(self, CHAN_BODY, "weapon_handgrenade.bounce"); + + if (!vlen(self.velocity)) + self.avelocity = g_vec_null; + } + + static void TFCNade_ThrowMIRV_Explode(void) { + float dmg = 100; + FX_Explosion(self.origin); + Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER); + sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); + + for (int i = 0; i < 4; i++) { + TFCNade_ThrowMIRVBomblet((NSEntity)self); + } + + 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/mirv_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.SetSkin(1); + eNade.ScheduleThink(TFCNade_ThrowMIRV_Explode, flTimer); + eNade.touch = TFCNade_ThrowMIRV_Touch; +} + +void +TFCNade_ThrowNapalm(player pl) +{ + + print("Throwing Napalm grenade!\n"); +} + +void +TFCNade_ThrowHallucination(player pl) +{ + + print("Throwing Hallucination grenade!\n"); +} + +void +TFCNade_ThrowEMP(player pl) +{ + vector vecNadeVelocity; + float flTimer; + + static void TFCNade_ThrowEMP_Touch(void) { + Sound_Play(self, CHAN_BODY, "weapon_handgrenade.bounce"); + + if (!vlen(self.velocity)) + self.avelocity = g_vec_null; + } + + static void TFCNade_ThrowEMP_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/emp_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_ThrowEMP_Touch; + eNade.ScheduleThink(TFCNade_ThrowEMP_Explode, flTimer); +} + +void +TFCNade_ThrowSecondary(player pl) +{ + switch (pl.classtype) { + case CLASS_SCOUT: + case CLASS_MEDIC: + TFCNade_ThrowConcussion(pl); + break; + case CLASS_SOLDIER: + TFCNade_ThrowNail(pl); + break; + case CLASS_DEMO: + case CLASS_HVYWEAPON: + TFCNade_ThrowMIRV(pl); + break; + case CLASS_PYRO: + TFCNade_ThrowNapalm(pl); + break; + case CLASS_SPY: + TFCNade_ThrowHallucination(pl); + break; + case CLASS_ENGINEER: + TFCNade_ThrowEMP(pl); + break; + case CLASS_SNIPER: + default: + break; + } +} + +void +TFCNade_SelfExplode(player pl) +{ + float dmg = 100; + FX_Explosion(pl.origin); + Damage_Radius(pl.origin, pl, dmg, dmg * 2.5f, TRUE, WEAPON_GLAUNCHER); + sound(pl, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); +} \ No newline at end of file diff --git a/src/server/progs.src b/src/server/progs.src index 8d8894f..58d8612 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -37,6 +37,7 @@ info_tfgoal.qc info_areadef.qc item_armor.qc item_healthkit.qc +nades.qc gamerules.qc client.qc diff --git a/src/shared/flags.h b/src/shared/flags.h index 299b85a..0886d1c 100644 --- a/src/shared/flags.h +++ b/src/shared/flags.h @@ -19,8 +19,8 @@ #define GF_FLASHLIGHT (1<<1) #define GF_NOBUILDZONE (1<<2) #define GF_NOGRENADEZONE (1<<3) -#define GF_UNUSED5 (1<<4) -#define GF_UNUSED6 (1<<5) +#define GF_GREN1COOK (1<<4) +#define GF_GREN2COOK (1<<5) #define GF_UNUSED7 (1<<6) #define GF_UNUSED8 (1<<7) #define GF_UNUSED9 (1<<8) diff --git a/src/shared/player.qc b/src/shared/player.qc index f97e103..30ead3e 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -59,6 +59,13 @@ class player:NSClientPlayer virtual void Physics_Jump(void); virtual float Physics_MaxSpeed(void); + virtual void ProcessInput(void); + + nonvirtual void TFC_CookGren1(void); + nonvirtual void TFC_CookGren2(void); + nonvirtual void TFC_ReleaseGren1(void); + nonvirtual void TFC_ReleaseGren2(void); + #ifdef CLIENT virtual void ReceiveEntity(float,float); virtual void PredictPreFrame(void); @@ -66,6 +73,9 @@ class player:NSClientPlayer virtual void UpdateAliveCam(void); #else + NSTimer gren1; + NSTimer gren2; + int m_iMaxHealth; int m_iMaxArmor; @@ -82,9 +92,128 @@ class player:NSClientPlayer virtual void SpawnIntoGame(void); virtual void MakeClass(classtype_e); virtual void ServerInputFrame(void); + + nonvirtual void TFC_FragSelf(void); + nonvirtual void TFC_FragSelf(void); #endif }; +#ifdef SERVER + +void TFCNade_ThrowCaltrop(player); +void TFCNade_ThrowHandGrenade(player); +void TFCNade_ThrowSecondary(player); +void TFCNade_SelfExplode(player); + +void +player::TFC_FragSelf(void) +{ + print("Primary exploded in your hand!\n"); + TFCNade_SelfExplode(this); +} + +void +player::TFC_ThrowSecondary(void) +{ + print("Secondary exploded in your hand!\n"); + TFCNade_ThrowSecondary(this); +} +#endif + +void +player::TFC_CookGren1(void) +{ + /* we're already cooking it */ + if (gflags & GF_GREN1COOK) + return; + + if (classtype == CLASS_SCOUT) { + /* caltrop sound */ +#ifdef SERVER + StartSound("weapons/tink1.wav", CHAN_AUTO, 0, true); +#endif + } else { + /* grenade timer sound */ +#ifdef SERVER + StartSound("weapons/timer.wav", CHAN_AUTO, 0, true); + gren1 = gren1.SetupTimer(this, TFC_FragSelf, 3.75f, false); + gren1.RunTimer(); +#endif + } + + gflags |= GF_GREN1COOK; +} + +void +player::TFC_ReleaseGren1(void) +{ + if (!(gflags & GF_GREN1COOK)) + return; + + if (classtype == CLASS_SCOUT) { + /* release caltrop */ +#ifdef SERVER + TFCNade_ThrowCaltrop(this); +#endif + } else { + /* release the nade! */ +#ifdef SERVER + TFCNade_ThrowHandGrenade(this); + gren1.StopTimer(); +#endif + } + + gflags &= ~GF_GREN1COOK; +} + +void +player::TFC_CookGren2(void) +{ + if (gflags & GF_GREN2COOK) + return; + + if (classtype == CLASS_SNIPER) + return; + +#ifdef SERVER + StartSound("weapons/timer.wav", CHAN_AUTO, 0, true); + gren2 = gren2.SetupTimer(this, TFC_ThrowSecondary, 3.75f, false); + gren2.RunTimer(); +#endif + + gflags |= GF_GREN2COOK; +} + +void +player::TFC_ReleaseGren2(void) +{ + if (!(gflags & GF_GREN2COOK)) + return; + +#ifdef SERVER + TFCNade_ThrowSecondary(this); + gren2.StopTimer(); +#endif + + gflags &= ~GF_GREN2COOK; +} + +void +player::ProcessInput(void) +{ + super::ProcessInput(); + + if (input_buttons & INPUT_BUTTON6) + TFC_CookGren1(); + else + TFC_ReleaseGren1(); + + if (input_buttons & INPUT_BUTTON7) + TFC_CookGren2(); + else + TFC_ReleaseGren2(); +} + #ifdef CLIENT void Weapons_AmmoUpdate(entity); void HUD_AmmoNotify_Check(player pl);