Initial commit.

This commit is contained in:
Marco Cawthorne 2024-03-14 17:23:29 -07:00
commit d77429ae74
Signed by: eukara
GPG key ID: CE2032F0A2882A22
46 changed files with 2442 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
data.pk3dir/

38
README.md Normal file
View file

@ -0,0 +1,38 @@
# FreeCoD
Blub blub.
![Preview 1](img/preview1.jpg)
![Preview 2](img/preview2.jpg)
![Preview 3](img/preview3.jpg)
![Preview 4](img/preview4.jpg)
## To-do list:
- Everything.
Other than that, it should be fairly representative of Call of Duty.
## Overview
This is a port of Call of Duty (MP) to Nuclide.
You have to own a copy of the game to play this.
All the code, resources etc. in this repo are of my own research and creation.
## License
ISC License
Copyright (c) 2024 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
img/preview2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
img/preview3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
img/preview4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

14
manifest.fmf Normal file
View file

@ -0,0 +1,14 @@
FTEMANIFEST 1
NAME "Call of Duty"
GAME cod
BASEGAME platform
BASEGAME cod
// you don't really want to change these
RTCBROKER master.frag-net.com:27950
PROTOCOLNAME "Nuclide"
MAINCONFIG nuclide.cfg
DOWNLOADSURL ""
-exec platform_default.cfg
-plug_load cod

6
src/Makefile Normal file
View file

@ -0,0 +1,6 @@
CC=fteqcc
all:
cd client && $(MAKE)
cd server && $(MAKE)
cd menu && $(MAKE)

4
src/client/Makefile Normal file
View file

@ -0,0 +1,4 @@
CC=fteqcc
all:
$(CC) progs.src

81
src/client/camera.qc Normal file
View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
struct
{
float m_flSpeed;
float m_flFracSin;
float m_flTime;
float m_flMove;
float m_flDelta;
int m_iCycle;
} g_camBobVars[4], *pCamBob;
/* tilts the camera for a head-bob like effect when moving */
void
Camera_RunBob(__inout vector camera_angle)
{
if (!autocvar(v_cambob, 1, "Enables bobbing effect for the first-person camera"))
return;
int s = (float)getproperty(VF_ACTIVESEAT);
pCamBob = &g_camBobVars[s];
/* we don't really care about the vertical velocity */
vector speed = pSeat->m_vecPredictedVelocity;
speed[2] = 0.0f;
pCamBob->m_flSpeed = vlen(speed);
/* don't bother on low speeds */
if ( pCamBob->m_flSpeed < 5.0f ) {
pCamBob->m_flMove = 0.0f;
pCamBob->m_flTime = 0.0f; /* progress has halted, start anew */
return;
} else if (pSeat->m_ePlayer.flags & FL_ONGROUND && pSeat->m_ePlayer.waterlevel == 0) {
pCamBob->m_flMove = clframetime * (pCamBob->m_flSpeed * 0.01);
} else {
pCamBob->m_flMove = 0.0f;
}
pCamBob->m_flTime = (pCamBob->m_flTime += pCamBob->m_flMove);
pCamBob->m_flFracSin = fabs(sin(pCamBob->m_flTime * M_PI));
pCamBob->m_iCycle = (int)pCamBob->m_flTime;
pCamBob->m_flDelta = (pCamBob->m_flFracSin * 0.0025f) * pCamBob->m_flSpeed;
camera_angle[0] += pCamBob->m_flDelta;
if (pCamBob->m_iCycle & 1) {
pCamBob->m_flDelta = -pCamBob->m_flDelta;
}
camera_angle[2] += pCamBob->m_flDelta;
}
/* applies a tilt to the camera for when we're strafing left to right */
void
Camera_StrafeRoll(__inout vector camera_angle)
{
if (!autocvar(v_camroll, 0, "Enables strafe-roll for the first-person camera"))
return;
float roll;
makevectors(camera_angle);
roll = dotproduct(pSeat->m_vecPredictedVelocity, v_right);
roll *= 0.015f;
camera_angle[2] += roll;
}

27
src/client/cmds.qc Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
/* This is where custom game-specific commands go!
* You'll also inherit all the commands defined in entry.c */
int
ClientGame_ConsoleCommand(void)
{
switch(argv(0)) {
default:
return (0);
}
return (1);
}

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

@ -0,0 +1,23 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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_hudmins;
vector g_hudres;
struct
{
float temp;
} g_seatslocal[4], *pSeatLocal;

27
src/client/draw.qc Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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_PreDraw(void)
{
}
void
ClientGame_PostDraw(void)
{
}

26
src/client/entities.qc Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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) {
default:
return (0);
}
return (1);
}

39
src/client/game_event.qc Normal file
View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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_EventParse(float fHeader)
{
switch (fHeader) {
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;
default:
return (0);
}
return (1);
}

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

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
const float baseIconSize = 32.0;
const float baseIconPadding = 16.0;
/* main entry */
void
HUD_Init(void)
{
}
/* main entry */
void
HUD_Draw(void)
{
Textmenu_Draw();
}
/* specatator main entry */
void
HUD_DrawSpectator(void)
{
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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_Forward(void)
{
}
void
HUD_DrawWeaponSelect_Back(void)
{
}
void
HUD_DrawWeaponSelect_Trigger(void)
{
}
void
HUD_DrawWeaponSelect_Last(void)
{
}
void
HUD_SlotSelect(int slot)
{
}
void
HUD_DrawWeaponSelect(void)
{
}

37
src/client/init.qc Normal file
View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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)
{
}
void
ClientGame_InitDone(void)
{
}
void
ClientGame_RendererRestart(string rstr)
{
}

