Gunman Chronicles: Basic work on weapons and their menus completed.

Some weapons and their visuals are not implemented yet.
It's a very good preview of how things are going to work though.
This commit is contained in:
Marco Cawthorne 2019-09-22 15:41:13 +02:00
parent 91d1c2250f
commit 6fea65a586
37 changed files with 3665 additions and 78 deletions

View file

@ -74,7 +74,7 @@ struct
entity eMuzzleflash;
float fNumBones;
float fEjectBone;
vector vPunchAngle;
vector punchangle;
float fLastWeapon;
float fBobTime;
float fBob;

View file

@ -80,7 +80,7 @@ CSQC_Parse_Damage(float save, float take, vector abs_pos)
pSeat->damage_alpha = 1.0f;
}
View_AddPunchAngle([take,0,0]);
//View_AddPunchAngle([take,0,0]);
return TRUE;
}

View file

@ -72,6 +72,5 @@ float clframetime;
/* prototypes */
void View_SetMuzzleflash(int);
void View_UpdateWeapon(entity, entity);
void View_AddPunchAngle(vector);
void View_PlayAnimation(int);
void Game_Input(void);

View file

@ -242,7 +242,7 @@ CSQC_UpdateView(float w, float h, float focus)
addentities(MASK_ENGINE);
setproperty(VF_MIN, video_mins);
setproperty(VF_SIZE, video_res);
setproperty(VF_ANGLES, view_angles + pSeat->vPunchAngle);
setproperty(VF_ANGLES, view_angles + pl.punchangle);
setproperty(VF_DRAWWORLD, 1);
if (g_skyscale != 0 && g_skypos) {
@ -270,7 +270,6 @@ CSQC_UpdateView(float w, float h, float focus)
pf.postdraw();
}
View_DropPunchAngle();
Fade_Update((int)video_mins[0],(int)video_mins[1], (int)w, (int)h);
#ifdef CSTRIKE

View file

@ -31,6 +31,7 @@ void Predict_PreFrame(player pl)
pl.net_jumptime = pl.jumptime;
pl.net_teleport_time = pl.teleport_time;
pl.net_viewzoom = pl.viewzoom;
pl.net_punchangle = pl.punchangle;
#ifdef VALVE
pl.net_w_attack_next = pl.w_attack_next;
@ -82,6 +83,8 @@ void Predict_PostFrame(player pl)
pl.jumptime = pl.net_jumptime;
pl.teleport_time = pl.net_teleport_time;
pl.viewzoom = pl.net_viewzoom;
pl.punchangle = pl.net_punchangle;
//pl.hook.origin = pl.net_hookpos;
#ifdef VALVE
pl.w_attack_next = pl.net_w_attack_next;

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
vector vHUDSlotNumPos[6] =
{
[168 / 256, 72 / 128],
[188 / 256, 72 / 128],
[208 / 256, 72 / 128],
[168 / 256, 92 / 128],
[188 / 256, 92 / 128],
[208 / 256, 92 / 128]
};
void HUD_DrawWeaponSelect_Forward(void)
{
player pl = (player)pSeat->ePlayer;
if (!pl.activeweapon) {
return;
}
if (Weapons_InputForward(pl) == FALSE) {
return;
}
if (pSeat->fHUDWeaponSelectTime < time) {
pSeat->fHUDWeaponSelected = pl.activeweapon;
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
} else {
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
pSeat->fHUDWeaponSelected--;
if (pSeat->fHUDWeaponSelected <= 0) {
pSeat->fHUDWeaponSelected = g_weapons.length - 1;
}
}
pSeat->fHUDWeaponSelectTime = time + 3;
if not (pl.g_items & g_weapons[pSeat->fHUDWeaponSelected].id) {
HUD_DrawWeaponSelect_Forward();
}
}
void HUD_DrawWeaponSelect_Back(void)
{
player pl = (player)pSeat->ePlayer;
if (!pl.activeweapon) {
return;
}
if (Weapons_InputBack(pl) == FALSE) {
return;
}
if (pSeat->fHUDWeaponSelectTime < time) {
pSeat->fHUDWeaponSelected = pl.activeweapon;
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
} else {
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
pSeat->fHUDWeaponSelected++;
if (pSeat->fHUDWeaponSelected >= g_weapons.length) {
pSeat->fHUDWeaponSelected = 1;
}
}
pSeat->fHUDWeaponSelectTime = time + 3;
if not (pl.g_items & g_weapons[pSeat->fHUDWeaponSelected].id) {
HUD_DrawWeaponSelect_Back();
}
}
void HUD_DrawWeaponSelect_Trigger(void)
{
player pl = (player)pSeat->ePlayer;
pl.activeweapon = pSeat->fHUDWeaponSelected;
sendevent("PlayerSwitchWeapon", "f", pSeat->fHUDWeaponSelected);
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE);
pSeat->fHUDWeaponSelected = pSeat->fHUDWeaponSelectTime = 0;
}
void HUD_DrawWeaponSelect_Last(void)
{
}
void HUD_DrawWeaponSelect_Num(vector vPos, float fValue)
{
drawsubpic(vPos, [20,20], "sprites/640hud7.spr_0.tga", vHUDSlotNumPos[fValue], [20/256, 20/128], g_hud_color, 1, DRAWFLAG_ADDITIVE);
}
int HUD_InSlotPos(int slot, int pos)
{
player pl = (player)pSeat->ePlayer;
for (int i = 1; i < g_weapons.length; i++) {
if (g_weapons[i].slot == slot && g_weapons[i].slot_pos == pos) {
if (pl.g_items & g_weapons[i].id) {
return i;
} else {
return -1;
}
}
}
return -1;
}
void HUD_DrawWeaponSelect(void)
{
player pl = (player)pSeat->ePlayer;
if (!pl.activeweapon) {
return;
}
if (pSeat->fHUDWeaponSelectTime < time) {
if (pSeat->fHUDWeaponSelected) {
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_hudoff.wav", 0.5, ATTN_NONE);
pSeat->fHUDWeaponSelected = 0;
}
return;
}
vector vecPos = video_mins + [16,16];
int b;
int wantslot = g_weapons[pSeat->fHUDWeaponSelected].slot;
int wantpos = g_weapons[pSeat->fHUDWeaponSelected].slot_pos;
for (int i = 0; i < 5; i++) {
int slot_selected = 0;
vecPos[1] = video_mins[1] + 16;
HUD_DrawWeaponSelect_Num(vecPos, i);
vecPos[1] += 20;
for (int x = 0; x < 32; x++) {
if (i == wantslot) {
slot_selected = TRUE;
if (x == wantpos) {
// Selected Sprite
Weapons_HUDPic(pSeat->fHUDWeaponSelected, 1, vecPos);
drawsubpic(vecPos, [170,45], "sprites/640hud3.spr_0.tga",
[0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
vecPos[1] += 50;
} else if ((b=HUD_InSlotPos(i, x)) != -1) {
// Unselected Sprite
Weapons_HUDPic(b, 0, vecPos);
vecPos[1] += 50;
}
} else if (HUD_InSlotPos(i, x) != -1) {
HUD_DrawWeaponSelect_Num(vecPos, 5);
vecPos[1] += 25;
}
}
if (slot_selected == TRUE) {
vecPos[0] += 175;
} else {
vecPos[0] += 25;
}
}
}

View file

@ -29,6 +29,8 @@ void Client_Init(float apilevel, string enginename, float engineversion)
precache_model("sprites/640hud4.spr");
precache_model("sprites/640hud5.spr");
precache_model("sprites/640hud6.spr");
BEAM_TRIPMINE = particleeffectnum("beam_tripmine");
}
void Client_InitDone(void)

View file

@ -38,7 +38,7 @@ decore.cpp
../../shared/valve/animations.h
../../shared/valve/animations.c
../../shared/valve/player.cpp
../../shared/rewolf/player.cpp
../player.c
../../shared/pmove.c
../predict.c
@ -52,6 +52,8 @@ decore.cpp
../../shared/rewolf/weapons.h
../../shared/rewolf/w_fists.c
../../shared/rewolf/w_gausspistol.c
../../shared/rewolf/w_grenade.c
../../shared/rewolf/w_shotgun.c
../../shared/rewolf/w_beamgun.c
../../shared/rewolf/w_chemicalgun.c
../../shared/rewolf/w_dml.c
@ -75,7 +77,7 @@ entities.c
../vgui.cpp
hud.c
../valve/hud_weaponselect.c
hud_weaponselect.c
../valve/scoreboard.c
../valve/input.c

View file

@ -18,12 +18,11 @@ vector g_hud_color;
struct
{
//Viewmodel stuff
/* viewmodel stuff */
entity eViewModel;
entity eMuzzleflash;
float fNumBones;
float fEjectBone;
vector vPunchAngle;
float fLastWeapon;
float fBobTime;
float fBob;
@ -33,20 +32,23 @@ struct
int iZoomed;
float flZoomTime;
//Player fields
/* player fields */
entity ePlayer;
vector vPlayerOrigin;
vector vPlayerOriginOld;
vector vPlayerVelocity;
float fPlayerFlags;
// Camera Fields
//entity ePlayerEnt;
/* camera fields */
vector vCameraPos;
vector vCameraAngle;
float fCameraTime;
/* punchangle */
vector punchangle;
vector net_punchangle;
/* hud.c */
/* hud.c */
float health_old;
float health_alpha;
float armor_old;
@ -58,10 +60,9 @@ struct
float ammo3_old;
float ammo3_alpha;
//UI fields
int iShowScores; // This is seperated from the other VGUI stuff so we can check scores while buying and whatnot
// We can only carry one item per slot, so this is hacking around the last one
/* This is seperated from the other VGUI stuff so we can check scores
* while buying and whatnot */
int iShowScores;
float fHUDWeaponSelected;
float fHUDWeaponSelectTime;

View file

@ -119,32 +119,6 @@ View_CalcRoll(void)
return autocvar_v_camroll ? roll : 0;
}
/*
====================
View_DropPunchAngle
Quickly lerp to the original viewposition
====================
*/
void View_DropPunchAngle(void)
{
float lerp;
lerp = 1.0f - (clframetime * 4);
pSeat->vPunchAngle *= lerp;
}
/*
====================
View_AddPunchAngle
Gives the angle a bit of an offset/punch/kick
====================
*/
void View_AddPunchAngle(vector add)
{
pSeat->vPunchAngle = add;
}
/*
====================
View_DrawViewModel
@ -208,8 +182,11 @@ void View_DrawViewModel(void)
makevectors(getproperty(VF_ANGLES));
eMuzzleflash.origin = gettaginfo(eViewModel, eMuzzleflash.skin);
dynamiclight_add(pSeat->vPlayerOrigin + (v_forward * 32), 400 * eMuzzleflash.alpha, [1,0.45,0]);
setorigin(eMuzzleflash, eMuzzleflash.origin);
addentity(eMuzzleflash);
}
setorigin(eViewModel, eViewModel.origin);
addentity(eViewModel);
}

View file

@ -52,6 +52,7 @@ void func_ladder :: func_ladder ( void )
#endif
#else
Init();
setorigin(this, origin);
#endif
}
@ -61,4 +62,5 @@ void func_ladder :: Initialized (void)
movetype = MOVETYPE_NONE;
skin = CONTENT_LADDER;
solid = SOLID_BSP;
setorigin(this, origin);
}

View file

@ -42,6 +42,15 @@ Game_Input(void)
if (self.impulse == 101) {
pl.health = 100;
pl.armor = 100;
Weapons_AddItem(pl, WEAPON_FISTS);
Weapons_AddItem(pl, WEAPON_GAUSSPISTOL);
Weapons_AddItem(pl, WEAPON_BEAMGUN);
Weapons_AddItem(pl, WEAPON_CHEMICALGUN);
Weapons_AddItem(pl, WEAPON_DML);
Weapons_AddItem(pl, WEAPON_MINIGUN);
Weapons_AddItem(pl, WEAPON_AICORE);
Weapons_AddItem(pl, WEAPON_SHOTGUN);
Weapons_AddItem(pl, WEAPON_GRENADE);
}
if (self.impulse == 102) {

View file

@ -29,7 +29,7 @@ monster_human_unarmed.cpp
../../shared/decals.c
../../shared/effects.c
../../shared/spraylogo.cpp
../../shared/valve/player.cpp
../../shared/rewolf/player.cpp
../valve/player.c
../../shared/pmove.c
../valve/spectator.c
@ -38,6 +38,8 @@ monster_human_unarmed.cpp
../../shared/rewolf/weapons.h
../../shared/rewolf/w_fists.c
../../shared/rewolf/w_gausspistol.c
../../shared/rewolf/w_grenade.c
../../shared/rewolf/w_shotgun.c
../../shared/rewolf/w_beamgun.c
../../shared/rewolf/w_chemicalgun.c
../../shared/rewolf/w_dml.c

View file

@ -74,7 +74,8 @@ void BaseGun_ShotMultiplierHandle( float fShots ) {
vPunch[0] = -2 * ( pSeat->iShotMultiplier / 6 );
vPunch[1] = random( -1, 1 );
View_AddPunchAngle( vPunch );
/*player pl = (player)self;
pl.punchangle += vPunch;*/
#endif
}

