From bf5c78fab221938a610b69f02b7d08bb28c93e22 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Thu, 12 Sep 2019 01:08:56 +0200 Subject: [PATCH] Opposing Force: Initial commit of weapons. Includes some networking fixes so we can actually use 32bits of items. That's what these mods are good for - testing the infrastructure. --- src/Makefile | 3 + src/client/gearbox/hud_weaponselect.c | 170 +++++++++++++ src/client/gearbox/init.c | 55 +++++ src/client/gearbox/progs.src | 80 ++++++ src/client/valve/player.c | 2 +- src/gs-entbase/client/text.cpp | 1 + src/server/gearbox/ammo_op4.cpp | 123 ++++++++++ src/server/gearbox/input.c | 82 +++++++ src/server/gearbox/progs.src | 88 +++++++ src/server/valve/defs.h | 2 +- src/server/valve/player.c | 2 +- src/server/valve/progs.src | 10 - src/shared/gearbox/items.h | 51 ++++ src/shared/gearbox/player.cpp | 123 ++++++++++ src/shared/gearbox/w_displacer.c | 168 +++++++++++++ src/shared/gearbox/w_eagle.c | 339 ++++++++++++++++++++++++++ src/shared/gearbox/w_grapple.c | 173 +++++++++++++ src/shared/gearbox/w_knife.c | 269 ++++++++++++++++++++ src/shared/gearbox/w_m249.c | 301 +++++++++++++++++++++++ src/shared/gearbox/w_penguin.c | 321 ++++++++++++++++++++++++ src/shared/gearbox/w_pipewrench.c | 336 +++++++++++++++++++++++++ src/shared/gearbox/w_shockrifle.c | 294 ++++++++++++++++++++++ src/shared/gearbox/w_sniperrifle.c | 288 ++++++++++++++++++++++ src/shared/gearbox/w_sporelauncher.c | 285 ++++++++++++++++++++++ src/shared/gearbox/weapons.c | 44 ++++ src/shared/gearbox/weapons.h | 64 +++++ src/shared/valve/w_crowbar.c | 35 +-- src/shared/valve/w_glock.c | 1 + src/shared/valve/w_snark.c | 2 +- src/shared/valve/weapon_common.c | 11 + 30 files changed, 3694 insertions(+), 29 deletions(-) create mode 100644 src/client/gearbox/hud_weaponselect.c create mode 100644 src/client/gearbox/init.c create mode 100644 src/client/gearbox/progs.src create mode 100644 src/server/gearbox/ammo_op4.cpp create mode 100644 src/server/gearbox/input.c create mode 100755 src/server/gearbox/progs.src create mode 100644 src/shared/gearbox/items.h create mode 100644 src/shared/gearbox/player.cpp create mode 100644 src/shared/gearbox/w_displacer.c create mode 100644 src/shared/gearbox/w_eagle.c create mode 100644 src/shared/gearbox/w_grapple.c create mode 100644 src/shared/gearbox/w_knife.c create mode 100644 src/shared/gearbox/w_m249.c create mode 100644 src/shared/gearbox/w_penguin.c create mode 100644 src/shared/gearbox/w_pipewrench.c create mode 100644 src/shared/gearbox/w_shockrifle.c create mode 100644 src/shared/gearbox/w_sniperrifle.c create mode 100644 src/shared/gearbox/w_sporelauncher.c create mode 100644 src/shared/gearbox/weapons.c create mode 100644 src/shared/gearbox/weapons.h diff --git a/src/Makefile b/src/Makefile index bcf322c7..c90969bb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,6 +14,9 @@ qc-progs: mkdir -p ../rewolf/data.pk3dir $(CC) client/rewolf/progs.src $(CC) server/rewolf/progs.src + mkdir -p ../gearbox/data.pk3dir + $(CC) client/gearbox/progs.src + $(CC) server/gearbox/progs.src mkdir -p ../tfc/data.pk3dir $(CC) client/tfc/progs.src $(CC) server/tfc/progs.src diff --git a/src/client/gearbox/hud_weaponselect.c b/src/client/gearbox/hud_weaponselect.c new file mode 100644 index 00000000..bbfeb8d0 --- /dev/null +++ b/src/client/gearbox/hud_weaponselect.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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[8] = +{ + [168 / 255,72 / 128], + [188 / 255,72 / 128], + [208 / 255,72 / 128], + [168 / 255,92 / 128], + [188 / 255,92 / 128], + [228 / 255,72 / 128], + [228 / 255,92 / 128], + [208 / 255,92 / 128], +}; + +void HUD_DrawWeaponSelect_Forward(void) +{ + player pl = (player)pSeat->ePlayer; + + if (!pl.activeweapon) { + 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; + + /* compiler bug */ + if (pl.g_items & g_weapons[pSeat->fHUDWeaponSelected].id) { + } else { + HUD_DrawWeaponSelect_Forward(); + } +} + +void HUD_DrawWeaponSelect_Back(void) +{ + player pl = (player)pSeat->ePlayer; + + if (!pl.activeweapon) { + 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; + + /* compiler bug */ + if (pl.g_items & g_weapons[pSeat->fHUDWeaponSelected].id) { + } else { + 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/255, 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 < 7; 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, 7); + vecPos[1] += 25; + } + } + + if (slot_selected == TRUE) { + vecPos[0] += 175; + } else { + vecPos[0] += 25; + } + } +} diff --git a/src/client/gearbox/init.c b/src/client/gearbox/init.c new file mode 100644 index 00000000..8db19945 --- /dev/null +++ b/src/client/gearbox/init.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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/640hudof01.spr"); + precache_model("sprites/640hudof02.spr"); + precache_model("sprites/640hudof03.spr"); + precache_model("sprites/640hudof04.spr"); + precache_model("sprites/640hudof05.spr"); + precache_model("sprites/640hudof06.spr"); + precache_model("sprites/ofch1.spr"); + precache_model("sprites/ofch2.spr"); + precache_model("sprites/320hudof01.spr"); + + BEAM_TRIPMINE = particleeffectnum("beam_tripmine"); +} + +void Client_InitDone(void) +{ +} + +void Game_RendererRestarted(string rstr) +{ + +} diff --git a/src/client/gearbox/progs.src b/src/client/gearbox/progs.src new file mode 100644 index 00000000..f3eeb9b9 --- /dev/null +++ b/src/client/gearbox/progs.src @@ -0,0 +1,80 @@ +#pragma target fte +#pragma progs_dat "../../../gearbox/data.pk3dir/csprogs.dat" + +#define CSQC +#define VALVE + +#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 +../../gs-entbase/client.src +../sound.c +../text.c +../voice.c +../../shared/valve/animations.h +../../shared/valve/animations.c +../../shared/gearbox/player.cpp +../player.c +../../shared/pmove.c +../predict.c +../../shared/decals.c +../../shared/effects.c +../../shared/spraylogo.cpp +../npc.c +init.c +../../shared/gearbox/items.h +../../shared/valve/weapon_common.h +../../shared/gearbox/weapons.h +../../shared/valve/w_crossbow.c +../../shared/valve/w_crowbar.c +../../shared/valve/w_egon.c +../../shared/valve/w_gauss.c +../../shared/valve/w_glock.c +../../shared/valve/w_handgrenade.c +../../shared/valve/w_hornetgun.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/gearbox/w_pipewrench.c +../../shared/gearbox/w_knife.c +../../shared/gearbox/w_grapple.c +../../shared/gearbox/w_eagle.c +../../shared/gearbox/w_m249.c +../../shared/gearbox/w_displacer.c +../../shared/gearbox/w_sniperrifle.c +../../shared/gearbox/w_sporelauncher.c +../../shared/gearbox/w_penguin.c +../../shared/gearbox/w_shockrifle.c +../../shared/gearbox/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 +hud_weaponselect.c +../valve/scoreboard.c +../valve/input.c +../entry.c +#endlist diff --git a/src/client/valve/player.c b/src/client/valve/player.c index ce1d2a29..e4d863e1 100644 --- a/src/client/valve/player.c +++ b/src/client/valve/player.c @@ -85,7 +85,7 @@ Player_ReadEntity(float new) if (fl & PLAYER_WEAPON) pl.activeweapon = readbyte(); if (fl & PLAYER_ITEMS) - pl.g_items = readfloat(); + pl.g_items = (__variant)readfloat(); if (fl & PLAYER_HEALTH) pl.health = readbyte(); if (fl & PLAYER_ARMOR) diff --git a/src/gs-entbase/client/text.cpp b/src/gs-entbase/client/text.cpp index 7630cf9c..77c3e128 100644 --- a/src/gs-entbase/client/text.cpp +++ b/src/gs-entbase/client/text.cpp @@ -67,6 +67,7 @@ GameText_DrawString(vector pos, string msg, vector col, float alpha) rpos[1] = ((video_res[1] - 12) * pos[1]); } rpos[1] += 20 * i; + rpos[1] -= (20 * c) / 2; drawstring(rpos, argv(i), '20 20', col, alpha, DRAWFLAG_ADDITIVE); } diff --git a/src/server/gearbox/ammo_op4.cpp b/src/server/gearbox/ammo_op4.cpp new file mode 100644 index 00000000..f920753a --- /dev/null +++ b/src/server/gearbox/ammo_op4.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 M249. + * A single ammo_556 will provide 50 bullets. + */ +/*class ammo_556:item_ammo +{ + void() ammo_556; + virtual void() touch; +}; + +void ammo_556::ammo_556(void) +{ + model = "models/w_357ammobox.mdl"; + item_ammo::item_ammo(); +} +void ammo_556::touch(void) +{ + if (other.classname == "player") { + player pl = (player)other; + if (pl.ammo_556 < 200) { + pl.ammo_556 = bound(0, pl.ammo_556 + 6, 36); + item_ammo::touch(); + } + } +}*/ + +/* + * Ammo for the M249. + * A single ammo_556 will provide 50 bullets. + */ +class ammo_556:item_ammo +{ + void() ammo_556; + virtual void() touch; +}; + +void ammo_556::ammo_556(void) +{ + model = "models/w_saw_clip.mdl"; + item_ammo::item_ammo(); +} +void ammo_556::touch(void) +{ + if (other.classname == "player") { + player pl = (player)other; + if (pl.ammo_556 < 200) { + pl.ammo_556 = bound(0, pl.ammo_556 + 6, 36); + item_ammo::touch(); + } + } +} + +/* + * Ammo for the M-40A1 Sniper. + * A single ammo_762 will provide 5 bullets. + */ +class ammo_762:item_ammo +{ + void() ammo_762; + virtual void() touch; +}; + +void ammo_762::ammo_762(void) +{ + model = "models/w_40a1clip.mdl"; + item_ammo::item_ammo(); +} +void ammo_762::touch(void) +{ + if (other.classname == "player") { + player pl = (player)other; + if (pl.ammo_762 < 200) { + pl.ammo_762 = bound(0, pl.ammo_762 + 5, 15); + item_ammo::touch(); + } + } +} + +/* + * Ammo for the Spore Launcher. + * A single ammo_spore will provide 1 spore. + * TODO + * It needs to be static (no pickup), and needs to + * fire a projectile upon inflicted damage. + */ + +class ammo_spore:item_ammo +{ + void() ammo_spore; + virtual void() touch; +}; + +void ammo_spore::ammo_spore(void) +{ + model = "models/spore_ammo.mdl"; + item_ammo::item_ammo(); +} +void ammo_spore::touch(void) +{ + if (other.classname == "player") { + player pl = (player)other; + if (pl.ammo_spore < 200) { + pl.ammo_spore = bound(0, pl.ammo_spore + 1, 20); + item_ammo::touch(); + } + } +} diff --git a/src/server/gearbox/input.c b/src/server/gearbox/input.c new file mode 100644 index 00000000..89e95e36 --- /dev/null +++ b/src/server/gearbox/input.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +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; + Weapons_AddItem(pl, WEAPON_CROWBAR); + Weapons_AddItem(pl, WEAPON_GLOCK); + Weapons_AddItem(pl, WEAPON_PYTHON); + Weapons_AddItem(pl, WEAPON_MP5); + Weapons_AddItem(pl, WEAPON_SHOTGUN); + Weapons_AddItem(pl, WEAPON_CROSSBOW); + Weapons_AddItem(pl, WEAPON_RPG); + Weapons_AddItem(pl, WEAPON_GAUSS); + Weapons_AddItem(pl, WEAPON_EGON); + Weapons_AddItem(pl, WEAPON_HORNETGUN); + Weapons_AddItem(pl, WEAPON_HANDGRENADE); + Weapons_AddItem(pl, WEAPON_SATCHEL); + Weapons_AddItem(pl, WEAPON_TRIPMINE); + Weapons_AddItem(pl, WEAPON_SNARK); + Weapons_AddItem(pl, WEAPON_PENGUIN); + Weapons_AddItem(pl, WEAPON_PIPEWRENCH); + Weapons_AddItem(pl, WEAPON_KNIFE); + Weapons_AddItem(pl, WEAPON_GRAPPLE); + Weapons_AddItem(pl, WEAPON_EAGLE); + Weapons_AddItem(pl, WEAPON_M249); + Weapons_AddItem(pl, WEAPON_SHOCKRIFLE); + Weapons_AddItem(pl, WEAPON_SPORELAUNCHER); + Weapons_AddItem(pl, WEAPON_SNIPERRIFLE); + Weapons_AddItem(pl, WEAPON_DISPLACER); + } + + 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; +} diff --git a/src/server/gearbox/progs.src b/src/server/gearbox/progs.src new file mode 100755 index 00000000..85397680 --- /dev/null +++ b/src/server/gearbox/progs.src @@ -0,0 +1,88 @@ +#pragma target fte +#pragma progs_dat "../../../gearbox/data.pk3dir/progs.dat" + +#define QWSSQC +#define VALVE +#define GEARBOX + +#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 +../../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/gearbox/player.cpp +../valve/player.c +../../shared/pmove.c +../valve/spectator.c +../../shared/gearbox/items.h +../../shared/valve/weapon_common.h +../../shared/gearbox/weapons.h +../../shared/valve/w_crossbow.c +../../shared/valve/w_crowbar.c +../../shared/valve/w_egon.c +../../shared/valve/w_gauss.c +../../shared/valve/w_glock.c +../../shared/valve/w_handgrenade.c +../../shared/valve/w_hornetgun.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/gearbox/w_pipewrench.c +../../shared/gearbox/w_knife.c +../../shared/gearbox/w_grapple.c +../../shared/gearbox/w_eagle.c +../../shared/gearbox/w_m249.c +../../shared/gearbox/w_displacer.c +../../shared/gearbox/w_sniperrifle.c +../../shared/gearbox/w_sporelauncher.c +../../shared/gearbox/w_penguin.c +../../shared/gearbox/w_shockrifle.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 +../gearbox/ammo_op4.cpp +../../shared/gearbox/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 diff --git a/src/server/valve/defs.h b/src/server/valve/defs.h index b9b524ba..f3976677 100644 --- a/src/server/valve/defs.h +++ b/src/server/valve/defs.h @@ -14,4 +14,4 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void Damage_Apply( entity eTarget, entity eAttacker, float iDamage, vector vHitPos, int bla); +void Damage_Apply(entity, entity, float, vector, int); diff --git a/src/server/valve/player.c b/src/server/valve/player.c index 30a64c23..adf67c01 100644 --- a/src/server/valve/player.c +++ b/src/server/valve/player.c @@ -164,7 +164,7 @@ float Player_SendEntity(entity ePEnt, float fChanged) WriteByte(MSG_ENTITY, pl.activeweapon); } if (fChanged & PLAYER_ITEMS) { - WriteFloat(MSG_ENTITY, pl.g_items); + WriteFloat(MSG_ENTITY, (__variant)pl.g_items); } if (fChanged & PLAYER_HEALTH) { WriteByte(MSG_ENTITY, pl.health); diff --git a/src/server/valve/progs.src b/src/server/valve/progs.src index 1c5fbed7..463a5adc 100755 --- a/src/server/valve/progs.src +++ b/src/server/valve/progs.src @@ -14,19 +14,15 @@ defs.h ../../shared/entities.h ../../shared/valve/animations.h ../defs.h - ../plugins.c ../logging.c - ../../gs-entbase/server.src monster_rat.cpp monster_scientist.cpp monster_scientist_dead.cpp - ../../shared/decals.c ../../shared/effects.c ../../shared/spraylogo.cpp - ../../shared/valve/player.cpp player.c ../../shared/pmove.c @@ -63,24 +59,18 @@ xen_plantlight.cpp ammo.cpp ../../shared/valve/weapons.c ../../shared/valve/weapon_common.c - ../spawn.c ../vox.c - ../../shared/valve/animations.c client.c ../client.c - server.c ../server.c - damage.c ../traceattack.c - ../footsteps.c ../flashlight.c input.c - spawn.c ../entry.c #endlist diff --git a/src/shared/gearbox/items.h b/src/shared/gearbox/items.h new file mode 100644 index 00000000..6d6b66b3 --- /dev/null +++ b/src/shared/gearbox/items.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 0x00000001i +#define ITEM_GLOCK 0x00000002i +#define ITEM_PYTHON 0x00000004i +#define ITEM_MP5 0x00000008i +#define ITEM_CROSSBOW 0x00000010i +#define ITEM_SHOTGUN 0x00000020i +#define ITEM_RPG 0x00000040i +#define ITEM_GAUSS 0x00000080i + +#define ITEM_EGON 0x00000100i +#define ITEM_HORNETGUN 0x00000200i +#define ITEM_HANDGRENADE 0x00000400i +#define ITEM_TRIPMINE 0x00000800i +#define ITEM_SATCHEL 0x00001000i +#define ITEM_SNARK 0x00002000i +#define ITEM_SUIT 0x00004000i +#define ITEM_LONGJUMP 0x00008000i + +#define ITEM_PIPEWRENCH 0x00010000i +#define ITEM_KNIFE 0x00020000i +#define ITEM_GRAPPLE 0x00040000i +#define ITEM_EAGLE 0x00080000i +#define ITEM_M249 0x00100000i +#define ITEM_DISPLACER 0x00200000i +#define ITEM_SNIPERRIFLE 0x00400000i +#define ITEM_PENGUIN 0x00800000i + +#define ITEM_SHOCKRIFLE 0x01000000i +#define ITEM_SPORELAUNCHER 0x02000000i +#define ITEM_UNUSED27 0x04000000i +#define ITEM_UNUSED28 0x08000000i +#define ITEM_UNUSED29 0x10000000i +#define ITEM_UNUSED30 0x20000000i +#define ITEM_UNUSED31 0x40000000i +#define ITEM_UNUSED32 0x80000000i diff --git a/src/shared/gearbox/player.cpp b/src/shared/gearbox/player.cpp new file mode 100644 index 00000000..4b3cd97a --- /dev/null +++ b/src/shared/gearbox/player.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 view_ofs; + float weapontime; + + /* Weapon specific */ + int glock_mag; + int mp5_mag; + int python_mag; + int shotgun_mag; + int crossbow_mag; + int rpg_mag; + int satchel_chg; + int eagle_mag; + int sniper_mag; + int m249_mag; + int sporelauncher_mag; + +#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; + 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_buckshot; + int ammo_m203_grenade; + int ammo_bolt; + int ammo_rocket; + int ammo_uranium; + int ammo_handgrenade; + int ammo_satchel; + int ammo_tripmine; + int ammo_snark; + int ammo_hornet; + int ammo_556; + int ammo_762; + int ammo_spore; + int ammo_shock; + int ammo_penguin; + + /* 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 +}; + diff --git a/src/shared/gearbox/w_displacer.c b/src/shared/gearbox/w_displacer.c new file mode 100644 index 00000000..75a59d98 --- /dev/null +++ b/src/shared/gearbox/w_displacer.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + DISP_IDLE1, + DISP_IDLE2, + DISP_SPINUP, + DISP_SPIN, + DISP_FIRE, + DISP_DRAW, + DISP_HOLSTER +}; + +void +w_displacer_precache(void) +{ + precache_sound("weapons/displacer_fire.wav"); + precache_sound("weapons/displacer_impact.wav"); + precache_sound("weapons/displacer_self.wav"); + precache_sound("weapons/displacer_spin.wav"); + precache_sound("weapons/displacer_spin2.wav"); + precache_sound("weapons/displacer_start.wav"); + precache_sound("weapons/displacer_teleport.wav"); + precache_sound("weapons/displacer_teleport_player.wav"); + precache_model("models/v_displacer.mdl"); + precache_model("models/w_displacer.mdl"); + precache_model("models/p_displacer.mdl"); +} + +void +w_displacer_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, -1, -1); +#endif +} + +string +w_displacer_wmodel(void) +{ + return "models/w_displacer.mdl"; +} +string +w_displacer_pmodel(void) +{ + return "models/p_displacer.mdl"; +} + +string +w_displacer_deathmsg(void) +{ + return "%s was assaulted by %s's Displacer."; +} + +void +w_displacer_draw(void) +{ + Weapons_SetModel("models/v_displacer.mdl"); + Weapons_ViewAnimation(DISP_DRAW); +} + +void +w_displacer_holster(void) +{ + Weapons_ViewAnimation(DISP_HOLSTER); +} + +void +w_displacer_primary(void) +{ +/* TODO, 250 damage */ +} + +void +w_displacer_secondary(void) +{ +/* TODO, self teleport */ +} + +void +w_displacer_release(void) +{ + +} + +float +w_displacer_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMSQUEAK : ANIM_AIMSQUEAK; +} + +void +w_displacer_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof02.spr_0.tga", + [0,180/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof01.spr_0.tga", + [0,180/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_displacer = +{ + .id = ITEM_DISPLACER, + .slot = 5, + .slot_pos = 1, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [48,208], + .draw = w_displacer_draw, + .holster = w_displacer_holster, + .primary = w_displacer_primary, + .secondary = w_displacer_secondary, + .reload = __NULL__, + .release = w_displacer_release, + .crosshair = __NULL__, + .precache = w_displacer_precache, + .pickup = __NULL__, + .updateammo = w_displacer_updateammo, + .wmodel = w_displacer_wmodel, + .pmodel = w_displacer_pmodel, + .deathmsg = w_displacer_deathmsg, + .aimanim = w_displacer_aimanim, + .hudpic = w_displacer_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_displacer(void) +{ + Weapons_InitItem(WEAPON_DISPLACER); +} +#endif diff --git a/src/shared/gearbox/w_eagle.c b/src/shared/gearbox/w_eagle.c new file mode 100644 index 00000000..466f03c7 --- /dev/null +++ b/src/shared/gearbox/w_eagle.c @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + EAGLE_IDLE1, + EAGLE_IDLE2, + EAGLE_IDLE3, + EAGLE_IDLE4, + EAGLE_IDLE5, + EAGLE_SHOOT, + EAGLE_SHOOT_EMPTY, + EAGLE_RELOAD, + EAGLE_RELOAD_NOSHOT, + EAGLE_DRAW, + EAGLE_HOLSTER +}; + +void +w_eagle_precache(void) +{ + precache_model("models/v_desert_eagle.mdl"); + precache_model("models/w_desert_eagle.mdl"); + precache_model("models/p_desert_eagle.mdl"); + + precache_sound("weapons/desert_eagle_fire.wav"); + precache_sound("weapons/desert_eagle_sight.wav"); +} +void +w_eagle_pickup(void) +{ + player pl = (player)self; + pl.eagle_mag = 7; +} + +void +w_eagle_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, pl.eagle_mag, pl.ammo_357, -1); +#endif +} + +string +w_eagle_wmodel(void) +{ + return "models/w_desert_eagle.mdl"; +} +string +w_eagle_pmodel(void) +{ + return "models/p_desert_eagle.mdl"; +} +string +w_eagle_deathmsg(void) +{ + return ""; +} + +void +w_eagle_draw(void) +{ +#ifdef CSQC + Weapons_SetModel("models/v_desert_eagle.mdl"); + Weapons_ViewAnimation(EAGLE_DRAW); +#else + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.eagle_mag, pl.ammo_357, -1); +#endif +} + +void +w_eagle_holster(void) +{ + Weapons_ViewAnimation(EAGLE_HOLSTER); +} + +void +w_eagle_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.eagle_mag <= 0) { + return; + } +#endif + + /* Actual firing */ + if (pl.a_ammo3 == 1) { +#ifdef SSQC + TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 34, [0, 0]); +#endif + pl.w_attack_next = 0.75f; + } else { +#ifdef SSQC + TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 34, [0.1,0.1]); +#endif + pl.w_attack_next = 0.2f; + } + +#ifdef SSQC + sound(pl, CHAN_WEAPON, "weapons/desert_eagle_fire.wav", 1, ATTN_NORM); + pl.eagle_mag--; + Weapons_UpdateAmmo(pl, pl.eagle_mag, pl.ammo_357, -1); +#else + pl.a_ammo1--; + View_SetMuzzleflash(MUZZLE_SMALL); + Weapons_ViewPunchAngle([-10,0,0]); + + if (pl.a_ammo1 <= 0) { + Weapons_ViewAnimation(EAGLE_SHOOT_EMPTY); + } else { + Weapons_ViewAnimation(EAGLE_SHOOT); + } +#endif +} + +void +w_eagle_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + + /* toggle laser */ + pl.a_ammo3 = 1 - pl.a_ammo3; + +#ifdef SSQC + sound(pl, CHAN_WEAPON, "weapons/desert_eagle_sight.wav", 1, ATTN_NORM); +#endif + + pl.w_attack_next = 0.5f; +} + +void +w_eagle_reload(void) +{ + player pl = (player)self; + if (pl.w_attack_next > 0.0) { + return; + } + + /* Ammo check */ +#ifdef CSQC + if (pl.a_ammo1 >= 7) { + return; + } + if (pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.eagle_mag >= 7) { + return; + } + if (pl.ammo_357 <= 0) { + return; + } +#endif + + /* Audio-Visual bit */ +#ifdef CSQC + if (pl.a_ammo1 <= 0) { + Weapons_ViewAnimation(EAGLE_RELOAD_NOSHOT); + } else { + Weapons_ViewAnimation(EAGLE_RELOAD); + } +#else + Weapons_ReloadWeapon(pl, player::eagle_mag, player::ammo_357, 7); + Weapons_UpdateAmmo(pl, pl.eagle_mag, pl.ammo_357, -1); +#endif + + pl.w_attack_next = 1.64f; + pl.w_idle_next = 10.0f; +} + +void +w_eagle_release(void) +{ + player pl = (player)self; + + if (pl.w_idle_next) { + return; + } + + Weapons_ViewAnimation(EAGLE_IDLE1 + floor(random(0,5))); + pl.w_idle_next = 15.0f; +} + +void +w_eagle_crosshair(void) +{ +#ifdef CSQC + player pl = (player)self; + vector cross_pos; + vector aicon_pos; + + /* crosshair/laser */ + if (pl.a_ammo3 == 1) { + float lerp; + Weapons_MakeVectors(); + vector src = pl.origin + pl.view_ofs; + traceline(src, src + (v_forward * 64), FALSE, pl); + lerp = Math_Lerp(24,8, trace_fraction); + cross_pos = (video_res / 2) + ([-lerp,-lerp] / 2); + drawsubpic( + cross_pos, + [lerp,lerp], + "sprites/laserdot.spr_0.tga", + [0,0], + [1.0, 1.0], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + cross_pos = (video_res / 2) + [-12,-12]; + drawsubpic( + cross_pos, + [24,24], + "sprites/ofch1.spr_0.tga", + [0,0], + [24/72, 24/72], + [1,1,1], + 1, + DRAWFLAG_NORMAL + ); + } + + /* ammo counters */ + HUD_DrawAmmo1(); + HUD_DrawAmmo2(); + + /* ammo icon */ + 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_eagle_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMPYTHON : ANIM_AIMPYTHON; +} + +void +w_eagle_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof02.spr_0.tga", + [0,90/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof01.spr_0.tga", + [0,90/256], + [170/256,45/256], + g_hud_color, + 1, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_eagle = +{ + .id = ITEM_EAGLE, + .slot = 1, + .slot_pos = 2, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [0,240], + .draw = w_eagle_draw, + .holster = w_eagle_holster, + .primary = w_eagle_primary, + .secondary = w_eagle_secondary, + .reload = w_eagle_reload, + .release = w_eagle_release, + .crosshair = w_eagle_crosshair, + .precache = w_eagle_precache, + .pickup = w_eagle_pickup, + .updateammo = w_eagle_updateammo, + .wmodel = w_eagle_wmodel, + .pmodel = w_eagle_pmodel, + .deathmsg = w_eagle_deathmsg, + .aimanim = w_eagle_aimanim, + .hudpic = w_eagle_hudpic +}; + +#ifdef SSQC +void +weapon_eagle(void) +{ + Weapons_InitItem(WEAPON_EAGLE); +} +#endif diff --git a/src/shared/gearbox/w_grapple.c b/src/shared/gearbox/w_grapple.c new file mode 100644 index 00000000..9af0c073 --- /dev/null +++ b/src/shared/gearbox/w_grapple.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + BARN_IDLE, + BARN_IDLE2, + BARN_IDLE3, + BARN_COUGH, + BARN_HOLSTER, + BARN_DRAW, + BARN_FIRE, + BARN_FIREWAIT, + BARN_FIREREACH, + BARN_FIRETRAVEL, + BARN_FIRERELEASE +}; + +void +w_grapple_precache(void) +{ + precache_sound("weapons/bgrapple_cough.wav"); + precache_sound("weapons/bgrapple_fire.wav"); + precache_sound("weapons/bgrapple_impact.wav"); + precache_sound("weapons/bgrapple_pull.wav"); + precache_sound("weapons/bgrapple_release.wav"); + precache_sound("weapons/bgrapple_wait.wav"); + precache_model("models/v_bgrap.mdl"); + precache_model("models/v_bgrap_tonguetip.mdl"); + precache_model("models/w_grapple.mdl"); + precache_model("models/p_bgrap.mdl"); +} + +void +w_grapple_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_grapple_wmodel(void) +{ + return "models/w_bgrap.mdl"; +} + +string +w_grapple_pmodel(void) +{ + return "models/p_bgrap.mdl"; +} + +string +w_grapple_deathmsg(void) +{ + return "%s was assaulted by %s's Barnacle."; +} + +void +w_grapple_draw(void) +{ + Weapons_SetModel("models/v_bgrap.mdl"); + Weapons_ViewAnimation(BARN_DRAW); +} + +void +w_grapple_holster(void) +{ + Weapons_ViewAnimation(BARN_HOLSTER); +} + +void +w_grapple_primary(void) +{ +/* TODO, 25 damage */ +} + +void +w_grapple_secondary(void) +{ +/* TODO, special CTF alt fire */ +} + + +void +w_grapple_release(void) +{ + +} + +float +w_grapple_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMSQUEAK : ANIM_AIMSQUEAK; +} + +void +w_grapple_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof02.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_grapple = +{ + .id = ITEM_GRAPPLE, + .slot = 0, + .slot_pos = 3, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [0,224], + .draw = w_grapple_draw, + .holster = w_grapple_holster, + .primary = w_grapple_primary, + .secondary = w_grapple_secondary, + .reload = __NULL__, + .release = w_grapple_release, + .crosshair = __NULL__, + .precache = w_grapple_precache, + .pickup = __NULL__, + .updateammo = w_grapple_updateammo, + .wmodel = w_grapple_wmodel, + .pmodel = w_grapple_pmodel, + .deathmsg = w_grapple_deathmsg, + .aimanim = w_grapple_aimanim, + .hudpic = w_grapple_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_grapple(void) +{ + Weapons_InitItem(WEAPON_GRAPPLE); +} +#endif diff --git a/src/shared/gearbox/w_knife.c b/src/shared/gearbox/w_knife.c new file mode 100644 index 00000000..5437df53 --- /dev/null +++ b/src/shared/gearbox/w_knife.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + KNIFE_IDLE1, + KNIFE_DRAW, + KNIFE_HOLSTER, + KNIFE_ATTACK1HIT, + KNIFE_ATTACK1MISS, + KNIFE_ATTACK2MISS, + KNIFE_ATTACK2HIT, + KNIFE_ATTACK3MISS, + KNIFE_ATTACK3HIT, + KNIFE_IDLE2, + KNIFE_IDLE3 +}; + +void +w_knife_precache(void) +{ + precache_sound("weapons/knife1.wav"); + precache_sound("weapons/knife2.wav"); + precache_sound("weapons/knife3.wav"); + precache_sound("weapons/knife_hit_wall1.wav"); + precache_sound("weapons/knife_hit_wall2.wav"); + precache_sound("weapons/knife_hit_flesh1.wav"); + precache_sound("weapons/knife_hit_flesh2.wav"); + precache_model("models/v_knife.mdl"); + precache_model("models/w_knife.mdl"); + precache_model("models/p_knife.mdl"); +} + +void +w_knife_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, -1, -1); +#endif +} + +string +w_knife_wmodel(void) +{ + return "models/w_knife.mdl"; +} + +string +w_knife_pmodel(void) +{ + return "models/p_knife.mdl"; +} + +string +w_knife_deathmsg(void) +{ + return "%s was assaulted by %s's Knife."; +} + +void +w_knife_draw(void) +{ + Weapons_SetModel("models/v_knife.mdl"); + Weapons_ViewAnimation(KNIFE_DRAW); +} + +void +w_knife_holster(void) +{ + Weapons_ViewAnimation(KNIFE_HOLSTER); +} + +void +w_knife_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 ? KNIFE_ATTACK1MISS:KNIFE_ATTACK1HIT; + break; + case 1: + anim = trace_fraction >= 1 ? KNIFE_ATTACK2MISS:KNIFE_ATTACK2HIT; + break; + default: + anim = trace_fraction >= 1 ? KNIFE_ATTACK3MISS:KNIFE_ATTACK3HIT; + } + Weapons_ViewAnimation(anim); +#else + if (pl.flags & FL_CROUCHING) { + Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f); + } else { + Animation_PlayerTopTemp(ANIM_CR_SHOOTCROWBAR, 0.42f); + } + + r = floor(random(0,3)); + switch (r) { + case 0: + sound(pl, CHAN_WEAPON, "weapons/knife1.wav", 1, ATTN_NORM); + break; + case 1: + sound(pl, CHAN_WEAPON, "weapons/knife2.wav", 1, ATTN_NORM); + break; + case 2: + sound(pl, CHAN_WEAPON, "weapons/knife3.wav", 1, ATTN_NORM); + break; + } + + 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, trace_endpos, FALSE ); + + if (!trace_ent.iBleeds) { + return; + } + + if (random() < 0.5) { + sound(pl, 8, "weapons/knife_hit_flesh1.wav", 1, ATTN_NORM); + } else { + sound(pl, 8, "weapons/knife_hit_flesh2.wav", 1, ATTN_NORM); + } + } else { + if (random() < 0.5) { + sound(pl, 8, "weapons/knife_hit_wall1.wav", 1, ATTN_NORM); + } else { + sound(pl, 8, "weapons/knife_hit_wall2.wav", 1, ATTN_NORM); + } + } +#endif +} + +void +w_knife_release(void) +{ + int r; + player pl = (player)self; + + if (pl.w_idle_next) { + return; + } + + r = (float)input_sequence % 3; + switch (r) { + case 0: + Weapons_ViewAnimation(KNIFE_IDLE1); + pl.w_idle_next = 2.7f; + break; + case 1: + Weapons_ViewAnimation(KNIFE_IDLE2); + pl.w_idle_next = 5.3f; + break; + default: + Weapons_ViewAnimation(KNIFE_IDLE3); + pl.w_idle_next = 5.3f; + break; + } +} + +float +w_knife_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR; +} + +void +w_knife_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof04.spr_0.tga", + [0,90/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof03.spr_0.tga", + [0,90/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_knife = +{ + .id = ITEM_KNIFE, + .slot = 0, + .slot_pos = 2, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [96,224], + .draw = w_knife_draw, + .holster = w_knife_holster, + .primary = w_knife_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_knife_release, + .crosshair = __NULL__, + .precache = w_knife_precache, + .pickup = __NULL__, + .updateammo = w_knife_updateammo, + .wmodel = w_knife_wmodel, + .pmodel = w_knife_pmodel, + .deathmsg = w_knife_deathmsg, + .aimanim = w_knife_aimanim, + .hudpic = w_knife_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void weapon_knife(void) +{ + Weapons_InitItem(WEAPON_KNIFE); +} +#endif diff --git a/src/shared/gearbox/w_m249.c b/src/shared/gearbox/w_m249.c new file mode 100644 index 00000000..ffbe5114 --- /dev/null +++ b/src/shared/gearbox/w_m249.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 { + M249_IDLE1, + M249_IDLE2, + M249_RELOAD, + M249_RELOAD2, + M249_HOLSTER, + M249_DRAW, + M249_FIRE +}; + +void +w_m249_precache(void) +{ + precache_model("models/v_saw.mdl"); + precache_model("models/w_saw.mdl"); + precache_model("models/p_saw.mdl"); + precache_sound("weapons/saw_fire1.wav"); + precache_sound("weapons/saw_fire2.wav"); + precache_sound("weapons/saw_fire3.wav"); + precache_sound("weapons/saw_reload.wav"); + precache_sound("weapons/saw_reload2.wav"); +} + +void +w_m249_pickup(void) +{ + player pl = (player)self; + pl.m249_mag = 50; +} + +void +w_m249_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, pl.m249_mag, pl.ammo_556, __NULL__); +#endif +} + +string +w_m249_wmodel(void) +{ + return "models/w_saw.mdl"; +} + +string +w_m249_pmodel(void) +{ + return "models/p_saw.mdl"; +} + +string +w_m249_deathmsg(void) +{ + return ""; +} + +void +w_m249_draw(void) +{ + Weapons_SetModel("models/v_saw.mdl"); + Weapons_ViewAnimation(M249_DRAW); +#ifdef SSQC + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.m249_mag, pl.ammo_556, __NULL__); +#endif +} + +void +w_m249_holster(void) +{ + Weapons_ViewAnimation(M249_DRAW); +} + +void +w_m249_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.m249_mag <= 0) { + return; + } +#endif + + Weapons_ViewAnimation(M249_FIRE); + pl.velocity += v_forward * -30; + + /* actual firing */ +#ifdef CSQC + pl.a_ammo1--; + View_SetMuzzleflash(MUZZLE_RIFLE); + Weapons_ViewPunchAngle([-10,0,0]); +#else + TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 8, [0.05234,0.05234]); + + int r = (float)input_sequence % 3; + switch (r) { + case 0: + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/saw_fire1.wav", 1, ATTN_NORM); + break; + case 1: + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/saw_fire2.wav", 1, ATTN_NORM); + break; + default: + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/saw_fire3.wav", 1, ATTN_NORM); + } + + pl.m249_mag--; + Weapons_UpdateAmmo(pl, pl.m249_mag, pl.ammo_556, __NULL__); +#endif + + pl.w_attack_next = 0.1f; + pl.w_idle_next = 10.0f; +} + +void +w_m249_reload(void) +{ + player pl = (player)self; + if (pl.w_attack_next) { + return; + } + + /* ammo check */ +#ifdef CSQC + if (pl.a_ammo1 >= 50) { + return; + } + if (pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.m249_mag >= 50) { + return; + } + if (pl.ammo_556 <= 0) { + return; + } +#endif + + Weapons_ViewAnimation(M249_RELOAD2); + +#ifdef SSQC + Weapons_ReloadWeapon(pl, player::m249_mag, player::ammo_556, 50); + Weapons_UpdateAmmo(pl, pl.m249_mag, pl.ammo_556, __NULL__); +#endif + + pl.w_attack_next = 1.5f; + pl.w_idle_next = 10.0f; +} + +void +w_m249_release(void) +{ + player pl = (player)self; + if (pl.w_idle_next > 0.0) { + return; + } + + if (random() < 0.5) { + Weapons_ViewAnimation(M249_IDLE1); + } else { + Weapons_ViewAnimation(M249_IDLE2); + } + + pl.w_idle_next = 15.0f; +} + +void +w_m249_crosshair(void) +{ +#ifdef CSQC + vector cross_pos; + vector aicon_pos; + + /* crosshair */ + cross_pos = (video_res / 2) + [-12,-12]; + drawsubpic( + cross_pos, + [24,24], + "sprites/ofch1.spr_0.tga", + [24/72,0], + [24/72, 24/72], + [1,1,1], + 1.0, + DRAWFLAG_NORMAL + ); + + /* ammo counters */ + HUD_DrawAmmo1(); + HUD_DrawAmmo2(); + + /* ammo icon */ + aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + "sprites/640hud7.spr_0.tga", + [24/128,72/128], + [24/256, 24/128], + g_hud_color, + pSeat->ammo2_alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_m249_aimanim(void) +{ + return self.flags & ANIM_CR_AIMMP5 ? ANIM_CR_AIMCROWBAR : ANIM_AIMMP5; +} + +void +w_m249_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof02.spr_0.tga", + [0,135/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof01.spr_0.tga", + [0,135/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_m249 = +{ + .id = ITEM_M249, + .slot = 5, + .slot_pos = 0, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [96,208], + .draw = w_m249_draw, + .holster = w_m249_holster, + .primary = w_m249_primary, + .secondary = __NULL__, + .reload = w_m249_reload, + .release = w_m249_release, + .crosshair = w_m249_crosshair, + .precache = w_m249_precache, + .pickup = w_m249_pickup, + .updateammo = w_m249_updateammo, + .wmodel = w_m249_wmodel, + .pmodel = w_m249_pmodel, + .deathmsg = w_m249_deathmsg, + .aimanim = w_m249_aimanim, + .hudpic = w_m249_hudpic +}; + +#ifdef SSQC +void +weapon_m249(void) +{ + Weapons_InitItem(WEAPON_M249); +} +#endif + diff --git a/src/shared/gearbox/w_penguin.c b/src/shared/gearbox/w_penguin.c new file mode 100644 index 00000000..37921b56 --- /dev/null +++ b/src/shared/gearbox/w_penguin.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + PENGUIN_IDLE, + PENGUIN_FIDGET1, + PENGUIN_FIDGET2, + PENGUIN_HOLSTER, + PENGUIN_DRAW, + PENGUIN_THROW +}; + +void +w_penguin_pickup(void) +{ +#ifdef SSQC + player pl = (player)self; + pl.ammo_penguin = bound(0, pl.ammo_penguin + 5, 10); +#endif +} + +void +w_penguin_draw(void) +{ + Weapons_SetModel("models/v_penguin.mdl"); + Weapons_ViewAnimation(PENGUIN_DRAW); +#ifdef SSQC + player pl = (player)self; + Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_penguin, __NULL__); +#endif +} + +void +w_penguin_holster(void) +{ + +} + +#ifdef SSQC +void +penguin_ai(void) +{ + input_movevalues = [250,0,0]; + input_buttons = 0; + input_impulse = 0; + input_angles = self.angles; + input_timelength = frametime; + + if (self.health <= 0) { + return; + } + + if (self.weapon <= 0.0 && self.aiment == __NULL__) { + entity ef; + float shortest = 999999; + for (ef = world; (ef = findfloat(ef, movetype, MOVETYPE_WALK));) { + float len = vlen(ef.origin - self.origin); + if (ef.classname != "snark" && len < shortest && ef.health > 0) { + self.owner = __NULL__; + self.aiment = ef; + shortest = len; + } + } + } + + if (self.aiment) { + self.angles = input_angles = vectoangles(self.aiment.origin - self.origin); + } + + if (self.aiment && self.weapon <= 0.0) { + self.weapon = 0.5f + random(); + sound(self, CHAN_VOICE, sprintf("squeek/sqk_hunt%d.wav",floor(random(1,4))), 1.0, ATTN_NORM); + input_buttons = 2; + Damage_Apply(self, world, 1, self.origin, TRUE); + + makevectors(self.angles); + traceline(self.origin, self.origin + (v_forward * 128), 0, self); + + if (trace_ent.takedamage == DAMAGE_YES) { + float pit = 100 + random(0,10); + sound(self, CHAN_BODY, "squeek/sqk_deploy1.wav", 1.0, ATTN_NORM, pit); + Damage_Apply(trace_ent, self, 10, trace_endpos, FALSE); + } + + if (self.aiment.health <= 0) { + self.aiment = __NULL__; + } + } + self.weapon -= frametime; + runstandardplayerphysics(self); +} + +void +penguin_die(int i) +{ + Effect_CreateExplosion(self.origin); + Damage_Radius(self.origin, self.owner, 150, 150 * 2.5f, TRUE); + sound(self, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM); + self.customphysics = __NULL__; + self.vDeath = __NULL__; + remove(self); +} + +void +penguin_pain(int i) +{ + /* add stuff? */ +} + +void +w_penguin_deploy(void) +{ + entity pingu = spawn(); + pingu.owner = self; + pingu.netname = "Penguin"; + pingu.classname = "snark"; /* so snarks and pingus don't attack e/o */ + setmodel(pingu, "models/w_penguin.mdl"); + makevectors(self.v_angle); + setorigin(pingu, self.origin + v_forward * 32); + pingu.solid = SOLID_BBOX; + pingu.movetype = MOVETYPE_WALK; + pingu.frame = 3; /* running like crazy. */ + pingu.customphysics = penguin_ai; + pingu.angles = self.angles; + pingu.health = 20; + pingu.vPain = penguin_pain; + pingu.takedamage = DAMAGE_YES; + pingu.aiment = __NULL__; + pingu.vDeath = penguin_die; + pingu.weapon = 3.0f; +} +#endif + +void +w_penguin_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_penguin <= 0) { + return; + } +#endif + + Weapons_ViewAnimation(PENGUIN_THROW); + + /* Audio-Visual Bit */ +#ifdef CSQC + pl.a_ammo2--; +#else + w_penguin_deploy(); + pl.ammo_penguin--; + Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_penguin, __NULL__); + + if (pl.a_ammo2 <= 0) { + Weapons_RemoveItem(pl, WEAPON_SNARK); + } +#endif + + pl.w_idle_next = 1.0f; + pl.w_attack_next = 0.25f; + +} + +void +w_penguin_secondary(void) +{ + +} + +void +w_penguin_reload(void) +{ + +} + +void +w_penguin_release(void) +{ + int r; + player pl = (player)self; + if (pl.w_idle_next > 0.0) { + return; + } + + r = floor(random(0,3)); + switch (r) { + case 0: + Weapons_ViewAnimation(PENGUIN_IDLE); + pl.w_idle_next = 1.875f; + break; + case 1: + Weapons_ViewAnimation(PENGUIN_FIDGET1); + pl.w_idle_next = 4.375f; + break; + default: + Weapons_ViewAnimation(PENGUIN_FIDGET2); + pl.w_idle_next = 5.0f; + break; + } +} + +void +w_penguin_precache(void) +{ + precache_model("models/w_penguin.mdl"); + precache_model("models/p_penguin.mdl"); + precache_model("models/v_penguin.mdl"); + precache_sound("squeek/sqk_deploy1.wav"); + precache_sound("squeek/sqk_die1.wav"); + precache_sound("squeek/sqk_blast1.wav"); + precache_sound("squeek/sqk_hunt1.wav"); + precache_sound("squeek/sqk_hunt2.wav"); + precache_sound("squeek/sqk_hunt3.wav"); +} + +void +w_penguin_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_penguin, __NULL__); +#endif +} + +string +w_penguin_wmodel(void) +{ + return "models/w_sqknest.mdl"; +} + +string +w_penguin_pmodel(void) +{ + return "models/p_penguin.mdl"; +} + +string +w_penguin_deathmsg(void) +{ + return ""; +} + + +float +w_penguin_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMSQUEAK : ANIM_AIMSQUEAK; +} + +void +w_penguin_hud(void) +{ +#ifdef CSQC + 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", [96/256,96/128], [24/256, 24/128], g_hud_color, pSeat->ammo2_alpha, DRAWFLAG_ADDITIVE); +#endif +} + +void +w_penguin_hudpic(int s, vector pos) +{ +#ifdef CSQC + if (s) { + drawsubpic(pos, [170,45], "sprites/640hudof04.spr_0.tga", + [0,180/256], [170/256,45/256], + g_hud_color, 1, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], "sprites/640hudof03.spr_0.tga", + [0,180/256], [170/256,45/256], + g_hud_color, 1, DRAWFLAG_ADDITIVE); + } +#endif +} + +weapon_t w_penguin = +{ + .id = ITEM_PENGUIN, + .slot = 4, + .slot_pos = 4, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [144,224], + .draw = w_penguin_draw, + .holster = w_penguin_holster, + .primary = w_penguin_primary, + .secondary = w_penguin_secondary, + .reload = w_penguin_reload, + .release = w_penguin_release, + .crosshair = __NULL__, + .precache = w_penguin_precache, + .pickup = w_penguin_pickup, + .updateammo = w_penguin_updateammo, + .wmodel = w_penguin_wmodel, + .pmodel = w_penguin_pmodel, + .deathmsg = w_penguin_deathmsg, + .aimanim = w_penguin_aimanim, + .hudpic = w_penguin_hudpic +}; diff --git a/src/shared/gearbox/w_pipewrench.c b/src/shared/gearbox/w_pipewrench.c new file mode 100644 index 00000000..ca11fc5f --- /dev/null +++ b/src/shared/gearbox/w_pipewrench.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + PIPE_IDLE1, + PIPE_IDLE2, + PIPE_IDLE3, + PIPE_DRAW, + PIPE_HOLSTER, + PIPE_ATTACK1HIT, + PIPE_ATTACK1MISS, + PIPE_ATTACK2HIT, + PIPE_ATTACK2MISS, + PIPE_ATTACK3HIT, + PIPE_ATTACK3MISS, + PIPE_ATTACKBIGWIND, + PIPE_ATTACKBIGHIT, + PIPE_ATTACKBIGMISS, + PIPE_ATTACKBIGLOOP +}; + +void +w_pipewrench_precache(void) +{ + precache_sound("weapons/pwrench_big_miss.wav"); + precache_sound("weapons/pwrench_big_hit1.wav"); + precache_sound("weapons/pwrench_big_hit2.wav"); + precache_sound("weapons/pwrench_big_hitbod1.wav"); + precache_sound("weapons/pwrench_big_hitbod2.wav"); + precache_sound("weapons/pwrench_miss1.wav"); + precache_sound("weapons/pwrench_miss2.wav"); + precache_sound("weapons/pwrench_hit1.wav"); + precache_sound("weapons/pwrench_hit2.wav"); + precache_sound("weapons/pwrench_hitbod1.wav"); + precache_sound("weapons/pwrench_hitbod2.wav"); + precache_sound("weapons/pwrench_hitbod3.wav"); + precache_model("models/v_pipe_wrench.mdl"); + precache_model("models/w_pipe_wrench.mdl"); + precache_model("models/p_pipe_wrench.mdl"); +} + +void +w_pipewrench_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_pipewrench_wmodel(void) +{ + return "models/w_pipe_wrench.mdl"; +} + +string +w_pipewrench_pmodel(void) +{ + return "models/p_pipe_wrench.mdl"; +} + +string +w_pipewrench_deathmsg(void) +{ + return "%s was assaulted by %s's Pipewrench."; +} + +void +w_pipewrench_draw(void) +{ + Weapons_SetModel("models/v_pipe_wrench.mdl"); + Weapons_ViewAnimation(PIPE_DRAW); +} + +void +w_pipewrench_holster(void) +{ + Weapons_ViewAnimation(PIPE_HOLSTER); +} + +void +w_pipewrench_primary(void) +{ + int anim = 0; + 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.9f; + } else { + pl.w_attack_next = 0.7f; + } + pl.w_idle_next = 2.5f; + +#ifdef CSQC + int r = floor(random(0,3)); + switch (r) { + case 0: + anim = trace_fraction >= 1 ? PIPE_ATTACK1MISS:PIPE_ATTACK1HIT; + break; + case 1: + anim = trace_fraction >= 1 ? PIPE_ATTACK2MISS:PIPE_ATTACK2HIT; + break; + default: + anim = trace_fraction >= 1 ? PIPE_ATTACK3MISS:PIPE_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/pwrench_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, trace_endpos, FALSE ); + + if (!trace_ent.iBleeds) { + return; + } + + if (random() < 0.33) { + sound(pl, 8, "weapons/pwrench_hitbod1.wav", 1, ATTN_NORM); + } else if (random() < 0.66) { + sound(pl, 8, "weapons/pwrench_hitbod2.wav", 1, ATTN_NORM); + } else { + sound(pl, 8, "weapons/pwrench_hitbod3.wav", 1, ATTN_NORM); + } + } else { + if (random() < 0.5) { + sound(pl, 8, "weapons/pwrench_hit1.wav", 1, ATTN_NORM); + } else { + sound(pl, 8, "weapons/pwrench_hit2.wav", 1, ATTN_NORM); + } + } +#endif +} + +void +w_pipewrench_secondary(void) +{ + player pl = (player)self; + + if (!pl.w_attack_next) { + /* Hack */ + if (pl.a_ammo1 != 1) { + Weapons_ViewAnimation(PIPE_ATTACKBIGWIND); + pl.a_ammo1 = 1; + pl.w_attack_next = 0.86f; + } + } + pl.w_idle_next = 2.5f; +} + +void +w_pipewrench_release(void) +{ + vector src; + player pl = (player)self; + + if (pl.w_attack_next > 0.0f) { + return; + } + + src = pl.origin + pl.view_ofs; + Weapons_MakeVectors(); + traceline(src, src + v_forward * 64, FALSE, self); + + if (pl.a_ammo1 == 1) { + #ifdef SSQC + int hitsound = 0; + string snd; + #endif + if (trace_fraction < 1.0) { + #ifdef SSQC + if (trace_ent.takedamage == DAMAGE_YES) { + hitsound = floor(random(1, 2)); + /* TODO Damage is 45 - 200+ (?) */ + Damage_Apply(trace_ent, self, 200, trace_endpos, FALSE); + } + else { + hitsound = 3; + } + #endif + Weapons_ViewAnimation(PIPE_ATTACKBIGHIT); + Weapons_ViewPunchAngle([-10,0,0]); + } else { + Weapons_ViewAnimation(PIPE_ATTACKBIGMISS); + } + +#ifdef SSQC + snd = "weapons/pwrench_big_miss.wav"; + switch (hitsound) { + case 1: + snd = "weapons/pwrench_big_hitbod1.wav"; + break; + case 2: + snd = "weapons/pwrench_big_hitbod2.wav"; + break; + case 3: + snd = "weapons/pwrench_big_hit1.wav"; + break; + } + Weapons_PlaySound(pl, CHAN_WEAPON, snd, 1.0f, ATTN_NORM); +#endif + pl.w_attack_next = 1.0f; + pl.w_idle_next = 10.0f; + pl.a_ammo1 = 0; + } + + /* Pure cosmetics start here */ + if (pl.w_idle_next) { + return; + } + + int r = floor(random(0,3)); + switch (r) { + case 0: + Weapons_ViewAnimation(PIPE_IDLE1); + pl.w_idle_next = 2.0f; + break; + case 1: + Weapons_ViewAnimation(PIPE_IDLE2); + pl.w_idle_next = 3.0f; + break; + case 2: + Weapons_ViewAnimation(PIPE_IDLE3); + pl.w_idle_next = 3.0f; + break; + } +} + +float +w_pipewrench_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR; +} + +void +w_pipewrench_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof02.spr_0.tga", + [0,0], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof01.spr_0.tga", + [0,0], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_pipewrench = +{ + .id = ITEM_PIPEWRENCH, + .slot = 0, + .slot_pos = 1, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [0,208], + .draw = w_pipewrench_draw, + .holster = w_pipewrench_holster, + .primary = w_pipewrench_primary, + .secondary = w_pipewrench_secondary, + .reload = __NULL__, + .release = w_pipewrench_release, + .crosshair = __NULL__, + .precache = w_pipewrench_precache, + .pickup = __NULL__, + .updateammo = w_pipewrench_updateammo, + .wmodel = w_pipewrench_wmodel, + .pmodel = w_pipewrench_pmodel, + .deathmsg = w_pipewrench_deathmsg, + .aimanim = w_pipewrench_aimanim, + .hudpic = w_pipewrench_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_pipewrench(void) +{ + Weapons_InitItem(WEAPON_PIPEWRENCH); +} +#endif diff --git a/src/shared/gearbox/w_shockrifle.c b/src/shared/gearbox/w_shockrifle.c new file mode 100644 index 00000000..44475c48 --- /dev/null +++ b/src/shared/gearbox/w_shockrifle.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + SHOCKRIFLE_IDLE1, + SHOCKRIFLE_SHOOT, + SHOCKRIFLE_DRAW, + SHOCKRIFLE_HOLSTER, + SHOCKRIFLE_IDLE2 +}; + +void +w_shockrifle_precache(void) +{ + precache_model("models/v_shock.mdl"); + precache_model("models/w_shock.mdl"); + precache_model("models/p_shock.mdl"); + + precache_sound("weapons/shock_discharge.wav"); + precache_sound("weapons/shock_draw.wav"); + precache_sound("weapons/shock_fire.wav"); + precache_sound("weapons/shock_impact.wav"); + precache_sound("weapons/shock_recharge.wav"); +} +void +w_shockrifle_pickup(void) +{ +#ifdef SSQC + player pl = (player)self; + pl.ammo_shock = 10; +#endif +} + +void +w_shockrifle_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, pl.ammo_shock, -1); +#endif +} + +string +w_shockrifle_wmodel(void) +{ + return "models/w_shock.mdl"; +} + +string +w_shockrifle_pmodel(void) +{ + return "models/p_shock.mdl"; +} + +string +w_shockrifle_deathmsg(void) +{ + return ""; +} + +void +w_shockrifle_draw(void) +{ + Weapons_SetModel("models/v_shock.mdl"); + Weapons_ViewAnimation(SHOCKRIFLE_DRAW); +#ifdef SSQC + player pl = (player)self; + Weapons_UpdateAmmo(pl, -1, pl.ammo_shock, -1); +#endif +} + +void +w_shockrifle_holster(void) +{ + +} + +#ifdef SSQC +void +w_shockrifle_shoothornet(void) +{ + static void Hornet_Touch(void) { + if (other.takedamage == DAMAGE_YES) { + Damage_Apply(other, self.owner, 10, trace_endpos, FALSE); + } else { + } + remove(self); + } + Weapons_MakeVectors(); + entity bolt = spawn(); + //setmodel(bolt, "models/hornet.mdl"); + setorigin(bolt, Weapons_GetCameraPos() + (v_forward * 16) + (v_up * -8)); + bolt.owner = self; + bolt.velocity = v_forward * 1000; + bolt.movetype = MOVETYPE_FLY; + bolt.solid = SOLID_BBOX; + //bolt.flags |= FL_LAGGEDMOVE; + bolt.gravity = 0.5f; + bolt.angles = vectoangles(bolt.velocity); + bolt.touch = Hornet_Touch; + setsize(bolt, [0,0,0], [0,0,0]); +} +#endif + +void +w_shockrifle_release(void) +{ + player pl = (player)self; + + if (pl.w_idle_next > 0.0) { + return; + } + + #ifdef CSQC + if (pl.a_ammo2 < 10) { + pl.a_ammo2 = bound(0, pl.a_ammo2 + 1, 10); + pl.w_idle_next = 0.5f; + } + #else + if (pl.ammo_shock < 10) { + pl.ammo_shock = bound(0, pl.ammo_shock + 1, 10); + Weapons_UpdateAmmo(pl, -1, pl.ammo_shock, -1); + pl.w_idle_next = 0.5f; + } + #endif + + if (pl.w_idle_next > 0.0) { + return; + } + + if (random() < 0.5) { + Weapons_ViewAnimation(SHOCKRIFLE_IDLE1); + } else { + Weapons_ViewAnimation(SHOCKRIFLE_IDLE2); + } + pl.w_idle_next = 3.333333f; +} + +void +w_shockrifle_primary(void) +{ + player pl = (player)self; + if (pl.w_attack_next > 0.0) { + return; + } + + /* Ammo check */ +#ifdef CSQC + if (pl.a_ammo2 <= 0) { + w_shockrifle_release(); + return; + } +#else + if (pl.ammo_shock <= 0) { + w_shockrifle_release(); + return; + } +#endif + + +#ifdef SSQC + w_shockrifle_shoothornet(); + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/shock_fire.wav", 1, ATTN_NORM); + + pl.ammo_shock--; + Weapons_UpdateAmmo(pl, -1, pl.ammo_shock, -1); +#else + pl.a_ammo2--; +#endif + + Weapons_ViewAnimation(SHOCKRIFLE_SHOOT); + pl.w_attack_next = 0.1f; + pl.w_idle_next = 0.75f; +} + +void +w_shockrifle_crosshair(void) +{ +#ifdef CSQC + vector cross_pos; + vector aicon_pos; + + /* crosshair */ + cross_pos = (video_res / 2) + [-12,-12]; + drawsubpic( + cross_pos, + [24,24], + "sprites/ofch1.spr_0.tga", + [0,24/72], + [24/72, 24/72], + [1,1,1], + 1.0, + DRAWFLAG_NORMAL + ); + + /* ammo counter */ + HUD_DrawAmmo2(); + + /* ammo icon */ + aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + "sprites/640hud7.spr_0.tga", + [224/256,48/128], + [24/256, 24/128], + g_hud_color, + pSeat->ammo2_alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_shockrifle_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMHIVE : ANIM_AIMHIVE; +} + +void +w_shockrifle_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/640hudof04.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/640hudof03.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_shockrifle = +{ + .id = ITEM_SHOCKRIFLE, + .slot = 6, + .slot_pos = 1, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [48,240], + .draw = w_shockrifle_draw, + .holster = w_shockrifle_holster, + .primary = w_shockrifle_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_shockrifle_release, + .crosshair = w_shockrifle_crosshair, + .precache = w_shockrifle_precache, + .pickup = w_shockrifle_pickup, + .updateammo = w_shockrifle_updateammo, + .wmodel = w_shockrifle_wmodel, + .pmodel = w_shockrifle_pmodel, + .deathmsg = w_shockrifle_deathmsg, + .aimanim = w_shockrifle_aimanim, + .hudpic = w_shockrifle_hudpic +}; + +#ifdef SSQC +void +weapon_shockrifle(void) +{ + Weapons_InitItem(WEAPON_SHOCKRIFLE); +} +#endif diff --git a/src/shared/gearbox/w_sniperrifle.c b/src/shared/gearbox/w_sniperrifle.c new file mode 100644 index 00000000..72946d16 --- /dev/null +++ b/src/shared/gearbox/w_sniperrifle.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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_DRAW, + SNIPER_IDLE1, + SNIPER_FIRE1, + SNIPER_FIRE2, + SNIPER_RELOAD1, + SNIPER_RELOAD2, + SNIPER_RELOAD3, + SNIPER_IDLE2, + SNIPER_HOLSTER, + SNIPER_DRAW +}; + +void +w_sniperrifle_precache(void) +{ + precache_model("models/v_m40a1.mdl"); + precache_model("models/w_m40a1.mdl"); + precache_model("models/p_m40a1.mdl"); + precache_sound("weapons/sniper_fire.wav"); +} + +void +w_sniperrifle_pickup(void) +{ + player pl = (player)self; + pl.sniper_mag = 5; +} + +void +w_sniperrifle_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, pl.sniper_mag, pl.ammo_762, __NULL__); +#endif +} + +string +w_sniperrifle_wmodel(void) +{ + return "models/w_m40a1.mdl"; +} + +string +w_sniperrifle_pmodel(void) +{ + return "models/p_m40a1.mdl"; +} + +string +w_sniperrifle_deathmsg(void) +{ + return ""; +} + +void +w_sniperrifle_draw(void) +{ + Weapons_SetModel("models/v_m40a1.mdl"); + Weapons_ViewAnimation(SNIPER_DRAW); +#ifdef SSQC + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.sniper_mag, pl.ammo_762, __NULL__); +#endif +} + +void +w_sniperrifle_holster(void) +{ + Weapons_ViewAnimation(SNIPER_HOLSTER); +} + +void +w_sniperrifle_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 SSQC + TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 40, [0.00873, 0.00873]); + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sniper_fire.wav", 1, ATTN_NORM); + + pl.sniper_mag--; + Weapons_UpdateAmmo(pl, pl.sniper_mag, pl.ammo_762, __NULL__); +#else + pl.a_ammo1--; + View_SetMuzzleflash(MUZZLE_SMALL); + Weapons_ViewPunchAngle([-10,0,0]); + + if (pl.a_ammo1) { + Weapons_ViewAnimation(SNIPER_FIRE1); + } else { + Weapons_ViewAnimation(SNIPER_FIRE2); + } +#endif + + pl.w_attack_next = 1.75f; + pl.w_idle_next = 10.0f; +} + +void +w_sniperrifle_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_sniperrifle_reload(void) +{ + player pl = (player)self; + if (pl.w_attack_next > 0.0) { + return; + } + + /* Ammo check */ +#ifdef CSQC + if (pl.a_ammo1 >= 5) { + return; + } + if (pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.sniper_mag >= 5) { + return; + } + if (pl.ammo_762 <= 0) { + return; + } +#endif + + /* Audio-Visual bit */ + /* TODO has a couple reloading states */ + Weapons_ViewAnimation(SNIPER_RELOAD1); +#ifdef SSQC + Weapons_ReloadWeapon(pl, player::sniper_mag, player::ammo_762, 5); + Weapons_UpdateAmmo(pl, pl.sniper_mag, pl.ammo_762, __NULL__); +#endif + pl.w_attack_next = 2.3f; + pl.w_idle_next = 10.0f; +} +void +w_sniperrifle_release(void) +{ + player pl = (player)self; + if (pl.w_idle_next > 0.0) { + return; + } + + if (random() < 0.5) { + Weapons_ViewAnimation(SNIPER_IDLE1); + } else { + Weapons_ViewAnimation(SNIPER_IDLE2); + } + pl.w_idle_next = 15.0f; +} +void +w_sniperrifle_crosshair(void) +{ +#ifdef CSQC + player pl = (player)self; + static vector cross_pos; + + if (pl.viewzoom == 1.0f) { + cross_pos = (video_res / 2) + [-12,-12]; + drawsubpic( + cross_pos, + [24,24], + "sprites/ofch1.spr_0.tga", + [0,48/72], + [24/72, 24/72], + [1,1,1], + 1, + DRAWFLAG_NORMAL + ); + } else { + cross_pos = (video_res / 2) + [-128,-128]; + drawsubpic( + cross_pos, + [256,256], + "sprites/ofch2.spr_0.tga", + [0,0], + [1, 1], + [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", [24/256,72/128], [24/256, 24/128], g_hud_color, pSeat->ammo2_alpha, DRAWFLAG_ADDITIVE); +#endif +} + +float +w_sniperrifle_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMPYTHON : ANIM_AIMPYTHON; +} + +void +w_sniperrifle_hudpic(int s, vector pos) +{ +#ifdef CSQC + if (s) { + drawsubpic(pos, [170,45], "sprites/640hudof04.spr_0.tga", [0,135/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], "sprites/640hudof03.spr_0.tga", [0,135/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } +#endif +} + +weapon_t w_sniperrifle = +{ + .id = ITEM_SNIPERRIFLE, + .slot = 5, + .slot_pos = 2, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [144,208], + .draw = w_sniperrifle_draw, + .holster = w_sniperrifle_holster, + .primary = w_sniperrifle_primary, + .secondary = w_sniperrifle_secondary, + .reload = w_sniperrifle_reload, + .release = w_sniperrifle_release, + .crosshair = w_sniperrifle_crosshair, + .precache = w_sniperrifle_precache, + .pickup = w_sniperrifle_pickup, + .updateammo = w_sniperrifle_updateammo, + .wmodel = w_sniperrifle_wmodel, + .pmodel = w_sniperrifle_pmodel, + .deathmsg = w_sniperrifle_deathmsg, + .aimanim = w_sniperrifle_aimanim, + .hudpic = w_sniperrifle_hudpic +}; + +#ifdef SSQC +void +weapon_sniperrifle(void) +{ + Weapons_InitItem(WEAPON_SNIPERRIFLE); +} +#endif diff --git a/src/shared/gearbox/w_sporelauncher.c b/src/shared/gearbox/w_sporelauncher.c new file mode 100644 index 00000000..66a3054e --- /dev/null +++ b/src/shared/gearbox/w_sporelauncher.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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 +{ + SPORE_IDLE1, + SPORE_FIDGET, + SPORE_RELOAD1, + SPORE_RELOAD2, + SPORE_RELOAD3, + SPORE_FIRE, + SPORE_HOLSTER, + SPORE_DRAW, + SPORE_IDLE2 +}; + +void +w_sporelauncher_precache(void) +{ + precache_model("models/spore.mdl"); + precache_model("models/v_spore_launcher.mdl"); + precache_model("models/w_spore_launcher.mdl"); + precache_model("models/p_spore_launcher.mdl"); + precache_sound("weapons/splauncher_altfire.wav"); + precache_sound("weapons/splauncher_bounce.wav"); + precache_sound("weapons/splauncher_fire.wav"); + precache_sound("weapons/splauncher_impact.wav"); + precache_sound("weapons/splauncher_pet.wav"); + precache_sound("weapons/splauncher_reload.wav"); + precache_sound("weapons/spore_ammo.wav"); + precache_sound("weapons/spore_hit1.wav"); + precache_sound("weapons/spore_hit2.wav"); + precache_sound("weapons/spore_hit3.wav"); + +} +void +w_sporelauncher_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, pl.sporelauncher_mag, pl.ammo_spore, -1); +#endif +} + +string +w_sporelauncher_wmodel(void) +{ + return "models/w_spore_launcher.mdl"; +} + +string +w_sporelauncher_pmodel(void) +{ + return "models/p_spore_launcher.mdl"; +} +string +w_sporelauncher_deathmsg(void) +{ + return ""; +} + +void +w_sporelauncher_pickup(void) +{ +#ifdef SSQC + player pl = (player)self; + pl.sporelauncher_mag = bound(0, pl.sporelauncher_mag + 5, 5); +#endif +} + +void +w_sporelauncher_draw(void) +{ +#ifdef CSQC + Weapons_SetModel("models/v_spore_launcher.mdl"); + Weapons_ViewAnimation(SPORE_DRAW); +#else + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.sporelauncher_mag, pl.ammo_spore, -1); +#endif +} + +void +w_sporelauncher_holster(void) +{ + Weapons_ViewAnimation(SPORE_HOLSTER); +} + +void +w_sporelauncher_primary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + +#ifdef SSQC + static void Spore_Touch(void) { + int r; + string hitsnd; + + if (other.takedamage == DAMAGE_YES) { + Damage_Apply(other, self.owner, 50, trace_endpos, FALSE); + } + + r = floor(random(0,3)); + hitsnd = "weapons/spore_hit1.wav"; + switch (r) { + case 0: + hitsnd = "weapons/spore_hit2.wav"; + break; + case 1: + hitsnd = "weapons/spore_hit3.wav"; + break; + } + sound(self, CHAN_BODY, hitsnd, 1.0f, ATTN_NORM); + remove(self); + } + + if (pl.sporelauncher_mag <= 0) { + return; + } + + Weapons_MakeVectors(); + entity blob = spawn(); + setmodel(blob, "models/spore.mdl"); + setorigin(blob, Weapons_GetCameraPos() + (v_forward * 16)); + blob.owner = self; + blob.velocity = v_forward * 2000; + blob.movetype = MOVETYPE_BOUNCE; + blob.solid = SOLID_BBOX; + //bolt.flags |= FL_LAGGEDMOVE; + blob.gravity = 0.5f; + blob.angles = vectoangles(blob.velocity); + blob.avelocity[2] = 10; + blob.touch = Spore_Touch; + blob.weapon = pl.viewzoom == 1.0 ? 1 : 0; + setsize(blob, [0,0,0], [0,0,0]); + + pl.sporelauncher_mag--; + Weapons_UpdateAmmo(pl, pl.sporelauncher_mag, pl.ammo_spore, -1); + sound(self, CHAN_WEAPON, "weapons/splauncher_fire.wav", 1, ATTN_NORM); +#else + if (pl.a_ammo1 <= 0) { + return; + } + + Weapons_ViewPunchAngle([-2,0,0]); + Weapons_ViewAnimation(SPORE_FIRE); +#endif + + pl.w_attack_next = 0.75f; + pl.w_idle_next = 10.0f; +} + +void +w_sporelauncher_reload(void) +{ + player pl = (player)self; +#ifdef CSQC + if (pl.a_ammo1 >= 5) { + return; + } + if (pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.shotgun_mag >= 5) { + return; + } + if (pl.ammo_buckshot <= 0) { + return; + } +#endif + + if (pl.a_ammo3 > SHOTTY_IDLE) { + return; + } + pl.a_ammo3 = SPORE_RELOAD1; + pl.w_idle_next = 0.0f; +} + +void +w_sporelauncher_crosshair(void) +{ +#ifdef CSQC + vector cross_pos; + vector aicon_pos; + + /* crosshair */ + cross_pos = (video_res / 2) + [-12,-12]; + drawsubpic( + cross_pos, + [24,24], + "sprites/ofch1.spr_0.tga", + [24/72,24/72], + [24/72,24/72], + [1,1,1], + 1.0, + DRAWFLAG_NORMAL + ); + + /* ammo counters */ + HUD_DrawAmmo1(); + HUD_DrawAmmo2(); + + /* ammo icon */ + aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + drawsubpic( + aicon_pos, + [24,24], + "sprites/640hud7.spr_0.tga", + [200/256,48/128], + [24/256, 24/128], + g_hud_color, + pSeat->ammo2_alpha, + DRAWFLAG_ADDITIVE + ); +#endif +} + +float +w_sporelauncher_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMBOW : ANIM_AIMBOW; +} + +void +w_sporelauncher_hudpic(int s, vector pos) +{ +#ifdef CSQC + if (s) { + drawsubpic(pos, [170,45], "sprites/640hudof04.spr_0.tga", [0,0], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], "sprites/640hudof03.spr_0.tga", [0,0], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } +#endif +} + +weapon_t w_sporelauncher = +{ + .id = ITEM_SPORELAUNCHER, + .slot = 6, + .slot_pos = 0, + .ki_spr = "sprites/320hudof01.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [48,224], + .draw = w_sporelauncher_draw, + .holster = w_sporelauncher_holster, + .primary = w_sporelauncher_primary, + .secondary = w_sporelauncher_primary, + .reload = w_sporelauncher_reload, + .release = __NULL__, + .crosshair = w_sporelauncher_crosshair, + .precache = w_sporelauncher_precache, + .pickup = w_sporelauncher_pickup, + .updateammo = w_sporelauncher_updateammo, + .wmodel = w_sporelauncher_wmodel, + .pmodel = w_sporelauncher_pmodel, + .deathmsg = w_sporelauncher_deathmsg, + .aimanim = w_sporelauncher_aimanim, + .hudpic = w_sporelauncher_hudpic +}; + +#ifdef SSQC +void +weapon_sporelauncher(void) +{ + Weapons_InitItem(WEAPON_SPORELAUNCHER); +} +#endif + diff --git a/src/shared/gearbox/weapons.c b/src/shared/gearbox/weapons.c new file mode 100644 index 00000000..926f11ea --- /dev/null +++ b/src/shared/gearbox/weapons.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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_pipewrench, + w_knife, + w_grapple, + w_glock, + w_python, + w_eagle, + w_mp5, + w_shotgun, + w_crossbow, + w_rpg, + w_gauss, + w_egon, + w_hornetgun, + w_handgrenade, + w_satchel, + w_tripmine, + w_snark, + w_penguin, + w_m249, + w_displacer, + w_sniperrifle, + w_sporelauncher, + w_shockrifle +}; diff --git a/src/shared/gearbox/weapons.h b/src/shared/gearbox/weapons.h new file mode 100644 index 00000000..6ccf3309 --- /dev/null +++ b/src/shared/gearbox/weapons.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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_PIPEWRENCH, + WEAPON_KNIFE, + WEAPON_GRAPPLE, + WEAPON_GLOCK, + WEAPON_PYTHON, + WEAPON_EAGLE, + WEAPON_MP5, + WEAPON_SHOTGUN, + WEAPON_CROSSBOW, + WEAPON_RPG, + WEAPON_GAUSS, + WEAPON_EGON, + WEAPON_HORNETGUN, + WEAPON_HANDGRENADE, + WEAPON_SATCHEL, + WEAPON_TRIPMINE, + WEAPON_SNARK, + WEAPON_PENGUIN, + WEAPON_M249, + WEAPON_DISPLACER, + WEAPON_SNIPERRIFLE, + WEAPON_SPORELAUNCHER, + WEAPON_SHOCKRIFLE +}; + +/* What the weapons do support and stuff */ +enum +{ + AMMO_9MM, + AMMO_357, + AMMO_BUCKSHOT, + AMMO_M203_GRENADE, + AMMO_BOLT, + AMMO_ROCKET, + AMMO_URANIUM, + AMMO_HANDGRENADE, + AMMO_SATCHEL, + AMMO_TRIPMINE, + AMMO_SNARK, + AMMO_556, + AMMO_762, + AMMO_SPORE +}; diff --git a/src/shared/valve/w_crowbar.c b/src/shared/valve/w_crowbar.c index 01bf8539..1e682c8c 100644 --- a/src/shared/valve/w_crowbar.c +++ b/src/shared/valve/w_crowbar.c @@ -45,7 +45,7 @@ void w_crowbar_updateammo(player pl) { #ifdef SSQC - Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); + Weapons_UpdateAmmo(pl, -1, -1, -1); #endif } @@ -83,6 +83,7 @@ void w_crowbar_primary(void) { int anim = 0; + int r; vector src; player pl = (player)self; @@ -94,7 +95,15 @@ w_crowbar_primary(void) src = pl.origin + pl.view_ofs; traceline(src, src + (v_forward * 32), FALSE, pl); - int r = (float)input_sequence % 3; + 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 ? CBAR_ATTACK1MISS:CBAR_ATTACK1HIT; @@ -106,16 +115,7 @@ w_crowbar_primary(void) anim = trace_fraction >= 1 ? CBAR_ATTACK3MISS:CBAR_ATTACK3HIT; } Weapons_ViewAnimation(anim); - - 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 SSQC +#else if (pl.flags & FL_CROUCHING) { Animation_PlayerTopTemp(ANIM_SHOOTCROWBAR, 0.5f); } else { @@ -142,12 +142,17 @@ w_crowbar_primary(void) return; } - if (random() < 0.33) { + r = floor(random(0,3)); + switch (r) { + case 0: sound(pl, 8, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM); - } else if (random() < 0.66) { + break; + case 1: sound(pl, 8, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM); - } else { + break; + case 2: sound(pl, 8, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM); + break; } } else { if (random() < 0.5) { diff --git a/src/shared/valve/w_glock.c b/src/shared/valve/w_glock.c index e1efedb9..c9914294 100644 --- a/src/shared/valve/w_glock.c +++ b/src/shared/valve/w_glock.c @@ -129,6 +129,7 @@ void w_glock_secondary(void) return; } + View_SetMuzzleflash(MUZZLE_SMALL); Weapons_ViewPunchAngle([-2,0,0]); #else if (!pl.glock_mag) { diff --git a/src/shared/valve/w_snark.c b/src/shared/valve/w_snark.c index 80cd6dc3..a6b265ea 100644 --- a/src/shared/valve/w_snark.c +++ b/src/shared/valve/w_snark.c @@ -119,7 +119,7 @@ void w_snark_deploy(void) snark.frame = 3; /* running like crazy. */ snark.customphysics = snark_ai; snark.angles = self.angles; - snark.health = 30; + snark.health = 20; snark.vPain = snark_pain; snark.takedamage = DAMAGE_YES; snark.aiment = __NULL__; diff --git a/src/shared/valve/weapon_common.c b/src/shared/valve/weapon_common.c index 64768443..807cc1de 100644 --- a/src/shared/valve/weapon_common.c +++ b/src/shared/valve/weapon_common.c @@ -269,6 +269,17 @@ void Weapons_InitItem(int w) void Weapons_UpdateAmmo(player pl, int a1, int a2, int a3) { + /* no change */ + if (a1 == -1) { + a1 = pl.a_ammo1; + } + if (a2 == -1) { + a2 = pl.a_ammo2; + } + if (a3 == -1) { + a3 = pl.a_ammo3; + } + /* Networked as bytes, since we don't need more. Clamp to avoid errors */ pl.a_ammo1 = bound(0, a1, 255); pl.a_ammo2 = bound(0, a2, 255);