40
src/client/progs.src Normal file
View file

@ -0,0 +1,40 @@
#pragma target fte_5768
#pragma progs_dat "../../csprogs.dat"
#define CSQC
#define CLIENT
#includelist
/* first the engine, then nuclide headers for client/shared */
../../../src/shared/fteextensions.qc
../../../src/shared/defs.h
../../../src/client/defs.h
/* mod specific header */
defs.h
/* for VGUI elements, we want to include this (optional) */
../../../src/vgui/include.src
/* include the entity codebase */
../../../src/gs-entbase/client.src
../../../src/gs-entbase/shared.src
/* mod specific functions */
../shared/include.src
draw.qc
init.qc
entities.qc
camera.qc
cmds.qc
game_event.qc
viewmodel.qc
hud.qc
hud_weaponselect.qc
scoreboard.qc
/* global client/shared code */
../../../src/client/include.src
../../../src/shared/include.src
#endlist

168
src/client/scoreboard.qc Normal file
View file

@ -0,0 +1,168 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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_GetID(FONT_20);
drawstring(pos + [0,-18], "Teams", [8,8], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [124,-18], "kills / deaths", [8,8], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [240,-18], "latency", [8,8], 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)), [8,8], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
temp = serverkey(sprintf("teamscore_%i", t));
l = stringwidth(temp, FALSE, [8,8]);
drawstring(pos + [150-l, 0], temp, [8,8], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [158, 0], "wins", [8,8], 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"), [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [154,0], "/", [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Get the kills and align them left to right */
temp = getplayerkeyvalue(i, "frags");
l = stringwidth(temp, FALSE, [8,8]);
drawstring(pos + [150 - l,0], temp, [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Deaths are right to left aligned */
temp = getplayerkeyvalue(i, "*deaths");
drawstring(pos + [165,0], temp, [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Get the latency and align it left to right */
temp = getplayerkeyvalue(i, "ping");
l = stringwidth(temp, FALSE, [8,8]);
drawstring(pos + [290 - l,0], temp, [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
pos[1] += 20;
}
pos[1] += 12;
}
drawfont = Font_GetID(FONT_CON);
}
void
Scores_DrawNormal(player pl, vector pos)
{
drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE);
drawfont = Font_GetID(FONT_20);
drawstring(pos + [0,-18], "Player", [8,8], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [124,-18], "kills / deaths", [8,8], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [240,-18], "latency", [8,8], 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"), [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
drawstring(pos + [154,0], "/", [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Get the kills and align them left to right */
kills = getplayerkeyvalue(i, "frags");
l = stringwidth(kills, FALSE, [8,8]);
drawstring(pos + [150 - l,0], kills, [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Deaths are right to left aligned */
deaths = getplayerkeyvalue(i, "*deaths");
drawstring(pos + [165,0], deaths, [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
/* Get the latency and align it left to right */
ping = getplayerkeyvalue(i, "ping");
l = stringwidth(ping, FALSE, [8,8]);
drawstring(pos + [290 - l,0], ping, [8,8], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE);
pos[1] += 20;
}
drawfont = Font_GetID(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 (Util_IsTeamplay()) {
Scores_DrawTeam(pl, pos);
} else {
Scores_DrawNormal(pl, pos);
}
}

140
src/client/viewmodel.qc Normal file
View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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 autocvar_v_bob = 0.01f;
var float autocvar_v_bobcycle = 1.0f;
var float autocvar_v_bobup = 0.5f;
struct
{
float m_flBobTime;
float m_flBobTime2;
float m_flBob;
float m_flBob2;
float m_flBobCycle;
float m_flBobCycle2;
float m_flSpeed;
} g_viewBobVars[4], *pViewBob;
/* bob vars are calculated separately from application, so that if there's
* more than one viewmodel we won't affect the speed of the bob by running
* the math too many times */
void
Viewmodel_CalcBob(void)
{
int s = (float)getproperty(VF_ACTIVESEAT);
pViewBob = &g_viewBobVars[s];
vector vecVel;
float flBob;
float var_bob;
float var_cycle;
float var_up;
var_bob = autocvar_v_bob;
var_cycle = autocvar_v_bobcycle;
var_up = autocvar_v_bobup;
pViewBob->m_flBobTime += clframetime;
pViewBob->m_flBobTime2 += clframetime;
pViewBob->m_flBobCycle = pViewBob->m_flBobTime - (int)(pViewBob->m_flBobTime / var_cycle) * var_cycle;
pViewBob->m_flBobCycle /= var_cycle;
if (pViewBob->m_flBobCycle < var_up) {
pViewBob->m_flBobCycle = MATH_PI * pViewBob->m_flBobCycle / var_up;
} else {
pViewBob->m_flBobCycle = MATH_PI + MATH_PI * (pViewBob->m_flBobCycle - var_up)/(1.0 - var_up);
}
vecVel = pSeat->m_vecPredictedVelocity;
vecVel[2] = 0;
pViewBob->m_flSpeed = vlen(vecVel);
flBob = pViewBob->m_flSpeed * var_bob;
flBob = flBob * 0.3 + flBob * 0.7 * sin(pViewBob->m_flBobCycle);
pViewBob->m_flBob = bound(-7, flBob, 4);
/* BOB2, which is half the cycle of bob1 */
pViewBob->m_flBobCycle2 = pViewBob->m_flBobTime2 - (int)(pViewBob->m_flBobTime2 / (var_cycle * 0.5f)) * (var_cycle * 0.5f);
pViewBob->m_flBobCycle2 /= (var_cycle * 0.5f);
if (pViewBob->m_flBobCycle2 < var_up) {
pViewBob->m_flBobCycle2 = MATH_PI * pViewBob->m_flBobCycle2 / var_up;
} else {
pViewBob->m_flBobCycle2 = MATH_PI + MATH_PI * (pViewBob->m_flBobCycle2 - var_up)/(1.0 - var_up);
}
flBob = pViewBob->m_flSpeed * var_bob;
flBob = flBob * 0.3 + flBob * 0.7 * sin(pViewBob->m_flBobCycle2);
pViewBob->m_flBob2 = bound(-7, flBob, 4);
/* make sure it's adjusted for scale */
pViewBob->m_flBob *= autocvar_cg_viewmodelScale;
}
void
Viewmodel_ApplyBob(entity gun)
{
int s = (float)getproperty(VF_ACTIVESEAT);
pViewBob = &g_viewBobVars[s];
float sintime;
float strength;
gun.angles[2] = -pViewBob->m_flBob;
vector angmod = [0,0,0];
angmod[0] -= pViewBob->m_flBob2 * 0.5f;
angmod[1] += pViewBob->m_flBob * 2.5f;
angmod[2] += pViewBob->m_flBob * 3.0f;
gun.angles += angmod * 1.5f;
/* sway with speed */
sintime = sin(time);
strength = pViewBob->m_flSpeed;
if (strength > 240)
strength = 240;
strength = 240 - strength;
strength *= 0.005f;
#ifdef WASTES
float sprint;
if (pSeatLocal->m_iSprinting && vlen(pSeat->m_vecPredictedVelocity) > 240) {
pSeatLocal->m_flSprintLerp = bound(0.0f, pSeatLocal->m_flSprintLerp + clframetime, 1.0f);
} else {
pSeatLocal->m_flSprintLerp = bound(0.0f, pSeatLocal->m_flSprintLerp - clframetime, 1.0f);
}
sprint = 20 * pSeatLocal->m_flSprintLerp;
gun.angles[0] += sprint;
gun.angles[1] += sprint + (sprint * pViewBob->m_flBob) * 0.25f;
if (pSeat->m_ePlayer.gflags & GF_IS_HEALING) {
pSeatLocal->m_flHealLerp = bound(0.0f, pSeatLocal->m_flHealLerp + clframetime, 1.0f);
} else {
pSeatLocal->m_flHealLerp = bound(0.0f, pSeatLocal->m_flHealLerp - clframetime, 1.0f);
}
gun.angles[0] += pSeatLocal->m_flHealLerp * 45;
gun.origin[2] -= pSeatLocal->m_flHealLerp * 5;
#endif
gun.angles[0] += strength * sintime;
gun.angles[1] += strength * sintime;
gun.angles[2] += strength * sintime;
gun.origin += [0,0,-1];
}

4
src/menu/Makefile Normal file
View file

@ -0,0 +1,4 @@
CC=fteqcc
all:
$(CC) progs.src

10
src/menu/progs.src Normal file
View file

@ -0,0 +1,10 @@
#pragma target fte_5768
//#pragma flag enable assumeint
#pragma progs_dat "../../menu.dat"
#define MENU
#define GAME_DIR "base"
#includelist
../../../src/menu-vgui/includes.src
#endlist

3
src/progs.src Normal file
View file

@ -0,0 +1,3 @@
#pragma sourcefile client/progs.src
#pragma sourcefile server/progs.src
#pragma sourcefile menu/progs.src

4
src/server/Makefile Normal file
View file

@ -0,0 +1,4 @@
CC=fteqcc
all:
$(CC) progs.src

15
src/server/damage.qc Normal file
View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/

28
src/server/defs.h Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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"
// stubs for spawning
void info_player_deathmatch(void)
{
}
void info_player_start(void)
{
}

53
src/server/gamerules.h Normal file
View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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 GameRules:CGameRules
{
void GameRules(void);
virtual void(NSClientPlayer) PlayerConnect;
virtual void(NSClientPlayer) PlayerDisconnect;
virtual void(NSClientPlayer) PlayerKill;
virtual void(NSClientPlayer) PlayerPostFrame;
virtual void(NSClientPlayer) LevelDecodeParms;
virtual void(NSClientPlayer) LevelChangeParms;
virtual void(void) LevelNewParms;
};
class SingleplayerRules:GameRules
{
void SingleplayerRules(void);
/* client */
virtual void(NSClientPlayer) PlayerSpawn;
virtual void(NSClientPlayer) PlayerDeath;
};
class MultiplayerRules:GameRules
{
int m_iIntermission;
int m_iIntermissionTime;
void MultiplayerRules(void);
virtual void(void) FrameStart;
/* client */
virtual void(NSClientPlayer) PlayerSpawn;
virtual void(NSClientPlayer) PlayerDeath;
virtual bool(NSClientPlayer, string) ConsoleCommand;
};

115
src/server/gamerules.qc Normal file
View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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
GameRules::GameRules(void)
{
}
void
GameRules::LevelDecodeParms(NSClientPlayer 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;
if (pl.flags & FL_CROUCHING) {
setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX);
} else {
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
}
}
void
GameRules::LevelChangeParms(NSClientPlayer 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;
}
void
GameRules::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
GameRules::PlayerPostFrame(NSClientPlayer pl)
{
}
void
GameRules::PlayerConnect(NSClientPlayer pl)
{
if (Plugin_PlayerConnect(pl) == FALSE)
bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname));
}
void
GameRules::PlayerDisconnect(NSClientPlayer 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
GameRules::PlayerKill(NSClientPlayer pl)
{
Damage_Apply(pl, pl, pl.health, 0, DMG_SKIP_ARMOR);
}
void
Game_Worldspawn(void)
{
}

View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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
MultiplayerRules::MultiplayerRules(void)
{
}
void
MultiplayerRules::FrameStart(void)
{
if (cvar("mp_timelimit"))
if (time >= (cvar("mp_timelimit") * 60)) {
IntermissionStart();
}
IntermissionCycle();
}
void
MultiplayerRules::PlayerDeath(NSClientPlayer pl)
{
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();
}
pl.SetMovetype(MOVETYPE_NONE);
pl.SetSolid(SOLID_NOT);
pl.SetModelindex(0);
pl.takedamage = DAMAGE_NO;
pl.armor = pl.activeweapon = pl.g_items = 0;
pl.think = PutClientInServer;
pl.nextthink = time + 4.0f;
}
void
MultiplayerRules::PlayerSpawn(NSClientPlayer 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";
setmodel(pl, pl.model);
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
pl.velocity = [0,0,0];
pl.gravity = __NULL__;
pl.frame = 1;
pl.SendFlags = UPDATE_ALL;
pl.customphysics = Empty;
pl.iBleeds = TRUE;
forceinfokey(pl, "*spec", "0");
forceinfokey(pl, "*deaths", ftos(pl.deaths));
LevelNewParms();
LevelDecodeParms(pl);
spot = Spawn_SelectRandom("info_player_deathmatch");
setorigin(pl, spot.origin);
pl.angles = spot.angles;
Weapons_RefreshAmmo(pl);
Client_FixAngle(pl, pl.angles);
}
float
MultiplayerRules::ConsoleCommand(NSClientPlayer pp, string cmd)
{
tokenize(cmd);
switch (argv(0)) {
default:
return (0);
}
return (1);
}
void
Game_InitRules(void)
{
g_grMode = spawn(MultiplayerRules);
if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) {
g_grMode = spawn(SingleplayerRules);
} else {
g_grMode = spawn(MultiplayerRules);
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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
SingleplayerRules::SingleplayerRules(void)
{
}
void
SingleplayerRules::PlayerDeath(NSClientPlayer pl)
{
pl.movetype = MOVETYPE_NONE;
pl.solid = SOLID_NOT;
pl.takedamage = DAMAGE_NO;
pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0;
pl.health = 0;
if (cvar("coop") == 1) {
pl.think = PutClientInServer;
pl.nextthink = time + 4.0f;
}
}
void
SingleplayerRules::PlayerSpawn(NSClientPlayer 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";
setmodel(pl, pl.model);
pl.AddEffects(EF_NOSHADOW);
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
pl.velocity = [0,0,0];
pl.gravity = __NULL__;
pl.frame = 1;
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);
}

32
src/server/items.h Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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:NSRenderableEntity
{
int m_bFloating;
int m_iClip;
int m_iWasDropped;
int id;
void item_pickup(void);
virtual void Spawned(void);
virtual void Touch(entity);
virtual void SetItem(int i);
virtual void Respawn(void);
virtual void SetFloating(int);
virtual void PickupRespawn(void);
};

92
src/server/items.qc Normal file
View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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(entity eToucher)
{
if (eToucher.classname != "player") {
return;
}
/* don't remove if AddItem fails */
if (Weapons_AddItem((player)eToucher, id, m_iClip) == FALSE) {
return;
}
Logging_Pickup(eToucher, this, __NULL__);
Sound_Play(other, CHAN_ITEM, "weapon.pickup");
UseTargets(eToucher, TRIG_TOGGLE, m_flDelay);
if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
Destroy();
} else {
Disappear();
ScheduleThink(PickupRespawn, 30.0f);
}
}
void item_pickup::SetItem(int i)
{
id = i;
m_oldModel = Weapons_GetWorldmodel(id);
SetModel(GetSpawnModel());
SetSize([-16,-16,0], [16,16,16]);
}
void item_pickup::SetFloating(int i)
{
m_bFloating = rint(bound(0, m_bFloating, 1));
}
void
item_pickup::PickupRespawn(void)
{
Respawn();
Sound_Play(this, CHAN_ITEM, "item.respawn");
}
void item_pickup::Respawn(void)
{
SetSolid(SOLID_TRIGGER);
SetOrigin(GetSpawnOrigin());
botinfo = BOTINFO_WEAPON;
/* At some points, the item id might not yet be set */
if (GetSpawnModel()) {
SetModel(GetSpawnModel());
}
SetSize([-16,-16,0], [16,16,16]);
ReleaseThink();
if (!m_bFloating) {
DropToFloor();
SetMovetype(MOVETYPE_TOSS);
}
}
void
item_pickup::Spawned(void)
{
super::Spawned();
Sound_Precache("item.respawn");
Sound_Precache("weapon.pickup");
}
void item_pickup::item_pickup(void)
{
}

25
src/server/modelevent.qc Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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_ServerModelEvent(float flTimeStamp, int iCode, string strData)
{
switch (iCode) {
default:
Event_ServerModelEvent(flTimeStamp, iCode, strData);
break;
}
}

35
src/server/progs.src Normal file
View file

@ -0,0 +1,35 @@
#pragma target fte_5768
//#pragma flag enable assumeint
#pragma progs_dat "../../progs.dat"
#define QWSSQC
#define SERVER
#includelist
/* engine, then nuclide headers & functions */
../../../src/shared/fteextensions.qc
../../../src/shared/defs.h
../../../src/server/defs.h
../../../src/botlib/botinfo.h
../../../src/gs-entbase/server.src
../../../src/gs-entbase/shared.src
/* mod specific header */
defs.h
../shared/include.src
/* include the botlib if desired (optional) */
../../../src/botlib/include.src
/* mod specific functions */
gamerules.qc
gamerules_singleplayer.qc
gamerules_multiplayer.qc
modelevent.qc
items.qc
/* global server/shared code */
../../../src/server/include.src
../../../src/shared/include.src
#endlist

40
src/shared/flags.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
/* game flags */
#define GF_SEMI_TOGGLED (int)(1<<0)
#define GF_FLASHLIGHT (int)(1<<1)
#define GF_UNUSED3 (int)(1<<2)
#define GF_UNUSED4 (int)(1<<3)
#define GF_UNUSED5 (int)(1<<4)
#define GF_UNUSED6 (int)(1<<5)
#define GF_UNUSED7 (int)(1<<6)
#define GF_UNUSED8 (int)(1<<7)
#define GF_UNUSED9 (int)(1<<8)
#define GF_UNUSED10 (int)(1<<9)
#define GF_UNUSED11 (int)(1<<10)
#define GF_UNUSED12 (int)(1<<11)
#define GF_UNUSED13 (int)(1<<12)
#define GF_UNUSED14 (int)(1<<14)
#define GF_UNUSED15 (int)(1<<16)
#define GF_UNUSED16 (int)(1<<13)
#define GF_UNUSED17 (int)(1<<17)
#define GF_UNUSED18 (int)(1<<18)
#define GF_UNUSED19 (int)(1<<19)
#define GF_UNUSED20 (int)(1<<20)
#define GF_UNUSED21 (int)(1<<21)
#define GF_UNUSED22 (int)(1<<22)
#define GF_UNUSED23 (int)(1<<23)

48
src/shared/fx_blood.qc Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
#ifdef CLIENT
var float PARTICLE_BLOOD;
void
FX_Blood_Init(void)
{
PARTICLE_BLOOD = particleeffectnum("part_blood");
}
#endif
void
FX_Blood(vector pos, vector color)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_BLOOD);
WriteCoord(MSG_MULTICAST, pos[0]);
WriteCoord(MSG_MULTICAST, pos[1]);
WriteCoord(MSG_MULTICAST, pos[2]);
WriteByte(MSG_MULTICAST, color[0] * 255);
WriteByte(MSG_MULTICAST, color[1] * 255);
WriteByte(MSG_MULTICAST, color[2] * 255);
msg_entity = self;
multicast(pos, MULTICAST_PVS);
#else
if (cvar("violence_hblood") <= 0) {
return;
}
pointparticles(PARTICLE_BLOOD, pos, [0,0,0], 1);
#endif
}

63
src/shared/fx_corpse.qc Normal file
View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
#ifdef SERVER
#define CORPSES_MAX 16
entity g_bodies;
void
FX_Corpse_Init(void)
{
entity next = spawn(NSRenderableEntity);
g_bodies = next;
for ( int i = 0; i <= CORPSES_MAX; i++ ) {
next.classname = "corpse";
next.owner = spawn(NSRenderableEntity);
if ( i == CORPSES_MAX ) {
next.owner = g_bodies;
} else {
next = next.owner;
}
}
}
entity
FX_Corpse_Next(void)
{
entity r = g_bodies;
g_bodies = g_bodies.owner;
return r;
}
entity
FX_Corpse_Spawn(player pl, float anim)
{
NSRenderableEntity body_next = (NSRenderableEntity)FX_Corpse_Next();
setorigin(body_next, pl.origin + [0,0,32]);
body_next.SetMovetype(MOVETYPE_TOSS);
body_next.SetSolid(SOLID_CORPSE);
setmodel(body_next, pl.model);
setsize(body_next, VEC_HULL_MIN, VEC_HULL_MAX);
body_next.SetModelindex(pl.modelindex);
body_next.SetAngles(pl.angles);
body_next.velocity = (pl.velocity) + [0,0,120];
body_next.colormap = pl.colormap;
body_next.SetFrame(anim);
return (entity)body_next;
}
#endif

10
src/shared/include.src Normal file
View file

@ -0,0 +1,10 @@
#includelist
player.qc
weapon_common.h
weapons.h
flags.h
fx_blood.qc
fx_corpse.qc
weapons.qc
weapon_common.qc
#endlist

114
src/shared/player.qc Normal file
View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
/* all potential SendFlags bits we can possibly send */
enumflags
{
PLAYER_AMMO1 = PLAYER_CUSTOMFIELDSTART,
PLAYER_AMMO2,
PLAYER_AMMO3,
PLAYER_UNUSED5,
PLAYER_UNUSED6,
PLAYER_UNUSED7,
PLAYER_UNUSED7,
PLAYER_UNUSED8
};
class player:NSClientPlayer
{
PREDICTED_INT(mode_tempstate)
#ifdef CLIENT
virtual void(float,float) ReceiveEntity;
virtual void(void) PredictPreFrame;
virtual void(void) PredictPostFrame;
#else
virtual void(void) EvaluateEntity;
virtual float(entity, float) SendEntity;
#endif
};
#ifdef CLIENT
/*
=================
player::ReceiveEntity
=================
*/
void
player::ReceiveEntity(float new, float fl)
{
NSClientPlayer::ReceiveEntity(new, fl);
setorigin(this, origin);
}
/*
=================
player::PredictPostFrame
Save the last valid server values away in the _net variants of each field
so we can roll them back later.
=================
*/
void
player::PredictPreFrame(void)
{
NSClientPlayer::PredictPreFrame();
}
/*
=================
player::PredictPostFrame
Where we roll back our values to the ones last sent/verified by the server.
=================
*/
void
player::PredictPostFrame(void)
{
NSClientPlayer::PredictPostFrame();
}
#else
void
player::EvaluateEntity(void)
{
NSClientPlayer::EvaluateEntity();
}
/*
=================
player::SendEntity
=================
*/
float
player::SendEntity(entity ePEnt, float fChanged)
{
/* don't broadcast invisible players */
if (IsFakeSpectator() && ePEnt != this)
return (0);
if (!GetModelindex() && ePEnt != this)
return (0);
fChanged = OptimiseChangedFlags(ePEnt, fChanged);
WriteByte(MSG_ENTITY, ENT_PLAYER);
WriteFloat(MSG_ENTITY, fChanged);
/* the generic client attributes */
NSClientPlayer::SendEntity(ePEnt, fChanged);
return (1);
}
#endif

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
#ifndef NEW_INVENTORY
/* for AI identification purposes */
typedef enum
{
WPNTYPE_INVALID, /* no logic */
WPNTYPE_RANGED, /* will want to keep their distance mostly */
WPNTYPE_THROW, /* has to keep some distance, but not too far */
WPNTYPE_CLOSE, /* have to get really close */
WPNTYPE_FULLAUTO, /* for things that need to be held down */
WPNTYPE_SEMI /* semi automatic */
} weapontype_t;
typedef struct
{
string name;
int id; /* bitflag id */
int slot;
int slot_pos;
int allow_drop;
int weight; /* required for bestweapon */
void(void) precache;
string() wmodel;
string() deathmsg;
/* player specific */
string(player) pmodel;
float(player) aimanim;
weapontype_t(player) type; /* required for bot-AI */
void(player) draw;
void(player) holster;
void(player) primary;
void(player) secondary;
void(player) reload;
void(player) release;
int(player, int, int) pickup;
void(player) updateammo;
void(player, int) predraw; /* predraw... */
void(player) postdraw; /* postdraw... */
int(player) isempty; /* kinda handy */
void(player, int, vector, float) hudpic;
} weapon_t;
void Weapons_Holster(player pl);
void Weapons_Primary(player pl);
void Weapons_Secondary(player pl);
void Weapons_Reload(player pl);
void Weapons_Release(player pl);
void Weapons_PreDraw(player pl, int);
float Weapons_GetAim(player, int);
int Weapons_IsEmpty(player, int);
void Weapons_DrawCrosshair(player pl);
void Weapons_MakeVectors(player pl);
vector Weapons_GetCameraPos(player pl);
void Weapons_ViewAnimation(player pl, int);
void Weapons_ViewPunchAngle(player pl, vector);
int Weapons_IsPresent(player, int);
void Weapons_UpdateAmmo(player, int, int, int);
int Weapons_GetAnimation(player pl);
void Weapons_EnableModel(void);
void Weapons_DisableModel(void);
weapontype_t Weapons_GetType(player, int);
void Weapons_SetLeftModel(string);
void Weapons_SetRightModel(string);
void Weapons_SetRightGeomset(string);
void Weapons_SetLeftGeomset(string);
/* compat */
void Weapons_SetGeomset(string);
void Weapons_SetModel(string);
void Weapons_Sound(entity, float, string);
#ifdef CLIENT
string Weapons_GetPlayermodel(player, int);
void Weapons_HUDPic(player, int, int, vector, float);
#endif
#else
#endif

478
src/shared/weapon_common.qc Normal file
View file

@ -0,0 +1,478 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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.
*/
#ifndef NEW_INVENTORY
var int g_weapon_weights[g_weapons.length];
#ifdef CLIENT
var int g_weapon_order[g_weapons.length];
#endif
void
Weapons_Init(void)
{
/* in the future we'll have no internal weapon table, then this will fill
* one up... */
/*searchhandle sh;
filestream fh;
string line;
sh = search_begin("scripts/weapon_*.txt", TRUE, TRUE);
for (int i = 0; i < search_getsize(sh); i++) {
fh = fopen(search_getfilename(sh, i), FILE_READ);
if (fh < 0) {
continue;
}
while ((line = fgets(fh))) {
int w = tokenize(line);
switch (argv(0)) {
case "name":
break;
case "slot":
break;
case "slot_pos":
break;
}
}
fclose(fh);
}*/
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].precache != __NULL__)
g_weapons[i].precache();
/* check our weapon weights */
int max = 0;
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].weight > max)
max = g_weapons[i].weight;
/* don't bother building the list if we've got no weights */
if (max <= 0)
return;
/* position in the weight array */
int w = 0;
/* loop through all weights */
for (int b = 0; b <= max; b++) {
/* loop through all weapons */
for (int i = 0; i < g_weapons.length; i++) {
/* if we've found a valid weight, add the weapon to the list */
if (g_weapons[i].weight == b) {
g_weapon_weights[w] = i;
w++;
}
}
}
#if 0
for (int i = 0; i < g_weapons.length; i++)
print(sprintf("Weapon-Weight order: %s, %i\n", g_weapons[g_weapon_weights[i]].name, i));
#endif
#ifdef CLIENT
/* build our slot-order table */
int st = 0;
int max_slots = 0;
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].slot > max_slots)
max_slots = g_weapons[i].slot;
int max_pos = 0;
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].slot_pos > max_pos)
max_pos = g_weapons[i].slot_pos;
/* loop through all slots */
for (int s = 0; s <= max_slots; s++) {
/* loop through all positions */
for (int p = 0; p < max_pos; p++) {
/* loop through all the weapons */
for (int i = 0; i < g_weapons.length; i++) {
if (g_weapons[i].slot == s && g_weapons[i].slot_pos == p) {
g_weapon_order[st] = i;
st++;
}
}
}
}
#if 0
for (int i = 0; i < g_weapons.length; i++)
print(sprintf("Weapon-List order: %s, %i\n", g_weapons[g_weapon_order[i]].name, i));
#endif
#endif
}
void
Weapons_SetLeftModel(string mdl)
{
#ifdef CLIENT
setmodel(pSeat->m_eViewModelL, mdl);
setsize(pSeat->m_eViewModelL, [0,0,0], [0,0,0]);
pSeat->m_eViewModelL.effects |= EF_NOSHADOW;
#endif
}
void
Weapons_SetRightModel(string mdl)
{
#ifdef CLIENT
setmodel(pSeat->m_eViewModel, mdl);
setsize(pSeat->m_eViewModel, [0,0,0], [0,0,0]);
pSeat->m_eViewModel.effects |= EF_NOSHADOW;
#endif
}
void
Weapons_SetModel(string mdl)
{
Weapons_SetRightModel(mdl);
Weapons_SetLeftModel("");
}
void
Weapons_SetRightGeomset(string set)
{
#ifdef CLIENT
setcustomskin(pSeat->m_eViewModel, "", set);
#endif
}
void
Weapons_SetLeftGeomset(string set)
{
#ifdef CLIENT
setcustomskin(pSeat->m_eViewModelL, "", set);
#endif
}
void
Weapons_SetGeomset(string set)
{
Weapons_SetRightGeomset(set);
}
void
Weapons_Draw(player pl)
{
int i = pl.activeweapon;
/* In case the previous weapon hid the model */
Weapons_EnableModel();
pl.w_attack_next = 0.5f;
pl.w_idle_next = 2.5f;
pl.viewzoom = 1.0f;
/* we're meant to respawn when we're dead, don't unset! */
if (pl.health > 0) {
pl.think = __NULL__;
pl.nextthink = 0.0f;
}
/* make sure this is all wiped */
pl.a_ammo1 = pl.a_ammo2 = pl.a_ammo3 = 0;
if (g_weapons[i].draw != __NULL__)
g_weapons[i].draw(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
pl.gflags |= GF_SEMI_TOGGLED;
}
void
Weapons_Holster(player pl)
{
int i = pl.activeweapon;
if (g_weapons[i].holster != __NULL__)
g_weapons[i].holster(pl);
}
void
Weapons_Primary(player pl)
{
int i = pl.activeweapon;
if (pl.gflags & GF_SEMI_TOGGLED)
return;
if (g_weapons[i].primary != __NULL__)
g_weapons[i].primary(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_AmmoUpdate(entity target)
{
player pl = (player)target;
int i = pl.activeweapon;
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_Secondary(player pl)
{
int i = pl.activeweapon;
if (g_weapons[i].secondary != __NULL__)
g_weapons[i].secondary(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_Reload(player pl)
{
int i = pl.activeweapon;
if (g_weapons[i].reload != __NULL__)
g_weapons[i].reload(pl);
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
Weapons_Release(player pl)
{
int i = pl.activeweapon;
if (g_weapons[i].release != __NULL__)
g_weapons[i].release(pl);
pl.gflags &= ~GF_SEMI_TOGGLED;
}
void
Weapons_PreDraw(player pl, int thirdperson)
{
int i = pl.activeweapon;
if (g_weapons[i].predraw != __NULL__)
g_weapons[i].predraw(pl, thirdperson);
}
int
Weapons_IsEmpty(player pl, int w)
{
int r = 0;
entity oself = self;
self = pl;
if (g_weapons[w].isempty != __NULL__)
r = g_weapons[w].isempty(pl);
self = oself;
return (r);
}
weapontype_t
Weapons_GetType(player pl, int w)
{
weapontype_t r = WPNTYPE_INVALID;
entity oself = self;
self = pl;
if (g_weapons[w].type != __NULL__)
r = g_weapons[w].type(pl);
self = oself;
return (r);
}
void
Weapons_DrawCrosshair(player pl)
{
int i = pl.activeweapon;
if (g_weapons[i].postdraw != __NULL__)
g_weapons[i].postdraw(pl);
}
string
Weapons_GetWorldmodel(int id)
{
if (g_weapons[id].wmodel != __NULL__)
return g_weapons[id].wmodel();
return "";
}
string
Weapons_GetPlayermodel(player pl, int id)
{
if (g_weapons[id].pmodel != __NULL__)
return g_weapons[id].pmodel(pl);
return "";
}
string
Weapons_GetDeathmessage(int id)
{
if (g_weapons[id].deathmsg != __NULL__)
return g_weapons[id].deathmsg();
return "";
}
float
Weapons_GetAim(player pl, int id)
{
if (g_weapons[id].aimanim != __NULL__)
return g_weapons[id].aimanim(pl);
return (0);
}
#ifdef CLIENT
void
Weapons_HUDPic(player pl, int id, int s, vector pos, float a)
{
if (g_weapons[id].hudpic != __NULL__)
g_weapons[id].hudpic(pl, s, pos, a);
}
#endif
void
Weapons_MakeVectors(player pl)
{
#ifdef SERVER
makevectors(pl.v_angle);
#else
makevectors(view_angles);
#endif
}
vector
Weapons_GetCameraPos(player pl)
{
#ifdef SERVER
return (pl.origin + pl.view_ofs);
#else
return getproperty(VF_ORIGIN);
#endif
}
void
Weapons_ViewAnimation(player pl, int i)
{
#if 0
View_PlayAnimation(i);
#endif
pl.weaponframe = i;
pl.weapontime = 0.0f;
}
#ifdef CLIENT
int View_GetAnimation(void);
#endif
int
Weapons_GetAnimation(player pl)
{
return pl.weaponframe;
}
void
Weapons_ViewPunchAngle(player pl, vector add)
{
pl.punchangle += add;
}
int
Weapons_IsPresent(player pl, int w)
{
if (pl.g_items & g_weapons[w].id) {
return (1);
} else {
return (0);
}
}
void
Weapons_EnableModel(void)
{
#ifdef CLIENT
View_EnableViewmodel();
#endif
}
void
Weapons_DisableModel(void)
{
#ifdef CLIENT
View_DisableViewmodel();
#endif
}
/*
=================
Weapons_UpdateAmmo
Sets .a_ammoX fields and clamps them so they can be networked as a single byte.
=================
*/
void
Weapons_UpdateAmmo(player pl, int a1, int a2, int a3)
{
/* no change */
if (a1 == -1)
a1 = pl.a_ammo1;
if (a2 == -1)
a2 = pl.a_ammo2;
if (a3 == -1)
a3 = pl.a_ammo3;
/* networked as bytes, since we don't need more. Clamp to avoid errors */
pl.a_ammo1 = a1;
pl.a_ammo2 = a2;
pl.a_ammo3 = a3;
}
void
Weapons_Sound(entity pl, float channel, string snd)
{
#if 0
#ifdef SERVER
float prev = pl.dimension_see;
pl.dimension_see=0;
Sound_Play(pl, channel, snd);
pl.dimension_see = prev;
#else
/* client side == immediately */
Sound_Play(pl, channel, snd);
#endif
#else
#ifdef SERVER
Sound_Play(pl, channel, snd);
#endif
#endif
}
#endif

20
src/shared/weapons.h Normal file
View file

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

20
src/shared/weapons.qc Normal file
View file

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

View file

@ -0,0 +1,116 @@
entityDef info_player_start
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Singleplayer Spawn Point"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef mp_deathmatch_spawn
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Deathmatch Spawn Point"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef mp_teamdeathmatch_spawn
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Team Deathmatch Spawn Point"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef mp_retrieval_spawn_allied
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Retrieval: Allied Spawn"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef mp_retrieval_spawn_axis
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Retrieval: Axis Spawn"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef mp_searchanddestroy_spawn_allied
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Search & Destroy: Allied Spawn"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef mp_searchanddestroy_spawn_axis
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Search & Destroy: Axis Spawn"
editor_color "1 0 0"
spawnclass NSSpawnPoint
}
entityDef misc_model
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Decorative Model"
editor_color "1 0 0"
spawnclass NSRenderableEntity
}
entityDef script_model
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Scripted Model"
editor_color "1 0 0"
spawnclass NSRenderableEntity
}
entityDef func_static
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Static Brush Model"
editor_color "1 0 0"
spawnclass func_wall
}
entityDef script_brushmodel
{
editor_mins "-16 -16 -36"
editor_maxs "16 16 36"
editor_description "Scripted Brush Model"
editor_color "1 0 0"
spawnclass func_wall
}

View file

@ -0,0 +1,51 @@
entityDef item_ammo_stielhandgranate_open
{
editor_color ".3 .3 1"
editor_mins "-16 -16 -16"
editor_maxs "16 16 16"
model "xmodel/ammo_stielhandgranate1"
spawnclass NSItem
}
entityDef item_ammo_stielhandgranate_closed
{
editor_color ".3 .3 1"
editor_mins "-16 -16 -16"
editor_maxs "16 16 16"
model "xmodel/ammo_stielhandgranate2"
spawnclass NSItem
}
entityDef item_health_small
{
editor_color ".3 .3 1"
editor_mins "-16 -16 -16"
editor_maxs "16 16 16"
model "xmodel/health_small"
spawnclass NSItem
}
entityDef item_health
{
editor_color ".3 .3 1"
editor_mins "-16 -16 -16"
editor_maxs "16 16 16"
model xmodel/health_medium"
spawnclass NSItem
}
entityDef item_health_large
{
editor_color ".3 .3 1"
editor_mins "-16 -16 -16"
editor_maxs "16 16 16"
model xmodel/health_large"
spawnclass NSItem
}