Insanity is now fully reimplemented

This commit is contained in:
Xylemon 2023-04-23 04:05:45 -07:00
parent 67707192fe
commit 181090b701
9 changed files with 882 additions and 24 deletions

69
src/client/defs.h Normal file
View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../valve/src/client/obituary.h"
#include "../../../valve/src/client/particles.h"
var int autocvar_cl_autoweaponswitch = TRUE;
vector g_hud_color;
vector g_hudmins;
vector g_hudres;
var string g_hud1_spr;
var string g_hud2_spr;
var string g_hud3_spr;
var string g_hud4_spr;
var string g_hud5_spr;
var string g_hud6_spr;
var string g_hud7_spr;
var string g_cross_spr;
var string g_laser_spr;
/* muzzleflash indices */
var int MUZZLE_SMALL;
var int MUZZLE_RIFLE;
var int MUZZLE_WEIRD;
struct
{
/* hud.c */
int m_iHealthOld;
float m_flHealthAlpha;
int m_iArmorOld;
float m_flArmorAlpha;
int m_iAmmo1Old;
float m_flAmmo1Alpha;
int m_iAmmo2Old;
float m_flAmmo2Alpha;
int m_iAmmo3Old;
float m_flAmmo3Alpha;
int m_iAmmoInsaneOld;
float m_flAmmoInsaneAlpha;
int m_iPickupWeapon;
float m_flPickupAlpha;
int m_iHUDWeaponSelected;
float m_flHUDWeaponSelectTime;
int m_iItemsOld;
float m_flDamageIndicator;
} g_seatslocal[4], *pSeatLocal;
void HUD_DrawAmmo1(void);
void HUD_DrawAmmo2(void);
void HUD_DrawAmmo3(void);
void HUD_DrawAmmoBar(vector pos, float val, float max, float a);
void HUD_WeaponPickupNotify(int);

612
src/client/hud.qc Normal file
View file

