Added missing They Hunger files.

This commit is contained in:
Marco Cawthorne 2019-12-22 23:28:39 +01:00
parent 77f952a143
commit 674432f6cb
25 changed files with 4153 additions and 1 deletions

1
.gitignore vendored
View File

@ -1,6 +1,5 @@
*~
darkstar/
hunger/
noffice/
pvk/
ship/

93
hunger/data.pk3dir/default.cfg Executable file
View File

@ -0,0 +1,93 @@
// Generic Binds
bind "ESC" "togglemenu"
bind "w" "+forward"
bind "s" "+back"
bind "a" "+moveleft"
bind "d" "+moveright"
bind "SPACE" "+jump"
bind "CTRL" "+duck"
bind "SHIFT" "+speed"
bind "0" "slot10"
bind "1" "slot1"
bind "2" "slot2"
bind "3" "slot3"
bind "4" "slot4"
bind "5" "slot5"
bind "6" "slot6"
bind "7" "slot7"
bind "8" "slot8"
bind "9" "slot9"
bind "UPARROW" "+forward"
bind "DOWNARROW" "+back"
bind "LEFTARROW" "+left"
bind "RIGHTARROW" "+right"
bind "MOUSE1" "+attack"
bind "MOUSE2" "+attack2"
bind "MWHEELDOWN" "invnext"
bind "MWHEELUP" "invprev"
bind "r" "+reload"
bind "e" "+use"
bind "TAB" "+showscores"
bind "y" "messagemode"
bind "u" "messagemode2"
bind "t" "impulse 201"
bind "f" "impulse 100"
// Game Variables
seta "hostname" "They Hunger Server"
name "Einar"
model nypdcop
seta "maxplayers" "8"
// Physics Variables
serverinfo "phy_stepheight" "18"
serverinfo "phy_airstepheight" "18"
serverinfo "phy_friction" "4"
serverinfo "phy_edgefriction" "1"
serverinfo "phy_stopspeed" "75"
serverinfo "phy_gravity" "800"
serverinfo "phy_airaccelerate" "10"
serverinfo "phy_accelerate" "8"
serverinfo "phy_maxspeed" "270"
// 2D/HUD Variables
seta "con_color" "255 0 0"
seta "vgui_color" "255 0 0"
seta "cross_color" "255 0 0"
seta "vid_conautoscale" "1"
seta "con_textsize" "12"
seta "cl_cursor_scale" "1"
seta "vid_conautoscale" "1"
seta "scr_conalpha" "1"
// View Variables
seta "cl_bob" "0"
seta "maxpitch" "89"
seta "minpitch" "-89"
seta "r_meshpitch" "1"
seta "v_bob" "0.01"
seta "v_bobcycle" "0.8"
seta "v_bobup" "0.5"
seta "v_contentblend" "0"
// 3D World Variables
seta "gl_blacklist_debug_glsl" "0"
seta "gl_overbright" "0"
seta "r_fb_models" "0"
seta "r_fullbrightSkins" "0"
seta "r_particledesc" "default"
seta "r_polygonoffset_submodel_factor" "0"
seta "r_polygonoffset_submodel_offset" "0"
seta "r_shadow_realtime_dlight_shadows" "0"
seta "r_shadow_realtime_world_shadows" "0"
// Misc defaults
seta "cfg_save_auto" "1"
seta "cl_idlefps" "60"
seta "cl_maxfps" "250"
seta "com_nogamedirnativecode" "0"
seta "con_logcenterprint" "0"
seta "con_notifylines" "0"
seta "lang" "en_us"
seta "r_imageexensions" "tga bmp pcx"
seta "scr_sshot_type" "tga"

15
hunger/modinfo.txt Normal file
View File

@ -0,0 +1,15 @@
// They Hunger Info File
game "They Hunger"
gamedir "hunger"
url_info "www.planethalflife.com/manke"
url_dl ""
version "3.0"
hlversion "1100"
size "142600000"
type "Single"
startmap "thintro"
trainmap "they30"
gamedll "dlls\einar.dll"
cldll "1"
svonly "0"

View File

@ -66,6 +66,9 @@ vector video_mins;
vector video_res;
vector mouse_pos;
/* TODO: Move these into gs-entbase/client/defs.h? */
vector g_vecSunDir;
/* this actually belongs in builtins.h since its an undocumented global */
float clframetime;

54
src/client/hunger/init.c Normal file
View File

@ -0,0 +1,54 @@
/*
* 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.
*/
float(entity foo, float chanid) getchannellevel = #0;
/*
=================
Client_Init
Comparable to worldspawn in SSQC in that it's mostly used for precaches
=================
*/
void Client_Init(float apilevel, string enginename, float engineversion)
{
precache_model("sprites/640hud1.spr");
precache_model("sprites/640hud2.spr");
precache_model("sprites/640hud3.spr");
precache_model("sprites/640hud4.spr");
precache_model("sprites/640hud5.spr");
precache_model("sprites/640hud6.spr");
precache_model("sprites/tfchud01.spr");
precache_model("sprites/tfchud02.spr");
precache_model("sprites/tfchud03.spr");
precache_model("sprites/tfchud04.spr");
precache_model("sprites/tfchud05.spr");
precache_model("sprites/tfchud06.spr");
precache_model("sprites/tfc_dmsg.spr");
precache_model("sprites/nmxhair2.spr");
BEAM_TRIPMINE = particleeffectnum("beam_tripmine");
}
void Client_InitDone(void)
{
}
void Game_RendererRestarted(string rstr)
{
}

View File

@ -0,0 +1,86 @@
#pragma target fte
#pragma progs_dat "../../../hunger/data.pk3dir/csprogs.dat"
#define CSQC
#define VALVE
#define HUNGER
#includelist
../../shared/fteextensions.qc
../../shared/defs.h
../../shared/math.h
../../shared/materials.h
../../shared/events.h
../../shared/entities.h
../valve/defs.h
../valve/particles.h
../defs.h
../../vgui/include.src
../util.c
../sky.c
../fade.c
../sprite.cpp
../titles.c
../text.c
../sentences.c
../../gs-entbase/client.src
../sound.c
../prints.c
../voice.c
../../shared/valve/animations.h
../../shared/valve/animations.c
../../shared/hunger/player.cpp
../player.c
../../shared/pmove.c
../predict.c
../../shared/decals.c
../../shared/effects.c
../../shared/spraylogo.cpp
../npc.c
init.c
../../shared/hunger/items.h
../../shared/valve/weapon_common.h
../../shared/hunger/weapons.h
../../shared/valve/w_crossbow.c
../../shared/valve/w_crowbar.c
../../shared/valve/w_gauss.c
../../shared/valve/w_mp5.c
../../shared/valve/w_python.c
../../shared/valve/w_rpg.c
../../shared/valve/w_satchel.c
../../shared/valve/w_shotgun.c
../../shared/valve/w_snark.c
../../shared/valve/w_tripmine.c
../../shared/hunger/w_ap9.c
../../shared/hunger/w_chaingun.c
../../shared/hunger/w_flame.c
../../shared/hunger/w_glock.c
../../shared/hunger/w_handgrenade.c
../../shared/hunger/w_medkit.c
../../shared/hunger/w_shovel.c
../../shared/hunger/w_sniper.c
../../shared/hunger/w_sniper2.c
../../shared/hunger/w_spanner.c
../../shared/hunger/w_taurus.c
../../shared/hunger/weapons.c
../../shared/valve/weapon_common.c
../valve/player.c
../valve/entities.c
../entities.c
../valve/cmds.c
../valve/game_event.c
../events.c
../valve/view.c
../view.c
../damage.c
../obituary.c
../chat.c
../vgui.cpp
../valve/hud.c
../valve/hud_weaponselect.c
../valve/scoreboard.c
../valve/input.c
../entry.c
#endlist

View File

@ -14,7 +14,9 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef DEVELOPER
#define GS_DEVELOPER
#endif
#ifdef WASTES
#define GS_BULLET_PHYSICS

View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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.
*/
/*
* Ammo for the Flamethrower.
* A single ammo_egonclip will provide 25, er, gas.
*/
class ammo_egonclip:item_ammo
{
void() ammo_egonclip;
virtual void() touch;
};
void ammo_egonclip::ammo_egonclip(void)
{
model = "models/w_gas.mdl";
item_ammo::item_ammo();
}
void ammo_egonclip::touch(void)
{
if not (other.flags & FL_CLIENT) {
return;
}
if (other.classname == "player") {
player pl = (player)other;
if (pl.ammo_gas < MAX_A_GAS) {
pl.ammo_gas = bound(0, pl.ammo_gas + 25, MAX_A_GAS);
item_ammo::touch();
}
}
}
/*
* Ammo for the AP9.
* A single ammo_th_ap9 will provide 40 bullets.
*/
class ammo_th_ap9:item_ammo
{
void() ammo_th_ap9;
virtual void() touch;
};
void ammo_th_ap9::ammo_th_ap9(void)
{
model = "models/w_ap9clip.mdl";
item_ammo::item_ammo();
}
void ammo_th_ap9::touch(void)
{
if not (other.flags & FL_CLIENT) {
return;
}
if (other.classname == "player") {
player pl = (player)other;
if (pl.ammo_ap9 < MAX_A_AP9) {
pl.ammo_ap9 = bound(0, pl.ammo_ap9 + 40, MAX_A_AP9);
item_ammo::touch();
}
}
}
/*
* Ammo for the Snipers.
* A single ammo_th_sniper will provide 5 bullets.
*/
class ammo_einar1:item_ammo
{
void() ammo_einar1;
virtual void() touch;
};
void ammo_einar1::ammo_einar1(void)
{
model = "models/w_antidote.mdl";
item_ammo::item_ammo();
}
void ammo_einar1::touch(void)
{
if not (other.flags & FL_CLIENT) {
return;
}
if (other.classname == "player") {
player pl = (player)other;
if (pl.ammo_sniper < MAX_A_SNIPER) {
pl.ammo_sniper = bound(0, pl.ammo_sniper + 5, MAX_A_SNIPER);
item_ammo::touch();
}
}
}
class ammo_th_sniper:item_ammo
{
void() ammo_th_sniper;
virtual void() touch;
};
void ammo_th_sniper::ammo_th_sniper(void)
{
model = "models/w_antidote.mdl";
item_ammo::item_ammo();
}
void ammo_th_sniper::touch(void)
{
if not (other.flags & FL_CLIENT) {
return;
}
if (other.classname == "player") {
player pl = (player)other;
if (pl.ammo_sniper < MAX_A_SNIPER) {
pl.ammo_sniper = bound(0, pl.ammo_sniper + 5, MAX_A_SNIPER);
item_ammo::touch();
}
}
}