View file

@ -39,10 +39,11 @@ class player
float activeweapon;
float viewzoom;
vector punchangle;
vector view_ofs;
float weapontime;
/* special for opfor */
/* any mods that use hooks */
entity hook;
/* Weapon specific */
@ -76,6 +77,8 @@ class player
float net_teleport_time;
float net_weapontime;
float net_viewzoom;
vector net_punchangle;
vector net_hookpos;
int net_ammo1;
int net_ammo2;
int net_ammo3;

View file

@ -43,6 +43,7 @@ w_displacer_precache(void)
precache_model("models/v_displacer.mdl");
precache_model("models/w_displacer.mdl");
precache_model("models/p_displacer.mdl");
precache_model("sprites/exit1.spr");
}
void

View file

@ -675,6 +675,7 @@ PMove_Run_Move(void)
void
PMove_Run(void)
{
float punch;
player pl = (player)self;
#ifdef VALVE
self.maxspeed = (self.flags & FL_CROUCHING) ? 135 : 270;
@ -697,12 +698,10 @@ PMove_Run(void)
}
/* grappling hook stuff */
#ifdef GEARBOX
if (pl.hook.skin == 1) {
pl.velocity = (pl.hook.origin - pl.origin);
pl.velocity = (pl.velocity * (1 / (vlen(pl.velocity) / 1000)));
}
#endif
/* call accelerate before and after the actual move,
* with half the move each time. this reduces framerate dependence.
@ -723,5 +722,11 @@ PMove_Run(void)
pl.w_idle_next = max(0, pl.w_idle_next - input_timelength);
#endif
pl.weapontime += input_timelength;
punch = max(0, 1.0f - (input_timelength * 4));
pl.punchangle[0] *= punch;
pl.punchangle[1] *= punch;
pl.punchangle[2] *= punch;
Game_Input();
}

View file

@ -21,10 +21,10 @@
#define ITEM_DML 0x00000010i
#define ITEM_MINIGUN 0x00000020i
#define ITEM_AICORE 0x00000040i
#define ITEM_UNUSED8 0x00000080i
#define ITEM_GRENADE 0x00000080i
#define ITEM_UNUSED9 0x00000100i
#define ITEM_UNUSED10 0x00000200i
#define ITEM_SHOTGUN 0x00000100i
#define ITEM_GAUSSADDON 0x00000200i
#define ITEM_UNUSED11 0x00000400i
#define ITEM_UNUSED12 0x00000800i
#define ITEM_UNUSED13 0x00001000i

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
int input_sequence;
class player
{
float health;
float armor;
/* When the weapon is done firing */
float w_attack_next;
/* When to play the next idle animation */
float w_idle_next;
/* Magazine/Clip */
int a_ammo1;
/* Rest in the inventory */
int a_ammo2;
/* Special ammo */
int a_ammo3;
/* We can't use the default .items field, because FTE will assume
* effects of some bits. Such as invisibility, quad, etc.
* also, modders probably want 32 bits for items. */
int g_items;
float activeweapon;
float viewzoom;
vector punchangle;
vector view_ofs;
float weapontime;
/* any mods that use hooks */
entity hook;
#ifdef CSQC
/* External model */
entity p_model;
int p_hand_bone;
int p_model_bone;
float pitch;
float lastweapon;
/* Prediction */
vector net_origin;
vector net_velocity;
float net_flags;
float net_w_attack_next;
float net_w_idle_next;
float net_jumptime;
float net_teleport_time;
float net_weapontime;
float net_viewzoom;
vector net_punchangle;
int net_ammo1;
int net_ammo2;
int net_ammo3;
int sequence;
virtual void() gun_offset;
virtual void() draw;
virtual float() predraw;
virtual void() postdraw;
#else
int ammo_battery; // beamgun
int ammo_chem; // chemicalgun
int ammo_rocket; // dml / grenades
int ammo_gauss; // gauspistol
int ammo_minigun; // minigun
int ammo_buckshot; // shotgun
int fist_mode; // knife/fists
int gauss_mode;
int shotgun_shells;
int shotgun_spread;
int dml_launch; /* when fired, when targeted */
int dml_flightpath; /* guided, homing, spiral */
int dml_detonate; /* on impact, in proximity, timed, when tripped */
int dml_payload; /* explosive, cluster */
int chem_acid;
int chem_neutral;
int chem_base;
int chem_pressure;
int beam_range; /* TOUCH TAZER, SHORT TAZER, MEDIUM BEAM, LONG BEAM */
int beam_poweracc; /* LOW HIGHEST, MEDIUM HIGH, HIGH MEDIUM, HIGHEST LOW */
int beam_lightning; /* BEAM, CHAIN, BALL */
int gren_detonate; /* when tripped (tripmine), timed, on impact */
int gren_payload; /* cluster, explosive */
/* conditional networking */
int old_modelindex;
vector old_origin;
vector old_angles;
vector old_velocity;
int old_flags;
int old_activeweapon;
int old_items;
int old_health;
int old_armor;
int old_movetype;
float old_viewofs;
int old_baseframe;
int old_frame;
int old_a_ammo1;
int old_a_ammo2;
int old_a_ammo3;
#endif
};

View file