@ -0,0 +1,612 @@
/*
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
* Copyright (c) 2016-2023 Gethyn ThomasQuail <gethyn@vera-visions.com>
*
* 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 HUD_DrawWeaponSelect(void);
/* Use first frame for drawing (needs precache) */
#define NUMSIZE_X 24/256
#define NUMSIZE_Y 24/128
#define HUD_ALPHA 0.5
float spr_hudnum[10] = {
0 / 256,
24 / 256,
(24*2) / 256,
(24*3) / 256,
(24*4) / 256,
(24*5) / 256,
(24*6) / 256,
(24*7) / 256,
(24*8) / 256,
(24*9) / 256
};
/* pre-calculated sprite definitions */
float spr_health[4] = {
80 / 256, // pos x
24 / 128, // pos u
32 / 256, // size x
32 / 128 // size y
};
float spr_suit1[4] = {
0 / 256, // pos x
24 / 128, // pos u
40 / 256, // size x
40 / 128 // size y
};
float spr_suit2[4] = {
40 / 256, // pos x
24 / 128, // pos u
40 / 256, // size x
40 / 128 // size y
};
float spr_flash1[4] = {
160 / 256, // pos x
24 / 128, // pos u
32 / 256, // size x
32 / 128 // size y
};
float spr_flash2[4] = {
112 / 256, // pos x
24 / 128, // pos u
48 / 256, // size x
32 / 128 // size y
};
string g_hud_insanity01;
string g_hud_insanity02;
string g_hud_insanity03;
/* precaches */
void
HUD_Init(void)
{
g_cross_spr = spriteframe("sprites/crosshairs.spr", 0, 0.0f);
g_laser_spr = spriteframe("sprites/laserdot.spr", 0, 0.0f);
g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f);
g_hud2_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
g_hud3_spr = spriteframe("sprites/640hud3.spr", 0, 0.0f);
g_hud4_spr = spriteframe("sprites/640hud4.spr", 0, 0.0f);
g_hud5_spr = spriteframe("sprites/640hud5.spr", 0, 0.0f);
g_hud6_spr = spriteframe("sprites/640hud6.spr", 0, 0.0f);
g_hud7_spr = spriteframe("sprites/640hud7.spr", 0, 0.0f);
g_hud_insanity01 = spriteframe("sprites/insanity.spr", 0, 0.0f);
g_hud_insanity02 = spriteframe("sprites/insanity2.spr", 0, 0.0f);
g_hud_insanity03 = spriteframe("sprites/insanity3.spr", 0, 0.0f);
HUD_AmmoNotify_Init();
HUD_DamageNotify_Init();
HUD_ItemNotify_Init();
}
/* seperator for mainly ammo */
void
HUD_DrawSeperator(vector pos)
{
drawsubpic(pos,
[2,24],
g_hud7_spr,
[240/256, 0],
[2/256, 24/128],
g_hud_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
/* handle single/multiple digits */
void
HUD_DrawNumber(int iNumber, vector vecPos, float fAlpha, vector vColor)
{
drawsubpic(vecPos,
[24,24],
g_hud7_spr,
[spr_hudnum[iNumber], 0],
[NUMSIZE_X, NUMSIZE_Y],
vColor,
fAlpha,
DRAWFLAG_ADDITIVE
);
}
void
HUD_DrawNums(float fNumber, vector vecPos, float fAlpha, vector vColor)
{
int i = fNumber;
if (i > 0) {
while (i > 0) {
HUD_DrawNumber((float)i % 10.0f, vecPos, fAlpha, vColor);
i = i / 10;
vecPos[0] -= 20;
}
} else {
HUD_DrawNumber(0, vecPos, fAlpha, vColor);
}
}
/* health */
void
HUD_DrawHealth(void)
{
vector pos;
player pl = (player)pSeat->m_ePlayer;
if (pl.health != pSeatLocal->m_iHealthOld) {
pSeatLocal->m_flHealthAlpha = 1.0;
}
if (pSeatLocal->m_flHealthAlpha >= HUD_ALPHA) {
pSeatLocal->m_flHealthAlpha -= clframetime * 0.5;
} else {
pSeatLocal->m_flHealthAlpha = HUD_ALPHA;
}
pos = g_hudmins + [88, g_hudres[1] - 42];
if (pl.health > 25) {
drawsubpic(
pos + [-72,-4],
[32,32],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
g_hud_color,
pSeatLocal->m_flHealthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(pl.health, pos, pSeatLocal->m_flHealthAlpha, g_hud_color);
} else {
drawsubpic(
pos + [-72,-4],
[32,32],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
[1,0,0],
pSeatLocal->m_flHealthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(pl.health, pos, pSeatLocal->m_flHealthAlpha, [1,0,0]);
}
pSeatLocal->m_iHealthOld = pl.health;
}
/* armor/suit charge */
void
HUD_DrawArmor(void)
{
vector pos;
player pl = (player)pSeat->m_ePlayer;
pos = g_hudmins + [198, g_hudres[1] - 42];
if (pl.armor != pSeatLocal->m_iArmorOld) {
pSeatLocal->m_flArmorAlpha = 1.0;
}
if (pSeatLocal->m_flArmorAlpha >= HUD_ALPHA) {
pSeatLocal->m_flArmorAlpha -= clframetime * 0.5;
} else {
pSeatLocal->m_flArmorAlpha = HUD_ALPHA;
}
drawsubpic(
pos + [-80,-9],
[40,40],
g_hud7_spr,
[spr_suit2[0], spr_suit2[1]],
[spr_suit2[2], spr_suit2[3]],
g_hud_color,
pSeatLocal->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
if (pl.armor > 0) {
float perc = bound(0, (pl.armor / 100), 1.0);
drawsubpic(
pos + [-80,-9] + [0, 40 * (1.0-perc)],
[40, 40 * perc],
g_hud7_spr,
[spr_suit1[0],spr_suit1[1] + spr_suit1[3] * (1.0-perc)],
[spr_suit1[2], spr_suit1[3] * perc],
g_hud_color,
pSeatLocal->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
}
HUD_DrawNums(pl.armor, pos, pSeatLocal->m_flArmorAlpha, g_hud_color);
pSeatLocal->m_iArmorOld = pl.armor;
}
/* magazine/clip ammo */
void
HUD_DrawAmmo1(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo1 != pSeatLocal->m_iAmmo1Old) {
pSeatLocal->m_flAmmo1Alpha = 1.0;
pSeatLocal->m_iAmmo1Old = pl.a_ammo1;
}
if (pSeatLocal->m_flAmmo1Alpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmo1Alpha -= clframetime * 0.5;
} else {
pSeatLocal->m_flAmmo1Alpha = HUD_ALPHA;
}
pos = g_hudmins + [g_hudres[0] - 152, g_hudres[1] - 42];
HUD_DrawNums(pl.a_ammo1, pos, pSeatLocal->m_flAmmo1Alpha, g_hud_color);
HUD_DrawSeperator(pos + [30,0]);
}
/* leftover type ammo */
void
HUD_DrawAmmo2(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo2 != pSeatLocal->m_iAmmo2Old) {
pSeatLocal->m_flAmmo2Alpha = 1.0;
pSeatLocal->m_iAmmo2Old = pl.a_ammo2;
}
if (pSeatLocal->m_flAmmo2Alpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmo2Alpha -= clframetime * 0.5;
} else {
pSeatLocal->m_flAmmo2Alpha = HUD_ALPHA;
}
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 42];
HUD_DrawNums(pl.a_ammo2, pos, pSeatLocal->m_flAmmo2Alpha, g_hud_color);
}
/* special ammo */
void
HUD_DrawAmmo3(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo3 != pSeatLocal->m_iAmmo3Old) {
pSeatLocal->m_flAmmo3Alpha = 1.0;
pSeatLocal->m_iAmmo3Old = pl.a_ammo3;
}
if (pSeatLocal->m_flAmmo3Alpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmo3Alpha -= clframetime * 0.5;
} else {
pSeatLocal->m_flAmmo3Alpha = HUD_ALPHA;
}
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 74];
HUD_DrawNums(pl.a_ammo3, pos, pSeatLocal->m_flAmmo3Alpha, g_hud_color);
}
/* ammo bar */
void
HUD_DrawAmmoBar(vector pos, float val, float max, float a)
{
if (val <= 0)
return;
float perc;
perc = val / max;
drawfill(pos + [10,0], [20,4], g_hud_color, a, DRAWFLAG_NORMAL);
drawfill(pos + [10,0], [20 * perc,4], [0,1,0], a, DRAWFLAG_NORMAL);
}
/* flashlight/torch indicator */
void
HUD_DrawFlashlight(void)
{
vector pos;
player pl = (player)pSeat->m_ePlayer;
pos = g_hudmins + [g_hudres[0] - 48, 16];
/* both on, draw both sprites at full intensity */
if (pl.gflags & GF_FLASHLIGHT) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[spr_flash1[0], spr_flash1[1]],
[spr_flash1[2], spr_flash1[3]],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos,
[48,32],
g_hud7_spr,
[spr_flash2[0], spr_flash2[1]],
[spr_flash2[2], spr_flash2[3]],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[spr_flash1[0], spr_flash1[1]],
[spr_flash1[2], spr_flash1[3]],
g_hud_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
}
/* logo animation used during e3 1998 */
void
HUD_DrawLogo(void)
{
vector pos;
static int f;
static float frame_timer;
frame_timer -= clframetime;
pos = [g_hudres[0] - 262, 48];
drawpic(
pos,
sprintf("sprites/640_logo.spr_%i.tga", f),
[256,48],
[1,1,1],
1.0f,
DRAWFLAG_ADDITIVE
);
if (frame_timer > 0) {
return;
}
frame_timer = 0.1f;
f++;
if (f == 31) {
f = 0;
}
}
/* weapon/ammo pickup notifications */
void
HUD_DrawNotify(void)
{
player pl = (player)self;
vector pos;
float a;
pos = g_hudmins + [g_hudres[0] - 192, g_hudres[1] - 128];
if (pSeatLocal->m_flPickupAlpha <= 0.0f) {
pos[1] += 48;
HUD_ItemNotify_Draw(pos);
HUD_AmmoNotify_Draw(pos);
return;
}
a = bound(0.0, pSeatLocal->m_flPickupAlpha, 1.0);
pos[1] += 48 * (1.0 - a);
Weapons_HUDPic(pl, pSeatLocal->m_iPickupWeapon, 1, pos, a);
HUD_ItemNotify_Draw(pos);
HUD_AmmoNotify_Draw(pos);
pSeatLocal->m_flPickupAlpha -= (clframetime * 0.5);
}
void
HUD_WeaponPickupNotify(int w)
{
#if defined (VALVE) || defined (GEARBOX)
switch (w) {
case WEAPON_SNARK:
case WEAPON_SATCHEL:
case WEAPON_HANDGRENADE:
case WEAPON_TRIPMINE:
#if defined(GEARBOX)
case WEAPON_PENGUIN:
#endif
return;
default:
}
#endif
pSeatLocal->m_iPickupWeapon = w;
pSeatLocal->m_flPickupAlpha = 2.5f;
}
void
HUD_DrawDamageIndicator(void)
{
vector cross_pos;
if (pSeatLocal->m_flDamageIndicator <= 0.0)
return;
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
/*drawsubpic(
cross_pos,
[24,24],
g_cross_spr,
[0.0, 72/128],
[0.1875, 0.1875],
[1,1,1] * pSeatLocal->m_flDamageIndicator,
1.0f,
DRAWFLAG_ADDITIVE
);*/
pSeatLocal->m_flDamageIndicator -= clframetime;
}
void
HUD_DrawInsanityIcon(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
float insanityalpha;
pos = g_hudmins + [13, g_hudres[1] - 92];
if (pl.gflags & GF_MADNESS) {
insanityalpha = bound(0,pl.sh_insaneactive * 0.05f,0.4);
drawfill(
video_mins,
video_res,
[1,0,0],
insanityalpha,
DRAWFLAG_ADDITIVE
);
}
if (pl.gflags & GF_MADNESS) {
drawsubpic(pos,
[40, 40],
g_hud_insanity01,
[0, 0],
[1.0, 1.0],
[1,1,1],
1.0f,
0
);
}
if (pl.sh_insaneactive > 40) {
drawsubpic(pos,
[40, 40],
g_hud_insanity02,
[0, 0],
[1.0, 1.0],
[1,1,1],
1.0f,
0
);
}
if (pl.sh_insaneactive > 50) {
drawsubpic(pos,
[40, 40],
g_hud_insanity03,
[0, 0],
[1.0, 1.0],
[1,1,1],
1.0f,
0
);
}
}
void
HUD_DrawInsanityTime(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
float insanecount = floor(pl.sh_insaneactive);
if (pl.gflags & GF_MADNESS) {
if (insanecount != pSeatLocal->m_iAmmoInsaneOld) {
pSeatLocal->m_flAmmoInsaneAlpha = 1.0;
pSeatLocal->m_iAmmoInsaneOld = insanecount;
}
if (pSeatLocal->m_flAmmoInsaneAlpha >= HUD_ALPHA) {
pSeatLocal->m_flAmmoInsaneAlpha -= clframetime * 0.5;
} else {
pSeatLocal->m_flAmmoInsaneAlpha = HUD_ALPHA;
}
pos = g_hudmins + [76, g_hudres[1] - 84];
HUD_DrawNums(insanecount, pos, pSeatLocal->m_flAmmoInsaneAlpha, g_hud_color);
}
}
/* main entry */
void
HUD_Draw(void)
{
player pl = (player)pSeat->m_ePlayer;
#ifndef TFC
g_hud_color = autocvar_con_color * (1 / 255);
#endif
/* little point in not drawing these, even if you don't have a suit */
Weapons_DrawCrosshair(pl);
HUD_DrawDamageIndicator();
HUD_DrawWeaponSelect();
Obituary_Draw();
Textmenu_Draw();
if (!(pl.g_items & ITEM_SUIT)) {
return;
}
HUD_DrawInsanityIcon();
HUD_DrawInsanityTime();
HUD_DamageNotify_Draw();
HUD_DrawHealth();
HUD_DrawArmor();
HUD_DrawFlashlight();
HUD_DrawNotify();
Damage_Draw();
}
string g_specmodes[] = {
"Free Camera",
"Third Person",
"First Person"
};
/* specatator main entry */
void
HUD_DrawSpectator(void)
{
Textmenu_Draw();
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
drawfont = Font_GetID(FONT_20);
vector vecPos = [0.0f, 0.0f, 0.0f];
string strText = __NULL__;
float palpha = 1.0f;
if (spec.spec_mode == SPECMODE_FREE) {
palpha = 0.5f;
}
strText = sprintf("Tracking: %s", getplayerkeyvalue(spec.spec_ent - 1, "name"));
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [20,20]) / 2);
vecPos[1] = g_hudmins[1] + g_hudres[1] - 60;
drawstring(vecPos, strText, [20,20], [1,1,1], palpha, DRAWFLAG_ADDITIVE);
strText = sprintf("Mode: %s", g_specmodes[spec.spec_mode]);
vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(strText, TRUE, [20,20]) / 2);
vecPos[1] = g_hudmins[1] + g_hudres[1] - 40;
drawstring(vecPos, strText, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
}