86
src/server/hunger/input.c Normal file
View File

@ -0,0 +1,86 @@
/*
* 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.
*/
/*
=================
Input_Handle
Handles impulse and whatnot
=================
*/
void Game_Input(void)
{
if (input_buttons & INPUT_BUTTON0) {
Weapons_Primary();
} else if (input_buttons & INPUT_BUTTON4) {
Weapons_Reload();
} else if (input_buttons & INPUT_BUTTON3) {
Weapons_Secondary();
} else {
Weapons_Release();
}
if (input_buttons & INPUT_BUTTON5) {
Player_UseDown();
} else {
Player_UseUp();
}
if (self.impulse == 100) {
Flashlight_Toggle();
}
if (cvar("sv_cheats") == 1) {
player pl = (player)self;
if (self.impulse == 101) {
pl.health = 100;
pl.armor = 100;
pl.g_items |= ITEM_SUIT;
Weapons_AddItem(pl, WEAPON_CROWBAR);
Weapons_AddItem(pl, WEAPON_SHOVEL);
Weapons_AddItem(pl, WEAPON_SPANNER);
Weapons_AddItem(pl, WEAPON_GLOCK);
Weapons_AddItem(pl, WEAPON_PYTHON);
Weapons_AddItem(pl, WEAPON_AP9);
Weapons_AddItem(pl, WEAPON_TAURUS);
Weapons_AddItem(pl, WEAPON_MP5);
Weapons_AddItem(pl, WEAPON_SHOTGUN);
Weapons_AddItem(pl, WEAPON_CROSSBOW);
Weapons_AddItem(pl, WEAPON_SNIPER);
Weapons_AddItem(pl, WEAPON_SNIPER2);
Weapons_AddItem(pl, WEAPON_RPG);
Weapons_AddItem(pl, WEAPON_GAUSS);
Weapons_AddItem(pl, WEAPON_FLAME);
Weapons_AddItem(pl, WEAPON_CHAINGUN);
Weapons_AddItem(pl, WEAPON_HANDGRENADE);
Weapons_AddItem(pl, WEAPON_SATCHEL);
Weapons_AddItem(pl, WEAPON_TRIPMINE);
Weapons_AddItem(pl, WEAPON_SNARK);
Weapons_AddItem(pl, WEAPON_MEDKIT);
}
if (self.impulse == 102) {
// Respawn all the entities
for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) {
CBaseEntity caw = (CBaseEntity)a;
caw.Respawn();
}
bprint(PRINT_HIGH, "Respawning all map entities...\n");
}
}
self.impulse = 0;
}

86
src/server/hunger/progs.src Executable file
View File

@ -0,0 +1,86 @@
#pragma target fte
#pragma progs_dat "../../../hunger/data.pk3dir/progs.dat"
#define QWSSQC
#define VALVE
#define HUNGER
#includelist
../../shared/fteextensions.qc
../../shared/defs.h
../valve/defs.h
../../shared/math.h
../../shared/materials.h
../../shared/events.h
../../shared/entities.h
../../shared/valve/animations.h
../defs.h
../plugins.c
../logging.c
../nodes.c
../../gs-entbase/server.src
../valve/monster_rat.cpp
../valve/monster_scientist.cpp
../valve/monster_scientist_dead.cpp
../../shared/decals.c
../../shared/effects.c
../../shared/spraylogo.cpp
../../shared/hunger/player.cpp
../valve/player.c
../../shared/pmove.c
../valve/spectator.c
../../shared/hunger/items.h
../../shared/valve/weapon_common.h
../../shared/hunger/weapons.h
../../shared/valve/w_crossbow.c
../../shared/valve/w_crowbar.c
../../shared/valve/w_gauss.c
../../shared/valve/w_mp5.c
../../shared/valve/w_python.c
../../shared/valve/w_rpg.c
../../shared/valve/w_satchel.c
../../shared/valve/w_shotgun.c
../../shared/valve/w_snark.c
../../shared/valve/w_tripmine.c
../../shared/hunger/w_ap9.c
../../shared/hunger/w_chaingun.c
../../shared/hunger/w_flame.c
../../shared/hunger/w_glock.c
../../shared/hunger/w_handgrenade.c
../../shared/hunger/w_medkit.c
../../shared/hunger/w_shovel.c
../../shared/hunger/w_sniper.c
../../shared/hunger/w_sniper2.c
../../shared/hunger/w_spanner.c
../../shared/hunger/w_taurus.c
../valve/items.cpp
../valve/item_longjump.cpp
../valve/item_suit.cpp
../valve/item_healthkit.cpp
../valve/item_battery.cpp
../valve/item_weaponbox.cpp
../valve/world_items.cpp
../valve/xen_spore_small.cpp
../valve/xen_spore_medium.cpp
../valve/xen_spore_large.cpp
../valve/xen_hair.cpp
../valve/xen_plantlight.cpp
../valve/ammo.cpp
../hunger/ammo_th.cpp
../../shared/hunger/weapons.c
../../shared/valve/weapon_common.c
../spawn.c
../vox.c
../../shared/valve/animations.c
../valve/client.c
../client.c
../valve/server.c
../server.c
../valve/damage.c
../traceattack.c
../footsteps.c
../flashlight.c
input.c
../valve/spawn.c
../entry.c
#endlist

51
src/shared/hunger/items.h Normal file
View File

@ -0,0 +1,51 @@
/*
* 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.
*/
#define ITEM_CROWBAR 0x00000001
#define ITEM_GLOCK 0x00000002
#define ITEM_PYTHON 0x00000004
#define ITEM_MP5 0x00000008
#define ITEM_CROSSBOW 0x00000010
#define ITEM_SHOTGUN 0x00000020
#define ITEM_RPG 0x00000040
#define ITEM_GAUSS 0x00000080
#define ITEM_FLAME 0x00000100
#define ITEM_CHAINGUN 0x00000200
#define ITEM_HANDGRENADE 0x00000400
#define ITEM_TRIPMINE 0x00000800
#define ITEM_SATCHEL 0x00001000
#define ITEM_SNARK 0x00002000
#define ITEM_SUIT 0x00004000
#define ITEM_LONGJUMP 0x00008000
#define ITEM_SHOVEL 0x00010000
#define ITEM_SPANNER 0x00020000
#define ITEM_AP9 0x00040000
#define ITEM_TAURUS 0x00080000
#define ITEM_SNIPER 0x00100000
#define ITEM_SNIPER2 0x00200000
#define ITEM_MEDKIT2 0x00400000
#define ITEM_UNUSED24 0x00800000
#define ITEM_UNUSED25 0x01000000
#define ITEM_UNUSED26 0x02000000
#define ITEM_UNUSED27 0x04000000
#define ITEM_UNUSED28 0x08000000
#define ITEM_UNUSED29 0x10000000
#define ITEM_UNUSED30 0x20000000
#define ITEM_UNUSED31 0x40000000
#define ITEM_UNUSED32 0x80000000

View File

