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.
This commit is contained in:
Marco Cawthorne 2019-09-12 01:08:56 +02:00
parent a683994dc5
commit bf5c78fab2
30 changed files with 3694 additions and 29 deletions

View file

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

View file

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

55
src/client/gearbox/init.c Normal file
View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
float(entity foo, float chanid) getchannellevel = #0;
/*
=================
Client_Init
Comparable to worldspawn in SSQC in that it's mostly used for precaches
=================
*/
void Client_Init(float apilevel, string enginename, float engineversion)
{
precache_model("sprites/640hud1.spr");
precache_model("sprites/640hud2.spr");
precache_model("sprites/640hud3.spr");
precache_model("sprites/640hud4.spr");
precache_model("sprites/640hud5.spr");
precache_model("sprites/640hud6.spr");
precache_model("sprites/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)
{
}

View file

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

View file

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

View file

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

View file

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

View file

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

88
src/server/gearbox/progs.src Executable file
View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
int input_sequence;
class player
{
float health;
float armor;
/* When the weapon is done firing */
float w_attack_next;
/* When to play the next idle animation */
float w_idle_next;
/* Magazine/Clip */
int a_ammo1;
/* Rest in the inventory */
int a_ammo2;
/* Special ammo */
int a_ammo3;
/* We can't use the default .items field, because FTE will assume
* effects of some bits. Such as invisibility, quad, etc.
* also, modders probably want 32 bits for items. */
int g_items;
float activeweapon;
float viewzoom;
vector 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
};

View file

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

View file

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

View file

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

View file

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

301
src/shared/gearbox/w_m249.c Normal file
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -129,6 +129,7 @@ void w_glock_secondary(void)
return;
}
View_SetMuzzleflash(MUZZLE_SMALL);
Weapons_ViewPunchAngle([-2,0,0]);
#else
if (!pl.glock_mag) {

View file

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

View file

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