View file

@ -10,7 +10,7 @@
#includelist
../../../src/shared/fteextensions.qc
../../../src/shared/defs.h
../../../valve/src/client/defs.h
defs.h
../../../src/client/defs.h
../../../src/vgui/include.src
@ -21,7 +21,7 @@
../../../valve/src/client/damage.qc
draw.qc
../../../valve/src/client/init.qc
init.qc
../../../valve/src/client/flashlight.qc
../../../valve/src/client/entities.qc
cmds.qc
@ -33,12 +33,13 @@ cmds.qc
../../../valve/src/client/hud_ammonotify.qc
../../../valve/src/client/hud_dmgnotify.qc
../../../valve/src/client/hud_itemnotify.qc
../../../valve/src/client/hud.qc
hud.qc
../../../valve/src/client/hud_weaponselect.qc
../../../valve/src/client/scoreboard.qc
../../../valve/src/client/modelevent.qc
../../../src/client/include.src
../../../valve/src/client/vgui_motd.qc
vgui_motd.qc
vgui_chooseteam.qc
../../../src/shared/include.src
#endlist

View file

@ -56,7 +56,11 @@ class SHTeamRules:HLGameRules
virtual bool(void) IsTeamplay;
virtual void(void) AddTeam1Kill;
virtual void(void) AddTeam2Kill;
virtual void(void) RemoveTeam1Kill;
virtual void(void) RemoveTeam2Kill;
virtual void(void) RegisterSciDeathHuntTeam;
virtual void(NSClientPlayer, entity) ScientistKill;
virtual void(NSClientPlayer, entity) ScientistKillFear;
virtual void(void) InitPostEnts;
};
@ -66,8 +70,6 @@ class SHTeamRules:HLGameRules
class SHGameHunt:SHTeamRules
{
void(void) SHGameHunt;
virtual void(void) RegisterSciDeath;
};
/* Stealth Hunting (1):
@ -75,7 +77,6 @@ class SHGameHunt:SHTeamRules
*/
class SHGameStealth:SHTeamRules
{
void(void) SHGameStealth;
};
@ -84,7 +85,6 @@ class SHGameStealth:SHTeamRules
*/
class SHGameSlaughter:HLGameRules
{
void(void) SHGameSlaughter;
};
@ -93,7 +93,6 @@ class SHGameSlaughter:HLGameRules
*/
class SHGameFear:HLGameRules
{
void(void) SHGameFear;
};

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
* Copyright (c) 2016-2023 Gethyn ThomasQuail <gethyn@vera-visions.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -45,6 +46,9 @@ HLGameRules::IsMultiplayer(void)
void
HLGameRules::PlayerDeath(NSClientPlayer pl)
{
player sh_pl = (player)pl;
/* obituary networking */
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_OBITUARY);
@ -71,10 +75,14 @@ HLGameRules::PlayerDeath(NSClientPlayer pl)
g_dmg_eAttacker.frags++;
}
pl.Death();
pl.takedamage = DAMAGE_NO;
pl.gflags &= ~GF_FLASHLIGHT;
pl.gflags &= ~GF_EGONBEAM;
pl.gflags &= ~GF_MADNESS;
sh_pl.sh_insaneactive = 0.0f;
pl.think = PutClientInServer;
pl.nextthink = time + 4.0f;
@ -239,14 +247,20 @@ HLGameRules::PlayerPostFrame(NSClientPlayer pp)
pl.sh_insaneactive = bound(0.0f, pl.sh_insaneactive - frametime, pl.sh_insaneactive);
if (pl.sh_insaneactive > 0.0f)
pl.gflags |= GF_MADNESS;
else {
/* Apply insanity flag to players, and players only */
if (pl.sh_insaneactive > 0.0f) {
if not (pl.gflags & GF_MADNESS) {
pl.gflags |= GF_MADNESS;
bprint(PRINT_HIGH, sprintf("%s is going insane!\n", pl.netname));
Sound_Play(pl, CHAN_AUTO, "player.insane");
}
} else {
if (pl.gflags & GF_MADNESS) {
bprint(PRINT_CHAT, sprintf("%s is no longer insane!\n", pl.netname));
bprint(PRINT_HIGH, sprintf("%s is no longer insane!\n", pl.netname));
}
pl.gflags &= ~GF_MADNESS;
}
}
void
@ -275,10 +289,12 @@ HLGameRules::ScientistKill(NSClientPlayer pp, entity sci)
msg_entity = world;
multicast([0,0,0], MULTICAST_ALL);
/* give players a frag per scientist they kill */
pl.frags++;
/*if (g_weapons[g_dmg_iWeapon].slot != 0)
return;*/
/* only reward melee frags for insanity, otherwise it's a bit OP */
if (g_weapons[g_dmg_iWeapon].slot != 0)
return;
/* if this is our first kill in a while, or in the timer... */
if (pl.sh_insanecount == 0 || pl.sh_insanetime > time) {
@ -288,11 +304,15 @@ HLGameRules::ScientistKill(NSClientPlayer pp, entity sci)
}
if (pl.sh_insanecount >= autocvar_sh_insanity) {
if (pl.sh_insaneactive <= 0.0f)
bprint(PRINT_CHAT, sprintf("%s is going insane!\n", pl.netname));
pl.sh_insaneactive += 3.0f;
/* always start with a 30 second cooldown
* otherwise give 3 seconds per frag */
if (pl.gflags & GF_MADNESS) {
pl.sh_insaneactive += 3.0f;
} else {
pl.sh_insaneactive += 30.0f;
}
/* clamp our timer */
if (pl.sh_insaneactive > 60)
pl.sh_insaneactive = 60;
}
@ -402,6 +422,18 @@ SHTeamRules::ScientistKill(NSClientPlayer cl, entity sci)
AddTeam1Kill();
}
void
SHTeamRules::ScientistKillFear(NSClientPlayer cl, entity sci)
{
super::ScientistKill(cl, sci);
if (cl.team == 2)
RemoveTeam2Kill();
else if (cl.team == 1)
AddTeam1Kill();
}
void
SHTeamRules::AddTeam1Kill(void)
{
@ -416,6 +448,48 @@ SHTeamRules::AddTeam2Kill(void)
forceinfokey(world, "teamkills_2", sprintf("%i", m_iKillsTeam2));
}
void
SHTeamRules::RemoveTeam1Kill(void)
{
m_iKillsTeam1--;
forceinfokey(world, "teamkills_1", sprintf("%i", m_iKillsTeam1));
}
void
SHTeamRules::RemoveTeam2Kill(void)
{
m_iKillsTeam2--;
forceinfokey(world, "teamkills_2", sprintf("%i", m_iKillsTeam2));
}
void
SHTeamRules::RegisterSciDeathHuntTeam(void)
{
super::RegisterSciDeath();
if (m_iScientistsAlive > 0)
return;
switch (g_chosen_mode) {
case SHMODE_STANDARD:
if (m_iKillsTeam1 > m_iKillsTeam2) {
m_iScoreTeam1++;
env_message_broadcast("Red team has won!");
} else if (m_iKillsTeam1 > m_iKillsTeam2) {
m_iScoreTeam2++;
env_message_broadcast("Blue team has won!");
} else {
env_message_broadcast("Both teams are tied!");
}
forceinfokey(world, "teamscore_1", sprintf("%i", m_iScoreTeam1));
forceinfokey(world, "teamscore_2", sprintf("%i", m_iScoreTeam2));
think = RestartRound;
nextthink = time + 5.0f;
break;
}
}
void
SHTeamRules::InitPostEnts(void)
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -46,6 +46,7 @@ Game_Worldspawn(void)
precache_model("models/player.mdl");
precache_model("models/w_weaponbox.mdl");
Sound_Precache("player.die");
Sound_Precache("player.insane");
Sound_Precache("player.fall");
Sound_Precache("player.lightfall");