@ -0,0 +1,128 @@
/*
* 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;
/* Weapon specific */
int glock_mag;
int ap9_mag;
int taurus_mag;
int mp5_mag;
int python_mag;
int shotgun_mag;
int crossbow_mag;
int sniper_mag;
int rpg_mag;
int chaingun_mag;
int satchel_chg;
#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_9mm;
int ammo_357;
int ammo_ap9;
int ammo_taurus;
int ammo_buckshot;
int ammo_m203_grenade;
int ammo_bolt;
int ammo_sniper;
int ammo_rocket;
int ammo_uranium;
int ammo_gas;
int ammo_handgrenade;
int ammo_satchel;
int ammo_tripmine;
int ammo_snark;
int ammo_hornet;
int ammo_medkit;
/* 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
};

356
src/shared/hunger/w_ap9.c Normal file
View File

@ -0,0 +1,356 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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
{
AP9_IDLE,
AP9_RELOAD,
AP9_DRAW,
AP9_SHOOT1,
AP9_SHOOT2,
AP9_SHOOT3
};
void
w_ap9_precache(void)
{
precache_model("models/v_ap9.mdl");
precache_model("models/w_ap9.mdl");
precache_model("models/p_ap9.mdl");
precache_sound("weapons/ap9_bolt.wav");
precache_sound("weapons/ap9_clipin.wav");
precache_sound("weapons/ap9_clipout.wav");
precache_sound("weapons/ap9_fire.wav");
}
void
w_ap9_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.ap9_mag, pl.ammo_ap9, -1);
#endif
}
string
w_ap9_wmodel(void)
{
return "models/w_ap9.mdl";
}
string
w_ap9_pmodel(void)
{
return "models/p_ap9.mdl";
}
string
w_ap9_deathmsg(void)
{
return "";
}
int
w_ap9_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.ap9_mag = 40;
} else {
if (pl.ammo_ap9 < MAX_A_AP9) {
pl.ammo_ap9 = bound(0, pl.ammo_ap9 + 40, MAX_A_AP9);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_ap9_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_ap9.mdl");
Weapons_ViewAnimation(AP9_DRAW);
#endif
}
void
w_ap9_holster(void)
{
}
void
w_ap9_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* ammo check */
#ifdef CSQC
if (!pl.a_ammo1) {
return;
}
#else
if (!pl.ap9_mag) {
return;
}
#endif
/* actual firing */
#ifdef CSQC
pl.a_ammo1--;
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-2,0,0]);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(AP9_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(AP9_SHOOT2);
break;
case 2:
Weapons_ViewAnimation(AP9_SHOOT3);
break;
}
#else
pl.ap9_mag--;
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 8, [0.1,0.1], WEAPON_AP9);
sound(pl, CHAN_WEAPON, "weapons/ap9_fire.wav", 1.0f, ATTN_NORM);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
#endif
pl.w_attack_next = 0.15f;
pl.w_idle_next = 5.0f;
}
void
w_ap9_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0) {
return;
}
/* ammo check */
#ifdef CSQC
if (!pl.a_ammo1) {
return;
}
#else
if (!pl.ap9_mag) {
return;
}
#endif
#ifdef CSQC
pl.a_ammo1 -= 3;
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-2,0,0]);
int r = floor(random(0,2));
switch (r) {
case 0:
Weapons_ViewAnimation(AP9_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(AP9_SHOOT2);
break;
case 2:
Weapons_ViewAnimation(AP9_SHOOT3);
break;
}
#else
pl.ap9_mag -= 3;
TraceAttack_FireBullets(3, pl.origin + pl.view_ofs, 8, [0.02,0.02], WEAPON_AP9);
sound(pl, CHAN_WEAPON, "weapons/ap9_fire.wav", 1.0f, ATTN_NORM);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
#endif
pl.w_attack_next = 1.0f;
pl.w_idle_next = 5.0f;
}
void
w_ap9_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
if (pl.a_ammo1 >= 40) {
return;
}
if (pl.a_ammo2 <= 0) {
return;
}
Weapons_ViewAnimation(AP9_RELOAD);
#else
if (pl.ap9_mag >= 40) {
return;
}
if (pl.ammo_ap9 <= 0) {
return;
}
Weapons_ReloadWeapon(pl, player::ap9_mag, player::ammo_ap9, 40);
#endif
pl.w_attack_next = 2.0f;
pl.w_idle_next = 10.0f;
}
void
w_ap9_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
Weapons_ViewAnimation(AP9_IDLE);
}
float
w_ap9_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIM1HAND : ANIM_AIM1HAND;
}
void
w_ap9_hud(void)
{
#ifdef CSQC
vector cross_pos;
vector aicon_pos;
cross_pos = (video_res / 2) + [-12,-12];
aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(
cross_pos,
[24,24],
"sprites/crosshairs.spr_0.tga",
[0.1875,0],
[0.1875, 0.1875],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
HUD_DrawAmmo1();
HUD_DrawAmmo2();
drawsubpic(
aicon_pos,
[24,24],
"sprites/640hud7.spr_0.tga",
[0,72/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
#endif
}
void
w_ap9_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud05.spr_0.tga",
[0,90/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud06.spr_0.tga",
[0,0],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_ap9 =
{
.id = ITEM_AP9,
.slot = 1,
.slot_pos = 2,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [32,16],
.ki_xy = [192,16],
.draw = w_ap9_draw,
.holster = w_ap9_holster,
.primary = w_ap9_primary,
.secondary = w_ap9_secondary,
.reload = w_ap9_reload,
.release = w_ap9_release,
.crosshair = w_ap9_hud,
.precache = w_ap9_precache,
.pickup = w_ap9_pickup,
.updateammo = w_ap9_updateammo,
.wmodel = w_ap9_wmodel,
.pmodel = w_ap9_pmodel,
.deathmsg = w_ap9_deathmsg,
.aimanim = w_ap9_aimanim,
.hudpic = w_ap9_hudpic
};
/* pickups */
#ifdef SSQC
void
weapon_th_ap9(void) {
Weapons_InitItem(WEAPON_AP9);
}
#endif

View File

@ -0,0 +1,326 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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.
*/
/* Animations */
enum {
CHAINGUN_IDLE1,
CHAINGUN_IDLE2,
CHAINGUN_SPINUP,
CHAINGUN_SPINDOWN,
CHAINGUN_FIRE,
CHAINGUN_DRAW,
CHAINGUN_HOLSTER
};
void
w_chaingun_precache(void)
{
precache_model("models/v_tfac.mdl");
precache_model("models/w_tfac.mdl");
precache_model("models/p_tfac.mdl");
precache_sound("weapons/asscan3.wav");
}
int
w_chaingun_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.chaingun_mag = 100;
} else {
if (pl.ammo_9mm < MAX_A_9MM) {
pl.ammo_9mm = bound(0, pl.ammo_9mm + 100, MAX_A_9MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_chaingun_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.chaingun_mag, pl.ammo_9mm, -1);
#endif
}
string
w_chaingun_wmodel(void)
{
return "models/w_tfac.mdl";
}
string
w_chaingun_pmodel(void)
{
return "models/p_tfac.mdl";
}
string
w_chaingun_deathmsg(void)
{
return "";
}
void
w_chaingun_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_tfac.mdl");
Weapons_ViewAnimation(CHAINGUN_DRAW);
#endif
}
void
w_chaingun_holster(void)
{
Weapons_ViewAnimation(CHAINGUN_HOLSTER);
}
void
w_chaingun_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
/* end firing */
if (pl.a_ammo3 == 1) {
pl.a_ammo3 = 0;
Weapons_ViewAnimation(CHAINGUN_SPINDOWN);
pl.w_attack_next = 1.0f;
pl.w_idle_next = pl.w_attack_next;
return;
}
/* end reload */
if (pl.a_ammo3 == 2) {
pl.a_ammo3 = 0;
Weapons_ViewAnimation(CHAINGUN_DRAW);
pl.w_attack_next = 1.0f;
pl.w_idle_next = pl.w_attack_next;
return;
}
int r = (float)input_sequence % 2;
if (r) {
Weapons_ViewAnimation(CHAINGUN_IDLE1);
} else {
Weapons_ViewAnimation(CHAINGUN_IDLE2);
}
pl.w_idle_next = 15.0f;
}
void
w_chaingun_primary(void)
{
player pl = (player)self;
/* in case we're spamming primary while reloading */
if (pl.a_ammo3 == 2) {
w_chaingun_release();
return;
}
if (pl.w_attack_next > 0.0) {
return;
}
/* ammo check */
#ifdef CSQC
if (pl.a_ammo1 <= 0) {
return;
}
#else
if (pl.chaingun_mag <= 0) {
return;
}
#endif
/* spin up first */
if (pl.a_ammo3 == 0) {
pl.a_ammo3 = 1;
Weapons_ViewAnimation(CHAINGUN_SPINUP);
sound(pl, CHAN_WEAPON, "weapons/asscan1.wav", 1.0f, ATTN_NORM);
pl.w_attack_next = 0.5f;
pl.w_idle_next = pl.w_attack_next;
return;
}
/* actual firing */
#ifdef CSQC
pl.a_ammo1--;
View_SetMuzzleflash(MUZZLE_RIFLE);
Weapons_ViewAnimation(CHAINGUN_FIRE);
Weapons_ViewPunchAngle([random(-2, 2),0,0]);
#else
pl.chaingun_mag--;
TraceAttack_FireBullets(1, Weapons_GetCameraPos(), 8, [0.15,0.15], WEAPON_CHAINGUN);
sound(pl, CHAN_WEAPON, "weapons/asscan3.wav", 1.0f, ATTN_NORM);
#endif
pl.w_attack_next = 0.1f;
pl.w_idle_next = 0.0f;
}
void
w_chaingun_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
w_chaingun_release();
return;
}
/* ammo check */
#ifdef CSQC
if (pl.a_ammo1 >= 100) {
return;
}
if (pl.a_ammo2 <= 0) {
return;
}
#else
if (pl.chaingun_mag >= 100) {
return;
}
if (pl.ammo_9mm <= 0) {
return;
}
#endif
#ifdef CSQC
Weapons_ViewAnimation(CHAINGUN_HOLSTER);
#else
sound(pl, CHAN_WEAPON, "weapons/reload3.wav", 1, ATTN_NORM);
Weapons_ReloadWeapon(pl, player::chaingun_mag, player::ammo_9mm, 100);
#endif
pl.a_ammo3 = 2;
pl.w_attack_next = 10.0f;
pl.w_idle_next = 1.5f;
}
void
w_chaingun_hud(void)
{
#ifdef CSQC
/* crosshair */
drawsubpic(
video_mins + (video_res / 2) + [-12,-12],
[24,24],
"sprites/crosshairs.spr_0.tga",
[24/128,0],
[24/128, 24/128],
[1,1,1],
1,
DRAWFLAG_NORMAL
);
/* ammo icon */
drawsubpic(
video_mins + [video_res[0] - 48, video_res[1] - 42],
[24,24],
"sprites/640hud7.spr_0.tga",
[0,72/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawAmmo1();
HUD_DrawAmmo2();
#endif
}
float
w_chaingun_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMMP5 : ANIM_AIMMP5;
}
void
w_chaingun_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud04.spr_0.tga",
[0,90/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud03.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_chaingun =
{
.id = ITEM_CHAINGUN,
.slot = 3,
.slot_pos = 3,
.ki_spr = "sprites/tfc_dmsg.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [0,16],
.draw = w_chaingun_draw,
.holster = w_chaingun_holster,
.primary = w_chaingun_primary,
.secondary = w_chaingun_release,
.reload = w_chaingun_reload,
.release = w_chaingun_release,
.crosshair = w_chaingun_hud,
.precache = w_chaingun_precache,
.pickup = w_chaingun_pickup,
.updateammo = w_chaingun_updateammo,
.wmodel = w_chaingun_wmodel,
.pmodel = w_chaingun_pmodel,
.deathmsg = w_chaingun_deathmsg,
.aimanim = w_chaingun_aimanim,
.hudpic = w_chaingun_hudpic
};
/* pickups */
#ifdef SSQC
void
weapon_th_chaingun(void)
{
Weapons_InitItem(WEAPON_CHAINGUN);
}
#endif

270
src/shared/hunger/w_flame.c Normal file
View File

@ -0,0 +1,270 @@
/*
* 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
{
FLAME_IDLE1,
FLAME_FIDGET1,
FLAME_ALTFIREON,
FLAME_ALTFIRECYCLE,
FLAME_ALTFIREOFF,
FLAME_FIRE1,
FLAME_FIRE2,
FLAME_FIRE3,
FLAME_FIRE4,
FLAME_DRAW,
FLAME_HOLSTER
};
void
w_flame_precache(void)
{
precache_model("sound/weapons/flmfire2.wav");
precache_model("sprites/fthrow.spr");
precache_model("models/v_egon.mdl");
precache_model("models/w_egon.mdl");
precache_model("models/p_egon.mdl");
}
void
w_flame_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_gas, __NULL__);
#endif
}
string
w_flame_wmodel(void)
{
return "models/w_egon.mdl";
}
string
w_flame_pmodel(void)
{
return "models/p_egon.mdl";
}
string
w_flame_deathmsg(void)
{
return "";
}
int
w_flame_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (pl.ammo_gas < MAX_A_GAS) {
pl.ammo_gas = bound(0, pl.ammo_gas + 20, MAX_A_GAS);
} else {
return FALSE;
}
#endif
return TRUE;
}
void
w_flame_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_egon.mdl");
Weapons_ViewAnimation(FLAME_DRAW);
pl.w_idle_next = 1.0f;
}
void
w_flame_holster(void)
{
Weapons_ViewAnimation(FLAME_HOLSTER);
}
#ifdef SSQC
void
Flame_Touch(void) {
if (other.takedamage != DAMAGE_YES) {
remove(self);
return;
}
/* anything else that can take damage */
Damage_Apply(other, self.owner, 40, WEAPON_FLAME, DMG_BURN);
remove(self);
}
#endif
void w_flame_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* Ammo check */
#ifdef CSQC
if (pl.a_ammo2 <= 0) {
return;
}
#else
if (pl.ammo_gas <= 0) {
return;
}
#endif
#ifdef CSQC
if (Weapons_GetAnimation() == FLAME_IDLE1)
Weapons_ViewAnimation(FLAME_ALTFIREON);
else if (Weapons_GetAnimation() == FLAME_ALTFIREON)
Weapons_ViewAnimation(FLAME_ALTFIRECYCLE);
pl.a_ammo2--;
#else
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/flmfire2.wav", 1, ATTN_NORM);
Weapons_MakeVectors();
entity flame = spawn();
setmodel(flame, "sprites/fthrow.spr");
setorigin(flame, Weapons_GetCameraPos() + (v_forward * 16));
flame.owner = self;
flame.velocity = v_forward * 300;
flame.movetype = MOVETYPE_FLYMISSILE;
flame.solid = SOLID_BBOX;
//flame.flags |= FL_LAGGEDMOVE;
flame.angles = vectoangles(flame.velocity);
flame.avelocity[2] = 10;
flame.touch = Flame_Touch;
/*frame.think = Flame_Touch;
flame.nextthink = time + 2.0f;*/
flame.effects |= EF_BRIGHTLIGHT;
setsize(flame, [0,0,0], [0,0,0]);
pl.ammo_gas--;
#endif
pl.w_attack_next = 0.2f;
pl.w_idle_next = 2.5f;
}
void
w_flame_secondary(void)
{
}
void
w_flame_reload(void)
{
}
void
w_flame_release(void)
{
#ifdef CSQC
player pl = (player)self;
if (Weapons_GetAnimation() == FLAME_ALTFIRECYCLE) {
Weapons_ViewAnimation(FLAME_ALTFIREOFF);
pl.w_idle_next = 1.0f;
} else {
if (pl.w_idle_next > 0.0f) {
return;
}
Weapons_ViewAnimation(FLAME_IDLE1);
}
#endif
}
void
w_flame_crosshair(void)
{
#ifdef CSQC
static vector cross_pos;
cross_pos = video_mins + (video_res / 2) + [-12,-12];
drawsubpic(cross_pos, [24,24], "sprites/crosshairs.spr_0.tga", [72/128,48/128], [0.1875, 0.1875], [1,1,1], 1, DRAWFLAG_NORMAL);
HUD_DrawAmmo2();
vector aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(aicon_pos, [24,24], "sprites/640hud7.spr_0.tga", [0,96/128], [24/256, 24/128], g_hud_color, pSeat->ammo2_alpha, DRAWFLAG_ADDITIVE);
#endif
}
float
w_flame_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMEGON : ANIM_AIMEGON;
}
void
w_flame_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/640hud5.spr_0.tga",
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/640hud2.spr_0.tga",
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_flame =
{
.id = ITEM_FLAME,
.slot = 3,
.slot_pos = 2,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [32,16],
.ki_xy = [0,192],
.draw = w_flame_draw,
.holster = __NULL__,
.primary = w_flame_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_flame_release,
.crosshair = w_flame_crosshair,
.precache = w_flame_precache,
.pickup = w_flame_pickup,
.updateammo = w_flame_updateammo,
.wmodel = w_flame_wmodel,
.pmodel = w_flame_pmodel,
.deathmsg = w_flame_deathmsg,
.aimanim = w_flame_aimanim,
.hudpic = w_flame_hudpic
};
#ifdef SSQC
void
weapon_egon(void) {
Weapons_InitItem(WEAPON_FLAME);
}
#endif