@ -1,2 +1,153 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_aicore = {};
enum {
AIC_IDLE, // 1.777778f
AIC_PLUGIN, // 1.066667f
AIC_DRAW // 1.7f
};
void
w_aicore_draw(void)
{
Weapons_SetModel("models/v_aicore.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(AIC_DRAW);
}
void
w_aicore_holster(void)
{
}
void
w_aicore_primary(void)
{
vector src;
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
src = Weapons_GetCameraPos();
#ifdef CSQC
//Weapons_ViewAnimation(GP_FIRESINGLE);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 2.5f;
}
void
w_aicore_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(AIC_IDLE);
pl.w_idle_next = 1.777778f;
}
void
w_aicore_updateammo(player pl)
{
}
string
w_aicore_wmodel(void)
{
return "";
}
string
w_aicore_pmodel(void)
{
return "";
}
string
w_aicore_deathmsg(void)
{
return "";
}
float
w_aicore_aimanim(void)
{
return 0;
}
void
w_aicore_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_aicore0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_aicore_precache(void)
{
precache_model("models/v_aicore.mdl");
}
weapon_t w_aicore =
{
.id = ITEM_AICORE,
.slot = 0,
.slot_pos = 1,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_aicore_draw,
.holster = w_aicore_holster,
.primary = w_aicore_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_aicore_release,
.crosshair = __NULL__,
.precache = w_aicore_precache,
.pickup = __NULL__,
.updateammo = w_aicore_updateammo,
.wmodel = w_aicore_wmodel,
.pmodel = w_aicore_pmodel,
.deathmsg = w_aicore_deathmsg,
.aimanim = w_aicore_aimanim,
.hudpic = w_aicore_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_aicore(void)
{
Weapons_InitItem(WEAPON_AICORE);
}
#endif

View file

@ -1,2 +1,353 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_beamgun = {};
enum {
BEAMGUN_DRAW,
BEAMGUN_IDLE, // 2.6f
BEAMGUN_FIDGET1, // 2.4f
BEAMGUN_FIDGET2, // 2.08f
BEAMGUN_FIRE, // 0.333333f
BEAMGUN_FIRESINGLE, // 0.333333f
BEAMGUN_CONFIG, // 2.26087f
BEAMGUN_CHARGE // 1.3f
};
void
w_beamgun_draw(void)
{
Weapons_SetModel("models/v_beam.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(BEAMGUN_DRAW);
}
void
w_beamgun_holster(void)
{
}
void
w_beamgun_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(BEAMGUN_IDLE);
pl.w_idle_next = 2.6f;
}
void
w_beamgun_primary(void)
{
vector src;
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
if (pl.a_ammo1 > 0) {
pl.a_ammo1 = 0;
pl.flags &= ~FL_SEMI_TOGGLED;
Weapons_ViewAnimation(BEAMGUN_CONFIG);
pl.w_attack_next = 2.26087f;
pl.w_idle_next = 2.26087f;
return;
}
if (pl.w_attack_next) {
return;
}
src = Weapons_GetCameraPos();
#ifdef CSQC
//Weapons_ViewAnimation(GP_FIRESINGLE);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 2.5f;
}
void
w_beamgun_secondary(void)
{
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
pl.flags &= ~FL_SEMI_TOGGLED;
if (pl.w_attack_next) {
return;
}
/* activate menu */
if (pl.a_ammo1 <= 0 || pl.a_ammo1 == 3) {
pl.a_ammo1 = 1;
} else {
pl.a_ammo1 = bound(1, pl.a_ammo1 + 1, 3);
}
}
void
w_beamgun_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_battery, -1);
#endif
}
string
w_beamgun_wmodel(void)
{
return "";
}
string
w_beamgun_pmodel(void)
{
return "";
}
string
w_beamgun_deathmsg(void)
{
return "";
}
float
w_beamgun_aimanim(void)
{
return 0;
}
void
w_beamgun_hud(void)
{
#ifdef CSQC
static string rmodes[] = {
"TOUCH TAZER",
"SHORT TAZER",
"MEDIUM BEAM",
"LONG BEAM"
};
static string pmodes[] = {
"LOW",
"MEDIUM",
"HIGH",
"HIGHEST"
};
static string amodes[] = {
"HIGHEST",
"HIGH",
"MEDIUM",
"LOW"
};
static string lmodes[] = {
"BEAM",
"CHAIN",
"BALL"
};
vector pos;
player pl = (player)self;
/* menu */
if (pl.a_ammo1 > 0) {
vector col1, col2, col3;
string txt1, txt2, txt3, txt4;
col1 = col2 = col3 = [1,1,1];
switch (pl.a_ammo1) {
case 1:
col1 = [0,1,0];
break;
case 2:
col2 = [0,1,0];
break;
case 3:
col3 = [0,1,0];
break;
}
txt1 = sprintf("RANGE: %s", rmodes[getstati(46)]);
txt2 = sprintf("POWER: %s", pmodes[getstati(47)]);
txt3 = sprintf("ACCURACY: %s", amodes[getstati(47)]);
txt4 = sprintf("LIGHTNING: %s", lmodes[getstati(48)]);
pos = video_mins + (video_res / 2) + [-80,-48];
drawfont = FONT_20;
drawstring(pos, txt1, [20,20], col1, 1.0f,
DRAWFLAG_ADDITIVE);
pos[1] += 24;
drawstring(pos, txt2, [20,20], col2, 1.0f,
DRAWFLAG_ADDITIVE);
pos[1] += 24;
drawstring(pos, txt3, [20,20], col2, 1.0f,
DRAWFLAG_ADDITIVE);
pos[1] += 24;
drawstring(pos, txt4, [20,20], col3, 1.0f,
DRAWFLAG_ADDITIVE);
return;
}
pos = video_mins + (video_res / 2) + [-15,-15];
drawsubpic(
pos,
[31,31],
"sprites/crosshairs.spr_0.tga",
[116/256,1/128],
[31/256, 31/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
HUD_DrawAmmo2();
#endif
}
void
w_beamgun_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_beamgun0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_beamgun_precache(void)
{
precache_model("models/v_beam.mdl");
#ifdef SSQC
clientstat(46, EV_INTEGER, player::beam_range);
clientstat(47, EV_INTEGER, player::beam_poweracc);
clientstat(48, EV_INTEGER, player::beam_lightning);
#endif
}
weapon_t w_beamgun =
{
.id = ITEM_BEAMGUN,
.slot = 3,
.slot_pos = 0,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_beamgun_draw,
.holster = w_beamgun_holster,
.primary = w_beamgun_primary,
.secondary = w_beamgun_secondary,
.reload = __NULL__,
.release = w_beamgun_release,
.crosshair = w_beamgun_hud,
.precache = w_beamgun_precache,
.pickup = __NULL__,
.updateammo = w_beamgun_updateammo,
.wmodel = w_beamgun_wmodel,
.pmodel = w_beamgun_pmodel,
.deathmsg = w_beamgun_deathmsg,
.aimanim = w_beamgun_aimanim,
.hudpic = w_beamgun_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_beamgun(void)
{
Weapons_InitItem(WEAPON_BEAMGUN);
}
#endif
#ifdef CSQC
int
w_beamgun_hudforward(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case 1:
sendevent("w_beamgun_range", "i", 1i);
break;
case 2:
sendevent("w_beamgun_power", "i", 1i);
break;
case 3:
sendevent("w_beamgun_light", "i", 1i);
break;
}
return FALSE;
}
int
w_beamgun_hudback(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case 1:
sendevent("w_beamgun_range", "i", -1i);
break;
case 2:
sendevent("w_beamgun_power", "i", -1i);
break;
case 3:
sendevent("w_beamgun_light", "i", -1i);
break;
}
return FALSE;
}
#else
void
CSEv_w_beamgun_range_i(int f)
{
player pl = (player)self;
pl.beam_range = bound(0, pl.beam_range + f, 3);
}
void
CSEv_w_beamgun_power_i(int f)
{
player pl = (player)self;
pl.beam_poweracc = bound(0, pl.beam_poweracc + f, 3);
}
void
CSEv_w_beamgun_light_i(int f)
{
player pl = (player)self;
pl.beam_lightning = bound(0, pl.beam_lightning + f, 2);
}
#endif

View file

@ -1,2 +1,468 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_chemicalgun = {};
enum {
CHEMGUN_DRAW, // 1.2f
CHEMGUN_HOLSTER, // 1.2f
CHEMGUN_IDLE, // 2.08f
CHEMGUN_FIDGET, // 2.08f
CHEMGUN_CONFIG, // 2.08f
CHEMGUN_SHOOT // 0.535714
};
void
w_chemicalgun_draw(void)
{
Weapons_SetModel("models/v_chemgun.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(CHEMGUN_DRAW);
}
void
w_chemicalgun_holster(void)
{
}
void
w_chemicalgun_primary(void)
{
vector src;
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
if (pl.a_ammo1 > 0) {
pl.a_ammo1 = 0;
pl.flags &= ~FL_SEMI_TOGGLED;
Weapons_ViewAnimation(CHEMGUN_CONFIG);
pl.w_attack_next = 2.08f;
pl.w_idle_next = pl.w_attack_next;
return;
}
if (pl.w_attack_next) {
return;
}
src = Weapons_GetCameraPos();
#ifdef CSQC
//Weapons_ViewAnimation(GP_FIRESINGLE);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 2.5f;
}
void
w_chemicalgun_secondary(void)
{
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
pl.flags &= ~FL_SEMI_TOGGLED;
if (pl.w_attack_next) {
return;
}
/* activate menu */
if (pl.a_ammo1 <= 0 || pl.a_ammo1 == 4) {
pl.a_ammo1 = 1;
} else {
pl.a_ammo1 = bound(1, pl.a_ammo1 + 1, 4);
}
}
void
w_chemicalgun_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(CHEMGUN_IDLE);
pl.w_idle_next = 2.08f;
}
void
w_chemicalgun_updateammo(player pl)
{
}
string
w_chemicalgun_wmodel(void)
{
return "";
}
string
w_chemicalgun_pmodel(void)
{
return "";
}
string
w_chemicalgun_deathmsg(void)
{
return "";
}
float
w_chemicalgun_aimanim(void)
{
return 0;
}
int
w_chemicalgun_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.chem_acid = 5;
pl.chem_neutral = 2;
pl.chem_base = 4;
pl.chem_pressure = 3;
}
if (pl.ammo_chem < 50) {
pl.ammo_chem = bound(0, pl.ammo_chem + 10, 50);
} else {
return FALSE;
}
#endif
return TRUE;
}
#ifdef CSQC
void
w_chemgun_drawvial(vector pos, int length, vector col)
{
int i;
vector npos;
const string parts[] = {
"sprites/vial_el.spr_0.tga",
"sprites/vial_ec.spr_0.tga",
"sprites/vial_ec.spr_0.tga",
"sprites/vial_ec.spr_0.tga",
"sprites/vial_er.spr_0.tga"
};
pos[0] += 96;
npos = pos;
/* empty */
for (i = 0; i < 5; i++) {
if (i >= length) {
drawpic(
pos,
parts[i],
[32,32],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
}
pos[0] += 32;
}
/* full */
for (i = 0; i < length; i++) {
drawpic(
npos,
parts[i],
[32,32],
col,
1.0f,
DRAWFLAG_ADDITIVE
);
npos[0] += 32;
}
}
void
w_chemgun_drawpressure(vector pos, int length, vector col)
{
int i;
const string parts[] = {
"sprites/hud_pntr.spr_0.tga",
"sprites/vial_ec.spr_0.tga",
"sprites/vial_ec.spr_0.tga",
"sprites/vial_ec.spr_0.tga",
"sprites/vial_er.spr_0.tga"
};
pos[0] += 96;
/* full */
for (i = 0; i < 5; i++) {
if (i == length) {
drawpic(
pos,
"sprites/hud_pntr.spr_0.tga",
[32,32],
col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawpic(
pos,
"sprites/hud_rule.spr_0.tga",
[32,32],
col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
pos[0] += 32;
}
}
#endif
void
w_chemicalgun_hud(void)
{
#ifdef CSQC
vector pos;
player pl = (player)self;
pos = video_mins + [video_res[0] - 125, video_res[1] - 42];
for (int i = 0; i < 3; i++) {
drawpic(
pos,
"gfx/vgui/640_ammo_chem.tga",
[32,16],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
pos[1] += 8;
}
HUD_DrawAmmo2();
/* menu */
if (pl.a_ammo1 > 0) {
vector col1, col2, col3, col4;
string txt1, txt2, txt3, txt4;
col1 = col2 = col3 = col4 = [1,1,1];
switch (pl.a_ammo1) {
case 1:
col1 = [0,1,0];
break;
case 2:
col2 = [0,1,0];
break;
case 3:
col3 = [0,1,0];
break;
case 4:
col4 = [0,1,0];
break;
}
txt1 = "ACID:";
txt2 = "NEUTRAL:";
txt3 = "BASE:";
txt4 = "PRESSURE:";
pos = video_mins + (video_res / 2) + [-128,-96];
drawfont = FONT_20;
drawstring(pos + [0,8], txt1, [20,20], col1, 1.0f,
DRAWFLAG_ADDITIVE);
w_chemgun_drawvial(pos, getstati(51), [0,1,0]);
pos[1] += 48;
drawstring(pos + [0,8], txt2, [20,20], col2, 1.0f,
DRAWFLAG_ADDITIVE);
w_chemgun_drawvial(pos, getstati(52), [0.25,0.25,1]);
pos[1] += 48;
drawstring(pos + [0,8], txt3, [20,20], col3, 1.0f,
DRAWFLAG_ADDITIVE);
w_chemgun_drawvial(pos, getstati(53), [1,0,0]);
pos[1] += 48;
drawstring(pos + [0,8], txt4, [20,20], col4, 1.0f,
DRAWFLAG_ADDITIVE);
w_chemgun_drawpressure(pos, getstati(54), [1,0.5,0.25]);
return;
}
#endif
}
void
w_chemicalgun_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_SPchemicalgun0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_chemicalgun_precache(void)
{
precache_model("models/v_chemgun.mdl");
/* empty */
precache_model("sprites/vial_el.spr"); /* 32x32 */
precache_model("sprites/vial_ec.spr");
precache_model("sprites/vial_er.spr");
/* full */
precache_model("sprites/vial_fl.spr");
precache_model("sprites/vial_fc.spr");
precache_model("sprites/vial_fr.spr");
precache_model("sprites/hud_pntr.spr");
precache_model("sprites/hud_rule.spr");
#ifdef SSQC
clientstat(51, EV_INTEGER, player::chem_acid);
clientstat(52, EV_INTEGER, player::chem_neutral);
clientstat(53, EV_INTEGER, player::chem_base);
clientstat(54, EV_INTEGER, player::chem_pressure);
#endif
}
weapon_t w_chemicalgun =
{
.id = ITEM_CHEMICALGUN,
.slot = 4,
.slot_pos = 1,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_chemicalgun_draw,
.holster = w_chemicalgun_holster,
.primary = w_chemicalgun_primary,
.secondary = w_chemicalgun_secondary,
.reload = __NULL__,
.release = w_chemicalgun_release,
.crosshair = w_chemicalgun_hud,
.precache = w_chemicalgun_precache,
.pickup = w_chemicalgun_pickup,
.updateammo = w_chemicalgun_updateammo,
.wmodel = w_chemicalgun_wmodel,
.pmodel = w_chemicalgun_pmodel,
.deathmsg = w_chemicalgun_deathmsg,
.aimanim = w_chemicalgun_aimanim,
.hudpic = w_chemicalgun_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_chemgun(void)
{
Weapons_InitItem(WEAPON_CHEMICALGUN);
}
#endif
#ifdef CSQC
int
w_chemgun_hudforward(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case 1:
sendevent("w_chem_a", "i", 1i);
break;
case 2:
sendevent("w_chem_n", "i", 1i);
break;
case 3:
sendevent("w_chem_b", "i", 1i);
break;
case 4:
sendevent("w_chem_p", "i", 1i);
break;
}
return FALSE;
}
int
w_chemgun_hudback(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case 1:
sendevent("w_chem_a", "i", -1i);
break;
case 2:
sendevent("w_chem_n", "i", -1i);
break;
case 3:
sendevent("w_chem_b", "i", -1i);
break;
case 4:
sendevent("w_chem_p", "i", -1i);
break;
}
return FALSE;
}
#else
void
CSEv_w_chem_a_i(int f)
{
player pl = (player)self;
pl.chem_acid = bound(0, pl.chem_acid + f, 5);
}
void
CSEv_w_chem_n_i(int f)
{
player pl = (player)self;
pl.chem_neutral = bound(0, pl.chem_neutral + f, 5);
}
void
CSEv_w_chem_b_i(int f)
{
player pl = (player)self;
pl.chem_base = bound(0, pl.chem_base + f, 5);
}
void
CSEv_w_chem_p_i(int f)
{
player pl = (player)self;
pl.chem_pressure = bound(0, pl.chem_pressure + f, 4);
}
#endif

View file

@ -1,2 +1,476 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_dml = {};
/* the rocket launcher */
enum {
DML_IDLE, // 2.5f
DML_FIDGET, // 2.0f
DML_RELOADBOTH, // 1.6f
DML_RELOADLEFT, // 1.6f
DML_RELOADRIGHT, // 1.6f
DML_FIRE, // 1.222222f
DML_CUSTOMIZE, // 4.0f
DML_DRAW // 1.222222f
};
enum {
DS_FULL,
DS_RELOADING
};
enum {
DMENU_NONE,
DMENU_LAUNCH,
DMENU_FLIGHTPATH,
DMENU_DETONATE,
DMENU_PAYLOAD
};
/* customizable states */
enum {
LAUNCH_FIRED,
LAUNCH_TARGETED
};
enum {
FLIGHTPATH_GUIDED,
FLIGHTPATH_HOMING,
FLIGHTPATH_SPIRAL
} ;
enum {
DETONATE_IMPACT,
DETONATE_PROXIMITY,
DETONATE_TIMED,
DETONATE_TRIPPED
};
enum {
PAYLOAD_EXPLOSIVE,
PAYLOAD_CLUSTER
};
/* functions */
void
w_dml_draw(void)
{
Weapons_SetModel("models/v_dml.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(DML_DRAW);
}
void
w_dml_holster(void)
{
}
void
w_dml_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
if (pl.a_ammo3 == DS_RELOADING) {
if (pl.a_ammo1 == 1) {
Weapons_ViewAnimation(DML_RELOADRIGHT);
} else {
Weapons_ViewAnimation(DML_RELOADLEFT);
}
sound(pl, CHAN_WEAPON, "weapons/dml_reload.wav", 1.0f, ATTN_NORM);
pl.w_attack_next = 1.6f;
pl.w_idle_next = pl.w_attack_next;
pl.a_ammo3 = DS_FULL;
return;
}
int r = (float)input_sequence % 5;
switch (r) {
case 0:
case 1:
case 2:
case 3:
Weapons_ViewAnimation(DML_IDLE);
pl.w_idle_next = 10.0f;
break;
default:
Weapons_ViewAnimation(DML_FIDGET);
pl.w_idle_next = 2.0f;
}
}
void
w_dml_primary(void)
{
vector src;
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
if (pl.a_ammo1 > 0) {
pl.a_ammo1 = 0;
pl.flags &= ~FL_SEMI_TOGGLED;
Weapons_ViewAnimation(DML_CUSTOMIZE);
sound(pl, 8, "weapons/dml_customize.wav", 1.0f, ATTN_NORM);
pl.w_attack_next = 4.0f;
pl.w_idle_next = 5.0f;
return;
}
if (pl.w_attack_next) {
return;
}
if (pl.a_ammo3 == DS_RELOADING) {
w_dml_release();
return;
}
src = Weapons_GetCameraPos();
#ifdef SSQC
sound(pl, CHAN_WEAPON, "weapons/dml_fire.wav", 1.0f, ATTN_NORM);
#endif
Weapons_ViewAnimation(DML_FIRE);
pl.w_attack_next = 1.222222f;
pl.w_idle_next = 1.222222f;
pl.a_ammo3 = DS_RELOADING;
}
void
w_dml_secondary(void)
{
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
pl.flags &= ~FL_SEMI_TOGGLED;
if (pl.w_attack_next) {
return;
}
/* activate menu */
if (pl.a_ammo1 <= 0 || pl.a_ammo1 == DMENU_PAYLOAD) {
pl.a_ammo1 = 1;
} else {
pl.a_ammo1 = bound(DMENU_LAUNCH, pl.a_ammo1 + 1, DMENU_PAYLOAD);
}
}
void
w_dml_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_rockets, -1);
#endif
}
string
w_dml_wmodel(void)
{
return "";
}
string
w_dml_pmodel(void)
{
return "";
}
string
w_dml_deathmsg(void)
{
return "";
}
float
w_dml_aimanim(void)
{
return 0;
}
int
w_dml_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (pl.ammo_rocket < 100) {
pl.ammo_rocket = bound(0, pl.ammo_rocket + 2, 100);
} else {
return FALSE;
}
#endif
return TRUE;
}
void
w_dml_hud(void)
{
#ifdef CSQC
static string lmodes[] = {
"WHEN FIRED",
"WHEN TARGETED"
};
static string fmodes[] = {
"GUIDED",
"HOMING",
"SPIRAL"
};
static string dmodes[] = {
"ON IMPACT",
"IN PROXIMITY",
"TIMED",
"WHEN TRIPPED"
};
static string pmodes[] = {
"EXPLOSIVE",
"CLUSTER"
};
vector pos;
vector jitter;
float lerp;
player pl = (player)self;
/* laser */
Weapons_MakeVectors();
vector src = Weapons_GetCameraPos();
traceline(src, src + (v_forward * 256), FALSE, pl);
lerp = Math_Lerp(18,6, trace_fraction);
jitter[0] = (random(0,2) - 2) * (1 - trace_fraction);
jitter[1] = (random(0,2) - 2) * (1 - trace_fraction);
pos = (video_res / 2) + ([-lerp,-lerp] / 2);
drawsubpic(
pos + jitter,
[lerp,lerp],
"sprites/laserdot.spr_0.tga",
[0,0],
[1.0, 1.0],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
/* menu */
if (pl.a_ammo1 > 0) {
vector col1, col2, col3, col4;
string txt1, txt2, txt3, txt4;
col1 = col2 = col3 = col4 = [1,1,1];
switch (pl.a_ammo1) {
case DMENU_LAUNCH:
col1 = [0,1,0];
break;
case DMENU_FLIGHTPATH:
col2 = [0,1,0];
break;
case DMENU_DETONATE:
col3 = [0,1,0];
break;
case DMENU_PAYLOAD:
col4 = [0,1,0];
break;
}
txt1 = sprintf("LAUNCH: %s", lmodes[getstati(42)]);
txt2 = sprintf("FLIGHTPATH: %s", fmodes[getstati(43)]);
txt3 = sprintf("DETONATE: %s", dmodes[getstati(44)]);
txt4 = sprintf("PAYLOAD: %s", pmodes[getstati(45)]);
pos = video_mins + (video_res / 2) + [-80,-48];
drawfont = FONT_20;
drawstring(pos, txt1, [20,20], col1, 1.0f,
DRAWFLAG_ADDITIVE);
pos[1] += 24;
drawstring(pos, txt2, [20,20], col2, 1.0f,
DRAWFLAG_ADDITIVE);
pos[1] += 24;
drawstring(pos, txt3, [20,20], col3, 1.0f,
DRAWFLAG_ADDITIVE);
pos[1] += 24;
drawstring(pos, txt4, [20,20], col4, 1.0f,
DRAWFLAG_ADDITIVE);
return;
}
pos = video_mins + (video_res / 2) + [-32,-15];
drawsubpic(
pos,
[63,31],
"sprites/crosshairs.spr_0.tga",
[149/256,1/128],
[63/256, 31/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
HUD_DrawAmmo2();
#endif
}
void
w_dml_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_dml0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_dml_precache(void)
{
precache_model("models/v_dml.mdl");
precache_model("sprites/laserdot.spr");
precache_sound("weapons/dml_reload.wav");
precache_sound("weapons/dml_customize.wav");
precache_sound("weapons/dml_fire.wav");
#ifdef SSQC
clientstat(42, EV_INTEGER, player::dml_launch);
clientstat(43, EV_INTEGER, player::dml_flightpath);
clientstat(44, EV_INTEGER, player::dml_detonate);
clientstat(45, EV_INTEGER, player::dml_payload);
#endif
}
weapon_t w_dml =
{
.id = ITEM_DML,
.slot = 3,
.slot_pos = 1,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_dml_draw,
.holster = w_dml_holster,
.primary = w_dml_primary,
.secondary = w_dml_secondary,
.reload = __NULL__,
.release = w_dml_release,
.crosshair = w_dml_hud,
.precache = w_dml_precache,
.pickup = w_dml_pickup,
.updateammo = w_dml_updateammo,
.wmodel = w_dml_wmodel,
.pmodel = w_dml_pmodel,
.deathmsg = w_dml_deathmsg,
.aimanim = w_dml_aimanim,
.hudpic = w_dml_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_dml(void)
{
Weapons_InitItem(WEAPON_DML);
}
#endif
#ifdef CSQC
int
w_dml_hudforward(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case DMENU_LAUNCH:
sendevent("w_dml_launch", "i", 1i);
break;
case DMENU_FLIGHTPATH:
sendevent("w_dml_path", "i", 1i);
break;
case DMENU_DETONATE:
sendevent("w_dml_det", "i", 1i);
break;
case DMENU_PAYLOAD:
sendevent("w_dml_pay", "i", 1i);
break;
}
return FALSE;
}
int
w_dml_hudback(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case DMENU_LAUNCH:
sendevent("w_dml_launch", "i", -1i);
break;
case DMENU_FLIGHTPATH:
sendevent("w_dml_path", "i", -1i);
break;
case DMENU_DETONATE:
sendevent("w_dml_det", "i", -1i);
break;
case DMENU_PAYLOAD:
sendevent("w_dml_pay", "i", -1i);
break;
}
return FALSE;
}
#else
void
CSEv_w_dml_launch_i(int f)
{
player pl = (player)self;
pl.dml_launch = bound(0, pl.dml_launch + f, 1);
}
void
CSEv_w_dml_path_i(int f)
{
player pl = (player)self;
pl.dml_flightpath = bound(0, pl.dml_flightpath + f, 2);
}
void
CSEv_w_dml_det_i(int f)
{
player pl = (player)self;
pl.dml_detonate = bound(0, pl.dml_detonate + f, 3);
}
void
CSEv_w_dml_pay_i(int f)
{
player pl = (player)self;
pl.dml_payload = bound(0, pl.dml_payload + f, 1);
}
#endif

View file

@ -1,2 +1,324 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_fists = {};
enum {
FISTS_IDLE, // 2.0f
FISTS_FIDGET1, // 3.0f
FISTS_FIDGET2, // 2.333333f
FISTS_RIGHT, // 0.419355f
FISTS_LEFT, // 0.419355f
FISTS_DOUBLE, // 0.739130f
FISTS_DRAW, // 1.4f
FISTS_HOLSTER, // 0.7f
KNIFE_DRAW, // 0.75f
KNIFE_HOLSTER, // 0.75f
KNIFE_IDLE, // 2.0f
KNIFE_FIDGET, // 2.0f
KNIFE_ATTACK1, // 0.789474f
KNIFE_ATTACK2, // 0.421053f
HANDS_PUSHBUTTON, // 8.0f
};
enum {
HS_KNIFE,
HS_KNIFE_TO_FISTS,
HS_FISTS,
HS_FISTS_TO_KNIFE
};
void
w_fists_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, -1, pl.fist_mode);
#endif
}
void
w_fists_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_hands.mdl");
Weapons_SetGeomset("geomset 1 2\n");
Weapons_ViewAnimation(KNIFE_DRAW);
sound(pl, CHAN_WEAPON, "weapons/KnifeDraw.wav", 1.0f, ATTN_NORM);
}
void
w_fists_holster(void)
{
Weapons_ViewAnimation(KNIFE_HOLSTER);
}
void
w_fists_release(void)
{
int r;
player pl = (player)self;
if (pl.w_idle_next) {
return;
}
if (pl.a_ammo3 == HS_FISTS_TO_KNIFE) {
Weapons_ViewAnimation(KNIFE_DRAW);
Weapons_SetGeomset("geomset 1 2\n");
sound(pl, CHAN_WEAPON, "weapons/KnifeDraw.wav", 1.0f, ATTN_NORM);
pl.a_ammo3 = HS_KNIFE;
pl.w_attack_next = 0.75f;
pl.w_idle_next = pl.w_attack_next;
return;
} else if (pl.a_ammo3 == HS_KNIFE_TO_FISTS) {
Weapons_ViewAnimation(FISTS_DRAW);
Weapons_SetGeomset("geomset 1 1\n");
pl.a_ammo3 = HS_FISTS;
pl.w_attack_next = 1.4f;
pl.w_idle_next = pl.w_attack_next;
return;
}
if (pl.a_ammo3 == HS_KNIFE) {
r = (float)input_sequence % 5;
switch (r) {
case 0:
case 1:
case 2:
case 3:
Weapons_ViewAnimation(KNIFE_IDLE);
pl.w_idle_next = 10.0f;
break;
default:
Weapons_ViewAnimation(KNIFE_FIDGET);
pl.w_idle_next = 2.0f;
}
} else {
r = (float)input_sequence % 5;
switch (r) {
case 0:
case 1:
case 2:
Weapons_ViewAnimation(FISTS_IDLE);
pl.w_idle_next = 10.0f;
break;
case 3:
Weapons_ViewAnimation(FISTS_FIDGET1);
pl.w_idle_next = 3.0f;
break;
default:
Weapons_ViewAnimation(FISTS_FIDGET2);
pl.w_idle_next = 2.333333f;
}
}
}
void
w_fists_leftsound(void)
{
player pl = (player)self;
int r;
r = (float)input_sequence % 3;
switch (r) {
case 0:
sound(pl, CHAN_WEAPON, "weapons/LeftPunch.wav", 1.0f, ATTN_NORM);
break;
case 1:
sound(pl, CHAN_WEAPON, "weapons/LeftPunch2.wav", 1.0f, ATTN_NORM);
break;
default:
sound(pl, CHAN_WEAPON, "weapons/LeftPunch3.wav", 1.0f, ATTN_NORM);
}
}
void
w_fists_rightsound(void)
{
player pl = (player)self;
int r;
r = (float)input_sequence % 3;
switch (r) {
case 0:
sound(pl, CHAN_WEAPON, "weapons/RightPunch.wav", 1.0f, ATTN_NORM);
break;
case 1:
sound(pl, CHAN_WEAPON, "weapons/RightPunch2.wav", 1.0f, ATTN_NORM);
break;
default:
sound(pl, CHAN_WEAPON, "weapons/RightPunch3.wav", 1.0f, ATTN_NORM);
}
}
void
w_fists_misssound(void)
{
player pl = (player)self;
int r;
r = (float)input_sequence % 2;
switch (r) {
case 0:
sound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1.0f, ATTN_NORM);
break;
default:
sound(pl, CHAN_WEAPON, "weapons/cbar_miss2.wav", 1.0f, ATTN_NORM);
}
}
void
w_fists_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
pl.a_ammo1 = 1 - pl.a_ammo1;
w_fists_misssound();
if (pl.a_ammo3 == HS_KNIFE) {
if (pl.a_ammo1 == 1) {
Weapons_ViewAnimation(KNIFE_ATTACK1);
} else {
Weapons_ViewAnimation(KNIFE_ATTACK2);
}
pl.w_attack_next = 0.5f;
pl.w_idle_next = pl.w_attack_next;
} else {
if (pl.a_ammo1 == 1) {
Weapons_ViewAnimation(FISTS_RIGHT);
} else {
Weapons_ViewAnimation(FISTS_LEFT);
}
pl.w_attack_next = 0.25f;
pl.w_idle_next = pl.w_attack_next;
}
}
void
w_fists_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
w_fists_release();
return;
}
if (pl.a_ammo3 == HS_KNIFE) {
Weapons_ViewAnimation(KNIFE_HOLSTER);
pl.a_ammo3 = HS_KNIFE_TO_FISTS;
pl.w_attack_next = 0.75f;
pl.w_idle_next = pl.w_attack_next;
} else if (pl.a_ammo3 == HS_FISTS) {
Weapons_ViewAnimation(FISTS_HOLSTER);
pl.a_ammo3 = HS_FISTS_TO_KNIFE;
pl.w_attack_next = 0.7f;
pl.w_idle_next = pl.w_attack_next;
}
}
string
w_fists_wmodel(void)
{
return "";
}
string
w_fists_pmodel(void)
{
return "";
}
string
w_fists_deathmsg(void)
{
return "%s killed %s with his knife.";
}
float
w_fists_aimanim(void)
{
return 0;
}
int
w_fists_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (pl.ammo_minigun < 100) {
pl.ammo_minigun = bound(0, pl.ammo_minigun + 30, 100);
} else {
return FALSE;
}
#endif
return TRUE;
}
void
w_fists_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_fists0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_fists_precache(void)
{
precache_model("models/v_hands.mdl");
precache_sound("weapons/KnifeDraw.wav");
precache_sound("weapons/LeftPunch.wav");
precache_sound("weapons/LeftPunch2.wav");
precache_sound("weapons/LeftPunch3.wav");
precache_sound("weapons/RightPunch.wav");
precache_sound("weapons/RightPunch2.wav");
precache_sound("weapons/RightPunch3.wav");
precache_sound("weapons/cbar_miss1.wav");
precache_sound("weapons/cbar_miss2.wav");
}
weapon_t w_fists =
{
.id = ITEM_FISTS,
.slot = 0,
.slot_pos = 0,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_fists_draw,
.holster = w_fists_holster,
.primary = w_fists_primary,
.secondary = w_fists_secondary,
.reload = __NULL__,
.release = w_fists_release,
.crosshair = __NULL__,
.precache = w_fists_precache,
.pickup = __NULL__,
.updateammo = w_fists_updateammo,
.wmodel = __NULL__,
.pmodel = __NULL__,
.deathmsg = w_fists_deathmsg,
.aimanim = w_fists_aimanim,
.hudpic = w_fists_hudpic
};

