Update against latest Nuclide
This commit is contained in:
parent
2aa2e39ff9
commit
41c845075e
32 changed files with 1415 additions and 352 deletions
|
@ -3,3 +3,4 @@ CC=fteqcc
|
||||||
all:
|
all:
|
||||||
cd client && $(MAKE)
|
cd client && $(MAKE)
|
||||||
cd server && $(MAKE)
|
cd server && $(MAKE)
|
||||||
|
cd rules && $(MAKE)
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../../../valve/src/shared/defs.h"
|
||||||
#include "../../../valve/src/client/obituary.h"
|
#include "../../../valve/src/client/obituary.h"
|
||||||
#include "../../../valve/src/client/particles.h"
|
#include "../../../valve/src/client/particles.h"
|
||||||
#include "../../../valve/src/client/hud_sprite.h"
|
#include "../../../valve/src/client/hud_sprite.h"
|
||||||
|
#include "../../../valve/src/client/HLWeaponSelect.h"
|
||||||
|
|
||||||
var int autocvar_cl_autoweaponswitch = TRUE;
|
var int autocvar_cl_autoweaponswitch = TRUE;
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ struct
|
||||||
int m_iItemsOld;
|
int m_iItemsOld;
|
||||||
|
|
||||||
float m_flDamageIndicator;
|
float m_flDamageIndicator;
|
||||||
|
HLWeaponSelect weaponSelectionHUD;
|
||||||
} g_seatslocal[4], *pSeatLocal;
|
} g_seatslocal[4], *pSeatLocal;
|
||||||
|
|
||||||
void HUD_DrawAmmo1(void);
|
void HUD_DrawAmmo1(void);
|
||||||
|
|
|
@ -148,7 +148,7 @@ void
|
||||||
HUD_DrawHealth(void)
|
HUD_DrawHealth(void)
|
||||||
{
|
{
|
||||||
vector pos;
|
vector pos;
|
||||||
NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer;
|
ncPlayer pl = (ncPlayer)pSeat->m_ePlayer;
|
||||||
|
|
||||||
if (pl.health != pSeatLocal->m_iHealthOld) {
|
if (pl.health != pSeatLocal->m_iHealthOld) {
|
||||||
pSeatLocal->m_flHealthAlpha = 1.0;
|
pSeatLocal->m_flHealthAlpha = 1.0;
|
||||||
|
@ -600,7 +600,7 @@ HUD_DrawSpectator(void)
|
||||||
{
|
{
|
||||||
Textmenu_Draw();
|
Textmenu_Draw();
|
||||||
|
|
||||||
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
|
ncSpectator spec = (ncSpectator)pSeat->m_ePlayer;
|
||||||
|
|
||||||
drawfont = Font_GetID(FONT_20);
|
drawfont = Font_GetID(FONT_20);
|
||||||
vector vecPos = [0.0f, 0.0f, 0.0f];
|
vector vecPos = [0.0f, 0.0f, 0.0f];
|
||||||
|
|
|
@ -28,6 +28,8 @@ ClientGame_Init(float apilevel, string enginename, float engineversion)
|
||||||
registercommand("+sciscore");
|
registercommand("+sciscore");
|
||||||
registercommand("-sciscore");
|
registercommand("-sciscore");
|
||||||
registercommand("chooseteam");
|
registercommand("chooseteam");
|
||||||
|
|
||||||
|
pSeatLocal->weaponSelectionHUD = spawn(HLWeaponSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VGUI_ShowMOTD(void);
|
void VGUI_ShowMOTD(void);
|
||||||
|
|
|
@ -26,6 +26,7 @@ init.qc
|
||||||
../../../valve/src/client/flashlight.qc
|
../../../valve/src/client/flashlight.qc
|
||||||
entities.qc
|
entities.qc
|
||||||
cmds.qc
|
cmds.qc
|
||||||
|
../../../valve/src/client/HLWeaponSelect.qc
|
||||||
../../../valve/src/client/game_event.qc
|
../../../valve/src/client/game_event.qc
|
||||||
../../../valve/src/client/camera.qc
|
../../../valve/src/client/camera.qc
|
||||||
../../../valve/src/client/viewmodel.qc
|
../../../valve/src/client/viewmodel.qc
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VGUIWindow winChooseTeam;
|
static vguiWindow winChooseTeam;
|
||||||
|
|
||||||
class TeamButton:VGUIButton
|
class TeamButton:vguiButton
|
||||||
{
|
{
|
||||||
void TeamButton(void);
|
void TeamButton(void);
|
||||||
|
|
||||||
|
@ -65,14 +65,14 @@ void
|
||||||
VGUI_ChooseTeam(void)
|
VGUI_ChooseTeam(void)
|
||||||
{
|
{
|
||||||
static int initialized;
|
static int initialized;
|
||||||
static VGUIButton btnTeamBlue;
|
static vguiButton btnTeamBlue;
|
||||||
static VGUIButton btnTeamRed;
|
static vguiButton btnTeamRed;
|
||||||
static VGUIButton btnAutoAssign;
|
static vguiButton btnAutoAssign;
|
||||||
static VGUIButton btnGoSpectator;
|
static vguiButton btnGoSpectator;
|
||||||
static VGUIFrame frmMapInfo;
|
static vguiFrame frmMapInfo;
|
||||||
static VGUILabel lblSelectTeam;
|
static vguiLabel lblSelectTeam;
|
||||||
static VGUILabel lblMapName;
|
static vguiLabel lblMapName;
|
||||||
static VGUILabel lblMapInfo;
|
static vguiLabel lblMapInfo;
|
||||||
|
|
||||||
static void VGUI_AutoAssign(void) {
|
static void VGUI_AutoAssign(void) {
|
||||||
sendevent("JoinAuto", "");
|
sendevent("JoinAuto", "");
|
||||||
|
@ -99,32 +99,32 @@ VGUI_ChooseTeam(void)
|
||||||
vector btnpos = [40,80];
|
vector btnpos = [40,80];
|
||||||
|
|
||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
winChooseTeam = spawn(VGUIWindow);
|
winChooseTeam = spawn(vguiWindow);
|
||||||
winChooseTeam.SetSize('640 480');
|
winChooseTeam.SetSize('640 480');
|
||||||
winChooseTeam.SetStyleMask(VGUIWindowBorderless | VGUIWindowFullscreen);
|
winChooseTeam.SetStyleMask(vguiWindowBorderless | vguiWindowFullscreen);
|
||||||
|
|
||||||
lblSelectTeam = spawn(VGUILabel);
|
lblSelectTeam = spawn(vguiLabel);
|
||||||
lblSelectTeam.SetTitle("SELECT YOUR TEAM");
|
lblSelectTeam.SetTitle("SELECT YOUR TEAM");
|
||||||
lblSelectTeam.SetTextSize(19);
|
lblSelectTeam.SetTextSize(19);
|
||||||
lblSelectTeam.SetPos([40, 38]);
|
lblSelectTeam.SetPos([40, 38]);
|
||||||
lblSelectTeam.SetSize('400 24');
|
lblSelectTeam.SetSize('400 24');
|
||||||
|
|
||||||
frmMapInfo = spawn(VGUIFrame);
|
frmMapInfo = spawn(vguiFrame);
|
||||||
frmMapInfo.SetPos('176 80');
|
frmMapInfo.SetPos('176 80');
|
||||||
frmMapInfo.SetSize('424 312');
|
frmMapInfo.SetSize('424 312');
|
||||||
|
|
||||||
lblMapName = spawn(VGUILabel);
|
lblMapName = spawn(vguiLabel);
|
||||||
lblMapName.SetTitle(mapname);
|
lblMapName.SetTitle(mapname);
|
||||||
lblMapName.SetTextSize(19);
|
lblMapName.SetTextSize(19);
|
||||||
lblMapName.SetPos('194 105');
|
lblMapName.SetPos('194 105');
|
||||||
lblMapName.SetSize('250 312');
|
lblMapName.SetSize('250 312');
|
||||||
|
|
||||||
lblMapInfo = spawn(VGUILabel);
|
lblMapInfo = spawn(vguiLabel);
|
||||||
lblMapInfo.SetTitle(VGUI_ChooseTeam_MapInfo());
|
lblMapInfo.SetTitle(VGUI_ChooseTeam_MapInfo());
|
||||||
lblMapInfo.SetPos('194 129');
|
lblMapInfo.SetPos('194 129');
|
||||||
lblMapInfo.SetSize('375 250');
|
lblMapInfo.SetSize('375 250');
|
||||||
|
|
||||||
btnTeamBlue = spawn(VGUIButton);
|
btnTeamBlue = spawn(vguiButton);
|
||||||
btnTeamBlue.SetTitle("BLUE");
|
btnTeamBlue.SetTitle("BLUE");
|
||||||
btnTeamBlue.SetPos(btnpos);
|
btnTeamBlue.SetPos(btnpos);
|
||||||
btnTeamBlue.SetSize('124 24');
|
btnTeamBlue.SetSize('124 24');
|
||||||
|
@ -132,7 +132,7 @@ VGUI_ChooseTeam(void)
|
||||||
btnTeamBlue.SetFunc(VGUI_JoinBlue);
|
btnTeamBlue.SetFunc(VGUI_JoinBlue);
|
||||||
btnpos[1] += 32;
|
btnpos[1] += 32;
|
||||||
|
|
||||||
btnTeamRed = spawn(VGUIButton);
|
btnTeamRed = spawn(vguiButton);
|
||||||
btnTeamRed.SetTitle("RED");
|
btnTeamRed.SetTitle("RED");
|
||||||
btnTeamRed.SetPos(btnpos);
|
btnTeamRed.SetPos(btnpos);
|
||||||
btnTeamRed.SetSize('124 24');
|
btnTeamRed.SetSize('124 24');
|
||||||
|
@ -140,7 +140,7 @@ VGUI_ChooseTeam(void)
|
||||||
btnTeamRed.SetFunc(VGUI_JoinRed);
|
btnTeamRed.SetFunc(VGUI_JoinRed);
|
||||||
btnpos[1] += 32;
|
btnpos[1] += 32;
|
||||||
|
|
||||||
btnAutoAssign = spawn(VGUIButton);
|
btnAutoAssign = spawn(vguiButton);
|
||||||
btnAutoAssign.SetTitle("AUTO ASSIGN");
|
btnAutoAssign.SetTitle("AUTO ASSIGN");
|
||||||
btnAutoAssign.SetPos(btnpos);
|
btnAutoAssign.SetPos(btnpos);
|
||||||
btnAutoAssign.SetSize('124 24');
|
btnAutoAssign.SetSize('124 24');
|
||||||
|
@ -148,7 +148,7 @@ VGUI_ChooseTeam(void)
|
||||||
btnAutoAssign.SetFunc(VGUI_AutoAssign);
|
btnAutoAssign.SetFunc(VGUI_AutoAssign);
|
||||||
btnpos[1] += 32;
|
btnpos[1] += 32;
|
||||||
|
|
||||||
btnGoSpectator = spawn(VGUIButton);
|
btnGoSpectator = spawn(vguiButton);
|
||||||
btnGoSpectator.SetTitle("SPECTATE");
|
btnGoSpectator.SetTitle("SPECTATE");
|
||||||
btnGoSpectator.SetPos(btnpos);
|
btnGoSpectator.SetPos(btnpos);
|
||||||
btnGoSpectator.SetSize('124 24');
|
btnGoSpectator.SetSize('124 24');
|
||||||
|
|
|
@ -18,11 +18,11 @@ void
|
||||||
VGUI_ShowMOTD(void)
|
VGUI_ShowMOTD(void)
|
||||||
{
|
{
|
||||||
static int initialized;
|
static int initialized;
|
||||||
static VGUIButton winMotdClose;
|
static vguiButton winMotdClose;
|
||||||
// static VGUIButton winMotdMapInfo;
|
// static vguiButton winMotdMapInfo;
|
||||||
static VGUIWindow winMotd;
|
static vguiWindow winMotd;
|
||||||
static VGUILabel winMotdHostname;
|
static vguiLabel winMotdHostname;
|
||||||
static VGUILabel winMotdBody;
|
static vguiLabel winMotdBody;
|
||||||
|
|
||||||
static void VGUI_ShowMOTD_Close(void)
|
static void VGUI_ShowMOTD_Close(void)
|
||||||
{
|
{
|
||||||
|
@ -36,12 +36,12 @@ VGUI_ShowMOTD(void)
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
winMotd = spawn(VGUIWindow);
|
winMotd = spawn(vguiWindow);
|
||||||
winMotd.SetTitle("Message Of The Day");
|
winMotd.SetTitle("Message Of The Day");
|
||||||
winMotd.SetSize('424 312');
|
winMotd.SetSize('424 312');
|
||||||
winMotd.SetStyleMask(0);
|
winMotd.SetStyleMask(0);
|
||||||
|
|
||||||
winMotdClose = spawn(VGUIButton);
|
winMotdClose = spawn(vguiButton);
|
||||||
winMotdClose.SetTitle("OK");
|
winMotdClose.SetTitle("OK");
|
||||||
winMotdClose.SetPos([16, 266]);
|
winMotdClose.SetPos([16, 266]);
|
||||||
winMotdClose.SetSize([160, 30]);
|
winMotdClose.SetSize([160, 30]);
|
||||||
|
@ -50,7 +50,7 @@ VGUI_ShowMOTD(void)
|
||||||
/* TODO An experiment with how to display map readme
|
/* TODO An experiment with how to display map readme
|
||||||
* files for non team games
|
* files for non team games
|
||||||
if (serverkeyfloat("teams") < 1) {
|
if (serverkeyfloat("teams") < 1) {
|
||||||
winMotdMapInfo = spawn(VGUIButton);
|
winMotdMapInfo = spawn(vguiButton);
|
||||||
winMotdMapInfo.SetTitle("Map Info");
|
winMotdMapInfo.SetTitle("Map Info");
|
||||||
winMotdMapInfo.SetPos([196, 266]);
|
winMotdMapInfo.SetPos([196, 266]);
|
||||||
winMotdMapInfo.SetSize([160, 30]);
|
winMotdMapInfo.SetSize([160, 30]);
|
||||||
|
@ -58,12 +58,12 @@ VGUI_ShowMOTD(void)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
winMotdHostname = spawn(VGUILabel);
|
winMotdHostname = spawn(vguiLabel);
|
||||||
winMotdHostname.SetTitle(serverkey("hostname"));
|
winMotdHostname.SetTitle(serverkey("hostname"));
|
||||||
winMotdHostname.SetTextSize(19);
|
winMotdHostname.SetTextSize(19);
|
||||||
winMotdHostname.SetPos([16, 20]);
|
winMotdHostname.SetPos([16, 20]);
|
||||||
|
|
||||||
winMotdBody = spawn(VGUILabel);
|
winMotdBody = spawn(vguiLabel);
|
||||||
winMotdBody.SetTitle(MOTD_GetTextBody());
|
winMotdBody.SetTitle(MOTD_GetTextBody());
|
||||||
winMotdBody.SetPos([16, 48]);
|
winMotdBody.SetPos([16, 48]);
|
||||||
winMotdBody.SetSize([392, 210]);
|
winMotdBody.SetSize([392, 210]);
|
||||||
|
|
10
src/rules/Makefile
Normal file
10
src/rules/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
QCC=fteqcc
|
||||||
|
|
||||||
|
all:
|
||||||
|
mkdir -pv ../../zpak001.pk3dir/progs/
|
||||||
|
$(QCC) fear.qc
|
||||||
|
$(QCC) hunt.qc
|
||||||
|
$(QCC) invasion.qc
|
||||||
|
$(QCC) madness.qc
|
||||||
|
$(QCC) slaughter.qc
|
||||||
|
$(QCC) stealth.qc
|
80
src/rules/arsenal.h
Normal file
80
src/rules/arsenal.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var string g_defaultArsenal = "";
|
||||||
|
var string g_mapArsenal = "";
|
||||||
|
|
||||||
|
void
|
||||||
|
SHArsenal_Init(void)
|
||||||
|
{
|
||||||
|
int c = 0i;
|
||||||
|
string line;
|
||||||
|
string lineFeed;
|
||||||
|
filestream arsHandle;
|
||||||
|
string standardArsenal = "arsenals/starteqp.txt";
|
||||||
|
string mapArsenal = cvars.GetString("sh_weapfileloc"); //strcat("arsenal/", game.GetMap(), ".txt");
|
||||||
|
|
||||||
|
g_defaultArsenal = "";
|
||||||
|
g_mapArsenal = "";
|
||||||
|
|
||||||
|
if (exists.InVFS(standardArsenal) == true) {
|
||||||
|
arsHandle = fopen(standardArsenal, FILE_READ);
|
||||||
|
|
||||||
|
if (arsHandle >= 0) {
|
||||||
|
while ((lineFeed = fgets(arsHandle))) {
|
||||||
|
c = (int)tokenize_console(lineFeed);
|
||||||
|
line = argv(0);
|
||||||
|
|
||||||
|
if (STRING_SET(line)) {
|
||||||
|
g_defaultArsenal = strcat(g_defaultArsenal, line, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(arsHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists.InVFS(mapArsenal) == true) {
|
||||||
|
arsHandle = fopen(mapArsenal, FILE_READ);
|
||||||
|
|
||||||
|
if (arsHandle >= 0) {
|
||||||
|
while ((lineFeed = fgets(arsHandle))) {
|
||||||
|
c = (int)tokenize_console(lineFeed);
|
||||||
|
line = argv(0);
|
||||||
|
|
||||||
|
if (STRING_SET(line)) {
|
||||||
|
g_mapArsenal = strcat(g_mapArsenal, line, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(arsHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSWarning("Default equipment: %s\nMap equipment: %s", g_defaultArsenal, g_mapArsenal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SHArsenal_GiveItemsToPlayer(entity targetPlayer)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)tokenize_console(g_defaultArsenal); i++) {
|
||||||
|
ents.Input(targetPlayer, "GiveItem", argv(i), targetPlayer);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < (int)tokenize_console(g_mapArsenal); i++) {
|
||||||
|
ents.Input(targetPlayer, "GiveItem", argv(i), targetPlayer);
|
||||||
|
}
|
||||||
|
}
|
213
src/rules/fear.qc
Normal file
213
src/rules/fear.qc
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma PROGS_DAT "../../zpak001.pk3dir/progs/fear.dat"
|
||||||
|
|
||||||
|
#include "../../../src/server/api.h"
|
||||||
|
|
||||||
|
string g_strTeamList;
|
||||||
|
const string mp_teamlist_fallback = "scientist;hgrunt";
|
||||||
|
var string autocvar_mp_teamlist = mp_teamlist_fallback;
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsTeamplay(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_teamplay");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AllowFlashlight(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_flashlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_StartGameType(void)
|
||||||
|
{
|
||||||
|
motd.LoadDefault();
|
||||||
|
|
||||||
|
if (IsTeamplay() == true) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* get the segments from our cvar */
|
||||||
|
g_strTeamList = autocvar_mp_teamlist;
|
||||||
|
c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
|
||||||
|
/* if we've got less than 2 teams, use the fallback... */
|
||||||
|
if (c < 2) {
|
||||||
|
g_strTeamList = mp_teamlist_fallback;
|
||||||
|
c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize all dem teams */
|
||||||
|
for (int i = 0; i < c; i++) {
|
||||||
|
teams.SetUp(i+1, argv(i), [255,255,255], true);
|
||||||
|
teams.SetSpawnPoint(i+1, "info_player_deathmatch");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
game.SetSpawnPoint("info_player_deathmatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HLDM_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
string playerModel;
|
||||||
|
|
||||||
|
ents.ChangeToClass(playerEntity, "player_mp");
|
||||||
|
|
||||||
|
if (IsTeamplay() == true) {
|
||||||
|
float teamCount = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
float playerTeam = playerEntity.team;
|
||||||
|
string teamModel;
|
||||||
|
|
||||||
|
/* not part of a team? pick one of the ones we have */
|
||||||
|
/* TODO: this should sort us into the lowest team */
|
||||||
|
if (playerTeam == 0) {
|
||||||
|
playerTeam = 1 + floor(random(0, teamCount)); /* teams start at 1 after all */
|
||||||
|
ents.Input(playerEntity, "SetTeam", ftos(playerTeam), playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
teamModel = argv(playerTeam - 1);
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", teamModel, teamModel);
|
||||||
|
} else {
|
||||||
|
/* interpret the 'model' InfoKey */
|
||||||
|
playerModel = userinfo.GetString(playerEntity, "model");
|
||||||
|
|
||||||
|
if (playerModel != "") {
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", playerModel, playerModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fallback is always models/player.mdl for Half-Life */
|
||||||
|
if (playerModel == "" || exists.InVFS(playerModel) == false) {
|
||||||
|
playerModel = "models/player.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
playerEntity.modelindex = getmodelindex(playerModel); /* keep OG size */
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
if (IsTeamplay() == false) {
|
||||||
|
HLDM_PlayerSpawn(playerEntity);
|
||||||
|
} else {
|
||||||
|
ents.ChangeToClass(playerEntity, "spectator");
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDisconnect(entity playerEntity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
CodeCallback_PlayerSpawn(playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDamage(entity playerEntity, entity inflictor, entity attacker)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_CallRequestTeam(entity playerEntity, int teamNum)
|
||||||
|
{
|
||||||
|
ents.Input(playerEntity, "SetTeam", itos(teamNum), playerEntity);
|
||||||
|
ents.Input(playerEntity, "Damage", "1000", playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||||
|
{
|
||||||
|
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||||
|
|
||||||
|
/* death-counter */
|
||||||
|
playerEntity.deaths++;
|
||||||
|
|
||||||
|
/* update score-counter */
|
||||||
|
if (ents.isPlayer(attacker)) {
|
||||||
|
if (playerEntity == attacker) {
|
||||||
|
attacker.frags--;
|
||||||
|
} else {
|
||||||
|
attacker.frags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ClientCommand(entity playerEntity, string command)
|
||||||
|
{
|
||||||
|
float commandArgs = tokenize(command);
|
||||||
|
|
||||||
|
switch (argv(0)) {
|
||||||
|
case "chooseteam":
|
||||||
|
string teamName = argv(1);
|
||||||
|
|
||||||
|
/* wrong mode */
|
||||||
|
if (IsTeamplay() == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no team defined */
|
||||||
|
if (!teamName) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
|
||||||
|
for (float i = 0; i < c; i++) {
|
||||||
|
if (argv(i) == teamName) {
|
||||||
|
string newTeam = ftos(i + 1);
|
||||||
|
ents.Input(playerEntity, "SetTeam", newTeam, playerEntity);
|
||||||
|
ents.Input(playerEntity, "Damage", "1000", playerEntity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
|
||||||
|
{
|
||||||
|
switch (impulseNum) {
|
||||||
|
case 100:
|
||||||
|
if (AllowFlashlight() == true) {
|
||||||
|
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
139
src/rules/hunt.qc
Normal file
139
src/rules/hunt.qc
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// SCIENTISTS DO NOT RESPAWN IN THIS MODE!
|
||||||
|
|
||||||
|
#pragma PROGS_DAT "../../zpak001.pk3dir/progs/hunt.dat"
|
||||||
|
|
||||||
|
#include "../../../src/server/api.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AllowFlashlight(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_flashlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_StartGameType(void)
|
||||||
|
{
|
||||||
|
motd.LoadDefault();
|
||||||
|
game.SetSpawnPoint("info_player_team1");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HLDM_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
string playerModel;
|
||||||
|
|
||||||
|
ents.ChangeToClass(playerEntity, "player");
|
||||||
|
|
||||||
|
|
||||||
|
/* interpret the 'model' InfoKey */
|
||||||
|
playerModel = userinfo.GetString(playerEntity, "model");
|
||||||
|
|
||||||
|
if (playerModel != "") {
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", playerModel, playerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fallback is always models/player.mdl for Half-Life */
|
||||||
|
if (playerModel == "" || exists.InVFS(playerModel) == false) {
|
||||||
|
playerModel = "models/player.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
playerEntity.modelindex = getmodelindex(playerModel); /* keep OG size */
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
ents.ChangeToClass(playerEntity, "spectator");
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDisconnect(entity playerEntity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
CodeCallback_PlayerSpawn(playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDamage(entity playerEntity, entity inflictor, entity attacker)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_CallRequestTeam(entity playerEntity, int teamNum)
|
||||||
|
{
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||||
|
{
|
||||||
|
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||||
|
|
||||||
|
/* death-counter */
|
||||||
|
playerEntity.deaths++;
|
||||||
|
|
||||||
|
/* update score-counter */
|
||||||
|
if (ents.isPlayer(attacker)) {
|
||||||
|
if (playerEntity == attacker) {
|
||||||
|
attacker.frags--;
|
||||||
|
} else {
|
||||||
|
attacker.frags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ClientCommand(entity playerEntity, string command)
|
||||||
|
{
|
||||||
|
float commandArgs = tokenize(command);
|
||||||
|
|
||||||
|
switch (argv(0)) {
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
|
||||||
|
{
|
||||||
|
switch (impulseNum) {
|
||||||
|
case 100:
|
||||||
|
if (AllowFlashlight() == true) {
|
||||||
|
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
215
src/rules/invasion.qc
Normal file
215
src/rules/invasion.qc
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// SCIENTISTS DO NOT RESPAWN IN THIS MODE!
|
||||||
|
|
||||||
|
#pragma PROGS_DAT "../../zpak001.pk3dir/progs/invasion.dat"
|
||||||
|
|
||||||
|
#include "../../../src/server/api.h"
|
||||||
|
|
||||||
|
string g_strTeamList;
|
||||||
|
const string mp_teamlist_fallback = "scientist;hgrunt";
|
||||||
|
var string autocvar_mp_teamlist = mp_teamlist_fallback;
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsTeamplay(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_teamplay");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AllowFlashlight(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_flashlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_StartGameType(void)
|
||||||
|
{
|
||||||
|
motd.LoadDefault();
|
||||||
|
|
||||||
|
if (IsTeamplay() == true) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* get the segments from our cvar */
|
||||||
|
g_strTeamList = autocvar_mp_teamlist;
|
||||||
|
c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
|
||||||
|
/* if we've got less than 2 teams, use the fallback... */
|
||||||
|
if (c < 2) {
|
||||||
|
g_strTeamList = mp_teamlist_fallback;
|
||||||
|
c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize all dem teams */
|
||||||
|
for (int i = 0; i < c; i++) {
|
||||||
|
teams.SetUp(i+1, argv(i), [255,255,255], true);
|
||||||
|
teams.SetSpawnPoint(i+1, "info_player_deathmatch");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
game.SetSpawnPoint("info_player_deathmatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HLDM_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
string playerModel;
|
||||||
|
|
||||||
|
ents.ChangeToClass(playerEntity, "player_mp");
|
||||||
|
|
||||||
|
if (IsTeamplay() == true) {
|
||||||
|
float teamCount = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
float playerTeam = playerEntity.team;
|
||||||
|
string teamModel;
|
||||||
|
|
||||||
|
/* not part of a team? pick one of the ones we have */
|
||||||
|
/* TODO: this should sort us into the lowest team */
|
||||||
|
if (playerTeam == 0) {
|
||||||
|
playerTeam = 1 + floor(random(0, teamCount)); /* teams start at 1 after all */
|
||||||
|
ents.Input(playerEntity, "SetTeam", ftos(playerTeam), playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
teamModel = argv(playerTeam - 1);
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", teamModel, teamModel);
|
||||||
|
} else {
|
||||||
|
/* interpret the 'model' InfoKey */
|
||||||
|
playerModel = userinfo.GetString(playerEntity, "model");
|
||||||
|
|
||||||
|
if (playerModel != "") {
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", playerModel, playerModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fallback is always models/player.mdl for Half-Life */
|
||||||
|
if (playerModel == "" || exists.InVFS(playerModel) == false) {
|
||||||
|
playerModel = "models/player.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
playerEntity.modelindex = getmodelindex(playerModel); /* keep OG size */
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
if (IsTeamplay() == false) {
|
||||||
|
HLDM_PlayerSpawn(playerEntity);
|
||||||
|
} else {
|
||||||
|
ents.ChangeToClass(playerEntity, "spectator");
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDisconnect(entity playerEntity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
CodeCallback_PlayerSpawn(playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDamage(entity playerEntity, entity inflictor, entity attacker)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_CallRequestTeam(entity playerEntity, int teamNum)
|
||||||
|
{
|
||||||
|
ents.Input(playerEntity, "SetTeam", itos(teamNum), playerEntity);
|
||||||
|
ents.Input(playerEntity, "Damage", "1000", playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||||
|
{
|
||||||
|
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||||
|
|
||||||
|
/* death-counter */
|
||||||
|
playerEntity.deaths++;
|
||||||
|
|
||||||
|
/* update score-counter */
|
||||||
|
if (ents.isPlayer(attacker)) {
|
||||||
|
if (playerEntity == attacker) {
|
||||||
|
attacker.frags--;
|
||||||
|
} else {
|
||||||
|
attacker.frags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ClientCommand(entity playerEntity, string command)
|
||||||
|
{
|
||||||
|
float commandArgs = tokenize(command);
|
||||||
|
|
||||||
|
switch (argv(0)) {
|
||||||
|
case "chooseteam":
|
||||||
|
string teamName = argv(1);
|
||||||
|
|
||||||
|
/* wrong mode */
|
||||||
|
if (IsTeamplay() == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no team defined */
|
||||||
|
if (!teamName) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
|
||||||
|
for (float i = 0; i < c; i++) {
|
||||||
|
if (argv(i) == teamName) {
|
||||||
|
string newTeam = ftos(i + 1);
|
||||||
|
ents.Input(playerEntity, "SetTeam", newTeam, playerEntity);
|
||||||
|
ents.Input(playerEntity, "Damage", "1000", playerEntity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
|
||||||
|
{
|
||||||
|
switch (impulseNum) {
|
||||||
|
case 100:
|
||||||
|
if (AllowFlashlight() == true) {
|
||||||
|
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
172
src/rules/madness.qc
Normal file
172
src/rules/madness.qc
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// SCIENTISTS WILL ATTACK EACH OTHER AS WELL AS
|
||||||
|
// PLAYERS. THEY ARE BASICALLY ALL ROGUE.
|
||||||
|
//
|
||||||
|
// IF A SCIENTIST KILLS NPCS OR PLAYERS
|
||||||
|
// IT WILL PLAY SH/HIDE_LAUGH.WAV
|
||||||
|
//
|
||||||
|
// THEY CAN ALSO RESPAWN
|
||||||
|
|
||||||
|
#pragma PROGS_DAT "../../zpak001.pk3dir/progs/madness.dat"
|
||||||
|
|
||||||
|
#include "../../../src/server/api.h"
|
||||||
|
#include "arsenal.h"
|
||||||
|
#include "scimanager.h"
|
||||||
|
#include "shared.h"
|
||||||
|
|
||||||
|
/* Slaughter is the default game mode. */
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_Input(entity activator, string inputName, string dataString)
|
||||||
|
{
|
||||||
|
switch (inputName) {
|
||||||
|
#if 0
|
||||||
|
case "CountScientists":
|
||||||
|
int livingScientists = 0i;
|
||||||
|
for (entity s = world; (s = find(s, ::classname, "monster_scientist"));) {
|
||||||
|
if (s.solid == SOLID_BBOX || s.solid == SOLID_SLIDEBOX) {
|
||||||
|
livingScientists++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverinfo.SetInteger("sci_count", livingScientists);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case "ScientistKilled":
|
||||||
|
activator.frags += 1;
|
||||||
|
break;
|
||||||
|
case "ScientistDied":
|
||||||
|
ScientistManager::RespawnSingle(activator, 10.0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_StartGameType(void)
|
||||||
|
{
|
||||||
|
SHArsenal_Init();
|
||||||
|
motd.LoadDefault();
|
||||||
|
|
||||||
|
teams.SetUp(1, "Players", [153, 204, 255], true);
|
||||||
|
teams.SetSpawnPoint(1, "info_player_team1");
|
||||||
|
teams.SetUp(4, "Scientists", [153, 204, 255], true);
|
||||||
|
teams.SetSpawnPoint(2, "monster_scientist");
|
||||||
|
|
||||||
|
precache_sound("sh/hide_laugh.wav");
|
||||||
|
|
||||||
|
// game.SetSpawnPoint("info_player_team1");
|
||||||
|
ScientistManager::PopulateLevel(cvars.GetInteger("sh_scimax"), "sh_scientist_madness");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
string playerModel;
|
||||||
|
|
||||||
|
ents.ChangeToClass(playerEntity, "player_slaughter");
|
||||||
|
ents.Input(playerEntity, "SetTeam", "1", playerEntity);
|
||||||
|
|
||||||
|
/* interpret the 'model' InfoKey */
|
||||||
|
playerModel = userinfo.GetString(playerEntity, "model");
|
||||||
|
|
||||||
|
if (playerModel != "") {
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", playerModel, playerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fallback is always models/player.mdl for Half-Life */
|
||||||
|
if (playerModel == "" || exists.InVFS(playerModel) == false) {
|
||||||
|
playerModel = "models/player.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
playerEntity.modelindex = getmodelindex(playerModel); /* keep OG size */
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
SHArsenal_GiveItemsToPlayer(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDisconnect(entity playerEntity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
CodeCallback_PlayerSpawn(playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDamage(entity playerEntity, entity inflictor, entity attacker)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||||
|
{
|
||||||
|
/* Only laugh when the target wasn't poisoned, TODO */
|
||||||
|
if (attacker.classname == "sh_scientist_madness" && playerEntity.WASPOISONED == false) {
|
||||||
|
sound(attacker, CHAN_AUTO, "sh/hide_laugh.wav", 1.0, ATTN_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||||
|
|
||||||
|
/* death-counter */
|
||||||
|
playerEntity.deaths++;
|
||||||
|
|
||||||
|
/* update score-counter */
|
||||||
|
if (ents.isPlayer(attacker)) {
|
||||||
|
if (playerEntity == attacker) {
|
||||||
|
attacker.frags--;
|
||||||
|
} else {
|
||||||
|
attacker.frags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ClientCommand(entity playerEntity, string command)
|
||||||
|
{
|
||||||
|
float commandArgs = tokenize(command);
|
||||||
|
|
||||||
|
switch (argv(0)) {
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
|
||||||
|
{
|
||||||
|
switch (impulseNum) {
|
||||||
|
case 100:
|
||||||
|
if (AllowFlashlight() == true) {
|
||||||
|
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
78
src/rules/scimanager.h
Normal file
78
src/rules/scimanager.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Utility class that handles sh_scientist entities across all game modes */
|
||||||
|
class
|
||||||
|
ScientistManager
|
||||||
|
{
|
||||||
|
const void PopulateLevel(int sciNum, string decl);
|
||||||
|
const void ClearScientists(string decl);
|
||||||
|
const void RespawnSingle(entity scientistEntity, float waitTime);
|
||||||
|
const void TeleportToSpot(entity scientistEntity);
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_RespawnTimerFinished(void)
|
||||||
|
{
|
||||||
|
ents.Input(self.owner, "Respawn", "", self.owner);
|
||||||
|
ScientistManager::TeleportToSpot(self.owner);
|
||||||
|
remove(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScientistManager::RespawnSingle(entity scientistEntity, float waitTime)
|
||||||
|
{
|
||||||
|
entity timer = spawn();
|
||||||
|
timer.owner = scientistEntity;
|
||||||
|
timer.think = _RespawnTimerFinished;
|
||||||
|
timer.nextthink = time + waitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScientistManager::TeleportToSpot(entity scientistEntity)
|
||||||
|
{
|
||||||
|
entity spawnPoint = game.FindRandomClassObject("monster_scientist");
|
||||||
|
setorigin(scientistEntity, spawnPoint.origin);
|
||||||
|
scientistEntity.angles = spawnPoint.angles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScientistManager::PopulateLevel(int sciNum, string decl)
|
||||||
|
{
|
||||||
|
int newMax = 0i;
|
||||||
|
|
||||||
|
for (entity s = world; (s = find(s, ::classname, "monster_scientist"));) {
|
||||||
|
newMax += 1i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sciNum > newMax) {
|
||||||
|
NSWarning("Scientists spawns for %i desired, can only deliver %i", sciNum, newMax);
|
||||||
|
sciNum = newMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < sciNum; i++) {
|
||||||
|
entity scientistEntity = ents.Create(decl, g_vec_null);
|
||||||
|
TeleportToSpot(scientistEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScientistManager::ClearScientists(string decl)
|
||||||
|
{
|
||||||
|
for (entity s = world; (s = find(s, ::classname, decl));) {
|
||||||
|
remove(s);
|
||||||
|
}
|
||||||
|
}
|
7
src/rules/shared.h
Normal file
7
src/rules/shared.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
bool
|
||||||
|
AllowFlashlight(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_flashlight");
|
||||||
|
}
|
||||||
|
|
151
src/rules/slaughter.qc
Normal file
151
src/rules/slaughter.qc
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma PROGS_DAT "../../zpak001.pk3dir/progs/slaughter.dat"
|
||||||
|
|
||||||
|
#include "../../../src/server/api.h"
|
||||||
|
#include "arsenal.h"
|
||||||
|
#include "scimanager.h"
|
||||||
|
#include "shared.h"
|
||||||
|
|
||||||
|
/* Slaughter is the default game mode. */
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_Input(entity activator, string inputName, string dataString)
|
||||||
|
{
|
||||||
|
switch (inputName) {
|
||||||
|
#if 0
|
||||||
|
case "CountScientists":
|
||||||
|
int livingScientists = 0i;
|
||||||
|
for (entity s = world; (s = find(s, ::classname, "monster_scientist"));) {
|
||||||
|
if (s.solid == SOLID_BBOX || s.solid == SOLID_SLIDEBOX) {
|
||||||
|
livingScientists++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverinfo.SetInteger("sci_count", livingScientists);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case "ScientistKilled":
|
||||||
|
activator.frags += 1;
|
||||||
|
break;
|
||||||
|
case "ScientistDied":
|
||||||
|
ScientistManager::RespawnSingle(activator, 10.0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_StartGameType(void)
|
||||||
|
{
|
||||||
|
SHArsenal_Init();
|
||||||
|
motd.LoadDefault();
|
||||||
|
game.SetSpawnPoint("info_player_team1");
|
||||||
|
ScientistManager::PopulateLevel(cvars.GetInteger("sh_scimax"), "sh_scientist");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
string playerModel;
|
||||||
|
|
||||||
|
ents.ChangeToClass(playerEntity, "player_slaughter");
|
||||||
|
|
||||||
|
/* interpret the 'model' InfoKey */
|
||||||
|
playerModel = userinfo.GetString(playerEntity, "model");
|
||||||
|
|
||||||
|
if (playerModel != "") {
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", playerModel, playerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* fallback is always models/player.mdl for Half-Life */
|
||||||
|
if (playerModel == "" || exists.InVFS(playerModel) == false) {
|
||||||
|
playerModel = "models/player.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
playerEntity.modelindex = getmodelindex(playerModel); /* keep OG size */
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
SHArsenal_GiveItemsToPlayer(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDisconnect(entity playerEntity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
CodeCallback_PlayerSpawn(playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDamage(entity playerEntity, entity inflictor, entity attacker)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||||
|
{
|
||||||
|
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||||
|
|
||||||
|
/* death-counter */
|
||||||
|
playerEntity.deaths++;
|
||||||
|
|
||||||
|
/* update score-counter */
|
||||||
|
if (ents.isPlayer(attacker)) {
|
||||||
|
if (playerEntity == attacker) {
|
||||||
|
attacker.frags--;
|
||||||
|
} else {
|
||||||
|
attacker.frags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ClientCommand(entity playerEntity, string command)
|
||||||
|
{
|
||||||
|
float commandArgs = tokenize(command);
|
||||||
|
|
||||||
|
switch (argv(0)) {
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
|
||||||
|
{
|
||||||
|
switch (impulseNum) {
|
||||||
|
case 100:
|
||||||
|
if (AllowFlashlight() == true) {
|
||||||
|
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
213
src/rules/stealth.qc
Normal file
213
src/rules/stealth.qc
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma PROGS_DAT "../../zpak001.pk3dir/progs/stealth.dat"
|
||||||
|
|
||||||
|
#include "../../../src/server/api.h"
|
||||||
|
|
||||||
|
string g_strTeamList;
|
||||||
|
const string mp_teamlist_fallback = "scientist;hgrunt";
|
||||||
|
var string autocvar_mp_teamlist = mp_teamlist_fallback;
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsTeamplay(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_teamplay");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AllowFlashlight(void)
|
||||||
|
{
|
||||||
|
return cvars.GetBool("mp_flashlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_StartGameType(void)
|
||||||
|
{
|
||||||
|
motd.LoadDefault();
|
||||||
|
|
||||||
|
if (IsTeamplay() == true) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* get the segments from our cvar */
|
||||||
|
g_strTeamList = autocvar_mp_teamlist;
|
||||||
|
c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
|
||||||
|
/* if we've got less than 2 teams, use the fallback... */
|
||||||
|
if (c < 2) {
|
||||||
|
g_strTeamList = mp_teamlist_fallback;
|
||||||
|
c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize all dem teams */
|
||||||
|
for (int i = 0; i < c; i++) {
|
||||||
|
teams.SetUp(i+1, argv(i), [255,255,255], true);
|
||||||
|
teams.SetSpawnPoint(i+1, "info_player_deathmatch");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
game.SetSpawnPoint("info_player_deathmatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HLDM_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
string playerModel;
|
||||||
|
|
||||||
|
ents.ChangeToClass(playerEntity, "player_mp");
|
||||||
|
|
||||||
|
if (IsTeamplay() == true) {
|
||||||
|
float teamCount = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
float playerTeam = playerEntity.team;
|
||||||
|
string teamModel;
|
||||||
|
|
||||||
|
/* not part of a team? pick one of the ones we have */
|
||||||
|
/* TODO: this should sort us into the lowest team */
|
||||||
|
if (playerTeam == 0) {
|
||||||
|
playerTeam = 1 + floor(random(0, teamCount)); /* teams start at 1 after all */
|
||||||
|
ents.Input(playerEntity, "SetTeam", ftos(playerTeam), playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
teamModel = argv(playerTeam - 1);
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", teamModel, teamModel);
|
||||||
|
} else {
|
||||||
|
/* interpret the 'model' InfoKey */
|
||||||
|
playerModel = userinfo.GetString(playerEntity, "model");
|
||||||
|
|
||||||
|
if (playerModel != "") {
|
||||||
|
playerModel = sprintf("models/player/%s/%s.mdl", playerModel, playerModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fallback is always models/player.mdl for Half-Life */
|
||||||
|
if (playerModel == "" || exists.InVFS(playerModel) == false) {
|
||||||
|
playerModel = "models/player.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
playerEntity.modelindex = getmodelindex(playerModel); /* keep OG size */
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerSpawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
if (IsTeamplay() == false) {
|
||||||
|
HLDM_PlayerSpawn(playerEntity);
|
||||||
|
} else {
|
||||||
|
ents.ChangeToClass(playerEntity, "spectator");
|
||||||
|
game.TeleportToSpawn(playerEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDisconnect(entity playerEntity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_PlayerRequestRespawn(entity playerEntity)
|
||||||
|
{
|
||||||
|
CodeCallback_PlayerSpawn(playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerDamage(entity playerEntity, entity inflictor, entity attacker)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_CallRequestTeam(entity playerEntity, int teamNum)
|
||||||
|
{
|
||||||
|
ents.Input(playerEntity, "SetTeam", itos(teamNum), playerEntity);
|
||||||
|
ents.Input(playerEntity, "Damage", "1000", playerEntity);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeCallback_PlayerKilled(entity playerEntity, entity inflictor, entity attacker, string weapon)
|
||||||
|
{
|
||||||
|
combat.Obituary(playerEntity.netname, attacker.netname, weapon, "");
|
||||||
|
|
||||||
|
/* death-counter */
|
||||||
|
playerEntity.deaths++;
|
||||||
|
|
||||||
|
/* update score-counter */
|
||||||
|
if (ents.isPlayer(attacker)) {
|
||||||
|
if (playerEntity == attacker) {
|
||||||
|
attacker.frags--;
|
||||||
|
} else {
|
||||||
|
attacker.frags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ClientCommand(entity playerEntity, string command)
|
||||||
|
{
|
||||||
|
float commandArgs = tokenize(command);
|
||||||
|
|
||||||
|
switch (argv(0)) {
|
||||||
|
case "chooseteam":
|
||||||
|
string teamName = argv(1);
|
||||||
|
|
||||||
|
/* wrong mode */
|
||||||
|
if (IsTeamplay() == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no team defined */
|
||||||
|
if (!teamName) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float c = tokenizebyseparator(g_strTeamList, ";");
|
||||||
|
|
||||||
|
for (float i = 0; i < c; i++) {
|
||||||
|
if (argv(i) == teamName) {
|
||||||
|
string newTeam = ftos(i + 1);
|
||||||
|
ents.Input(playerEntity, "SetTeam", newTeam, playerEntity);
|
||||||
|
ents.Input(playerEntity, "Damage", "1000", playerEntity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeCallback_ImpulseCommand(entity playerEntity, float impulseNum)
|
||||||
|
{
|
||||||
|
switch (impulseNum) {
|
||||||
|
case 100:
|
||||||
|
if (AllowFlashlight() == true) {
|
||||||
|
ents.Input(playerEntity, "UseItem", "item_suit", playerEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
|
||||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gamerules.h"
|
|
||||||
#include "../../../valve/src/server/items.h"
|
|
||||||
#include "../../../valve/src/server/flashlight.h"
|
|
|
@ -14,126 +14,6 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class HLGameRules:CGameRules
|
|
||||||
{
|
|
||||||
int m_iScientistsAlive;
|
|
||||||
|
|
||||||
float m_flRestockTimer;
|
|
||||||
float m_flBreakRespawnTimer;
|
|
||||||
|
|
||||||
/* client */
|
|
||||||
virtual void(NSClientPlayer) PlayerSpawn;
|
|
||||||
virtual void(NSClientPlayer) PlayerDeath;
|
|
||||||
virtual bool PlayerRequestRespawn(NSClientPlayer);
|
|
||||||
virtual bool ImpulseCommand(NSClient, float);
|
|
||||||
virtual void(NSClientPlayer) PlayerPostFrame;
|
|
||||||
virtual void(NSClientPlayer, entity) ScientistKill;
|
|
||||||
virtual void(void) RegisterSciDeath;
|
|
||||||
|
|
||||||
virtual bool(NSClientPlayer, string) ConsoleCommand;
|
|
||||||
virtual void(NSClientPlayer) LevelDecodeParms;
|
|
||||||
virtual void(NSClientPlayer) LevelChangeParms;
|
|
||||||
virtual void(void) LevelNewParms;
|
|
||||||
virtual void(void) FrameStart;
|
|
||||||
virtual void(void) CheckRules;
|
|
||||||
virtual bool(void) IsMultiplayer;
|
|
||||||
virtual void(void) RestartRound;
|
|
||||||
|
|
||||||
virtual void(void) CountScientists;
|
|
||||||
|
|
||||||
void(void) HLGameRules;
|
|
||||||
virtual void(void) InitPostEnts;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SHTeamRules:HLGameRules
|
|
||||||
{
|
|
||||||
int m_iKillsTeam1;
|
|
||||||
int m_iKillsTeam2;
|
|
||||||
|
|
||||||
int m_iScoreTeam1;
|
|
||||||
int m_iScoreTeam2;
|
|
||||||
|
|
||||||
void(void) SHTeamRules;
|
|
||||||
|
|
||||||
virtual void(void) RestartRound;
|
|
||||||
virtual void(NSClientPlayer) PlayerSpawn;
|
|
||||||
virtual bool(void) IsTeamplay;
|
|
||||||
virtual void(void) AddTeam1Kill;
|
|
||||||
virtual void(void) AddTeam2Kill;
|
|
||||||
virtual void(void) RegisterSciDeath;
|
|
||||||
virtual void(NSClientPlayer, entity) ScientistKill;
|
|
||||||
virtual void(void) InitPostEnts;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SHInvasionRules:HLGameRules
|
|
||||||
{
|
|
||||||
void(void) SHInvasionRules;
|
|
||||||
virtual void(void) RegisterSciDeath;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Standard Hunting (0):
|
|
||||||
Round-based competitive killing where scientists are always running around. Scientists don't respawn.
|
|
||||||
*/
|
|
||||||
class SHGameHunt:SHTeamRules
|
|
||||||
{
|
|
||||||
void(void) SHGameHunt;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Stealth Hunting (1):
|
|
||||||
Round-based competitive killing where scientists stand or walk around, but will run in fear if they see the player. Similar to deer hunting. Scientists don't respawn.
|
|
||||||
*/
|
|
||||||
class SHGameStealth:SHTeamRules
|
|
||||||
{
|
|
||||||
void(void) SHGameStealth;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Traditional Slaughter (2):
|
|
||||||
Casual killing where scientists behave the same as they were in Half-Life. Scientists respawn.
|
|
||||||
*/
|
|
||||||
class SHGameSlaughter:HLGameRules
|
|
||||||
{
|
|
||||||
void(void) SHGameSlaughter;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Live in Fear (3):
|
|
||||||
Unique round-based gamemode where players have to only kill an evil randomly selected player controlled scientist causing chaos. Those who kill good scientists are punished with lost points. The evil scientist gains one point from every kill (NPC or Players). Scientists respawn.
|
|
||||||
*/
|
|
||||||
class SHGameFear:SHTeamRules
|
|
||||||
{
|
|
||||||
void(void) SHGameFear;
|
|
||||||
virtual void(NSClientPlayer, entity) ScientistKill;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Madness (4):
|
|
||||||
Unique gamemode where scientists attack themselves and the players. Scientists inject players and NPCs only once with a poison that slowly drains their health to 0. The scientists also play a sound (sh/hide_laugh.wav) when they get a sucessful kill and are still alive. Scientists respawn.
|
|
||||||
*/
|
|
||||||
class SHGameMadness:HLGameRules
|
|
||||||
{
|
|
||||||
void(void) SHGameMadness;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Invasion (5):
|
|
||||||
Unique new round-based gamemode where scientists attack similar to madness but work together to kill everyone else. If players eleminate all scientists, then they win the round and have to do it all over again. Heavy WIP. Scientists and players don't respawn.
|
|
||||||
*/
|
|
||||||
class SHGameInvasion:SHInvasionRules
|
|
||||||
{
|
|
||||||
void(void) SHGameInvasion;
|
|
||||||
|
|
||||||
virtual string Title(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SHMODE_STANDARD = 0,
|
SHMODE_STANDARD = 0,
|
||||||
|
@ -170,4 +50,4 @@ var int autocvar_sh_announcescideath = 1;
|
||||||
var int autocvar_sh_announcescinum = 1;
|
var int autocvar_sh_announcescinum = 1;
|
||||||
|
|
||||||
/* default kills required for insanity */
|
/* default kills required for insanity */
|
||||||
var int autocvar_sh_insanity = 5;
|
var int autocvar_sh_insanity = 5;
|
||||||
|
|
|
@ -20,10 +20,10 @@ HLGameRules::RestartRound(void)
|
||||||
{
|
{
|
||||||
/* respawn all players and scientists */
|
/* respawn all players and scientists */
|
||||||
for (entity e = world; (e = find( e, ::classname, "player"));) {
|
for (entity e = world; (e = find( e, ::classname, "player"));) {
|
||||||
PlayerSpawn((NSClientPlayer)e);
|
PlayerSpawn((ncPlayer)e);
|
||||||
}
|
}
|
||||||
for (entity e = world; (e = find( e, ::classname, "monster_scientist"));) {
|
for (entity e = world; (e = find( e, ::classname, "monster_scientist"));) {
|
||||||
NSEntity sci = (NSEntity)e;
|
ncEntity sci = (ncEntity)e;
|
||||||
sci.Respawn();
|
sci.Respawn();
|
||||||
}
|
}
|
||||||
env_message_broadcast("New round, let's go!");
|
env_message_broadcast("New round, let's go!");
|
||||||
|
@ -42,7 +42,7 @@ HLGameRules::IsMultiplayer(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLGameRules::LevelDecodeParms(NSClientPlayer pp)
|
HLGameRules::LevelDecodeParms(ncPlayer pp)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
g_landmarkpos[0] = parm1;
|
g_landmarkpos[0] = parm1;
|
||||||
|
@ -61,7 +61,7 @@ HLGameRules::LevelDecodeParms(NSClientPlayer pp)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLGameRules::LevelChangeParms(NSClientPlayer pp)
|
HLGameRules::LevelChangeParms(ncPlayer pp)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
parm1 = g_landmarkpos[0];
|
parm1 = g_landmarkpos[0];
|
||||||
|
@ -91,7 +91,7 @@ HLGameRules::LevelNewParms(void)
|
||||||
/* we check what fields have changed over the course of the frame and network
|
/* we check what fields have changed over the course of the frame and network
|
||||||
* only the ones that have actually changed */
|
* only the ones that have actually changed */
|
||||||
void
|
void
|
||||||
HLGameRules::PlayerPostFrame(NSClientPlayer pp)
|
HLGameRules::PlayerPostFrame(ncPlayer pp)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ HLGameRules::CountScientists(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLGameRules::ScientistKill(NSClientPlayer pp, entity sci)
|
HLGameRules::ScientistKill(ncPlayer pp, entity sci)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ HLGameRules::CheckRules(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLGameRules::PlayerDeath(NSClientPlayer pl)
|
HLGameRules::PlayerDeath(ncPlayer pl)
|
||||||
{
|
{
|
||||||
SHPlayer sh_pl = (SHPlayer)pl;
|
SHPlayer sh_pl = (SHPlayer)pl;
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ HLGameRules::PlayerDeath(NSClientPlayer pl)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLGameRules::PlayerRequestRespawn(NSClientPlayer bp)
|
HLGameRules::PlayerRequestRespawn(ncPlayer bp)
|
||||||
{
|
{
|
||||||
if (bp.TimeSinceDeath() > 0.5f) {
|
if (bp.TimeSinceDeath() > 0.5f) {
|
||||||
bp.ScheduleThink(PutClientInServer, 0.0f);
|
bp.ScheduleThink(PutClientInServer, 0.0f);
|
||||||
|
@ -311,7 +311,7 @@ HLGameRules::PlayerRequestRespawn(NSClientPlayer bp)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLGameRules::PlayerSpawn(NSClientPlayer pp)
|
HLGameRules::PlayerSpawn(ncPlayer pp)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
/* this is where the mods want to deviate */
|
/* this is where the mods want to deviate */
|
||||||
|
@ -457,7 +457,7 @@ HLGameRules::HLGameRules(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLGameRules::ConsoleCommand(NSClientPlayer pp, string cmd)
|
HLGameRules::ConsoleCommand(ncPlayer pp, string cmd)
|
||||||
{
|
{
|
||||||
tokenize(cmd);
|
tokenize(cmd);
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ SHTeamRules::IsTeamplay(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHTeamRules::PlayerSpawn(NSClientPlayer pp)
|
SHTeamRules::PlayerSpawn(ncPlayer pp)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ SHTeamRules::PlayerSpawn(NSClientPlayer pp)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHTeamRules::ScientistKill(NSClientPlayer cl, entity sci)
|
SHTeamRules::ScientistKill(ncPlayer cl, entity sci)
|
||||||
{
|
{
|
||||||
super::ScientistKill(cl, sci);
|
super::ScientistKill(cl, sci);
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ SHInvasionRules::RegisterSciDeath(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHInvasionRules::PlayerDeath(NSClientPlayer pl)
|
SHInvasionRules::PlayerDeath(ncPlayer pl)
|
||||||
{
|
{
|
||||||
pl = (SHPlayer)pl;
|
pl = (SHPlayer)pl;
|
||||||
super::PlayerDeath(pl);
|
super::PlayerDeath(pl);
|
||||||
|
@ -622,7 +622,7 @@ SHInvasionRules::SHInvasionRules(void)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TriggerFlashlight(NSClient target)
|
TriggerFlashlight(ncClient target)
|
||||||
{
|
{
|
||||||
entity oldself = self;
|
entity oldself = self;
|
||||||
self = target;
|
self = target;
|
||||||
|
@ -631,7 +631,7 @@ TriggerFlashlight(NSClient target)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLGameRules::ImpulseCommand(NSClient bp, float num)
|
HLGameRules::ImpulseCommand(ncClient bp, float num)
|
||||||
{
|
{
|
||||||
switch (num) {
|
switch (num) {
|
||||||
case 100:
|
case 100:
|
||||||
|
|
|
@ -6,7 +6,7 @@ SHGameFear::SHGameFear(void)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SHGameFear::ScientistKill(NSClientPlayer pp, entity sci)
|
SHGameFear::ScientistKill(ncPlayer pp, entity sci)
|
||||||
{
|
{
|
||||||
SHPlayer pl = (SHPlayer)pp;
|
SHPlayer pl = (SHPlayer)pp;
|
||||||
|
|
||||||
|
|
|
@ -69,20 +69,16 @@ enum
|
||||||
SCIA_DEADTABLE3
|
SCIA_DEADTABLE3
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHScientist:NSTalkMonster
|
class SHScientist:ncTalkMonster
|
||||||
{
|
{
|
||||||
void SHScientist(void);
|
void SHScientist(void);
|
||||||
|
|
||||||
/* override */
|
/* override */
|
||||||
virtual void SeeThink(void);
|
virtual void SeeThink(void);
|
||||||
virtual float GetWalkSpeed(void);
|
|
||||||
virtual float GetChaseSpeed(void);
|
|
||||||
virtual float GetRunSpeed(void);
|
|
||||||
virtual void PanicFrame(void);
|
virtual void PanicFrame(void);
|
||||||
|
|
||||||
virtual void Respawn(void);
|
virtual void Respawn(void);
|
||||||
virtual void Pain(entity, entity, int, vector, int);
|
virtual void Death(entity, entity, int, vector, vector, int);
|
||||||
virtual void Death(entity, entity, int, vector, int);
|
|
||||||
virtual void PlayerUse(void);
|
virtual void PlayerUse(void);
|
||||||
virtual void TalkPanic(void);
|
virtual void TalkPanic(void);
|
||||||
|
|
||||||
|
@ -93,6 +89,12 @@ class SHScientist:NSTalkMonster
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SHScientist::SHScientist(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Players scare scientists if they see them in Stealth Hunting */
|
/* Players scare scientists if they see them in Stealth Hunting */
|
||||||
void
|
void
|
||||||
SHScientist::SeeThink(void)
|
SHScientist::SeeThink(void)
|
||||||
|
@ -126,27 +128,6 @@ SHScientist::PanicFrame(void)
|
||||||
input_movevalues = [6 * cvar("sh_scispeed"), 0, 0];
|
input_movevalues = [6 * cvar("sh_scispeed"), 0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
|
||||||
SHScientist::GetWalkSpeed(void)
|
|
||||||
{
|
|
||||||
super::GetWalkSpeed();
|
|
||||||
return 1.6 * cvar("sh_scispeed");
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
SHScientist::GetChaseSpeed(void)
|
|
||||||
{
|
|
||||||
super:: GetChaseSpeed();
|
|
||||||
return 6 * cvar("sh_scispeed");
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
|
||||||
SHScientist::GetRunSpeed(void)
|
|
||||||
{
|
|
||||||
super::GetRunSpeed();
|
|
||||||
return 3.5 * cvar("sh_scispeed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SHScientist::FallNoise(void)
|
SHScientist::FallNoise(void)
|
||||||
|
@ -180,7 +161,7 @@ SHScientist::AttackMelee(void)
|
||||||
|
|
||||||
/* set these globals for scientist's poison
|
/* set these globals for scientist's poison
|
||||||
* a little messy but it works */
|
* a little messy but it works */
|
||||||
.NSTimer poisonTimer;
|
.ncTimer poisonTimer;
|
||||||
.entity poisonSource;
|
.entity poisonSource;
|
||||||
.float OldTargetHealth;
|
.float OldTargetHealth;
|
||||||
|
|
||||||
|
@ -337,30 +318,9 @@ SHScientist::PlayerUse(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHScientist::Pain(entity inflictor, entity attacker, int damage, vector dir, int location)
|
SHScientist::Death(entity inflictor, entity attacker, int damage, vector dir, vector absImpactPos, int location)
|
||||||
{
|
|
||||||
super::Pain(inflictor, attacker, damage, dir, location);
|
|
||||||
|
|
||||||
/* make everyone on edge */
|
|
||||||
WarnAllies();
|
|
||||||
|
|
||||||
if (m_flAnimTime > time) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsAlive() == true) {
|
|
||||||
Sound_Speak(this, "monster_scientist.pain");
|
|
||||||
SetFrame(SCIA_FLINCH + floor(random(0, 6)));
|
|
||||||
m_iFlags |= MONSTER_FEAR;
|
|
||||||
m_flAnimTime = time + 0.25f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SHScientist::Death(entity inflictor, entity attacker, int damage, vector dir, int location)
|
|
||||||
{
|
{
|
||||||
bool deathcheck = false;
|
bool deathcheck = false;
|
||||||
HLGameRules rules = (HLGameRules)g_grMode;
|
|
||||||
|
|
||||||
/* upset everyone */
|
/* upset everyone */
|
||||||
if not (g_chosen_mode == SHMODE_MADNESS || g_chosen_mode == SHMODE_INVASION)
|
if not (g_chosen_mode == SHMODE_MADNESS || g_chosen_mode == SHMODE_INVASION)
|
||||||
|
@ -368,61 +328,32 @@ SHScientist::Death(entity inflictor, entity attacker, int damage, vector dir, in
|
||||||
|
|
||||||
if (IsAlive() == true) {
|
if (IsAlive() == true) {
|
||||||
SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
|
SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
|
||||||
rules.ScientistKill((SHPlayer)attacker, (entity)this);
|
g_grMode.Input(attacker, "ScientistKilled", "");
|
||||||
|
|
||||||
Plugin_PlayerObituary(attacker, this, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage);
|
|
||||||
Sound_Speak(this, "monster_scientist.die");
|
|
||||||
deathcheck = true;
|
deathcheck = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now mark our state as 'dead' */
|
/* now mark our state as 'dead' */
|
||||||
super::Death(inflictor, attacker, damage, dir, location);
|
super::Death(inflictor, attacker, damage, dir, absImpactPos, location);
|
||||||
|
|
||||||
/* now we'll tell our kill function about it, since we're now legally dead */
|
/* now we'll tell our kill function about it, since we're now legally dead */
|
||||||
if (deathcheck == true) {
|
if (deathcheck == true) {
|
||||||
rules.RegisterSciDeath();
|
g_grMode.Input(this, "ScientistDied", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* will not respawn by themselves in these modes */
|
|
||||||
if (g_chosen_mode == SHMODE_STANDARD || g_chosen_mode == SHMODE_STEALTH || g_chosen_mode == SHMODE_INVASION)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ScheduleThink(Respawn, 10.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHScientist::Respawn(void)
|
SHScientist::Respawn(void)
|
||||||
{
|
{
|
||||||
HLGameRules rules = (HLGameRules)g_grMode;
|
|
||||||
|
|
||||||
/* don't spawn if we're hitting scimax */
|
|
||||||
if (serverkeyfloat("sci_count") >= serverkeyfloat("sv_scimax"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
super::Respawn();
|
super::Respawn();
|
||||||
|
|
||||||
/* unset notarget for attacking scientists
|
|
||||||
* TODO in the future we shouldn't have to mess with flags this way */
|
|
||||||
flags &= ~FL_NOTARGET;
|
|
||||||
|
|
||||||
if not (g_chosen_mode == SHMODE_MADNESS || g_chosen_mode == SHMODE_INVASION)
|
|
||||||
m_iFlags |= MONSTER_CANFOLLOW;
|
|
||||||
|
|
||||||
/* attack EVERYONE */
|
|
||||||
if (g_chosen_mode == SHMODE_MADNESS)
|
|
||||||
m_iAlliance = MAL_ROGUE;
|
|
||||||
|
|
||||||
/* attack anyone but aliens */
|
|
||||||
if (g_chosen_mode == SHMODE_INVASION)
|
|
||||||
m_iAlliance = MAL_ALIEN;
|
|
||||||
|
|
||||||
/* scientists are always afraid in these modes */
|
/* scientists are always afraid in these modes */
|
||||||
if (g_chosen_mode == SHMODE_STANDARD || g_chosen_mode == SHMODE_MADNESS || g_chosen_mode == SHMODE_INVASION) {
|
if (g_chosen_mode == SHMODE_STANDARD || g_chosen_mode == SHMODE_MADNESS || g_chosen_mode == SHMODE_INVASION) {
|
||||||
m_iFlags |= MONSTER_FEAR;
|
m_iFlags |= MONSTER_FEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_iBody <= 0i)
|
if (m_iBody <= 0i) {
|
||||||
m_iBody = 0i;
|
m_iBody = 0i;
|
||||||
|
}
|
||||||
|
|
||||||
if ((cvar("sh_scirand") == 1) || (m_iBody == 0i)) {
|
if ((cvar("sh_scirand") == 1) || (m_iBody == 0i)) {
|
||||||
m_iBody = floor(random(1,5));
|
m_iBody = floor(random(1,5));
|
||||||
|
@ -452,13 +383,4 @@ SHScientist::Respawn(void)
|
||||||
SetBodyInGroup(1, 4);
|
SetBodyInGroup(1, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recount to update sciscore and so on */
|
|
||||||
rules.CountScientists();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SHScientist::SHScientist(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,14 @@
|
||||||
../../../src/botlib/botinfo.h
|
../../../src/botlib/botinfo.h
|
||||||
../../../src/gs-entbase/server.src
|
../../../src/gs-entbase/server.src
|
||||||
../../../src/gs-entbase/shared.src
|
../../../src/gs-entbase/shared.src
|
||||||
defs.h
|
../../../valve/src/server/defs.h
|
||||||
../shared/include.src
|
../shared/include.src
|
||||||
|
gamerules.h
|
||||||
monster_scientist.qc
|
monster_scientist.qc
|
||||||
../../../valve/src/server/player.qc
|
|
||||||
../../../src/botlib/include.src
|
../../../src/botlib/include.src
|
||||||
shdata_parse.qc
|
shdata_parse.qc
|
||||||
gamerules.qc
|
|
||||||
gamerules_fear.qc
|
|
||||||
gamerules_hunt.qc
|
|
||||||
gamerules_invasion.qc
|
|
||||||
gamerules_madness.qc
|
|
||||||
gamerules_slaughter.qc
|
|
||||||
gamerules_stealth.qc
|
|
||||||
server.qc
|
server.qc
|
||||||
../../../valve/src/server/flashlight.qc
|
../../../valve/src/server/HLSuit.qc
|
||||||
../../../valve/src/server/spawn.qc
|
|
||||||
../../../src/server/include.src
|
../../../src/server/include.src
|
||||||
../../../src/shared/include.src
|
../../../src/shared/include.src
|
||||||
#endlist
|
#endlist
|
||||||
|
|
|
@ -20,26 +20,24 @@ Game_InitRules(void)
|
||||||
g_chosen_mode = autocvar_sh_realistic;
|
g_chosen_mode = autocvar_sh_realistic;
|
||||||
|
|
||||||
switch (autocvar_sh_realistic) {
|
switch (autocvar_sh_realistic) {
|
||||||
case SHMODE_STANDARD:
|
|
||||||
g_grMode = spawn(SHGameHunt);
|
|
||||||
break;
|
|
||||||
case SHMODE_STEALTH:
|
case SHMODE_STEALTH:
|
||||||
g_grMode = spawn(SHGameStealth);
|
g_grMode = ncGameRules::InitFromProgs("progs/stealth.dat");
|
||||||
break;
|
break;
|
||||||
case SHMODE_SLAUGHTER:
|
case SHMODE_SLAUGHTER:
|
||||||
g_grMode = spawn(SHGameSlaughter);
|
g_grMode = ncGameRules::InitFromProgs("progs/slaughter.dat");
|
||||||
break;
|
break;
|
||||||
case SHMODE_LIVEINFEAR:
|
case SHMODE_LIVEINFEAR:
|
||||||
g_grMode = spawn(SHGameFear);
|
g_grMode = ncGameRules::InitFromProgs("progs/fear.dat");
|
||||||
break;
|
break;
|
||||||
case SHMODE_MADNESS:
|
case SHMODE_MADNESS:
|
||||||
g_grMode = spawn(SHGameMadness);
|
g_grMode = ncGameRules::InitFromProgs("progs/madness.dat");
|
||||||
break;
|
break;
|
||||||
case SHMODE_INVASION:
|
case SHMODE_INVASION:
|
||||||
g_grMode = spawn(SHGameInvasion);
|
g_grMode = ncGameRules::InitFromProgs("progs/invasion.dat");
|
||||||
break;
|
break;
|
||||||
|
case SHMODE_STANDARD:
|
||||||
default:
|
default:
|
||||||
g_grMode = spawn(HLGameRules);
|
g_grMode = ncGameRules::InitFromProgs("progs/hunt.dat");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +68,5 @@ Game_Worldspawn(void)
|
||||||
EntityDef_Precache("weapon_chainsaw");
|
EntityDef_Precache("weapon_chainsaw");
|
||||||
EntityDef_Precache("weapon_hammer");
|
EntityDef_Precache("weapon_hammer");
|
||||||
|
|
||||||
Player_Precache();
|
|
||||||
SHData_Parse(mapname);
|
SHData_Parse(mapname);
|
||||||
FX_Corpse_Init();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,15 @@
|
||||||
../../../valve/src/shared/entities.h
|
../../../valve/src/shared/entities.h
|
||||||
../../../valve/src/shared/events.h
|
../../../valve/src/shared/events.h
|
||||||
../../../valve/src/shared/flags.h
|
../../../valve/src/shared/flags.h
|
||||||
|
../../../valve/src/shared/skeleton.h
|
||||||
../../../valve/src/shared/player.qc
|
../../../valve/src/shared/player.qc
|
||||||
player.qc
|
player.qc
|
||||||
../../../valve/src/shared/pmove.qc
|
|
||||||
pmove.qc
|
pmove.qc
|
||||||
../../../valve/src/shared/animations.h
|
../../../valve/src/shared/animations.h
|
||||||
../../../valve/src/shared/animations.qc
|
../../../valve/src/shared/animations.qc
|
||||||
|
|
||||||
../../../valve/src/shared/fx_blood.qc
|
../../../valve/src/shared/fx_blood.qc
|
||||||
../../../valve/src/shared/fx_gaussbeam.qc
|
../../../valve/src/shared/fx_gaussbeam.qc
|
||||||
../../../valve/src/shared/fx_corpse.qc
|
|
||||||
../../../valve/src/shared/HLGaussBeam.qc
|
../../../valve/src/shared/HLGaussBeam.qc
|
||||||
../../../valve/src/shared/HLWeapon.qc
|
../../../valve/src/shared/HLWeapon.qc
|
||||||
../../../valve/src/shared/w_tripmine.qc
|
../../../valve/src/shared/w_tripmine.qc
|
||||||
|
|
|
@ -68,7 +68,7 @@ SHPlayer::SHPlayer(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHSciAnim_PlayerUpdate(NSClientPlayer playerTarget)
|
SHSciAnim_PlayerUpdate(ncPlayer playerTarget)
|
||||||
{
|
{
|
||||||
bool useTopAnim;
|
bool useTopAnim;
|
||||||
SHPlayer pl = (SHPlayer)playerTarget;
|
SHPlayer pl = (SHPlayer)playerTarget;
|
||||||
|
@ -199,7 +199,7 @@ void
|
||||||
SHPlayer::ReceiveEntity(float new, float flChanged)
|
SHPlayer::ReceiveEntity(float new, float flChanged)
|
||||||
{
|
{
|
||||||
/* the generic client attributes */
|
/* the generic client attributes */
|
||||||
NSClientPlayer::ReceiveEntity(new, flChanged);
|
ncPlayer::ReceiveEntity(new, flChanged);
|
||||||
|
|
||||||
/* animation */
|
/* animation */
|
||||||
READENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
|
READENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
|
||||||
|
@ -318,7 +318,7 @@ SHPlayer::SendEntity(entity ePEnt, float flChanged)
|
||||||
flChanged = OptimiseChangedFlags(ePEnt, flChanged);
|
flChanged = OptimiseChangedFlags(ePEnt, flChanged);
|
||||||
|
|
||||||
/* the generic client attributes */
|
/* the generic client attributes */
|
||||||
NSClientPlayer::SendEntity(ePEnt, flChanged);
|
ncPlayer::SendEntity(ePEnt, flChanged);
|
||||||
|
|
||||||
SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
|
SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
|
||||||
SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
|
SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
entityDef monster_scientist
|
entityDef monster_scientist
|
||||||
|
{
|
||||||
|
"editor_mins" "-16 -16 -36"
|
||||||
|
"editor_maxs" "16 16 36"
|
||||||
|
"editor_description" "Scientist Spawn Point"
|
||||||
|
"editor_color" "1 0 0"
|
||||||
|
"spawnclass" "ncSpawnPoint"
|
||||||
|
}
|
||||||
|
|
||||||
|
entityDef sh_scientist
|
||||||
{
|
{
|
||||||
"spawnclass" "SHScientist"
|
"spawnclass" "SHScientist"
|
||||||
"model" "models/scientist.mdl"
|
"model" "models/scientist.mdl"
|
||||||
|
@ -11,12 +20,11 @@ entityDef monster_scientist
|
||||||
"propdata" "actor_human"
|
"propdata" "actor_human"
|
||||||
|
|
||||||
"follow_on_use" "1"
|
"follow_on_use" "1"
|
||||||
"speed_walk" "64"
|
"speed_walk" "64"
|
||||||
"speed_run" "364"
|
"speed_run" "364"
|
||||||
|
|
||||||
"snd_pain" "monster_scientist.pain"
|
"snd_pain" "Scientist.Pain"
|
||||||
"snd_death" "monster_scientist.die"
|
"snd_death" "Scientist.Die"
|
||||||
"snd_thud" "monster_scientist.thud"
|
|
||||||
|
|
||||||
"talk_answer" "!SC_ANSWER"
|
"talk_answer" "!SC_ANSWER"
|
||||||
"talk_ask" "!SC_QUESTION"
|
"talk_ask" "!SC_QUESTION"
|
||||||
|
@ -37,38 +45,23 @@ entityDef monster_scientist
|
||||||
"talk_follow" "!SC_OK"
|
"talk_follow" "!SC_OK"
|
||||||
"talk_stop_follow" "!SC_STOP"
|
"talk_stop_follow" "!SC_STOP"
|
||||||
"talk_deny_follow" "!SC_POK"
|
"talk_deny_follow" "!SC_POK"
|
||||||
|
}
|
||||||
|
|
||||||
when "body" equals "1" {
|
|
||||||
"pitch" "105"
|
|
||||||
"netname" "Walter"
|
|
||||||
"body1" "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
when "body" equals "2" {
|
entityDef sh_scientist_madness
|
||||||
"pitch" "100"
|
{
|
||||||
"netname" "Einstein"
|
"inherit" "sh_scientist"
|
||||||
"body1" "2"
|
"def_attack_melee" "scientist_syringe_poison"
|
||||||
}
|
"melee_range" "96"
|
||||||
|
"act_meleeAttack1" "61"
|
||||||
|
"act_meleeAttack2" "61"
|
||||||
|
"team" "4"
|
||||||
|
}
|
||||||
|
|
||||||
when "body" equals "3" {
|
entityDef scientist_syringe_poison
|
||||||
"pitch" "95"
|
{
|
||||||
"netname" "Luther"
|
"damage" "15"
|
||||||
"skin" "1"
|
"delay" "0.5"
|
||||||
"body1" "3"
|
"wait" "0.5"
|
||||||
}
|
"attempts" "2"
|
||||||
|
}
|
||||||
when "body" equals "4" {
|
|
||||||
"pitch" "105"
|
|
||||||
"netname" "Slick"
|
|
||||||
"body1" "4"
|
|
||||||
}
|
|
||||||
|
|
||||||
// pre-disaster
|
|
||||||
when "spawnflags" equals "256" {
|
|
||||||
"talk_ask" ""
|
|
||||||
"talk_player_ask" "!SC_PQUEST"
|
|
||||||
"talk_player_greet" "!SC_PHELLO"
|
|
||||||
"talk_player_idle" "!SC_PIDLE"
|
|
||||||
"follow_on_use" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,3 +2,13 @@ entityDef player
|
||||||
{
|
{
|
||||||
"spawnclass" "SHPlayer"
|
"spawnclass" "SHPlayer"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityDef player_slaughter
|
||||||
|
{
|
||||||
|
"inherit" "player"
|
||||||
|
"ammo_9mm" "44"
|
||||||
|
"item" "item_suit"
|
||||||
|
"weapon" "weapon_crowbar,weapon_9mmhandgun"
|
||||||
|
"current_weapon" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ entityDef info_player_start
|
||||||
"editor_maxs" "16 16 36"
|
"editor_maxs" "16 16 36"
|
||||||
"editor_description" "Singleplayer Spawn Point"
|
"editor_description" "Singleplayer Spawn Point"
|
||||||
"editor_color" "1 0 0"
|
"editor_color" "1 0 0"
|
||||||
"spawnclass" "NSSpawnPoint"
|
"spawnclass" "ncSpawnPoint"
|
||||||
}
|
}
|
||||||
|
|
||||||
entityDef info_player_deathmatch
|
entityDef info_player_deathmatch
|
||||||
|
@ -13,7 +13,7 @@ entityDef info_player_deathmatch
|
||||||
"editor_maxs" "16 16 36"
|
"editor_maxs" "16 16 36"
|
||||||
"editor_description" "Deathmatch Spawn Point"
|
"editor_description" "Deathmatch Spawn Point"
|
||||||
"editor_color" "1 0 0"
|
"editor_color" "1 0 0"
|
||||||
"spawnclass" "NSSpawnPoint"
|
"spawnclass" "ncSpawnPoint"
|
||||||
}
|
}
|
||||||
|
|
||||||
entityDef info_player_coop
|
entityDef info_player_coop
|
||||||
|
@ -22,7 +22,7 @@ entityDef info_player_coop
|
||||||
"editor_maxs" "16 16 36"
|
"editor_maxs" "16 16 36"
|
||||||
"editor_description" "Cooperative Spawn Point"
|
"editor_description" "Cooperative Spawn Point"
|
||||||
"editor_color" "1 0 0"
|
"editor_color" "1 0 0"
|
||||||
"spawnclass" "NSSpawnPoint"
|
"spawnclass" "ncSpawnPoint"
|
||||||
}
|
}
|
||||||
|
|
||||||
entityDef info_player_team1
|
entityDef info_player_team1
|
||||||
|
@ -31,7 +31,7 @@ entityDef info_player_team1
|
||||||
"editor_maxs" "16 16 36"
|
"editor_maxs" "16 16 36"
|
||||||
"editor_description" "Red Team Spawn Point"
|
"editor_description" "Red Team Spawn Point"
|
||||||
"editor_color" "1 0 0"
|
"editor_color" "1 0 0"
|
||||||
"spawnclass" "NSSpawnPoint"
|
"spawnclass" "ncSpawnPoint"
|
||||||
}
|
}
|
||||||
|
|
||||||
entityDef info_player_team2
|
entityDef info_player_team2
|
||||||
|
@ -40,5 +40,5 @@ entityDef info_player_team2
|
||||||
"editor_maxs" "16 16 36"
|
"editor_maxs" "16 16 36"
|
||||||
"editor_description" "Blue Team Spawn Point"
|
"editor_description" "Blue Team Spawn Point"
|
||||||
"editor_color" "0 0 1"
|
"editor_color" "0 0 1"
|
||||||
"spawnclass" "NSSpawnPoint"
|
"spawnclass" "ncSpawnPoint"
|
||||||
}
|
}
|
|
@ -42,7 +42,7 @@ entityDef damage_hammerCharged
|
||||||
|
|
||||||
entityDef projectile_hammer
|
entityDef projectile_hammer
|
||||||
{
|
{
|
||||||
"spawnclass" "NSProjectile"
|
"spawnclass" "ncProjectile"
|
||||||
"damage" "skill:plr_hammer"
|
"damage" "skill:plr_hammer"
|
||||||
"is_bullet" "1"
|
"is_bullet" "1"
|
||||||
"decal_impact" "Impact.Shot"
|
"decal_impact" "Impact.Shot"
|
||||||
|
@ -52,7 +52,7 @@ entityDef projectile_hammer
|
||||||
|
|
||||||
entityDef projectile_hammerCharged
|
entityDef projectile_hammerCharged
|
||||||
{
|
{
|
||||||
"spawnclass" "NSProjectile"
|
"spawnclass" "ncProjectile"
|
||||||
"def_damage" "damage_hammerCharged"
|
"def_damage" "damage_hammerCharged"
|
||||||
"is_bullet" "1"
|
"is_bullet" "1"
|
||||||
"decal_impact" "Impact.Shot"
|
"decal_impact" "Impact.Shot"
|
||||||
|
|
5
zpak001.pk3dir/quake.rc
Normal file
5
zpak001.pk3dir/quake.rc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
exec default_controls.cfg
|
||||||
|
exec default_cvar.cfg
|
||||||
|
exec default_video.cfg
|
||||||
|
exec default_valve.cfg
|
||||||
|
exec default_scihunt.cfg
|
Loading…
Reference in a new issue