diff --git a/src/server/defs.h b/src/server/defs.h new file mode 100644 index 0000000..d0b48f3 --- /dev/null +++ b/src/server/defs.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2016-2020 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. + */ + +#include "gamerules.h" +#include "../../../valve/src/server/items.h" +#include "../../../valve/src/server/flashlight.h" diff --git a/src/server/gamerules.h b/src/server/gamerules.h new file mode 100644 index 0000000..059904d --- /dev/null +++ b/src/server/gamerules.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2020 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. + */ + +class HLGameRules:NSGameRules +{ + virtual void DamageApply(entity, entity, float, int, damageType_t); + virtual void PlayerConnect(NSClientPlayer); + virtual void PlayerDisconnect(NSClientPlayer); + virtual void PlayerKill(NSClientPlayer); + virtual void PlayerPostFrame(NSClientPlayer); + + virtual void LevelDecodeParms(NSClientPlayer); + virtual void LevelChangeParms(NSClientPlayer); + virtual void LevelNewParms(void); + + virtual bool IsMultiplayer(void); + + virtual bool ImpulseCommand(NSClient, float); +}; + +class HLSingleplayerRules:HLGameRules +{ + /* client */ + virtual void(NSClientPlayer) PlayerSpawn; + virtual void(NSClientPlayer) PlayerDeath; + virtual bool(void) IsMultiplayer; + virtual bool ImpulseCommand(NSClient, float); +}; + +class HLMultiplayerRules:HLGameRules +{ + int m_iIntermission; + int m_iIntermissionTime; + string m_strTeamList; + + void(void) HLMultiplayerRules; + + virtual void(void) FrameStart; + virtual void(void) CheckRules; + virtual bool(void) MonstersSpawn; + + /* client */ + virtual void(NSClientPlayer) PlayerSpawn; + virtual void(NSClientPlayer) PlayerDeath; + virtual bool(NSClientPlayer, string) ConsoleCommand; + virtual bool(void) IsMultiplayer; + virtual bool(void) IsTeamplay; + virtual void(void) InitPostEnts; + virtual bool PlayerRequestRespawn(NSClientPlayer); +}; diff --git a/src/server/gamerules.qc b/src/server/gamerules.qc index 72fd13f..979b86f 100644 --- a/src/server/gamerules.qc +++ b/src/server/gamerules.qc @@ -20,6 +20,36 @@ HLGameRules::IsMultiplayer(void) return false; } +void +HLGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type) +{ + player targetPlayer; + player causingPlayer; + + /* handle Quad Damage */ + if (c.classname == "player") { + causingPlayer = (player)c; + + if (causingPlayer.HasQuadDamage()) + dmg *= 4.0f; + } + + if (t.classname == "player") { + targetPlayer = (player)t; + + /* handle Invulnerability */ + if (targetPlayer.HasInvulnerability()) + return; + + /* handle Enviro Suit */ + if (type == DMG_BURN || type == DMG_ACID) + if (targetPlayer.HasEnviroSuit()) + return; + } + + super::DamageApply(t, c, dmg, w, type); +} + void HLGameRules::LevelDecodeParms(NSClientPlayer pp) { diff --git a/src/server/item_artifact.qc b/src/server/item_artifact.qc index 6d6a7f4..75874af 100644 --- a/src/server/item_artifact.qc +++ b/src/server/item_artifact.qc @@ -17,6 +17,8 @@ class item_artifact:NSRenderableEntity { float m_respawnTime; + int m_itemID; + float m_usageTime; void(void) item_artifact; @@ -36,6 +38,22 @@ item_artifact::Touch(entity eToucher) Sound_Play(eToucher, CHAN_ITEM, noise); Logging_Pickup(eToucher, this, __NULL__); + if (m_itemID == ITEM_QUAD) { + pl.m_quadFinishTime = time + 30.0f; + } else if (m_itemID == ITEM_INVIS) { + pl.m_invisFinishTime = time + 30.0f; + } else if (m_itemID == ITEM_INVULN) { + pl.m_invulnFinishTime = time + 30.0f; + } else if (m_itemID == ITEM_ENVIROSUIT) { + pl.m_enviroFinishTime = time + 30.0f; + } + + pl.g_items |= m_itemID; + pl.SetRenderMode(GetRenderMode()); + pl.SetRenderFX(GetRenderFX()); + pl.SetRenderColor(GetRenderColor()); + pl.SetRenderAmt(GetRenderAmt()); + /* TODO: if deathmatch is 4 and player invincible, don't pick up */ if (cvar("deathmatch") == 0 || cvar("deathmatch") == 2) { Destroy(); @@ -78,6 +96,7 @@ item_artifact::item_artifact(void) { m_oldModel = model; m_respawnTime = 60.0f; + m_itemID = 0i; } /*QUAKED item_artifact_envirosuit (0 0 0.8) (-16 -16 0) (16 16 32) @@ -112,6 +131,7 @@ item_artifact_envirosuit::Touch(entity eToucher) if (eToucher.classname != "player") return; + m_itemID = ITEM_ENVIROSUIT; super::Touch(eToucher); } @@ -160,6 +180,7 @@ item_artifact_invisibility::Touch(entity eToucher) return; m_respawnTime = 5 * 60.0f; + m_itemID = ITEM_INVIS; super::Touch(eToucher); } @@ -207,6 +228,7 @@ item_artifact_invulnerability::Touch(entity eToucher) return; m_respawnTime = 5 * 60.0f; + m_itemID = ITEM_INVULN; super::Touch(eToucher); } @@ -242,6 +264,7 @@ void item_artifact_super_damage::Spawned(void) { super::Spawned(); + Sound_Precache("item_artifact_super_damage.attack"); SetRenderFX(RFX_GLOWSHELL); SetRenderColor([0.5, 0.5, 1.0]); SetRenderAmt(0.45f); @@ -253,5 +276,6 @@ item_artifact_super_damage::Touch(entity eToucher) if (eToucher.classname != "player") return; + m_itemID = ITEM_QUAD; super::Touch(eToucher); } \ No newline at end of file diff --git a/src/server/progs.src b/src/server/progs.src index e89af1c..c20bf09 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -15,7 +15,7 @@ ../../../src/gs-entbase/server.src ../../../src/gs-entbase/shared.src -../../../valve/src/server/defs.h +defs.h ../shared/include.src diff --git a/src/shared/items.h b/src/shared/items.h index bdb51da..ca8036d 100644 --- a/src/shared/items.h +++ b/src/shared/items.h @@ -14,28 +14,28 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define ITEM_CROWBAR 0x00000001i -#define ITEM_SHOTGUN 0x00000002i +#define ITEM_CROWBAR 0x00000001i +#define ITEM_SHOTGUN 0x00000002i #define ITEM_SUPERSHOTGUN 0x00000004i -#define ITEM_NAILGUN 0x00000008i +#define ITEM_NAILGUN 0x00000008i #define ITEM_SUPERNAILGUN 0x00000010i -#define ITEM_GRENADELAUNCHER 0x00000020i +#define ITEM_GRENADELAUNCHER 0x00000020i #define ITEM_ROCKETLAUNCHER 0x00000040i -#define ITEM_LIGHTNING 0x00000080i +#define ITEM_LIGHTNING 0x00000080i #define ITEM_UNUSED10 0x00000100i #define ITEM_UNUSED11 0x00000200i -#define ITEM_UNUSED12 0x00000400i +#define ITEM_UNUSED12 0x00000400i #define ITEM_UNUSED13 0x00000800i #define ITEM_UNUSED14 0x00001000i #define ITEM_UNUSED15 0x00002000i -#define ITEM_SUIT 0x00004000i +#define ITEM_SUIT 0x00004000i #define ITEM_LONGJUMP 0x00008000i -#define ITEM_UNUSED17 0x00010000i -#define ITEM_UNUSED18 0x00020000i -#define ITEM_UNUSED19 0x00040000i -#define ITEM_UNUSED20 0x00080000i +#define ITEM_QUAD 0x00010000i +#define ITEM_INVIS 0x00020000i +#define ITEM_INVULN 0x00040000i +#define ITEM_ENVIROSUIT 0x00080000i #define ITEM_UNUSED21 0x00100000i #define ITEM_UNUSED22 0x00200000i #define ITEM_UNUSED23 0x00400000i diff --git a/src/shared/player.qc b/src/shared/player.qc index 9c4e8d4..ccd2a93 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -14,6 +14,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "items.h" + #ifdef CLIENT /* Here's a list of bone names that we are aware of on HL player models. Usually we'd use skeletalobjects to share the same skeleton/anim with @@ -132,6 +134,13 @@ class player:NSClientPlayer PREDICTED_FLOAT_N(ammo_rockets) PREDICTED_FLOAT_N(ammo_cells) +#ifdef SERVER + float m_quadFinishTime; + float m_invisFinishTime; + float m_invulnFinishTime; + float m_enviroFinishTime; +#endif + virtual void Physics_Jump(void); virtual void UpdatePlayerAnimation(float); @@ -150,6 +159,11 @@ class player:NSClientPlayer virtual void Save(float); virtual void Restore(string,string); #endif + + nonvirtual bool HasQuadDamage(void); + nonvirtual bool HasInvisibility(void); + nonvirtual bool HasInvulnerability(void); + nonvirtual bool HasEnviroSuit(void); }; void Animation_PlayerUpdate(player); @@ -449,6 +463,33 @@ player::EvaluateEntity(void) EVALUATE_FIELD(ammo_nails, PLAYER_AMMO1) EVALUATE_FIELD(ammo_rockets, PLAYER_AMMO1) EVALUATE_FIELD(ammo_cells, PLAYER_AMMO1) + + if (g_items & ITEM_QUAD) { + if (m_quadFinishTime < time) { + g_items &= ~ITEM_QUAD; + } + } + + if (g_items & ITEM_INVIS) { + if (m_invisFinishTime < time) { + + g_items &= ~ITEM_INVIS; + } + } + + if (g_items & ITEM_INVULN) { + if (m_invulnFinishTime < time) { + + g_items &= ~ITEM_INVULN; + } + } + + if (g_items & ITEM_ENVIROSUIT) { + if (m_enviroFinishTime < time) { + + } + g_items &= ~ITEM_ENVIROSUIT; + } } /* @@ -488,6 +529,30 @@ player::SendEntity(entity ePEnt, float flChanged) } #endif +bool +player::HasQuadDamage(void) +{ + return g_items & ITEM_QUAD ? true : false; +} + +bool +player::HasInvisibility(void) +{ + return g_items & ITEM_INVIS ? true : false; +} + +bool +player::HasInvulnerability(void) +{ + return g_items & ITEM_INVULN ? true : false; +} + +bool +player::HasEnviroSuit(void) +{ + return g_items & ITEM_ENVIROSUIT ? true : false; +} + void player::player(void) { diff --git a/src/shared/w_crowbar.qc b/src/shared/w_crowbar.qc index 3cf87b7..3f692f0 100644 --- a/src/shared/w_crowbar.qc +++ b/src/shared/w_crowbar.qc @@ -93,6 +93,10 @@ w_crowbar_primary(player pl) Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTCROWBAR : ANIM_SHOOTCROWBAR, 0.41f); #ifdef SERVER + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + Sound_Play(pl, CHAN_WEAPON, "weapon_crowbar.swing"); if (trace_fraction >= 1.0) { diff --git a/src/shared/w_grenadelauncher.qc b/src/shared/w_grenadelauncher.qc index 81a1948..542e7b8 100644 --- a/src/shared/w_grenadelauncher.qc +++ b/src/shared/w_grenadelauncher.qc @@ -154,6 +154,10 @@ w_grenadelauncher_primary(player pl) /* fire the actual projectile (on the server) */ #ifdef SERVER + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + w_grenadelauncher_shootnade(pl); #endif diff --git a/src/shared/w_lightning.qc b/src/shared/w_lightning.qc index b0eaa27..bdc6126 100644 --- a/src/shared/w_lightning.qc +++ b/src/shared/w_lightning.qc @@ -131,6 +131,9 @@ w_lightning_primary(player pl) } } + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } Sound_Play(pl, CHAN_WEAPON, "weapon_lightning.start"); #endif diff --git a/src/shared/w_nailgun.qc b/src/shared/w_nailgun.qc index a3a261a..1149904 100644 --- a/src/shared/w_nailgun.qc +++ b/src/shared/w_nailgun.qc @@ -138,6 +138,10 @@ w_nailgun_primary(player pl) nail.angles = vectoangles(nail.velocity); } + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + Sound_Play(pl, CHAN_WEAPON, "weapon_nailgun.shoot"); #endif diff --git a/src/shared/w_rocketlauncher.qc b/src/shared/w_rocketlauncher.qc index 3827df0..942ec85 100644 --- a/src/shared/w_rocketlauncher.qc +++ b/src/shared/w_rocketlauncher.qc @@ -138,6 +138,10 @@ w_rocketlauncher_primary(player pl) setsize(rocket, [0,0,0], [0,0,0]); Sound_Play(pl, CHAN_WEAPON, "weapon_rocketlauncher.shoot"); + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } #endif } diff --git a/src/shared/w_shotgun.qc b/src/shared/w_shotgun.qc index 5be9ac3..c7d7c83 100644 --- a/src/shared/w_shotgun.qc +++ b/src/shared/w_shotgun.qc @@ -133,6 +133,10 @@ w_shotgun_primary(player pl) /* Singleplayer is more accurate */ TraceAttack_FireBulletsWithDecal(6, pl.origin + pl.view_ofs, Skill_GetValue("plr_shotgun", 4), [0.1,0.1], WEAPON_SHOTGUN, "Impact.BigShot"); Sound_Play(pl, CHAN_WEAPON, "weapon_shotgun.shoot"); + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } #else //View_AddEvent(w_shotgun_ejectshell, 0.25f); #endif diff --git a/src/shared/w_supernailgun.qc b/src/shared/w_supernailgun.qc index fee58bf..1bdcf45 100644 --- a/src/shared/w_supernailgun.qc +++ b/src/shared/w_supernailgun.qc @@ -140,6 +140,10 @@ w_supernailgun_primary(player pl) } Sound_Play(pl, CHAN_WEAPON, "weapon_supernailgun.shoot"); + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } #endif pl.w_attack_next = 0.085f; diff --git a/src/shared/w_supershotgun.qc b/src/shared/w_supershotgun.qc index 6cc6a1c..35c76f2 100644 --- a/src/shared/w_supershotgun.qc +++ b/src/shared/w_supershotgun.qc @@ -151,6 +151,10 @@ w_supershotgun_primary(player pl) #else TraceAttack_FireBulletsWithDecal(14, pl.origin + pl.view_ofs, Skill_GetValue("plr_supershotgun", 4), [0.14,0.08], WEAPON_SUPERSHOTGUN, "Impact.BigShot"); Sound_Play(pl, CHAN_WEAPON, "weapon_supershotgun.shoot"); + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } #endif Weapons_ViewPunchAngle(pl, [-2,0,0]); diff --git a/zpak001.pk3dir/sound/items_dmc.sndshd b/zpak001.pk3dir/sound/items_dmc.sndshd index ee7024e..757032c 100644 --- a/zpak001.pk3dir/sound/items_dmc.sndshd +++ b/zpak001.pk3dir/sound/items_dmc.sndshd @@ -54,6 +54,11 @@ item_artifact_super_damage.pickup sample items/damage.wav } +item_artifact_super_damage.attack +{ + sample items/damage3.wav +} + dmc_item.respawn { sample items/itembk2.wav