View file

@ -1,2 +1,426 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_gausspistol = {};
enum {
GP_IDLE1, // 3.75f
GP_IDLE2, // 3.0f
GP_FIRESINGLE, // 0.727273f
GP_FIREFAST, // 0.2f
GP_FIRECHARGE, // 3.0f
GP_DRAW, // 1.071429f
GP_HOLSTER, // 0.9375f
SNIPER_IDLE1, // 3.0f
SNIPER_IDLE2, // 3.0f
SNIPER_FIDGET, // 3.0f
SNIPER_SHOOT, // 0.357143
SNIPER_DRAW, // 0.937500
SNIPER_HOLSTER // 1.666667f
};
enum {
GM_SINGLE,
GM_CHARGE,
GM_FAST,
GM_SNIPER
};
void
w_gausspistol_draw(void)
{
Weapons_SetModel("models/v_guasspistol.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(GP_DRAW);
}
void
w_gausspistol_holster(void)
{
Weapons_ViewAnimation(GP_HOLSTER);
}
void
w_gausspistol_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
int r = (float)input_sequence % 5;
switch (r) {
case 0:
case 1:
case 2:
case 3:
Weapons_ViewAnimation(GP_IDLE1);
pl.w_idle_next = 3.75f;
break;
default:
Weapons_ViewAnimation(GP_IDLE2);
pl.w_idle_next = 3.0f;
}
}
void
w_gausspistol_primary(void)
{
vector src;
int take = 1;
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
if (pl.a_ammo1 > 0) {
pl.a_ammo1 = 0;
pl.flags &= ~FL_SEMI_TOGGLED;
return;
}
if (pl.w_attack_next > 0) {
return;
}
/* ammo check */
if (pl.a_ammo2 <= 0) {
return;
}
if (pl.a_ammo3 == GM_CHARGE && pl.a_ammo2 < 10) {
return;
}
switch (pl.a_ammo3) {
case GM_FAST:
Weapons_ViewAnimation(GP_FIREFAST);
#ifdef SSQC
sound(self, CHAN_WEAPON, "weapons/gauss_fire4.wav", 1, ATTN_NORM);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 2.5f;
break;
case GM_CHARGE:
take = 10;
Weapons_ViewAnimation(GP_FIRECHARGE);
#ifdef SSQC
sound(self, CHAN_WEAPON, "weapons/gauss_fire2.wav", 1, ATTN_NORM);
sound(self, 8, "weapons/gauss_charge.wav", 1, ATTN_NORM);
#endif
pl.w_attack_next = 2.0f;
pl.w_idle_next = 5.0f;
break;
default:
pl.flags &= ~FL_SEMI_TOGGLED;
Weapons_ViewAnimation(GP_FIRESINGLE);
#ifdef SSQC
sound(self, CHAN_WEAPON, "weapons/gauss_fire1.wav", 1, ATTN_NORM);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 2.5f;
break;
}
src = Weapons_GetCameraPos();
#ifdef SSQC
pl.ammo_gauss -= take;
#else
pl.a_ammo2 -= take;
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-5,0,0]);
#endif
}
void
w_gausspistol_secondary(void)
{
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
pl.flags &= ~FL_SEMI_TOGGLED;
/* activate menu */
pl.a_ammo1 = 1;
w_gausspistol_release();
}
void
w_gausspistol_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_gauss, pl.gauss_mode);
#endif
}
string
w_gausspistol_wmodel(void)
{
return "models/w_gauss.mdl";
}
string
w_gausspistol_pmodel(void)
{
return "models/p_gauss.mdl";
}
string
w_gausspistol_deathmsg(void)
{
return "%s kills %s with his Gauss-Pistol";
}
float
w_gausspistol_aimanim(void)
{
return 0;
}
int
w_gausspistol_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (pl.ammo_gauss < 150) {
pl.ammo_gauss = bound(0, pl.ammo_gauss + 35, 150);
} else {
return FALSE;
}
#endif
return TRUE;
}
void
w_gausspistol_hud(void)
{
#ifdef CSQC
vector pos;
player pl = (player)self;
pos = video_mins + [video_res[0] - 125, video_res[1] - 42];
for (int i = 0; i < 3; i++) {
drawpic(
pos,
"gfx/vgui/640_ammo_gauss.tga",
[32,16],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
pos[1] += 8;
}
HUD_DrawAmmo2();
/* menu */
if (pl.a_ammo1 > 0) {
pos = video_mins + (video_res / 2) + [-96,-72];
/* far left */
if (pl.a_ammo3 == GM_SINGLE) {
drawsubpic(
pos,
[64,144],
"sprites/gausshud2.spr_0.tga",
[0/192,0/144],
[64/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos + [64,0],
[128,144],
"sprites/gausshud1.spr_0.tga",
[64/192,0/144],
[128/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
}
if (pl.a_ammo3 == GM_CHARGE) {
drawsubpic(
pos,
[64,144],
"sprites/gausshud1.spr_0.tga",
[0/192,0/144],
[64/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos + [64,0],
[64,144],
"sprites/gausshud2.spr_0.tga",
[64/192,0/144],
[64/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos + [128,0],
[64,144],
"sprites/gausshud1.spr_0.tga",
[128/192,0/144],
[64/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
}
if (pl.a_ammo3 == GM_FAST) {
drawsubpic(
pos,
[128,144],
"sprites/gausshud1.spr_0.tga",
[0/192,0/144],
[128/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos + [128,0],
[64,144],
"sprites/gausshud2.spr_0.tga",
[128/192,0/144],
[64/192, 144/144],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
}
return;
}
pos = video_mins + (video_res / 2) + [-15,-15];
drawsubpic(
pos,
[31,31],
"sprites/crosshairs.spr_0.tga",
[1/256,1/128],
[31/256, 31/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_gausspistol_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_gaussPistol0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_gausspistol_precache(void)
{
precache_model("models/v_guasspistol.mdl");
precache_model("sprites/gausshud1.spr");
precache_model("sprites/gausshud2.spr");
precache_sound("weapons/gauss_fire4.wav");
precache_sound("weapons/gauss_fire2.wav");
precache_sound("weapons/gauss_fire1.wav");
precache_sound("weapons/gauss_charge.wav");
}
weapon_t w_gausspistol =
{
.id = ITEM_GAUSSPISTOL,
.slot = 1,
.slot_pos = 0,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_gausspistol_draw,
.holster = w_gausspistol_holster,
.primary = w_gausspistol_primary,
.secondary = w_gausspistol_secondary,
.reload = __NULL__,
.release = w_gausspistol_release,
.crosshair = w_gausspistol_hud,
.precache = w_gausspistol_precache,
.pickup = w_gausspistol_pickup,
.updateammo = w_gausspistol_updateammo,
.wmodel = w_gausspistol_wmodel,
.pmodel = w_gausspistol_pmodel,
.deathmsg = w_gausspistol_deathmsg,
.aimanim = w_gausspistol_aimanim,
.hudpic = w_gausspistol_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_gausspistol(void)
{
Weapons_InitItem(WEAPON_GAUSSPISTOL);
}
#endif
#ifdef CSQC
int
w_gausspistol_hudforward(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
pl.a_ammo3 = bound(GM_SINGLE, pl.a_ammo3 - 1, GM_FAST);
sendevent("w_gp_setmode", "i", pl.a_ammo3);
return FALSE;
}
int
w_gausspistol_hudback(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
pl.a_ammo3 = bound(GM_SINGLE, pl.a_ammo3 + 1, GM_FAST);
sendevent("w_gp_setmode", "i", pl.a_ammo3);
return FALSE;
}
#else
void CSEv_w_gp_setmode_i(int f)
{
player pl = (player)self;
pl.a_ammo3 = f;
pl.gauss_mode = f;
}
#endif

View file

@ -0,0 +1,304 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
enum {
GREN_IDLE1, // 2.0f
GREN_IDLE2, // 2.0f
GREN_FIDGET, // 1.2f
GREN_RELOAD, // 1.6f
GREN_ARM, // 1.2f
GREN_THROW, // 0.5f
GREN_TRIPMINE, // 1.33333f
GREN_DRAW // 0.588235f
};
void
w_grenade_draw(void)
{
Weapons_SetModel("models/v_grenade.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(GREN_DRAW);
}
void
w_grenade_holster(void)
{
}
void
w_grenade_primary(void)
{
vector src;
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
if (pl.a_ammo1 > 0) {
pl.a_ammo1 = 0;
pl.flags &= ~FL_SEMI_TOGGLED;
Weapons_ViewAnimation(GREN_FIDGET);
pl.w_attack_next = 1.2f;
pl.w_idle_next = pl.w_attack_next;
return;
}
if (pl.w_attack_next) {
return;
}
src = Weapons_GetCameraPos();
#ifdef CSQC
//Weapons_ViewAnimation(GP_FIRESINGLE);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 2.5f;
}
void
w_grenade_secondary(void)
{
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
pl.flags &= ~FL_SEMI_TOGGLED;
if (pl.w_attack_next) {
return;
}
/* activate menu */
if (pl.a_ammo1 <= 0) {
pl.a_ammo1 = 1;
} else {
if (pl.a_ammo1 == 1) {
pl.a_ammo1 = 2;
} else {
pl.a_ammo1 = 1;
}
}
}
void
w_grenade_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(GREN_IDLE1);
pl.w_idle_next = 1.777778f;
}
void
w_grenade_updateammo(player pl)
{
}
string
w_grenade_wmodel(void)
{
return "";
}
string
w_grenade_pmodel(void)
{
return "";
}
string
w_grenade_deathmsg(void)
{
return "";
}
float
w_grenade_aimanim(void)
{
return 0;
}
void
w_grenade_hud(void)
{
#ifdef CSQC
vector pos;
player pl = (player)self;
static string dmodes[] = {
"WHEN TRIPPED",
"TIMED",
"ON IMPACT"
};
static string pmodes[] = {
"CLUSTER",
"EXPLOSIVE"
};
HUD_DrawAmmo2();
/* menu */
if (pl.a_ammo1 > 0) {
vector col1, col2;
string txt1, txt2;
col1 = col2 = [1,1,1];
switch (pl.a_ammo1) {
case 1:
col1 = [0,1,0];
break;
case 2:
col2 = [0,1,0];
break;
}
txt1 = sprintf("DETONATE: %s", dmodes[getstati(49)]);
txt2 = sprintf("PAYLOAD: %s", pmodes[getstati(50)]);
pos = video_mins + (video_res / 2) + [-48,-16];
drawfont = FONT_20;
drawstring(pos, txt1, [20,20], col1, 1.0f,
DRAWFLAG_ADDITIVE);
drawstring(pos + [0,24], txt2, [20,20], col2, 1.0f,
DRAWFLAG_ADDITIVE);
return;
}
#endif
}
void
w_grenade_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_dmlGrenade0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_grenade_precache(void)
{
precache_model("models/v_grenade.mdl");
#ifdef SSQC
clientstat(49, EV_INTEGER, player::gren_detonate);
clientstat(50, EV_INTEGER, player::gren_payload);
#endif
}
weapon_t w_grenade =
{
.id = ITEM_GRENADE,
.slot = 4,
.slot_pos = 0,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_grenade_draw,
.holster = w_grenade_holster,
.primary = w_grenade_primary,
.secondary = w_grenade_secondary,
.reload = __NULL__,
.release = w_grenade_release,
.crosshair = w_grenade_hud,
.precache = w_grenade_precache,
.pickup = __NULL__,
.updateammo = w_grenade_updateammo,
.wmodel = w_grenade_wmodel,
.pmodel = w_grenade_pmodel,
.deathmsg = w_grenade_deathmsg,
.aimanim = w_grenade_aimanim,
.hudpic = w_grenade_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_grenade(void)
{
Weapons_InitItem(WEAPON_GRENADE);
}
#endif
#ifdef CSQC
int
w_grenade_hudforward(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case 1:
sendevent("w_gren_det", "i", 1i);
break;
case 2:
sendevent("w_gren_pay", "i", 1i);
break;
}
return FALSE;
}
int
w_grenade_hudback(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case 1:
sendevent("w_gren_det", "i", -1i);
break;
case 2:
sendevent("w_gren_pay", "i", -1i);
break;
}
return FALSE;
}
#else
void
CSEv_w_gren_det_i(int f)
{
player pl = (player)self;
pl.gren_detonate = bound(0, pl.gren_detonate + f, 2);
}
void
CSEv_w_gren_pay_i(int f)
{
player pl = (player)self;
pl.gren_payload = bound(0, pl.gren_payload + f, 1);
}
#endif

View file

@ -1,2 +1,306 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
weapon_t w_minigun = {};
enum {
MG_IDLE, // 2.0f
MG_FIDGET, // 2.6f
MG_FIRE, // 0.333333f
MG_SPINUP, // 2.0f
MG_FIRELOOP, // 0.666667f
MG_SPINDOWN, // 2.0f
MG_DRAW, // 1.5f
MG_IDLELOOP, // 0.666667f
MG_HOLSTER // 1.5f
};
void
w_minigun_draw(void)
{
Weapons_SetModel("models/v_mechagun.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(MG_DRAW);
}
void
w_minigun_holster(void)
{
Weapons_ViewAnimation(MG_DRAW);
}
void
w_minigun_release(void)
{
player pl = (player)self;
if (pl.w_idle_next) {
return;
}
if (pl.a_ammo3 == 1) {
Weapons_ViewAnimation(MG_IDLELOOP);
pl.w_idle_next = 0.666667f;
return;
}
int r = (float)input_sequence % 5;
switch (r) {
case 0:
case 1:
case 2:
case 3:
Weapons_ViewAnimation(MG_IDLE);
pl.w_idle_next = 10.0f;
break;
default:
Weapons_ViewAnimation(MG_FIDGET);
pl.w_idle_next = 2.0f;
}
}
void
w_minigun_primary(void)
{
vector src;
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
#ifdef CSQC
if (pl.a_ammo2 <= 0) {
w_minigun_release();
return;
}
#else
if (pl.ammo_minigun <= 0) {
w_minigun_release();
return;
}
#endif
src = Weapons_GetCameraPos();
#ifdef SSQC
int r = floor(random(0,3));
switch (r) {
case 0:
sound(pl, CHAN_WEAPON, "weapons/hks1.wav", 1.0f, ATTN_NORM);
break;
case 1:
sound(pl, CHAN_WEAPON, "weapons/hks2.wav", 1.0f, ATTN_NORM);
break;
default:
sound(pl, CHAN_WEAPON, "weapons/hks3.wav", 1.0f, ATTN_NORM);
}
#else
View_SetMuzzleflash(MUZZLE_RIFLE);
Weapons_ViewPunchAngle([-2,0,0]);
#endif
#ifdef CSQC
pl.a_ammo2--;
#else
pl.ammo_minigun--;
#endif
if (pl.a_ammo3 == 1) {
#ifdef CSQC
Weapons_ViewAnimation(MG_FIRELOOP);
#else
TraceAttack_FireBullets(1, src, 8, [0.1,0.1], WEAPON_MINIGUN);
#endif
pl.w_attack_next = 0.1f;
pl.w_idle_next = 0.1f;
} else {
#ifdef CSQC
Weapons_ViewAnimation(MG_FIRE);
#else
TraceAttack_FireBullets(1, src, 8, [0.05,0.05], WEAPON_MINIGUN);
#endif
pl.w_attack_next = 0.25f;
pl.w_idle_next = 2.5f;
}
}
void
w_minigun_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
#ifdef SSQC
if (pl.a_ammo3 == 0) {
sound(pl, 8, "weapons/MechaSpinUp.wav", 1.0f, ATTN_NORM);
} else {
sound(pl, 8, "weapons/MechaSpinDown.wav", 1.0f, ATTN_NORM);
}
#else
if (pl.a_ammo3 == 0) {
Weapons_ViewAnimation(MG_SPINUP);
} else {
Weapons_ViewAnimation(MG_SPINDOWN);
}
#endif
pl.a_ammo3 = 1 - pl.a_ammo3;
pl.w_attack_next = 2.0f;
pl.w_idle_next = 2.0f;
}
void
w_minigun_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_minigun, -1);
#endif
}
string
w_minigun_wmodel(void)
{
return "models/w_mechagun.mdl";
}
string
w_minigun_pmodel(void)
{
return "models/p_9mmar.mdl";
}
string
w_minigun_deathmsg(void)
{
return "";
}
float
w_minigun_aimanim(void)
{
return 0;
}
int
w_minigun_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (pl.ammo_minigun < 100) {
pl.ammo_minigun = bound(0, pl.ammo_minigun + 30, 100);
} else {
return FALSE;
}
#endif
return TRUE;
}
void
w_minigun_hud(void)
{
#ifdef CSQC
vector pos;
pos = video_mins + (video_res / 2) + [-23,-15];
drawsubpic(
pos,
[47,31],
"sprites/crosshairs.spr_0.tga",
[67/256,1/128],
[47/256, 31/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
pos = video_mins + [video_res[0] - 125, video_res[1] - 42];
for (int i = 0; i < 3; i++) {
drawpic(
pos,
"gfx/vgui/640_ammo_minigun.tga",
[32,16],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
pos[1] += 8;
}
HUD_DrawAmmo2();
#endif
}
void
w_minigun_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_minigun0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_minigun_precache(void)
{
precache_model("models/v_mechagun.mdl");
precache_model("models/w_mechagun.mdl");
precache_model("models/p_9mmar.mdl");
precache_sound("weapons/MechaSpinDown.wav");
precache_sound("weapons/MechaSpinUp.wav");
precache_sound("weapons/hks1.wav");
precache_sound("weapons/hks2.wav");
precache_sound("weapons/hks3.wav");
}
weapon_t w_minigun =
{
.id = ITEM_MINIGUN,
.slot = 2,
.slot_pos = 1,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_minigun_draw,
.holster = w_minigun_holster,
.primary = w_minigun_primary,
.secondary = w_minigun_secondary,
.reload = __NULL__,
.release = w_minigun_release,
.crosshair = w_minigun_hud,
.precache = w_minigun_precache,
.pickup = w_minigun_pickup,
.updateammo = w_minigun_updateammo,
.wmodel = w_minigun_wmodel,
.pmodel = w_minigun_pmodel,
.deathmsg = w_minigun_deathmsg,
.aimanim = w_minigun_aimanim,
.hudpic = w_minigun_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_minigun(void)
{
Weapons_InitItem(WEAPON_MINIGUN);
}
#endif

View file

@ -0,0 +1,413 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <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.
*/
enum {
SHOTGUN_DRAW, // 0.909091f
SHOTGUN_IDLE, // 2.0f
SHOTGUN_FIDGET, // 2.0f
SHOTGUN_SHOOT1, // 0.846154f
SHOTGUN_SHOOT2, // 0.846154f
SHOTGUN_SHOOT3, // 0.846154f
SHOTGUN_SHOOT4, // 0.846154f
SHOTGUN_CUSTOMIZE // 2.25f
};
enum {
SMENU_NONE,
SMENU_SHELLS,
SMENU_SPREAD
};
enum {
SPREAD_RIOT,
SPREAD_SHOT,
SPREAD_RIFLE
};
#ifdef CSQC
string gsmodes[] = {
"RIOTGUN",
"SHOTGUN",
"RIFLE"
};
#endif
void
w_shotgun_draw(void)
{
Weapons_SetModel("models/v_shotgun.mdl");
Weapons_SetGeomset("geomset 1 1\n");
Weapons_ViewAnimation(SHOTGUN_DRAW);
}
void
w_shotgun_holster(void)
{
Weapons_ViewAnimation(SHOTGUN_DRAW);
}
void
w_shotgun_primary(void)
{
vector src;
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
if (pl.a_ammo1 > 0) {
pl.a_ammo1 = 0;
pl.flags &= ~FL_SEMI_TOGGLED;
Weapons_ViewAnimation(SHOTGUN_CUSTOMIZE);
pl.w_attack_next = 2.25f;
pl.w_idle_next = 2.25f;
return;
}
if (pl.w_attack_next) {
return;
}
src = Weapons_GetCameraPos();
pl.velocity += v_forward * -128;
#ifdef SSQC
vector spread = [0.1,0.05];
int pellets;
switch (pl.shotgun_spread) {
case SPREAD_RIOT:
spread = [0.1,0.1];
break;
case SPREAD_RIFLE:
spread = [0.05,0.05];
break;
default:
spread = [0.1,0.05];
}
pellets = pl.shotgun_shells * 4;
TraceAttack_FireBullets(pellets, src, 5, spread, WEAPON_SHOTGUN);
sound(self, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM);
#else
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-5,0,0]);
int r = (float)input_sequence % 4;
switch (r) {
case 0:
Weapons_ViewAnimation(SHOTGUN_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(SHOTGUN_SHOOT2);
break;
case 2:
Weapons_ViewAnimation(SHOTGUN_SHOOT3);
break;
default:
Weapons_ViewAnimation(SHOTGUN_SHOOT4);
}
#endif
pl.w_attack_next = 0.846154f;
pl.w_idle_next = 2.5f;
}
void
w_shotgun_secondary(void)
{
player pl = (player)self;
if not (pl.flags & FL_SEMI_TOGGLED) {
return;
}
pl.flags &= ~FL_SEMI_TOGGLED;
if (pl.w_attack_next) {
return;
}
/* activate menu */
if (pl.a_ammo1 <= 0) {
pl.a_ammo1 = 1;
} else {
if (pl.a_ammo1 == 1) {
pl.a_ammo1 = 2;
} else {
pl.a_ammo1 = 1;
}
}
}
void
w_shotgun_release(void)
{
player pl = (player)self;
pl.flags |= FL_SEMI_TOGGLED;
if (pl.w_idle_next) {
return;
}
int r = (float)input_sequence % 5;
switch (r) {
case 0:
case 1:
case 2:
case 3:
Weapons_ViewAnimation(SHOTGUN_IDLE);
pl.w_idle_next = 10.0f;
break;
default:
Weapons_ViewAnimation(SHOTGUN_FIDGET);
pl.w_idle_next = 2.0f;
}
}
void
w_shotgun_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_buckshot, -1);
#endif
}
string
w_shotgun_wmodel(void)
{
return "";
}
string
w_shotgun_pmodel(void)
{
return "";
}
string
w_shotgun_deathmsg(void)
{
return "";
}
float
w_shotgun_aimanim(void)
{
return 0;
}
int
w_shotgun_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.shotgun_shells = 2;
pl.shotgun_spread = SPREAD_SHOT;
}
if (pl.ammo_buckshot < 90) {
pl.ammo_buckshot = bound(0, pl.ammo_buckshot + 16, 90);
} else {
return FALSE;
}
#endif
return TRUE;
}
void
w_shotgun_hud(void)
{
#ifdef CSQC
vector pos;
player pl = (player)self;
pos = video_mins + [video_res[0] - 125, video_res[1] - 42];
for (int i = 0; i < 3; i++) {
drawpic(
pos,
"gfx/vgui/640_ammo_buckshot.tga",
[32,16],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
pos[1] += 8;
}
HUD_DrawAmmo2();
/* menu */
if (pl.a_ammo1 > 0) {
vector col1, col2;
string shellstr, spreadstr;
col1 = col2 = [1,1,1];
switch (pl.a_ammo1) {
case SMENU_SHELLS:
col1 = [0,1,0];
break;
case SMENU_SPREAD:
col2 = [0,1,0];
break;
}
shellstr = sprintf("SHELLS: %i", getstati(40));
spreadstr = sprintf("SPREAD: %s", gsmodes[getstati(41)]);
pos = video_mins + (video_res / 2) + [-48,-16];
drawfont = FONT_20;
drawstring(pos, shellstr, [20,20], col1, 1.0f,
DRAWFLAG_ADDITIVE);
drawstring(pos + [0,24], spreadstr, [20,20], col2, 1.0f,
DRAWFLAG_ADDITIVE);
return;
}
/* crosshair */
pos = video_mins + (video_res / 2) + [-15,-15];
drawsubpic(
pos,
[31,31],
"sprites/crosshairs.spr_0.tga",
[34/256,1/128],
[31/256, 31/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_shotgun_hudpic(int selected, vector pos)
{
#ifdef CSQC
drawpic(
pos,
"gfx/vgui/640_weapon_shotgun0.tga",
[170,43],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
#endif
}
void
w_shotgun_precache(void)
{
precache_model("models/v_shotgun.mdl");
precache_model("models/w_shotgun.mdl");
precache_model("models/p_shotgun.mdl");
precache_sound("weapons/sbarrel1.wav");
#ifdef SSQC
clientstat(40, EV_INTEGER, player::shotgun_shells);
clientstat(41, EV_INTEGER, player::shotgun_spread);
#endif
}
weapon_t w_shotgun =
{
.id = ITEM_SHOTGUN,
.slot = 2,
.slot_pos = 0,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_shotgun_draw,
.holster = w_shotgun_holster,
.primary = w_shotgun_primary,
.secondary = w_shotgun_secondary,
.reload = __NULL__,
.release = w_shotgun_release,
.crosshair = w_shotgun_hud,
.precache = w_shotgun_precache,
.pickup = w_shotgun_pickup,
.updateammo = w_shotgun_updateammo,
.wmodel = w_shotgun_wmodel,
.pmodel = w_shotgun_pmodel,
.deathmsg = w_shotgun_deathmsg,
.aimanim = w_shotgun_aimanim,
.hudpic = w_shotgun_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_shotgun(void)
{
Weapons_InitItem(WEAPON_SHOTGUN);
}
#endif
#ifdef CSQC
int
w_shotgun_hudforward(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case SMENU_SHELLS:
sendevent("w_shot_shell", "i", 1i);
break;
case SMENU_SPREAD:
sendevent("w_shot_spread", "i", 1i);
break;
}
return FALSE;
}
int
w_shotgun_hudback(player pl)
{
if (pl.a_ammo1 <= 0) {
return TRUE;
}
switch (pl.a_ammo1) {
case SMENU_SHELLS:
sendevent("w_shot_shell", "i", -1i);
break;
case SMENU_SPREAD:
sendevent("w_shot_spread", "i", -1i);
break;
}
return FALSE;
}
#else
void
CSEv_w_shot_shell_i(int f)
{
player pl = (player)self;
pl.shotgun_shells = bound(1, pl.shotgun_shells + f, 4);
}
void
CSEv_w_shot_spread_i(int f)
{
player pl = (player)self;
pl.shotgun_spread = bound(SPREAD_RIOT, pl.shotgun_spread + f, SPREAD_RIFLE);
}
#endif

View file

@ -15,13 +15,60 @@
*/
weapon_t w_null = {};
weapon_t g_weapons[] = {
w_null,
w_fists,
w_aicore,
w_gausspistol,
w_beamgun,
w_chemicalgun,
w_dml,
w_shotgun,
w_minigun,
w_aicore
w_beamgun,
w_dml,
w_grenade,
w_chemicalgun
};
#ifdef CSQC
int(player) gp_inputforward[] = {
__NULL__,
__NULL__,
__NULL__,
w_gausspistol_hudforward,
w_shotgun_hudforward,
__NULL__,
w_beamgun_hudforward,
w_dml_hudforward,
w_grenade_hudforward,
w_chemgun_hudforward
}
int(player) gp_inputback[] = {
__NULL__,
__NULL__,
__NULL__,
w_gausspistol_hudback,
w_shotgun_hudback,
__NULL__,
w_beamgun_hudback,
w_dml_hudback,
w_grenade_hudback,
w_chemgun_hudback
}
int Weapons_InputForward(player pl)
{
if (gp_inputforward[pl.activeweapon] != __NULL__) {
return gp_inputforward[pl.activeweapon](pl);
}
return TRUE;
}
int Weapons_InputBack(player pl)
{
if (gp_inputback[pl.activeweapon] != __NULL__) {
return gp_inputback[pl.activeweapon](pl);
}
return TRUE;
}
#endif

View file

@ -18,11 +18,13 @@
enum
{
WEAPON_NONE,
WEAPON_FISTS,
WEAPON_GAUSSPISTOL,
WEAPON_BEAMGUN,
WEAPON_CHEMICALGUN,
WEAPON_DML,
WEAPON_MINIGUN,
WEAPON_AICORE
WEAPON_FISTS, // 0
WEAPON_AICORE,
WEAPON_GAUSSPISTOL, // 1
WEAPON_SHOTGUN, // 2
WEAPON_MINIGUN, // 2
WEAPON_BEAMGUN, // 3
WEAPON_DML, // 3
WEAPON_GRENADE,
WEAPON_CHEMICALGUN
};

View file

@ -38,9 +38,13 @@ class player
float activeweapon;
float viewzoom;
vector punchangle;
vector view_ofs;
float weapontime;
/* any mods that use hooks */
entity hook;
/* Weapon specific */
int glock_mag;
int mp5_mag;
@ -70,6 +74,7 @@ class player
float net_teleport_time;
float net_weapontime;
float net_viewzoom;
vector net_punchangle;
int net_ammo1;
int net_ammo2;
int net_ammo3;

View file

@ -39,9 +39,13 @@ class player
float activeweapon;
float viewzoom;
vector punchangle;
vector view_ofs;
float weapontime;
/* any mods that use hooks */
entity hook;
/* Weapon specific */
int glock_mag;
int mp5_mag;
@ -69,6 +73,7 @@ class player
float net_teleport_time;
float net_weapontime;
float net_viewzoom;
vector net_punchangle;
int net_ammo1;
int net_ammo2;
int net_ammo3;

View file

@ -131,7 +131,8 @@ w_mp5_primary(void)
pl.a_ammo1--;
View_SetMuzzleflash(MUZZLE_RIFLE);
Weapons_ViewPunchAngle([random(-2, 2),0,0]);
int r = (float)input_sequence % 4;
Weapons_ViewPunchAngle([r-2,0,0]);
#else
/* singleplayer is more accurate */
if (cvar("sv_playerslots") == 1) {

View file

@ -88,6 +88,13 @@ w_python_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_357.mdl");
/* singleplayer doesn't do scope */
if (cvar("sv_playerslots") == 1) {
Weapons_SetGeomset("geomset 4 1\n");
} else {
Weapons_SetGeomset("geomset 4 2\n");
}
Weapons_ViewAnimation(PYTHON_DRAW);
#endif
}
@ -150,6 +157,11 @@ w_python_secondary(void)
return;
}
/* singleplayer doesn't do scope */
if (cvar("sv_playerslots") == 1) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.5f;

View file

@ -87,10 +87,6 @@ void w_shotgun_draw(void)
{
Weapons_SetModel("models/v_shotgun.mdl");
Weapons_ViewAnimation(SHOTGUN_DRAW);
#ifdef SSQC
player pl = (player)self;
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__);
#endif
}
void w_shotgun_holster(void)
@ -128,7 +124,6 @@ void w_shotgun_primary(void)
}
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM);
pl.shotgun_mag--;
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__);
#else
View_SetMuzzleflash(MUZZLE_WEIRD);
Weapons_ViewPunchAngle([-5,0,0]);

View file

@ -31,7 +31,14 @@ void Weapons_SetModel(string mdl)
{
#ifdef CSQC
setmodel(pSeat->eViewModel, mdl);
#endif
#endif
}
void Weapons_SetGeomset(string set)
{
#ifdef CSQC
setcustomskin(pSeat->eViewModel, "", set);
#endif
}
void Weapons_Draw(void)
@ -213,8 +220,8 @@ int Weapons_GetAnimation(void)
void Weapons_ViewPunchAngle(vector add)
{
#ifdef CSQC
View_AddPunchAngle(add);
player pl = (player)self;
pl.punchangle += add;
#endif
}

View file

@ -51,6 +51,7 @@ void Weapons_ViewPunchAngle(vector);
void Weapons_PlaySound(entity, float, string, float, float);
int Weapons_IsPresent(player, int);
void Weapons_SetModel(string);
void Weapons_SetGeomset(string);
#ifdef SSQC
void Weapons_RefreshAmmo(player);
void Weapons_InitItem(int);