Initial commit, carried over from Nuclide's Git on March 8th 2021
This commit is contained in:
commit
1a25ccc334
137 changed files with 17088 additions and 0 deletions
15
LICENSE
Normal file
15
LICENSE
Normal file
|
@ -0,0 +1,15 @@
|
|||
ISC License
|
||||
|
||||
Copyright (c) 2016-2021, Marco "eukara" Hladik <marco@icculus.org>
|
||||
|
||||
Permission to use, copy, modify, and/or 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 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.
|
46
README.md
Normal file
46
README.md
Normal file
|
@ -0,0 +1,46 @@
|
|||
# FreeHL
|
||||
Clean-room reimplementation of Half-Life: Deathmatch and Half-Life (Experimental).
|
||||
|
||||
Similar to FreeCS, this aims to recreate the feeling of the original game.
|
||||
It's designed to work with the content from the CD version of the game.
|
||||
|
||||
Netplay improvements, such as prediction of both player physics and weapon-logic
|
||||
are present.
|
||||
|
||||
This is 100% original code, feel free to audit however you wish.
|
||||
No proprietary SDKs have been looked at or taken apart, unlike similar projects.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Building
|
||||
Clone the repository into the Nuclide-SDK:
|
||||
|
||||
> git clone REPOURL valve
|
||||
|
||||
then either run Nuclide's ./build_game.sh shell script, or issue 'make' inside
|
||||
./valve/src!
|
||||
|
||||
Obviously make sure that Nuclide has fteqw and fteqcc set-up for building.
|
||||
|
||||
## Community
|
||||
Join us on #halflife via irc.frag-net.com and chat.
|
||||
|
||||
## License
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2016-2021 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.
|
BIN
img/preview1.jpg
Normal file
BIN
img/preview1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
BIN
img/preview2.jpg
Normal file
BIN
img/preview2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
BIN
img/preview3.jpg
Normal file
BIN
img/preview3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
BIN
img/preview4.jpg
Normal file
BIN
img/preview4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
5
src/Makefile
Normal file
5
src/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
CC=fteqcc
|
||||
|
||||
all:
|
||||
cd client && $(MAKE)
|
||||
cd server && $(MAKE)
|
4
src/client/Makefile
Normal file
4
src/client/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
CC=fteqcc
|
||||
|
||||
all:
|
||||
$(CC) progs.src
|
25
src/client/cmds.qc
Normal file
25
src/client/cmds.qc
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
ClientGame_ConsoleCommand(void)
|
||||
{
|
||||
switch(argv(0)) {
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
131
src/client/defs.h
Normal file
131
src/client/defs.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 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.
|
||||
*/
|
||||
|
||||
#include "obituary.h"
|
||||
#include "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;
|
||||
|
||||
struct
|
||||
{
|
||||
/* viewmodel stuff */
|
||||
entity m_eViewModel;
|
||||
entity m_eMuzzleflash;
|
||||
int m_iVMBones;
|
||||
int m_iVMEjectBone;
|
||||
int m_iLastWeapon;
|
||||
int m_iOldWeapon;
|
||||
float m_flBobTime;
|
||||
float m_flBob;
|
||||
|
||||
/* damage overlay */
|
||||
float m_flDamageAlpha;
|
||||
vector m_vecDamagePos;
|
||||
|
||||
/* +zoomin cmd */
|
||||
int m_iZoomed;
|
||||
float m_flZoomTime;
|
||||
|
||||
/* player fields */
|
||||
entity m_ePlayer;
|
||||
vector m_vecPredictedOrigin;
|
||||
vector m_vecPredictedOriginOld;
|
||||
vector m_vecPredictedVelocity;
|
||||
float m_flPredictedFlags;
|
||||
|
||||
/* camera fields */
|
||||
vector m_vecCameraOrigin;
|
||||
vector m_vecCameraAngle;
|
||||
float m_flCameraTime;
|
||||
|
||||
/* 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_iPickupWeapon;
|
||||
float m_flPickupAlpha;
|
||||
|
||||
/* This is seperated from the other VGUI stuff so we can check scores
|
||||
* while buying and whatnot */
|
||||
int m_iScoresVisible;
|
||||
int m_iHUDWeaponSelected;
|
||||
float m_flHUDWeaponSelectTime;
|
||||
|
||||
/* saturn controller */
|
||||
int m_iSaturnMenu;
|
||||
|
||||
/* centerprint related */
|
||||
float m_flCenterprintAlpha;
|
||||
float m_flCenterprintTime;
|
||||
float m_iCenterprintLines;
|
||||
string m_strCenterprintBuffer[18];
|
||||
|
||||
/* chat related */
|
||||
float m_flPrintTime;
|
||||
string m_strPrintBuffer[5];
|
||||
int m_iPrintLines;
|
||||
|
||||
int m_iInputAttack2;
|
||||
int m_iInputReload;
|
||||
int m_iInputUse;
|
||||
int m_iInputDuck;
|
||||
float m_flInputBlockTime;
|
||||
|
||||
/* fading */
|
||||
float m_flFadeDuration;
|
||||
float m_flFadeHold;
|
||||
float m_flFadeMaxAlpha;
|
||||
float m_flFadeStyle;
|
||||
float m_flFadeAlpha;
|
||||
float m_flFadeTime;
|
||||
vector m_vecFadeColor;
|
||||
int m_iFadeActive;
|
||||
|
||||
/* shake */
|
||||
float m_flShakeFreq;
|
||||
float m_flShakeDuration;
|
||||
float m_flShakeTime;
|
||||
float m_flShakeAmp;
|
||||
|
||||
entity m_pWeaponFX;
|
||||
} g_seats[4], *pSeat;
|
||||
|
||||
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);
|
29
src/client/entities.qc
Normal file
29
src/client/entities.qc
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
ClientGame_EntityUpdate(float id, float new)
|
||||
{
|
||||
switch (id) {
|
||||
case ENT_TRIPMINE:
|
||||
w_tripmine_parse();
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
124
src/client/game_event.qc
Normal file
124
src/client/game_event.qc
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
ClientGame_EventParse(float fHeader)
|
||||
{
|
||||
switch (fHeader) {
|
||||
case EV_OBITUARY:
|
||||
Obituary_Parse();
|
||||
break;
|
||||
case EV_SPARK:
|
||||
vector vSparkPos, vSparkAngle;
|
||||
vSparkPos[0] = readcoord();
|
||||
vSparkPos[1] = readcoord();
|
||||
vSparkPos[2] = readcoord();
|
||||
vSparkAngle[0] = readcoord();
|
||||
vSparkAngle[1] = readcoord();
|
||||
vSparkAngle[2] = readcoord();
|
||||
FX_Spark(vSparkPos, vSparkAngle);
|
||||
break;
|
||||
case EV_GIBHUMAN:
|
||||
vector vGibPos;
|
||||
vGibPos[0] = readcoord();
|
||||
vGibPos[1] = readcoord();
|
||||
vGibPos[2] = readcoord();
|
||||
FX_GibHuman(vGibPos);
|
||||
break;
|
||||
case EV_BLOOD:
|
||||
vector vBloodPos;
|
||||
vector vBloodColor;
|
||||
|
||||
vBloodPos[0] = readcoord();
|
||||
vBloodPos[1] = readcoord();
|
||||
vBloodPos[2] = readcoord();
|
||||
|
||||
vBloodColor[0] = readbyte() / 255;
|
||||
vBloodColor[1] = readbyte() / 255;
|
||||
vBloodColor[2] = readbyte() / 255;
|
||||
|
||||
FX_Blood(vBloodPos, vBloodColor);
|
||||
break;
|
||||
case EV_EXPLOSION:
|
||||
vector vExploPos;
|
||||
|
||||
vExploPos[0] = readcoord();
|
||||
vExploPos[1] = readcoord();
|
||||
vExploPos[2] = readcoord();
|
||||
|
||||
FX_Explosion(vExploPos);
|
||||
break;
|
||||
case EV_MODELGIB:
|
||||
vector vecPos;
|
||||
vecPos[0] = readcoord();
|
||||
vecPos[1] = readcoord();
|
||||
vecPos[2] = readcoord();
|
||||
|
||||
vector vSize;
|
||||
vSize[0] = readcoord();
|
||||
vSize[1] = readcoord();
|
||||
vSize[2] = readcoord();
|
||||
|
||||
float fStyle = readbyte();
|
||||
int count = readbyte();
|
||||
FX_BreakModel(count, vecPos, vSize, [0,0,0], fStyle);
|
||||
break;
|
||||
case EV_IMPACT:
|
||||
int iType;
|
||||
vector vOrigin, vNormal;
|
||||
|
||||
iType = (int)readbyte();
|
||||
vOrigin[0] = readcoord();
|
||||
vOrigin[1] = readcoord();
|
||||
vOrigin[2] = readcoord();
|
||||
|
||||
vNormal[0] = readcoord();
|
||||
vNormal[1] = readcoord();
|
||||
vNormal[2] = readcoord();
|
||||
|
||||
FX_Impact(iType, vOrigin, vNormal);
|
||||
break;
|
||||
case EV_CHAT:
|
||||
float fSender = readbyte();
|
||||
float fTeam = readbyte();
|
||||
string sMessage = readstring();
|
||||
|
||||
CSQC_Parse_Print(sprintf("%s: %s", getplayerkeyvalue(fSender, "name"), sMessage), PRINT_CHAT);
|
||||
break;
|
||||
case EV_CHAT_TEAM:
|
||||
float fSender2 = readbyte();
|
||||
float fTeam2 = readbyte();
|
||||
string sMessage2 = readstring();
|
||||
|
||||
CSQC_Parse_Print(sprintf("[TEAM] %s: %s", getplayerkeyvalue(fSender2, "name"), sMessage2), PRINT_CHAT);
|
||||
break;
|
||||
case EV_CHAT_VOX:
|
||||
Vox_Play(readstring());
|
||||
break;
|
||||
case EV_VIEWMODEL:
|
||||
View_PlayAnimation(readbyte());
|
||||
break;
|
||||
case EV_WEAPON_PICKUP:
|
||||
int w = readbyte();
|
||||
|
||||
if (autocvar_cl_autoweaponswitch == 1) {
|
||||
sendevent("PlayerSwitchWeapon", "i", w);
|
||||
}
|
||||
|
||||
HUD_WeaponPickupNotify(w);
|
||||
break;
|
||||
}
|
||||
}
|
438
src/client/hud.qc
Normal file
438
src/client/hud.qc
Normal file
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 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 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
|
||||
};
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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, 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 != pSeat->m_iHealthOld) {
|
||||
pSeat->m_flHealthAlpha = 1.0;
|
||||
}
|
||||
|
||||
if (pSeat->m_flHealthAlpha >= HUD_ALPHA) {
|
||||
pSeat->m_flHealthAlpha -= clframetime * 0.5;
|
||||
} else {
|
||||
pSeat->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,
|
||||
pSeat->m_flHealthAlpha,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
HUD_DrawNums(pl.health, pos, pSeat->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],
|
||||
pSeat->m_flHealthAlpha,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
HUD_DrawNums(pl.health, pos, pSeat->m_flHealthAlpha, [1,0,0]);
|
||||
}
|
||||
|
||||
pSeat->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 != pSeat->m_iArmorOld) {
|
||||
pSeat->m_flArmorAlpha = 1.0;
|
||||
}
|
||||
|
||||
if (pSeat->m_flArmorAlpha >= HUD_ALPHA) {
|
||||
pSeat->m_flArmorAlpha -= clframetime * 0.5;
|
||||
} else {
|
||||
pSeat->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,
|
||||
pSeat->m_flArmorAlpha,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
|
||||
if (pl.armor > 0) {
|
||||
drawsubpic(
|
||||
pos + [-80,-9],
|
||||
[40, 40 * (pl.armor / 100)],
|
||||
g_hud7_spr,
|
||||
[spr_suit1[0],
|
||||
spr_suit1[1]],
|
||||
[spr_suit1[2], spr_suit1[3] * (pl.armor / 100)],
|
||||
g_hud_color,
|
||||
pSeat->m_flArmorAlpha,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
}
|
||||
|
||||
HUD_DrawNums(pl.armor, pos, pSeat->m_flArmorAlpha, g_hud_color);
|
||||
pSeat->m_iArmorOld = pl.armor;
|
||||
}
|
||||
|
||||
/* magazine/clip ammo */
|
||||
void
|
||||
HUD_DrawAmmo1(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
vector pos;
|
||||
|
||||
if (pl.a_ammo1 != pSeat->m_iAmmo1Old) {
|
||||
pSeat->m_flAmmo1Alpha = 1.0;
|
||||
pSeat->m_iAmmo1Old = pl.a_ammo1;
|
||||
}
|
||||
|
||||
if (pSeat->m_flAmmo1Alpha >= HUD_ALPHA) {
|
||||
pSeat->m_flAmmo1Alpha -= clframetime * 0.5;
|
||||
} else {
|
||||
pSeat->m_flAmmo1Alpha = HUD_ALPHA;
|
||||
}
|
||||
|
||||
pos = g_hudmins + [g_hudres[0] - 152, g_hudres[1] - 42];
|
||||
HUD_DrawNums(pl.a_ammo1, pos, pSeat->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 != pSeat->m_iAmmo2Old) {
|
||||
pSeat->m_flAmmo2Alpha = 1.0;
|
||||
pSeat->m_iAmmo2Old = pl.a_ammo2;
|
||||
}
|
||||
|
||||
if (pSeat->m_flAmmo2Alpha >= HUD_ALPHA) {
|
||||
pSeat->m_flAmmo2Alpha -= clframetime * 0.5;
|
||||
} else {
|
||||
pSeat->m_flAmmo2Alpha = HUD_ALPHA;
|
||||
}
|
||||
|
||||
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 42];
|
||||
HUD_DrawNums(pl.a_ammo2, pos, pSeat->m_flAmmo2Alpha, g_hud_color);
|
||||
}
|
||||
|
||||
/* special ammo */
|
||||
void
|
||||
HUD_DrawAmmo3(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
vector pos;
|
||||
|
||||
if (pl.a_ammo3 != pSeat->m_iAmmo3Old) {
|
||||
pSeat->m_flAmmo3Alpha = 1.0;
|
||||
pSeat->m_iAmmo3Old = pl.a_ammo3;
|
||||
}
|
||||
|
||||
if (pSeat->m_flAmmo3Alpha >= HUD_ALPHA) {
|
||||
pSeat->m_flAmmo3Alpha -= clframetime * 0.5;
|
||||
} else {
|
||||
pSeat->m_flAmmo3Alpha = HUD_ALPHA;
|
||||
}
|
||||
|
||||
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 74];
|
||||
HUD_DrawNums(pl.a_ammo3, pos, pSeat->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)
|
||||
{
|
||||
vector pos;
|
||||
|
||||
if (pSeat->m_flPickupAlpha <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
pos = g_hudmins + [g_hudres[0] - 192, g_hudres[1] - 128];
|
||||
Weapons_HUDPic(pSeat->m_iPickupWeapon, 1, pos, pSeat->m_flPickupAlpha);
|
||||
pSeat->m_flPickupAlpha -= clframetime;
|
||||
}
|
||||
|
||||
void
|
||||
HUD_WeaponPickupNotify(int w)
|
||||
{
|
||||
pSeat->m_iPickupWeapon = w;
|
||||
pSeat->m_flPickupAlpha = 1.0f;
|
||||
}
|
||||
|
||||
/* main entry */
|
||||
void
|
||||
HUD_Draw(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
g_hud_color = autocvar_con_color * (1 / 255);
|
||||
|
||||
/* little point in not drawing these, even if you don't have a suit */
|
||||
Weapons_DrawCrosshair();
|
||||
HUD_DrawWeaponSelect();
|
||||
Obituary_Draw();
|
||||
Textmenu_Draw();
|
||||
|
||||
if (!(pl.g_items & ITEM_SUIT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HUD_DrawHealth();
|
||||
HUD_DrawArmor();
|
||||
HUD_DrawFlashlight();
|
||||
HUD_DrawNotify();
|
||||
Damage_Draw();
|
||||
}
|
||||
|
||||
/* specatator main entry */
|
||||
void
|
||||
HUD_DrawSpectator(void)
|
||||
{
|
||||
// FIXME
|
||||
Textmenu_Draw();
|
||||
}
|
228
src/client/hud_weaponselect.qc
Normal file
228
src/client/hud_weaponselect.qc
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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 g_vecHUDNums[6] =
|
||||
{
|
||||
[168 / 256, 72 / 128],
|
||||
[188 / 256, 72 / 128],
|
||||
[208 / 256, 72 / 128],
|
||||
[168 / 256, 92 / 128],
|
||||
[188 / 256, 92 / 128],
|
||||
[208 / 256, 92 / 128]
|
||||
};
|
||||
|
||||
void
|
||||
HUD_DrawWeaponSelect_Forward(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
if (!pl.activeweapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pSeat->m_flHUDWeaponSelectTime < time) {
|
||||
pSeat->m_iHUDWeaponSelected = pl.activeweapon;
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
|
||||
} else {
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
|
||||
pSeat->m_iHUDWeaponSelected--;
|
||||
if (pSeat->m_iHUDWeaponSelected <= 0) {
|
||||
pSeat->m_iHUDWeaponSelected = g_weapons.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
pSeat->m_flHUDWeaponSelectTime = time + 3;
|
||||
|
||||
if not (pl.g_items & g_weapons[pSeat->m_iHUDWeaponSelected].id) {
|
||||
HUD_DrawWeaponSelect_Forward();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HUD_DrawWeaponSelect_Back(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
if (!pl.activeweapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pSeat->m_flHUDWeaponSelectTime < time) {
|
||||
pSeat->m_iHUDWeaponSelected = pl.activeweapon;
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
|
||||
} else {
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
|
||||
pSeat->m_iHUDWeaponSelected++;
|
||||
if (pSeat->m_iHUDWeaponSelected >= g_weapons.length) {
|
||||
pSeat->m_iHUDWeaponSelected = 1;
|
||||
}
|
||||
}
|
||||
|
||||
pSeat->m_flHUDWeaponSelectTime = time + 3;
|
||||
|
||||
if not (pl.g_items & g_weapons[pSeat->m_iHUDWeaponSelected].id) {
|
||||
HUD_DrawWeaponSelect_Back();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HUD_DrawWeaponSelect_Trigger(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
pl.activeweapon = pSeat->m_iHUDWeaponSelected;
|
||||
sendevent("PlayerSwitchWeapon", "i", pSeat->m_iHUDWeaponSelected);
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE);
|
||||
pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0;
|
||||
}
|
||||
|
||||
void
|
||||
HUD_DrawWeaponSelect_Last(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
if (pl.g_items & g_weapons[pSeat->m_iOldWeapon].id) {
|
||||
pl.activeweapon = pSeat->m_iOldWeapon;
|
||||
sendevent("PlayerSwitchWeapon", "i", pSeat->m_iOldWeapon);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HUD_DrawWeaponSelect_Num(vector vecPos, float fValue)
|
||||
{
|
||||
drawsubpic(vecPos, [20,20], g_hud7_spr, g_vecHUDNums[fValue], [20/256, 20/128], g_hud_color, 1, DRAWFLAG_ADDITIVE);
|
||||
}
|
||||
|
||||
int
|
||||
HUD_InSlotPos(int slot, int pos)
|
||||
{
|
||||
player pl = (player)pSeat->m_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_SlotSelect(int slot)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
int curslot = g_weapons[pSeat->m_iHUDWeaponSelected].slot;
|
||||
int i;
|
||||
|
||||
if (g_textmenu != "") {
|
||||
Textmenu_Input(slot);
|
||||
return;
|
||||
}
|
||||
|
||||
/* hack to see if we have ANY weapons at all. */
|
||||
if (!pl.activeweapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pSeat->m_flHUDWeaponSelectTime < time) {
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
|
||||
} else {
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
|
||||
}
|
||||
|
||||
/* weren't in that slot? select the first one then */
|
||||
if (curslot != slot) {
|
||||
for (i = 1; i < g_weapons.length; i++) {
|
||||
if (g_weapons[i].slot == slot && pl.g_items & g_weapons[i].id) {
|
||||
pSeat->m_iHUDWeaponSelected = i;
|
||||
pSeat->m_flHUDWeaponSelectTime = time + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int first = -1;
|
||||
for (i = 1; i < g_weapons.length; i++) {
|
||||
if (g_weapons[i].slot == slot && pl.g_items & g_weapons[i].id) {
|
||||
if (i < pSeat->m_iHUDWeaponSelected && first == -1) {
|
||||
first = i;
|
||||
} else if (i > pSeat->m_iHUDWeaponSelected) {
|
||||
first = -1;
|
||||
pSeat->m_iHUDWeaponSelected = i;
|
||||
pSeat->m_flHUDWeaponSelectTime = time + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (first > 0) {
|
||||
pSeat->m_iHUDWeaponSelected = first;
|
||||
pSeat->m_flHUDWeaponSelectTime = time + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HUD_DrawWeaponSelect(void)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
if (!pl.activeweapon) {
|
||||
return;
|
||||
}
|
||||
if (pSeat->m_flHUDWeaponSelectTime < time) {
|
||||
if (pSeat->m_iHUDWeaponSelected) {
|
||||
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudoff.wav", 0.5, ATTN_NONE);
|
||||
pSeat->m_iHUDWeaponSelected = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vector vecPos = g_hudmins + [16,16];
|
||||
|
||||
int b;
|
||||
int wantslot = g_weapons[pSeat->m_iHUDWeaponSelected].slot;
|
||||
int wantpos = g_weapons[pSeat->m_iHUDWeaponSelected].slot_pos;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int slot_selected = 0;
|
||||
vecPos[1] = g_hudmins[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->m_iHUDWeaponSelected, 1, vecPos, 1.0f);
|
||||
drawsubpic(vecPos, [170,45], g_hud3_spr,
|
||||
[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, 1.0f);
|
||||
vecPos[1] += 50;
|
||||
}
|
||||
} else if (HUD_InSlotPos(i, x) != -1) {
|
||||
HUD_DrawWeaponSelect_Num(vecPos, 5);
|
||||
vecPos[1] += 25;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot_selected == TRUE) {
|
||||
vecPos[0] += 175;
|
||||
} else {
|
||||
vecPos[0] += 25;
|
||||
}
|
||||
}
|
||||
}
|
48
src/client/init.qc
Normal file
48
src/client/init.qc
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
ClientGame_Init
|
||||
|
||||
Comparable to worldspawn in SSQC in that it's mostly used for precaches
|
||||
=================
|
||||
*/
|
||||
void
|
||||
ClientGame_Init(float apilevel, string enginename, float engineversion)
|
||||
{
|
||||
Obituary_Init();
|
||||
}
|
||||
|
||||
void
|
||||
ClientGame_InitDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ClientGame_RendererRestart(string rstr)
|
||||
{
|
||||
Obituary_Precache();
|
||||
|
||||
FX_Blood_Init();
|
||||
FX_BreakModel_Init();
|
||||
FX_Explosion_Init();
|
||||
FX_GibHuman_Init();
|
||||
FX_Spark_Init();
|
||||
FX_Impact_Init();
|
||||
|
||||
BEAM_TRIPMINE = particleeffectnum("weapon_tripmine.beam");
|
||||
}
|
29
src/client/input.qc
Normal file
29
src/client/input.qc
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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();
|
||||
}
|
||||
}
|
48
src/client/obituary.h
Normal file
48
src/client/obituary.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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 OBITUARY_LINES 4
|
||||
#define OBITUARY_TIME 5
|
||||
|
||||
/* imagery */
|
||||
typedef struct {
|
||||
string name; /* name of the weapon/type, e.g. d_crowbar */
|
||||
string sprite; /* name of the spritesheet it's from */
|
||||
float size[2]; /* on-screen size in pixels */
|
||||
float src_pos[2]; /* normalized position in the sprite sheet */
|
||||
float src_size[2]; /* normalized size in the sprite sheet */
|
||||
string src_sprite; /* precaching reasons */
|
||||
} obituaryimg_t;
|
||||
|
||||
obituaryimg_t *g_obtypes;
|
||||
int g_obtype_count;
|
||||
|
||||
/* actual obituary storage */
|
||||
typedef struct
|
||||
{
|
||||
string attacker;
|
||||
string victim;
|
||||
int icon;
|
||||
} obituary_t;
|
||||
|
||||
obituary_t g_obituary[OBITUARY_LINES];
|
||||
int g_obituary_count;
|
||||
float g_obituary_time;
|
||||
|
||||
void Obituary_Init(void);
|
||||
void Obituary_Precache(void);
|
||||
void Obituary_Draw(void);
|
||||
void Obituary_Parse(void);
|
221
src/client/obituary.qc
Normal file
221
src/client/obituary.qc
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
Obituary_Init(void)
|
||||
{
|
||||
int c;
|
||||
int i;
|
||||
filestream fh;
|
||||
string line;
|
||||
vector tmp;
|
||||
|
||||
if (g_obtype_count > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_obtype_count = 0;
|
||||
i = 0;
|
||||
|
||||
fh = fopen("sprites/hud.txt", FILE_READ);
|
||||
if (fh < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* count valid entries */
|
||||
while ((line = fgets(fh))) {
|
||||
if (substring(line, 0, 2) == "d_") {
|
||||
c = tokenize(line);
|
||||
if (c == 7 && argv(1) == "640") {
|
||||
g_obtype_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_obtypes = memalloc(sizeof(obituaryimg_t) * g_obtype_count);
|
||||
|
||||
fseek(fh, 0);
|
||||
|
||||
/* read them in */
|
||||
while ((line = fgets(fh))) {
|
||||
if (substring(line, 0, 2) == "d_") {
|
||||
c = tokenize(line);
|
||||
|
||||
/* we only care about the high-res (640) variants. the 320
|
||||
* HUD is useless to us. Just use the builtin scaler */
|
||||
if (c == 7 && argv(1) == "640") {
|
||||
g_obtypes[i].name = substring(argv(0), 2, -1);
|
||||
g_obtypes[i].src_sprite = sprintf("sprites/%s.spr", argv(2));
|
||||
precache_model(g_obtypes[i].src_sprite);
|
||||
g_obtypes[i].sprite = spriteframe(sprintf("sprites/%s.spr", argv(2)), 0, 0.0f);
|
||||
g_obtypes[i].size[0] = stof(argv(5));
|
||||
g_obtypes[i].size[1] = stof(argv(6));
|
||||
tmp = drawgetimagesize(g_obtypes[i].sprite);
|
||||
g_obtypes[i].src_pos[0] = stof(argv(3)) / tmp[0];
|
||||
g_obtypes[i].src_pos[1] = stof(argv(4)) / tmp[1];
|
||||
g_obtypes[i].src_size[0] = g_obtypes[i].size[0] / tmp[0];
|
||||
g_obtypes[i].src_size[1] = g_obtypes[i].size[1] / tmp[1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
}
|
||||
|
||||
void
|
||||
Obituary_Precache(void)
|
||||
{
|
||||
for (int i = 0; i < g_obtype_count; i++)
|
||||
precache_model(g_obtypes[i].src_sprite);
|
||||
}
|
||||
|
||||
void
|
||||
Obituary_KillIcon(int id, float w)
|
||||
{
|
||||
if (w > 0)
|
||||
for (int i = 0; i < g_obtype_count; i++) {
|
||||
if (g_weapons[w].name == g_obtypes[i].name) {
|
||||
g_obituary[id].icon = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* look for skull instead */
|
||||
for (int i = 0; i < g_obtype_count; i++) {
|
||||
if (g_obtypes[i].name == "skull") {
|
||||
g_obituary[id].icon = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Obituary_Add(string attacker, string victim, float weapon, float flags)
|
||||
{
|
||||
int i;
|
||||
int x, y;
|
||||
x = OBITUARY_LINES;
|
||||
|
||||
/* we're not full yet, so fill up the buffer */
|
||||
if (g_obituary_count < x) {
|
||||
y = g_obituary_count;
|
||||
g_obituary[y].attacker = attacker;
|
||||
g_obituary[y].victim = victim;
|
||||
Obituary_KillIcon(y, weapon);
|
||||
g_obituary_count++;
|
||||
} else {
|
||||
for (i = 0; i < (x-1); i++) {
|
||||
g_obituary[i].attacker = g_obituary[i+1].attacker;
|
||||
g_obituary[i].victim = g_obituary[i+1].victim;
|
||||
g_obituary[i].icon = g_obituary[i+1].icon;
|
||||
}
|
||||
/* after rearranging, add the newest to the bottom. */
|
||||
g_obituary[x-1].attacker = attacker;
|
||||
g_obituary[x-1].victim = victim;
|
||||
Obituary_KillIcon(x-1, weapon);
|
||||
}
|
||||
|
||||
g_obituary_time = OBITUARY_TIME;
|
||||
|
||||
if (g_weapons[weapon].deathmsg) {
|
||||
string conprint = g_weapons[weapon].deathmsg();
|
||||
|
||||
if (conprint != "") {
|
||||
print(sprintf(conprint, attacker, victim));
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Obituary_Draw(void)
|
||||
{
|
||||
int i;
|
||||
vector pos;
|
||||
vector item;
|
||||
drawfont = FONT_CON;
|
||||
pos = g_hudmins + [g_hudres[0] - 18, 56];
|
||||
|
||||
if (g_obituary_time <= 0 && g_obituary_count > 0) {
|
||||
for (i = 0; i < (OBITUARY_LINES-1); i++) {
|
||||
g_obituary[i].attacker = g_obituary[i+1].attacker;
|
||||
g_obituary[i].victim = g_obituary[i+1].victim;
|
||||
g_obituary[i].icon = g_obituary[i+1].icon;
|
||||
}
|
||||
g_obituary[OBITUARY_LINES-1].attacker = "";
|
||||
|
||||
g_obituary_time = OBITUARY_TIME;
|
||||
g_obituary_count--;
|
||||
}
|
||||
|
||||
if (g_obituary_count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
item = pos;
|
||||
for (i = 0; i < OBITUARY_LINES; i++) {
|
||||
string a, v;
|
||||
|
||||
if (!g_obituary[i].attacker) {
|
||||
break;
|
||||
}
|
||||
|
||||
item[0] = pos[0];
|
||||
|
||||
v = g_obituary[i].victim;
|
||||
drawstring_r(item + [0,2], v, [12,12], [1,1,1], 1.0f, 0);
|
||||
item[0] -= stringwidth(v, TRUE, [12,12]) + 4;
|
||||
item[0] -= g_obtypes[g_obituary[i].icon].size[0];
|
||||
|
||||
drawsubpic(
|
||||
item,
|
||||
[g_obtypes[g_obituary[i].icon].size[0], g_obtypes[g_obituary[i].icon].size[1]],
|
||||
g_obtypes[g_obituary[i].icon].sprite,
|
||||
[g_obtypes[g_obituary[i].icon].src_pos[0],g_obtypes[g_obituary[i].icon].src_pos[1]],
|
||||
[g_obtypes[g_obituary[i].icon].src_size[0],g_obtypes[g_obituary[i].icon].src_size[1]],
|
||||
g_hud_color,
|
||||
1.0f,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
|
||||
a = g_obituary[i].attacker;
|
||||
drawstring_r(item + [-4,2], a, [12,12], [1,1,1], 1.0f, 0);
|
||||
item[1] += 18;
|
||||
}
|
||||
|
||||
g_obituary_time = max(0, g_obituary_time - clframetime);
|
||||
}
|
||||
|
||||
void
|
||||
Obituary_Parse(void)
|
||||
{
|
||||
string attacker;
|
||||
string victim;
|
||||
float weapon;
|
||||
float flags;
|
||||
|
||||
attacker = readstring();
|
||||
victim = readstring();
|
||||
weapon = readbyte();
|
||||
flags = readbyte();
|
||||
|
||||
if (!attacker) {
|
||||
return;
|
||||
}
|
||||
|
||||
Obituary_Add(attacker, victim, weapon, flags);
|
||||
}
|
17
src/client/particles.h
Normal file
17
src/client/particles.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
var float BEAM_TRIPMINE;
|
44
src/client/player.qc
Normal file
44
src/client/player.qc
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
Player_PreDraw(base_player pl, int thirdperson)
|
||||
{
|
||||
/* Handle the flashlights... */
|
||||
if (pl.gflags & GF_FLASHLIGHT) {
|
||||
vector src;
|
||||
vector ang;
|
||||
|
||||
if (pl.entnum != player_localentnum) {
|
||||
src = pl.origin + pl.view_ofs;
|
||||
ang = [pl.pitch, pl.angles[1], pl.angles[2]];
|
||||
} else {
|
||||
src = pSeat->m_vecPredictedOrigin + [0,0,-8];
|
||||
ang = view_angles;
|
||||
}
|
||||
|
||||
makevectors(ang);
|
||||
traceline(src, src + (v_forward * 8096), MOVE_NORMAL, pl);
|
||||
|
||||
if (serverkeyfloat("*bspversion") == BSPVER_HL) {
|
||||
dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]);
|
||||
} else {
|
||||
float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight");
|
||||
dynamiclight_set(p, LFIELD_ANGLES, ang);
|
||||
dynamiclight_set(p, LFIELD_FLAGS, 3);
|
||||
}
|
||||
}
|
||||
}
|
25
src/client/predict.qc
Normal file
25
src/client/predict.qc
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
GamePredict_PreFrame(player pl)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
GamePredict_PostFrame(player pl)
|
||||
{
|
||||
}
|
38
src/client/progs.src
Executable file
38
src/client/progs.src
Executable file
|
@ -0,0 +1,38 @@
|
|||
#pragma target fte
|
||||
#pragma progs_dat "../../csprogs.dat"
|
||||
|
||||
#define CSQC
|
||||
#define CLIENT
|
||||
#define VALVE
|
||||
#define CLASSIC_VGUI
|
||||
#define GS_RENDERFX
|
||||
|
||||
#includelist
|
||||
../../../src/shared/fteextensions.qc
|
||||
../../../src/shared/defs.h
|
||||
defs.h
|
||||
../../../src/client/defs.h
|
||||
|
||||
../../../src/vgui/include.src
|
||||
|
||||
../../../src/gs-entbase/client.src
|
||||
../../../src/gs-entbase/shared.src
|
||||
../shared/include.src
|
||||
|
||||
predict.qc
|
||||
init.qc
|
||||
player.qc
|
||||
entities.qc
|
||||
cmds.qc
|
||||
game_event.qc
|
||||
view.qc
|
||||
obituary.qc
|
||||
hud.qc
|
||||
hud_weaponselect.qc
|
||||
scoreboard.qc
|
||||
input.qc
|
||||
../../../base/src/client/modelevent.qc
|
||||
|
||||
../../../src/client/include.src
|
||||
../../../src/shared/include.src
|
||||
#endlist
|
181
src/client/scoreboard.qc
Normal file
181
src/client/scoreboard.qc
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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 SCORE_HEADER_C [255/255,156/255,0]
|
||||
#define SCORE_LINE_C [255/255,200/255,0]
|
||||
|
||||
var int autocvar_cl_centerscores = FALSE;
|
||||
var int g_scores_teamplay = 0;
|
||||
|
||||
void
|
||||
Scores_Init(void)
|
||||
{
|
||||
g_scores_teamplay = (int)serverkeyfloat("teamplay");
|
||||
}
|
||||
|
||||
void
|
||||
Scores_DrawTeam(player pl, vector pos)
|
||||
{
|
||||
drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
drawfont = FONT_20;
|
||||
drawstring(pos + [0,-18], "Teams", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [124,-18], "kills / deaths", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [240,-18], "latency", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
pos[1] += 12;
|
||||
|
||||
for (int t = 1; t <= serverkeyfloat("teams"); t++) {
|
||||
float l;
|
||||
string temp;
|
||||
drawstring(pos, serverkey(sprintf("team_%i", t)), [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
temp = serverkey(sprintf("teamscore_%i", t));
|
||||
l = stringwidth(temp, FALSE, [20,20]);
|
||||
drawstring(pos + [150-l, 0], temp, [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [158, 0], "wins", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
pos[1] += 16;
|
||||
|
||||
for (int i = -1; i > -32; i--) {
|
||||
if (getplayerkeyfloat(i, "*team") != t) {
|
||||
continue;
|
||||
}
|
||||
|
||||
temp = getplayerkeyvalue(i, "name");
|
||||
|
||||
/* Out of players */
|
||||
if (!temp) {
|
||||
break;
|
||||
} else if (temp == getplayerkeyvalue(pl.entnum-1, "name")) {
|
||||
drawfill(pos, [290, 13], [0,0,1], 0.5f, DRAWFLAG_ADDITIVE);
|
||||
}
|
||||
|
||||
drawstring(pos + [24,0], getplayerkeyvalue(i, "name"), [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [154,0], "/", [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
/* Get the kills and align them left to right */
|
||||
temp = getplayerkeyvalue(i, "frags");
|
||||
l = stringwidth(temp, FALSE, [20,20]);
|
||||
drawstring(pos + [150 - l,0], temp, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
/* Deaths are right to left aligned */
|
||||
temp = getplayerkeyvalue(i, "*deaths");
|
||||
drawstring(pos + [165,0], temp, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
/* Get the latency and align it left to right */
|
||||
temp = getplayerkeyvalue(i, "ping");
|
||||
l = stringwidth(temp, FALSE, [20,20]);
|
||||
|
||||
if (getplayerkeyfloat(i, "*dead") == 1) {
|
||||
drawsubpic(
|
||||
pos - [8,0],
|
||||
[32,16],
|
||||
g_hud1_spr,
|
||||
[224/256, 240/256],
|
||||
[32/256, 16/256],
|
||||
[1,0,0],
|
||||
1.0f,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
}
|
||||
|
||||
drawstring(pos + [290 - l,0], temp, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
pos[1] += 20;
|
||||
}
|
||||
pos[1] += 12;
|
||||
}
|
||||
|
||||
drawfont = FONT_CON;
|
||||
}
|
||||
|
||||
void
|
||||
Scores_DrawNormal(player pl, vector pos)
|
||||
{
|
||||
drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
drawfont = FONT_20;
|
||||
drawstring(pos + [0,-18], "Player", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [124,-18], "kills / deaths", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [240,-18], "latency", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
pos[1] += 12;
|
||||
for (int i = -1; i > -32; i--) {
|
||||
float l;
|
||||
string ping;
|
||||
string kills;
|
||||
string deaths;
|
||||
string name;
|
||||
|
||||
name = getplayerkeyvalue(i, "name");
|
||||
|
||||
/* Out of players */
|
||||
if (!name) {
|
||||
break;
|
||||
} else if (name == getplayerkeyvalue(pl.entnum-1, "name")) {
|
||||
drawfill(pos, [290, 13], [0,0,1], 0.5f, DRAWFLAG_ADDITIVE);
|
||||
}
|
||||
|
||||
drawstring(pos, getplayerkeyvalue(i, "name"), [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
drawstring(pos + [154,0], "/", [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
/* Get the kills and align them left to right */
|
||||
kills = getplayerkeyvalue(i, "frags");
|
||||
l = stringwidth(kills, FALSE, [20,20]);
|
||||
drawstring(pos + [150 - l,0], kills, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
/* Deaths are right to left aligned */
|
||||
deaths = getplayerkeyvalue(i, "*deaths");
|
||||
drawstring(pos + [165,0], deaths, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
|
||||
/* Get the latency and align it left to right */
|
||||
ping = getplayerkeyvalue(i, "ping");
|
||||
l = stringwidth(ping, FALSE, [20,20]);
|
||||
|
||||
drawstring(pos + [290 - l,0], ping, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
|
||||
pos[1] += 20;
|
||||
}
|
||||
|
||||
drawfont = FONT_CON;
|
||||
}
|
||||
|
||||
void
|
||||
Scores_Draw(void)
|
||||
{
|
||||
vector pos;
|
||||
player pl;
|
||||
|
||||
pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
if (autocvar_cl_centerscores) {
|
||||
int c = 10;
|
||||
|
||||
/* calculate all valid entries */
|
||||
for (int i = -1; i > -32; i--) {
|
||||
if (getplayerkeyvalue(i, "name")) {
|
||||
break;
|
||||
}
|
||||
c += 10;
|
||||
}
|
||||
pos = video_mins + [(video_res[0] / 2) - 145, (video_res[1] / 2) - c];
|
||||
} else {
|
||||
pos = video_mins + [(video_res[0] / 2) - 145, 30];
|
||||
}
|
||||
|
||||
if (serverkeyfloat("teams") > 0) {
|
||||
Scores_DrawTeam(pl, pos);
|
||||
} else {
|
||||
Scores_DrawNormal(pl, pos);
|
||||
}
|
||||
}
|
51
src/client/view.qc
Normal file
51
src/client/view.qc
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
View_UpdateWeapon(entity vm, entity mflash)
|
||||
{
|
||||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
/* only bother upon change */
|
||||
if (pSeat->m_iLastWeapon == pl.activeweapon) {
|
||||
return;
|
||||
}
|
||||
pSeat->m_iOldWeapon = pSeat->m_iLastWeapon;
|
||||
pSeat->m_iLastWeapon = pl.activeweapon;
|
||||
|
||||
if (!pl.activeweapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* hack, we changed the wep, move this into Game_Input/PMove */
|
||||
Weapons_Draw();
|
||||
|
||||
/* we forced a weapon call outside the prediction,
|
||||
* thus we need to update all the net variables to
|
||||
* make sure these updates are recognized. this is
|
||||
* vile but it'll have to do for now */
|
||||
pl.net_w_attack_next = pl.w_attack_next;
|
||||
pl.net_w_idle_next = pl.w_idle_next;
|
||||
pl.net_viewzoom = pl.viewzoom;
|
||||
pl.net_weapontime = pl.weapontime;
|
||||
|
||||
/* figure out when the attachments start. in FTE attachments for
|
||||
* HLMDL are treated as bones. they start at numbones + 1 */
|
||||
skel_delete(mflash.skeletonindex);
|
||||
mflash.skeletonindex = skel_create(vm.modelindex);
|
||||
pSeat->m_iVMBones = skel_get_numbones(mflash.skeletonindex) + 1;
|
||||
pSeat->m_iVMEjectBone = pSeat->m_iVMBones + 1;
|
||||
}
|
2
src/progs.src
Executable file
2
src/progs.src
Executable file
|
@ -0,0 +1,2 @@
|
|||
#pragma sourcefile client/progs.src
|
||||
#pragma sourcefile server/progs.src
|
4
src/server/Makefile
Normal file
4
src/server/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
CC=fteqcc
|
||||
|
||||
all:
|
||||
$(CC) progs.src
|
364
src/server/ammo.qc
Normal file
364
src/server/ammo.qc
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
class item_ammo:CBaseEntity
|
||||
{
|
||||
void(void) item_ammo;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void item_ammo::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
player pl = (player)other;
|
||||
Sound_Play(other, CHAN_ITEM, "ammo.pickup");
|
||||
Weapons_RefreshAmmo(pl);
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
|
||||
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 20.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void item_ammo::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
SetSize([-16,-16,0],[16,16,16]);
|
||||
SetOrigin(m_oldOrigin);
|
||||
SetModel(m_oldModel);
|
||||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
|
||||
if (real_owner)
|
||||
Sound_Play(this, CHAN_ITEM, "ammo.respawn");
|
||||
|
||||
droptofloor();
|
||||
}
|
||||
|
||||
void item_ammo::item_ammo(void)
|
||||
{
|
||||
precache_model(model);
|
||||
m_oldModel = model;
|
||||
SetModel(m_oldModel);
|
||||
CBaseEntity::CBaseEntity();
|
||||
}
|
||||
|
||||
/*QUAKED ammo_357 (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the .357 Magnum Revolver.
|
||||
A single ammo_357 will provide 6 bullets.
|
||||
|
||||
*/
|
||||
class ammo_357:item_ammo
|
||||
{
|
||||
void(void) ammo_357;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_357::ammo_357(void)
|
||||
{
|
||||
model = "models/w_357ammobox.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_357::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_357 < MAX_A_357) {
|
||||
pl.ammo_357 = bound(0, pl.ammo_357 + 6, MAX_A_357);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED ammo_9mmAR (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the 9mm Handgun and the 9mm AR.
|
||||
A single ammo_9mmAR will provide 50 bullets.
|
||||
|
||||
*/
|
||||
class ammo_9mmAR:item_ammo
|
||||
{
|
||||
void(void) ammo_9mmAR;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_9mmAR::ammo_9mmAR(void)
|
||||
{
|
||||
model = "models/w_9mmarclip.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_9mmAR::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_9mm < MAX_A_9MM) {
|
||||
pl.ammo_9mm = bound(0, pl.ammo_9mm + 50, MAX_A_9MM);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
CLASSEXPORT(ammo_mp5clip, ammo_9mmAR)
|
||||
|
||||
/*QUAKED ammo_9mmbox (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the 9mm Handgun and the 9mm AR.
|
||||
A single ammo_9mmbox will provide 200 bullets.
|
||||
|
||||
*/
|
||||
class ammo_9mmbox:item_ammo
|
||||
{
|
||||
void(void) ammo_9mmbox;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_9mmbox::ammo_9mmbox(void)
|
||||
{
|
||||
model = "models/w_chainammo.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_9mmbox::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_9mm < MAX_A_9MM) {
|
||||
pl.ammo_9mm = bound(0, pl.ammo_9mm + 200, MAX_A_9MM);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED ammo_9mmclip (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the 9mm Handgun and the 9mm AR.
|
||||
A single ammo_9mmclip will provide 17 bullets.
|
||||
|
||||
*/
|
||||
class ammo_9mmclip:item_ammo
|
||||
{
|
||||
void(void) ammo_9mmclip;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_9mmclip::ammo_9mmclip(void)
|
||||
{
|
||||
model = "models/w_9mmclip.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_9mmclip::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_9mm < MAX_A_9MM) {
|
||||
pl.ammo_9mm = bound(0, pl.ammo_9mm + 17, MAX_A_9MM);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED ammo_ARgrenades (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the 9mm AR's secondary fire.
|
||||
A single ammo_ARgrenades will provide 2 AR grenades.
|
||||
|
||||
*/
|
||||
class ammo_ARgrenades:item_ammo
|
||||
{
|
||||
void(void) ammo_ARgrenades;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_ARgrenades::ammo_ARgrenades(void)
|
||||
{
|
||||
model = "models/w_argrenade.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_ARgrenades::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_m203_grenade < MAX_A_M203_GRENADE) {
|
||||
pl.ammo_m203_grenade = bound(0, pl.ammo_m203_grenade + 2, MAX_A_M203_GRENADE);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
CLASSEXPORT(ammo_mp5grenades, ammo_ARgrenades)
|
||||
|
||||
/*QUAKED ammo_buckshot (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the Shotgun.
|
||||
A single ammo_buckshot will provide 12 shells.
|
||||
|
||||
*/
|
||||
class ammo_buckshot:item_ammo
|
||||
{
|
||||
void(void) ammo_buckshot;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_buckshot::ammo_buckshot(void)
|
||||
{
|
||||
model = "models/w_shotbox.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_buckshot::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_buckshot < MAX_A_BUCKSHOT) {
|
||||
pl.ammo_buckshot = bound(0, pl.ammo_buckshot + 12, MAX_A_BUCKSHOT);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED ammo_crossbow (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the Crossbow.
|
||||
A single ammo_crossbow will provide 5 bolts.
|
||||
|
||||
*/
|
||||
class ammo_crossbow:item_ammo
|
||||
{
|
||||
void(void) ammo_crossbow;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_crossbow::ammo_crossbow(void)
|
||||
{
|
||||
model = "models/w_crossbow_clip.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_crossbow::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
if (other.classname == "player") {
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_bolt < MAX_A_BOLT) {
|
||||
pl.ammo_bolt = bound(0, pl.ammo_bolt + 5, MAX_A_BOLT);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED ammo_gaussclip (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the Tau Cannon and the Gluon Gun.
|
||||
A single ammo_gaussclip will provide 20 cells.
|
||||
|
||||
*/
|
||||
class ammo_gaussclip:item_ammo
|
||||
{
|
||||
void(void) ammo_gaussclip;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_gaussclip::ammo_gaussclip(void)
|
||||
{
|
||||
model = "models/w_gaussammo.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_gaussclip::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_uranium < MAX_A_URANIUM) {
|
||||
pl.ammo_uranium = bound(0, pl.ammo_uranium + 20, MAX_A_URANIUM);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
||||
|
||||
/*QUAKED ammo_rpgclip (0 0 0.8) (-16 -16 0) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ammo for the RPG.
|
||||
A single ammo_rpgclip will provide 1 rocket.
|
||||
|
||||
*/
|
||||
class ammo_rpgclip:item_ammo
|
||||
{
|
||||
void(void) ammo_rpgclip;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void ammo_rpgclip::ammo_rpgclip(void)
|
||||
{
|
||||
model = "models/w_rpgammo.mdl";
|
||||
item_ammo::item_ammo();
|
||||
}
|
||||
void ammo_rpgclip::touch(void)
|
||||
{
|
||||
if not (other.flags & FL_CLIENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
player pl = (player)other;
|
||||
if (pl.ammo_rocket < MAX_A_ROCKET) {
|
||||
pl.ammo_rocket = bound(0, pl.ammo_rocket + 1, MAX_A_ROCKET);
|
||||
item_ammo::touch();
|
||||
}
|
||||
}
|
77
src/server/client.qc
Normal file
77
src/server/client.qc
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/* called every input frame */
|
||||
void
|
||||
Game_RunClientCommand(void)
|
||||
{
|
||||
Footsteps_Update();
|
||||
Animation_PlayerUpdate();
|
||||
PMove_Run();
|
||||
}
|
||||
|
||||
/* custom chat packet */
|
||||
void
|
||||
SV_SendChat(entity sender, string msg, entity eEnt, float fType)
|
||||
{
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, fType == 0 ? EV_CHAT:EV_CHAT_TEAM);
|
||||
WriteByte(MSG_MULTICAST, num_for_edict(sender) - 1);
|
||||
WriteByte(MSG_MULTICAST, sender.team);
|
||||
WriteString(MSG_MULTICAST, msg);
|
||||
|
||||
if (eEnt) {
|
||||
msg_entity = eEnt;
|
||||
multicast([0,0,0], MULTICAST_ONE);
|
||||
} else {
|
||||
multicast([0,0,0], MULTICAST_ALL);
|
||||
}
|
||||
|
||||
localcmd(sprintf("echo [SERVER] %s: %s\n", sender.netname, msg));
|
||||
}
|
||||
|
||||
/* client cmd overrides happen here */
|
||||
void
|
||||
Game_ParseClientCommand(string cmd)
|
||||
{
|
||||
tokenize(cmd);
|
||||
|
||||
if (argv(1) == "timeleft") {
|
||||
string msg;
|
||||
string timestring;
|
||||
float timeleft;
|
||||
timeleft = cvar("mp_timelimit") - (time / 60);
|
||||
timestring = Vox_TimeToString(timeleft);
|
||||
msg = sprintf("we have %s minutes remaining", timestring);
|
||||
Vox_Singlecast(self, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv(0) == "say") {
|
||||
SV_SendChat(self, argv(1), world, 0);
|
||||
return;
|
||||
} else if (argv(0) == "say_team") {
|
||||
entity a;
|
||||
for (a = world; (a = find(a, ::classname, "player"));) {
|
||||
if (a.team == self.team) {
|
||||
SV_SendChat(self, argv(1), a, 1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
clientcommand(self, cmd);
|
||||
}
|
166
src/server/damage.qc
Normal file
166
src/server/damage.qc
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/* generic function that applies damage, pain and suffering */
|
||||
void
|
||||
Damage_Apply(entity t, entity c, float dmg, int w, int type)
|
||||
{
|
||||
base_player tp = (base_player)t;
|
||||
|
||||
CGameRules rules = (CGameRules)g_grMode;
|
||||
if (t.flags & FL_GODMODE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* already dead, please avoid recursion */
|
||||
if (t.health <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* skip armor */
|
||||
if not (type & DMG_SKIP_ARMOR)
|
||||
if (tp.armor && dmg > 0) {
|
||||
float flArmor;
|
||||
float flNewDamage;
|
||||
|
||||
flNewDamage = dmg * 0.2;
|
||||
flArmor = (dmg - flNewDamage) * 0.5;
|
||||
|
||||
if (flArmor > tp.armor) {
|
||||
flArmor = tp.armor;
|
||||
flArmor *= (1/0.5);
|
||||
flNewDamage = dmg - flArmor;
|
||||
tp.armor = 0;
|
||||
} else {
|
||||
tp.armor -= flArmor;
|
||||
}
|
||||
dmg = flNewDamage;
|
||||
}
|
||||
|
||||
dmg = rint(dmg);
|
||||
t.health -= dmg;
|
||||
|
||||
/* the globals... */
|
||||
g_dmg_eAttacker = c;
|
||||
g_dmg_eTarget = t;
|
||||
g_dmg_iDamage = dmg;
|
||||
g_dmg_iHitBody = trace_surface_id;
|
||||
g_dmg_iFlags = type;
|
||||
g_dmg_iWeapon = w;
|
||||
|
||||
if (dmg > 0) {
|
||||
t.dmg_take = dmg;
|
||||
t.dmg_inflictor = c;
|
||||
} else if (t.max_health && t.health > t.max_health) {
|
||||
t.health = t.max_health;
|
||||
}
|
||||
|
||||
/* set this global in case we need it later */
|
||||
g_eAttacker = c;
|
||||
|
||||
CBaseEntity s = (CBaseEntity)t;
|
||||
|
||||
if (s.health <= 0) {
|
||||
if (s.flags & FL_CLIENT) {
|
||||
rules.PlayerDeath((player)s);
|
||||
} else {
|
||||
s.Death();
|
||||
}
|
||||
} else {
|
||||
if (s.flags & FL_CLIENT) {
|
||||
rules.PlayerPain((player)s);
|
||||
} else {
|
||||
s.Pain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* physical check of whether or not we can trace important parts of an ent */
|
||||
float
|
||||
Damage_CheckTrace(entity t, vector vecHitPos)
|
||||
{
|
||||
/* We're lazy. Who cares */
|
||||
if (t.solid == SOLID_BSP) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
traceline(vecHitPos, t.origin, 1, self);
|
||||
if (trace_fraction == 1) {
|
||||
return TRUE;
|
||||
}
|
||||
traceline(vecHitPos, t.origin + [15,15,0], 1, self);
|
||||
if (trace_fraction == 1) {
|
||||
return TRUE;
|
||||
}
|
||||
traceline(vecHitPos, t.origin + [-15,-15,0], 1, self);
|
||||
if (trace_fraction == 1) {
|
||||
return TRUE;
|
||||
}
|
||||
traceline(vecHitPos, t.origin + [-15,15,0], 1, self);
|
||||
if (trace_fraction == 1) {
|
||||
return TRUE;
|
||||
}
|
||||
traceline(vecHitPos, t.origin + [15,-15,0], 1, self);
|
||||
if (trace_fraction == 1) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* even more pain and suffering, mostly used for explosives */
|
||||
void
|
||||
Damage_Radius(vector org, entity attacker, float dmg, float r, int check, int w)
|
||||
{
|
||||
float new_dmg;
|
||||
float dist;
|
||||
float diff;
|
||||
vector pos;
|
||||
|
||||
for (entity e = world; (e = findfloat(e, ::takedamage, DAMAGE_YES));) {
|
||||
pos[0] = e.absmin[0] + (0.5 * (e.absmax[0] - e.absmin[0]));
|
||||
pos[1] = e.absmin[1] + (0.5 * (e.absmax[1] - e.absmin[1]));
|
||||
pos[2] = e.absmin[2] + (0.5 * (e.absmax[2] - e.absmin[2]));
|
||||
|
||||
/* don't bother if it's not anywhere near us */
|
||||
dist = vlen(org - pos);
|
||||
if (dist > r) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* can we physically hit this thing? */
|
||||
if (Damage_CheckTrace(e, org) == FALSE) {
|
||||
if (check == TRUE) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate new damage values */
|
||||
diff = vlen(org - pos);
|
||||
diff = (r - diff) / r;
|
||||
new_dmg = rint(dmg * diff);
|
||||
|
||||
if (diff > 0) {
|
||||
Damage_Apply(e, attacker, new_dmg, w, DMG_EXPLODE);
|
||||
|
||||
/* approximate, feel free to tweak */
|
||||
if (e.movetype == MOVETYPE_WALK) {
|
||||
makevectors(vectoangles(e.origin - org));
|
||||
e.velocity += v_forward * (new_dmg * 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
src/server/defs.h
Normal file
18
src/server/defs.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
#include "gamerules.h"
|
||||
#include "items.h"
|
42
src/server/flashlight.qc
Normal file
42
src/server/flashlight.qc
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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 Flashlight_Toggle(void)
|
||||
{
|
||||
if (cvar("sv_playerslots") != 1) {
|
||||
if (cvar("mp_flashlight") != 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VALVE
|
||||
player pl = (player)self;
|
||||
if (!(pl.g_items & ITEM_SUIT)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (self.health <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.gflags & GF_FLASHLIGHT) {
|
||||
self.gflags &= ~GF_FLASHLIGHT;
|
||||
} else {
|
||||
self.gflags |= GF_FLASHLIGHT;
|
||||
}
|
||||
sound(self, CHAN_ITEM, "items/flashlight1.wav", 1, ATTN_IDLE);
|
||||
}
|
47
src/server/gamerules.h
Normal file
47
src/server/gamerules.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
class HLGameRules:CGameRules
|
||||
{
|
||||
virtual void(base_player) PlayerConnect;
|
||||
virtual void(base_player) PlayerDisconnect;
|
||||
virtual void(base_player) PlayerKill;
|
||||
virtual void(base_player) PlayerPostFrame;
|
||||
|
||||
virtual void(base_player) LevelDecodeParms;
|
||||
virtual void(base_player) LevelChangeParms;
|
||||
virtual void(void) LevelNewParms;
|
||||
};
|
||||
|
||||
class HLSingleplayerRules:HLGameRules
|
||||
{
|
||||
/* client */
|
||||
virtual void(base_player) PlayerSpawn;
|
||||
virtual void(base_player) PlayerDeath;
|
||||
};
|
||||
|
||||
class HLMultiplayerRules:HLGameRules
|
||||
{
|
||||
int m_iIntermission;
|
||||
int m_iIntermissionTime;
|
||||
|
||||
virtual void(void) FrameStart;
|
||||
|
||||
/* client */
|
||||
virtual void(base_player) PlayerSpawn;
|
||||
virtual void(base_player) PlayerDeath;
|
||||
virtual float(base_player, string) ConsoleCommand;
|
||||
};
|
143
src/server/gamerules.qc
Normal file
143
src/server/gamerules.qc
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
HLGameRules::LevelDecodeParms(base_player pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
g_landmarkpos[0] = parm1;
|
||||
g_landmarkpos[1] = parm2;
|
||||
g_landmarkpos[2] = parm3;
|
||||
pl.angles[0] = parm4;
|
||||
pl.angles[1] = parm5;
|
||||
pl.angles[2] = parm6;
|
||||
pl.velocity[0] = parm7;
|
||||
pl.velocity[1] = parm8;
|
||||
pl.velocity[2] = parm9;
|
||||
pl.g_items = parm10;
|
||||
pl.activeweapon = parm11;
|
||||
pl.flags = parm64;
|
||||
|
||||
pl.ammo_9mm = parm12;
|
||||
pl.ammo_357 = parm13;
|
||||
pl.ammo_buckshot = parm14;
|
||||
pl.ammo_m203_grenade = parm15;
|
||||
pl.ammo_bolt = parm16;
|
||||
pl.ammo_rocket = parm17;
|
||||
pl.ammo_uranium = parm18;
|
||||
pl.ammo_handgrenade = parm19;
|
||||
pl.ammo_satchel = parm20;
|
||||
pl.ammo_tripmine = parm21;
|
||||
pl.ammo_snark = parm22;
|
||||
pl.ammo_hornet = parm23;
|
||||
|
||||
pl.glock_mag = parm24;
|
||||
pl.mp5_mag = parm25;
|
||||
pl.python_mag = parm26;
|
||||
pl.shotgun_mag = parm27;
|
||||
pl.crossbow_mag = parm28;
|
||||
pl.rpg_mag = parm29;
|
||||
pl.satchel_chg = parm30;
|
||||
|
||||
if (pl.flags & FL_CROUCHING) {
|
||||
setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX);
|
||||
} else {
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::LevelChangeParms(base_player pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
parm1 = g_landmarkpos[0];
|
||||
parm2 = g_landmarkpos[1];
|
||||
parm3 = g_landmarkpos[2];
|
||||
parm4 = pl.angles[0];
|
||||
parm5 = pl.angles[1];
|
||||
parm6 = pl.angles[2];
|
||||
parm7 = pl.velocity[0];
|
||||
parm8 = pl.velocity[1];
|
||||
parm9 = pl.velocity[2];
|
||||
parm64 = pl.flags;
|
||||
parm10 = pl.g_items;
|
||||
parm11 = pl.activeweapon;
|
||||
parm12 = pl.ammo_9mm;
|
||||
parm13 = pl.ammo_357;
|
||||
parm14 = pl.ammo_buckshot;
|
||||
parm15 = pl.ammo_m203_grenade;
|
||||
parm16 = pl.ammo_bolt;
|
||||
parm17 = pl.ammo_rocket;
|
||||
parm18 = pl.ammo_uranium;
|
||||
parm19 = pl.ammo_handgrenade;
|
||||
parm20 = pl.ammo_satchel;
|
||||
parm21 = pl.ammo_tripmine;
|
||||
parm22 = pl.ammo_snark;
|
||||
parm23 = pl.ammo_hornet;
|
||||
parm24 = pl.glock_mag;
|
||||
parm25 = pl.mp5_mag;
|
||||
parm26 = pl.python_mag;
|
||||
parm27 = pl.shotgun_mag;
|
||||
parm28 = pl.crossbow_mag;
|
||||
parm29 = pl.rpg_mag;
|
||||
parm30 = pl.satchel_chg;
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::LevelNewParms(void)
|
||||
{
|
||||
parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 =
|
||||
parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 =
|
||||
parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 =
|
||||
parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 =
|
||||
parm29 = parm30 = 0;
|
||||
parm64 = FL_CLIENT;
|
||||
}
|
||||
|
||||
/* we check what fields have changed over the course of the frame and network
|
||||
* only the ones that have actually changed */
|
||||
void
|
||||
HLGameRules::PlayerPostFrame(base_player pl)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::PlayerConnect(base_player pl)
|
||||
{
|
||||
if (Plugin_PlayerConnect(pl) == FALSE)
|
||||
bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname));
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::PlayerDisconnect(base_player pl)
|
||||
{
|
||||
if (Plugin_PlayerDisconnect(pl) == FALSE)
|
||||
bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname));
|
||||
|
||||
/* Make this unusable */
|
||||
pl.solid = SOLID_NOT;
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.modelindex = 0;
|
||||
pl.health = 0;
|
||||
pl.takedamage = 0;
|
||||
pl.SendFlags = -1;
|
||||
}
|
||||
|
||||
void
|
||||
HLGameRules::PlayerKill(base_player pl)
|
||||
{
|
||||
Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR);
|
||||
}
|
166
src/server/gamerules_multiplayer.qc
Normal file
166
src/server/gamerules_multiplayer.qc
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
HLMultiplayerRules::FrameStart(void)
|
||||
{
|
||||
if (cvar("mp_timelimit"))
|
||||
if (time >= (cvar("mp_timelimit") * 60)) {
|
||||
IntermissionStart();
|
||||
}
|
||||
|
||||
IntermissionCycle();
|
||||
}
|
||||
|
||||
void
|
||||
HLMultiplayerRules::PlayerDeath(base_player pl)
|
||||
{
|
||||
/* obituary networking */
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_OBITUARY);
|
||||
if (g_dmg_eAttacker.netname)
|
||||
WriteString(MSG_MULTICAST, g_dmg_eAttacker.netname);
|
||||
else
|
||||
WriteString(MSG_MULTICAST, g_dmg_eAttacker.classname);
|
||||
WriteString(MSG_MULTICAST, pl.netname);
|
||||
WriteByte(MSG_MULTICAST, g_dmg_iWeapon);
|
||||
WriteByte(MSG_MULTICAST, 0);
|
||||
msg_entity = world;
|
||||
multicast([0,0,0], MULTICAST_ALL);
|
||||
|
||||
Plugin_PlayerObituary(g_dmg_eAttacker, g_dmg_eTarget, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage);
|
||||
|
||||
/* death-counter */
|
||||
pl.deaths++;
|
||||
forceinfokey(pl, "*deaths", ftos(pl.deaths));
|
||||
|
||||
/* update score-counter */
|
||||
if (pl.flags & FL_CLIENT || pl.flags & FL_MONSTER)
|
||||
if (g_dmg_eAttacker.flags & FL_CLIENT) {
|
||||
if (pl == g_dmg_eAttacker)
|
||||
g_dmg_eAttacker.frags--;
|
||||
else
|
||||
g_dmg_eAttacker.frags++;
|
||||
}
|
||||
|
||||
/* in DM we only care about the frags */
|
||||
if (cvar("mp_fraglimit"))
|
||||
if (g_dmg_eAttacker.frags >= cvar("mp_fraglimit")) {
|
||||
IntermissionStart();
|
||||
}
|
||||
|
||||
weaponbox_spawn((player)pl);
|
||||
|
||||
/* either gib, or make a corpse */
|
||||
if (pl.health < -50) {
|
||||
FX_GibHuman(pl.origin);
|
||||
} else {
|
||||
/* Let's handle corpses on the clientside */
|
||||
entity corpse = spawn();
|
||||
setorigin(corpse, pl.origin + [0,0,32]);
|
||||
setmodel(corpse, pl.model);
|
||||
setsize(corpse, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
corpse.movetype = MOVETYPE_TOSS;
|
||||
corpse.solid = SOLID_TRIGGER;
|
||||
corpse.modelindex = pl.modelindex;
|
||||
corpse.frame = ANIM_DIESIMPLE;
|
||||
corpse.angles = pl.angles;
|
||||
corpse.velocity = pl.velocity;
|
||||
}
|
||||
|
||||
/* now let's make the real client invisible */
|
||||
pl.SetModelindex(0);
|
||||
pl.SetMovetype(MOVETYPE_NONE);
|
||||
pl.SetSolid(SOLID_NOT);
|
||||
pl.takedamage = DAMAGE_NO;
|
||||
pl.gflags &= ~GF_FLASHLIGHT;
|
||||
pl.armor = pl.activeweapon = pl.g_items = 0;
|
||||
pl.health = 0;
|
||||
|
||||
Sound_Play(pl, CHAN_AUTO, "player.die");
|
||||
|
||||
/* force respawn */
|
||||
pl.think = PutClientInServer;
|
||||
pl.nextthink = time + 4.0f;
|
||||
}
|
||||
|
||||
void
|
||||
HLMultiplayerRules::PlayerSpawn(base_player pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
/* this is where the mods want to deviate */
|
||||
entity spot;
|
||||
|
||||
pl.classname = "player";
|
||||
pl.health = pl.max_health = 100;
|
||||
pl.takedamage = DAMAGE_YES;
|
||||
pl.solid = SOLID_SLIDEBOX;
|
||||
pl.movetype = MOVETYPE_WALK;
|
||||
pl.flags = FL_CLIENT;
|
||||
pl.viewzoom = 1.0;
|
||||
pl.model = "models/player.mdl";
|
||||
string mymodel = infokey(pl, "model");
|
||||
|
||||
if (mymodel) {
|
||||
mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel);
|
||||
if (whichpack(mymodel)) {
|
||||
pl.model = mymodel;
|
||||
}
|
||||
}
|
||||
setmodel(pl, pl.model);
|
||||
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
pl.view_ofs = VEC_PLAYER_VIEWPOS;
|
||||
pl.velocity = [0,0,0];
|
||||
pl.gravity = __NULL__;
|
||||
pl.frame = 1;
|
||||
//pl.SendEntity = Player_SendEntity;
|
||||
pl.SendFlags = UPDATE_ALL;
|
||||
pl.customphysics = Empty;
|
||||
pl.iBleeds = TRUE;
|
||||
forceinfokey(pl, "*spec", "0");
|
||||
forceinfokey(pl, "*deaths", ftos(pl.deaths));
|
||||
|
||||
LevelNewParms();
|
||||
LevelDecodeParms(pl);
|
||||
pl.g_items = ITEM_CROWBAR | ITEM_GLOCK | ITEM_SUIT;
|
||||
pl.activeweapon = WEAPON_GLOCK;
|
||||
pl.glock_mag = 18;
|
||||
pl.ammo_9mm = 44;
|
||||
|
||||
spot = Spawn_SelectRandom("info_player_deathmatch");
|
||||
setorigin(pl, spot.origin);
|
||||
pl.angles = spot.angles;
|
||||
Weapons_RefreshAmmo(pl);
|
||||
|
||||
Client_FixAngle(pl, pl.angles);
|
||||
}
|
||||
|
||||
float
|
||||
HLMultiplayerRules::ConsoleCommand(base_player pp, string cmd)
|
||||
{
|
||||
tokenize(cmd);
|
||||
|
||||
switch (argv(0)) {
|
||||
case "bot_add":
|
||||
Bot_AddQuick();
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
103
src/server/gamerules_singleplayer.qc
Normal file
103
src/server/gamerules_singleplayer.qc
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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
|
||||
HLSingleplayerRules::PlayerDeath(base_player pl)
|
||||
{
|
||||
pl.movetype = MOVETYPE_NONE;
|
||||
pl.solid = SOLID_NOT;
|
||||
pl.takedamage = DAMAGE_NO;
|
||||
pl.gflags &= ~GF_FLASHLIGHT;
|
||||
pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0;
|
||||
pl.health = 0;
|
||||
Sound_Play(pl, CHAN_AUTO, "player.die");
|
||||
|
||||
if (cvar("coop") == 1) {
|
||||
pl.think = PutClientInServer;
|
||||
pl.nextthink = time + 4.0f;
|
||||
}
|
||||
|
||||
if (pl.health < -50) {
|
||||
FX_GibHuman(pl.origin);
|
||||
}
|
||||
|
||||
/* Let's handle corpses on the clientside */
|
||||
entity corpse = spawn();
|
||||
setorigin(corpse, pl.origin + [0,0,32]);
|
||||
setmodel(corpse, pl.model);
|
||||
setsize(corpse, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
corpse.movetype = MOVETYPE_TOSS;
|
||||
corpse.solid = SOLID_TRIGGER;
|
||||
corpse.modelindex = pl.modelindex;
|
||||
corpse.frame = ANIM_DIESIMPLE;
|
||||
corpse.angles = pl.angles;
|
||||
corpse.velocity = pl.velocity;
|
||||
}
|
||||
|
||||
void
|
||||
HLSingleplayerRules::PlayerSpawn(base_player pl)
|
||||
{
|
||||
pl.classname = "player";
|
||||
pl.health = pl.max_health = 100;
|
||||
pl.takedamage = DAMAGE_YES;
|
||||
pl.solid = SOLID_SLIDEBOX;
|
||||
pl.movetype = MOVETYPE_WALK;
|
||||
pl.flags = FL_CLIENT;
|
||||
pl.viewzoom = 1.0;
|
||||
pl.model = "models/player.mdl";
|
||||
|
||||
|
||||
if (cvar("coop") == 1) {
|
||||
string mymodel = infokey(pl, "model");
|
||||
if (mymodel) {
|
||||
mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel);
|
||||
if (whichpack(mymodel)) {
|
||||
pl.model = mymodel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setmodel(pl, pl.model);
|
||||
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
pl.view_ofs = VEC_PLAYER_VIEWPOS;
|
||||
pl.velocity = [0,0,0];
|
||||
pl.gravity = __NULL__;
|
||||
pl.frame = 1;
|
||||
//pl.SendEntity = Player_SendEntity;
|
||||
pl.SendFlags = UPDATE_ALL;
|
||||
pl.customphysics = Empty;
|
||||
pl.iBleeds = TRUE;
|
||||
forceinfokey(pl, "*spec", "0");
|
||||
forceinfokey(pl, "*deaths", ftos(pl.deaths));
|
||||
|
||||
/* this is where the mods want to deviate */
|
||||
entity spot;
|
||||
|
||||
if (startspot != "") {
|
||||
dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot));
|
||||
LevelDecodeParms(pl);
|
||||
setorigin(pl, Landmark_GetSpot());
|
||||
} else {
|
||||
LevelNewParms();
|
||||
spot = find(world, ::classname, "info_player_start");
|
||||
setorigin(pl, spot.origin);
|
||||
pl.angles = spot.angles;
|
||||
}
|
||||
|
||||
Weapons_RefreshAmmo(pl);
|
||||
Client_FixAngle(pl, pl.angles);
|
||||
}
|
108
src/server/input.qc
Normal file
108
src/server/input.qc
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
Input_Handle
|
||||
|
||||
Handles impulse and whatnot
|
||||
=================
|
||||
*/
|
||||
void Game_Input(void)
|
||||
{
|
||||
CGameRules rules = (CGameRules)g_grMode;
|
||||
|
||||
if (rules.m_iIntermission) {
|
||||
rules.IntermissionEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_buttons & INPUT_BUTTON0) {
|
||||
Weapons_Primary();
|
||||
} else if (input_buttons & INPUT_BUTTON4) {
|
||||
Weapons_Reload();
|
||||
} else if (input_buttons & INPUT_BUTTON3) {
|
||||
Weapons_Secondary();
|
||||
} else {
|
||||
Weapons_Release();
|
||||
}
|
||||
|
||||
if (input_buttons & INPUT_BUTTON5) {
|
||||
Player_UseDown();
|
||||
} else {
|
||||
Player_UseUp();
|
||||
}
|
||||
|
||||
if (self.impulse == 100) {
|
||||
Flashlight_Toggle();
|
||||
}
|
||||
|
||||
if (cvar("sv_cheats") == 1) {
|
||||
player pl = (player)self;
|
||||
if (self.impulse == 101) {
|
||||
pl.health = 100;
|
||||
pl.armor = 100;
|
||||
pl.g_items |= ITEM_SUIT;
|
||||
Weapons_AddItem(pl, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(pl, WEAPON_GLOCK, -1);
|
||||
Weapons_AddItem(pl, WEAPON_PYTHON, -1);
|
||||
Weapons_AddItem(pl, WEAPON_MP5, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SHOTGUN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_CROSSBOW, -1);
|
||||
Weapons_AddItem(pl, WEAPON_RPG, -1);
|
||||
Weapons_AddItem(pl, WEAPON_GAUSS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_EGON, -1);
|
||||
Weapons_AddItem(pl, WEAPON_HORNETGUN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_HANDGRENADE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SATCHEL, -1);
|
||||
Weapons_AddItem(pl, WEAPON_TRIPMINE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SNARK, -1);
|
||||
#ifdef GEARBOX
|
||||
Weapons_AddItem(pl, WEAPON_PIPEWRENCH, -1);
|
||||
Weapons_AddItem(pl, WEAPON_KNIFE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_GRAPPLE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_EAGLE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_PENGUIN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_M249, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DISPLACER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SNIPERRIFLE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SPORELAUNCHER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SHOCKRIFLE, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (self.impulse == 102) {
|
||||
// Respawn all the entities
|
||||
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
|
||||
CBaseEntity caw = (CBaseEntity)a;
|
||||
caw.Respawn();
|
||||
caw.SendFlags |=
|
||||
BASEFL_CHANGED_ORIGIN |
|
||||
BASEFL_CHANGED_ANGLES |
|
||||
BASEFL_CHANGED_MODELINDEX |
|
||||
BASEFL_CHANGED_SIZE |
|
||||
BASEFL_CHANGED_SOLID |
|
||||
BASEFL_CHANGED_FRAME |
|
||||
BASEFL_CHANGED_SKIN |
|
||||
BASEFL_CHANGED_MOVETYPE |
|
||||
BASEFL_CHANGED_EFFECTS;
|
||||
}
|
||||
bprint(PRINT_HIGH, "Respawning all map entities...\n");
|
||||
}
|
||||
}
|
||||
|
||||
self.impulse = 0;
|
||||
}
|
91
src/server/item_battery.qc
Normal file
91
src/server/item_battery.qc
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED item_battery (0 0 0.8) (-16 -16 0) (16 16 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
HEV Suit energy battery.
|
||||
It adds the following energy values to the HEV Suit by default:
|
||||
Skill 1 (Easy): 15
|
||||
Skill 2 (Medium): 15
|
||||
Skill 3 (Hard): 10
|
||||
|
||||
The values can be tweaked in the skill.cfg file.
|
||||
|
||||
*/
|
||||
class item_battery:CBaseEntity
|
||||
{
|
||||
void(void) item_battery;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void item_battery::touch(void)
|
||||
{
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
base_player pl = (base_player)other;
|
||||
|
||||
if (pl.armor >= 100) {
|
||||
return;
|
||||
}
|
||||
/* Move this somewhere else? */
|
||||
pl.armor += Skill_GetValue("battery", 15);
|
||||
if (pl.armor > 100) {
|
||||
pl.armor = 100;
|
||||
}
|
||||
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
Sound_Play(other, CHAN_ITEM, "item.battery");
|
||||
|
||||
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 20.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void item_battery::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
SetSize([-16,-16,0],[16,16,16]);
|
||||
SetOrigin(m_oldOrigin);
|
||||
SetModel(m_oldModel);
|
||||
// botinfo = BOTINFO_ARMOR;
|
||||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
|
||||
if (!real_owner)
|
||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||
|
||||
droptofloor();
|
||||
}
|
||||
|
||||
void item_battery::item_battery(void)
|
||||
{
|
||||
Sound_Precache("item.battery");
|
||||
Sound_Precache("item.respawn");
|
||||
model = "models/w_battery.mdl";
|
||||
CBaseEntity::CBaseEntity();
|
||||
item_healthkit::Respawn();
|
||||
}
|
80
src/server/item_healthkit.qc
Normal file
80
src/server/item_healthkit.qc
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED item_healthkit (0 0 0.8) (-16 -16 0) (16 16 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Healthkit item.
|
||||
Adds 20 of health to the player.
|
||||
|
||||
*/
|
||||
class item_healthkit:CBaseEntity
|
||||
{
|
||||
void(void) item_healthkit;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
void item_healthkit::touch(void)
|
||||
{
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (other.health >= other.max_health) {
|
||||
return;
|
||||
}
|
||||
|
||||
Damage_Apply(other, this, -20, 0, DMG_GENERIC);
|
||||
Sound_Play(this, CHAN_ITEM, "item.healthkit");
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
|
||||
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 20.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void item_healthkit::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
SetSize([-16,-16,0],[16,16,16]);
|
||||
SetOrigin(m_oldOrigin);
|
||||
SetModel(m_oldModel);
|
||||
//botinfo = BOTINFO_HEALTH;
|
||||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
|
||||
if (!real_owner)
|
||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||
|
||||
droptofloor();
|
||||
}
|
||||
|
||||
void item_healthkit::item_healthkit(void)
|
||||
{
|
||||
Sound_Precache("item.healthkit");
|
||||
Sound_Precache("item.respawn");
|
||||
model = "models/w_medkit.mdl";
|
||||
CBaseEntity::CBaseEntity();
|
||||
item_healthkit::Respawn();
|
||||
}
|
108
src/server/item_longjump.qc
Normal file
108
src/server/item_longjump.qc
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED item_longjump (0 0 0.8) (-16 -16 0) (16 16 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Longjump module.
|
||||
Allows the player to jump longer distance by holding crouch
|
||||
and pressing jump.
|
||||
|
||||
*/
|
||||
class item_longjump:CBaseTrigger
|
||||
{
|
||||
string m_strOnPlayerTouch;
|
||||
|
||||
void(void) item_longjump;
|
||||
|
||||
virtual void(void) touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
item_longjump::touch(void)
|
||||
{
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
player pl = (player)other;
|
||||
if (pl.g_items & ITEM_LONGJUMP) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
sound(other, CHAN_ITEM, "fvox/blip.wav", 1, ATTN_NORM);
|
||||
sound(other, CHAN_VOICE, "fvox/powermove_on.wav", 1, ATTN_NORM);
|
||||
pl.g_items |= ITEM_LONGJUMP;
|
||||
|
||||
if (!target) {
|
||||
UseOutput(other, m_strOnPlayerTouch);
|
||||
} else {
|
||||
UseTargets(other, TRIG_TOGGLE, m_flDelay);
|
||||
}
|
||||
|
||||
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 30.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
item_longjump::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
SetSize([-16,-16,0],[16,16,16]);
|
||||
SetOrigin(m_oldOrigin);
|
||||
SetModel(m_oldModel);
|
||||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
|
||||
if (!real_owner)
|
||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||
}
|
||||
|
||||
void
|
||||
item_longjump::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "OnPlayerTouch":
|
||||
strValue = strreplace(",", ",_", strValue);
|
||||
m_strOnPlayerTouch = strcat(m_strOnPlayerTouch, ",_", strValue);
|
||||
break;
|
||||
default:
|
||||
CBaseTrigger::SpawnKey(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
item_longjump::item_longjump(void)
|
||||
{
|
||||
model = "models/w_longjump.mdl";
|
||||
precache_sound("items/suitchargeok1.wav");
|
||||
precache_sound("fvox/powermove_on.wav");
|
||||
precache_sound("fvox/blip.wav");
|
||||
CBaseTrigger::CBaseTrigger();
|
||||
Respawn();
|
||||
}
|
113
src/server/item_suit.qc
Normal file
113
src/server/item_suit.qc
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED item_suit (0 0 0.8) (-16 -16 0) (16 16 36) SUIT_LONGINTRO
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
HEV Suit
|
||||
Provides the player with armor, a flashlight and a Heads-Up-Display.
|
||||
|
||||
When SUIT_LONGINTRO is set, the intro dialog will be longer.
|
||||
|
||||
*/
|
||||
|
||||
class item_suit:CBaseTrigger
|
||||
{
|
||||
string m_strOnPlayerTouch;
|
||||
|
||||
void(void) item_suit;
|
||||
|
||||
virtual void(void) touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
item_suit::touch(void)
|
||||
{
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
player pl = (player)other;
|
||||
if (pl.g_items & ITEM_SUIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
sound(other, CHAN_ITEM, "fvox/bell.wav", 1, ATTN_NORM);
|
||||
sound(other, CHAN_VOICE, "fvox/hev_logon.wav", 1, ATTN_NORM);
|
||||
pl.g_items |= ITEM_SUIT;
|
||||
m_iValue = TRUE;
|
||||
|
||||
if (!target) {
|
||||
UseOutput(other, m_strOnPlayerTouch);
|
||||
} else {
|
||||
UseTargets(other, TRIG_TOGGLE, m_flDelay);
|
||||
}
|
||||
|
||||
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 30.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
item_suit::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
SetOrigin(m_oldOrigin);
|
||||
SetModel(m_oldModel);
|
||||
m_iValue = FALSE;
|
||||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
|
||||
if (!real_owner)
|
||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||
}
|
||||
|
||||
void
|
||||
item_suit::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "OnPlayerTouch":
|
||||
strValue = strreplace(",", ",_", strValue);
|
||||
m_strOnPlayerTouch = strcat(m_strOnPlayerTouch, ",_", strValue);
|
||||
break;
|
||||
default:
|
||||
CBaseTrigger::SpawnKey(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
item_suit::item_suit(void)
|
||||
{
|
||||
model = "models/w_suit.mdl";
|
||||
precache_sound("items/suitchargeok1.wav");
|
||||
precache_sound("fvox/hev_logon.wav");
|
||||
precache_sound("fvox/bell.wav");
|
||||
CBaseTrigger::CBaseTrigger();
|
||||
|
||||
m_strOnPlayerTouch = CreateOutput(m_strOnPlayerTouch);
|
||||
}
|
112
src/server/item_weaponbox.qc
Normal file
112
src/server/item_weaponbox.qc
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
class item_weaponbox:CBaseEntity
|
||||
{
|
||||
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 weapon_items;
|
||||
|
||||
void(void) item_weaponbox;
|
||||
virtual void(void) touch;
|
||||
virtual void(player) setup;
|
||||
};
|
||||
|
||||
void item_weaponbox::touch(void)
|
||||
{
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
player pl = (player)other;
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
sound(pl, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM);
|
||||
|
||||
pl.ammo_9mm += ammo_9mm;
|
||||
pl.ammo_357 += ammo_357;
|
||||
pl.ammo_buckshot += ammo_buckshot;
|
||||
pl.ammo_m203_grenade += ammo_m203_grenade;
|
||||
pl.ammo_bolt += ammo_bolt;
|
||||
pl.ammo_rocket += ammo_rocket;
|
||||
pl.ammo_uranium += ammo_uranium;
|
||||
pl.ammo_handgrenade += ammo_handgrenade;
|
||||
pl.ammo_satchel += ammo_satchel;
|
||||
pl.ammo_tripmine += ammo_tripmine;
|
||||
pl.ammo_snark += ammo_snark;
|
||||
pl.ammo_hornet += ammo_hornet;
|
||||
|
||||
/* cull */
|
||||
pl.ammo_9mm = min(pl.ammo_9mm, MAX_A_9MM);
|
||||
pl.ammo_357 = min(pl.ammo_357, MAX_A_357);
|
||||
pl.ammo_buckshot = min(pl.ammo_buckshot, MAX_A_BUCKSHOT);
|
||||
pl.ammo_m203_grenade = min(pl.ammo_m203_grenade, MAX_A_M203_GRENADE);
|
||||
pl.ammo_bolt = min(pl.ammo_bolt, MAX_A_BOLT);
|
||||
pl.ammo_rocket = min(pl.ammo_rocket, MAX_A_ROCKET);
|
||||
pl.ammo_uranium = min(pl.ammo_uranium, MAX_A_URANIUM);
|
||||
pl.ammo_handgrenade = min(pl.ammo_handgrenade, MAX_A_HANDGRENADE);
|
||||
pl.ammo_satchel = min(pl.ammo_satchel, MAX_A_SATCHEL);
|
||||
pl.ammo_tripmine = min(pl.ammo_tripmine, MAX_A_TRIPMINE);
|
||||
pl.ammo_snark = min(pl.ammo_snark, MAX_A_SNARK);
|
||||
pl.ammo_hornet = min(pl.ammo_hornet, MAX_A_HORNET);
|
||||
|
||||
pl.g_items |= weapon_items;
|
||||
Weapons_RefreshAmmo(pl);
|
||||
|
||||
remove(this);
|
||||
}
|
||||
|
||||
void item_weaponbox::setup(player pl)
|
||||
{
|
||||
/* TODO: Should the magazine bits be transferred too? */
|
||||
ammo_9mm = pl.ammo_9mm;
|
||||
ammo_357 = pl.ammo_357;
|
||||
ammo_buckshot = pl.ammo_buckshot;
|
||||
ammo_m203_grenade = pl.ammo_m203_grenade;
|
||||
ammo_bolt = pl.ammo_bolt;
|
||||
ammo_rocket = pl.ammo_rocket;
|
||||
ammo_uranium = pl.ammo_uranium;
|
||||
ammo_handgrenade = pl.ammo_handgrenade;
|
||||
ammo_satchel = pl.ammo_satchel;
|
||||
ammo_tripmine = pl.ammo_tripmine;
|
||||
ammo_snark = pl.ammo_snark;
|
||||
ammo_hornet = pl.ammo_hornet;
|
||||
weapon_items = pl.g_items;
|
||||
}
|
||||
|
||||
void item_weaponbox::item_weaponbox(void)
|
||||
{
|
||||
SetModel("models/w_weaponbox.mdl");
|
||||
SetSize([-16,-16,0], [16,16,16]);
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
}
|
||||
|
||||
void weaponbox_spawn(player spawner)
|
||||
{
|
||||
item_weaponbox weaponbox = spawn(item_weaponbox);
|
||||
weaponbox.SetOrigin(spawner.origin);
|
||||
weaponbox.setup(spawner);
|
||||
}
|
30
src/server/items.h
Normal file
30
src/server/items.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/* PICKUP ITEMS */
|
||||
class item_pickup:CBaseTrigger
|
||||
{
|
||||
int m_bFloating;
|
||||
int m_iClip;
|
||||
int m_iWasDropped;
|
||||
int id;
|
||||
void(void) item_pickup;
|
||||
|
||||
virtual void(void) touch;
|
||||
virtual void(int i) SetItem;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(int) SetFloating;
|
||||
};
|
88
src/server/items.qc
Normal file
88
src/server/items.qc
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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 item_pickup::touch(void)
|
||||
{
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
/* don't remove if AddItem fails */
|
||||
if (Weapons_AddItem((player)other, id, m_iClip) == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging_Pickup(other, this, __NULL__);
|
||||
Sound_Play(other, CHAN_ITEM, "weapon.pickup");
|
||||
|
||||
UseTargets(other, TRIG_TOGGLE, m_flDelay);
|
||||
|
||||
if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 30.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void item_pickup::SetItem(int i)
|
||||
{
|
||||
id = i;
|
||||
m_oldModel = Weapons_GetWorldmodel(id);
|
||||
SetModel(m_oldModel);
|
||||
}
|
||||
|
||||
void item_pickup::SetFloating(int i)
|
||||
{
|
||||
m_bFloating = rint(bound(0, m_bFloating, 1));
|
||||
}
|
||||
|
||||
void item_pickup::Respawn(void)
|
||||
{
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(m_oldOrigin);
|
||||
|
||||
/* At some points, the item id might not yet be set */
|
||||
if (m_oldModel) {
|
||||
SetModel(m_oldModel);
|
||||
}
|
||||
|
||||
SetSize([-16,-16,0], [16,16,16]);
|
||||
|
||||
think = __NULL__;
|
||||
nextthink = -1;
|
||||
|
||||
if (!m_iWasDropped && cvar("sv_playerslots") > 1) {
|
||||
if (!real_owner)
|
||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||
|
||||
m_iClip = -1;
|
||||
}
|
||||
|
||||
if (!m_bFloating) {
|
||||
droptofloor();
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
}
|
||||
}
|
||||
|
||||
void item_pickup::item_pickup(void)
|
||||
{
|
||||
Sound_Precache("item.respawn");
|
||||
Sound_Precache("weapon.pickup");
|
||||
CBaseTrigger::CBaseTrigger();
|
||||
Respawn();
|
||||
}
|
128
src/server/monster_alien_controller.qc
Normal file
128
src/server/monster_alien_controller.qc
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_alien_controller (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Alien Controller
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
CON_ATTACK,
|
||||
CON_ATTACK2,
|
||||
CON_THROW,
|
||||
CON_IDLE2,
|
||||
CON_BLOCK,
|
||||
CON_SHOOT,
|
||||
CON_FLINCH,
|
||||
CON_FLINCH2,
|
||||
CON_FALL,
|
||||
CON_FORWARD,
|
||||
CON_BACKWARD,
|
||||
CON_UP,
|
||||
CON_DOWN,
|
||||
CON_RIGHT,
|
||||
CON_LEFT,
|
||||
CON_IDLE,
|
||||
CON_UNUSED,
|
||||
CON_UNUSED2,
|
||||
CON_DIE
|
||||
};
|
||||
|
||||
class monster_alien_controller:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
void(void) monster_alien_controller;
|
||||
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_alien_controller::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_controller.die");
|
||||
SetFrame(CON_FLINCH + floor(random(0, 2)));
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_controller::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(CON_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_controller.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_controller::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_controller.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_controller::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(CON_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_controller::monster_alien_controller(void)
|
||||
{
|
||||
Sound_Precache("monster_alien_controller.alert");
|
||||
Sound_Precache("monster_alien_controller.attack");
|
||||
Sound_Precache("monster_alien_controller.die");
|
||||
Sound_Precache("monster_alien_controller.idle");
|
||||
Sound_Precache("monster_alien_controller.pain");
|
||||
netname = "Alien Controller";
|
||||
model = "models/controller.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
153
src/server/monster_alien_grunt.qc
Normal file
153
src/server/monster_alien_grunt.qc
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_alien_grunt (0 0.8 0.8) (-32 -32 0) (32 32 64)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Alien Grunt
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
AG_IDLE,
|
||||
AG_THREAT,
|
||||
AG_WALK,
|
||||
AG_RUN,
|
||||
AG_LEFT,
|
||||
AG_RIGHT,
|
||||
AG_FLINCH,
|
||||
AG_FLINCHBIG,
|
||||
AG_ATTACK,
|
||||
AG_ATTACK2,
|
||||
AG_VICTORYSQUAT,
|
||||
AG_VICTORYEAT,
|
||||
AG_VICTORYSTAND,
|
||||
AG_FLINCHARML,
|
||||
AG_FLINCHLEGL,
|
||||
AG_FLINCHARMR,
|
||||
AG_FLINCHLEGR,
|
||||
AG_SHOOTUP,
|
||||
AG_SHOOTDOWN,
|
||||
AG_SHOOT,
|
||||
AG_SHOOTQUICK,
|
||||
AG_SHOOTLONG,
|
||||
AG_DIEHS,
|
||||
AG_DIEGUT,
|
||||
AG_DIEFORWARD,
|
||||
AG_DIE,
|
||||
AG_DIEBACK,
|
||||
AG_FLOAT,
|
||||
AG_SCARE,
|
||||
AG_OPEN,
|
||||
AG_SMASHRAIL,
|
||||
AG_LAND
|
||||
};
|
||||
|
||||
class monster_alien_grunt:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
void(void) monster_alien_grunt;
|
||||
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_alien_grunt::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_grunt.pain");
|
||||
SetFrame(AG_FLINCH + floor(random(0, 2)));
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_grunt::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
/* headshots == different animation */
|
||||
if (g_dmg_iHitBody == BODY_HEAD) {
|
||||
if (random() < 0.5) {
|
||||
SetFrame(AG_DIEHS);
|
||||
} else {
|
||||
SetFrame(AG_DIEFORWARD);
|
||||
}
|
||||
} else {
|
||||
SetFrame(AG_DIE + floor(random(0, 2)));
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_grunt.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_grunt::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_grunt.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_grunt::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(AG_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_grunt::monster_alien_grunt(void)
|
||||
{
|
||||
Sound_Precache("monster_alien_grunt.alert");
|
||||
Sound_Precache("monster_alien_grunt.attack");
|
||||
Sound_Precache("monster_alien_grunt.die");
|
||||
Sound_Precache("monster_alien_grunt.idle");
|
||||
Sound_Precache("monster_alien_grunt.pain");
|
||||
|
||||
netname = "Alien Grunt";
|
||||
model = "models/agrunt.mdl";
|
||||
base_mins = [-32,-32,0];
|
||||
base_maxs = [32,32,64];
|
||||
base_health = Skill_GetValue("agrunt_health", 90);
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
254
src/server/monster_alien_slave.qc
Normal file
254
src/server/monster_alien_slave.qc
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_alien_slave (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Alien Slave
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
SLV_IDLE,
|
||||
SLV_IDLE2,
|
||||
SLV_IDLE3,
|
||||
SLV_CROUCH,
|
||||
SLV_WALK,
|
||||
SLV_WALK2,
|
||||
SLV_RUN,
|
||||
SLV_RIGHT,
|
||||
SLV_LEFT,
|
||||
SLV_JUMP,
|
||||
SLV_STAIRUP,
|
||||
SLV_ATTACK,
|
||||
SLV_ATTACKZAP,
|
||||
SLV_FLINCH,
|
||||
SLV_FLINCHLA,
|
||||
SLV_FLINCHRA,
|
||||
SLV_FLINCHL,
|
||||
SLV_FLINCHR,
|
||||
SLV_DIEHS,
|
||||
SLV_DIE,
|
||||
SLV_DIEBACK,
|
||||
SLV_DIEFORWARD,
|
||||
SLV_COLLAR,
|
||||
SLV_COLLAR2,
|
||||
SLV_PUSHUP,
|
||||
SLV_GRAB,
|
||||
SLV_UPDOWN,
|
||||
SLV_DOWNUP,
|
||||
SLV_JIBBER,
|
||||
SLV_JABBER
|
||||
};
|
||||
|
||||
class monster_alien_slave:CBaseNPC
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
void(void) monster_alien_slave;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) IdleChat;
|
||||
virtual void(void) Respawn;
|
||||
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
|
||||
virtual int(void) AttackMelee;
|
||||
virtual void(void) AttackFlail;
|
||||
|
||||
virtual int(void) AttackRanged;
|
||||
virtual void(void) AttackBeam;
|
||||
};
|
||||
|
||||
int
|
||||
monster_alien_slave::AnimIdle(void)
|
||||
{
|
||||
return SLV_IDLE;
|
||||
}
|
||||
|
||||
int
|
||||
monster_alien_slave::AnimWalk(void)
|
||||
{
|
||||
return SLV_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_alien_slave::AnimRun(void)
|
||||
{
|
||||
return SLV_RUN;
|
||||
}
|
||||
|
||||
int
|
||||
monster_alien_slave::AttackMelee(void)
|
||||
{
|
||||
/* visual */
|
||||
AnimPlay(SLV_ATTACK);
|
||||
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
|
||||
/* functional */
|
||||
think = AttackFlail;
|
||||
nextthink = 0.25f;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::AttackFlail(void)
|
||||
{
|
||||
traceline(origin, m_eEnemy.origin, FALSE, this);
|
||||
|
||||
if (trace_fraction >= 1.0 || trace_ent.takedamage != DAMAGE_YES) {
|
||||
Sound_Play(this, CHAN_WEAPON, "monster_zombie.attackmiss");
|
||||
return;
|
||||
}
|
||||
|
||||
Damage_Apply(trace_ent, this, 25, 0, 0);
|
||||
Sound_Play(this, CHAN_WEAPON, "monster_zombie.attackhit");
|
||||
}
|
||||
|
||||
int
|
||||
monster_alien_slave::AttackRanged(void)
|
||||
{
|
||||
/* visual */
|
||||
AnimPlay(SLV_ATTACKZAP);
|
||||
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_slave.attack_charge");
|
||||
|
||||
/* functional */
|
||||
think = AttackBeam;
|
||||
nextthink = time + 1.5f;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::AttackBeam(void)
|
||||
{
|
||||
traceline(origin, m_eEnemy.origin, FALSE, this);
|
||||
Sound_Play(this, CHAN_WEAPON, "monster_alien_slave.attack_shoot");
|
||||
|
||||
if (trace_fraction >= 1.0 || trace_ent.takedamage != DAMAGE_YES) {
|
||||
//Sound_Play(this, CHAN_WEAPON, "monster_zombie.attackmiss");
|
||||
return;
|
||||
}
|
||||
|
||||
Damage_Apply(trace_ent, this, 100, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::IdleChat(void)
|
||||
{
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentence(m_talkIdle);
|
||||
|
||||
m_flIdleTime = time + 5.0f + random(0,20);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::Pain(void)
|
||||
{
|
||||
CBaseNPC::Pain();
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_slave.pain");
|
||||
SetFrame(SLV_FLINCH + floor(random(0, 2)));
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
/* headshots == different animation */
|
||||
if (g_dmg_iHitBody == BODY_HEAD) {
|
||||
if (random() < 0.5) {
|
||||
SetFrame(SLV_DIEHS);
|
||||
} else {
|
||||
SetFrame(SLV_DIEBACK);
|
||||
}
|
||||
} else {
|
||||
SetFrame(SLV_DIE + floor(random(0, 3)));
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_alien_slave.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseNPC::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::Respawn(void)
|
||||
{
|
||||
CBaseNPC::Respawn();
|
||||
SetFrame(SLV_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::monster_alien_slave(void)
|
||||
{
|
||||
Sound_Precache("monster_alien_slave.die");
|
||||
Sound_Precache("monster_alien_slave.pain");
|
||||
Sound_Precache("monster_alien_slave.attack_charge");
|
||||
Sound_Precache("monster_alien_slave.attack_shoot");
|
||||
Sound_Precache("monster_zombie.attackhit");
|
||||
Sound_Precache("monster_zombie.attackmiss");
|
||||
|
||||
m_talkAnswer = "";
|
||||
m_talkAsk = "";
|
||||
m_talkAllyShot = "";
|
||||
m_talkGreet = "SLV_ALERT";
|
||||
m_talkIdle = "!SLV_IDLE";
|
||||
m_talkSmelling = "";
|
||||
m_talkStare = "";
|
||||
m_talkSurvived = "";
|
||||
m_talkWounded = "";
|
||||
|
||||
m_talkPlayerAsk = "";
|
||||
m_talkPlayerGreet = "!SLV_ALERT";
|
||||
m_talkPlayerIdle = "";
|
||||
m_talkPlayerWounded1 = "";
|
||||
m_talkPlayerWounded2 = "";
|
||||
m_talkPlayerWounded3 = "";
|
||||
m_talkUnfollow = "";
|
||||
m_talkFollow = "";
|
||||
m_talkStopFollow = "";
|
||||
|
||||
netname = "Alien Slave";
|
||||
model = "models/islave.mdl";
|
||||
base_health = Skill_GetValue("islave_health", 30);
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
m_iAlliance = MAL_ALIEN;
|
||||
CBaseNPC::CBaseNPC();
|
||||
}
|
48
src/server/monster_apache.qc
Normal file
48
src/server/monster_apache.qc
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_apache (0 0.8 0.8) (-300 -300 -172) (300 300 8)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Boeing AH-64 Apache
|
||||
|
||||
*/
|
||||
|
||||
class monster_apache:CBaseMonster
|
||||
{
|
||||
void(void) monster_apache;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void monster_apache::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
movetype = MOVETYPE_NONE;
|
||||
takedamage = DAMAGE_NO;
|
||||
iBleeds = FALSE;
|
||||
setsize(this, [-300,-300,-172], [300, 300, 8]);
|
||||
}
|
||||
|
||||
void monster_apache::monster_apache(void)
|
||||
{
|
||||
netname = "Apache";
|
||||
model = "models/apache.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
base_health = Skill_GetValue("apache_health", 250);
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
34
src/server/monster_babycrab.qc
Normal file
34
src/server/monster_babycrab.qc
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_babycrab (0 0.8 0.8) (-16 -16 0) (16 16 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Baby Headcrab
|
||||
|
||||
*/
|
||||
|
||||
class monster_babycrab:monster_headcrab
|
||||
{
|
||||
void(void) monster_babycrab;
|
||||
};
|
||||
|
||||
void
|
||||
monster_babycrab::monster_babycrab(void)
|
||||
{
|
||||
monster_headcrab::monster_headcrab();
|
||||
}
|
83
src/server/monster_barnacle.qc
Normal file
83
src/server/monster_barnacle.qc
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_barnacle (0 0.8 0.8) (-16 -16 -36) (16 16 0)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Barnacle
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
BCL_IDLE,
|
||||
BCL_IDLE2,
|
||||
BCL_IDLE3,
|
||||
BCL_FLINCH,
|
||||
BCL_ATTACK,
|
||||
BCL_CHEW,
|
||||
BCL_DIE
|
||||
};
|
||||
|
||||
class monster_barnacle:CBaseMonster
|
||||
{
|
||||
void(void) monster_barnacle;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Physics;
|
||||
};
|
||||
|
||||
void
|
||||
monster_barnacle::Physics(void)
|
||||
{
|
||||
movetype = MOVETYPE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barnacle::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(BCL_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_barnacle.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_barnacle::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(BCL_IDLE);
|
||||
}
|
||||
|
||||
void monster_barnacle::monster_barnacle(void)
|
||||
{
|
||||
Sound_Precache("monster_barnacle.attackchew");
|
||||
Sound_Precache("monster_barnacle.attackpull");
|
||||
Sound_Precache("monster_barnacle.die");
|
||||
|
||||
netname = "Barnacle";
|
||||
model = "models/barnacle.mdl";
|
||||
base_mins = [-16,-16,-36];
|
||||
base_maxs = [16,16,0];
|
||||
base_health = Skill_GetValue("barnacle_health", 25);
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
209
src/server/monster_barney.qc
Normal file
209
src/server/monster_barney.qc
Normal file
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_barney (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Barney Calhoun
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
BA_IDLE1,
|
||||
BA_IDLE2,
|
||||
BA_IDLE3,
|
||||
BA_IDLE4,
|
||||
BA_WALK,
|
||||
BA_RUN,
|
||||
BA_SHOOT1,
|
||||
BA_SHOOT2,
|
||||
BA_DRAW,
|
||||
BA_HOLSTER,
|
||||
BA_RELOAD,
|
||||
BA_TURNLEFT,
|
||||
BA_TURNRIGHT,
|
||||
BA_FLINCH_LA,
|
||||
BA_FLINCH_RA,
|
||||
BA_FLINCH_LL,
|
||||
BA_FLINCH_RL,
|
||||
BA_FLINCH_SML
|
||||
};
|
||||
|
||||
class monster_barney:CBaseNPC
|
||||
{
|
||||
void(void) monster_barney;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) OnPlayerUse;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
|
||||
virtual void(void) AttackDraw;
|
||||
virtual void(void) AttackHolster;
|
||||
virtual int(void) AttackMelee;
|
||||
virtual int(void) AttackRanged;
|
||||
};
|
||||
|
||||
int
|
||||
monster_barney::AnimIdle(void)
|
||||
{
|
||||
return BA_IDLE1;
|
||||
}
|
||||
|
||||
int
|
||||
monster_barney::AnimWalk(void)
|
||||
{
|
||||
return BA_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_barney::AnimRun(void)
|
||||
{
|
||||
return BA_RUN;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::AttackDraw(void)
|
||||
{
|
||||
AnimPlay(BA_DRAW);
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::AttackHolster(void)
|
||||
{
|
||||
AnimPlay(BA_HOLSTER);
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
}
|
||||
|
||||
int
|
||||
monster_barney::AttackMelee(void)
|
||||
{
|
||||
return AttackRanged();
|
||||
}
|
||||
|
||||
int
|
||||
monster_barney::AttackRanged(void)
|
||||
{
|
||||
/* visual */
|
||||
AnimPlay(BA_SHOOT1);
|
||||
m_flAttackThink = time + 0.4f;
|
||||
|
||||
/* functional */
|
||||
v_angle = vectoangles(m_eEnemy.origin - origin);
|
||||
TraceAttack_FireBullets(1, origin + [0,0,16], 8, [0.01,0.01], 2);
|
||||
Sound_Play(this, CHAN_WEAPON, "weapon_glock.fire");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::OnPlayerUse(void)
|
||||
{
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
Sentence("!BA_POK");
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseNPC::OnPlayerUse();
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::Pain(void)
|
||||
{
|
||||
CBaseNPC::Pain();
|
||||
|
||||
WarnAllies();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Speak(this, "monster_barney.pain");
|
||||
|
||||
AnimPlay(BA_FLINCH_LA + floor(random(0, 5)));
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
m_iFlags |= MONSTER_FEAR;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::Death(void)
|
||||
{
|
||||
WarnAllies();
|
||||
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(25 + floor(random(0, 6)));
|
||||
Sound_Speak(this, "monster_barney.die");
|
||||
}
|
||||
|
||||
/* now mark our state as 'dead' */
|
||||
CBaseNPC::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::Respawn(void)
|
||||
{
|
||||
CBaseNPC::Respawn();
|
||||
m_iFlags |= MONSTER_CANFOLLOW;
|
||||
PlayerUse = OnPlayerUse;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney::monster_barney(void)
|
||||
{
|
||||
Sound_Precache("monster_barney.die");
|
||||
Sound_Precache("monster_barney.pain");
|
||||
|
||||
/* TODO
|
||||
* BA_MAD - When player gets too naughty
|
||||
* */
|
||||
m_talkAnswer = "!BA_ANSWER";
|
||||
m_talkAsk = "!BA_QUESTION";
|
||||
m_talkAllyShot = "!BA_SHOOT";
|
||||
m_talkGreet = "";
|
||||
m_talkIdle = "!BA_IDLE";
|
||||
m_talkHearing = "!BA_HEAR";
|
||||
m_talkSmelling = "!BA_SMELL";
|
||||
m_talkStare = "!BA_STARE";
|
||||
m_talkSurvived = "!BA_WOUND";
|
||||
m_talkWounded = "!BA_WOUND";
|
||||
|
||||
m_talkPlayerAsk = "!BA_QUESTION";
|
||||
m_talkPlayerGreet = "!BA_HELLO";
|
||||
m_talkPlayerIdle = "!BA_IDLE";
|
||||
m_talkPlayerWounded1 = "!BA_CUREA";
|
||||
m_talkPlayerWounded2 = "!BA_CUREB";
|
||||
m_talkPlayerWounded3 = "!BA_CUREC";
|
||||
m_talkUnfollow = "!BA_WAIT";
|
||||
m_talkFollow = "!BA_OK";
|
||||
m_talkStopFollow = "!BA_STOP";
|
||||
|
||||
model = "models/barney.mdl";
|
||||
netname = "Barney";
|
||||
base_health = Skill_GetValue("barney_health", 35);
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
m_iAlliance = MAL_FRIEND;
|
||||
CBaseNPC::CBaseNPC();
|
||||
}
|
89
src/server/monster_barney_dead.qc
Normal file
89
src/server/monster_barney_dead.qc
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_barney_dead (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Barney's corpse
|
||||
|
||||
*/
|
||||
|
||||
class monster_barney_dead:CBaseEntity
|
||||
{
|
||||
int m_iPose;
|
||||
void(void) monster_barney_dead;
|
||||
|
||||
virtual void(void) Hide;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Gib;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
monster_barney_dead::Gib(void)
|
||||
{
|
||||
takedamage = DAMAGE_NO;
|
||||
FX_GibHuman(this.origin);
|
||||
Hide();
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney_dead::Hide(void)
|
||||
{
|
||||
SetModel("");
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney_dead::Respawn(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
SetOrigin(m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_CORPSE;
|
||||
movetype = MOVETYPE_NONE;
|
||||
SetModel(m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
takedamage = DAMAGE_YES;
|
||||
health = 0;
|
||||
velocity = [0,0,0];
|
||||
iBleeds = TRUE;
|
||||
SetFrame(35 + m_iPose);
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney_dead::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "pose":
|
||||
m_iPose = stoi(strValue);
|
||||
break;
|
||||
default:
|
||||
CBaseMonster::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_barney_dead::monster_barney_dead(void)
|
||||
{
|
||||
model = "models/barney.mdl";
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
132
src/server/monster_bigmomma.qc
Normal file
132
src/server/monster_bigmomma.qc
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_bigmomma (0 0.8 0.8) (-95 -95 0) (95 95 190)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Gonarch
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
GON_IDLE,
|
||||
GON_IDLE2,
|
||||
GON_WALK,
|
||||
GON_RUN,
|
||||
GON_DIE,
|
||||
GON_CLAW,
|
||||
GON_CLAW2,
|
||||
GON_CLAW3,
|
||||
GON_SPAWN,
|
||||
GON_SHOOT,
|
||||
GON_FLINCH,
|
||||
GON_DEFEND,
|
||||
GON_JUMP,
|
||||
GON_ANGRY,
|
||||
GON_ANGRY2,
|
||||
GON_ANGRY3,
|
||||
GON_BREAKWALL,
|
||||
GON_FALL,
|
||||
GON_FALL2,
|
||||
GON_FALLDIE
|
||||
};
|
||||
|
||||
class monster_bigmomma:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_bigmomma;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_bigmomma::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_bigmomma.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_bigmomma::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_bigmomma.pain");
|
||||
SetFrame(GON_FLINCH);
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_bigmomma::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(GON_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_bigmomma.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_bigmomma::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(GON_IDLE);
|
||||
}
|
||||
|
||||
void monster_bigmomma::monster_bigmomma(void)
|
||||
{
|
||||
Sound_Precache("monster_bigmomma.alert");
|
||||
Sound_Precache("monster_bigmomma.attack");
|
||||
Sound_Precache("monster_bigmomma.child");
|
||||
Sound_Precache("monster_bigmomma.die");
|
||||
Sound_Precache("monster_bigmomma.idle");
|
||||
Sound_Precache("monster_bigmomma.pain");
|
||||
Sound_Precache("monster_bigmomma.step");
|
||||
netname = "Gonarch";
|
||||
model = "models/big_mom.mdl";
|
||||
/* health is based on factor, for it's not killable until last stage */
|
||||
base_health = Skill_GetValue("bigmomma_health_factor", 1.5) * 300;
|
||||
base_mins = [-95,-95,0];
|
||||
base_maxs = [95,95,190];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
37
src/server/monster_bloater.qc
Normal file
37
src/server/monster_bloater.qc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_bloater (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Flocking Floater
|
||||
|
||||
*/
|
||||
|
||||
class monster_bloater:CBaseMonster
|
||||
{
|
||||
void(void) monster_bloater;
|
||||
};
|
||||
|
||||
void monster_bloater::monster_bloater(void)
|
||||
{
|
||||
netname = "Floater";
|
||||
model = "models/floater.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
155
src/server/monster_bullchicken.qc
Normal file
155
src/server/monster_bullchicken.qc
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_bullchicken (0 0.8 0.8) (-32 -32 0) (32 32 64)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Bullsquid
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
BULL_WALK,
|
||||
BULL_RUN,
|
||||
BULL_SURPIRSE,
|
||||
BULL_FLINCH,
|
||||
BULL_FLINCH2,
|
||||
BULL_LEFT,
|
||||
BULL_RIGHT,
|
||||
BULL_IDLE,
|
||||
BULL_WHIP,
|
||||
BULL_BITE,
|
||||
BULL_RANGE,
|
||||
BULL_LOOK,
|
||||
BULL_SEECRAB,
|
||||
BULL_EAT,
|
||||
BULL_INSPECT,
|
||||
BULL_SNIFF,
|
||||
BULL_DIE,
|
||||
BULL_DIE2,
|
||||
BULL_JUMP,
|
||||
BULL_DRAGIDLE,
|
||||
BULL_DRAG,
|
||||
BULL_SCARE,
|
||||
BULL_FALLIDLE,
|
||||
BULL_FALL
|
||||
};
|
||||
|
||||
/* the growls are used in combination with the bite sounds
|
||||
* for close range attacks
|
||||
*/
|
||||
|
||||
class monster_bullchicken:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_bullchicken;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
};
|
||||
|
||||
int
|
||||
monster_bullchicken::AnimIdle(void)
|
||||
{
|
||||
return BULL_IDLE;
|
||||
}
|
||||
|
||||
int
|
||||
monster_bullchicken::AnimWalk(void)
|
||||
{
|
||||
return BULL_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_bullchicken::AnimRun(void)
|
||||
{
|
||||
return BULL_RUN;
|
||||
}
|
||||
|
||||
void
|
||||
monster_bullchicken::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_bullchicken.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_bullchicken::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_bullchicken.pain");
|
||||
SetFrame((random() < 0.5) ? BULL_FLINCH : BULL_FLINCH2);
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_bullchicken::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
|
||||
/* two different animations */
|
||||
SetFrame((random() < 0.5) ? BULL_DIE : BULL_DIE2);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_bullchicken.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void monster_bullchicken::monster_bullchicken(void)
|
||||
{
|
||||
Sound_Precache("monster_bullchicken.alert");
|
||||
Sound_Precache("monster_bullchicken.attack");
|
||||
Sound_Precache("monster_bullchicken.attackbite");
|
||||
Sound_Precache("monster_bullchicken.attackshoot");
|
||||
Sound_Precache("monster_bullchicken.die");
|
||||
Sound_Precache("monster_bullchicken.idle");
|
||||
Sound_Precache("monster_bullchicken.pain");
|
||||
netname = "Bullsquid";
|
||||
model = "models/bullsquid.mdl";
|
||||
base_health = Skill_GetValue("bullsquid_health", 40);
|
||||
base_mins = [-32,-32,0];
|
||||
base_maxs = [32,32,64];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
54
src/server/monster_cockroach.qc
Normal file
54
src/server/monster_cockroach.qc
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_cockroach (0 0.8 0.8) (-4 -4 0) (4 4 4)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Cockroach
|
||||
|
||||
*/
|
||||
|
||||
class monster_cockroach:CBaseMonster
|
||||
{
|
||||
void(void) monster_cockroach;
|
||||
virtual void(void) Death;
|
||||
};
|
||||
|
||||
void
|
||||
monster_cockroach::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
Sound_Play(this, CHAN_VOICE, "monster_cockroach.die");
|
||||
}
|
||||
|
||||
/* make sure we gib this thing */
|
||||
health = -100;
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void monster_cockroach::monster_cockroach(void)
|
||||
{
|
||||
Sound_Precache("monster_cockroach.die");
|
||||
netname = "Cockroach";
|
||||
model = "models/roach.mdl";
|
||||
base_mins = [-1,-1,0];
|
||||
base_maxs = [1,1,1];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
37
src/server/monster_flyer_flock.qc
Normal file
37
src/server/monster_flyer_flock.qc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_flyer_flock (0 0.8 0.8) (-16 -16 0) (16 16 16)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Boid
|
||||
|
||||
*/
|
||||
|
||||
class monster_flyer_flock:CBaseMonster
|
||||
{
|
||||
void(void) monster_flyer_flock;
|
||||
};
|
||||
|
||||
void monster_flyer_flock::monster_flyer_flock(void)
|
||||
{
|
||||
netname = "Boid";
|
||||
model = "models/aflock.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,16];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
138
src/server/monster_gargantua.qc
Normal file
138
src/server/monster_gargantua.qc
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_gargantua (0 0.8 0.8) (-32 -32 0) (32 32 128)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Gargantua
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
GARG_IDLE,
|
||||
GARG_IDLE2,
|
||||
GARG_IDLE3,
|
||||
GARG_IDLE4,
|
||||
GARG_WALK,
|
||||
GARG_RUN,
|
||||
GARG_SHOOT,
|
||||
GARG_SHOOT2,
|
||||
GARG_ATTACK,
|
||||
GARG_STOMP,
|
||||
GARG_LEFT,
|
||||
GARG_RIGHT,
|
||||
GARG_FLINCH,
|
||||
GARG_FLINCH2,
|
||||
GARG_DIE,
|
||||
GARG_BITEHEAD,
|
||||
GARG_THROW,
|
||||
GARG_SMASH,
|
||||
GARG_ROLLCAR,
|
||||
GARG_KICKCAR,
|
||||
GARG_PUSHCAR,
|
||||
GARG_BUST
|
||||
};
|
||||
|
||||
class monster_gargantua:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_gargantua;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_gargantua::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_gargantua.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_gargantua::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_gargantua.pain");
|
||||
SetFrame((random() < 0.5) ? GARG_FLINCH : GARG_FLINCH2);
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_gargantua::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(GARG_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_gargantua.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_gargantua::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(GARG_IDLE);
|
||||
/* takes damage from explosives only
|
||||
* takedamage = DAMAGE_NO; */
|
||||
iBleeds = FALSE;
|
||||
}
|
||||
|
||||
void monster_gargantua::monster_gargantua(void)
|
||||
{
|
||||
Sound_Precache("monster_gargantua.alert");
|
||||
Sound_Precache("monster_gargantua.attack");
|
||||
Sound_Precache("monster_gargantua.attackflame");
|
||||
Sound_Precache("monster_gargantua.attackflameon");
|
||||
Sound_Precache("monster_gargantua.attackflameoff");
|
||||
Sound_Precache("monster_gargantua.die");
|
||||
Sound_Precache("monster_gargantua.idle");
|
||||
Sound_Precache("monster_gargantua.pain");
|
||||
Sound_Precache("monster_gargantua.step");
|
||||
netname = "Gargantua";
|
||||
model = "models/garg.mdl";
|
||||
base_health = Skill_GetValue("gargantua_health", 800);
|
||||
base_mins = [-32,-32,0];
|
||||
base_maxs = [32,32,128];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
87
src/server/monster_gman.qc
Normal file
87
src/server/monster_gman.qc
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_gman (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
G-Man
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
GMAN_IDLE,
|
||||
GMAN_IDLETIE,
|
||||
GMAN_IDLELOOK,
|
||||
GMAN_IDLE2,
|
||||
GMAN_OPEN,
|
||||
GMAN_STAND,
|
||||
GMAN_WALK,
|
||||
GMAN_YES,
|
||||
GMAN_NO,
|
||||
GMAN_NOBIG,
|
||||
GMAN_YESBIG,
|
||||
GMAN_LISTEN,
|
||||
GMAN_LOOKDOWN,
|
||||
GMAN_LOOKDOWN2
|
||||
};
|
||||
|
||||
class monster_gman:CBaseMonster
|
||||
{
|
||||
void(void) monster_gman;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
};
|
||||
|
||||
int
|
||||
monster_gman::AnimIdle(void)
|
||||
{
|
||||
return GMAN_IDLE;
|
||||
}
|
||||
|
||||
int
|
||||
monster_gman::AnimWalk(void)
|
||||
{
|
||||
return GMAN_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_gman::AnimRun(void)
|
||||
{
|
||||
return GMAN_WALK;
|
||||
}
|
||||
|
||||
void monster_gman::Respawn(void)
|
||||
{
|
||||
/* he can't die, he's the G-Man! */
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(GMAN_IDLE);
|
||||
takedamage = DAMAGE_NO;
|
||||
iBleeds = FALSE;
|
||||
}
|
||||
|
||||
void monster_gman::monster_gman(void)
|
||||
{
|
||||
netname = "G-Man";
|
||||
model = "models/gman.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
181
src/server/monster_headcrab.qc
Normal file
181
src/server/monster_headcrab.qc
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_headcrab (0 0.8 0.8) (-16 -16 0) (16 16 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Headcrab
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
HC_IDLE1,
|
||||
HC_IDLE2,
|
||||
HC_IDLE3,
|
||||
HC_WALK,
|
||||
HC_RUN,
|
||||
HC_ANGRY,
|
||||
HC_FLINCH,
|
||||
HC_DIE,
|
||||
HC_180_LEFT,
|
||||
HC_180_RIGHT,
|
||||
HC_JUMP,
|
||||
HC_JUMP_VARIATION1,
|
||||
HC_JUMP_VARIATION2,
|
||||
HC_YAW_ADJUSTMENT,
|
||||
HC_HEADCRABBED1,
|
||||
HC_HEADCRABBED2,
|
||||
HC_HEADIDLE,
|
||||
HC_CRASHIDLE,
|
||||
HC_CRASH,
|
||||
HC_STRUGGLEIDLE,
|
||||
HC_STRUGGLE
|
||||
};
|
||||
|
||||
class monster_headcrab:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_headcrab;
|
||||
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
virtual int(void) AttackRanged;
|
||||
virtual void(void) touch;
|
||||
};
|
||||
|
||||
int
|
||||
monster_headcrab::AnimIdle(void)
|
||||
{
|
||||
return HC_IDLE1;
|
||||
}
|
||||
|
||||
int
|
||||
monster_headcrab::AnimWalk(void)
|
||||
{
|
||||
return HC_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_headcrab::AnimRun(void)
|
||||
{
|
||||
return HC_RUN;
|
||||
}
|
||||
|
||||
int
|
||||
monster_headcrab::AttackRanged(void)
|
||||
{
|
||||
/* visual */
|
||||
if (random() < 0.5)
|
||||
AnimPlay(HC_JUMP);
|
||||
else
|
||||
AnimPlay(HC_JUMP_VARIATION1);
|
||||
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
Sound_Play(this, CHAN_VOICE, "monster_headcrab.attack");
|
||||
|
||||
/* functional */
|
||||
makevectors(vectoangles(m_eEnemy.origin - origin));
|
||||
velocity = v_forward * 512 + [0,0,250];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_headcrab::touch(void)
|
||||
{
|
||||
if (other.takedamage == DAMAGE_YES)
|
||||
if (frame == HC_JUMP || frame == HC_JUMP_VARIATION1)
|
||||
Damage_Apply(other, this, 500, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
monster_headcrab::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_headcrab.pain");
|
||||
SetFrame(HC_FLINCH);
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_headcrab::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(HC_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_headcrab.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_headcrab::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_headcrab.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_headcrab::monster_headcrab(void)
|
||||
{
|
||||
Sound_Precache("monster_headcrab.alert");
|
||||
Sound_Precache("monster_headcrab.attack");
|
||||
Sound_Precache("monster_headcrab.attackhit");
|
||||
Sound_Precache("monster_headcrab.die");
|
||||
Sound_Precache("monster_headcrab.idle");
|
||||
Sound_Precache("monster_headcrab.pain");
|
||||
|
||||
if (classname == "monster_babycrab") {
|
||||
netname = "Baby Headcrab";
|
||||
model = "models/baby_headcrab.mdl";
|
||||
base_health = Skill_GetValue ("headcrab_health", 10) /4;
|
||||
} else {
|
||||
netname = "Headcrab";
|
||||
model = "models/headcrab.mdl";
|
||||
base_health = Skill_GetValue("headcrab_health", 10);
|
||||
}
|
||||
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,36];
|
||||
m_iAlliance = MAL_ALIEN;
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
97
src/server/monster_hevsuit_dead.qc
Normal file
97
src/server/monster_hevsuit_dead.qc
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_hevsuit_dead (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
HEV-Suit/Player's corpse
|
||||
|
||||
*/
|
||||
|
||||
class monster_hevsuit_dead:CBaseMonster
|
||||
{
|
||||
int m_iPose;
|
||||
void(void) monster_hevsuit_dead;
|
||||
|
||||
virtual void(void) Hide;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Gib;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
monster_hevsuit_dead::Gib(void)
|
||||
{
|
||||
takedamage = DAMAGE_NO;
|
||||
FX_GibHuman(this.origin);
|
||||
Hide();
|
||||
}
|
||||
|
||||
void
|
||||
monster_hevsuit_dead::Hide(void)
|
||||
{
|
||||
SetModel("");
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_hevsuit_dead::Respawn(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
SetOrigin(m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_CORPSE;
|
||||
movetype = MOVETYPE_NONE;
|
||||
SetModel(m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
takedamage = DAMAGE_YES;
|
||||
health = 0;
|
||||
velocity = [0,0,0];
|
||||
iBleeds = TRUE;
|
||||
SetFrame(73 + m_iPose);
|
||||
SendFlags |= NPC_BODY;
|
||||
}
|
||||
|
||||
void
|
||||
monster_hevsuit_dead::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "pose":
|
||||
m_iPose = stoi(strValue);
|
||||
break;
|
||||
case "body":
|
||||
SetBody(stoi(strValue) + 1);
|
||||
break;
|
||||
case "skin":
|
||||
SetSkin(stoi(strValue));
|
||||
break;
|
||||
default:
|
||||
CBaseMonster::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_hevsuit_dead::monster_hevsuit_dead(void)
|
||||
{
|
||||
model = "models/player.mdl";
|
||||
m_iBody = 2;
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
96
src/server/monster_hgrunt_dead.qc
Normal file
96
src/server/monster_hgrunt_dead.qc
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_hgrunt_dead (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Human Grunt's corpse
|
||||
|
||||
*/
|
||||
|
||||
class monster_hgrunt_dead:CBaseMonster
|
||||
{
|
||||
int m_iPose;
|
||||
void(void) monster_hgrunt_dead;
|
||||
|
||||
virtual void(void) Hide;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Gib;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
monster_hgrunt_dead::Gib(void)
|
||||
{
|
||||
takedamage = DAMAGE_NO;
|
||||
FX_GibHuman(this.origin);
|
||||
Hide();
|
||||
}
|
||||
|
||||
void
|
||||
monster_hgrunt_dead::Hide(void)
|
||||
{
|
||||
SetModel("");
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_hgrunt_dead::Respawn(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
SetOrigin(m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_CORPSE;
|
||||
movetype = MOVETYPE_NONE;
|
||||
SetModel(m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
takedamage = DAMAGE_YES;
|
||||
health = 0;
|
||||
velocity = [0,0,0];
|
||||
iBleeds = TRUE;
|
||||
SetFrame(44 + m_iPose);
|
||||
SendFlags |= NPC_BODY;
|
||||
}
|
||||
|
||||
void
|
||||
monster_hgrunt_dead::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "pose":
|
||||
m_iPose = stoi(strValue);
|
||||
break;
|
||||
case "body":
|
||||
m_iBody = stoi(strValue) + 1;
|
||||
break;
|
||||
case "skin":
|
||||
skin = stoi(strValue);
|
||||
break;
|
||||
default:
|
||||
CBaseMonster::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_hgrunt_dead::monster_hgrunt_dead(void)
|
||||
{
|
||||
model = "models/hgrunt.mdl";
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
202
src/server/monster_houndeye.qc
Normal file
202
src/server/monster_houndeye.qc
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_houndeye (0 0.8 0.8) (-16 -16 0) (16 16 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Houndeye
|
||||
|
||||
*/
|
||||
|
||||
#define HE_BLAST_RADIUS 384
|
||||
|
||||
enum
|
||||
{
|
||||
HE_IDLE,
|
||||
HE_IDLE2,
|
||||
HE_IDLE3,
|
||||
HE_RUN,
|
||||
HE_RUN2,
|
||||
HE_RUN3,
|
||||
HE_DIE,
|
||||
HE_DIE2,
|
||||
HE_DIE3,
|
||||
HE_DIE4,
|
||||
HE_ATTACK,
|
||||
HE_FLINCH,
|
||||
HE_FLINCH2,
|
||||
HE_DIE5,
|
||||
HE_WALKLIMP,
|
||||
HE_WALK2,
|
||||
HE_LEADERLOOK,
|
||||
HE_SLEEP,
|
||||
HE_GOTOSLEEP,
|
||||
HE_WAKE,
|
||||
HE_IDLEMAD,
|
||||
HE_IDLEMAD2,
|
||||
HE_IDLEMAD3,
|
||||
HE_INSPECT,
|
||||
HE_EAT,
|
||||
HE_LEFT,
|
||||
HE_RIGHT,
|
||||
HE_JUMPBACK,
|
||||
HE_WAKEFAST,
|
||||
HE_WHIMPER,
|
||||
HE_JUMPWINDOW
|
||||
};
|
||||
|
||||
class monster_houndeye:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_houndeye;
|
||||
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
|
||||
virtual int(void) AttackMelee;
|
||||
virtual void(void) AttackBlast;
|
||||
};
|
||||
|
||||
int
|
||||
monster_houndeye::AttackMelee(void)
|
||||
{
|
||||
AnimPlay(HE_ATTACK);
|
||||
Sound_Play(this, CHAN_WEAPON, "monster_houndeye.attack");
|
||||
m_flAttackThink = m_flAnimTime + 0.5f;
|
||||
|
||||
think = AttackBlast;
|
||||
nextthink = m_flAnimTime;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_houndeye::AttackBlast(void)
|
||||
{
|
||||
float new_dmg;
|
||||
float dist;
|
||||
float diff;
|
||||
vector pos;
|
||||
float dmg = 50; /* TODO: set proper damage */
|
||||
|
||||
for (entity e = world; (e = findfloat(e, ::takedamage, DAMAGE_YES));) {
|
||||
pos[0] = e.absmin[0] + (0.5 * (e.absmax[0] - e.absmin[0]));
|
||||
pos[1] = e.absmin[1] + (0.5 * (e.absmax[1] - e.absmin[1]));
|
||||
pos[2] = e.absmin[2] + (0.5 * (e.absmax[2] - e.absmin[2]));
|
||||
|
||||
if (e.classname == "monster_houndeye")
|
||||
continue;
|
||||
|
||||
/* don't bother if it's not anywhere near us */
|
||||
dist = vlen(origin - pos);
|
||||
if (dist > HE_BLAST_RADIUS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* can we physically hit this thing? */
|
||||
other = world;
|
||||
traceline(e.origin, origin, MOVE_OTHERONLY, this);
|
||||
|
||||
if (trace_fraction < 1.0f)
|
||||
dmg *= 0.5f;
|
||||
|
||||
/* calculate new damage values */
|
||||
diff = vlen(origin - pos);
|
||||
diff = (HE_BLAST_RADIUS - diff) / HE_BLAST_RADIUS;
|
||||
new_dmg = rint(dmg * diff);
|
||||
|
||||
if (diff > 0) {
|
||||
Damage_Apply(e, this, new_dmg, 0, DMG_EXPLODE);
|
||||
}
|
||||
}
|
||||
Sound_Play(this, CHAN_WEAPON, "monster_houndeye.blast");
|
||||
}
|
||||
|
||||
void
|
||||
monster_houndeye::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_houndeye.pain");
|
||||
SetFrame(HE_FLINCH + floor(random(0, 2)));
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_houndeye::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(HE_DIE + floor(random(0, 4)));
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_houndeye.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_houndeye::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_houndeye.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_houndeye::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(HE_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
monster_houndeye::monster_houndeye(void)
|
||||
{
|
||||
Sound_Precache("monster_houndeye.alert");
|
||||
Sound_Precache("monster_houndeye.attack");
|
||||
Sound_Precache("monster_houndeye.blast");
|
||||
Sound_Precache("monster_houndeye.die");
|
||||
Sound_Precache("monster_houndeye.idle");
|
||||
Sound_Precache("monster_houndeye.pain");
|
||||
netname = "Houndeye";
|
||||
model = "models/houndeye.mdl";
|
||||
base_health = Skill_GetValue("houndeye_health", 20);
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,36];
|
||||
m_iAlliance = MAL_ALIEN;
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
94
src/server/monster_human_assassin.qc
Normal file
94
src/server/monster_human_assassin.qc
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_human_assassin (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Black Ops - Assassin
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
HAS_IDLE,
|
||||
HAS_IDLE3,
|
||||
HAS_IDLE2,
|
||||
HAS_RUN,
|
||||
HAS_WALK,
|
||||
HAS_SHOOT,
|
||||
HAS_NADETHROW,
|
||||
HAS_KICK,
|
||||
HAS_KICK2,
|
||||
HAS_DIERUN,
|
||||
HAS_DIEBACK,
|
||||
HAS_DIE,
|
||||
HAS_JUMP,
|
||||
HAS_UP,
|
||||
HAS_UNUSED,
|
||||
HAS_ATTACKDOWN,
|
||||
HAS_LAND
|
||||
};
|
||||
|
||||
class monster_human_assassin:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_human_assassin;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_human_assassin::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
/* headshots == different animation */
|
||||
/* this animation may not have been used, but it looks cool */
|
||||
if (g_dmg_iHitBody == BODY_HEAD) {
|
||||
if (random() < 0.5) {
|
||||
SetFrame(HAS_DIERUN);
|
||||
} else {
|
||||
SetFrame(HAS_DIEBACK);
|
||||
}
|
||||
} else {
|
||||
SetFrame(HAS_DIE);
|
||||
}
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_assassin::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
frame = HAS_IDLE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_assassin::monster_human_assassin(void)
|
||||
{
|
||||
netname = "Assassin";
|
||||
model = "models/hassassin.mdl";
|
||||
base_health = Skill_GetValue("hassassin_health", 50);
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
319
src/server/monster_human_grunt.qc
Normal file
319
src/server/monster_human_grunt.qc
Normal file
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_human_grunt (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
HECU - Human Grunt
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
GR_WALK,
|
||||
GR_RUN,
|
||||
GR_VICTORYDANCE,
|
||||
GR_COWER,
|
||||
GR_FLINCH,
|
||||
GR_LEFTLEGFLINCH,
|
||||
GR_RIGHTLEGFLINCH,
|
||||
GR_RIGHTARMFLINCH,
|
||||
GR_LEFTARMFLINCH,
|
||||
GR_LAUNCHNADE,
|
||||
GR_THROWNADE,
|
||||
GR_IDLE,
|
||||
GR_IDLE2,
|
||||
GR_COMBATIDLE,
|
||||
GR_FRONTKICK,
|
||||
GR_CROUCHIDLE,
|
||||
GR_CROUCHWAIT,
|
||||
GR_CROUCHSHOOTMP5,
|
||||
GR_STANDSHOOTMP5,
|
||||
GR_RELOADMP5,
|
||||
GR_CROUCHSHOOTSG,
|
||||
GR_STANDSHOOTSG,
|
||||
GR_RELOADSG,
|
||||
GR_SIGNALADV,
|
||||
GR_SIGNALFLANK,
|
||||
GR_SIGNALRETREAT,
|
||||
GR_DROPNADE,
|
||||
GR_LIMPWALK,
|
||||
GR_LIMPRUN,
|
||||
GR_TURNLEFT,
|
||||
GR_TURNRIGHT,
|
||||
GR_STRAFELEFT,
|
||||
GR_STRAFERIGHT,
|
||||
GR_DIEBACK,
|
||||
GR_DIEFORWARD,
|
||||
GR_DIE,
|
||||
GR_DIEBACK2,
|
||||
GR_DIEHS,
|
||||
GR_DIEGUT,
|
||||
GR_BARNACLE1,
|
||||
GR_BARNACLE2,
|
||||
GR_BARNACLE3,
|
||||
GR_BARNACLE4,
|
||||
GR_DEADSTOMACH,
|
||||
GR_DEADSTOMACH2,
|
||||
GR_DEADSIDE,
|
||||
GR_DEADSITTING,
|
||||
GR_REPELJUMP,
|
||||
GR_REPEL,
|
||||
GR_REPELSHOOT,
|
||||
GR_REPELLAND,
|
||||
GR_REPELDIE,
|
||||
GR_DRAGHOLEIDLE,
|
||||
GR_DRAGHOLE,
|
||||
GR_BUSTWALL,
|
||||
GR_HOPRAIL,
|
||||
GR_CONVERSE1,
|
||||
GR_CONVERSE2,
|
||||
GR_STARTLELEFT,
|
||||
GR_STRRTLERIGHT,
|
||||
GR_DIVE,
|
||||
GR_DEFUSE,
|
||||
GR_CORNER1,
|
||||
GR_CORNER2,
|
||||
GR_STONETOSS,
|
||||
GR_CLIFFDIE,
|
||||
GR_DIVESIDEIDLE,
|
||||
GR_DIVESIDE,
|
||||
GR_DIVEKNEELIDLE,
|
||||
GR_DIVEKNEEL,
|
||||
GR_WMBUTTON,
|
||||
GR_WM,
|
||||
GR_WMJUMP,
|
||||
GR_BUSTWINDOW,
|
||||
GR_DRAGLEFT,
|
||||
GR_DRAGRIGHT,
|
||||
GR_TRACKWAVE,
|
||||
GR_TRACKDIVE,
|
||||
GR_FLYBACK,
|
||||
GR_IMPALED,
|
||||
GR_JUMPTRACKS,
|
||||
GR_THROWPIPE,
|
||||
GR_PLUNGER
|
||||
};
|
||||
|
||||
class monster_human_grunt:CBaseNPC
|
||||
{
|
||||
float m_flIdleTime;
|
||||
int m_iMP5Burst;
|
||||
|
||||
void(void) monster_human_grunt;
|
||||
|
||||
virtual void(void) Scream;
|
||||
virtual void(void) IdleChat;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
|
||||
virtual int(void) AttackRanged;
|
||||
virtual int(void) AttackMelee;
|
||||
virtual void(void) AttackKick;
|
||||
|
||||
};
|
||||
|
||||
int
|
||||
monster_human_grunt::AnimIdle(void)
|
||||
{
|
||||
return GR_IDLE;
|
||||
}
|
||||
|
||||
int
|
||||
monster_human_grunt::AnimWalk(void)
|
||||
{
|
||||
return GR_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_human_grunt::AnimRun(void)
|
||||
{
|
||||
return GR_RUN;
|
||||
}
|
||||
|
||||
int
|
||||
monster_human_grunt::AttackMelee(void)
|
||||
{
|
||||
/* visual */
|
||||
AnimPlay(GR_FRONTKICK);
|
||||
|
||||
m_flAttackThink = m_flAnimTime;
|
||||
Sound_Play(this, CHAN_VOICE, "monster_zombie.attack");
|
||||
|
||||
/* functional */
|
||||
think = AttackKick;
|
||||
nextthink = 0.25f;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::AttackKick(void)
|
||||
{
|
||||
traceline(origin, m_eEnemy.origin, FALSE, this);
|
||||
|
||||
if (trace_fraction >= 1.0 || trace_ent.takedamage != DAMAGE_YES) {
|
||||
//Sound_Play(this, CHAN_WEAPON, "monster_zombie.attackmiss");
|
||||
return;
|
||||
}
|
||||
|
||||
Damage_Apply(trace_ent, this, 25, 0, 0);
|
||||
//Sound_Play(this, CHAN_WEAPON, "monster_zombie.attackhit");
|
||||
}
|
||||
|
||||
int
|
||||
monster_human_grunt::AttackRanged(void)
|
||||
{
|
||||
/* visual */
|
||||
AnimPlay(GR_STANDSHOOTMP5);
|
||||
Sound_Play(this, CHAN_WEAPON, "weapon_mp5.shoot");
|
||||
|
||||
if (m_iMP5Burst >= 2) {
|
||||
m_iMP5Burst = 0;
|
||||
m_flAttackThink = time + 0.4f;
|
||||
} else {
|
||||
m_iMP5Burst++;
|
||||
m_flAttackThink = time + 0.1f;
|
||||
}
|
||||
|
||||
/* functional */
|
||||
v_angle = vectoangles(m_eEnemy.origin - origin);
|
||||
TraceAttack_FireBullets(1, origin + [0,0,16], 8, [0.01,0.01], 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void monster_human_grunt::Scream(void)
|
||||
{
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentence(m_talkAllyShot);
|
||||
m_flIdleTime = time + 5.0f;
|
||||
}
|
||||
|
||||
void monster_human_grunt::IdleChat(void)
|
||||
{
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentence(m_talkIdle);
|
||||
|
||||
/* Sentence(m_talkPlayerIdle); */
|
||||
/* come up with logic to make them repsone to questions
|
||||
* Sentence(m_talkAsk);
|
||||
* Sentence(m_talkAnswer);
|
||||
*/
|
||||
m_flIdleTime = time + 5.0f + random(0,20);
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_human_grunt.pain");
|
||||
SetFrame(GR_FLINCH);
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
/* headshots == different animation */
|
||||
/* this animation may not have been used, but it looks cool */
|
||||
if (g_dmg_iHitBody == BODY_HEAD) {
|
||||
if (random() < 0.5) {
|
||||
SetFrame(GR_DIEHS);
|
||||
} else {
|
||||
SetFrame(GR_DIEBACK);
|
||||
}
|
||||
} else {
|
||||
SetFrame(GR_DIE);
|
||||
}
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_human_grunt.die");
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(GR_IDLE);
|
||||
}
|
||||
|
||||
|
||||
void monster_human_grunt::monster_human_grunt(void)
|
||||
{
|
||||
Sound_Precache("monster_human_grunt.die");
|
||||
Sound_Precache("monster_human_grunt.pain");
|
||||
|
||||
/* Adding some into other slots in hopes it feels right
|
||||
* listed below are other setences that might need their own:
|
||||
* !HG_MONST - Monster HG_ALERT
|
||||
* !HG_GREN - Grenade toss
|
||||
* !HG_CHECK - Sector check question
|
||||
* !HG_CLEAR - Sector clear response */
|
||||
|
||||
m_talkAnswer = "!HG_ANSWER";
|
||||
m_talkAsk = "!HG_QUEST";
|
||||
m_talkAllyShot = "!HG_COVER";
|
||||
m_talkGreet = "";
|
||||
m_talkIdle = "!HG_IDLE";
|
||||
m_talkSmelling = "";
|
||||
m_talkStare = "";
|
||||
m_talkSurvived = "!HG_CLEAR";
|
||||
m_talkWounded = "!HG_CHECK";
|
||||
|
||||
m_talkPlayerAsk = "";
|
||||
m_talkPlayerGreet = "!HG_ALERT";
|
||||
m_talkPlayerIdle = "!HG_CHARGE";
|
||||
m_talkPlayerWounded1 = "";
|
||||
m_talkPlayerWounded2 = "";
|
||||
m_talkPlayerWounded3 = "";
|
||||
m_talkUnfollow = "";
|
||||
m_talkFollow = "";
|
||||
m_talkStopFollow = "";
|
||||
|
||||
|
||||
netname = "Grunt";
|
||||
model = "models/hgrunt.mdl";
|
||||
base_health = Skill_GetValue("hgrunt_health", 50);
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
m_iAlliance = MAL_ENEMY;
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
137
src/server/monster_ichthyosaur.qc
Normal file
137
src/server/monster_ichthyosaur.qc
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_ichthyosaur (0 0.8 0.8) (-32 -32 0) (32 32 64)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Ichthyosaur
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
ICHY_IDLE,
|
||||
ICHY_SWIM,
|
||||
ICHY_THRUST,
|
||||
ICHY_DIE1,
|
||||
ICHY_DIE2,
|
||||
ICHY_FLINCH,
|
||||
ICHY_FLINCH2,
|
||||
ICHY_DIE3,
|
||||
ICHY_BITER,
|
||||
ICHY_BITEL,
|
||||
ICHY_ATTACK,
|
||||
ICHY_RIGHT,
|
||||
ICHY_LEFT,
|
||||
ICHY_180,
|
||||
ICHY_HITCAGE,
|
||||
ICHY_JUMP
|
||||
};
|
||||
|
||||
class monster_ichthyosaur:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_ichthyosaur;
|
||||
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_ichthyosaur::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_ichthyosaur.pain");
|
||||
SetFrame(ICHY_FLINCH + floor(random(0, 2)));
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_ichthyosaur::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
int r = floor(random(0,3));
|
||||
|
||||
switch (r) {
|
||||
case 1:
|
||||
SetFrame(ICHY_DIE2);
|
||||
break;
|
||||
case 2:
|
||||
SetFrame(ICHY_DIE3);
|
||||
break;
|
||||
default:
|
||||
SetFrame(ICHY_DIE1);
|
||||
break;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_ichthyosaur.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_ichthyosaur::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_ichthyosaur.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_ichthyosaur::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(ICHY_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
monster_ichthyosaur::monster_ichthyosaur(void)
|
||||
{
|
||||
Sound_Precache("monster_ichthyosaur.alert");
|
||||
Sound_Precache("monster_ichthyosaur.attack");
|
||||
Sound_Precache("monster_ichthyosaur.die");
|
||||
Sound_Precache("monster_ichthyosaur.idle");
|
||||
Sound_Precache("monster_ichthyosaur.pain");
|
||||
netname = "Ichthyosaur";
|
||||
model = "models/icky.mdl";
|
||||
base_mins = [-32,-32,0];
|
||||
base_maxs = [32,32,64];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
84
src/server/monster_leech.qc
Normal file
84
src/server/monster_leech.qc
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_leech (0 0.8 0.8) (-6 -6 0) (6 6 6)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Leech
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
LEECH_SWIM,
|
||||
LEECH_SWIM2,
|
||||
LEECH_ATTACK,
|
||||
LEECH_HOVER,
|
||||
LEECH_LEFT,
|
||||
LEECH_RIGHT,
|
||||
LEECH_DIE,
|
||||
LEECH_DIEEND
|
||||
};
|
||||
|
||||
class monster_leech:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_leech;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) DeathEnd;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_leech::DeathEnd(void)
|
||||
{
|
||||
SetFrame(LEECH_DIEEND);
|
||||
}
|
||||
|
||||
void
|
||||
monster_leech::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(LEECH_DIE);
|
||||
think = DeathEnd;
|
||||
nextthink = time + 1.0f;
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_leech::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(LEECH_SWIM);
|
||||
}
|
||||
|
||||
void monster_leech::monster_leech(void)
|
||||
{
|
||||
Sound_Precache("monster_leech.alert");
|
||||
Sound_Precache("monster_leech.attack");
|
||||
netname = "Leech";
|
||||
model = "models/leech.mdl";
|
||||
base_mins = [-6,-6,0];
|
||||
base_maxs = [6,6,6];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
47
src/server/monster_miniturret.qc
Normal file
47
src/server/monster_miniturret.qc
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_miniturret (0 0.8 0.8) (-16 -16 -32) (16 16 32)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Automatic Turret (small)
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
TUR_IDLE,
|
||||
TUR_FIRE,
|
||||
TUR_SPIN,
|
||||
TUR_DEPLOY,
|
||||
TUR_RETIRE,
|
||||
TUR_DIE
|
||||
};
|
||||
|
||||
class monster_miniturret:CBaseMonster
|
||||
{
|
||||
void(void) monster_miniturret;
|
||||
};
|
||||
|
||||
void monster_miniturret::monster_miniturret(void)
|
||||
{
|
||||
netname = "Mini-Turret";
|
||||
model = "models/miniturret.mdl";
|
||||
base_mins = [-16,-16,-32];
|
||||
base_maxs = [16,16,32];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
134
src/server/monster_nihilanth.qc
Normal file
134
src/server/monster_nihilanth.qc
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_nihilanth (0 0.8 0.8) (-192 -192 0) (192 192 384)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Nihilanth
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
NIL_IDLE,
|
||||
NIL_ATTACK,
|
||||
NIL_ATTACK2,
|
||||
NIL_THROW,
|
||||
NIL_BLOCK,
|
||||
NIL_RECHARGE,
|
||||
NIL_IDLEOPEN,
|
||||
NIL_ATTACKOPEN,
|
||||
NIL_ATTACKOPEN2,
|
||||
NIL_FLINCH,
|
||||
NIL_FLINCH2,
|
||||
NIL_FALL,
|
||||
NIL_DIE,
|
||||
NIL_FORWARD,
|
||||
NIL_BACK,
|
||||
NIL_UP,
|
||||
NIL_DOWN,
|
||||
NIL_RIGHT,
|
||||
NIL_LEFT,
|
||||
NIL_WALK2,
|
||||
NIL_SHOOT
|
||||
};
|
||||
|
||||
class monster_nihilanth:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_nihilanth;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_nihilanth::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_nihilanth.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_nihilanth::Pain(void)
|
||||
{
|
||||
CBaseMonster::Pain();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_nihilanth.pain");
|
||||
|
||||
SetFrame((random() < 0.5) ? NIL_FLINCH : NIL_FLINCH2);
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_nihilanth::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(NIL_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_nihilanth.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_nihilanth::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(NIL_IDLE);
|
||||
}
|
||||
|
||||
void monster_nihilanth::monster_nihilanth(void)
|
||||
{
|
||||
Sound_Precache("monster_nihilanth.attack");
|
||||
Sound_Precache("monster_nihilanth.attackball");
|
||||
Sound_Precache("monster_nihilanth.attackballmove");
|
||||
Sound_Precache("monster_nihilanth.die");
|
||||
Sound_Precache("monster_nihilanth.idle");
|
||||
Sound_Precache("monster_nihilanth.pain");
|
||||
Sound_Precache("monster_nihilanth.recharge");
|
||||
netname = "Nihilanth";
|
||||
model = "models/nihilanth.mdl";
|
||||
base_health = Skill_GetValue("nihilanth_health", 800);
|
||||
base_mins = [-192,-192,-32];
|
||||
base_maxs = [192,192,384];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
45
src/server/monster_osprey.qc
Normal file
45
src/server/monster_osprey.qc
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_osprey (0 0.8 0.8) (-480 -480 -112) (480 480 24)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Bell Boeing VV-22 Osprey
|
||||
|
||||
*/
|
||||
|
||||
class monster_osprey:CBaseMonster
|
||||
{
|
||||
void(void) monster_osprey;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void monster_osprey::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
takedamage = DAMAGE_NO;
|
||||
iBleeds = FALSE;
|
||||
}
|
||||
|
||||
void monster_osprey::monster_osprey(void)
|
||||
{
|
||||
netname = "Osprey";
|
||||
model = "models/osprey.mdl";
|
||||
base_mins = [-480,-480,-112];
|
||||
base_maxs = [480,480,24];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
37
src/server/monster_rat.qc
Normal file
37
src/server/monster_rat.qc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_rat (0 0.8 0.8) (-6 -6 0) (6 6 6)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Rat
|
||||
|
||||
*/
|
||||
|
||||
class monster_rat:CBaseMonster
|
||||
{
|
||||
void(void) monster_rat;
|
||||
};
|
||||
|
||||
void monster_rat::monster_rat(void)
|
||||
{
|
||||
netname = "Rat";
|
||||
model = "models/bigrat.mdl";
|
||||
base_mins = [-6,-6,-0];
|
||||
base_maxs = [6,6,6];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
236
src/server/monster_scientist.qc
Normal file
236
src/server/monster_scientist.qc
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_scientist (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Scientist
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
SCIA_WALK,
|
||||
SCIA_WALKSCARED,
|
||||
SCIA_RUN,
|
||||
SCIA_RUNSCARED,
|
||||
SCIA_RUNLOOK,
|
||||
SCIA_180LEFT,
|
||||
SCIA_180RIGHT,
|
||||
SCIA_FLINCH,
|
||||
SCIA_PAIN,
|
||||
SCIA_PAINLEFT,
|
||||
SCIA_PAINRIGHT,
|
||||
SCIA_PAINLEGLEFT,
|
||||
SCIA_PAINLEGRIGHT,
|
||||
SCIA_IDLE1,
|
||||
SCIA_IDLE2,
|
||||
SCIA_IDLE3,
|
||||
SCIA_IDLE4,
|
||||
SCIA_IDLE5,
|
||||
SCIA_IDLE6,
|
||||
SCIA_SCARED_END,
|
||||
SCIA_SCARED1,
|
||||
SCIA_SCARED2,
|
||||
SCIA_SCARED3,
|
||||
SCIA_SCARED4,
|
||||
SCIA_PANIC,
|
||||
SCIA_FEAR1,
|
||||
SCIA_FEAR2,
|
||||
SCIA_CRY,
|
||||
SCIA_SCI1,
|
||||
SCIA_SCI2,
|
||||
SCIA_SCI3,
|
||||
SCIA_DIE_SIMPLE,
|
||||
SCIA_DIE_FORWARD1,
|
||||
SCIA_DIE_FORWARD2,
|
||||
SCIA_DIE_BACKWARD,
|
||||
SCIA_DIE_HEADSHOT,
|
||||
SCIA_DIE_GUTSHOT,
|
||||
SCIA_LYING1,
|
||||
SCIA_LYING2,
|
||||
SCIA_DEADSIT,
|
||||
SCIA_DEADTABLE1,
|
||||
SCIA_DEADTABLE2,
|
||||
SCIA_DEADTABLE3
|
||||
};
|
||||
|
||||
class monster_scientist:CBaseNPC
|
||||
{
|
||||
void(void) monster_scientist;
|
||||
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) OnPlayerUse;
|
||||
virtual void(void) Pain;
|
||||
virtual void(void) Death;
|
||||
virtual int(void) AnimIdle;
|
||||
virtual int(void) AnimWalk;
|
||||
virtual int(void) AnimRun;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
int
|
||||
monster_scientist::AnimIdle(void)
|
||||
{
|
||||
return SCIA_IDLE1;
|
||||
}
|
||||
|
||||
int
|
||||
monster_scientist::AnimWalk(void)
|
||||
{
|
||||
return SCIA_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_scientist::AnimRun(void)
|
||||
{
|
||||
return SCIA_RUN;
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::OnPlayerUse(void)
|
||||
{
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
Sentence("!SC_POK");
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseNPC::OnPlayerUse();
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::Pain(void)
|
||||
{
|
||||
WarnAllies();
|
||||
|
||||
if (m_flAnimTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sound_Speak(this, "monster_scientist.pain");
|
||||
|
||||
frame = SCIA_FLINCH + floor(random(0, 6));
|
||||
m_iFlags |= MONSTER_FEAR;
|
||||
m_flAnimTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::Death(void)
|
||||
{
|
||||
WarnAllies();
|
||||
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
|
||||
Sound_Speak(this, "monster_scientist.die");
|
||||
}
|
||||
|
||||
/* now mark our state as 'dead' */
|
||||
CBaseNPC::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::Respawn(void)
|
||||
{
|
||||
CBaseNPC::Respawn();
|
||||
m_iFlags |= MONSTER_CANFOLLOW;
|
||||
PlayerUse = OnPlayerUse;
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "body":
|
||||
SetBody(stoi(strValue) + 1);
|
||||
break;
|
||||
default:
|
||||
CBaseEntity::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::monster_scientist(void)
|
||||
{
|
||||
Sound_Precache("monster_scientist.die");
|
||||
Sound_Precache("monster_scientist.pain");
|
||||
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
m_talkAsk = "";
|
||||
m_talkPlayerAsk = "!SC_PQUEST";
|
||||
m_talkPlayerGreet = "!SC_PHELLO";
|
||||
m_talkPlayerIdle = "!SC_PIDLE";
|
||||
} else {
|
||||
m_talkAsk = "!SC_QUESTION";
|
||||
m_talkPlayerAsk = "!SC_QUESTION";
|
||||
m_talkPlayerGreet = "!SC_HELLO";
|
||||
m_talkPlayerIdle = "!SC_PIDLE";
|
||||
}
|
||||
|
||||
m_talkAnswer = "!SC_ANSWER";
|
||||
m_talkAllyShot = "!SC_PLFEAR";
|
||||
m_talkGreet = "";
|
||||
m_talkIdle = "!SC_IDLE";
|
||||
m_talkHearing = "!SC_HEAR";
|
||||
m_talkSmelling = "!SC_SMELL";
|
||||
m_talkStare = "!SC_STARE";
|
||||
m_talkSurvived = "!SC_WOUND";
|
||||
m_talkWounded = "!SC_MORTAL";
|
||||
|
||||
/* they seem to use predisaster lines regardless of disaster state */
|
||||
m_talkPlayerWounded1 = "!SC_CUREA";
|
||||
m_talkPlayerWounded2 = "!SC_CUREB";
|
||||
m_talkPlayerWounded3 = "!SC_CUREC";
|
||||
m_talkUnfollow = "!SC_WAIT";
|
||||
m_talkFollow = "!SC_OK";
|
||||
m_talkStopFollow = "!SC_STOP";
|
||||
m_iBody = -1;
|
||||
|
||||
model = "models/scientist.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
base_health = Skill_GetValue("scientist_health", 20);
|
||||
|
||||
CBaseNPC::CBaseNPC();
|
||||
|
||||
/* has the body not been overriden, etc. choose a character for us */
|
||||
if (m_iBody == -1) {
|
||||
SetBody((int)floor(random(1,5)));
|
||||
}
|
||||
|
||||
switch (m_iBody) {
|
||||
case 1:
|
||||
m_flPitch = 105;
|
||||
netname = "Walter";
|
||||
break;
|
||||
case 2:
|
||||
m_flPitch = 100;
|
||||
netname = "Einstein";
|
||||
break;
|
||||
case 3:
|
||||
m_flPitch = 95;
|
||||
netname = "Luther";
|
||||
SetSkin(1);
|
||||
break;
|
||||
default:
|
||||
m_flPitch = 100;
|
||||
netname = "Slick";
|
||||
}
|
||||
}
|
131
src/server/monster_scientist_dead.qc
Normal file
131
src/server/monster_scientist_dead.qc
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_scientist_dead (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Scientists' corpse
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
DSCIA_LYING1 = 37,
|
||||
DSCIA_LYING2,
|
||||
DSCIA_DEADSIT,
|
||||
DSCIA_DEADTABLE1,
|
||||
DSCIA_DEADTABLE2,
|
||||
DSCIA_DEADTABLE3,
|
||||
DSCIA_DEADHANG
|
||||
};
|
||||
|
||||
class monster_scientist_dead:CBaseMonster
|
||||
{
|
||||
int m_iPose;
|
||||
void(void) monster_scientist_dead;
|
||||
|
||||
virtual void(void) Hide;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Gib;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
monster_scientist_dead::Gib(void)
|
||||
{
|
||||
takedamage = DAMAGE_NO;
|
||||
FX_GibHuman(this.origin);
|
||||
Hide();
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist_dead::Hide(void)
|
||||
{
|
||||
SetModel("");
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist_dead::Respawn(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
SetOrigin(m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_CORPSE;
|
||||
movetype = MOVETYPE_NONE;
|
||||
SetModel(m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
takedamage = DAMAGE_YES;
|
||||
health = 0;
|
||||
velocity = [0,0,0];
|
||||
iBleeds = TRUE;
|
||||
SendFlags |= NPC_BODY;
|
||||
|
||||
switch (m_iPose) {
|
||||
case 1:
|
||||
SetFrame(DSCIA_LYING2);
|
||||
break;
|
||||
case 2:
|
||||
SetFrame(DSCIA_DEADSIT);
|
||||
break;
|
||||
case 3:
|
||||
SetFrame(DSCIA_DEADHANG);
|
||||
break;
|
||||
case 4:
|
||||
SetFrame(DSCIA_DEADTABLE1);
|
||||
break;
|
||||
case 5:
|
||||
SetFrame(DSCIA_DEADTABLE2);
|
||||
break;
|
||||
case 6:
|
||||
SetFrame(DSCIA_DEADTABLE3);
|
||||
break;
|
||||
default:
|
||||
SetFrame(DSCIA_LYING1);
|
||||
}
|
||||
|
||||
droptofloor();
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist_dead::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "pose":
|
||||
m_iPose = stoi(strValue);
|
||||
break;
|
||||
case "body":
|
||||
SetBody(stoi(strValue) + 1);
|
||||
break;
|
||||
case "skin":
|
||||
SetSkin(stoi(strValue));
|
||||
break;
|
||||
default:
|
||||
CBaseMonster::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist_dead::monster_scientist_dead(void)
|
||||
{
|
||||
model = "models/scientist.mdl";
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
78
src/server/monster_sentry.qc
Normal file
78
src/server/monster_sentry.qc
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_sentry (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Sentry Gun
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
SENT_IDLE,
|
||||
SENT_FIRE,
|
||||
SENT_SPIN,
|
||||
SENT_DEPLOY,
|
||||
SENT_RETIRE,
|
||||
SENT_DIE
|
||||
};
|
||||
|
||||
|
||||
class monster_sentry:CBaseMonster
|
||||
{
|
||||
void(void) monster_sentry;
|
||||
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Respawn;
|
||||
|
||||
};
|
||||
|
||||
void
|
||||
monster_sentry::Death(void)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
SetFrame(SENT_DIE);
|
||||
Sound_Play(this, CHAN_VOICE, "monster_sentry.die");
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death();
|
||||
}
|
||||
|
||||
void
|
||||
monster_sentry::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
SetFrame(SENT_IDLE);
|
||||
iBleeds = FALSE;
|
||||
}
|
||||
|
||||
void monster_sentry::monster_sentry(void)
|
||||
{
|
||||
Sound_Precache("monster_sentry.alert");
|
||||
Sound_Precache("monster_sentry.die");
|
||||
Sound_Precache("monster_sentry.idle");
|
||||
Sound_Precache("monster_sentry.retract");
|
||||
netname = "Sentry";
|
||||
model = "models/sentry.mdl";
|
||||
base_health = Skill_GetValue("sentry_health", 40);
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
142
src/server/monster_sitting_scientist.qc
Normal file
142
src/server/monster_sitting_scientist.qc
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_sitting_scientist (0 0.8 0.8) (-14 -14 0) (14 14 36)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Sitting scientists
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
DSCIA_LYING1 = 37,
|
||||
DSCIA_LYING2,
|
||||
DSCIA_DEADSIT,
|
||||
DSCIA_DEADTABLE1,
|
||||
DSCIA_DEADTABLE2,
|
||||
DSCIA_DEADTABLE3,
|
||||
DSCIA_DEADHANG
|
||||
};
|
||||
|
||||
class monster_sitting_scientist:CBaseMonster
|
||||
{
|
||||
int m_iPose;
|
||||
void(void) monster_sitting_scientist;
|
||||
|
||||
virtual void(void) Hide;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) Death;
|
||||
virtual void(void) Gib;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
monster_sitting_scientist::Gib(void)
|
||||
{
|
||||
takedamage = DAMAGE_NO;
|
||||
FX_GibHuman(this.origin);
|
||||
Hide();
|
||||
}
|
||||
|
||||
void
|
||||
monster_sitting_scientist::Death(void)
|
||||
{
|
||||
if (health < -50) {
|
||||
Gib();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_sitting_scientist::Hide(void)
|
||||
{
|
||||
SetModel("");
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
monster_sitting_scientist::Respawn(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
SetOrigin(m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_BBOX;
|
||||
movetype = MOVETYPE_NONE;
|
||||
SetModel(m_oldModel);
|
||||
setsize(this, [-14,-14,0],[14,14,36]);
|
||||
takedamage = DAMAGE_YES;
|
||||
health = 0;
|
||||
velocity = [0,0,0];
|
||||
iBleeds = TRUE;
|
||||
SendFlags |= NPC_BODY;
|
||||
frame = 74;
|
||||
droptofloor();
|
||||
}
|
||||
|
||||
void
|
||||
monster_sitting_scientist::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "pose":
|
||||
m_iPose = stoi(strValue);
|
||||
break;
|
||||
case "body":
|
||||
SetBody(stoi(strValue) + 1);
|
||||
break;
|
||||
case "skin":
|
||||
SetSkin(stoi(strValue));
|
||||
break;
|
||||
default:
|
||||
CBaseMonster::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
monster_sitting_scientist::monster_sitting_scientist(void)
|
||||
{
|
||||
model = "models/scientist.mdl";
|
||||
CBaseMonster::CBaseMonster();
|
||||
|
||||
/* has the body not been overriden, etc. choose a character for us */
|
||||
if (m_iBody == -1) {
|
||||
SetBody((int)floor(random(1,5)));
|
||||
}
|
||||
|
||||
switch (m_iBody) {
|
||||
case 1:
|
||||
m_flPitch = 105;
|
||||
netname = "Walter";
|
||||
break;
|
||||
case 2:
|
||||
m_flPitch = 100;
|
||||
netname = "Einstein";
|
||||
break;
|
||||
case 3:
|
||||
m_flPitch = 95;
|
||||
netname = "Luther";
|
||||
SetSkin(1);
|
||||
break;
|
||||
default:
|
||||
m_flPitch = 100;
|
||||
netname = "Slick";
|
||||
}
|
||||
}
|
132
src/server/monster_tentacle.qc
Normal file
132
src/server/monster_tentacle.qc
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_tentacle (0 0.8 0.8) (-32 -32 0) (32 32 64)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Tentacle
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
TE_IDLEPIT,
|
||||
TE_RISE,
|
||||
TE_TOFLOOR1,
|
||||
TE_IDLE,
|
||||
TE_PISSED,
|
||||
TE_SMALLRISE,
|
||||
TE_WAVE,
|
||||
TE_STRIKE,
|
||||
TE_TAP,
|
||||
TE_ROTATE,
|
||||
TE_REAR,
|
||||
TE_REARIDLE,
|
||||
TE_TOLEV1,
|
||||
TE_IDELLEV1,
|
||||
TE_FIDGETLEV1,
|
||||
TE_SNAPLEV1,
|
||||
TE_STRIKELEV1,
|
||||
TE_TAPLEV1,
|
||||
TE_ROTATELEV1,
|
||||
TE_REARLEV1,
|
||||
TE_REARIDELLEV1,
|
||||
TE_TOLEV2,
|
||||
TE_IDLELEV2,
|
||||
TE_FIDGETLEV2,
|
||||
TE_SNAPLEV2,
|
||||
TE_SWINGLEV2,
|
||||
TE_TUTLEV2,
|
||||
TE_STRIKELEV2,
|
||||
TE_TAPLEV2,
|
||||
TE_ROTATELEV2,
|
||||
TE_REARLEV2,
|
||||
TE_FREAKDIE,
|
||||
TE_REARIDLE2,
|
||||
TE_TOLEV3,
|
||||
TE_IDLELEV3,
|
||||
TE_FIDGETLEV3,
|
||||
TE_SIDELEV3,
|
||||
TE_SWIPELEV3,
|
||||
TE_STRIKELEV3,
|
||||
TE_TAPLEV3,
|
||||
TE_ROTATELEV3,
|
||||
TE_REARLEV3,
|
||||
TE_REARIDLELEV3,
|
||||
TE_DOORLEV1,
|
||||
TE_ENGINELEV3,
|
||||
TE_ENGINEIDLE,
|
||||
TE_ENGINESWAY,
|
||||
TE_ENGINESWAT,
|
||||
TE_ENGINEBOB,
|
||||
TE_ENGINEDEATH,
|
||||
TE_ENGINEDEATH2,
|
||||
TE_ENGINEDEATH3,
|
||||
TE_GRABIDLE,
|
||||
TE_GRAB
|
||||
};
|
||||
|
||||
class monster_tentacle:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
|
||||
void(void) monster_tentacle;
|
||||
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_tentacle::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + random(2,10);
|
||||
|
||||
Sound_Play(this, CHAN_VOICE, "monster_tentacle.idle");
|
||||
}
|
||||
|
||||
void
|
||||
monster_tentacle::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
/* not entirely true, takes damage then retreats and reheals */
|
||||
takedamage = DAMAGE_NO;
|
||||
iBleeds = FALSE;
|
||||
SetFrame(TE_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
monster_tentacle::monster_tentacle(void)
|
||||
{
|
||||
Sound_Precache("monster_tentacle.alert");
|
||||
Sound_Precache("monster_tentacle.attack");
|
||||
Sound_Precache("monster_tentacle.die");
|
||||
Sound_Precache("monster_tentacle.idle");
|
||||
netname = "Tentacle";
|
||||
model = "models/tentacle2.mdl";
|
||||
base_mins = [-32,-32,0];
|
||||
base_maxs = [32,32,64];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
47
src/server/monster_turret.qc
Normal file
47
src/server/monster_turret.qc
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_turret (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Automatic Turret (large)
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
TUR_IDLE,
|
||||
TUR_FIRE,
|
||||
TUR_SPIN,
|
||||
TUR_DEPLOY,
|
||||
TUR_RETIRE,
|
||||
TUR_DIE
|
||||
};
|
||||
|
||||
class monster_turret:CBaseMonster
|
||||
{
|
||||
void(void) monster_turret;
|
||||
};
|
||||
|
||||
void monster_turret::monster_turret(void)
|
||||
{
|
||||
netname = "Turret";
|
||||
model = "models/turret.mdl";
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
}
|
222
src/server/monster_zombie.qc
Normal file
222
src/server/monster_zombie.qc
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 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.
|
||||
*/
|
||||
|
||||
/*QUAKED monster_zombie (0 0.8 0.8) (-16 -16 0) (16 16 72)
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Zombie
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
ZO_IDLE,
|
||||
ZO_TURNLEFT,
|
||||
ZO_TURNRIGHT,
|
||||
ZO_FLINCHSM,
|
||||
ZO_FLINCH,
|
||||
ZO_FLINCHBIG,
|
||||
ZO_RISE,
|
||||
ZO_FALLING,
|
||||
ZO_ATTACK1,
|
||||
ZO_ATTACK2,
|
||||
ZO_WALK,
|
||||
ZO_FLINCHLA,
|
||||
ZO_FLINCHRA,
|
||||
ZO_FLINCHLEFT,
|
||||
ZO_FLINCHRIGHT,
|
||||
ZO_DIEHS,
|
||||
ZO_DIEHS2,
|
||||
ZO_DIE,
|
||||
ZO_DIE2,
|
||||
ZO_DIE3,
|
||||
ZO_PAUSE,
|
||||
ZO_WALLBUST,
|
||||
ZO_WALLKICK,
|
||||
ZO_WINDOWBUST,
|
||||
ZO_SODA,
|
||||
ZO_SLIDEIDLE,
|
||||
ZO_SLIDE,
|
||||