View file

@ -3,6 +3,7 @@
../../../valve/src/shared/events.h
../../../valve/src/shared/flags.h
player.qc
pmove.qc
../../../valve/src/shared/weapon_common.h
../../../valve/src/shared/animations.h
../../../valve/src/shared/animations.qc

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -144,6 +144,8 @@ class player:NSClientPlayer
PREDICTED_INT(ammo_chainsaw_state)
PREDICTED_INT(ammo_hammer_state)
PREDICTED_FLOAT(sh_insanetime)
PREDICTED_FLOAT(sh_insaneactive)
PREDICTED_FLOAT(anim_top)
PREDICTED_FLOAT(anim_top_time)
PREDICTED_FLOAT(anim_top_delay)
@ -151,6 +153,9 @@ class player:NSClientPlayer
PREDICTED_FLOAT(anim_bottom_time)
virtual void UpdatePlayerAnimation(float);
virtual float Physics_MaxSpeed(void);
virtual void Physics_InputPreMove(void);
virtual void Physics_InputPostMove(void);
#ifdef CLIENT
virtual void UpdatePlayerAttachments(bool);
@ -162,8 +167,6 @@ class player:NSClientPlayer
virtual float(entity, float) SendEntity;
int sh_insanecount;
float sh_insanetime;
float sh_insaneactive;
#endif
};
@ -322,6 +325,8 @@ player::ReceiveEntity(float new, float fl)
mode_tempstate = readbyte();
ammo_chainsaw_state = readbyte();
ammo_hammer_state = readbyte();
sh_insanetime = readfloat();
sh_insaneactive = readfloat();
}
setorigin(this, origin);
@ -518,6 +523,10 @@ player::EvaluateEntity(void)
SendFlags |= PLAYER_AMMO3;
else if (ATTR_CHANGED(ammo_hammer_state))
SendFlags |= PLAYER_AMMO3;
else if (ATTR_CHANGED(sh_insanetime))
SendFlags |= PLAYER_AMMO3;
else if (ATTR_CHANGED(sh_insaneactive))
SendFlags |= PLAYER_AMMO3;
SAVE_STATE(glock_mag)
SAVE_STATE(mp5_mag)
@ -623,6 +632,8 @@ player::SendEntity(entity ePEnt, float flChanged)
WriteByte(MSG_ENTITY, mode_tempstate);
WriteByte(MSG_ENTITY, ammo_chainsaw_state);
WriteByte(MSG_ENTITY, ammo_hammer_state);
WriteFloat(MSG_ENTITY, sh_insanetime);
WriteFloat(MSG_ENTITY, sh_insaneactive);
}
return (1);