354
src/shared/hunger/w_glock.c Normal file
View File

@ -0,0 +1,354 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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
{
GLOCK_IDLE1,
GLOCK_IDLE2,
GLOCK_IDLE3,
GLOCK_SHOOT,
GLOCK_SHOOT_EMPTY,
GLOCK_RELOAD_EMPTY,
GLOCK_RELOAD,
GLOCK_DRAW,
GLOCK_HOLSTER,
GLOCK_SILENCER
};
void
w_glock_precache(void)
{
precache_model("models/v_9mmhandgun.mdl");
precache_model("models/w_silencer.mdl");
precache_model("models/p_9mmhandgun.mdl");
precache_sound("weapons/pl_gun1.wav");
precache_sound("weapons/pl_gun3.wav");
}
void
w_glock_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.glock_mag, pl.ammo_9mm, -1);
#endif
}
string
w_glock_wmodel(void)
{
return "models/w_silencer.mdl";
}
string
w_glock_pmodel(void)
{
return "models/p_9mmhandgun.mdl";
}
string
w_glock_deathmsg(void)
{
return "";
}
int
w_glock_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.glock_mag = 18;
} else {
if (pl.ammo_9mm < 250) {
pl.ammo_9mm = bound(0, pl.ammo_9mm + 18, 250);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_glock_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_9mmhandgun.mdl");
Weapons_ViewAnimation(GLOCK_DRAW);
#endif
}
void
w_glock_holster(void)
{
Weapons_ViewAnimation(GLOCK_HOLSTER);
}
void
w_glock_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
if (!pl.a_ammo1) {
return;
}
if (pl.a_ammo3 == 1) {
View_SetMuzzleflash(0);
} else {
View_SetMuzzleflash(MUZZLE_SMALL);
}
Weapons_ViewPunchAngle([-2,0,0]);
#else
if (!pl.glock_mag) {
return;
}
#endif
#ifdef SSQC
/* Different sound & accuracy without silencer */
if (pl.a_ammo3 == 1) {
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 34, [0.01, 0.01], WEAPON_GLOCK);
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/pl_gun1.wav", 1, ATTN_NORM);
} else {
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 34, [0.1,0.1], WEAPON_GLOCK);
Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/pl_gun3.wav", 1, ATTN_NORM);
}
#endif
#ifdef CSQC
pl.a_ammo1--;
#else
pl.glock_mag--;
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
#endif
if (pl.a_ammo1) {
Weapons_ViewAnimation(GLOCK_SHOOT);
} else {
Weapons_ViewAnimation(GLOCK_SHOOT_EMPTY);
}
/* Fires faster without silencer */
if (pl.a_ammo3 == 1) {
pl.w_attack_next = 0.3f;
} else {
pl.w_attack_next = 0.2f;
}
pl.w_idle_next = 5.0f;
}
void
w_glock_release(void)
{
player pl = (player)self;
int r;
if (pl.w_idle_next > 0.0) {
return;
}
r = floor(random(0,3));
switch (r) {
case 1:
Weapons_ViewAnimation(GLOCK_IDLE2);
pl.w_idle_next = 2.5f;
break;
case 2:
Weapons_ViewAnimation(GLOCK_IDLE3);
pl.w_idle_next = 3.5f;
break;
default:
Weapons_ViewAnimation(GLOCK_IDLE1);
pl.w_idle_next = 3.75f;
break;
}
}
void
w_glock_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* toggle silencer */
pl.a_ammo3 = 1 - pl.a_ammo3;
if (pl.a_ammo3) {
Weapons_SetGeomset("geomset 1 2\n");
Weapons_ViewAnimation(GLOCK_SILENCER);
pl.w_attack_next = 3.3f;
pl.w_idle_next = pl.w_attack_next;
} else {
Weapons_SetGeomset("geomset 1 0\n");
Weapons_ViewAnimation(GLOCK_HOLSTER);
pl.w_attack_next = 0.94f;
pl.w_idle_next = pl.w_attack_next;
}
}
void
w_glock_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
if (pl.a_ammo1 >= 18) {
return;
}
if (pl.a_ammo2 <= 0) {
return;
}
if (pl.a_ammo1) {
Weapons_ViewAnimation(GLOCK_RELOAD);
} else {
Weapons_ViewAnimation(GLOCK_RELOAD_EMPTY);
}
#else
if (pl.glock_mag >= 18) {
return;
}
if (pl.ammo_9mm <= 0) {
return;
}
Weapons_ReloadWeapon(pl, player::glock_mag, player::ammo_9mm, 18);
#endif
pl.w_attack_next = 2.0f;
pl.w_idle_next = 10.0f;
}
float
w_glock_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIM1HAND : ANIM_AIM1HAND;
}
void
w_glock_hud(void)
{
#ifdef CSQC
static vector cross_pos;
cross_pos = (video_res / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],
"sprites/crosshairs.spr_0.tga",
[0.1875,0], [0.1875, 0.1875],
[1,1,1], 1, DRAWFLAG_NORMAL
);
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(
aicon_pos,
[24,24],
"sprites/640hud7.spr_0.tga",
[0,72/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
#endif
}
void
w_glock_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud05.spr_0.tga",
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud06.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_glock =
{
.id = ITEM_GLOCK,
.slot = 1,
.slot_pos = 0,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [32,16],
.ki_xy = [192,16],
.draw = w_glock_draw,
.holster = w_glock_holster,
.primary = w_glock_primary,
.secondary = w_glock_secondary,
.reload = w_glock_reload,
.release = w_glock_release,
.crosshair = w_glock_hud,
.precache = w_glock_precache,
.pickup = w_glock_pickup,
.updateammo = w_glock_updateammo,
.wmodel = w_glock_wmodel,
.pmodel = w_glock_pmodel,
.deathmsg = w_glock_deathmsg,
.aimanim = w_glock_aimanim,
.hudpic = w_glock_hudpic
};
#ifdef SSQC
void
weapon_9mmhandgun(void) {
Weapons_InitItem(WEAPON_GLOCK);
}
void
weapon_glock(void) {
Weapons_InitItem(WEAPON_GLOCK);
}
#endif

View File

@ -0,0 +1,266 @@
/*
* 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
{
HANDGRENADE_IDLE,
HANDGRENADE_FIDGET,
HANDGRENADE_PULLPIN,
HANDGRENADE_THROW1,
HANDGRENADE_THROW2,
HANDGRENADE_THROW3,
HANDGRENADE_HOLSTER,
HANDGRENADE_DRAW
};
/* It's just the grenade with a different model, they could
* have just renamed the model itself... why.
*/
void w_handgrenade_precache(void)
{
precache_sound("weapons/g_bounce1.wav");
precache_sound("weapons/g_bounce2.wav");
precache_sound("weapons/g_bounce3.wav");
precache_sound("weapons/g_bounce4.wav");
precache_sound("weapons/g_bounce5.wav");
precache_model("models/v_tnt.mdl");
precache_model("models/w_tnt.mdl");
precache_model("models/p_tnt.mdl");
}
void w_handgrenade_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_handgrenade, -1);
#endif
}
string w_handgrenade_wmodel(void)
{
return "models/w_tnt.mdl";
}
string w_handgrenade_pmodel(void)
{
return "models/p_tnt.mdl";
}
string w_handgrenade_deathmsg(void)
{
return "";
}
int w_handgrenade_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (pl.ammo_handgrenade < MAX_A_HANDGRENADE) {
pl.ammo_handgrenade = bound(0, pl.ammo_handgrenade + 1, MAX_A_HANDGRENADE);
} else {
return FALSE;
}
#endif
return TRUE;
}
#ifdef SSQC
void w_handgrenade_throw(void)
{
static void WeaponFrag_Throw_Explode( void )
{
Effect_CreateExplosion(self.origin);
Damage_Radius(self.origin, self.owner, 150, 150 * 2.5f, TRUE, WEAPON_HANDGRENADE);
sound(self, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM);
remove(self);
}
static void WeaponFrag_Throw_Touch( void )
{
if (other.takedamage == DAMAGE_YES) {
Damage_Apply(other, self.owner, 15, WEAPON_HANDGRENADE, DMG_BLUNT);
}
int r = floor(random(0,6));
string sample = sprintf("weapons/g_bounce%i.wav", r);
sound( self, CHAN_BODY, sample, 1, ATTN_NORM );
self.frame = 0;
}
player pl = (player)self;
vector vPLAngle = pl.v_angle;
if ( vPLAngle[0] < 0 ) {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 - 10) / 90.0);
} else {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 + 10) / 90.0);
}
float flVel = (90 - vPLAngle[0]) * 5;
if ( flVel > 1000 ) {
flVel = 1000;
}
makevectors( vPLAngle );
vector vecSrc = pl.origin + pl.view_ofs + v_forward * 16;
vector vecThrow = v_forward * flVel + pl.velocity;
entity eGrenade = spawn();
eGrenade.owner = pl;
eGrenade.classname = "remove_me";
eGrenade.solid = SOLID_BBOX;
eGrenade.frame = 1;
eGrenade.velocity = vecThrow;
eGrenade.movetype = MOVETYPE_BOUNCE;
eGrenade.think = WeaponFrag_Throw_Explode;
eGrenade.touch = WeaponFrag_Throw_Touch;
eGrenade.nextthink = time + 4.0f;
setmodel( eGrenade, "models/w_tnt.mdl" );
setsize( eGrenade, [0,0,0], [0,0,0] );
setorigin( eGrenade, vecSrc );
}
#endif
void w_handgrenade_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_tnt.mdl");
Weapons_ViewAnimation(HANDGRENADE_DRAW);
#endif
}
void w_handgrenade_holster(void)
{
}
void w_handgrenade_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* We're abusing this network variable for the holding check */
if (pl.a_ammo3 > 0) {
return;
}
/* Ammo check */
#ifdef CSQC
if (pl.a_ammo2 <= 0) {
return;
}
#else
if (pl.ammo_handgrenade <= 0) {
return;
}
#endif
#ifdef CSQC
Weapons_ViewAnimation(HANDGRENADE_PULLPIN);
#endif
pl.a_ammo3 = 1;
pl.w_attack_next = 0.5f;
pl.w_idle_next = 0.5f;
}
void w_handgrenade_hud(void)
{
#ifdef CSQC
HUD_DrawAmmo2();
vector aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(aicon_pos, [16,24], "sprites/640hud7.spr_0.tga", [48/256,96/128], [24/256, 24/128], g_hud_color, pSeat->ammo2_alpha, DRAWFLAG_ADDITIVE);
#endif
}
void w_handgrenade_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.a_ammo3 == 1) {
#ifdef CSQC
pl.a_ammo2--;
Weapons_ViewAnimation(HANDGRENADE_THROW1);
#else
pl.ammo_handgrenade--;
w_handgrenade_throw();
#endif
pl.a_ammo3 = 2;
pl.w_attack_next = 1.0f;
pl.w_idle_next = 0.5f;
} else if (pl.a_ammo3 == 2) {
#ifdef CSQC
Weapons_ViewAnimation(HANDGRENADE_DRAW);
#else
if (!pl.ammo_handgrenade) {
Weapons_RemoveItem(pl, WEAPON_HANDGRENADE);
}
#endif
pl.w_attack_next = 0.5f;
pl.w_idle_next = 0.5f;
pl.a_ammo3 = 0;
}
}
float
w_handgrenade_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR;
}
void
w_handgrenade_hudpic(int s, vector pos)
{
#ifdef CSQC
if (s) {
drawsubpic(pos, [170,45], "sprites/640hud6.spr_0.tga", [0,0], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
} else {
drawsubpic(pos, [170,45], "sprites/640hud3.spr_0.tga", [0,0], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
}
#endif
}
weapon_t w_handgrenade =
{
ITEM_HANDGRENADE,
4,
0,
"sprites/640hud1.spr_0.tga",
[32,16],
[192,160],
w_handgrenade_draw,
w_handgrenade_holster,
w_handgrenade_primary,
w_handgrenade_release,
w_handgrenade_release,
w_handgrenade_release,
w_handgrenade_hud,
w_handgrenade_precache,
w_handgrenade_pickup,
w_handgrenade_updateammo,
w_handgrenade_wmodel,
w_handgrenade_pmodel,
w_handgrenade_deathmsg,
w_handgrenade_aimanim,
w_handgrenade_hudpic
};
#ifdef SSQC
void weapon_handgrenade(void) {
Weapons_InitItem(WEAPON_HANDGRENADE);
}
#endif

View File

@ -0,0 +1,241 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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
{
MEDKIT_IDLE1,
MEDKIT_IDLE2,
MEDKIT_USE,
MEDKIT_UNUSED,
MEDKIT_HOLSTER,
MEDKIT_DRAW
};
void
w_medkit_precache(void)
{
precache_model("models/v_tfc_medkit.mdl");
precache_model("models/w_tfc_medkit.mdl");
precache_model("models/p_tfc_medkit.mdl");
}
void
w_medkit_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, pl.ammo_medkit, -1);
#endif
}
string
w_medkit_wmodel(void)
{
return "models/w_tfc_medkit.mdl";
}
string
w_medkit_pmodel(void)
{
return "models/p_tfc_medkit.mdl";
}
string
w_medkit_deathmsg(void)
{
return "%s was somehow killed by %s's Medkit.";
}
int
w_medkit_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.ammo_medkit = 8;
} else {
if (pl.ammo_medkit < MAX_A_MEDKIT) {
pl.ammo_medkit = bound(0, pl.ammo_medkit + 8, MAX_A_MEDKIT);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_medkit_draw(void)
{
Weapons_SetModel("models/v_tfc_medkit.mdl");
Weapons_ViewAnimation(MEDKIT_DRAW);
}
void
w_medkit_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef SSQC
if (!pl.ammo_medkit) {
return;
}
/* Don't give the player more than 100 health */
if (pl.health >= 100) {
return;
}
/* We want to only give health to the player & skip armor */
Damage_Apply(pl, pl, -15, WEAPON_MEDKIT, DMG_GENERIC );
pl.ammo_medkit--;
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
Weapons_PlaySound(pl, CHAN_WEAPON, "items/smallmedkit1.wav", 1, ATTN_NORM);
#endif
if (pl.health >= 100) {
return;
} else {
Weapons_ViewAnimation(MEDKIT_USE);
}
pl.w_attack_next = 2.4f;
pl.w_idle_next = 5.0f;
}
void
w_medkit_release(void)
{
player pl = (player)self;
int r;
if (pl.w_idle_next > 0.0) {
return;
}
r = floor(random(0,2));
switch (r) {
case 1:
Weapons_ViewAnimation(MEDKIT_IDLE1);
pl.w_idle_next = 1.16f;
break;
case 2:
Weapons_ViewAnimation(MEDKIT_IDLE2);
pl.w_idle_next = 2.36f;
break;
}
}
float
w_medkit_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMSQUEAK : ANIM_AIMSQUEAK;
}
void
w_medkit_crosshair(void)
{
#ifdef CSQC
vector aicon_pos;
aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
HUD_DrawAmmo2();
drawsubpic(
aicon_pos,
[24,24],
"sprites/640hud7.spr_0.tga",
[24/256,96/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
#endif
}
void
w_medkit_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud05.spr_0.tga",
[0,180/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud06.spr_0.tga",
[0,90/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_medkit =
{
.id = ITEM_MEDKIT2,
.slot = 4,
.slot_pos = 4,
.ki_spr = "sprites/tfc_dmsg.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [0,192],
.draw = w_medkit_draw,
.holster = __NULL__,
.primary = w_medkit_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_medkit_release,
.crosshair = w_medkit_crosshair,
.precache = w_medkit_precache,
.pickup = w_medkit_pickup,
.updateammo = w_medkit_updateammo,
.wmodel = w_medkit_wmodel,
.pmodel = w_medkit_pmodel,
.deathmsg = w_medkit_deathmsg,
.aimanim = w_medkit_aimanim,
.hudpic = w_medkit_hudpic
};
#ifdef SSQC
void
weapon_th_medkit(void) {
Weapons_InitItem(WEAPON_MEDKIT);
}
#endif

View File

@ -0,0 +1,248 @@
/*
* 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
{
SHOVEL_IDLE,
SHOVEL_DRAW,
SHOVEL_HOLSTER,
SHOVEL_ATTACK1HIT,
SHOVEL_ATTACK1MISS,
SHOVEL_ATTACK2MISS,
SHOVEL_ATTACK2HIT,
SHOVEL_ATTACK3MISS,
SHOVEL_ATTACK3HIT
};
void
w_shovel_precache(void)
{
precache_sound("weapons/cbar_miss1.wav");
precache_sound("weapons/cbar_hit1.wav");
precache_sound("weapons/cbar_hit2.wav");
precache_sound("weapons/cbar_hitbod1.wav");
precache_sound("weapons/cbar_hitbod2.wav");
precache_sound("weapons/cbar_hitbod3.wav");
precache_model("models/v_shovel.mdl");
precache_model("models/w_shovel.mdl");
precache_model("models/p_shovel.mdl");
}
void
w_shovel_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, -1, -1);
#endif
}
string
w_shovel_wmodel(void)
{
return "models/w_shovel.mdl";
}
string
w_shovel_pmodel(void)
{
return "models/p_shovel.mdl";
}
string
w_shovel_deathmsg(void)
{
return "%s was assaulted by %s's Crowbar.";
}
void
w_shovel_draw(void)
{
Weapons_SetModel("models/v_shovel.mdl");
Weapons_ViewAnimation(SHOVEL_DRAW);
}
void
w_shovel_holster(void)
{
Weapons_ViewAnimation(SHOVEL_HOLSTER);
}
void
w_shovel_primary(void)
{
int anim = 0;
int r;
vector src;
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
Weapons_MakeVectors();
src = pl.origin + pl.view_ofs;
traceline(src, src + (v_forward * 32), FALSE, pl);
if (trace_fraction >= 1.0) {
pl.w_attack_next = 0.5f;
} else {
pl.w_attack_next = 0.25f;
}
pl.w_idle_next = 2.5f;
#ifdef CSQC
r = floor(random(0,3));
switch (r) {
case 0:
anim = trace_fraction >= 1 ? SHOVEL_ATTACK1MISS:SHOVEL_ATTACK1HIT;
break;
case 1:
anim = trace_fraction >= 1 ? SHOVEL_ATTACK2MISS:SHOVEL_ATTACK2HIT;
break;
default:
anim = trace_fraction >= 1 ? SHOVEL_ATTACK3MISS:SHOVEL_ATTACK3HIT;
}
Weapons_ViewAnimation(anim);
#else
if (pl.flags & FL_CROUCHING) {
Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f);
} else {
Animation_PlayerTopTemp(ANIM_CR_SHOOTCROWBAR, 0.42f);
}
sound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1, ATTN_NORM);
if (trace_fraction >= 1.0) {
return;
}
/* don't bother with decals, we got squibs */
if (trace_ent.iBleeds) {
Effect_CreateBlood(trace_endpos, [0,0,0]);
} else {
Effect_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal);
}
if (trace_ent.takedamage) {
Damage_Apply(trace_ent, self, 10, WEAPON_SHOVEL, DMG_BLUNT );
if (!trace_ent.iBleeds) {
return;
}
r = floor(random(0,3));
switch (r) {
case 0:
sound(pl, 8, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
break;
case 1:
sound(pl, 8, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM);
break;
case 2:
sound(pl, 8, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM);
break;
}
} else {
if (random() < 0.5) {
sound(pl, 8, "weapons/cbar_hit1.wav", 1, ATTN_NORM);
} else {
sound(pl, 8, "weapons/cbar_hit2.wav", 1, ATTN_NORM);
}
}
#endif
}
void
w_shovel_release(void)
{
player pl = (player)self;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(SHOVEL_IDLE);
pl.w_idle_next = 15.0f;
}
float
w_shovel_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR;
}
void
w_shovel_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud04.spr_0.tga",
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud03.spr_0.tga",
[0,90/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_shovel =
{
.id = ITEM_SHOVEL,
.slot = 0,
.slot_pos = 1,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [192,0],
.draw = w_shovel_draw,
.holster = w_shovel_holster,
.primary = w_shovel_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_shovel_release,
.crosshair = __NULL__,
.precache = w_shovel_precache,
.pickup = __NULL__,
.updateammo = w_shovel_updateammo,
.wmodel = w_shovel_wmodel,
.pmodel = w_shovel_pmodel,
.deathmsg = w_shovel_deathmsg,
.aimanim = w_shovel_aimanim,
.hudpic = w_shovel_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_th_shovel(void)
{
Weapons_InitItem(WEAPON_SHOVEL);
}
#endif

View File

@ -0,0 +1,354 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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
{
SNIPER_IDLE1,
SNIPER_UNUSED1,
SNIPER_FIRE1,
SNIPER_DRAW,
SNIPER_HOLSTER,
SNIPER_IDLE2
};
void
w_sniper_precache(void)
{
precache_model("models/v_tfc_sniper.mdl");
precache_model("models/w_isotopebox.mdl");
precache_model("models/p_sniper.mdl");
precache_sound("weapons/sniper.wav");
precache_sound("weapons/reload3.wav");
}
int
w_sniper_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.sniper_mag = 5;
} else {
if (pl.ammo_sniper < MAX_A_SNIPER) {
pl.ammo_sniper = bound(0, pl.ammo_sniper + 5, MAX_A_SNIPER);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_sniper_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.sniper_mag, pl.ammo_sniper, -1);
#endif
}
string
w_sniper_wmodel(void)
{
return "models/w_isotopebox.mdl";
}
string
w_sniper_pmodel(void)
{
return "models/p_sniper.mdl";
}
string
w_sniper_deathmsg(void)
{
return "";
}
void
w_sniper_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_tfc_sniper.mdl");
Weapons_ViewAnimation(SNIPER_DRAW);
#endif
}
void
w_sniper_holster(void)
{
#ifdef CSQC
Weapons_ViewAnimation(SNIPER_HOLSTER);
#endif
}
void
w_sniper_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.a_ammo3 == 1) {
Weapons_ViewAnimation(SNIPER_DRAW);
pl.a_ammo3 = 0;
pl.w_attack_next = 0.0f;
pl.w_idle_next = 15.0f;
return;
}
int r = floor(random(0,2));
switch (r) {
case 0:
Weapons_ViewAnimation(SNIPER_IDLE1);
pl.w_idle_next = 3.0f;
break;
case 1:
Weapons_ViewAnimation(SNIPER_IDLE2);
pl.w_idle_next = 2.0f;
break;
}
pl.w_idle_next = 15.0f;
}
void
w_sniper_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* Ammo check */
#ifdef CSQC
if (pl.a_ammo1 <= 0) {
return;
}
#else
if (pl.sniper_mag <= 0) {
return;
}
#endif
/* Actual firing */
#ifdef CSQC
pl.a_ammo1--;
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-20,0,0]);
Weapons_ViewAnimation(SNIPER_FIRE1);
#else
pl.sniper_mag--;
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 40, [0.008, 0.008], WEAPON_SNIPER);
sound(pl, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM);
#endif
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.w_attack_next = 0.1f;
} else {
pl.w_attack_next = 1.0f;
}
pl.w_idle_next = 10.0f;
}
void
w_sniper_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.25f;
} else {
pl.viewzoom = 1.0f;
}
pl.w_attack_next = 0.5f;
}
void
w_sniper_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
w_sniper_release();
return;
}
#ifdef CSQC
if (pl.a_ammo1 >= 5) {
return;
}
if (pl.a_ammo2 <= 0) {
return;
}
Weapons_ViewAnimation(SNIPER_HOLSTER);
#else
if (pl.sniper_mag >= 5) {
return;
}
if (pl.ammo_sniper <= 0) {
return;
}
sound(pl, CHAN_WEAPON, "weapons/reload3.wav", 1, ATTN_NORM);
Weapons_ReloadWeapon(pl, player::sniper_mag, player::ammo_sniper, 5);
#endif
pl.a_ammo3 = 1;
pl.w_attack_next = 2.5f;
pl.w_idle_next = 2.0f;
}
void
w_sniper_crosshair(void)
{
#ifdef CSQC
player pl = (player)self;
static vector cross_pos;
vector aicon_pos;
if (pl.viewzoom < 1.0f) {
drawfill(
video_mins,
video_res,
[0,0.2,0],
1.0f,
DRAWFLAG_ADDITIVE
);
cross_pos = video_mins + (video_res / 2) + [-128,-104];
drawpic(
cross_pos,
"sprites/nmxhair2.spr_0.tga",
[256,208],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
} else {
cross_pos = video_mins + (video_res / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],
"sprites/crosshairs.spr_0.tga",
[48/128,0],
[24/128,24/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(
aicon_pos,
[24,24],
"sprites/640hud7.spr_0.tga",
[24/256,72/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
#endif
}
float
w_sniper_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMPYTHON : ANIM_AIMPYTHON;
}
void
w_sniper_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud02.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud01.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_sniper =
{
.id = ITEM_SNIPER,
.slot = 2,
.slot_pos = 3,
.ki_spr = "sprites/tfc_dmsg.spr_0.tga",
.ki_size = [60,16],
.ki_xy = [0,96],
.draw = w_sniper_draw,
.holster = w_sniper_holster,
.primary = w_sniper_primary,
.secondary = w_sniper_secondary,
.reload = w_sniper_reload,
.release = w_sniper_release,
.crosshair = w_sniper_crosshair,
.precache = w_sniper_precache,
.pickup = w_sniper_pickup,
.updateammo = w_sniper_updateammo,
.wmodel = w_sniper_wmodel,
.pmodel = w_sniper_pmodel,
.deathmsg = w_sniper_deathmsg,
.aimanim = w_sniper_aimanim,
.hudpic = w_sniper_hudpic
};
/* pickups */
#ifdef SSQC
void
weapon_einar1(void)
{
Weapons_InitItem(WEAPON_SNIPER);
}
#endif

View File

@ -0,0 +1,337 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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
{
SNIPER_IDLE,
SNIPER_RELOAD,
SNIPER_DRAW,
SNIPER_FIRE
};
void
w_sniper2_precache(void)
{
precache_model("models/v_hkg36.mdl");
precache_model("models/w_hkg36.mdl");
precache_model("models/p_hkg36.mdl");
precache_sound("weapons/sniper.wav");
}
int
w_sniper2_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.sniper_mag = 5;
} else {
if (pl.ammo_sniper < MAX_A_SNIPER) {
pl.ammo_sniper = bound(0, pl.ammo_sniper + 5, MAX_A_SNIPER);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_sniper2_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.sniper_mag, pl.ammo_sniper, -1);
#endif
}
string
w_sniper2_wmodel(void)
{
return "models/w_hkg36.mdl";
}
string
w_sniper2_pmodel(void)
{
return "models/p_hkg36.mdl";
}
string
w_sniper2_deathmsg(void)
{
return "";
}
void
w_sniper2_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_hkg36.mdl");
Weapons_ViewAnimation(SNIPER_DRAW);
#endif
}
void
w_sniper2_holster(void)
{
}
void
w_sniper2_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
int r = floor(random(0,2));
switch (r) {
case 0:
Weapons_ViewAnimation(SNIPER_IDLE1);
pl.w_idle_next = 3.0f;
break;
case 1:
Weapons_ViewAnimation(SNIPER_IDLE2);
pl.w_idle_next = 2.0f;
break;
}
pl.w_idle_next = 15.0f;
}
void
w_sniper2_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* Ammo check */
#ifdef CSQC
if (pl.a_ammo1 <= 0) {
return;
}
#else
if (pl.sniper_mag <= 0) {
return;
}
#endif
/* Actual firing */
#ifdef CSQC
pl.a_ammo1--;
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-20,0,0]);
Weapons_ViewAnimation(SNIPER_FIRE);
#else
pl.sniper_mag--;
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 40, [0.008, 0.008], WEAPON_SNIPER);
sound(pl, CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM);
#endif
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.w_attack_next = 0.1f;
} else {
pl.w_attack_next = 1.0f;
}
pl.w_idle_next = 10.0f;
}
void
w_sniper2_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.25f;
} else {
pl.viewzoom = 1.0f;
}
pl.w_attack_next = 0.5f;
}
void
w_sniper2_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
if (pl.a_ammo1 >= 5) {
return;
}
if (pl.a_ammo2 <= 0) {
return;
}
Weapons_ViewAnimation(SNIPER_RELOAD);
#else
if (pl.sniper_mag >= 5) {
return;
}
if (pl.ammo_sniper <= 0) {
return;
}
Weapons_ReloadWeapon(pl, player::sniper_mag, player::ammo_sniper, 5);
#endif
pl.w_attack_next = 3.82f;
pl.w_idle_next = 5.0f;
}
void
w_sniper2_crosshair(void)
{
#ifdef CSQC
player pl = (player)self;
static vector cross_pos;
vector aicon_pos;
if (pl.viewzoom < 1.0f) {
drawfill(
video_mins,
video_res,
[0.2,0,0],
1.0f,
DRAWFLAG_ADDITIVE
);
cross_pos = video_mins + (video_res / 2) + [-128,-104];
drawpic(
cross_pos,
"sprites/nmxhair2.spr_0.tga",
[256,208],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
} else {
cross_pos = video_mins + (video_res / 2) + [-12,-12];
drawsubpic(
cross_pos,
[24,24],
"sprites/crosshairs.spr_0.tga",
[48/128,0],
[24/128,24/128],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(
aicon_pos,
[24,24],
"sprites/640hud7.spr_0.tga",
[24/256,72/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
#endif
}
float
w_sniper2_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMPYTHON : ANIM_AIMPYTHON;
}
void
w_sniper2_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud02.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud01.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_sniper2 =
{
.id = ITEM_SNIPER2,
.slot = 2,
.slot_pos = 4,
.ki_spr = "sprites/tfc_dmsg.spr_0.tga",
.ki_size = [60,16],
.ki_xy = [0,96],
.draw = w_sniper2_draw,
.holster = w_sniper2_holster,
.primary = w_sniper2_primary,
.secondary = w_sniper2_secondary,
.reload = w_sniper2_reload,
.release = w_sniper2_release,
.crosshair = w_sniper2_crosshair,
.precache = w_sniper2_precache,
.pickup = w_sniper2_pickup,
.updateammo = w_sniper2_updateammo,
.wmodel = w_sniper2_wmodel,
.pmodel = w_sniper2_pmodel,
.deathmsg = w_sniper2_deathmsg,
.aimanim = w_sniper2_aimanim,
.hudpic = w_sniper2_hudpic
};
/* pickups */
#ifdef SSQC
void
weapon_th_sniper(void)
{
Weapons_InitItem(WEAPON_SNIPER2);
}
#endif

View File

@ -0,0 +1,240 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
* Copyright (c) 2019 Gethyn ThomasQuail <xylemon@posteo.net>
*
* 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
{
SPAN_IDLE,
SPAN_ATTACK1,
SPAN_ATTACK2,
SPAN_UNUSED,
SPAN_DRAW,
SPAN_HOLSTER
};
void
w_spanner_precache(void)
{
precache_sound("weapons/cbar_miss1.wav");
precache_sound("weapons/cbar_hit1.wav");
precache_sound("weapons/cbar_hit2.wav");
precache_sound("weapons/cbar_hitbod1.wav");
precache_sound("weapons/cbar_hitbod2.wav");
precache_sound("weapons/cbar_hitbod3.wav");
precache_model("models/v_tfc_spanner.mdl");
precache_model("models/backpack.mdl");
precache_model("models/p_spanner.mdl");
}
void
w_spanner_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, -1, -1, -1);
#endif
}
string
w_spanner_wmodel(void)
{
return "models/backpack.mdl";
}
string
w_spanner_pmodel(void)
{
return "models/p_spanner.mdl";
}
string
w_spanner_deathmsg(void)
{
return "%s was assaulted by %s's Crowbar.";
}
void
w_spanner_draw(void)
{
Weapons_SetModel("models/v_tfc_spanner.mdl");
Weapons_ViewAnimation(SPAN_DRAW);
}
void
w_spanner_holster(void)
{
Weapons_ViewAnimation(SPAN_HOLSTER);
}
void
w_spanner_primary(void)
{
int anim = 0;
int r;
vector src;
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
Weapons_MakeVectors();
src = pl.origin + pl.view_ofs;
traceline(src, src + (v_forward * 32), FALSE, pl);
if (trace_fraction >= 1.0) {
pl.w_attack_next = 0.375f;
} else {
pl.w_attack_next = 0.20f;
}
pl.w_idle_next = 2.5f;
#ifdef CSQC
if (random() < 0.5) {
Weapons_ViewAnimation(SPAN_ATTACK1);
} else {
Weapons_ViewAnimation(SPAN_ATTACK2);
}
#else
if (pl.flags & FL_CROUCHING) {
Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f);
} else {
Animation_PlayerTopTemp(ANIM_CR_SHOOTCROWBAR, 0.42f);
}
sound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1, ATTN_NORM);
if (trace_fraction >= 1.0) {
return;
}
/* don't bother with decals, we got squibs */
if (trace_ent.iBleeds) {
Effect_CreateBlood(trace_endpos, [0,0,0]);
} else {
Effect_Impact(IMPACT_MELEE, trace_endpos, trace_plane_normal);
}
if (trace_ent.takedamage) {
Damage_Apply(trace_ent, self, 10, WEAPON_SPANNER, DMG_BLUNT );
if (!trace_ent.iBleeds) {
return;
}
r = floor(random(0,3));
switch (r) {
case 0:
sound(pl, 8, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
break;
case 1:
sound(pl, 8, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM);
break;
case 2:
sound(pl, 8, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM);
break;
}
} else {
if (random() < 0.5) {
sound(pl, 8, "weapons/cbar_hit1.wav", 1, ATTN_NORM);
} else {
sound(pl, 8, "weapons/cbar_hit2.wav", 1, ATTN_NORM);
}
}
#endif
}
void
w_spanner_release(void)
{
player pl = (player)self;
if (pl.w_idle_next) {
return;
}
Weapons_ViewAnimation(SPAN_IDLE);
pl.w_idle_next = 15.0f;
}
float
w_spanner_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR;
}
void
w_spanner_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/tfchud04.spr_0.tga",
[0,180/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/tfchud03.spr_0.tga",
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_spanner =
{
.id = ITEM_SPANNER,
.slot = 0,
.slot_pos = 2,
.ki_spr = "sprites/tfc_dmsg.spr_0.tga",
.ki_size = [48,16],
.ki_xy = [0,48],
.draw = w_spanner_draw,
.holster = w_spanner_holster,
.primary = w_spanner_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_spanner_release,
.crosshair = __NULL__,
.precache = w_spanner_precache,
.pickup = __NULL__,
.updateammo = w_spanner_updateammo,
.wmodel = w_spanner_wmodel,
.pmodel = w_spanner_pmodel,
.deathmsg = w_spanner_deathmsg,
.aimanim = w_spanner_aimanim,
.hudpic = w_spanner_hudpic
};
/* entity definitions for pickups */
#ifdef SSQC
void
weapon_th_spanner(void)
{
Weapons_InitItem(WEAPON_SPANNER);
}
#endif

View File

@ -0,0 +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.
*/
enum
{
TAURUS_IDLE1,
TAURUS_IDLE2,
TAURUS_IDLE3,
TAURUS_SHOOT,
TAURUS_SHOOT2,
TAURUS_SHOOT3,
TAURUS_SHOOT_EMPTY,
TAURUS_RELOAD,
TAURUS_RELOAD2,
TAURUS_DRAW,
TAURUS_HOLSTER
};
void
w_taurus_precache(void)
{
precache_model("models/v_taurus.mdl");
precache_model("models/w_taurus.mdl");
precache_model("models/p_taurus.mdl");
precache_sound("weapons/tau_fire.wav");
}
void
w_taurus_updateammo(player pl)
{
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.taurus_mag, pl.ammo_taurus, -1);
#endif
}
string
w_taurus_wmodel(void)
{
return "models/w_taurus.mdl";
}
string
w_taurus_pmodel(void)
{
return "models/p_taurus.mdl";
}
string
w_taurus_deathmsg(void)
{
return "";
}
int
w_taurus_pickup(int new)
{
#ifdef SSQC
player pl = (player)self;
if (new) {
pl.taurus_mag = 10;
} else {
if (pl.ammo_taurus < MAX_A_TAURUS) {
pl.ammo_taurus = bound(0, pl.ammo_taurus + 10, MAX_A_TAURUS);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_taurus_draw(void)
{
#ifdef CSQC
Weapons_SetModel("models/v_taurus.mdl");
#endif
}
void
w_taurus_holster(void)
{
#ifdef CSQC
Weapons_ViewAnimation(TAURUS_HOLSTER);
#endif
}
void
w_taurus_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* ammo check */
#ifdef CSQC
if (!pl.a_ammo1) {
return;
}
#else
if (!pl.taurus_mag) {
return;
}
#endif
/* actual firing */
#ifdef CSQC
pl.a_ammo1--;
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-2,0,0]);
if (pl.a_ammo1) {
Weapons_ViewAnimation(TAURUS_SHOOT);
} else {
Weapons_ViewAnimation(TAURUS_SHOOT_EMPTY);
}
#else
pl.taurus_mag--;
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 12, [0.01,0,01], WEAPON_TAURUS);
sound(pl, CHAN_WEAPON, "weapons/tau_fire.wav", 1.0f, ATTN_NORM);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f);
#endif
pl.w_attack_next = 0.25f;
pl.w_idle_next = 5.0f;
}
void
w_taurus_secondary(void)
{
}
void
w_taurus_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CSQC
if (pl.a_ammo1 >= 10) {
return;
}
if (pl.a_ammo2 <= 0) {
return;
}
if (pl.a_ammo1) {
Weapons_ViewAnimation(TAURUS_RELOAD);
} else {
Weapons_ViewAnimation(TAURUS_RELOAD2);
}
#else
if (pl.taurus_mag >= 10) {
return;
}
if (pl.ammo_taurus <= 0) {
return;
}
Weapons_ReloadWeapon(pl, player::taurus_mag, player::ammo_taurus, 10);
#endif
pl.w_attack_next = 2.0f;
pl.w_idle_next = 10.0f;
}
void
w_taurus_release(void)
{
player pl = (player)self;
int r;
if (pl.w_idle_next > 0.0) {
return;
}
r = floor(random(0,3));
switch (r) {
case 1:
Weapons_ViewAnimation(TAURUS_IDLE2);
pl.w_idle_next = 2.25f;
break;
case 2:
Weapons_ViewAnimation(TAURUS_IDLE3);
pl.w_idle_next = 2.5f;
break;
default:
Weapons_ViewAnimation(TAURUS_IDLE1);
pl.w_idle_next = 2.81f;
break;
}
}
float
w_taurus_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CR_AIM1HAND : ANIM_AIM1HAND;
}
void
w_taurus_hud(void)
{
#ifdef CSQC
vector cross_pos;
vector aicon_pos;
cross_pos = video_mins + (video_res / 2) + [-12,-12];
aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42];
drawsubpic(
cross_pos,
[24,24],
"sprites/crosshairs.spr_0.tga",
[0.1875,0],
[0.1875, 0.1875],
[1,1,1],
1.0f,
DRAWFLAG_NORMAL
);
HUD_DrawAmmo1();
HUD_DrawAmmo2();
drawsubpic(
aicon_pos,
[24,24],
"sprites/640hud7.spr_0.tga",
[0,72/128],
[24/256, 24/128],
g_hud_color,
pSeat->ammo2_alpha,
DRAWFLAG_ADDITIVE
);
#endif
}
void
w_taurus_hudpic(int selected, vector pos)
{
#ifdef CSQC
if (selected) {
drawsubpic(
pos,
[170,45],
"sprites/640hud4.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
"sprites/640hud1.spr_0.tga",
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_taurus =
{
.id = ITEM_TAURUS,
.slot = 1,
.slot_pos = 3,
.ki_spr = "sprites/640hud1.spr_0.tga",
.ki_size = [32,16],
.ki_xy = [192,16],
.draw = w_taurus_draw,
.holster = w_taurus_holster,
.primary = w_taurus_primary,
.secondary = w_taurus_secondary,
.reload = w_taurus_reload,
.release = w_taurus_release,
.crosshair = w_taurus_hud,
.precache = w_taurus_precache,
.pickup = w_taurus_pickup,
.updateammo = w_taurus_updateammo,
.wmodel = w_taurus_wmodel,
.pmodel = w_taurus_pmodel,
.deathmsg = w_taurus_deathmsg,
.aimanim = w_taurus_aimanim,
.hudpic = w_taurus_hudpic
};
/* pickups */
#ifdef SSQC
void
weapon_th_taurus(void)
{
Weapons_InitItem(WEAPON_TAURUS);
}
#endif

View File

@ -0,0 +1,41 @@
/*
* 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_null = {};
weapon_t g_weapons[] = {
w_null,
w_crowbar,
w_shovel,
w_spanner,
w_glock,
w_python,
w_ap9,
w_taurus,
w_mp5,
w_shotgun,
w_crossbow,
w_sniper,
w_sniper2,
w_rpg,
w_gauss,
w_flame,
w_chaingun,
w_handgrenade,
w_satchel,
w_tripmine,
w_snark,
w_medkit
};

View File

@ -0,0 +1,60 @@
/*
* 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 Indices for the weapon table */
enum
{
WEAPON_NONE,
WEAPON_CROWBAR,
WEAPON_SHOVEL,
WEAPON_SPANNER,
WEAPON_GLOCK,
WEAPON_PYTHON,
WEAPON_AP9,
WEAPON_TAURUS,
WEAPON_MP5,
WEAPON_SHOTGUN,
WEAPON_CROSSBOW,
WEAPON_SNIPER,
WEAPON_SNIPER2,
WEAPON_RPG,
WEAPON_GAUSS,
WEAPON_FLAME,
WEAPON_CHAINGUN,
WEAPON_HANDGRENADE,
WEAPON_SATCHEL,
WEAPON_TRIPMINE,
WEAPON_SNARK,
WEAPON_MEDKIT
};
#define MAX_A_9MM 250
#define MAX_A_357 36
#define MAX_A_AP9 200
#define MAX_A_TAURUS 80
#define MAX_A_BUCKSHOT 125
#define MAX_A_M203_GRENADE 10
#define MAX_A_BOLT 50
#define MAX_A_SNIPER 50
#define MAX_A_ROCKET 5
#define MAX_A_URANIUM 100
#define MAX_A_GAS 100
#define MAX_A_HANDGRENADE 10
#define MAX_A_SATCHEL 5
#define MAX_A_TRIPMINE 10
#define MAX_A_SNARK 10
#define MAX_A_HORNET 8
#define MAX_A_MEDKIT 12