From f39acbed5e0a070bd061bc74d24cb29c772c638d Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Thu, 27 Jul 2023 23:18:09 -0700 Subject: [PATCH] Initial work on the extra DMC content for 3wave and Suparsonik's addon work --- src/client/game_event.qc | 111 +++++ src/client/init.qc | 56 +++ src/client/progs.src | 1 + src/server/ammo.qc | 165 +++++++ src/server/extraitems.qc | 56 +++ src/server/gamerules_multiplayer.qc | 7 +- src/server/gamerules_singleplayer.qc | 23 +- src/server/progs.src | 43 +- src/shared/events.h | 1 + src/shared/include.src | 19 +- src/shared/items.h | 48 +- src/shared/player.qc | 139 +++--- src/shared/w_crowbar.qc | 2 +- src/shared/w_grapple.qc | 244 +++++++++++ src/shared/w_grenadelauncher.qc | 56 +++ src/shared/w_hammer.qc | 206 +++++++++ src/shared/w_ice_shotgun.qc | 231 ++++++++++ src/shared/w_ice_supershotgun.qc | 263 +++++++++++ src/shared/w_lava_nailgun.qc | 263 +++++++++++ src/shared/w_lava_supernailgun.qc | 248 +++++++++++ src/shared/w_lightning.qc | 19 +- src/shared/w_multi_gren.qc | 276 ++++++++++++ src/shared/w_multi_rocket.qc | 219 ++++++++++ src/shared/w_nailgun.qc | 18 + src/shared/w_plasma_cannon.qc | 371 ++++++++++++++++ src/shared/w_plasma_rifle.qc | 410 ++++++++++++++++++ src/shared/w_proxmine.qc | 271 ++++++++++++ src/shared/w_rocketlauncher.qc | 16 + src/shared/w_supernailgun.qc | 15 + src/shared/weapons.h | 31 ++ src/shared/weapons.qc | 13 +- zpak001.pk3dir/def/weapon_grenadelauncher.def | 15 - zpak001.pk3dir/def/weapon_nailgun.def | 15 - zpak001.pk3dir/def/weapon_rocketlauncher.def | 15 - zpak001.pk3dir/def/weapon_supernailgun.def | 15 - zpak001.pk3dir/def/weapons.def | 7 + zpak001.pk3dir/def/weapons/extraweapons.def | 205 +++++++++ .../def/weapons/grenadelauncher.def | 54 +++ .../lightning.def} | 2 +- zpak001.pk3dir/def/weapons/nailgun.def | 39 ++ zpak001.pk3dir/def/weapons/rocketlauncher.def | 59 +++ zpak001.pk3dir/def/weapons/supernailgun.def | 39 ++ .../supershotgun.def} | 2 +- zpak001.pk3dir/particles/extraweapons.cfg | 44 ++ .../particles/weapon_grenadelauncher.cfg | 15 + zpak001.pk3dir/particles/weapon_nailgun.cfg | 14 + .../particles/weapon_rocketlauncher.cfg | 17 + .../particles/weapon_supernailgun.cfg | 14 + zpak001.pk3dir/scripts/constants.txt | 21 + zpak001.pk3dir/sound/weapons_dmc.sndshd | 16 + 50 files changed, 4228 insertions(+), 221 deletions(-) create mode 100644 src/client/game_event.qc create mode 100644 src/client/init.qc create mode 100644 src/server/extraitems.qc create mode 100644 src/shared/w_grapple.qc create mode 100644 src/shared/w_hammer.qc create mode 100644 src/shared/w_ice_shotgun.qc create mode 100644 src/shared/w_ice_supershotgun.qc create mode 100644 src/shared/w_lava_nailgun.qc create mode 100644 src/shared/w_lava_supernailgun.qc create mode 100644 src/shared/w_multi_gren.qc create mode 100644 src/shared/w_multi_rocket.qc create mode 100644 src/shared/w_plasma_cannon.qc create mode 100644 src/shared/w_plasma_rifle.qc create mode 100644 src/shared/w_proxmine.qc delete mode 100644 zpak001.pk3dir/def/weapon_grenadelauncher.def delete mode 100644 zpak001.pk3dir/def/weapon_nailgun.def delete mode 100644 zpak001.pk3dir/def/weapon_rocketlauncher.def delete mode 100644 zpak001.pk3dir/def/weapon_supernailgun.def create mode 100644 zpak001.pk3dir/def/weapons.def create mode 100644 zpak001.pk3dir/def/weapons/extraweapons.def create mode 100644 zpak001.pk3dir/def/weapons/grenadelauncher.def rename zpak001.pk3dir/def/{weapon_lightning.def => weapons/lightning.def} (87%) create mode 100644 zpak001.pk3dir/def/weapons/nailgun.def create mode 100644 zpak001.pk3dir/def/weapons/rocketlauncher.def create mode 100644 zpak001.pk3dir/def/weapons/supernailgun.def rename zpak001.pk3dir/def/{weapon_supershotgun.def => weapons/supershotgun.def} (86%) create mode 100644 zpak001.pk3dir/particles/extraweapons.cfg create mode 100644 zpak001.pk3dir/particles/weapon_grenadelauncher.cfg create mode 100644 zpak001.pk3dir/particles/weapon_nailgun.cfg create mode 100644 zpak001.pk3dir/particles/weapon_rocketlauncher.cfg create mode 100644 zpak001.pk3dir/particles/weapon_supernailgun.cfg create mode 100644 zpak001.pk3dir/scripts/constants.txt diff --git a/src/client/game_event.qc b/src/client/game_event.qc new file mode 100644 index 0000000..4046f5c --- /dev/null +++ b/src/client/game_event.qc @@ -0,0 +1,111 @@ +/* + * 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. + */ + +void +EV_PickupMessage(void) +{ + string titlesMsg = __NULL__; + int weapon = readbyte(); + string ammoShells = ftos(readbyte()); + string ammoNails = ftos(readbyte()); + string ammoRockets = ftos(readbyte()); + string ammoCells = ftos(readbyte()); + + switch (weapon) { + case WEAPON_SUPERSHOTGUN: + titlesMsg = Titles_GetTextBody("You_Get_SS"); + break; + case WEAPON_NAILGUN: + titlesMsg = Titles_GetTextBody("You_Get_NG"); + break; + case WEAPON_SUPERNAILGUN: + titlesMsg = Titles_GetTextBody("You_Get_SG"); + break; + case WEAPON_ROCKETLAUNCHER: + titlesMsg = Titles_GetTextBody("You_Get_RL"); + break; + case WEAPON_GRENADELAUNCHER: + titlesMsg = Titles_GetTextBody("You_Get_GL"); + break; + case WEAPON_LIGHTNING: + titlesMsg = Titles_GetTextBody("You_Get_LG"); + break; + default: + titlesMsg = Titles_GetTextBody("You_Get_NoGun"); + } + + CSQC_Parse_Print(sprintf(titlesMsg, ammoShells, ammoNails, ammoRockets, ammoCells), PRINT_HIGH); +} + +int +ClientGame_EventParse(float fHeader) +{ + switch (fHeader) { + case EV_DMC_PICKUPMSG: + EV_PickupMessage(); + break; + case EV_OBITUARY: + Obituary_Parse(); + break; + case EV_HITNOTIFY: + pSeatLocal->m_flDamageIndicator = 1.0f; + break; + case EV_BLOOD: + vector vBloodPos; + vector vBloodColor; + + vBloodPos[0] = readcoord(); + vBloodPos[1] = readcoord(); + vBloodPos[2] = readcoord(); + + vBloodColor[0] = readbyte() / 255; + vBloodColor[1] = readbyte() / 255; + vBloodColor[2] = readbyte() / 255; + + FX_Blood(vBloodPos, vBloodColor); + break; + case EV_CHAT: + float fSender = readbyte(); + float fTeam = readbyte(); + string sMessage = readstring(); + + CSQC_Parse_Print(sprintf("%s: %s", getplayerkeyvalue(fSender, "name"), sMessage), PRINT_CHAT); + break; + case EV_CHAT_TEAM: + float fSender2 = readbyte(); + float fTeam2 = readbyte(); + string sMessage2 = readstring(); + + CSQC_Parse_Print(sprintf("[TEAM] %s: %s", getplayerkeyvalue(fSender2, "name"), sMessage2), PRINT_CHAT); + break; + case EV_VIEWMODEL: + View_PlayAnimation(readbyte()); + break; + case EV_WEAPON_PICKUP: + int w = readbyte(); + + if (autocvar_cl_autoweaponswitch == 1) { + sendevent("PlayerSwitchWeapon", "i", w); + } + + HUD_WeaponPickupNotify(w); + break; + default: + return (0); + } + + return (1); +} diff --git a/src/client/init.qc b/src/client/init.qc new file mode 100644 index 0000000..1fafae1 --- /dev/null +++ b/src/client/init.qc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016-2021 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. + */ + +/* +================= +ClientGame_Init + +Comparable to worldspawn in SSQC in that it's mostly used for precaches +================= +*/ +void +ClientGame_Init(float apilevel, string enginename, float engineversion) +{ + Obituary_Init(); + registercommand("chooseteam"); +} + +void VGUI_ShowMOTD(); + +void +ClientGame_InitDone(void) +{ + VGUI_ShowMOTD(); +} + +void +ClientGame_RendererRestart(string rstr) +{ + precache_model("models/shell.mdl"); + precache_model("models/shotgunshell.mdl"); + + /* there's also muzzleflash.spr, but that's just MUZZLE_SMALL again */ + MUZZLE_RIFLE = (int)getmodelindex("sprites/muzzleflash1.spr"); + MUZZLE_SMALL = (int)getmodelindex("sprites/muzzleflash2.spr"); + MUZZLE_WEIRD = (int)getmodelindex("sprites/muzzleflash3.spr"); + + Damage_Precache(); + Obituary_Precache(); + + FX_Blood_Init(); + + BEAM_TRIPMINE = particleeffectnum("weapon_tripmine.beam"); +} diff --git a/src/client/progs.src b/src/client/progs.src index 66f98f4..eb6a0dd 100644 --- a/src/client/progs.src +++ b/src/client/progs.src @@ -31,6 +31,7 @@ game_event.qc ../../../valve/src/client/viewmodel.qc ../../../valve/src/client/view.qc ../../../valve/src/client/obituary.qc +../../../valve/src/client/hud_sprite.qc ../../../valve/src/client/hud_itemnotify.qc ../../../valve/src/client/hud_dmgnotify.qc hud_ammonotify.qc diff --git a/src/server/ammo.qc b/src/server/ammo.qc index db63be9..e7acc95 100644 --- a/src/server/ammo.qc +++ b/src/server/ammo.qc @@ -261,3 +261,168 @@ item_cells::Touch(entity eToucher) } +/* extra items start here */ +/*QUAKED item_lava_spikes (0 0 0.8) (-16 -16 0) (16 16 32) + +Lava Spikes from Mission Pack 2 by Rogue Entertainment + +-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY -------- +model="models/b_lnail.mdl" +*/ + +class item_lava_spikes:item_ammo +{ + void(void) item_lava_spikes; + virtual void(entity) Touch; +}; + +void +item_lava_spikes::item_lava_spikes(void) +{ + model = "models/b_lnail0.mdl"; + noise = "models/b_lnail1.mdl"; +} + +void +item_lava_spikes::Touch(entity eToucher) +{ + if not (eToucher.flags & FL_CLIENT) { + return; + } + if (eToucher.classname == "player") { + player pl = (player)eToucher; + if (pl.ammo_lava_nails < 200) { + if (HasSpawnFlags(1)) + pl.ammo_lava_nails = bound(0, pl.ammo_lava_nails + 50, 200); + else + pl.ammo_lava_nails = bound(0, pl.ammo_lava_nails + 25, 200); + + item_ammo::Touch(eToucher); + } + } +} + + +/*QUAKED item_multi_rockets (0 0 0.8) (-16 -16 0) (16 16 32) + +Lava Spikes from Mission Pack 2 by Rogue Entertainment + +-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY -------- +model="models/b_lnail.mdl" +*/ + +class item_multi_rockets:item_ammo +{ + void(void) item_multi_rockets; + virtual void(entity) Touch; +}; + +void +item_multi_rockets::item_multi_rockets(void) +{ + model = "models/b_mrock0.mdl"; + noise = "models/b_mrock1.mdl"; +} + +void +item_multi_rockets::Touch(entity eToucher) +{ + if not (eToucher.flags & FL_CLIENT) { + return; + } + if (eToucher.classname == "player") { + player pl = (player)eToucher; + if (pl.ammo_multi_rockets < 100) { + if (HasSpawnFlags(1)) + pl.ammo_multi_rockets = bound(0, pl.ammo_multi_rockets + 10, 100); + else + pl.ammo_multi_rockets = bound(0, pl.ammo_multi_rockets + 5, 100); + + item_ammo::Touch(eToucher); + } + } +} + + +/*QUAKED item_multi_rockets (0 0 0.8) (-16 -16 0) (16 16 32) + +Multi Rockets from Mission Pack 2 by Rogue Entertainment + +-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY -------- +model="models/b_plas0.mdl" +*/ + +class item_plasma:item_ammo +{ + void(void) item_plasma; + virtual void(entity) Touch; +}; + +void +item_plasma::item_plasma(void) +{ + model = "models/b_plas0.mdl"; + noise = "models/b_plas1.mdl"; +} + +void +item_plasma::Touch(entity eToucher) +{ + if not (eToucher.flags & FL_CLIENT) { + return; + } + if (eToucher.classname == "player") { + player pl = (player)eToucher; + if (pl.ammo_plasma < 100) { + if (HasSpawnFlags(1)) + pl.ammo_plasma = bound(0, pl.ammo_plasma + 12, 100); + else + pl.ammo_plasma = bound(0, pl.ammo_plasma + 6, 100); + + item_ammo::Touch(eToucher); + } + } +} + + + + +/*QUAKED item_ice_shells (0 0 0.8) (-16 -16 0) (16 16 32) + +Ice Shells for FreeDMC + +-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY -------- +model="models/w_icebox.mdl" +*/ + +class item_ice_shells:item_ammo +{ + void(void) item_ice_shells; + virtual void(entity) Touch; +}; + +void +item_ice_shells::item_ice_shells(void) +{ + model = "models/w_icebox.mdl"; + noise = "models/w_icebox_big.mdl"; +} + +void +item_ice_shells::Touch(entity eToucher) +{ + if not (eToucher.flags & FL_CLIENT) { + return; + } + if (eToucher.classname == "player") { + player pl = (player)eToucher; + if (pl.ammo_ice_shells < 200) { + if (HasSpawnFlags(1)) + pl.ammo_ice_shells = bound(0, pl.ammo_ice_shells + 40, 200); + else + pl.ammo_ice_shells = bound(0, pl.ammo_ice_shells + 20, 200); + + item_ammo::Touch(eToucher); + } + } +} \ No newline at end of file diff --git a/src/server/extraitems.qc b/src/server/extraitems.qc new file mode 100644 index 0000000..23f38a0 --- /dev/null +++ b/src/server/extraitems.qc @@ -0,0 +1,56 @@ +/* DoE extra items for DMC */ + +/* anti gravity belt */ +class item_powerup_belt:NSItem +{ + void item_powerup_belt(void); + + virtual void Respawn(void); + virtual void Touch(entity); + +}; + +void +item_powerup_belt::item_powerup_belt(void) +{ + +} + +void +item_powerup_belt::Respawn(void) +{ + SetModel("models/beltup.mdl"); + modelflags = MF_ROTATE; +} + +void +item_powerup_belt::Touch(entity eToucher) +{ +} + +/* the shield upgrade */ +class item_powerup_shield:NSItem +{ + void item_powerup_shield(void); + + virtual void Respawn(void); + virtual void Touch(entity); +}; + +void +item_powerup_shield::item_powerup_shield(void) +{ + +} + +void +item_powerup_shield::Respawn(void) +{ + SetModel("models/shield.mdl"); + modelflags = MF_ROTATE; +} + +void +item_powerup_shield::Touch(entity eToucher) +{ +} \ No newline at end of file diff --git a/src/server/gamerules_multiplayer.qc b/src/server/gamerules_multiplayer.qc index 10cfba6..28a8028 100644 --- a/src/server/gamerules_multiplayer.qc +++ b/src/server/gamerules_multiplayer.qc @@ -122,7 +122,9 @@ HLMultiplayerRules::PlayerDeath(NSClientPlayer pl) /* either gib, or make a corpse */ if (pl.health < -50) { - FX_GibHuman(pl.origin, vectoangles(pl.origin - g_dmg_eAttacker.origin), g_dmg_iDamage * 2.0f); + vector gibDir = vectoangles(pl.origin - g_dmg_eAttacker.origin); + float gibStrength = g_dmg_iDamage * 2.0f; + BreakModel_Entity(pl, gibDir, gibStrength); } else { FX_Corpse_Spawn((player)pl, ANIM_DIESIMPLE); } @@ -195,10 +197,11 @@ HLMultiplayerRules::PlayerSpawn(NSClientPlayer pp) pl.gravity = __NULL__; pl.SetFrame(1); pl.SendFlags = UPDATE_ALL; - pl.iBleeds = TRUE; pl.SetInfoKey("*spec", "0"); pl.SetInfoKey("*dead", "0"); pl.SetInfoKey("*deaths", ftos(pl.deaths)); + pl.SetPropData("actor_human"); + pl.SetCanBleed(true); LevelNewParms(); LevelDecodeParms(pl); diff --git a/src/server/gamerules_singleplayer.qc b/src/server/gamerules_singleplayer.qc index 681614c..b351a8e 100644 --- a/src/server/gamerules_singleplayer.qc +++ b/src/server/gamerules_singleplayer.qc @@ -14,6 +14,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +bool FreeDMC_CanThreeWave(void); +bool FreeDMC_CanExtra(void); + bool HLSingleplayerRules::IsMultiplayer(void) { @@ -37,7 +40,9 @@ HLSingleplayerRules::PlayerDeath(NSClientPlayer pl) } if (pl.health < -50) { - FX_GibHuman(pl.origin, vectoangles(pl.origin - g_dmg_eAttacker.origin), g_dmg_iDamage * 2.0f); + vector gibDir = vectoangles(pl.origin - g_dmg_eAttacker.origin); + float gibStrength = g_dmg_iDamage * 2.0f; + BreakModel_Entity(pl, gibDir, gibStrength); } /* Let's handle corpses on the clientside */ @@ -83,6 +88,7 @@ HLSingleplayerRules::PlayerSpawn(NSClientPlayer pl) pl.ClearVelocity(); pl.SetInfoKey("*spec", "0"); pl.SetInfoKey("*deaths", ftos(pl.deaths)); + pl.SetPropData("actor_human"); pl.SetCanBleed(true); if (startspot != "") { @@ -116,6 +122,21 @@ HLSingleplayerRules::ImpulseCommand(NSClient bp, float num) Weapons_AddItem(pl, WEAPON_GRENADELAUNCHER, -1); Weapons_AddItem(pl, WEAPON_ROCKETLAUNCHER, -1); Weapons_AddItem(pl, WEAPON_LIGHTNING, -1); + + if (FreeDMC_CanExtra()) { + Weapons_AddItem(pl, WEAPON_HAMMER, -1); + Weapons_AddItem(pl, WEAPON_GRAPPLE, -1); + Weapons_AddItem(pl, WEAPON_ICESHOTGUN, -1); + Weapons_AddItem(pl, WEAPON_ICESUPERSHOTGUN, -1); + Weapons_AddItem(pl, WEAPON_MULTIGREN, -1); + Weapons_AddItem(pl, WEAPON_MULTIROCKET, -1); + Weapons_AddItem(pl, WEAPON_LAVANAILGUN, -1); + Weapons_AddItem(pl, WEAPON_LAVASUPERNAILGUN, -1); + Weapons_AddItem(pl, WEAPON_PLASMACANNON, -1); + Weapons_AddItem(pl, WEAPON_PLASMARIFLE, -1); + Weapons_AddItem(pl, WEAPON_PROXMINE, -1); + } + break; default: return super::ImpulseCommand(bp, num); diff --git a/src/server/progs.src b/src/server/progs.src index 22a48e7..033499e 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -18,42 +18,6 @@ defs.h ../shared/include.src - -../../../valve/src/server/monster_apache.qc -../../../valve/src/server/monster_alien_controller.qc -../../../valve/src/server/monster_alien_grunt.qc -../../../valve/src/server/monster_alien_slave.qc -../../../valve/src/server/monster_barnacle.qc -../../../valve/src/server/monster_barney.qc -../../../valve/src/server/monster_barney_dead.qc -../../../valve/src/server/monster_bigmomma.qc -../../../valve/src/server/monster_bloater.qc -../../../valve/src/server/monster_bullchicken.qc -../../../valve/src/server/monster_cockroach.qc -../../../valve/src/server/monster_flyer_flock.qc -../../../valve/src/server/monster_gargantua.qc -../../../valve/src/server/monster_gman.qc -../../../valve/src/server/monster_headcrab.qc -../../../valve/src/server/monster_babycrab.qc -../../../valve/src/server/monster_hevsuit_dead.qc -../../../valve/src/server/monster_houndeye.qc -../../../valve/src/server/monster_human_grunt.qc -../../../valve/src/server/monster_hgrunt_dead.qc -../../../valve/src/server/monster_human_assassin.qc -../../../valve/src/server/monster_ichthyosaur.qc -../../../valve/src/server/monster_leech.qc -../../../valve/src/server/monster_miniturret.qc -../../../valve/src/server/monster_nihilanth.qc -../../../valve/src/server/monster_osprey.qc -../../../valve/src/server/monster_rat.qc -../../../valve/src/server/monster_scientist_dead.qc -../../../valve/src/server/monster_sitting_scientist.qc -../../../valve/src/server/monster_scientist.qc -../../../valve/src/server/monster_sentry.qc -../../../valve/src/server/monster_tentacle.qc -../../../valve/src/server/monster_turret.qc -../../../valve/src/server/monster_zombie.qc - ../../../valve/src/server/player.qc ../../../valve/src/server/items.qc ../../../valve/src/server/item_longjump.qc @@ -62,15 +26,12 @@ defs.h ../../../valve/src/server/item_battery.qc item_backpack.qc ../../../valve/src/server/world_items.qc -../../../valve/src/server/xen_spore_small.qc -../../../valve/src/server/xen_spore_medium.qc -../../../valve/src/server/xen_spore_large.qc -../../../valve/src/server/xen_hair.qc -../../../valve/src/server/xen_plantlight.qc + ammo.qc item_armor.qc item_health.qc item_artifact.qc +extraitems.qc ambient_comp_hum.qc ambient_drip.qc diff --git a/src/shared/events.h b/src/shared/events.h index 693e457..359cf95 100644 --- a/src/shared/events.h +++ b/src/shared/events.h @@ -17,4 +17,5 @@ enum { EV_DMC_PICKUPMSG, + EV_GIBALIEN, }; diff --git a/src/shared/include.src b/src/shared/include.src index 83ead32..c5f80f8 100644 --- a/src/shared/include.src +++ b/src/shared/include.src @@ -9,12 +9,7 @@ player.qc pmove.qc ../../../valve/src/shared/fx_blood.qc -../../../valve/src/shared/fx_breakmodel.qc -../../../valve/src/shared/fx_explosion.qc -../../../valve/src/shared/fx_gibhuman.qc -../../../valve/src/shared/fx_spark.qc ../../../valve/src/shared/fx_corpse.qc -../../../valve/src/shared/fx_impact.qc items.h weapons.h @@ -26,6 +21,20 @@ w_supernailgun.qc w_grenadelauncher.qc w_rocketlauncher.qc w_lightning.qc + +w_grapple.qc + +w_hammer.qc +w_lava_nailgun.qc +w_lava_supernailgun.qc +w_plasma_cannon.qc +w_plasma_rifle.qc +w_multi_rocket.qc +w_multi_gren.qc +w_proxmine.qc +w_ice_shotgun.qc +w_ice_supershotgun.qc + weapons.qc ../../../valve/src/shared/weapon_common.qc #endlist diff --git a/src/shared/items.h b/src/shared/items.h index ca8036d..f42e886 100644 --- a/src/shared/items.h +++ b/src/shared/items.h @@ -23,29 +23,29 @@ #define ITEM_ROCKETLAUNCHER 0x00000040i #define ITEM_LIGHTNING 0x00000080i -#define ITEM_UNUSED10 0x00000100i -#define ITEM_UNUSED11 0x00000200i -#define ITEM_UNUSED12 0x00000400i -#define ITEM_UNUSED13 0x00000800i -#define ITEM_UNUSED14 0x00001000i -#define ITEM_UNUSED15 0x00002000i -#define ITEM_SUIT 0x00004000i -#define ITEM_LONGJUMP 0x00008000i +#define ITEM_LASER 0x00000100i +#define ITEM_HAMMER 0x00000200i +#define ITEM_PROXMINE 0x00000400i +#define ITEM_LAVANAIL 0x00000800i +#define ITEM_LAVASUPERNAILGUN 0x00001000i +#define ITEM_MULTIGREN 0x00002000i +#define ITEM_SUIT 0x00004000i +#define ITEM_LONGJUMP 0x00008000i -#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 -#define ITEM_UNUSED24 0x00800000i +#define ITEM_QUAD 0x00010000i +#define ITEM_INVIS 0x00020000i +#define ITEM_INVULN 0x00040000i +#define ITEM_ENVIROSUIT 0x00080000i +#define ITEM_MULTIROCKET 0x00100000i +#define ITEM_PLASMACAN 0x00200000i +#define ITEM_PLASMARIF 0x00400000i +#define ITEM_PROXMINE 0x00800000i -#define ITEM_UNUSED25 0x01000000i -#define ITEM_UNUSED26 0x02000000i -#define ITEM_UNUSED27 0x04000000i -#define ITEM_UNUSED28 0x08000000i -#define ITEM_UNUSED29 0x10000000i -#define ITEM_UNUSED30 0x20000000i -#define ITEM_UNUSED31 0x40000000i -#define ITEM_UNUSED32 0x80000000i +#define ITEM_ICESHOTGUN 0x01000000i +#define ITEM_ICESUPERSHOTGUN 0x02000000i +#define ITEM_GRAPPLE 0x04000000i +#define ITEM_UNUSED28 0x08000000i +#define ITEM_UNUSED29 0x10000000i +#define ITEM_UNUSED30 0x20000000i +#define ITEM_UNUSED31 0x40000000i +#define ITEM_UNUSED32 0x80000000i \ No newline at end of file diff --git a/src/shared/player.qc b/src/shared/player.qc index c4d4330..2406e5f 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -15,89 +15,7 @@ */ #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 - another model - but because FTEQW does not support that for HLMDL we - are forced to manually position the bones of our attachnment - by iterating over them and manually setting their position in 3D-space. -*/ -string g_pbones[] = -{ - "Bip01", - "Bip01 Footsteps", - "Bip01 Pelvis", - "Bip01 L Leg", - "Bip01 L Leg1", - "Bip01 L Foot", - "Bip01 L Toe0", - "Bip01 L Toe01", - "Bip01 L Toe02", - "Dummy16", - "Bip01 R Leg", - "Bip01 R Leg1", - "Bip01 R Foot", - "Bip01 R Toe0", - "Bip01 R Toe01", - "Bip01 R Toe02", - "Dummy11", - "Bip01 Spine", - "Bip01 Spine1", - "Bip01 Spine2", - "Bip01 Spine3", - "Bip01 Neck", - "Bip01 Head", - "Dummy21", - "Dummy08", - "Bone02", - "Bone03", - "Bone04", - "Dummy05", - "Bone09", - "Bone10", - "Dummy04", - "Bone05", - "Bone06", - "Dummy03", - "Bone07", - "Bone08", - "Dummy09", - "Bone11", - "Bone12", -"Dummy10", - "Bone13", - "Bone14", - "Bone15", - "Bip01 L Arm", - "Bip01 L Arm1", - "Bip01 L Arm2", - "Bip01 L Hand", - "Bip01 L Finger0", - "Bip01 L Finger01", - "Bip01 L Finger02", - "Dummy06", - "Bip01 L Finger1", - "Bip01 L Finger11", - "Bip01 L Finger12", - "Dummy07", - "Bip01 R Arm", - "Bip01 R Arm1", - "Bip01 R Arm2", - "Bip01 R Hand", - "Bip01 R Finger0", - "Bip01 R Finger01", - "Bip01 R Finger02", - "Dummy01", - "Bip01 R Finger1", - "Bip01 R Finger11", - "Bip01 R Finger12", - "Dummy02", - "Box02", - "Bone08", - "Bone15" -}; -#endif +#include "../../../valve/src/shared/skeleton.h" /* all custom SendFlags bits we can possibly send */ enumflags @@ -134,7 +52,14 @@ class player:NSClientPlayer PREDICTED_FLOAT_N(ammo_rockets) PREDICTED_FLOAT_N(ammo_cells) + /* extra types */ + PREDICTED_FLOAT(ammo_lava_nails) + PREDICTED_FLOAT(ammo_multi_rockets) + PREDICTED_FLOAT(ammo_plasma) + PREDICTED_FLOAT(ammo_ice_shells) + #ifdef SERVER + entity hook; float m_quadFinishTime; float m_invisFinishTime; float m_invulnFinishTime; @@ -322,6 +247,11 @@ player::ReceiveEntity(float new, float flChanged) READENTITY_BYTE(ammo_rockets, PLAYER_AMMO1) READENTITY_BYTE(ammo_cells, PLAYER_AMMO1) + READENTITY_BYTE(ammo_lava_nails, PLAYER_AMMO1) + READENTITY_BYTE(ammo_multi_rockets, PLAYER_AMMO1) + READENTITY_BYTE(ammo_plasma, PLAYER_AMMO1) + READENTITY_BYTE(ammo_ice_shells, PLAYER_AMMO1) + setorigin(this, origin); /* these only concern the current player */ @@ -371,6 +301,11 @@ player::PredictPreFrame(void) SAVE_STATE(ammo_nails) SAVE_STATE(ammo_rockets) SAVE_STATE(ammo_cells) + + SAVE_STATE(ammo_lava_nails) + SAVE_STATE(ammo_multi_rockets) + SAVE_STATE(ammo_plasma) + SAVE_STATE(ammo_ice_shells) } /* @@ -396,6 +331,11 @@ player::PredictPostFrame(void) ROLL_BACK(ammo_nails) ROLL_BACK(ammo_rockets) ROLL_BACK(ammo_cells) + + ROLL_BACK(ammo_lava_nails) + ROLL_BACK(ammo_multi_rockets) + ROLL_BACK(ammo_plasma) + ROLL_BACK(ammo_ice_shells) } #else @@ -415,6 +355,12 @@ player::Save(float handle) SaveInt(handle, "ammo_nails", ammo_nails); SaveInt(handle, "ammo_rockets", ammo_rockets); SaveInt(handle, "ammo_cells", ammo_cells); + + /* extra */ + SaveInt(handle, "ammo_lava_nails", ammo_lava_nails); + SaveInt(handle, "ammo_multi_rockets", ammo_multi_rockets); + SaveInt(handle, "ammo_plasma", ammo_plasma); + SaveInt(handle, "ammo_ice_shells", ammo_ice_shells); } void @@ -450,6 +396,19 @@ player::Restore(string strKey, string strValue) case "ammo_cells": ammo_cells = ReadInt(strValue); break; + /* extra */ + case "ammo_lava_nails": + ammo_lava_nails = ReadInt(strValue); + break; + case "ammo_multi_rockets": + ammo_multi_rockets = ReadInt(strValue); + break; + case "ammo_plasma": + ammo_plasma = ReadInt(strValue); + break; + case "ammo_ice_shells": + ammo_ice_shells = ReadInt(strValue); + break; default: super::Restore(strKey, strValue); } @@ -525,6 +484,11 @@ player::EvaluateEntity(void) EVALUATE_FIELD(ammo_nails, PLAYER_AMMO1) EVALUATE_FIELD(ammo_rockets, PLAYER_AMMO1) EVALUATE_FIELD(ammo_cells, PLAYER_AMMO1) + + EVALUATE_FIELD(ammo_lava_nails, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_multi_rockets, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_plasma, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_ice_shells, PLAYER_AMMO1) } /* @@ -560,6 +524,11 @@ player::SendEntity(entity ePEnt, float flChanged) SENDENTITY_BYTE(ammo_rockets, PLAYER_AMMO1) SENDENTITY_BYTE(ammo_cells, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_lava_nails, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_multi_rockets, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_plasma, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_ice_shells, PLAYER_AMMO1) + return (1); } #endif @@ -600,4 +569,8 @@ player::player(void) ammo_nails = 0; ammo_rockets = 0; ammo_cells = 0; + ammo_lava_nails = 0; + ammo_multi_rockets = 0; + ammo_plasma = 0; + ammo_ice_shells = 0; } diff --git a/src/shared/w_crowbar.qc b/src/shared/w_crowbar.qc index df7f6c0..a3732f5 100644 --- a/src/shared/w_crowbar.qc +++ b/src/shared/w_crowbar.qc @@ -108,7 +108,7 @@ w_crowbar_primary(player pl) if (trace_ent.iBleeds) { FX_Blood(trace_endpos, [1,0,0]); } else { - FX_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal); + SurfData_Impact(trace_ent, trace_endpos, trace_plane_normal); } if (trace_ent.takedamage) { diff --git a/src/shared/w_grapple.qc b/src/shared/w_grapple.qc new file mode 100644 index 0000000..71fd8f4 --- /dev/null +++ b/src/shared/w_grapple.qc @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016-2021 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. + */ + +#ifdef CLIENT +/* because some people apparently prefer the worse quality one */ +var int autocvar_cl_tonguemode = 0; +#endif + +enum +{ + GRAP_IDLE, + GRAP_SHOOT, +}; + +void +w_grapple_precache(void) +{ +#ifdef SERVER + precache_sound("weapons/bgrapple_cough.wav"); + precache_sound("weapons/bgrapple_fire.wav"); + precache_sound("weapons/bgrapple_impact.wav"); + precache_sound("weapons/bgrapple_pull.wav"); + precache_sound("weapons/bgrapple_release.wav"); + precache_sound("weapons/bgrapple_wait.wav"); + precache_model("sprites/_tongue.spr"); + precache_model("sprites/tongue.spr"); + precache_model("models/w_bgrap.mdl"); +#else + precache_model("models/v_ghook.mdl"); + precache_model("models/v_bgrap_tonguetip.mdl"); + precache_model("models/p_bgrap.mdl"); +#endif +} + +void +w_grapple_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, -1, -1); +} + +string +w_grapple_wmodel(void) +{ + return "models/w_bgrap.mdl"; +} + +string +w_grapple_pmodel(player pl) +{ + return "models/p_bgrap.mdl"; +} + +string +w_grapple_deathmsg(void) +{ + return "%s was assaulted by %s's Barnacle."; +} + +void +w_grapple_draw(player pl) +{ + Weapons_SetModel("models/v_ghook.mdl"); + Weapons_ViewAnimation(pl, GRAP_IDLE); +} + +void +w_grapple_holster(player pl) +{ + Weapons_ViewAnimation(pl, GRAP_IDLE); +} + +/* called once the tongue hits a wall */ +#ifdef SERVER +void +Grapple_Touch(void) +{ + player pl = (player)self.owner; + pl.hook.movetype = MOVETYPE_NONE; + pl.hook.touch = __NULL__; + pl.hook.velocity = [0,0,0]; + pl.hook.solid = SOLID_NOT; + pl.grapvelocity = (pl.hook.origin); +} +#endif + +/* spawn and pull */ +void +w_grapple_primary(player pl) +{ +#ifdef SERVER + /* it's already been spawned. */ + if (pl.hook != __NULL__) { + /* play the looping reel anim once */ + if (pl.a_ammo1 == 1) { + pl.a_ammo1 = 2; + //Weapons_ViewAnimation(pl, BARN_FIRETRAVEL); + } else if (pl.a_ammo1 == 2) { + pl.hook.skin = 1; /* grappled */ + } + + if (pl.w_attack_next > 0.0) { + return; + } + + Weapons_MakeVectors(pl); + vector src = Weapons_GetCameraPos(pl); + traceline(src, src + (v_forward * 32), FALSE, pl); + if (trace_ent.takedamage == DAMAGE_YES && trace_ent.iBleeds) { + Damage_Apply(trace_ent, pl, 25, WEAPON_GRAPPLE, DMG_GENERIC); + } + pl.w_attack_next = 0.5f; + return; + } + + Weapons_MakeVectors(pl); + pl.hook = spawn(); + setorigin(pl.hook, Weapons_GetCameraPos(pl) + (v_forward * 16)); + pl.hook.owner = self; + pl.hook.velocity = v_forward * 1500; + pl.hook.movetype = MOVETYPE_FLYMISSILE; + pl.hook.solid = SOLID_BBOX; + pl.hook.angles = vectoangles(pl.hook.velocity); + pl.hook.touch = Grapple_Touch; + setsize(pl.hook, [0,0,0], [0,0,0]); + setmodel(pl.hook, "models/hook.mdl"); +#endif + + if (pl.w_attack_next > 0.0) { + return; + } + Weapons_ViewAnimation(pl, GRAP_SHOOT); + pl.w_attack_next = 1.0f; + +#ifdef CLIENT + Weapons_SetGeomset("geomset 1 2\n"); +#endif +} + +/* let go, hang */ +void +w_grapple_secondary(player pl) +{ +#ifdef SERVER + if (pl.hook == __NULL__) { + return; + } + + pl.hook.skin = 0; /* ungrappled */ + pl.grapvelocity = g_vec_null; + pl.w_attack_next = 0.0f; +#endif +} + +/* de-spawn and play idle anims */ +void +w_grapple_release(player pl) +{ +#ifdef SERVER + if (pl.hook != __NULL__) { + pl.a_ammo1 = 0; /* cache */ + pl.hook.skin = 0; /* ungrappled */ + remove(pl.hook); + pl.w_idle_next = 1.0f; + pl.hook = __NULL__; + pl.grapvelocity = g_vec_null; + } +#endif + pl.w_attack_next = 0.0f; +#ifdef CLIENT + Weapons_SetGeomset("geomset 1 0\n"); +#endif +} + +float +w_grapple_aimanim(player pl) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMSQUEAK : ANIM_AIMSQUEAK; +} + +void +w_grapple_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + if (selected) { + drawsubpic( + pos, + [170,45], + g_hudcb_spr, + [0,0], + [1,0.625], + g_hud_color, + a, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + g_hudcb_spr, + [0,0], + [1,0.625], + g_hud_color, + a, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_grapple = +{ + .name = "grapple", + .id = ITEM_GRAPPLE, + .slot = 0, + .slot_pos = 2, + .draw = w_grapple_draw, + .holster = w_grapple_holster, + .primary = w_grapple_primary, + .secondary = w_grapple_secondary, + .reload = __NULL__, + .release = w_grapple_release, + .postdraw = __NULL__, + .precache = w_grapple_precache, + .pickup = __NULL__, + .updateammo = w_grapple_updateammo, + .wmodel = w_grapple_wmodel, + .pmodel = w_grapple_pmodel, + .deathmsg = w_grapple_deathmsg, + .aimanim = w_grapple_aimanim, + .hudpic = w_grapple_hudpic +}; \ No newline at end of file diff --git a/src/shared/w_grenadelauncher.qc b/src/shared/w_grenadelauncher.qc index 0baf7ad..16d7f6a 100644 --- a/src/shared/w_grenadelauncher.qc +++ b/src/shared/w_grenadelauncher.qc @@ -23,6 +23,44 @@ Hornetgun Weapon */ +#ifdef CLIENT +void w_grenadelauncher_ejectbrass(void) +{ + static void w_supershotgun_ejectshell_death(void) { + remove(self); + } + static void w_supershotgun_ejectshell_touch(void) { + //if (other == world) + //Sound_Play(self, CHAN_BODY, "modelevent_shell.land"); + } + entity eShell = spawn(); + setmodel(eShell, "models/brass.mdl"); + eShell.solid = SOLID_BBOX; + eShell.movetype = MOVETYPE_BOUNCE; + eShell.drawmask = MASK_ENGINE; + eShell.angles = [pSeat->m_eViewModel.angles[0], pSeat->m_eViewModel.angles[1], 0]; + eShell.velocity = pSeat->m_vecPredictedVelocity; + + makevectors(pSeat->m_eViewModel.angles); + eShell.velocity += (v_forward * 0); + + if (random() < 0.5) + eShell.velocity += (v_right * 40); + else + eShell.velocity += (v_right * -40); + + eShell.velocity += (v_up * 100); + eShell.touch = w_supershotgun_ejectshell_touch; + + eShell.avelocity = [0,45,900]; + eShell.think = w_supershotgun_ejectshell_death; + eShell.nextthink = time + 2.5f; + setsize(eShell, [0,0,0], [0,0,0]); + + setorigin(eShell, pSeat->m_eViewModel.origin + (v_forward * 12) + (v_up * -24)); +} +#endif + enum { GRENLAUNCHER_IDLE, @@ -35,11 +73,13 @@ w_grenadelauncher_precache(void) #ifdef SERVER Sound_Precache("weapon_grenadelauncher.shoot"); Sound_Precache("weapon_grenadelauncher.bounce"); + Sound_Precache("weapon_grenadelauncher.explode"); precache_model("models/g_rock.mdl"); precache_model("models/grenade.mdl"); #else precache_model("models/v_rock.mdl"); precache_model("models/p_rock.mdl"); + precache_model("models/brass.mdl"); #endif } @@ -92,6 +132,7 @@ w_grenadelauncher_draw(player pl) void w_grenadelauncher_shootnade(player pl) { +#if 0 static void Grenade_Explode(void) { float dmg = Skill_GetValue("plr_grenadelauncher", 120); FX_Explosion(self.origin); @@ -138,6 +179,16 @@ w_grenadelauncher_shootnade(player pl) grenade.traileffectnum = particleeffectnum("weapon_rpg.trail"); setsize(grenade, [0,0,0], [0,0,0]); +#else + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_grenade"); + self = oldself; + rocket.Launch(pl.origin, pl.v_angle, 0.0f, 0.0f, 0.0f); +#endif + Sound_Play(pl, CHAN_WEAPON, "weapon_grenadelauncher.shoot"); } #endif @@ -166,6 +217,11 @@ w_grenadelauncher_primary(player pl) Weapons_ViewAnimation(pl, GRENLAUNCHER_SHOOT); Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); +#ifdef CLIENT + if (FreeDMC_CanExtra()) + View_AddEvent(w_grenadelauncher_ejectbrass, 0.325f); +#endif + pl.w_attack_next = 0.6; } diff --git a/src/shared/w_hammer.qc b/src/shared/w_hammer.qc new file mode 100644 index 0000000..3aa5e99 --- /dev/null +++ b/src/shared/w_hammer.qc @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_crowbar (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/w_hammer.mdl" + +DEATHMATCH CLASSIC (1999) ENTITY + +Crowbar Weapon + +*/ + +enum +{ + CBAR_IDLE, + CBAR_ATTACK, +}; + +void +w_hammer_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_crowbar.swing"); + Sound_Precache("weapon_crowbar.hit"); + Sound_Precache("weapon_crowbar.hitbody"); + Sound_Precache("player_dmc.jump"); + precache_model("models/w_hammer.mdl"); +#else + precache_model("models/v_hammer.mdl"); + precache_model("models/p_hammer.mdl"); +#endif +} + +string +w_hammer_wmodel(void) +{ + return "models/w_hammer.mdl"; +} +string +w_hammer_pmodel(player pl) +{ + return "models/p_hammer.mdl"; +} + +string +w_hammer_deathmsg(void) +{ + return "%s was assaulted by %s's Crowbar."; +} + +void +w_hammer_draw(player pl) +{ + Weapons_SetModel("models/v_hammer.mdl"); + Weapons_ViewAnimation(pl, CBAR_IDLE); +} + +void +w_hammer_primary(player pl) +{ + int anim = 0; + vector src; + + if (pl.w_attack_next) { + return; + } + + Weapons_MakeVectors(pl); + src = pl.origin + pl.view_ofs; + + /* make sure we can gib corpses */ + int oldhitcontents = pl.hitcontentsmaski; + pl.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE; + traceline(src, src + (v_forward * 64), FALSE, pl); + pl.hitcontentsmaski = oldhitcontents; + + pl.w_attack_next = 0.5f; + pl.w_idle_next = 2.5f; + + Weapons_ViewAnimation(pl, CBAR_ATTACK); + 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) { + return; + } + + /* don't bother with decals, we got squibs */ + if (trace_ent.iBleeds) { + FX_Blood(trace_endpos, [1,0,0]); + } else { + SurfData_Impact(trace_ent, trace_endpos, trace_plane_normal); + } + + if (trace_ent.takedamage) { + Damage_Apply(trace_ent, pl, Skill_GetValue("plr_crowbar", 20), WEAPON_CROWBAR, DMG_BLUNT); + if (trace_ent.iBleeds) { + Sound_Play(pl, CHAN_WEAPON, "weapon_crowbar.hitbody"); + } + } else { + Sound_Play(pl, CHAN_WEAPON, "weapon_crowbar.hit"); + DecalGroups_Place("Impact.Shot", trace_endpos + (v_forward * -2)); + } +#endif +} + +float +w_hammer_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR; +} + +void +w_hammer_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + if (selected) { + drawsubpic( + pos, + [170,45], + g_hudcb_spr, + [0,0], + [1,0.625], + g_hud_color, + a, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + g_hudcb_spr, + [0,0], + [1,0.625], + g_hud_color, + a, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +int +w_hammer_isempty(player pl) +{ + return 0; +} + +weapontype_t w_hammer_type(player pl) +{ + return WPNTYPE_CLOSE; +} + + +void +w_hammer_crosshair(player pl) +{ +#ifdef CLIENT + HUD_DrawQuakeCrosshair(); +#endif +} + +weapon_t w_hammer = +{ + .name = "hammer", + .id = ITEM_HAMMER, + .slot = 0, + .slot_pos = 1, + .weight = 0, + .draw = w_hammer_draw, + .holster = __NULL__, + .primary = w_hammer_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_hammer_crosshair, + .precache = w_hammer_precache, + .pickup = __NULL__, + .updateammo = __NULL__, + .wmodel = w_hammer_wmodel, + .pmodel = w_hammer_pmodel, + .deathmsg = w_hammer_deathmsg, + .aimanim = w_hammer_aimanim, + .isempty = w_hammer_isempty, + .type = w_hammer_type, + .hudpic = w_hammer_hudpic +}; diff --git a/src/shared/w_ice_shotgun.qc b/src/shared/w_ice_shotgun.qc new file mode 100644 index 0000000..6fb7a68 --- /dev/null +++ b/src/shared/w_ice_shotgun.qc @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_shotgun (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_shotgun.mdl" + +HALF-LIFE (1998) ENTITY + +Shotgun Weapon + +*/ + +enum +{ + SHOTGUN_IDLE1, + SHOTGUN_FIRE1 +}; + +#ifdef CLIENT +void w_ice_shotgun_ejectshell(void) +{ + static void w_ice_shotgun_ejectshell_death(void) { + remove(self); + } + static void w_ice_shotgun_ejectshell_touch(void) { + if (other == world) + Sound_Play(self, CHAN_BODY, "modelevent_shotgunshell.land"); + } + entity eShell = spawn(); + setmodel(eShell, "models/ishell.mdl"); + eShell.solid = SOLID_BBOX; + eShell.movetype = MOVETYPE_BOUNCE; + eShell.drawmask = MASK_ENGINE; + eShell.angles = [pSeat->m_eViewModel.angles[0], pSeat->m_eViewModel.angles[1], 0]; + eShell.velocity = pSeat->m_vecPredictedVelocity; + + makevectors(pSeat->m_eViewModel.angles); + eShell.velocity += (v_forward * 0); + eShell.velocity += (v_right * 80); + eShell.velocity += (v_up * 100); + eShell.touch = w_ice_shotgun_ejectshell_touch; + + eShell.avelocity = [0,45,900]; + eShell.think = w_ice_shotgun_ejectshell_death; + eShell.nextthink = time + 2.5f; + setsize(eShell, [0,0,0], [0,0,0]); + setorigin(eShell, pSeat->m_eViewModel.origin + (v_forward * 20) + (v_up * -16)); +} +#endif + +void w_ice_shotgun_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_shotgun.shoot"); + precache_model("models/g_ishot.mdl"); + precache_model("models/shotgunshell.mdl"); +#else + precache_model("models/v_ishot.mdl"); + precache_model("models/p_ishot.mdl"); + precache_model("models/ishell.mdl"); + Sound_Precache("modelevent_shotgunshell.land"); +#endif +} + +void +w_ice_shotgun_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_ice_shells, -1); +} + +string +w_ice_shotgun_wmodel(void) +{ + return "models/g_ishot.mdl"; +} + +string +w_ice_shotgun_pmodel(player pl) +{ + return "models/p_ishot.mdl"; +} + +string +w_ice_shotgun_deathmsg(void) +{ + return ""; +} + +int +w_ice_shotgun_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_ice_shells < MAX_A_SHELLS) { + pl.ammo_ice_shells = bound(0, pl.ammo_ice_shells + 5, MAX_A_SHELLS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_ice_shotgun_draw(player pl) +{ + Weapons_SetModel("models/v_ishot.mdl"); +} + +void +w_ice_shotgun_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_ice_shells <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + +#ifdef SERVER + /* 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_ice_shotgun_ejectshell, 0.25f); +#endif + + Weapons_ViewAnimation(pl, SHOTGUN_FIRE1); + Weapons_ViewPunchAngle(pl, [-5,0,0]); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTSHOTGUN : ANIM_SHOOTSHOTGUN, 0.5f); + + pl.ammo_ice_shells--; + + pl.w_idle_next = 0.5f; + pl.w_attack_next = 0.5; +} + +void +w_ice_shotgun_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + drawsubpic(aicon_pos, [24,24], g_hudsgammo, [0, 0], [1,1], g_hud_color, pSeatLocal->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE); +#endif +} + +float +w_ice_shotgun_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMSHOTGUN : ANIM_AIMSHOTGUN; +} + +int +w_ice_shotgun_isempty(player pl) +{ + if (pl.ammo_ice_shells <= 0) + return 1; + + return 0; +} + +void +w_ice_shotgun_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_ice_shotgun_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudsg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudsg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_ice_shells, MAX_A_SHELLS, a); +#endif +} + +weapontype_t +w_ice_shotgun_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t w_ice_shotgun = +{ + .name = "ice_shotgun", + .id = ITEM_ICESHOTGUN, + .slot = 1, + .slot_pos = 1, + .weight = 15, + .draw = w_ice_shotgun_draw, + .holster = __NULL__, + .primary = w_ice_shotgun_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_ice_shotgun_crosshair, + .precache = w_ice_shotgun_precache, + .pickup = w_ice_shotgun_pickup, + .updateammo = w_ice_shotgun_updateammo, + .wmodel = w_ice_shotgun_wmodel, + .pmodel = w_ice_shotgun_pmodel, + .deathmsg = w_ice_shotgun_deathmsg, + .aimanim = w_ice_shotgun_aimanim, + .isempty = w_ice_shotgun_isempty, + .type = w_ice_shotgun_type, + .hudpic = w_ice_shotgun_hudpic +}; diff --git a/src/shared/w_ice_supershotgun.qc b/src/shared/w_ice_supershotgun.qc new file mode 100644 index 0000000..aa51789 --- /dev/null +++ b/src/shared/w_ice_supershotgun.qc @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_9mmhandgun (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_shot2.mdl" + +HALF-LIFE (1998) ENTITY + +9mm Handgun/Glock Weapon +Same as weapon_glock + +*/ + +/*QUAKED weapon_glock (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_shot2.mdl" + +HALF-LIFE (1998) ENTITY + +9mm Handgun/Glock Weapon +Same as weapon_9mmhandgun + +*/ + +enum +{ + SUPERSHOT_IDLE, + SUPERSHOT_SHOOT, +}; + +#ifdef CLIENT +void w_ice_supershotgun_ejectshell_s(bool right) +{ + static void w_ice_supershotgun_ejectshell_death(void) { + remove(self); + } + static void w_ice_supershotgun_ejectshell_touch(void) { + if (other == world) + Sound_Play(self, CHAN_BODY, "modelevent_shell.land"); + } + entity eShell = spawn(); + setmodel(eShell, "models/ishell.mdl"); + eShell.solid = SOLID_BBOX; + eShell.movetype = MOVETYPE_BOUNCE; + eShell.drawmask = MASK_ENGINE; + eShell.angles = [pSeat->m_eViewModel.angles[0], pSeat->m_eViewModel.angles[1], 0]; + eShell.velocity = pSeat->m_vecPredictedVelocity; + + makevectors(pSeat->m_eViewModel.angles); + eShell.velocity += (v_forward * 0); + + if (right) + eShell.velocity += (v_right * 80); + else + eShell.velocity += (v_right * -80); + + eShell.velocity += (v_up * 100); + eShell.touch = w_ice_supershotgun_ejectshell_touch; + + eShell.avelocity = [0,45,900]; + eShell.think = w_ice_supershotgun_ejectshell_death; + eShell.nextthink = time + 2.5f; + setsize(eShell, [0,0,0], [0,0,0]); + + if (right) + setorigin(eShell, pSeat->m_eViewModel.origin + (v_forward * 28) + (v_right * 4) + (v_up * -18)); + else + setorigin(eShell, pSeat->m_eViewModel.origin + (v_forward * 28) + (v_right * -4) + (v_up * -18)); +} + +void w_ice_supershotgun_ejectshell(void) +{ + w_ice_supershotgun_ejectshell_s(true); + w_ice_supershotgun_ejectshell_s(false); +} +#endif + +void +w_ice_supershotgun_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_supershotgun.shoot"); + precache_model("models/g_ishot2.mdl"); + precache_model("models/ishell.mdl"); +#else + precache_model("models/v_ishot2.mdl"); + precache_model("models/p_ishot2.mdl"); + precache_model("models/ishell.mdl"); + Sound_Precache("modelevent_shell.land"); +#endif +} + +void +w_ice_supershotgun_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_ice_shells, -1); +} + +string +w_ice_supershotgun_wmodel(void) +{ + return "models/g_ishot2.mdl"; +} + +string +w_ice_supershotgun_pmodel(player pl) +{ + return "models/p_ishot2.mdl"; +} + +string +w_ice_supershotgun_deathmsg(void) +{ + return ""; +} + +int +w_ice_supershotgun_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_ice_shells < MAX_A_SHELLS) { + pl.ammo_ice_shells = bound(0, pl.ammo_ice_shells + 5, MAX_A_SHELLS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_ice_supershotgun_draw(player pl) +{ + Weapons_SetModel("models/v_ishot2.mdl"); + Weapons_ViewAnimation(pl, SUPERSHOT_IDLE); +} + +void +w_ice_supershotgun_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + + if (pl.ammo_ice_shells < 2) { + Weapons_SwitchBest(pl, 0); + return; + } + + /* actual firing */ + pl.ammo_ice_shells -= 2; + +#ifdef CLIENT + View_AddEvent(w_ice_supershotgun_ejectshell, 0.325f); +#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]); + Weapons_ViewAnimation(pl, SUPERSHOT_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTSHOTGUN : ANIM_SHOOTSHOTGUN, 0.5f); + + pl.w_attack_next = 0.7f; +} + +float +w_ice_supershotgun_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMSHOTGUN : ANIM_AIMSHOTGUN; +} + +void +w_ice_supershotgun_hud(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + drawsubpic(aicon_pos, [24,24], g_hudssgammo, [0, 0], [1,1], g_hud_color, pSeatLocal->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE); +#endif +} + +int +w_ice_supershotgun_isempty(player pl) +{ + if (pl.ammo_ice_shells <= 0) + return 1; + + return 0; +} + +void +w_ice_supershotgun_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_ice_supershotgun_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudssg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudssg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_ice_shells, MAX_A_SHELLS, a); +#endif +} + +weapontype_t +w_ice_supershotgun_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t w_ice_supershotgun = +{ + .name = "doubleshotgun", + .id = ITEM_ICESUPERSHOTGUN, + .slot = 2, + .slot_pos = 1, + .weight = 5, + .draw = w_ice_supershotgun_draw, + .holster = __NULL__, + .primary = w_ice_supershotgun_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_ice_supershotgun_hud, + .precache = w_ice_supershotgun_precache, + .pickup = w_ice_supershotgun_pickup, + .updateammo = w_ice_supershotgun_updateammo, + .wmodel = w_ice_supershotgun_wmodel, + .pmodel = w_ice_supershotgun_pmodel, + .deathmsg = w_ice_supershotgun_deathmsg, + .aimanim = w_ice_supershotgun_aimanim, + .isempty = w_ice_supershotgun_isempty, + .type = w_ice_supershotgun_type, + .hudpic = w_ice_supershotgun_hudpic +}; \ No newline at end of file diff --git a/src/shared/w_lava_nailgun.qc b/src/shared/w_lava_nailgun.qc new file mode 100644 index 0000000..8d4701d --- /dev/null +++ b/src/shared/w_lava_nailgun.qc @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_nailgun (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_nail.mdl" + +DEATHMATCH CLASSIC (1999) ENTITY + +Nailgun + +*/ + +enum +{ + NAILGUN_IDLE, + NAILGUN_SHOOT, +}; + +void +w_lava_nailgun_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_nailgun.shoot"); + precache_model("models/g_lnail.mdl"); +#else + precache_model("models/v_lnail.mdl"); + precache_model("models/p_lnail.mdl"); +#endif +} + +int +w_lava_nailgun_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_lava_nails < MAX_A_NAILS) { + pl.ammo_lava_nails = bound(0, pl.ammo_lava_nails + 30, MAX_A_NAILS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_lava_nailgun_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_lava_nails, -1); +} + +string +w_lava_nailgun_wmodel(void) +{ + return "models/g_lnail.mdl"; +} + +string +w_lava_nailgun_pmodel(player pl) +{ + return "models/p_lnail.mdl"; +} + +string +w_lava_nailgun_deathmsg(void) +{ + return ""; +} + +void +w_lava_nailgun_draw(player pl) +{ + Weapons_SetModel("models/v_lnail.mdl"); + Weapons_ViewAnimation(pl, NAILGUN_IDLE); +} + +void +w_lava_nailgun_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_lava_nails <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + + pl.ammo_lava_nails--; + + /* Actual firing */ +#ifdef CLIENT +#else + #if 0 + { + static void nail_touch(void) { + if (trace_ent.iBleeds) { + FX_Blood(trace_endpos, [1,0,0]); + } else { + FX_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal); + } + + if (trace_ent.takedamage) { + Damage_Apply(trace_ent, self.owner, Skill_GetValue("plr_nailgun", 9), WEAPON_NAILGUN, DMG_BLUNT); + } else { + makevectors(self.angles); + DecalGroups_Place("Impact.BigShot", trace_endpos + (v_forward * -2)); + } + + remove(self); + } + + entity nail = spawn(); + setmodel(nail, "models/lspike.mdl"); + vector velOffset = pl.velocity * input_timelength; + setsize(nail, g_vec_null, g_vec_null); + nail.movetype = MOVETYPE_FLYMISSILE; + nail.solid = SOLID_BBOX; + nail.touch = nail_touch; + nail.owner = pl; + Weapons_MakeVectors(pl); + + if (pl.ammo_lava_nails & 1) { + setorigin(nail, velOffset + Weapons_GetCameraPos(pl) + (v_right * -2) + (v_up * -5)); + nail.velocity = v_forward * 1000 + (v_right * -2) + (v_up * -5); + } else { + setorigin(nail, velOffset + Weapons_GetCameraPos(pl) + (v_right * 2) + (v_up * -5)); + nail.velocity = v_forward * 1000 + (v_right * 2) + (v_up * -5); + } + nail.angles = vectoangles(nail.velocity); + } + #else + vector startPos; + Weapons_MakeVectors(pl); + + if (pl.ammo_lava_nails & 1) + startPos = Weapons_GetCameraPos(pl) + (v_right * -2) + (v_up * -5); + else + startPos = Weapons_GetCameraPos(pl) + (v_right * 2) + (v_up * -5); + + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_lnail"); + self = oldself; + rocket.Launch(startPos, pl.v_angle, 0.0f, 0.0f, 0.0f); + #endif + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + + Sound_Play(pl, CHAN_WEAPON, "weapon_nailgun.shoot"); +#endif + + Weapons_ViewPunchAngle(pl, [-2,0,0]); + Weapons_ViewAnimation(pl, NAILGUN_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTMP5 : ANIM_SHOOTMP5, 0.45f); + + pl.w_attack_next = 0.1f; +} + +void +w_lava_nailgun_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + g_hudngammo, + [0, 0], + [24/24, 24/24], + g_hud_color, + pSeatLocal->m_flAmmo2Alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_lava_nailgun_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMMP5 : ANIM_AIMMP5; +} + +int +w_lava_nailgun_isempty(player pl) +{ + if (pl.ammo_lava_nails <= 0) + return 1; + + return 0; +} + +void +w_lava_nailgun_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_lava_nailgun_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudng_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudng_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_lava_nails, MAX_A_NAILS, a); +#endif +} + +weapontype_t +w_lava_nailgun_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t w_lava_nailgun = +{ + .name = "lava_nailgun", + .id = ITEM_LAVANAIL, + .slot = 3, + .slot_pos = 1, + .weight = 6, + .draw = w_lava_nailgun_draw, + .holster = __NULL__, + .primary = w_lava_nailgun_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_lava_nailgun_crosshair, + .precache = w_lava_nailgun_precache, + .pickup = w_lava_nailgun_pickup, + .updateammo = w_lava_nailgun_updateammo, + .wmodel = w_lava_nailgun_wmodel, + .pmodel = w_lava_nailgun_pmodel, + .deathmsg = w_lava_nailgun_deathmsg, + .aimanim = w_lava_nailgun_aimanim, + .isempty = w_lava_nailgun_isempty, + .type = w_lava_nailgun_type, + .hudpic = w_lava_nailgun_hudpic +}; diff --git a/src/shared/w_lava_supernailgun.qc b/src/shared/w_lava_supernailgun.qc new file mode 100644 index 0000000..aad530e --- /dev/null +++ b/src/shared/w_lava_supernailgun.qc @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_supernailgun (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_nail2.mdl" + +HALF-LIFE (1998) ENTITY + +MP5/9mmAR Weapon +Same as weapon_9mmAR + +*/ + +/* Animations */ +enum +{ + SUPERNAIL_IDLE, + SUPERNAIL_SHOOT +}; + +void +w_lava_supernailgun_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_supernailgun.shoot"); + precache_model("models/g_lnail2.mdl"); + precache_model("models/lspike.mdl"); +#else + precache_model("models/v_lnail2.mdl"); + precache_model("models/p_lnail2.mdl"); + Sound_Precache("modelevent_shell.land"); +#endif +} + +int +w_lava_supernailgun_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_lava_nails < MAX_A_NAILS) { + pl.ammo_lava_nails = bound(0, pl.ammo_lava_nails + 30, MAX_A_NAILS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_lava_supernailgun_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_lava_nails, -1); +} + +string +w_lava_supernailgun_wmodel(void) +{ + return "models/g_lnail2.mdl"; +} + +string +w_lava_supernailgun_pmodel(player pl) +{ + return "models/p_lnail2.mdl"; +} + +string +w_lava_supernailgun_deathmsg(void) +{ + return ""; +} + +void +w_lava_supernailgun_draw(player pl) +{ + Weapons_SetModel("models/v_lnail2.mdl"); + Weapons_ViewAnimation(pl, SUPERNAIL_IDLE); +} + +void +w_lava_supernailgun_primary(player pl) +{ + if (pl.w_attack_next > 0.0f) + return; + + if (pl.ammo_lava_nails < 1) { + Weapons_SwitchBest(pl, 0); + return; + } + + pl.ammo_lava_nails--; + Weapons_ViewAnimation(pl, SUPERNAIL_SHOOT); + Weapons_ViewPunchAngle(pl, [-2,0,0]); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTMP5 : ANIM_SHOOTMP5, 0.1f); + +#ifdef CLIENT +#else + #if 0 + { + static void nail_touch(void) { + if (trace_ent.iBleeds) { + FX_Blood(trace_endpos, [1,0,0]); + } else { + FX_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal); + } + + if (trace_ent.takedamage) { + Damage_Apply(trace_ent, self.owner, Skill_GetValue("plr_supernailgun", 18), WEAPON_SUPERNAILGUN, DMG_BLUNT); + } else { + makevectors(self.angles); + DecalGroups_Place("Impact.BigShot", trace_endpos + (v_forward * -2)); + } + + remove(self); + } + + entity nail = spawn(); + setmodel(nail, "models/lspike.mdl"); + vector velOffset = pl.velocity * input_timelength; + setorigin(nail, velOffset + Weapons_GetCameraPos(pl) + (v_up * -5)); + setsize(nail, g_vec_null, g_vec_null); + nail.movetype = MOVETYPE_FLYMISSILE; + nail.solid = SOLID_BBOX; + nail.touch = nail_touch; + nail.owner = pl; + Weapons_MakeVectors(pl); + nail.velocity = v_forward * 1000 + (v_up * -5); + nail.angles = vectoangles(nail.velocity); + } + #else + vector startPos; + Weapons_MakeVectors(pl); + + startPos = Weapons_GetCameraPos(pl) + (v_up * -5); + + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_lsupernail"); + self = oldself; + rocket.Launch(startPos, pl.v_angle, 0.0f, 0.0f, 0.0f); + #endif + + 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; + pl.w_idle_next = 10.0f; +} + +void +w_lava_supernailgun_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + drawsubpic(aicon_pos, [24,24], g_hudsngammo, [0, 0], [1,1], g_hud_color, pSeatLocal->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE); +#endif +} + +float +w_lava_supernailgun_aimanim(player pl) +{ + return pl.flags & ANIM_CR_AIMMP5 ? ANIM_CR_AIMCROWBAR : ANIM_AIMMP5; +} + +int +w_lava_supernailgun_isempty(player pl) +{ + if (pl.ammo_lava_nails <= 0) + return 1; + + return 0; +} + +void +w_lava_supernailgun_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_lava_supernailgun_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudsng_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudsng_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_lava_nails, MAX_A_NAILS, a); +#endif +} + +weapontype_t +w_lava_supernailgun_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t w_lava_supernailgun = +{ + .name = "lava_supernail", + .id = ITEM_LAVASUPERNAILGUN, + .slot = 4, + .slot_pos = 1, + .weight = 3, + .draw = w_lava_supernailgun_draw, + .holster = __NULL__, + .primary = w_lava_supernailgun_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_lava_supernailgun_crosshair, + .precache = w_lava_supernailgun_precache, + .pickup = w_lava_supernailgun_pickup, + .updateammo = w_lava_supernailgun_updateammo, + .wmodel = w_lava_supernailgun_wmodel, + .pmodel = w_lava_supernailgun_pmodel, + .deathmsg = w_lava_supernailgun_deathmsg, + .aimanim = w_lava_supernailgun_aimanim, + .isempty = w_lava_supernailgun_isempty, + .type = w_lava_supernailgun_type, + .hudpic = w_lava_supernailgun_hudpic +}; \ No newline at end of file diff --git a/src/shared/w_lightning.qc b/src/shared/w_lightning.qc index eb6f89d..b289eba 100644 --- a/src/shared/w_lightning.qc +++ b/src/shared/w_lightning.qc @@ -198,6 +198,7 @@ w_lightning_primary(player pl) return; } +#if 1 pl.ammo_cells--; #ifdef SERVER @@ -247,7 +248,6 @@ w_lightning_primary(player pl) } } #endif - Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); @@ -255,6 +255,23 @@ w_lightning_primary(player pl) pl.w_attack_next = 0.1f; pl.gflags |= GF_EGONBEAM; + +#else +#ifdef SERVER + static float foo = 0; + Weapons_MakeVectors(pl); + NSPortal_Spawn(pl.origin, v_forward, pl, foo); + foo = 1 - foo; +#endif + + Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + Weapons_ViewPunchAngle(pl, [-2,0,0]); + + pl.w_attack_next = 1.0f; + pl.gflags |= GF_EGONBEAM; +#endif } void diff --git a/src/shared/w_multi_gren.qc b/src/shared/w_multi_gren.qc new file mode 100644 index 0000000..81129b6 --- /dev/null +++ b/src/shared/w_multi_gren.qc @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_hornetgun (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_rock.mdl" + +HALF-LIFE (1998) ENTITY + +Hornetgun Weapon + +*/ + +enum +{ + GRENLAUNCHER_IDLE, + GRENLAUNCHER_SHOOT, +}; + +void +w_multi_gren_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_grenadelauncher.shoot"); + Sound_Precache("weapon_grenadelauncher.bounce"); + Sound_Precache("weapon_grenadelauncher.explode"); + precache_model("models/g_mrock.mdl"); + precache_model("models/mgrenade.mdl"); +#else + precache_model("models/v_mrock.mdl"); + precache_model("models/p_mrock.mdl"); +#endif +} + +int +w_multi_gren_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_rockets < MAX_A_ROCKETS) { + pl.ammo_rockets = bound(0, pl.ammo_rockets + 5, MAX_A_ROCKETS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_multi_gren_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_rockets, -1); +} + +string +w_multi_gren_wmodel(void) +{ + return "models/g_mrock.mdl"; +} + +string +w_multi_gren_pmodel(player pl) +{ + return "models/p_mrock.mdl"; +} + +string +w_multi_gren_deathmsg(void) +{ + return ""; +} + +void +w_multi_gren_draw(player pl) +{ + Weapons_SetModel("models/v_mrock.mdl"); + Weapons_ViewAnimation(pl, GRENLAUNCHER_IDLE); +} + +#ifdef SERVER +void +w_multi_gren_shootnade(player pl) +{ +#if 0 + static void Grenade_Explode(void) { + float dmg = Skill_GetValue("plr_grenadelauncher", 120); + FX_Explosion(self.origin); + Damage_Radius(self.origin, self.owner, dmg, dmg + 40, TRUE, WEAPON_GRENADELAUNCHER); + sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); + remove(self); + } + static void Grenade_Bounce(void) { + /* if what we are touching can be damaged, explode */ + if (other.takedamage) { + Grenade_Explode(); + return; + } + + Sound_Play(self, CHAN_VOICE, "weapon_grenadelauncher.bounce"); + } + + Weapons_MakeVectors(pl); + + /* spawn the 'pineapple' */ + entity grenade = spawn(); + setmodel(grenade, "models/grenade.mdl"); + setorigin(grenade, pl.origin); + grenade.owner = pl; + + if (pl.v_angle[0]) { + grenade.velocity = v_forward * 600; + grenade.velocity += v_up * 200; + grenade.velocity += ((random() - 0.5) * v_right) * 10; + grenade.velocity += ((random() - 0.5) * v_up) * 10; + } else { + grenade.velocity = v_forward * 600; + grenade.velocity[2] = 200; + } + + grenade.avelocity = [300, 300, 300]; + grenade.movetype = MOVETYPE_BOUNCE; + grenade.solid = SOLID_BBOX; + //grenade.flags |= FL_LAGGEDMOVE; + grenade.angles = vectoangles(grenade.velocity); + grenade.touch = Grenade_Bounce; + grenade.think = Grenade_Explode; + grenade.nextthink = time + 2.5f; + grenade.traileffectnum = particleeffectnum("weapon_rpg.trail"); + setsize(grenade, [0,0,0], [0,0,0]); + +#else + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_multinade"); + self = oldself; + rocket.Launch(pl.origin, pl.v_angle, 0.0f, 0.0f, 0.0f); +#endif + + Sound_Play(pl, CHAN_WEAPON, "weapon_grenadelauncher.shoot"); +} +#endif + +void +w_multi_gren_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_rockets <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + + /* fire the actual projectile (on the server) */ +#ifdef SERVER + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + + w_multi_gren_shootnade(pl); +#endif + + /* remove ammo and play the animation on view + player model */ + pl.ammo_rockets--; + Weapons_ViewAnimation(pl, GRENLAUNCHER_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + +#ifdef CLIENT + if (FreeDMC_CanExtra()) + View_AddEvent(w_grenadelauncher_ejectbrass, 0.325f); +#endif + + pl.w_attack_next = 0.6; +} + +void +w_multi_gren_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + drawsubpic( + aicon_pos, + [24,24], + g_hudglammo, + [0, 0], + [24/24, 24/24], + g_hud_color, + pSeatLocal->m_flAmmo2Alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_multi_gren_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMGAUSS : ANIM_AIMGAUSS; +} + +int +w_multi_gren_isempty(player pl) +{ + return (pl.ammo_rockets == 0) ? true : false; +} + +void +w_multi_gren_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_multi_gren_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudgl_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudgl_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_rockets, MAX_A_ROCKETS, a); +#endif +} + +weapontype_t +w_multi_gren_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t +w_multi_gren = +{ + .name = "grenadel", + .id = ITEM_MULTIGREN, + .slot = 5, + .slot_pos = 1, + .weight = 4, + .draw = w_multi_gren_draw, + .holster = __NULL__, + .primary = w_multi_gren_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_multi_gren_crosshair, + .precache = w_multi_gren_precache, + .pickup = w_multi_gren_pickup, + .updateammo = w_multi_gren_updateammo, + .wmodel = w_multi_gren_wmodel, + .pmodel = w_multi_gren_pmodel, + .deathmsg = w_multi_gren_deathmsg, + .aimanim = w_multi_gren_aimanim, + .isempty = w_multi_gren_isempty, + .type = w_multi_gren_type, + .hudpic = w_multi_gren_hudpic +}; diff --git a/src/shared/w_multi_rocket.qc b/src/shared/w_multi_rocket.qc new file mode 100644 index 0000000..e8d9867 --- /dev/null +++ b/src/shared/w_multi_rocket.qc @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_rocketlauncher (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_rock2.mdl" + +HALF-LIFE (1998) ENTITY + +RPG Weapon + +*/ + +enum +{ + RPG_IDLE, + RPG_SHOOT +}; + +void +w_multi_rocket_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_rocketlauncher.shoot"); + Sound_Precache("weapon_rocketlauncher.explode"); + precache_model("models/g_mrock2.mdl"); + precache_model("models/mrocket.mdl"); +#else + precache_model("models/v_mrock2.mdl"); + precache_model("models/p_mrock2.mdl"); +#endif +} + +void +w_multi_rocket_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_rockets, -1); +} + +string +w_multi_rocket_wmodel(void) +{ + return "models/g_mrock2.mdl"; +} + +string +w_multi_rocket_pmodel(player pl) +{ + return "models/p_mrock2.mdl"; +} + +string +w_multi_rocket_deathmsg(void) +{ + return ""; +} + +int +w_multi_rocket_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_rockets < MAX_A_ROCKETS) { + pl.ammo_rockets = bound(0, pl.ammo_rockets + 5, MAX_A_ROCKETS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_multi_rocket_draw(player pl) +{ + Weapons_SetModel("models/v_mrock2.mdl"); + Weapons_ViewAnimation(pl, RPG_IDLE); +} + +void +w_multi_rocket_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_rockets <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + + /* visual fluff */ + Weapons_ViewAnimation(pl, RPG_SHOOT); + Weapons_ViewPunchAngle(pl, [-10,0,0]); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + pl.w_attack_next = 0.8f; + pl.ammo_rockets--; + +#ifdef SERVER + vector startPos; + Weapons_MakeVectors(pl); + startPos = Weapons_GetCameraPos(pl) + (v_forward * 16) + (v_up * -5); + + + NSProjectile_SpawnDefAtPosition("projectile_mrocket", pl, startPos, pl.v_angle + [0, -10, 0] * 0.66); + NSProjectile_SpawnDefAtPosition("projectile_mrocket", pl, startPos, pl.v_angle + [0, -5, 0] * 0.66); + NSProjectile_SpawnDefAtPosition("projectile_mrocket", pl, startPos, pl.v_angle + [0, 5, 0] * 0.66); + NSProjectile_SpawnDefAtPosition("projectile_mrocket", pl, startPos, pl.v_angle + [0, 10, 0] * 0.66); + + Sound_Play(pl, CHAN_WEAPON, "weapon_rocketlauncher.shoot"); + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } +#endif +} + +float +w_multi_rocket_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMGAUSS : ANIM_AIMGAUSS; +} + +int +w_multi_rocket_isempty(player pl) +{ + if (pl.ammo_rockets <= 0) + return 1; + + return 0; +} + +void +w_multi_rocket_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_multi_rocket_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudrl_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudrl_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_rockets, MAX_A_ROCKETS, a); +#endif +} + +void +w_multi_rocket_hud(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + /* ammo icon */ + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + g_hudrlammo, + [0, 0], + [24/24, 24/24], + g_hud_color, + pSeatLocal->m_flAmmo2Alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +weapontype_t +w_multi_rocket_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t +w_multi_rocket = +{ + .name = "rocketl", + .id = ITEM_MULTIROCKET, + .slot = 6, + .slot_pos = 1, + .weight = 2, + .draw = w_multi_rocket_draw, + .holster = __NULL__, + .primary = w_multi_rocket_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_multi_rocket_hud, + .precache = w_multi_rocket_precache, + .pickup = w_multi_rocket_pickup, + .updateammo = w_multi_rocket_updateammo, + .wmodel = w_multi_rocket_wmodel, + .pmodel = w_multi_rocket_pmodel, + .deathmsg = w_multi_rocket_deathmsg, + .aimanim = w_multi_rocket_aimanim, + .isempty = w_multi_rocket_isempty, + .type = w_multi_rocket_type, + .hudpic = w_multi_rocket_hudpic +}; \ No newline at end of file diff --git a/src/shared/w_nailgun.qc b/src/shared/w_nailgun.qc index a2fbaa1..af46e5a 100644 --- a/src/shared/w_nailgun.qc +++ b/src/shared/w_nailgun.qc @@ -101,6 +101,7 @@ w_nailgun_primary(player pl) /* Actual firing */ #ifdef CLIENT #else + #if 0 { static void nail_touch(void) { if (trace_ent.iBleeds) { @@ -138,6 +139,23 @@ w_nailgun_primary(player pl) } nail.angles = vectoangles(nail.velocity); } + #else + vector startPos; + Weapons_MakeVectors(pl); + + if (pl.ammo_nails & 1) + startPos = Weapons_GetCameraPos(pl) + (v_right * -2) + (v_up * -5); + else + startPos = Weapons_GetCameraPos(pl) + (v_right * 2) + (v_up * -5); + + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_nail"); + self = oldself; + rocket.Launch(startPos, pl.v_angle, 0.0f, 0.0f, 0.0f); + #endif if (pl.HasQuadDamage()) { Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); diff --git a/src/shared/w_plasma_cannon.qc b/src/shared/w_plasma_cannon.qc new file mode 100644 index 0000000..0f84b82 --- /dev/null +++ b/src/shared/w_plasma_cannon.qc @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_crossbow (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_light.mdl" + +HALF-LIFE (1998) ENTITY + +Crossbow Weapon + +*/ + +#ifdef CLIENT +#define LIGHTNINGBEAM_COUNT 16 +string g_lightning_beamtex; + +static float lightning_jitlut[BEAM_COUNT] = { + 0.000000, + 0.195090, + 0.382683, + 0.555570, + 0.707106, + 0.831469, + 0.923879, + 0.980785, + 1.000000, + 0.980786, + 0.923880, + 0.831471, + 0.707108, + 0.555572, + 0.382685, + 0.000000, +}; + +void +w_plasma_cannon_renderbeam(string spriteFrame, vector startOrg, vector endOrg, float beamWidth, float beamAmp, vector colorTint, float timeScale, float seedValue) +{ +#if 1 + vector vecPlayer; + NSClientPlayer pl; + + #define RANDOMNUM seedValue + + int s = (float)getproperty(VF_ACTIVESEAT); + pSeat = &g_seats[s]; + pl = (NSClientPlayer)pSeat->m_ePlayer; + vecPlayer = pl.GetEyePos(); + + if (spriteFrame) { + float last_progression = 0.0f; + makevectors(g_view.GetCameraAngle()); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon(spriteFrame, DRAWFLAG_ADDITIVE, 0); + + for (float i = 0; i < LIGHTNINGBEAM_COUNT; i++) { + float progression = (i / (LIGHTNINGBEAM_COUNT-1)); + vector point; + vector jitter; + float a = 1.0f; + + /* our steps from a - b */ + point[0] = Math_Lerp(startOrg[0], endOrg[0], progression); + point[1] = Math_Lerp(startOrg[1], endOrg[1], progression); + point[2] = Math_Lerp(startOrg[2], endOrg[2], progression); + + /* get the direction the beam is 'looking' */ + makevectors(vectoangles(endOrg - startOrg)); + + /* nudge it a lil bit up/down left/right from its trajectory */ + /* these are all randomly chosen constants */ + jitter = v_right * (pseudorand((timeScale * time) + i + RANDOMNUM) - 0.5); + jitter += v_up * (pseudorand((timeScale * time) + i + 64.12 + RANDOMNUM) - 0.5); + jitter += v_right * (pseudorand(100 + ((timeScale*2) * time) + i + RANDOMNUM) - 0.5); + jitter += v_up * (pseudorand(100 + ((timeScale*2) * time) + i + 25.4 + RANDOMNUM) - 0.5); + jitter *= beamAmp; + + /* start/end points get less jittery the closer we get*/ + jitter *= lightning_jitlut[i]; + + /* apply jitter */ + point += jitter; + + R_PolygonVertex(point, [1, 0], colorTint, a); + + if (autocvar(cl_showoff, 0)) + dynamiclight_add(point, 150, [0.25, 0.25, 1.0]); + + + last_progression = progression; + } + + R_EndPolygonRibbon(beamWidth, [-1,0]); + } +#else + vector vecPlayer; + NSClientPlayer pl; + int s = (float)getproperty(VF_ACTIVESEAT); + pSeat = &g_seats[s]; + pl = (NSClientPlayer)pSeat->m_ePlayer; + vecPlayer = pl.GetEyePos(); + makevectors(g_view.GetCameraAngle()); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon(spriteFrame, DRAWFLAG_ADDITIVE, 0); + R_PolygonVertex(startOrg, [1, 0], colorTint, 1.0); + R_PolygonVertex(endOrg, [1, 0], colorTint, 1.0); + R_EndPolygonRibbon(4, [-1,0]); +#endif +} +#endif + +enum +{ + LIGHTNING_IDLE, + LIGHTNING_SHOOT, +}; + +void +w_plasma_cannon_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_lightning.start"); + Sound_Precache("weapon_lightning.shaft"); + precache_model("models/g_plasma.mdl"); +#else + g_lightning_beamtex = spriteframe("sprites/lgtning.spr", 0, 0.0f); + precache_model("models/v_plasma.mdl"); + precache_model("models/p_plasma.mdl"); +#endif +} + +void +w_plasma_cannon_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_cells, -1); +} + +string +w_plasma_cannon_wmodel(void) +{ + return "models/g_plasma.mdl"; +} + +string +w_plasma_cannon_pmodel(player pl) +{ + return "models/p_plasma.mdl"; +} + +string +w_plasma_cannon_deathmsg(void) +{ + return ""; +} + +int +w_plasma_cannon_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_cells < MAX_A_CELLS) { + pl.ammo_cells = bound(0, pl.ammo_cells + 15, MAX_A_CELLS); + } else { + if (!new) + return (0); + } + +#endif + return (1); +} + +void +w_plasma_cannon_draw(player pl) +{ + Weapons_SetModel("models/v_plasma.mdl"); + Weapons_ViewAnimation(pl, LIGHTNING_IDLE); +} + +void +w_plasma_cannon_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_cells <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + +#if 1 + pl.ammo_cells--; + +#ifdef SERVER + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_plasmaball"); + self = oldself; + rocket.Launch(pl.origin, pl.v_angle, 0.0f, 0.0f, 0.0f); +#endif + Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + Weapons_ViewPunchAngle(pl, [-2,0,0]); + + pl.w_attack_next = 1.0f; + +#else +#ifdef SERVER + static float foo = 0; + Weapons_MakeVectors(pl); + NSPortal_Spawn(pl.origin, v_forward, pl, foo); + foo = 1 - foo; +#endif + + Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + Weapons_ViewPunchAngle(pl, [-2,0,0]); + + pl.w_attack_next = 1.0f; + pl.gflags |= GF_EGONBEAM; +#endif +} + +void +w_plasma_cannon_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + g_hudlgammo, + [0, 0], + [24/24, 24/24], + g_hud_color, + pSeatLocal->m_flAmmo2Alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_plasma_cannon_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMGAUSS : ANIM_AIMGAUSS; +} + +int +w_plasma_cannon_isempty(player pl) +{ + if (pl.ammo_cells <= 0) + return 1; + + return 0; +} + +void +w_plasma_cannon_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_plasma_cannon_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudlg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudlg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_cells, MAX_A_CELLS, a); +#endif +} + +weapontype_t +w_plasma_cannon_type(player pl) +{ + return WPNTYPE_RANGED; +} + +void +w_plasma_cannon_postdraw(player pl, int thirdperson) +{ +#ifdef CLIENT + if (!(pl.gflags & GF_EGONBEAM)) + return; + + vector src; + vector endpos; + + if (thirdperson) { + makevectors(pl.v_angle); + src = pl.origin; + endpos = pl.origin + (v_forward * 1024); + traceline(src, endpos, MOVE_NORMAL, pl); + //w_plasma_cannon_beamfx(gettaginfo(pl.p_model, 10), trace_endpos, pl); + w_plasma_cannon_renderbeam(g_lightning_beamtex, gettaginfo(pl.p_model, 10), trace_endpos, trace_fraction * 32, trace_fraction * 48.0, [1,1,1], 60.0f, 12516); + } else { + vector gunpos = gettaginfo(pSeat->m_eViewModel, 33); + src = pl.GetEyePos(); + makevectors(view_angles); + gunpos += (v_up * -16) + (v_forward * 42); + endpos = src + v_forward * 1024; + traceline(src, endpos, FALSE, pl); + endpos = trace_endpos; + //w_plasma_cannon_beamfx(gunpos, endpos, pl); + w_plasma_cannon_renderbeam(g_lightning_beamtex, gunpos, endpos, trace_fraction * 32, trace_fraction * 48.0, [1,1,1], 60.0f, 125156); + } + + int i = (cltime*10.0f) % 11.0f; + vector fsize = [32,32]; + makevectors(view_angles); + trace_endpos += v_forward * -16; /* nudge towards our camera */ + dynamiclight_add(trace_endpos, 128, [0.5, 0.5, 1.0]); +#endif +} + +void +w_plasma_cannon_release(player pl) +{ + pl.gflags &= ~GF_EGONBEAM; +} + +weapon_t w_plasma_cannon = +{ + .name = "lightning", + .id = ITEM_PLASMACAN, + .slot = 7, + .slot_pos = 1, + .weight = 1, + .draw = w_plasma_cannon_draw, + .holster = __NULL__, + .primary = w_plasma_cannon_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_plasma_cannon_release, + .postdraw = w_plasma_cannon_crosshair, + .precache = w_plasma_cannon_precache, + .pickup = w_plasma_cannon_pickup, + .updateammo = w_plasma_cannon_updateammo, + .wmodel = w_plasma_cannon_wmodel, + .pmodel = w_plasma_cannon_pmodel, + .deathmsg = w_plasma_cannon_deathmsg, + .aimanim = w_plasma_cannon_aimanim, + .isempty = w_plasma_cannon_isempty, + .type = w_plasma_cannon_type, + .hudpic = w_plasma_cannon_hudpic, + .predraw = w_plasma_cannon_postdraw +}; diff --git a/src/shared/w_plasma_rifle.qc b/src/shared/w_plasma_rifle.qc new file mode 100644 index 0000000..7b1e007 --- /dev/null +++ b/src/shared/w_plasma_rifle.qc @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_crossbow (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_light.mdl" + +HALF-LIFE (1998) ENTITY + +Crossbow Weapon + +*/ + +#ifdef CLIENT +#define LIGHTNINGBEAM_COUNT 16 +string g_lightning_beamtex; + +static float lightning_jitlut[BEAM_COUNT] = { + 0.000000, + 0.195090, + 0.382683, + 0.555570, + 0.707106, + 0.831469, + 0.923879, + 0.980785, + 1.000000, + 0.980786, + 0.923880, + 0.831471, + 0.707108, + 0.555572, + 0.382685, + 0.000000, +}; + +void +w_plasma_rifle_renderbeam(string spriteFrame, vector startOrg, vector endOrg, float beamWidth, float beamAmp, vector colorTint, float timeScale, float seedValue) +{ +#if 1 + vector vecPlayer; + NSClientPlayer pl; + + #define RANDOMNUM seedValue + + int s = (float)getproperty(VF_ACTIVESEAT); + pSeat = &g_seats[s]; + pl = (NSClientPlayer)pSeat->m_ePlayer; + vecPlayer = pl.GetEyePos(); + + if (spriteFrame) { + float last_progression = 0.0f; + makevectors(g_view.GetCameraAngle()); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon(spriteFrame, DRAWFLAG_ADDITIVE, 0); + + for (float i = 0; i < LIGHTNINGBEAM_COUNT; i++) { + float progression = (i / (LIGHTNINGBEAM_COUNT-1)); + vector point; + vector jitter; + float a = 1.0f; + + /* our steps from a - b */ + point[0] = Math_Lerp(startOrg[0], endOrg[0], progression); + point[1] = Math_Lerp(startOrg[1], endOrg[1], progression); + point[2] = Math_Lerp(startOrg[2], endOrg[2], progression); + + /* get the direction the beam is 'looking' */ + makevectors(vectoangles(endOrg - startOrg)); + + /* nudge it a lil bit up/down left/right from its trajectory */ + /* these are all randomly chosen constants */ + jitter = v_right * (pseudorand((timeScale * time) + i + RANDOMNUM) - 0.5); + jitter += v_up * (pseudorand((timeScale * time) + i + 64.12 + RANDOMNUM) - 0.5); + jitter += v_right * (pseudorand(100 + ((timeScale*2) * time) + i + RANDOMNUM) - 0.5); + jitter += v_up * (pseudorand(100 + ((timeScale*2) * time) + i + 25.4 + RANDOMNUM) - 0.5); + jitter *= beamAmp; + + /* start/end points get less jittery the closer we get*/ + jitter *= lightning_jitlut[i]; + + /* apply jitter */ + point += jitter; + + R_PolygonVertex(point, [1, 0], colorTint, a); + + if (autocvar(cl_showoff, 0)) + dynamiclight_add(point, 150, [0.25, 0.25, 1.0]); + + + last_progression = progression; + } + + R_EndPolygonRibbon(beamWidth, [-1,0]); + } +#else + vector vecPlayer; + NSClientPlayer pl; + int s = (float)getproperty(VF_ACTIVESEAT); + pSeat = &g_seats[s]; + pl = (NSClientPlayer)pSeat->m_ePlayer; + vecPlayer = pl.GetEyePos(); + makevectors(g_view.GetCameraAngle()); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon(spriteFrame, DRAWFLAG_ADDITIVE, 0); + R_PolygonVertex(startOrg, [1, 0], colorTint, 1.0); + R_PolygonVertex(endOrg, [1, 0], colorTint, 1.0); + R_EndPolygonRibbon(4, [-1,0]); +#endif +} +#endif + +enum +{ + LIGHTNING_IDLE, + LIGHTNING_SHOOT, +}; + +void +w_plasma_rifle_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_lightning.start"); + Sound_Precache("weapon_lightning.shaft"); + precache_model("models/g_light.mdl"); +#else + g_lightning_beamtex = spriteframe("sprites/lgtning.spr", 0, 0.0f); + precache_model("models/v_light.mdl"); + precache_model("models/p_light.mdl"); +#endif +} + +void +w_plasma_rifle_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_cells, -1); +} + +string +w_plasma_rifle_wmodel(void) +{ + return "models/g_light.mdl"; +} + +string +w_plasma_rifle_pmodel(player pl) +{ + return "models/p_light.mdl"; +} + +string +w_plasma_rifle_deathmsg(void) +{ + return ""; +} + +int +w_plasma_rifle_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_cells < MAX_A_CELLS) { + pl.ammo_cells = bound(0, pl.ammo_cells + 15, MAX_A_CELLS); + } else { + if (!new) + return (0); + } + +#endif + return (1); +} + +void +w_plasma_rifle_draw(player pl) +{ + Weapons_SetModel("models/v_light.mdl"); + Weapons_ViewAnimation(pl, LIGHTNING_IDLE); +} + +void +w_plasma_rifle_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_cells <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + +#if 1 + pl.ammo_cells--; + +#ifdef SERVER + { + if (pl.WaterLevel() > 1) { + // we're underwater... fry everyone (around us) */ + float lightDmg = (float)pl.ammo_cells * 35.0f; + Damage_Radius(self.origin, self, lightDmg, lightDmg + 40, TRUE, WEAPON_LIGHTNING); + } else { + vector startPos = Weapons_GetCameraPos(pl); + Weapons_MakeVectors(pl); + traceline(startPos, startPos + v_forward * 600, MOVE_NORMAL, pl); + + WriteByte(MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte(MSG_MULTICAST, TE_LIGHTNING2); + WriteEntity(MSG_MULTICAST, pl); + WriteCoord(MSG_MULTICAST, startPos[0]); + WriteCoord(MSG_MULTICAST, startPos[1]); + WriteCoord(MSG_MULTICAST, startPos[2]); + WriteCoord(MSG_MULTICAST, trace_endpos[0]); + WriteCoord(MSG_MULTICAST, trace_endpos[1]); + WriteCoord(MSG_MULTICAST, trace_endpos[2]); + multicast(startPos, MULTICAST_PHS); + + if (trace_ent.takedamage) { + Damage_Apply(trace_ent, pl, Skill_GetValue("plr_lightning", 30), WEAPON_LIGHTNING, DMG_BLUNT); + + /* throw players into the air */ + if (trace_ent.classname == "player") { + NSClientPlayer tp = (NSClientPlayer)trace_ent; + tp.SetVelocity(tp.GetVelocity() + [0, 0, 400]); + } + } + } + } + + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + + if (!(pl.gflags & GF_EGONBEAM)) + Sound_Play(pl, CHAN_WEAPON, "weapon_lightning.start"); + else { + if (pl.m_lightningTime < time) { + Sound_Play(pl, CHAN_WEAPON, "weapon_lightning.shaft"); + pl.m_lightningTime = time + 0.6f; + } + } +#endif + Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + Weapons_ViewPunchAngle(pl, [-2,0,0]); + + pl.w_attack_next = 0.1f; + pl.gflags |= GF_EGONBEAM; + +#else +#ifdef SERVER + static float foo = 0; + Weapons_MakeVectors(pl); + NSPortal_Spawn(pl.origin, v_forward, pl, foo); + foo = 1 - foo; +#endif + + Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + Weapons_ViewPunchAngle(pl, [-2,0,0]); + + pl.w_attack_next = 1.0f; + pl.gflags |= GF_EGONBEAM; +#endif +} + +void +w_plasma_rifle_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + g_hudlgammo, + [0, 0], + [24/24, 24/24], + g_hud_color, + pSeatLocal->m_flAmmo2Alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_plasma_rifle_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMGAUSS : ANIM_AIMGAUSS; +} + +int +w_plasma_rifle_isempty(player pl) +{ + if (pl.ammo_cells <= 0) + return 1; + + return 0; +} + +void +w_plasma_rifle_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_plasma_rifle_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudlg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudlg_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_cells, MAX_A_CELLS, a); +#endif +} + +weapontype_t +w_plasma_rifle_type(player pl) +{ + return WPNTYPE_RANGED; +} + +void +w_plasma_rifle_postdraw(player pl, int thirdperson) +{ +#ifdef CLIENT + if (!(pl.gflags & GF_EGONBEAM)) + return; + + vector src; + vector endpos; + + if (thirdperson) { + makevectors(pl.v_angle); + src = pl.origin; + endpos = pl.origin + (v_forward * 1024); + traceline(src, endpos, MOVE_NORMAL, pl); + //w_plasma_rifle_beamfx(gettaginfo(pl.p_model, 10), trace_endpos, pl); + w_plasma_rifle_renderbeam(g_lightning_beamtex, gettaginfo(pl.p_model, 10), trace_endpos, trace_fraction * 32, trace_fraction * 48.0, [1,1,1], 60.0f, 12516); + } else { + vector gunpos = gettaginfo(pSeat->m_eViewModel, 33); + src = pl.GetEyePos(); + makevectors(view_angles); + gunpos += (v_up * -16) + (v_forward * 42); + endpos = src + v_forward * 1024; + traceline(src, endpos, FALSE, pl); + endpos = trace_endpos; + //w_plasma_rifle_beamfx(gunpos, endpos, pl); + w_plasma_rifle_renderbeam(g_lightning_beamtex, gunpos, endpos, trace_fraction * 32, trace_fraction * 48.0, [1,1,1], 60.0f, 125156); + } + + int i = (cltime*10.0f) % 11.0f; + vector fsize = [32,32]; + makevectors(view_angles); + trace_endpos += v_forward * -16; /* nudge towards our camera */ + dynamiclight_add(trace_endpos, 128, [0.5, 0.5, 1.0]); +#endif +} + +void +w_plasma_rifle_release(player pl) +{ + pl.gflags &= ~GF_EGONBEAM; +} + +weapon_t w_plasma_rifle = +{ + .name = "lightning", + .id = ITEM_PLASMARIF, + .slot = 7, + .slot_pos = 2, + .weight = 1, + .draw = w_plasma_rifle_draw, + .holster = __NULL__, + .primary = w_plasma_rifle_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_plasma_rifle_release, + .postdraw = w_plasma_rifle_crosshair, + .precache = w_plasma_rifle_precache, + .pickup = w_plasma_rifle_pickup, + .updateammo = w_plasma_rifle_updateammo, + .wmodel = w_plasma_rifle_wmodel, + .pmodel = w_plasma_rifle_pmodel, + .deathmsg = w_plasma_rifle_deathmsg, + .aimanim = w_plasma_rifle_aimanim, + .isempty = w_plasma_rifle_isempty, + .type = w_plasma_rifle_type, + .hudpic = w_plasma_rifle_hudpic, + .predraw = w_plasma_rifle_postdraw +}; diff --git a/src/shared/w_proxmine.qc b/src/shared/w_proxmine.qc new file mode 100644 index 0000000..c8a9a81 --- /dev/null +++ b/src/shared/w_proxmine.qc @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2023 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. + */ + +/*QUAKED weapon_hornetgun (0 0 1) (-16 -16 0) (16 16 32) +"model" "models/g_rock.mdl" + +HALF-LIFE (1998) ENTITY + +Hornetgun Weapon + +*/ + +enum +{ + GRENLAUNCHER_IDLE, + GRENLAUNCHER_SHOOT, +}; + +void +w_proxmine_precache(void) +{ +#ifdef SERVER + Sound_Precache("weapon_grenadelauncher.shoot"); + Sound_Precache("weapon_grenadelauncher.bounce"); + Sound_Precache("weapon_grenadelauncher.explode"); + precache_model("models/g_prox.mdl"); + precache_model("models/grenade.mdl"); +#else + precache_model("models/v_prox.mdl"); + precache_model("models/p_prox.mdl"); +#endif +} + +int +w_proxmine_pickup(player pl, int new, int startammo) +{ +#ifdef SERVER + if (pl.ammo_rockets < MAX_A_ROCKETS) { + pl.ammo_rockets = bound(0, pl.ammo_rockets + 5, MAX_A_ROCKETS); + } else { + if (!new) + return (0); + } +#endif + return (1); +} + +void +w_proxmine_updateammo(player pl) +{ + Weapons_UpdateAmmo(pl, -1, pl.ammo_rockets, -1); +} + +string +w_proxmine_wmodel(void) +{ + return "models/g_prox.mdl"; +} + +string +w_proxmine_pmodel(player pl) +{ + return "models/p_prox.mdl"; +} + +string +w_proxmine_deathmsg(void) +{ + return ""; +} + +void +w_proxmine_draw(player pl) +{ + Weapons_SetModel("models/v_prox.mdl"); + Weapons_ViewAnimation(pl, GRENLAUNCHER_IDLE); +} + +#ifdef SERVER +void +w_proxmine_shootnade(player pl) +{ +#if 0 + static void Grenade_Explode(void) { + float dmg = Skill_GetValue("plr_grenadelauncher", 120); + FX_Explosion(self.origin); + Damage_Radius(self.origin, self.owner, dmg, dmg + 40, TRUE, WEAPON_GRENADELAUNCHER); + sound(self, CHAN_WEAPON, sprintf("weapons/explode%d.wav", floor(random() * 2) + 3), 1, ATTN_NORM); + remove(self); + } + static void Grenade_Bounce(void) { + /* if what we are touching can be damaged, explode */ + if (other.takedamage) { + Grenade_Explode(); + return; + } + + Sound_Play(self, CHAN_VOICE, "weapon_grenadelauncher.bounce"); + } + + Weapons_MakeVectors(pl); + + /* spawn the 'pineapple' */ + entity grenade = spawn(); + setmodel(grenade, "models/grenade.mdl"); + setorigin(grenade, pl.origin); + grenade.owner = pl; + + if (pl.v_angle[0]) { + grenade.velocity = v_forward * 600; + grenade.velocity += v_up * 200; + grenade.velocity += ((random() - 0.5) * v_right) * 10; + grenade.velocity += ((random() - 0.5) * v_up) * 10; + } else { + grenade.velocity = v_forward * 600; + grenade.velocity[2] = 200; + } + + grenade.avelocity = [300, 300, 300]; + grenade.movetype = MOVETYPE_BOUNCE; + grenade.solid = SOLID_BBOX; + //grenade.flags |= FL_LAGGEDMOVE; + grenade.angles = vectoangles(grenade.velocity); + grenade.touch = Grenade_Bounce; + grenade.think = Grenade_Explode; + grenade.nextthink = time + 2.5f; + grenade.traileffectnum = particleeffectnum("weapon_rpg.trail"); + setsize(grenade, [0,0,0], [0,0,0]); + +#else + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_proxgrenade"); + self = oldself; + rocket.Launch(pl.origin, pl.v_angle, 0.0f, 0.0f, 0.0f); +#endif + + Sound_Play(pl, CHAN_WEAPON, "weapon_grenadelauncher.shoot"); +} +#endif + +void +w_proxmine_primary(player pl) +{ + if (pl.w_attack_next > 0.0) + return; + if (pl.ammo_rockets <= 0) { + Weapons_SwitchBest(pl, 0); + return; + } + + /* fire the actual projectile (on the server) */ +#ifdef SERVER + if (pl.HasQuadDamage()) { + Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); + } + + w_proxmine_shootnade(pl); +#endif + + /* remove ammo and play the animation on view + player model */ + pl.ammo_rockets--; + Weapons_ViewAnimation(pl, GRENLAUNCHER_SHOOT); + Animation_PlayerTop(pl, (pl.flags & FL_CROUCHING) ? ANIM_CR_SHOOTGAUSS : ANIM_SHOOTGAUSS, 0.43f); + + pl.w_attack_next = 0.6; +} + +void +w_proxmine_crosshair(player pl) +{ +#ifdef CLIENT + vector aicon_pos; + aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42]; + + HUD_DrawQuakeCrosshair(); + HUD_DrawAmmo2(); + + drawsubpic( + aicon_pos, + [24,24], + g_hudglammo, + [0, 0], + [24/24, 24/24], + g_hud_color, + pSeatLocal->m_flAmmo2Alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_proxmine_aimanim(player pl) +{ + return pl.flags & FL_CROUCHING ? ANIM_CR_AIMGAUSS : ANIM_AIMGAUSS; +} + +int +w_proxmine_isempty(player pl) +{ + return (pl.ammo_rockets == 0) ? true : false; +} + +void +w_proxmine_hudpic(player pl, int selected, vector pos, float a) +{ +#ifdef CLIENT + vector hud_col; + + if (w_proxmine_isempty(pl)) + hud_col = [1,0,0]; + else + hud_col = g_hud_color; + + if (selected) { + drawsubpic(pos, [170,45], g_hudgl_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], g_hudgl_spr, [0,0], [1,0.625], hud_col, a, DRAWFLAG_ADDITIVE); + } + + HUD_DrawAmmoBar(pos, pl.ammo_rockets, MAX_A_ROCKETS, a); +#endif +} + +weapontype_t +w_proxmine_type(player pl) +{ + return WPNTYPE_RANGED; +} + +weapon_t +w_proxmine = +{ + .name = "grenadel", + .id = ITEM_PROXMINE, + .slot = 5, + .slot_pos = 2, + .weight = 4, + .draw = w_proxmine_draw, + .holster = __NULL__, + .primary = w_proxmine_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = __NULL__, + .postdraw = w_proxmine_crosshair, + .precache = w_proxmine_precache, + .pickup = w_proxmine_pickup, + .updateammo = w_proxmine_updateammo, + .wmodel = w_proxmine_wmodel, + .pmodel = w_proxmine_pmodel, + .deathmsg = w_proxmine_deathmsg, + .aimanim = w_proxmine_aimanim, + .isempty = w_proxmine_isempty, + .type = w_proxmine_type, + .hudpic = w_proxmine_hudpic +}; diff --git a/src/shared/w_rocketlauncher.qc b/src/shared/w_rocketlauncher.qc index 18175ac..ab1d11f 100644 --- a/src/shared/w_rocketlauncher.qc +++ b/src/shared/w_rocketlauncher.qc @@ -34,6 +34,7 @@ w_rocketlauncher_precache(void) { #ifdef SERVER Sound_Precache("weapon_rocketlauncher.shoot"); + Sound_Precache("weapon_rocketlauncher.explode"); precache_model("models/g_rock2.mdl"); precache_model("models/rocket.mdl"); #else @@ -106,6 +107,7 @@ w_rocketlauncher_primary(player pl) pl.ammo_rockets--; #ifdef SERVER +#if 0 static void Rocket_Touch(void) { float radiusDamage = Skill_GetValue("plr_rocketlauncher", 120); float baseDamage = Skill_GetValue("plr_rocketlauncher_impact", 100); @@ -138,6 +140,20 @@ w_rocketlauncher_primary(player pl) rocket.traileffectnum = particleeffectnum("weapon_rpg.trail"); setsize(rocket, [0,0,0], [0,0,0]); +#else + vector startPos; + Weapons_MakeVectors(pl); + startPos = Weapons_GetCameraPos(pl) + (v_forward * 16) + (v_up * -5); + + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_rocket"); + self = oldself; + rocket.Launch(startPos, pl.v_angle, 0.0f, 0.0f, 0.0f); +#endif + Sound_Play(pl, CHAN_WEAPON, "weapon_rocketlauncher.shoot"); if (pl.HasQuadDamage()) { diff --git a/src/shared/w_supernailgun.qc b/src/shared/w_supernailgun.qc index 32ba138..1f0b939 100644 --- a/src/shared/w_supernailgun.qc +++ b/src/shared/w_supernailgun.qc @@ -108,6 +108,7 @@ w_supernailgun_primary(player pl) #ifdef CLIENT #else + #if 0 { static void nail_touch(void) { if (trace_ent.iBleeds) { @@ -139,6 +140,20 @@ w_supernailgun_primary(player pl) nail.velocity = v_forward * 1000 + (v_up * -5); nail.angles = vectoangles(nail.velocity); } + #else + vector startPos; + Weapons_MakeVectors(pl); + + startPos = Weapons_GetCameraPos(pl) + (v_up * -5); + + entity oldself = self; + NSProjectile rocket = spawn(NSProjectile); + rocket.owner = pl; + self = rocket; + EntityDef_SpawnClassname("projectile_supernail"); + self = oldself; + rocket.Launch(startPos, pl.v_angle, 0.0f, 0.0f, 0.0f); + #endif Sound_Play(pl, CHAN_WEAPON, "weapon_supernailgun.shoot"); diff --git a/src/shared/weapons.h b/src/shared/weapons.h index f1dd60a..93651ce 100644 --- a/src/shared/weapons.h +++ b/src/shared/weapons.h @@ -19,16 +19,47 @@ enum { WEAPON_NONE, WEAPON_CROWBAR, + WEAPON_HAMMER, + WEAPON_GRAPPLE, WEAPON_SHOTGUN, + WEAPON_ICESHOTGUN, WEAPON_SUPERSHOTGUN, + WEAPON_ICESUPERSHOTGUN, WEAPON_NAILGUN, + WEAPON_LAVANAILGUN, WEAPON_SUPERNAILGUN, + WEAPON_LAVASUPERNAILGUN, WEAPON_GRENADELAUNCHER, + WEAPON_MULTIGREN, + WEAPON_PROXMINE, WEAPON_ROCKETLAUNCHER, + WEAPON_MULTIROCKET, WEAPON_LIGHTNING, + WEAPON_PLASMACANNON, + WEAPON_PLASMARIFLE }; #define MAX_A_SHELLS 100 #define MAX_A_NAILS 200 #define MAX_A_ROCKETS 100 #define MAX_A_CELLS 100 + +/* check if we have the ThreeWave data installed */ +bool +FreeDMC_CanThreeWave(void) +{ + if not (whichpack("models/v_grapple.mdl")) + return false; + + return true; +} + +/* check if we have the FreeDMC extras pack installed */ +bool +FreeDMC_CanExtra(void) +{ + if not (whichpack("models/v_ishot.mdl")) + return false; + + return true; +} \ No newline at end of file diff --git a/src/shared/weapons.qc b/src/shared/weapons.qc index ee237d3..f88b4f7 100644 --- a/src/shared/weapons.qc +++ b/src/shared/weapons.qc @@ -18,11 +18,22 @@ weapon_t w_null = {}; weapon_t g_weapons[] = { w_null, w_crowbar, + w_hammer, /* SoA */ + w_grapple, w_shotgun, + w_ice_shotgun, w_supershotgun, + w_ice_supershotgun, w_nailgun, + w_lava_nailgun, /* DoE */ w_supernailgun, + w_lava_supernailgun, /* DoE */ w_grenadelauncher, + w_multi_gren, /* DoE */ + w_proxmine, /* SoA */ w_rocketlauncher, - w_lightning + w_multi_rocket, /* DoE */ + w_lightning, + w_plasma_cannon, /* DoE */ + w_plasma_rifle /* SoA */ }; diff --git a/zpak001.pk3dir/def/weapon_grenadelauncher.def b/zpak001.pk3dir/def/weapon_grenadelauncher.def deleted file mode 100644 index 836010d..0000000 --- a/zpak001.pk3dir/def/weapon_grenadelauncher.def +++ /dev/null @@ -1,15 +0,0 @@ -entityDef weapon_grenadelauncher -{ - "editor_color" ".3 .3 1" - "editor_mins" "-16 -16 0" - "editor_maxs" "16 16 32" - "editor_usage" "Grenade Launcher" - "editor_rotatable" "1" - - "spawnclass" "NSItem" - "model" "models/g_rock.mdl" - "inv_item" "6" - "snd_acquire" "dmc_weapon.pickup" - "snd_respawn" "dmc_item.respawn" - "spin" "1" -} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapon_nailgun.def b/zpak001.pk3dir/def/weapon_nailgun.def deleted file mode 100644 index 65794f4..0000000 --- a/zpak001.pk3dir/def/weapon_nailgun.def +++ /dev/null @@ -1,15 +0,0 @@ -entityDef weapon_nailgun -{ - "editor_color" ".3 .3 1" - "editor_mins" "-16 -16 0" - "editor_maxs" "16 16 32" - "editor_usage" "Nailgun" - "editor_rotatable" "1" - - "spawnclass" "NSItem" - "model" "models/g_nail.mdl" - "inv_item" "4" - "snd_acquire" "dmc_weapon.pickup" - "snd_respawn" "dmc_item.respawn" - "spin" "1" -} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapon_rocketlauncher.def b/zpak001.pk3dir/def/weapon_rocketlauncher.def deleted file mode 100644 index 2c12c21..0000000 --- a/zpak001.pk3dir/def/weapon_rocketlauncher.def +++ /dev/null @@ -1,15 +0,0 @@ -entityDef weapon_rocketlauncher -{ - "editor_color" ".3 .3 1" - "editor_mins" "-16 -16 0" - "editor_maxs" "16 16 32" - "editor_usage" "Rocket Launcher" - "editor_rotatable" "1" - - "spawnclass" "NSItem" - "model" "models/g_rock2.mdl" - "inv_item" "7" - "snd_acquire" "dmc_weapon.pickup" - "snd_respawn" "dmc_item.respawn" - "spin" "1" -} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapon_supernailgun.def b/zpak001.pk3dir/def/weapon_supernailgun.def deleted file mode 100644 index 2936538..0000000 --- a/zpak001.pk3dir/def/weapon_supernailgun.def +++ /dev/null @@ -1,15 +0,0 @@ -entityDef weapon_supernailgun -{ - "editor_color" ".3 .3 1" - "editor_mins" "-16 -16 0" - "editor_maxs" "16 16 32" - "editor_usage" "Super Nailgun" - "editor_rotatable" "1" - - "spawnclass" "NSItem" - "model" "models/g_nail2.mdl" - "inv_item" "5" - "snd_acquire" "dmc_weapon.pickup" - "snd_respawn" "dmc_item.respawn" - "spin" "1" -} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapons.def b/zpak001.pk3dir/def/weapons.def new file mode 100644 index 0000000..6230695 --- /dev/null +++ b/zpak001.pk3dir/def/weapons.def @@ -0,0 +1,7 @@ +include weapons/grenadelauncher.def +include weapons/lightning.def +include weapons/nailgun.def +include weapons/rocketlauncher.def +include weapons/supernailgun.def +include weapons/supershotgun.def +include weapons/extraweapons.def \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapons/extraweapons.def b/zpak001.pk3dir/def/weapons/extraweapons.def new file mode 100644 index 0000000..3e81849 --- /dev/null +++ b/zpak001.pk3dir/def/weapons/extraweapons.def @@ -0,0 +1,205 @@ +// lava nail +entityDef projectile_lnail +{ + "spawnclass" "NSProjectile" + "model" "models/lspike.mdl" + + "def_damage" "damage_lavaNailDirect" + + "health" "0" + "velocity" "1000" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "0" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "0" + "model_detonate" "extraweapons.lavanailimpact" +} + +entityDef damage_lavaNailDirect +{ + "damage" "15" +} + +// lava super nail +entityDef projectile_lsupernail +{ + "spawnclass" "NSProjectile" + "model" "models/lspike.mdl" + + "def_damage" "damage_lavaSupernailDirect" + + "health" "0" + "velocity" "1000" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "0" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "0" + "model_detonate" "extraweapons.lavanailimpact" +} + +entityDef damage_lavaSupernailDirect +{ + "damage" "18" +} + +// sticky prox grenade +entityDef projectile_proxgrenade +{ + "spawnclass" "NSProjectile" + "model" "models/proxbomb.mdl" + + "def_splash_damage" "damage_grenadeSplash" + + "health" "0" + "velocity" "600 0 200" + "angular_velocity" "300 300 300" + "fuse" "2.5" + "bounce" "1" + "detonate_on_fuse" "1" + "detonate_on_death" "0" + "detonate_on_world" "0" + "detonate_on_actor" "1" + "stick_to_world" "1" + "stick_to_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "1" + + "smoke_fly" "weapon_grenadelauncher.trail" + "model_detonate" "fx_explosion.main" + "light_color" "1 0.8 0.4" + "light_radius" "160" + "light_offset" "0 0 0" + + "explode_light_color" "2 1.6 0.8" + "explode_light_radius" "320" + "explode_light_fadetime" "0.5" + + "snd_explode" "weapon_grenadelauncher.explode" + "snd_bounce" "weapon_grenadelauncher.bounce" +} + +// cluster multi nade +entityDef projectile_multinade +{ + "spawnclass" "NSProjectile" + "model" "models/mgrenade.mdl" + + "def_splash_damage" "damage_grenadeSplash" + + "health" "0" + "velocity" "600 0 200" + "angular_velocity" "300 300 300" + "fuse" "1" + "bounce" "1" + "detonate_on_fuse" "1" + "detonate_on_death" "0" + "detonate_on_world" "0" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "1" + + "debris_count" "5" + "projectile_debris" "projectile_multinade_sub" + + "smoke_fly" "weapon_grenadelauncher.trail" + + "snd_bounce" "weapon_grenadelauncher.bounce" +} + +entityDef projectile_multinade_sub +{ + "spawnclass" "NSProjectile" + "model" "models/mgrenade.mdl" + + "def_splash_damage" "damage_grenadeSplash" + + "health" "0" + "velocity" "0 0 350" + "angular_velocity" "300 300 300" + "fuse" "1" + "bounce" "1" + "detonate_on_fuse" "1" + "detonate_on_death" "0" + "detonate_on_world" "0" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "1" + + "smoke_fly" "weapon_grenadelauncher.trail" + "model_detonate" "fx_explosion.main" + "light_color" "1 0.8 0.4" + "light_radius" "160" + "light_offset" "0 0 0" + + "explode_light_color" "2 1.6 0.8" + "explode_light_radius" "320" + "explode_light_fadetime" "0.5" + + "snd_explode" "weapon_grenadelauncher.explode" +} + +// multi rocket +entityDef projectile_mrocket +{ + "spawnclass" "NSProjectile" + "model" "models/mrocket.mdl" + + "def_damage" "damage_rocketDirect" + "def_splash_damage" "damage_rocketSplash" + + "health" "0" + "velocity" "1000" + "angular_velocity" "0 0 200" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "1" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "1" + + "smoke_fly" "weapon_rocketlauncher.trail" + "model_detonate" "fx_explosion.main" + "light_color" "1 0.8 0.4" + "light_radius" "160" + "light_offset" "0 0 0" + + "explode_light_color" "2 1.6 0.8" + "explode_light_radius" "320" + "explode_light_fadetime" "0.5" + + "snd_explode" "weapon_rocketlauncher.explode" +} + +entityDef projectile_plasmaball +{ + "spawnclass" "NSProjectile" + "model" "sprites/nhth1.spr" + "rendermode" "5" + "renderamt" "255" + "rendercolor" "255 255 255" + "mins" "0 0 0" + "maxs" "0 0 0" + + "def_damage" "damage_nailDirect" + "light_color" "0.4 0.4 1.0" + "light_radius" "160" + "light_offset" "0 0 0" + + "health" "0" + "velocity" "1000" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "0" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "0" + "model_detonate" "extraweapons.iceexplo" +} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapons/grenadelauncher.def b/zpak001.pk3dir/def/weapons/grenadelauncher.def new file mode 100644 index 0000000..a945792 --- /dev/null +++ b/zpak001.pk3dir/def/weapons/grenadelauncher.def @@ -0,0 +1,54 @@ +entityDef weapon_grenadelauncher +{ + "editor_color" ".3 .3 1" + "editor_mins" "-16 -16 0" + "editor_maxs" "16 16 32" + "editor_usage" "Grenade Launcher" + "editor_rotatable" "1" + + "spawnclass" "NSItem" + "model" "models/g_rock.mdl" + "inv_item" "$WEAPON_GRENADELAUNCHER" + "snd_acquire" "dmc_weapon.pickup" + "snd_respawn" "dmc_item.respawn" + "spin" "1" +} + +entityDef projectile_grenade +{ + "spawnclass" "NSProjectile" + "model" "models/grenade.mdl" + + "def_splash_damage" "damage_grenadeSplash" + + "health" "0" + "velocity" "600 0 200" + "angular_velocity" "300 300 300" + "fuse" "2.5" + "bounce" "1" + "detonate_on_fuse" "1" + "detonate_on_death" "0" + "detonate_on_world" "0" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "1" + + "smoke_fly" "weapon_grenadelauncher.trail" + "model_detonate" "fx_explosion.main" + "light_color" "1 0.8 0.4" + "light_radius" "160" + "light_offset" "0 0 0" + + "explode_light_color" "2 1.6 0.8" + "explode_light_radius" "320" + "explode_light_fadetime" "0.5" + + "snd_explode" "weapon_grenadelauncher.explode" + "snd_bounce" "weapon_grenadelauncher.bounce" +} + +entityDef damage_grenadeSplash +{ + "damage" "skill:plr_grenadelauncher" + "radius" "160" +} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapon_lightning.def b/zpak001.pk3dir/def/weapons/lightning.def similarity index 87% rename from zpak001.pk3dir/def/weapon_lightning.def rename to zpak001.pk3dir/def/weapons/lightning.def index c736495..60ba034 100644 --- a/zpak001.pk3dir/def/weapon_lightning.def +++ b/zpak001.pk3dir/def/weapons/lightning.def @@ -8,7 +8,7 @@ entityDef weapon_lightning "spawnclass" "NSItem" "model" "models/g_light.mdl" - "inv_item" "8" + "inv_item" "$WEAPON_LIGHTNING" "snd_acquire" "dmc_weapon.pickup" "snd_respawn" "dmc_item.respawn" "spin" "1" diff --git a/zpak001.pk3dir/def/weapons/nailgun.def b/zpak001.pk3dir/def/weapons/nailgun.def new file mode 100644 index 0000000..77bfc8a --- /dev/null +++ b/zpak001.pk3dir/def/weapons/nailgun.def @@ -0,0 +1,39 @@ +entityDef weapon_nailgun +{ + "editor_color" ".3 .3 1" + "editor_mins" "-16 -16 0" + "editor_maxs" "16 16 32" + "editor_usage" "Nailgun" + "editor_rotatable" "1" + + "spawnclass" "NSItem" + "model" "models/g_nail.mdl" + "inv_item" "$WEAPON_NAILGUN" + "snd_acquire" "dmc_weapon.pickup" + "snd_respawn" "dmc_item.respawn" + "spin" "1" +} + +entityDef projectile_nail +{ + "spawnclass" "NSProjectile" + "model" "models/spike.mdl" + + "def_damage" "damage_nailDirect" + + "health" "0" + "velocity" "1000" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "0" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "0" + "model_detonate" "weapon_nailgun.impact" +} + +entityDef damage_nailDirect +{ + "damage" "skill:plr_nailgun" +} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapons/rocketlauncher.def b/zpak001.pk3dir/def/weapons/rocketlauncher.def new file mode 100644 index 0000000..57ded35 --- /dev/null +++ b/zpak001.pk3dir/def/weapons/rocketlauncher.def @@ -0,0 +1,59 @@ +entityDef weapon_rocketlauncher +{ + "editor_color" ".3 .3 1" + "editor_mins" "-16 -16 0" + "editor_maxs" "16 16 32" + "editor_usage" "Rocket Launcher" + "editor_rotatable" "1" + + "spawnclass" "NSItem" + "model" "models/g_rock2.mdl" + "inv_item" "$WEAPON_ROCKETLAUNCHER" + "snd_acquire" "dmc_weapon.pickup" + "snd_respawn" "dmc_item.respawn" + "spin" "1" +} + +entityDef projectile_rocket +{ + "spawnclass" "NSProjectile" + "model" "models/rocket.mdl" + + "def_damage" "damage_rocketDirect" + "def_splash_damage" "damage_rocketSplash" + + "health" "0" + "velocity" "1000" + "angular_velocity" "0 0 200" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "1" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "1" + + "smoke_fly" "weapon_rocketlauncher.trail" + "model_detonate" "fx_explosion.main" + "light_color" "1 0.8 0.4" + "light_radius" "160" + "light_offset" "0 0 0" + + "explode_light_color" "2 1.6 0.8" + "explode_light_radius" "320" + "explode_light_fadetime" "0.5" + + "snd_explode" "weapon_rocketlauncher.explode" +} + +entityDef damage_rocketDirect +{ + "damage" "skill:plr_rocketlauncher_impact" + "damage_random" "skill:plr_rocketlauncher_impact_rand" +} + +entityDef damage_rocketSplash +{ + "damage" "skill:plr_rocketlauncher" + "radius" "160" +} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapons/supernailgun.def b/zpak001.pk3dir/def/weapons/supernailgun.def new file mode 100644 index 0000000..8123404 --- /dev/null +++ b/zpak001.pk3dir/def/weapons/supernailgun.def @@ -0,0 +1,39 @@ +entityDef weapon_supernailgun +{ + "editor_color" ".3 .3 1" + "editor_mins" "-16 -16 0" + "editor_maxs" "16 16 32" + "editor_usage" "Super Nailgun" + "editor_rotatable" "1" + + "spawnclass" "NSItem" + "model" "models/g_nail2.mdl" + "inv_item" "$WEAPON_SUPERNAILGUN" + "snd_acquire" "dmc_weapon.pickup" + "snd_respawn" "dmc_item.respawn" + "spin" "1" +} + +entityDef projectile_supernail +{ + "spawnclass" "NSProjectile" + "model" "models/spike.mdl" + + "def_damage" "damage_supernailDirect" + + "health" "0" + "velocity" "1000" + "fuse" "10" + "detonate_on_fuse" "0" + "detonate_on_death" "0" + "detonate_on_world" "1" + "detonate_on_actor" "1" + "impact_damage_effect" "1" + "impact_gib" "0" + "model_detonate" "weapon_supernailgun.impact" +} + +entityDef damage_supernailDirect +{ + "damage" "skill:plr_supernailgun" +} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapon_supershotgun.def b/zpak001.pk3dir/def/weapons/supershotgun.def similarity index 86% rename from zpak001.pk3dir/def/weapon_supershotgun.def rename to zpak001.pk3dir/def/weapons/supershotgun.def index 062c797..0d51b63 100644 --- a/zpak001.pk3dir/def/weapon_supershotgun.def +++ b/zpak001.pk3dir/def/weapons/supershotgun.def @@ -8,7 +8,7 @@ entityDef weapon_supershotgun "spawnclass" "NSItem" "model" "models/g_shot2.mdl" - "inv_item" "3" + "inv_item" "$WEAPON_SUPERSHOTGUN" "snd_acquire" "dmc_weapon.pickup" "snd_respawn" "dmc_item.respawn" "spin" "1" diff --git a/zpak001.pk3dir/particles/extraweapons.cfg b/zpak001.pk3dir/particles/extraweapons.cfg new file mode 100644 index 0000000..d6f8197 --- /dev/null +++ b/zpak001.pk3dir/particles/extraweapons.cfg @@ -0,0 +1,44 @@ +r_part icepuff +{ + model "models/iceball.mdl" + count 20 + scale 1 + alpha 1 + die 1 + randomvel 20 + orgadd 0 31 + spawnorg 4 + gravity 40 +} + +r_part iceexplo +{ + texture "particles/quake" + count 512 + scale 2 + die 0.8 + diesubrand 0.4 + randomvel 256 + rampmode absolute + rampindexlist 244 245 246 254 + gravity 40 + friction -4 + spawnorg 16 + assoc explode2vi +} + +r_part lavanailimpact +{ + texture "particles/quake" + count 128 + scale 3 + die 0.1 + diesubrand 0.2 + randomvel 64 + rampmode absolute + rampindexlist 229 230 231 232 233 234 235 236 237 238 239 251 250 + gravity 40 + friction -4 + spawnorg 16 + assoc explode2vi +} \ No newline at end of file diff --git a/zpak001.pk3dir/particles/weapon_grenadelauncher.cfg b/zpak001.pk3dir/particles/weapon_grenadelauncher.cfg new file mode 100644 index 0000000..182eb05 --- /dev/null +++ b/zpak001.pk3dir/particles/weapon_grenadelauncher.cfg @@ -0,0 +1,15 @@ +r_part trail +{ + texture "particles/quake" + step 3 + scale 4 + die 0.8 + diesubrand 0.6 + rampmode absolute + rampindex 6 0.667 + rampindex 5 0.5 + rampindex 4 0.333 + rampindex 3 0.167 + spawnorg 3 + gravity -40 +} \ No newline at end of file diff --git a/zpak001.pk3dir/particles/weapon_nailgun.cfg b/zpak001.pk3dir/particles/weapon_nailgun.cfg new file mode 100644 index 0000000..26c1205 --- /dev/null +++ b/zpak001.pk3dir/particles/weapon_nailgun.cfg @@ -0,0 +1,14 @@ +r_part impact +{ + texture "particles/quake" + count 20 + scale 1 + alpha 1 + die 1 + randomvel 20 + orgadd 0 31 + spawnorg 4 + gravity 40 + scalefactor 0.8 + colorindex 0 7 +} \ No newline at end of file diff --git a/zpak001.pk3dir/particles/weapon_rocketlauncher.cfg b/zpak001.pk3dir/particles/weapon_rocketlauncher.cfg new file mode 100644 index 0000000..115f5f9 --- /dev/null +++ b/zpak001.pk3dir/particles/weapon_rocketlauncher.cfg @@ -0,0 +1,17 @@ +r_part trail +{ + texture "particles/quake" + step 3 + scale 4 + die 1.2 + diesubrand 0.6 + rampmode absolute + rampindex 109 1.0 + rampindex 107 0.833 + rampindex 6 0.667 + rampindex 5 0.5 + rampindex 4 0.333 + rampindex 3 0.167 + spawnorg 3 + gravity -40 +} \ No newline at end of file diff --git a/zpak001.pk3dir/particles/weapon_supernailgun.cfg b/zpak001.pk3dir/particles/weapon_supernailgun.cfg new file mode 100644 index 0000000..26c1205 --- /dev/null +++ b/zpak001.pk3dir/particles/weapon_supernailgun.cfg @@ -0,0 +1,14 @@ +r_part impact +{ + texture "particles/quake" + count 20 + scale 1 + alpha 1 + die 1 + randomvel 20 + orgadd 0 31 + spawnorg 4 + gravity 40 + scalefactor 0.8 + colorindex 0 7 +} \ No newline at end of file diff --git a/zpak001.pk3dir/scripts/constants.txt b/zpak001.pk3dir/scripts/constants.txt new file mode 100644 index 0000000..a55e4a7 --- /dev/null +++ b/zpak001.pk3dir/scripts/constants.txt @@ -0,0 +1,21 @@ +// weapon constants +WEAPON_NONE 0 +WEAPON_CROWBAR 1 +WEAPON_HAMMER 2 +WEAPON_GRAPPLE 3 +WEAPON_SHOTGUN 4 +WEAPON_ICESHOTGUN 5 +WEAPON_SUPERSHOTGUN 6 +WEAPON_ICESUPERSHOTGUN 7 +WEAPON_NAILGUN 8 +WEAPON_LAVANAILGUN 9 +WEAPON_SUPERNAILGUN 10 +WEAPON_LAVASUPERNAILGUN 11 +WEAPON_GRENADELAUNCHER 12 +WEAPON_MULTIGREN 13 +WEAPON_PROXMINE 14 +WEAPON_ROCKETLAUNCHER 15 +WEAPON_MULTIROCKET 16 +WEAPON_LIGHTNING 17 +WEAPON_PLASMACANNON 18 +WEAPON_PLASMARIFLE 19 \ No newline at end of file diff --git a/zpak001.pk3dir/sound/weapons_dmc.sndshd b/zpak001.pk3dir/sound/weapons_dmc.sndshd index 0ea7696..d3413cd 100644 --- a/zpak001.pk3dir/sound/weapons_dmc.sndshd +++ b/zpak001.pk3dir/sound/weapons_dmc.sndshd @@ -46,6 +46,14 @@ weapon_grenadelauncher.shoot sample weapons/grenade.wav } +weapon_grenadelauncher.explode +{ + alerts + sample weapons/explode3.wav + sample weapons/explode4.wav + sample weapons/explode5.wav +} + weapon_grenadelauncher.bounce { alerts @@ -58,6 +66,14 @@ weapon_rocketlauncher.shoot sample weapons/sgun1.wav } +weapon_rocketlauncher.explode +{ + alerts + sample weapons/explode3.wav + sample weapons/explode4.wav + sample weapons/explode5.wav +} + weapon_lightning.start { alerts