90
src/shared/pmove.qc Normal file
View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
* Copyright (c) 2016-2023 Gethyn ThomasQuail <gethyn@vera-visions.com>
*
* 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 PMOVE_AIRSTEPHEIGHT 0
#define PMOVE_STEPHEIGHT 18
#define PMOVE_FRICTION 4
#define PMOVE_EDGEFRICTION 1
#define PMOVE_STOPSPEED 100
#define PMOVE_GRAVITY 800
#define PMOVE_AIRACCELERATE 10
#define PMOVE_WATERACCELERATE 10
#define PMOVE_ACCELERATE 10
#define PMOVE_MAXSPEED 270
#define PMOVE_STEP_WALKSPEED 135
#define PMOVE_STEP_RUNSPEED 220
#define PHY_VIEWPOS [0,0,28]
#define PHY_VIEWPOS_CROUCHED [0,0,12]
#include "items.h"
/* insanity changes player move and attack speed */
void
player::Physics_InputPreMove(void)
{
float insanecooldown;
super::Physics_InputPreMove();
if (gflags & GF_MADNESS) {
/* give us a nice transition from insanity */
insanecooldown = bound(1,sh_insaneactive * 0.1f,3);
input_movevalues *= insanecooldown;
}
}
void
player::Physics_InputPostMove(void)
{
super::Physics_InputPostMove();
if (gflags & GF_MADNESS) {
w_attack_next = max(0, w_attack_next - input_timelength);
}
}
float
player::Physics_MaxSpeed(void)
{
if (gflags & GF_MADNESS) {
return 1000.0f;
} else {
return super::Physics_MaxSpeed();
}
}
void
player::Physics_Jump(void)
{
if (waterlevel >= 2) {
if (watertype == CONTENT_WATER) {
velocity[2] = 100;
} else if (watertype == CONTENT_SLIME) {
velocity[2] = 80;
} else {
velocity[2] = 50;
}
} else {
/* Half-Life: Longjump module */
if (flags & FL_CROUCHING && g_items & 0x00008000i) {
makevectors([0, v_angle[1], 0]);
velocity = v_forward * 512;
velocity[2] += 100;
}
if (flags & FL_ONGROUND)
velocity[2] += 265;
}
}