Initial work on the extra DMC content for 3wave and Suparsonik's addon work

This commit is contained in:
Marco Cawthorne 2023-07-27 23:18:09 -07:00
parent ccab59cb15
commit f39acbed5e
Signed by: eukara
GPG key ID: CE2032F0A2882A22
50 changed files with 4228 additions and 221 deletions

111
src/client/game_event.qc Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
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);
}

56
src/client/init.qc Normal file
View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
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");
}

View file

@ -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

View file

@ -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);
}
}
}

56
src/server/extraitems.qc Normal file
View file

@ -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)
{
}

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -17,4 +17,5 @@
enum
{
EV_DMC_PICKUPMSG,
EV_GIBALIEN,
};

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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) {

244
src/shared/w_grapple.qc Normal file
View file

@ -0,0 +1,244 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#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
};

View file

@ -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;
}

206
src/shared/w_hammer.qc Normal file
View file

@ -0,0 +1,206 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

231
src/shared/w_ice_shotgun.qc Normal file
View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -0,0 +1,263 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -0,0 +1,263 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -0,0 +1,248 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -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

276
src/shared/w_multi_gren.qc Normal file
View file

@ -0,0 +1,276 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -0,0 +1,219 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -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");

View file

@ -0,0 +1,371 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -0,0 +1,410 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

271
src/shared/w_proxmine.qc Normal file
View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*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
};

View file

@ -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()) {

View file

@ -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");

View file

@ -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;
}

View file

@ -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 */
};

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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

View file

@ -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