Initial commit, carried over from Nuclide's Git on March 8th 2021

This commit is contained in:
Marco Cawthorne 2021-03-08 10:38:54 +01:00
commit 6ff68fcc34
108 changed files with 17405 additions and 0 deletions

15
LICENSE Normal file
View File

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

48
README.md Normal file
View File

@ -0,0 +1,48 @@
# FreeCS
Clean-room reimplementation of Counter-Strike 1.5 (mod-version).
Aiming for a stable reimagining of the original mod in QuakeC.
Not aiming for accuracy, but for a smooth, exploit and bug-free
experience over the Internet.
This is all 100% new, original code written by good old trial and error.
Differences exist and features are slowly being implemented one by one.
This allows the code to be fully free and unencumbered, unlike similar projects.
Featuring proper weapon prediction to enable stress-free netplay.
![Preview 1](img/preview1.jpg)
![Preview 2](img/preview2.jpg)
![Preview 3](img/preview3.jpg)
![Preview 4](img/preview4.jpg)
## Building
Clone the repository into the Nuclide-SDK:
> git clone REPOURL cstrike
then either run Nuclide's ./build_game.sh shell script, or issue 'make' inside
./cstrike/src!
Obviously make sure that Nuclide has fteqw and fteqcc set-up for building.
## Community
Join us on #freecs via irc.freenode.net and chat.
## License
ISC License
Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

BIN
img/preview1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
img/preview2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
img/preview3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
img/preview4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

5
src/Makefile Normal file
View File

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

4
src/client/Makefile Normal file
View File

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

204
src/client/cmds.qc Normal file
View File

@ -0,0 +1,204 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
int
ClientGame_ConsoleCommand(void)
{
switch(argv(0)) {
case "chooseteam":
Textmenu_Toggle("TEAM_SELECT");
break;
case "buy":
Textmenu_Toggle("BUY");
break;
case "radio1":
Textmenu_Toggle("RADIOA");
break;
case "radio2":
Textmenu_Toggle("RADIOB");
break;
case "radio3":
Textmenu_Toggle("RADIOC");
break;
case "nightvision":
/*Nightvision_Toggle();*/
break;
case "drop":
sendevent("DropWeapon", "");
break;
case "glock":
sendevent("BuyWeapon", "f", WEAPON_GLOCK18);
break;
case "usp":
sendevent("BuyWeapon", "f", WEAPON_USP45);
break;
case "p228":
sendevent("BuyWeapon", "f", WEAPON_P228);
break;
case "deagle":
sendevent("BuyWeapon", "f", WEAPON_DEAGLE);
break;
case "fn57":
sendevent("BuyWeapon", "f", WEAPON_FIVESEVEN);
break;
case "elites":
sendevent("BuyWeapon", "f", WEAPON_ELITES);
break;
case "m3":
sendevent("BuyWeapon", "f", WEAPON_M3);
break;
case "xm1014":
sendevent("BuyWeapon", "f", WEAPON_XM1014);
break;
case "tmp":
sendevent("BuyWeapon", "f", WEAPON_TMP);
break;
case "mac10":
sendevent("BuyWeapon", "f", WEAPON_MAC10);
break;
case "mp5":
sendevent("BuyWeapon", "f", WEAPON_MP5);
break;
case "ump45":
sendevent("BuyWeapon", "f", WEAPON_UMP45);
break;
case "p90":
sendevent("BuyWeapon", "f", WEAPON_P90);
break;
case "ak47":
sendevent("BuyWeapon", "f", WEAPON_AK47);
break;
case "m4a1":
sendevent("BuyWeapon", "f", WEAPON_M4A1);
break;
case "sg552":
sendevent("BuyWeapon", "f", WEAPON_SG552);
break;
case "aug":
sendevent("BuyWeapon", "f", WEAPON_AUG);
break;
case "scout":
sendevent("BuyWeapon", "f", WEAPON_SCOUT);
break;
case "sg550":
sendevent("BuyWeapon", "f", WEAPON_SG550);
break;
case "awp":
sendevent("BuyWeapon", "f", WEAPON_AWP);
break;
case "g3sg1":
sendevent("BuyWeapon", "f", WEAPON_G3SG1);
break;
case "m249":
sendevent("BuyWeapon", "f", WEAPON_PARA);
break;
case "buyammo1":
case "primammo":
sendevent("AmmoBuyPrimary", "");
break;
case "buyammo2":
case "secammo":
sendevent("AmmoBuySecondary", "");
break;
case "vest":
sendevent("BuyEquipment", "f", 0);
break;
case "vesthelm":
sendevent("BuyEquipment", "f", 1);
break;
case "flash":
sendevent("BuyEquipment", "f", 2);
break;
case "hegren":
sendevent("BuyEquipment", "f", 3);
break;
case "vsgren":
sendevent("BuyEquipment", "f", 4);
break;
case "defuser":
sendevent("BuyEquipment", "f", 5);
break;
case "nvg":
sendevent("BuyEquipment", "f", 6);
break;
case "coverme":
sendevent("Radio", "f", RADIO_CT_COVERME);
break;
case "takepoint":
sendevent("Radio", "f", RADIO_CT_POINT);
break;
case "takepoint":
sendevent("Radio", "f", RADIO_POSITION);
break;
case "regroup":
sendevent("Radio", "f", RADIO_REGROUP);
break;
case "followme":
sendevent("Radio", "f", RADIO_FOLLOWME);
break;
case "takingfire":
sendevent("Radio", "f", RADIO_FIREASSIS);
break;
case "go":
sendevent("Radio", "f", RADIO_GO);
break;
case "fallback":
sendevent("Radio", "f", RADIO_FALLBACK);
break;
case "sticktog":
sendevent("Radio", "f", RADIO_STICKTOG);
break;
case "getinpos":
sendevent("Radio", "f", RADIO_COM_GETINPOS);
break;
case "stormfront":
sendevent("Radio", "f", RADIO_STORMFRONT);
break;
case "report":
sendevent("Radio", "f", RADIO_COM_REPORTIN);
break;
case "roger":
sendevent("Radio", "f", RADIO_ROGER);
break;
case "enemyspot":
sendevent("Radio", "f", RADIO_CT_ENEMYS);
break;
case "needbackup":
sendevent("Radio", "f", RADIO_CT_BACKUP);
break;
case "sectorclear":
sendevent("Radio", "f", RADIO_CLEAR);
break;
case "inposition":
sendevent("Radio", "f", RADIO_CT_INPOS);
break;
case "reportingin":
sendevent("Radio", "f", RADIO_CT_REPORTINGIN);
break;
case "getout":
sendevent("Radio", "f", RADIO_GETOUT);
break;
case "negative":
sendevent("Radio", "f", RADIO_NEGATIVE);
break;
case "enemydown":
sendevent("Radio", "f", RADIO_ENEMYDOWN);
break;
default:
return FALSE;
}
return TRUE;
}

123
src/client/crosshair.qc Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define CS_CROSS_COLOR [0,1,0]
#define CS_CROSS_ALPHA 1.0f
void
Cstrike_DrawCrosshair(void)
{
player pl = (player)self;
int cross_dist;
int line_length;
/* these are defined in the weapon-code files */
float distance = pl.cs_cross_mindist;
float delta = pl.cs_cross_deltadist;
if (!(pl.flags & FL_ONGROUND)) {
distance = distance * 2.0f;
} else if (pl.flags & FL_CROUCHING) { /* crouching... */
distance = distance * 0.5f;
} else if (vlen(pl.velocity) > 120) { /* running, not walking */
distance = distance * 1.5f;
}
/* amount of shots that we've shot does affect our accuracy */
if (pl.cs_shotmultiplier > pl.cs_shotmultiplier_net) {
pl.cs_crosshairdistance = min(15, pl.cs_crosshairdistance + delta);
} else if (pl.cs_crosshairdistance > distance) {
pl.cs_crosshairdistance -= (pl.cs_crosshairdistance * clframetime);
}
pl.cs_shotmultiplier_net = pl.cs_shotmultiplier;
if (pl.cs_crosshairdistance < distance) {
pl.cs_crosshairdistance = distance;
}
cross_dist = ceil(pl.cs_crosshairdistance);
line_length = max(1, ((cross_dist - distance) / 2) + 5);
/* line setup */
vector vert1, vert2, hori1, hori2;
vert1 = vert2 = hori1 = hori2 = g_hudmins + (g_hudres / 2);
/* vertical Lines */
vert1[1] -= (cross_dist + line_length);
vert2[1] += cross_dist + 1;
/* horizontal Lines */
hori1[0] -= (cross_dist + line_length);
hori2[0] += cross_dist + 1;
drawfill(vert1, [1, line_length], CS_CROSS_COLOR, CS_CROSS_ALPHA, DRAWFLAG_ADDITIVE);
drawfill(vert2, [1, line_length], CS_CROSS_COLOR, CS_CROSS_ALPHA, DRAWFLAG_ADDITIVE);
drawfill(hori1, [line_length, 1], CS_CROSS_COLOR, CS_CROSS_ALPHA, DRAWFLAG_ADDITIVE);
drawfill(hori2, [line_length, 1], CS_CROSS_COLOR, CS_CROSS_ALPHA, DRAWFLAG_ADDITIVE);
}
/* AUG zoom uses this. so does the spectator cam */
void
Cstrike_DrawSimpleCrosshair(void)
{
static vector cross_pos;
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
drawsubpic(cross_pos, [24,24], g_cs_cross, [0.1875,0], [0.1875, 0.1875], [1,1,1], 1, DRAWFLAG_NORMAL);
}
/*
=================
HUD_DrawScope
Tries to draw a scope whenever viewzoom < 1.0f
=================
*/
void
Cstrike_DrawScope(void)
{
vector scope_pos;
static float scope_offset;
static float scope_scale;
static void Cstrike_ScopePic(vector pos, vector sz, string img) {
drawpic((pos * scope_scale) + [scope_offset, 0], img, sz * scope_scale, [1,1,1], 1.0f);
}
// Draw the scope in the middle, seperately from the border
scope_pos = g_hudmins + (g_hudres / 2) + [-128,-128];
drawpic(scope_pos, g_cs_scope0, [256,256], [1,1,1], 1.0f, DRAWFLAG_NORMAL);
// Border scale to fit the screen
scope_scale = g_hudres[1] / 480;
scope_offset = g_hudmins[0] + (g_hudres[0] / 2) - ((640 * scope_scale) / 2);
// Type 1 Border... more coming soon?
Cstrike_ScopePic([0,0], [192,112], g_cs_scope1);
Cstrike_ScopePic([192,0], [256,112], g_cs_scope2);
Cstrike_ScopePic([448,0], [192,112], g_cs_scope3);
Cstrike_ScopePic([0,112], [192,256], g_cs_scope4);
Cstrike_ScopePic([448,112], [192,256], g_cs_scope5);
Cstrike_ScopePic([0,368], [192,112], g_cs_scope6);
Cstrike_ScopePic([192,368], [256,112], g_cs_scope7);
Cstrike_ScopePic([448,368], [192,112], g_cs_scope8);
// Rect borders left and right
if (scope_offset > 0) {
drawfill([0,0], [scope_offset, g_hudres[1]], [0,0,0], 1.0f);
drawfill([(640 * scope_scale) + scope_offset, 0], [scope_offset, g_hudres[1]], [0,0,0], 1.0f);
}
}

160
src/client/defs.h Normal file
View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "hud.h"
#include "radio.h"
#include "../../../valve/src/client/obituary.h"
var int autocvar_cl_autoweaponswitch = TRUE;
vector g_hud_color;
vector g_hudmins;
vector g_hudres;
var string g_hud1_spr;
var string g_hud2_spr;
var string g_hud3_spr;
var string g_hud4_spr;
var string g_hud5_spr;
var string g_hud6_spr;
var string g_hud7_spr;
var string g_hud10_spr;
var string g_hud11_spr;
var string g_hud12_spr;
var string g_hud13_spr;
var string g_hud14_spr;
var string g_hud15_spr;
var string g_hud16_spr;
var string g_cs_cross;
var string g_cs_scope0;
var string g_cs_scope1;
var string g_cs_scope2;
var string g_cs_scope3;
var string g_cs_scope4;
var string g_cs_scope5;
var string g_cs_scope6;
var string g_cs_scope7;
var string g_cs_scope8;
struct
{
/* viewmodel stuff */
entity m_eViewModel;
entity m_eMuzzleflash;
int m_iVMBones;
int m_iVMEjectBone;
int m_iLastWeapon;
int m_iOldWeapon;
float m_flBobTime;
float m_flBob;
/* damage overlay */
float m_flDamageAlpha;
vector m_vecDamagePos;
/* +zoomin cmd */
int m_iZoomed;
float m_flZoomTime;
/* player fields */
entity m_ePlayer;
vector m_vecPredictedOrigin;
vector m_vecPredictedOriginOld;
vector m_vecPredictedVelocity;
float m_flPredictedFlags;
/* camera fields */
vector m_vecCameraOrigin;
vector m_vecCameraAngle;
float m_flCameraTime;
/* hud.c */
int m_iHealthOld;
float m_flHealthAlpha;
int m_iArmorOld;
float m_flArmorAlpha;
int m_iAmmo1Old;
float m_flAmmo1Alpha;
int m_iAmmo2Old;
float m_flAmmo2Alpha;
int m_iAmmo3Old;
float m_flAmmo3Alpha;
int m_iPickupWeapon;
float m_flPickupAlpha;
/* This is seperated from the other VGUI stuff so we can check scores
* while buying and whatnot */
int m_iScoresVisible;
int m_iHUDWeaponSelected;
float m_flHUDWeaponSelectTime;
/* saturn controller */
int m_iSaturnMenu;
/* centerprint related */
float m_flCenterprintAlpha;
float m_flCenterprintTime;
float m_iCenterprintLines;
string m_strCenterprintBuffer[18];
/* chat related */
float m_flPrintTime;
string m_strPrintBuffer[5];
int m_iPrintLines;
int m_iInputAttack2;
int m_iInputReload;
int m_iInputUse;
int m_iInputDuck;
float m_flInputBlockTime;
/* fading */
float m_flFadeDuration;
float m_flFadeHold;
float m_flFadeMaxAlpha;
float m_flFadeStyle;
float m_flFadeAlpha;
float m_flFadeTime;
vector m_vecFadeColor;
int m_iFadeActive;
entity m_pWeaponFX;
/* shake */
float m_flShakeFreq;
float m_flShakeDuration;
float m_flShakeTime;
float m_flShakeAmp;
/* cstrike additions */
float m_iMoneyOld;
float m_flMoneyAlpha;
float m_iMoneyDelta;
int m_iTimeUnitsOld;
float m_flTimeAlpha;
vector m_vecMoneyColor;
} g_seats[4], *pSeat;
void HUD_DrawAmmo1(void);
void HUD_DrawAmmo2(void);
void HUD_DrawAmmo3(void);
void HUD_WeaponPickupNotify(int);
void HUD_DrawAmmoBar(vector pos, float val, float max, float a);
void Cstrike_DrawCrosshair(void);
void Cstrike_DrawSimpleCrosshair(void);
void Cstrike_DrawScope(void);
void Textmenu_Call(string);

29
src/client/entities.qc Normal file
View File

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

144
src/client/game_event.qc Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
ClientGame_EventParse(float fHeader)
{
switch (fHeader) {
case EV_OBITUARY:
Obituary_Parse();
break;
case EV_SPARK:
vector vSparkPos, vSparkAngle;
vSparkPos[0] = readcoord();
vSparkPos[1] = readcoord();
vSparkPos[2] = readcoord();
vSparkAngle[0] = readcoord();
vSparkAngle[1] = readcoord();
vSparkAngle[2] = readcoord();
FX_Spark(vSparkPos, vSparkAngle);
break;
case EV_GIBHUMAN:
vector vGibPos;
vGibPos[0] = readcoord();
vGibPos[1] = readcoord();
vGibPos[2] = readcoord();
FX_GibHuman(vGibPos);
break;
case EV_BLOOD:
vector vBloodPos;
vector vBloodColor;
vBloodPos[0] = readcoord();
vBloodPos[1] = readcoord();
vBloodPos[2] = readcoord();
vBloodColor[0] = readbyte() / 255;
vBloodColor[1] = readbyte() / 255;
vBloodColor[2] = readbyte() / 255;
FX_Blood(vBloodPos, vBloodColor);
break;
case EV_EXPLOSION:
vector vExploPos;
vExploPos[0] = readcoord();
vExploPos[1] = readcoord();
vExploPos[2] = readcoord();
FX_Explosion(vExploPos);
break;
case EV_MODELGIB:
vector vecPos;
vecPos[0] = readcoord();
vecPos[1] = readcoord();
vecPos[2] = readcoord();
vector vSize;
vSize[0] = readcoord();
vSize[1] = readcoord();
vSize[2] = readcoord();
float fStyle = readbyte();
int count = readbyte();
FX_BreakModel(count, vecPos, vSize, [0,0,0], fStyle);
break;
case EV_IMPACT:
int iType;
vector vOrigin, vNormal;
iType = (int)readbyte();
vOrigin[0] = readcoord();
vOrigin[1] = readcoord();
vOrigin[2] = readcoord();
vNormal[0] = readcoord();
vNormal[1] = readcoord();
vNormal[2] = readcoord();
FX_Impact(iType, vOrigin, vNormal);
break;
case EV_SMOKE:
vector vSmokePos;
vSmokePos[0] = readcoord();
vSmokePos[1] = readcoord();
vSmokePos[2] = readcoord();
FX_Smokenade(vSmokePos);
break;
case EV_CHAT:
float fSender = readbyte();
float fTeam = readbyte();
string sMessage = readstring();
CSQC_Parse_Print(sprintf("%s: %s", getplayerkeyvalue(fSender, "name"), sMessage), PRINT_CHAT);
break;
case EV_CHAT_TEAM:
float fSender2 = readbyte();
float fTeam2 = readbyte();
string sMessage2 = readstring();
CSQC_Parse_Print(sprintf("[TEAM] %s: %s", getplayerkeyvalue(fSender2, "name"), sMessage2), PRINT_CHAT);
break;
case EV_CHAT_VOX:
Vox_Play(readstring());
break;
case EV_VIEWMODEL:
View_PlayAnimation(readbyte());
break;
case EV_WEAPON_PICKUP:
int w = readbyte();
if (autocvar_cl_autoweaponswitch == 1) {
sendevent("PlayerSwitchWeapon", "i", w);
}
player pl = (player)pSeat->m_ePlayer;
if (getplayerkeyfloat(pl.entnum-1, "*team") == TEAM_CT) {
setcustomskin(pSeat->m_eViewModel, "", "geomset 0 2\n");
} else {
setcustomskin(pSeat->m_eViewModel, "", "geomset 0 1\n");
}
HUD_WeaponPickupNotify(w);
break;
case EV_RADIOMSG:
Radio_PlayMessage(readbyte());
break;
case EV_RADIOMSG2:
Radio_PlayPlayerMessage(readbyte(), readbyte());
break;
}
}

77
src/client/hud.h Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* pre-calculated sprite definitions */
float spr_health[4] = {
48 / 256, // pos x
25 / 256, // pos u
24 / 256, // size x
24 / 256 // size y
};
float spr_suit1[4] = {
0 / 256, // pos x
25 / 256, // pos u
24 / 256, // size x
24 / 256 // size y
};
float spr_suit2[4] = {
24 / 256, // pos x
25 / 256, // pos u
24 / 256, // size x
24 / 256 // size y
};
float spr_suit3[4] = {
0 / 256, // pos x
124 / 256, // pos u
24 / 256, // size x
24 / 256 // size y
};
float spr_suit4[4] = {
24 / 256, // pos x
124 / 256, // pos u
24 / 256, // size x
24 / 256 // size y
};
float spr_flash1[4] = {
160 / 256, // pos x
24 / 256, // pos u
32 / 256, // size x
32 / 256 // size y
};
float spr_flash2[4] = {
112 / 256, // pos x
24 / 256, // pos u
48 / 256, // size x
32 / 256 // size y
};
string
HUD_GetChatColorHEX(float fTeam)
{
if (fTeam == TEAM_CT) {
return "^x7AC";
} else if (fTeam == TEAM_T) {
return "^xC33";
} else {
return "^xCCC";
}
}

691
src/client/hud.qc Normal file
View File

@ -0,0 +1,691 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void HUD_DrawWeaponSelect(void);
/* Use first frame for drawing (needs precache) */
#define NUMSIZE_X 24/256
#define NUMSIZE_Y 24/256
#define HUD_ALPHA 0.5
float spr_hudnum[10] = {
0 / 256,
23 / 256,
47 / 256,
70 / 256,
95 / 256,
119 / 256,
144 / 256,
169 / 256,
192 / 256,
216 / 256
};
/* precaches */
void
HUD_Init(void)
{
precache_model("sprites/640_logo.spr");
g_hud1_spr = spriteframe("sprites/640hud1.spr", 0, 0.0f);
g_hud2_spr = spriteframe("sprites/640hud2.spr", 0, 0.0f);
g_hud3_spr = spriteframe("sprites/640hud3.spr", 0, 0.0f);
g_hud4_spr = spriteframe("sprites/640hud4.spr", 0, 0.0f);
g_hud5_spr = spriteframe("sprites/640hud5.spr", 0, 0.0f);
g_hud6_spr = spriteframe("sprites/640hud6.spr", 0, 0.0f);
g_hud7_spr = spriteframe("sprites/640hud7.spr", 0, 0.0f);
g_hud10_spr = spriteframe("sprites/640hud10.spr", 0, 0.0f);
g_hud11_spr = spriteframe("sprites/640hud11.spr", 0, 0.0f);
g_hud12_spr = spriteframe("sprites/640hud12.spr", 0, 0.0f);
g_hud13_spr = spriteframe("sprites/640hud13.spr", 0, 0.0f);
g_hud14_spr = spriteframe("sprites/640hud14.spr", 0, 0.0f);
g_hud15_spr = spriteframe("sprites/640hud15.spr", 0, 0.0f);
g_hud16_spr = spriteframe("sprites/640hud16.spr", 0, 0.0f);
precache_model("sprites/bottom.spr");
precache_model("sprites/bottom_left.spr");
precache_model("sprites/bottom_right.spr");
precache_model("sprites/left.spr");
precache_model("sprites/radar640.spr");
precache_model("sprites/right.spr");
precache_model("sprites/sniper_scope.spr");
precache_model("sprites/top.spr");
precache_model("sprites/top_left.spr");
precache_model("sprites/top_right.spr");
}
/* seperator for mainly ammo */
void
HUD_DrawSeperator(vector pos)
{
drawsubpic(pos,
[2,24],
g_hud7_spr,
[240/256, 0],
[2/256, 24/256],
g_hud_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
/* handle single/multiple digits */
void
HUD_DrawNumber(int iNumber, vector vecPos, float fAlpha, vector vColor)
{
drawsubpic(vecPos,
[20,25],
g_hud7_spr,
[spr_hudnum[iNumber], 0],
[20/256, 25/256],
vColor,
fAlpha,
DRAWFLAG_ADDITIVE
);
}
void
HUD_DrawNums(float fNumber, vector vecPos, float fAlpha, vector vColor)
{
int i = fNumber;
if (i > 0) {
while (i > 0) {
HUD_DrawNumber((float)i % 10, vecPos, fAlpha, vColor);
i = i / 10;
vecPos[0] -= 20;
}
} else {
HUD_DrawNumber(0, vecPos, fAlpha, vColor);
}
}
/* timer */
void
HUD_DrawTimer(int spectator)
{
int iMinutes, iSeconds, iTens, iUnits;
vector time_pos;
if (spectator) {
time_pos = g_hudmins + [(g_hudres[0] / 2) - 62, 16];
} else {
time_pos = g_hudmins + [(g_hudres[0] / 2) - 62, g_hudres[1] - 42];
}
if (getstatf(STAT_GAMETIME) == -1) {
return;
}
iMinutes = getstatf(STAT_GAMETIME) / 60;
iSeconds = getstatf(STAT_GAMETIME) - 60 * iMinutes;
iTens = iSeconds / 10;
iUnits = iSeconds - 10 * iTens;
/* Flashing red numbers */
if ((iMinutes == 0) && (iTens <= 1)) {
float fAlpha;
/* 0:00 is fully red */
if ((iTens == 0) && (iUnits == 0)) {
fAlpha = 1;
} else {
fAlpha = fabs(sin(time * 20));
}
HUD_DrawNumber(iMinutes, time_pos + [48,0], fAlpha, [1,0,0]);
HUD_DrawNumber(iTens, time_pos + [75,0], fAlpha, [1,0,0]);
HUD_DrawNumber(iUnits, time_pos + [99,0],fAlpha, [1,0,0]);
HUD_DrawNumber(iMinutes, time_pos + [48,0], 1 - fAlpha, g_hud_color);
HUD_DrawNumber(iTens, time_pos + [75,0], 1 - fAlpha, g_hud_color);
HUD_DrawNumber(iUnits, time_pos + [99,0],1 - fAlpha, g_hud_color);
/* : symbol */
drawsubpic(time_pos + [70,6], [3,3], g_hud7_spr, [0.9375, 0], [0.01171875, 0.01171875], [1,0,0], fAlpha, DRAWFLAG_ADDITIVE);
drawsubpic(time_pos + [70,16], [3,3], g_hud7_spr, [0.9375, 0], [0.01171875, 0.01171875], [1,0,0], fAlpha, DRAWFLAG_ADDITIVE);
drawsubpic(time_pos + [70,6], [3,3], g_hud7_spr, [0.9375, 0], [0.01171875, 0.01171875], g_hud_color, 1 - fAlpha, DRAWFLAG_ADDITIVE);
drawsubpic(time_pos + [70,16], [3,3], g_hud7_spr, [0.9375, 0], [0.01171875, 0.01171875], g_hud_color, 1 - fAlpha, DRAWFLAG_ADDITIVE);
/* clock */
drawsubpic(time_pos, [24,25], g_hud7_spr, [NUMSIZE_X * 6, NUMSIZE_Y * 3], [NUMSIZE_X, NUMSIZE_Y], [1,0,0], fAlpha, DRAWFLAG_ADDITIVE);
drawsubpic(time_pos, [24,25], g_hud7_spr, [NUMSIZE_X * 6, NUMSIZE_Y * 3], [NUMSIZE_X, NUMSIZE_Y], g_hud_color, 1 - fAlpha, DRAWFLAG_ADDITIVE);
} else {
if (iUnits != pSeat->m_iTimeUnitsOld) {
pSeat->m_flTimeAlpha = 1.0;
}
if (pSeat->m_flTimeAlpha >= HUD_ALPHA) {
pSeat->m_flTimeAlpha -= clframetime * 0.5;
} else {
pSeat->m_flTimeAlpha = HUD_ALPHA;
}
HUD_DrawNumber(iMinutes, time_pos + [48,0], pSeat->m_flTimeAlpha, g_hud_color);
HUD_DrawNumber(iTens, time_pos + [75,0], pSeat->m_flTimeAlpha, g_hud_color);
HUD_DrawNumber(iUnits, time_pos + [95,0], pSeat->m_flTimeAlpha, g_hud_color);
drawsubpic(time_pos + [70,6], [3,3], g_hud7_spr, [0.9375, 0], [0.01171875, 0.01171875], g_hud_color, pSeat->m_flTimeAlpha, DRAWFLAG_ADDITIVE);
drawsubpic(time_pos + [70,16], [3,3], g_hud7_spr, [0.9375, 0], [0.01171875, 0.01171875], g_hud_color, pSeat->m_flTimeAlpha, DRAWFLAG_ADDITIVE);
drawsubpic(time_pos, [24,25], g_hud7_spr, [NUMSIZE_X * 6, NUMSIZE_Y * 3], [NUMSIZE_X, NUMSIZE_Y], g_hud_color, pSeat->m_flTimeAlpha, DRAWFLAG_ADDITIVE);
pSeat->m_iTimeUnitsOld = iUnits;
}
}
void
HUD_DrawMoney(void)
{
vector money_pos;
float endalpha;
money_pos = g_hudmins + [g_hudres[0] - 160, g_hudres[1] - 72];
/* if the money differs from last frame, paint it appropriately */
if (getstati(STAT_MONEY) > pSeat->m_iMoneyOld) {
/* effect already in progress from something else, go add on top of it! */
if (pSeat->m_flMoneyAlpha > 0) {
pSeat->m_iMoneyDelta += (pSeat->m_iMoneyOld - getstati(STAT_MONEY));
} else {
pSeat->m_iMoneyDelta = pSeat->m_iMoneyOld - getstati(STAT_MONEY);
}
/* make it green for a short time */
pSeat->m_vecMoneyColor = [0,1,0];
pSeat->m_flMoneyAlpha = 1.0;
} else if (getstati(STAT_MONEY) < pSeat->m_iMoneyOld) {
/* same one as above */
if (pSeat->m_flMoneyAlpha > 0) {
pSeat->m_iMoneyDelta += (pSeat->m_iMoneyOld - getstati(STAT_MONEY));
} else {
pSeat->m_iMoneyDelta = pSeat->m_iMoneyOld - getstati(STAT_MONEY);
}
/* make it red */
pSeat->m_vecMoneyColor = [1,0,0];
pSeat->m_flMoneyAlpha = 1.0;
pSeat->m_iMoneyDelta = pSeat->m_iMoneyOld - getstati(STAT_MONEY);
}
/* maximum alpha is variable. */
endalpha = pSeat->m_flMoneyAlpha * HUD_ALPHA;
/* dollar sign */
drawsubpic(
money_pos,
[18,26],
g_hud7_spr,
[192/256, 24/256],
[18/256, 26/256],
g_hud_color,
HUD_ALPHA - endalpha,
DRAWFLAG_ADDITIVE
);
/* if the alpha/color effect is active, draw the money twice in their
* varying alphas/colors */
if (pSeat->m_flMoneyAlpha > 0) {
/* red/green dollar sign */
drawsubpic(
money_pos,
[18,26],
g_hud7_spr,
[192/256, 24/256],
[18/256, 26/256],
pSeat->m_vecMoneyColor,
endalpha,
DRAWFLAG_ADDITIVE
);
/* draw the +/- symbols depending on whether
* or not we made or lost money */
if (pSeat->m_iMoneyDelta < 0) {
drawsubpic(money_pos + [0,-32], [18,23], g_hud7_spr, [0.8671875, 0.09765625], [0.0703125, 0.08984375], pSeat->m_vecMoneyColor, endalpha, DRAWFLAG_ADDITIVE);
} else {
drawsubpic(money_pos + [0,-32], [13,23], g_hud7_spr, [0.8203125, 0.09765625], [0.05078125, 0.08984375], pSeat->m_vecMoneyColor, endalpha, DRAWFLAG_ADDITIVE);
}
/* shift the numbers for reverse drawing */
money_pos[0] += (24 * 5);
/* draw the red/green overlay numbers on top of ours */
HUD_DrawNums(getstati(STAT_MONEY), money_pos, endalpha, pSeat->m_vecMoneyColor);
/* draw above how much money we've lost/gotten from all this */
HUD_DrawNums(fabs(pSeat->m_iMoneyDelta), money_pos + [0,-32], endalpha, pSeat->m_vecMoneyColor);
} else {
money_pos[0] += (24 * 5);
}
/* regular number */
HUD_DrawNums(
getstati(STAT_MONEY),
money_pos,
HUD_ALPHA - endalpha,
g_hud_color
);
pSeat->m_iMoneyOld = getstati(STAT_MONEY);
pSeat->m_flMoneyAlpha = max(0, pSeat->m_flMoneyAlpha - (clframetime * 0.5));
}
/* health */
void
HUD_DrawHealth(void)
{
vector pos;
player pl = (player)pSeat->m_ePlayer;
if (pl.health != pSeat->m_iHealthOld) {
pSeat->m_flHealthAlpha = 1.0;
}
if (pSeat->m_flHealthAlpha >= HUD_ALPHA) {
pSeat->m_flHealthAlpha -= clframetime * 0.5;
} else {
pSeat->m_flHealthAlpha = HUD_ALPHA;
}
pos = g_hudmins + [88, g_hudres[1] - 42];
if (pl.health > 25) {
drawsubpic(
pos + [-72,1],
[24,24],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
g_hud_color,
pSeat->m_flHealthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(pl.health, pos, pSeat->m_flHealthAlpha, g_hud_color);
} else {
drawsubpic(
pos + [-72,1],
[24,24],
g_hud7_spr,
[spr_health[0], spr_health[1]],
[spr_health[2], spr_health[3]],
[1,0,0],
pSeat->m_flHealthAlpha,
DRAWFLAG_ADDITIVE
);
HUD_DrawNums(pl.health, pos, pSeat->m_flHealthAlpha, [1,0,0]);
}
pSeat->m_iHealthOld = pl.health;
}
/* armor/suit charge */
void
HUD_DrawArmor(void)
{
vector pos;
player pl = (player)pSeat->m_ePlayer;
pos = g_hudmins + [198, g_hudres[1] - 42];
if (pl.armor != pSeat->m_iArmorOld) {
pSeat->m_flArmorAlpha = 1.0;
}
if (pSeat->m_flArmorAlpha >= HUD_ALPHA) {
pSeat->m_flArmorAlpha -= clframetime * 0.5;
} else {
pSeat->m_flArmorAlpha = HUD_ALPHA;
}
if (pl.g_items & ITEM_HELMET) {
drawsubpic(
pos + [-80,1],
[24,24],
g_hud7_spr,
[spr_suit4[0], spr_suit4[1]],
[spr_suit4[2], spr_suit4[3]],
g_hud_color,
pSeat->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos + [-80,1],
[24,24],
g_hud7_spr,
[spr_suit2[0], spr_suit2[1]],
[spr_suit2[2], spr_suit2[3]],
g_hud_color,
pSeat->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
}
if (pl.armor > 0) {
if (pl.g_items & ITEM_HELMET) {
drawsubpic(
pos + [-80,1],
[24, 24 * (pl.armor / 100)],
g_hud7_spr,
[spr_suit3[0],
spr_suit3[1]],
[spr_suit3[2], spr_suit3[3] * (pl.armor / 100)],
g_hud_color,
pSeat->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos + [-80,1],
[24, 24 * (pl.armor / 100)],
g_hud7_spr,
[spr_suit1[0],
spr_suit1[1]],
[spr_suit1[2], spr_suit1[3] * (pl.armor / 100)],
g_hud_color,
pSeat->m_flArmorAlpha,
DRAWFLAG_ADDITIVE
);
}
}
HUD_DrawNums(pl.armor, pos, pSeat->m_flArmorAlpha, g_hud_color);
pSeat->m_iArmorOld = pl.armor;
}
/* magazine/clip ammo */
void
HUD_DrawAmmo1(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo1 != pSeat->m_iAmmo1Old) {
pSeat->m_flAmmo1Alpha = 1.0;
pSeat->m_iAmmo1Old = pl.a_ammo1;
}
if (pSeat->m_flAmmo1Alpha >= HUD_ALPHA) {
pSeat->m_flAmmo1Alpha -= clframetime * 0.5;
} else {
pSeat->m_flAmmo1Alpha = HUD_ALPHA;
}
pos = g_hudmins + [g_hudres[0] - 152, g_hudres[1] - 42];
HUD_DrawNums(pl.a_ammo1, pos, pSeat->m_flAmmo1Alpha, g_hud_color);
HUD_DrawSeperator(pos + [30,0]);
}
/* leftover type ammo */
void
HUD_DrawAmmo2(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo2 != pSeat->m_iAmmo2Old) {
pSeat->m_flAmmo2Alpha = 1.0;
pSeat->m_iAmmo2Old = pl.a_ammo2;
}
if (pSeat->m_flAmmo2Alpha >= HUD_ALPHA) {
pSeat->m_flAmmo2Alpha -= clframetime * 0.5;
} else {
pSeat->m_flAmmo2Alpha = HUD_ALPHA;
}
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 42];
HUD_DrawNums(pl.a_ammo2, pos, pSeat->m_flAmmo2Alpha, g_hud_color);
}
/* special ammo */
void
HUD_DrawAmmo3(void)
{
player pl = (player)pSeat->m_ePlayer;
vector pos;
if (pl.a_ammo3 != pSeat->m_iAmmo3Old) {
pSeat->m_flAmmo3Alpha = 1.0;
pSeat->m_iAmmo3Old = pl.a_ammo3;
}
if (pSeat->m_flAmmo3Alpha >= HUD_ALPHA) {
pSeat->m_flAmmo3Alpha -= clframetime * 0.5;
} else {
pSeat->m_flAmmo3Alpha = HUD_ALPHA;
}
pos = g_hudmins + [g_hudres[0] - 72, g_hudres[1] - 74];
HUD_DrawNums(pl.a_ammo3, pos, pSeat->m_flAmmo3Alpha, g_hud_color);
}
/* ammo bar */
void
HUD_DrawAmmoBar(vector pos, float val, float max, float a)
{
if (val <= 0)
return;
float perc;
perc = val / max;
drawfill(pos + [10,5], [20,4], g_hud_color, a, DRAWFLAG_NORMAL);
drawfill(pos + [10,5], [20 * perc,4], [0,1,0], a, DRAWFLAG_NORMAL);
}
/* flashlight/torch indicator */
void
HUD_DrawFlashlight(void)
{
vector pos;
player pl = (player)pSeat->m_ePlayer;
pos = g_hudmins + [g_hudres[0] - 48, 16];
/* both on, draw both sprites at full intensity */
if (pl.gflags & GF_FLASHLIGHT) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[spr_flash1[0], spr_flash1[1]],
[spr_flash1[2], spr_flash1[3]],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
drawsubpic(
pos,
[48,32],
g_hud7_spr,
[spr_flash2[0], spr_flash2[1]],
[spr_flash2[2], spr_flash2[3]],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[spr_flash1[0], spr_flash1[1]],
[spr_flash1[2], spr_flash1[3]],
g_hud_color,
HUD_ALPHA,
DRAWFLAG_ADDITIVE
);
}
}
void
HUD_DrawZones(void)
{
int zc = 0;
vector pos = [0,0,0];
player pl = (player)pSeat->m_ePlayer;
if (pl.gflags & GF_BUYZONE) {
zc++;
}
if (pl.gflags & GF_BOMBZONE) {
zc++;
}
if (pl.gflags & GF_RESCUEZONE) {
zc++;
}
if (pl.g_items & ITEM_DEFUSAL) {
zc++;
}
pos = g_hudmins + [16, (g_hudres[1] / 2) - (zc * 16)];
if (pl.gflags & GF_BUYZONE) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[96/256,148/256],
[32/256,32/256],
[0,1,0],
1.0f,
DRAWFLAG_ADDITIVE
);
pos[1] += 32;
}
if (pl.gflags & GF_BOMBZONE) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[0/256,148/256],
[32/256,32/256],
[0,1,0],
1.0f,
DRAWFLAG_ADDITIVE
);
pos[1] += 32;
}
if (pl.gflags & GF_RESCUEZONE) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[64/256,148/256],
[32/256,32/256],
[0,1,0],
1.0f,
DRAWFLAG_ADDITIVE
);
pos[1] += 32;
}
if (pl.g_items & ITEM_DEFUSAL) {
drawsubpic(
pos,
[32,32],
g_hud7_spr,
[32/256,148/256],
[32/256,32/256],
[0,1,0],
1.0f,
DRAWFLAG_ADDITIVE
);
pos[1] += 32;
}
}
/* defusal etc. progress bar */
void
HUD_DrawProgress(void)
{
vector vSize = [540,16];
vector vMainPos;
float progress;
progress = getstatf(STAT_PROGRESS) / 10.0f;
if (progress > 0) {
vMainPos = g_hudmins;
vMainPos[0] += (g_hudres[0] / 2) - (vSize[0] / 2);
vMainPos[1] += (g_hudres[1] / 2) - (vSize[1] / 2);
vector vBar = vSize;
vBar[0] = 538 * progress;
vBar[1] = 14;
drawfill(vMainPos + [1,1], vBar, g_hud_color, 1.0, DRAWFLAG_ADDITIVE);
drawfill(vMainPos, [vSize[0], 1], g_hud_color, 1.0f); // Top
drawfill([vMainPos[0], vMainPos[1] + vSize[1]], [vSize[0], 1], g_hud_color, 1.0f); // Bottom
drawfill(vMainPos, [1, vSize[1]], g_hud_color, 1.0f); // Left
drawfill([vMainPos[0] + vSize[0], vMainPos[1]], [1, vSize[1] + 1], g_hud_color, 1.0f); // Right
}
}
/* weapon/ammo pickup notifications */
void
HUD_DrawNotify(void)
{
vector pos;
if (pSeat->m_flPickupAlpha <= 0.0f) {
return;
}
pos = g_hudmins + [g_hudres[0] - 192, g_hudres[1] - 128];
Weapons_HUDPic(pSeat->m_iPickupWeapon, 1, pos, pSeat->m_flPickupAlpha);
pSeat->m_flPickupAlpha -= clframetime;
}
void
HUD_WeaponPickupNotify(int w)
{
pSeat->m_iPickupWeapon = w;
pSeat->m_flPickupAlpha = 1.0f;
}
/* main entry */
void
HUD_Draw(void)
{
player pl = (player)pSeat->m_ePlayer;
g_hud_color = autocvar_con_color * (1 / 255);
/* little point in not drawing these, even if you don't have a suit */
Weapons_DrawCrosshair();
HUD_DrawWeaponSelect();
Obituary_Draw();
Textmenu_Draw();
HUD_DrawMoney();
HUD_DrawTimer(0);
if (!(pl.g_items & ITEM_SUIT)) {
return;
}
HUD_DrawNotify();
HUD_DrawHealth();
HUD_DrawArmor();
HUD_DrawZones();
HUD_DrawProgress();
HUD_DrawFlashlight();
Damage_Draw();
}
/* specatator main entry */
void
HUD_DrawSpectator(void)
{
// FIXME
Textmenu_Draw();
Obituary_Draw();
HUD_DrawTimer(1);
}

View File

@ -0,0 +1,228 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
vector g_vecHUDNums[6] =
{
[168 / 256, 72 / 256],
[188 / 256, 72 / 256],
[208 / 256, 72 / 256],
[168 / 256, 92 / 256],
[188 / 256, 92 / 256],
[208 / 256, 92 / 256]
};
void
HUD_DrawWeaponSelect_Forward(void)
{
player pl = (player)pSeat->m_ePlayer;
if (!pl.activeweapon) {
return;
}
if (pSeat->m_flHUDWeaponSelectTime < time) {
pSeat->m_iHUDWeaponSelected = pl.activeweapon;
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
} else {
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
pSeat->m_iHUDWeaponSelected--;
if (pSeat->m_iHUDWeaponSelected <= 0) {
pSeat->m_iHUDWeaponSelected = g_weapons.length - 1;
}
}
pSeat->m_flHUDWeaponSelectTime = time + 3;
if not (pl.g_items & g_weapons[pSeat->m_iHUDWeaponSelected].id) {
HUD_DrawWeaponSelect_Forward();
}
}
void
HUD_DrawWeaponSelect_Back(void)
{
player pl = (player)pSeat->m_ePlayer;
if (!pl.activeweapon) {
return;
}
if (pSeat->m_flHUDWeaponSelectTime < time) {
pSeat->m_iHUDWeaponSelected = pl.activeweapon;
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
} else {
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
pSeat->m_iHUDWeaponSelected++;
if (pSeat->m_iHUDWeaponSelected >= g_weapons.length) {
pSeat->m_iHUDWeaponSelected = 1;
}
}
pSeat->m_flHUDWeaponSelectTime = time + 3;
if not (pl.g_items & g_weapons[pSeat->m_iHUDWeaponSelected].id) {
HUD_DrawWeaponSelect_Back();
}
}
void
HUD_DrawWeaponSelect_Trigger(void)
{
player pl = (player)pSeat->m_ePlayer;
pl.activeweapon = pSeat->m_iHUDWeaponSelected;
sendevent("PlayerSwitchWeapon", "i", pSeat->m_iHUDWeaponSelected);
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE);
pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0;
}
void
HUD_DrawWeaponSelect_Last(void)
{
player pl = (player)pSeat->m_ePlayer;
if (pl.g_items & g_weapons[pSeat->m_iOldWeapon].id) {
pl.activeweapon = pSeat->m_iOldWeapon;
sendevent("PlayerSwitchWeapon", "i", pSeat->m_iOldWeapon);
}
}
void
HUD_DrawWeaponSelect_Num(vector vecPos, int val)
{
drawsubpic(vecPos, [20,20], g_hud7_spr, g_vecHUDNums[val], [20/256, 20/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
}
int
HUD_InSlotPos(int slot, int pos)
{
player pl = (player)pSeat->m_ePlayer;
for (int i = 1; i < g_weapons.length; i++) {
if (g_weapons[i].slot == slot && g_weapons[i].slot_pos == pos) {
if (pl.g_items & g_weapons[i].id) {
return i;
} else {
return -1;
}
}
}
return -1;
}
void
HUD_SlotSelect(int slot)
{
player pl = (player)pSeat->m_ePlayer;
int curslot = g_weapons[pSeat->m_iHUDWeaponSelected].slot;
int i;
if (g_textmenu != "") {
Textmenu_Input(slot);
return;
}
/* hack to see if we have ANY weapons at all. */
if (!pl.activeweapon) {
return;
}
if (pSeat->m_flHUDWeaponSelectTime < time) {
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE);
} else {
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE);
}
/* weren't in that slot? select the first one then */
if (curslot != slot) {
for (i = 1; i < g_weapons.length; i++) {
if (g_weapons[i].slot == slot && pl.g_items & g_weapons[i].id) {
pSeat->m_iHUDWeaponSelected = i;
pSeat->m_flHUDWeaponSelectTime = time + 3;
break;
}
}
} else {
int first = -1;
for (i = 1; i < g_weapons.length; i++) {
if (g_weapons[i].slot == slot && pl.g_items & g_weapons[i].id) {
if (i < pSeat->m_iHUDWeaponSelected && first == -1) {
first = i;
} else if (i > pSeat->m_iHUDWeaponSelected) {
first = -1;
pSeat->m_iHUDWeaponSelected = i;
pSeat->m_flHUDWeaponSelectTime = time + 3;
break;
}
}
}
if (first > 0) {
pSeat->m_iHUDWeaponSelected = first;
pSeat->m_flHUDWeaponSelectTime = time + 3;
}
}
}
void
HUD_DrawWeaponSelect(void)
{
player pl = (player)pSeat->m_ePlayer;
if (!pl.activeweapon) {
return;
}
if (pSeat->m_flHUDWeaponSelectTime < time) {
if (pSeat->m_iHUDWeaponSelected) {
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudoff.wav", 0.5, ATTN_NONE);
pSeat->m_iHUDWeaponSelected = 0;
}
return;
}
vector vecPos = g_hudmins + [16,16];
int b;
int wantslot = g_weapons[pSeat->m_iHUDWeaponSelected].slot;
int wantpos = g_weapons[pSeat->m_iHUDWeaponSelected].slot_pos;
for (int i = 0; i < 5; i++) {
int slot_selected = 0;
vecPos[1] = g_hudmins[1] + 16;
HUD_DrawWeaponSelect_Num(vecPos, i);
vecPos[1] += 20;
for (int x = 0; x < 32; x++) {
if (i == wantslot) {
slot_selected = TRUE;
if (x == wantpos) {
// Selected Sprite
Weapons_HUDPic(pSeat->m_iHUDWeaponSelected, 1, vecPos, 1.0f);
drawsubpic(vecPos, [170,45], g_hud3_spr,
[0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
vecPos[1] += 50;
} else if ((b=HUD_InSlotPos(i, x)) != -1) {
// Unselected Sprite
Weapons_HUDPic(b, 0, vecPos, 1.0f);
vecPos[1] += 50;
}
} else if (HUD_InSlotPos(i, x) != -1) {
HUD_DrawWeaponSelect_Num(vecPos, 5);
vecPos[1] += 25;
}
}
if (slot_selected == TRUE) {
vecPos[0] += 175;
} else {
vecPos[0] += 25;
}
}
}

141
src/client/init.qc Normal file
View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
ClientGame_Init
Comparable to worldspawn in SSQC in that it's mostly used for precaches
=================
*/
void
ClientGame_Init(float apilevel, string enginename, float engineversion)
{
registercommand("chooseteam");
registercommand("buy");
/* radio */
registercommand("radio1");
registercommand("radio2");
registercommand("radio3");
registercommand("motd");
registercommand("drop");
registercommand("nightvision");
/* pistols */
registercommand("glock");
registercommand("usp");
registercommand("p228");
registercommand("deagle");
registercommand("fn57");
registercommand("elites");
/* shotties */
registercommand("m3");
registercommand("xm1014");
/* smg */
registercommand("tmp");
registercommand("mac10");
registercommand("mp5");
registercommand("ump45");
/* rifles */
registercommand("p90");
registercommand("ak47");
registercommand("m4a1");
registercommand("sg552");
registercommand("aug");
registercommand("scout");
registercommand("sg550");
registercommand("awp");
registercommand("g3sg1");
/* lonely */
registercommand("m249");
/* ammo */
registercommand("primammo");
registercommand("buyammo1");
registercommand("secammo");
registercommand("buyammo2");
/* equipment */
registercommand("vest");
registercommand("vesthelm");
registercommand("flash");
registercommand("hegren");
registercommand("vsgren");
registercommand("defuser");
registercommand("nvg");
/* radio */
registercommand("coverme");
registercommand("takepoint");
registercommand("holdpos");
registercommand("regroup");
registercommand("followme");
registercommand("takingfire");
registercommand("go");
registercommand("fallback");
registercommand("sticktog");
registercommand("getinpos");
registercommand("stormfront");
registercommand("report");
registercommand("roger");
registercommand("enemyspot");
registercommand("needbackup");
registercommand("sectorclear");
registercommand("inposition");
registercommand("reportingin");
registercommand("getout");
registercommand("negative");
registercommand("enemydown");
Obituary_Init();
}
void
ClientGame_InitDone(void)
{
Textmenu_Call("TEAM_SELECT");
}
void
ClientGame_RendererRestart(string rstr)
{
g_cs_cross = spriteframe("sprites/crosshairs.spr", 0, 0.0f);
g_cs_scope0 = spriteframe("sprites/sniper_scope.spr", 0, 0.0f);
g_cs_scope1 = spriteframe("sprites/top_left.spr", 0, 0.0f);
g_cs_scope2 = spriteframe("sprites/top.spr", 0, 0.0f);
g_cs_scope3 = spriteframe("sprites/top_right.spr", 0, 0.0f);
g_cs_scope4 = spriteframe("sprites/left.spr", 0, 0.0f);
g_cs_scope5 = spriteframe("sprites/right.spr", 0, 0.0f);
g_cs_scope6 = spriteframe("sprites/bottom_left.spr", 0, 0.0f);
g_cs_scope7 = spriteframe("sprites/bottom.spr", 0, 0.0f);
g_cs_scope8 = spriteframe("sprites/bottom_right.spr", 0, 0.0f);
Obituary_Precache();
FX_Blood_Init();
FX_BreakModel_Init();
FX_Explosion_Init();
FX_GibHuman_Init();
FX_Spark_Init();
FX_Impact_Init();
FX_Smokenade_Init();
}

149
src/client/player.qc Normal file
View File

@ -0,0 +1,149 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
Player_PreDraw(base_player pl, int thirdperson)
{
/* Handle the flashlights... */
if (pl.gflags & GF_FLASHLIGHT) {
vector src;
vector ang;
if (pl.entnum != player_localentnum) {
src = pl.origin + pl.view_ofs;
ang = [pl.pitch, pl.angles[1], pl.angles[2]];
} else {
src = pSeat->m_vecPredictedOrigin + [0,0,-8];
ang = view_angles;
}
makevectors(ang);
traceline(src, src + (v_forward * 8096), MOVE_NORMAL, pl);
if (serverkeyfloat("*bspversion") == BSPVER_HL) {
dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]);
} else {
float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight");
dynamiclight_set(p, LFIELD_ANGLES, ang);
dynamiclight_set(p, LFIELD_FLAGS, 3);
}
}
}
void
Player_ReceiveEntity(float new)
{
float fl;
player pl = (player)self;
if (new == TRUE) {
spawnfunc_player();
pl.classname = "player";
pl.solid = SOLID_SLIDEBOX;
pl.drawmask = MASK_ENGINE;
pl.customphysics = Empty;
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
} else {
int i;
//FIXME: splitscreen
if (pl.entnum == player_localentnum) {
//FIXME: splitscreen
pSeat = &g_seats[0];
for (i = pl.sequence+1; i <= servercommandframe; i++) {
if (!getinputstate(i)) {
break; //erk?... too old?
}
input_sequence = i;
PMove_Run();
}
/* any differences in things that are read below are now
* officially from prediction misses. */
}
}
pl.sequence = servercommandframe;
fl = readfloat();
/* HACK: we need to make this more reliable */
if (fl == UPDATE_ALL) {
/* we respawned */
pl.gravity = __NULL__;
}
if (fl & PLAYER_MODELINDEX)
pl.modelindex = readshort();
if (fl & PLAYER_ORIGIN) {
pl.origin[0] = readcoord();
pl.origin[1] = readcoord();
}
if (fl & PLAYER_ORIGIN_Z)
pl.origin[2] = readcoord();
if (fl & PLAYER_ANGLES_X)
pl.pitch = readfloat();
if (fl & PLAYER_ANGLES_Y)
pl.angles[1] = readfloat();
if (fl & PLAYER_ANGLES_Z)
pl.angles[2] = readfloat();
if (fl & PLAYER_VELOCITY) {
pl.velocity[0] = readcoord();
pl.velocity[1] = readcoord();
}
if (fl & PLAYER_VELOCITY_Z)
pl.velocity[2] = readcoord();
if (fl & PLAYER_FLAGS) {
pl.flags = readfloat();
pl.gflags = readfloat();
}
if (fl & PLAYER_WEAPON)
pl.activeweapon = readbyte();
if (fl & PLAYER_ITEMS)
pl.g_items = (__variant)readfloat();
if (fl & PLAYER_HEALTH)
pl.health = readbyte();
if (fl & PLAYER_ARMOR)
pl.armor = readbyte();
if (fl & PLAYER_MOVETYPE)
pl.movetype = readbyte();
if (fl & PLAYER_VIEWOFS)
pl.view_ofs[2] = readfloat();
if (fl & PLAYER_BASEFRAME) {
pl.baseframe = readbyte();
pl.baseframe1time = 0.0f;
pl.baseframe2time = 0.0f;
}
if (fl & PLAYER_FRAME)
pl.frame = readbyte();
if (fl & PLAYER_AMMO1)
pl.a_ammo1 = readbyte();
if (fl & PLAYER_AMMO2)
pl.a_ammo2 = readbyte();
if (fl & PLAYER_AMMO3)
pl.a_ammo3 = readbyte();
if (fl & PLAYER_CSSHOT)
pl.cs_shotmultiplier = readbyte();
if (fl & PLAYER_CSSHOTTIME)
pl.cs_shottime = readfloat();
setorigin(pl, pl.origin);
}

43
src/client/predict.qc Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
Predict_PreFrame
We're part way through parsing new player data.
Propagate our pmove state to whatever the current frame before its stomped on
(so any non-networked state updates locally).
=================
*/
void
GamePredict_PreFrame(player pl)
{
}
/*
=================
Predict_PostFrame
We're part way through parsing new player data.
Rewind our pmove state back to before we started predicting.
(to give consistent state instead of accumulating errors)
=================
*/
void
GamePredict_PostFrame(player pl)
{
}

42
src/client/progs.src Normal file
View File

@ -0,0 +1,42 @@
#pragma target fte
#pragma progs_dat "../../csprogs.dat"
#pragma includedir "../../../valve/src"
#define CSQC
#define CLIENT
#define VALVE
#define CSTRIKE
#define CLASSIC_VGUI
#define GS_RENDERFX
#includelist
../../../src/shared/fteextensions.qc
../../../src/shared/defs.h
../shared/defs.h
defs.h
../../../src/client/defs.h
../../../src/vgui/include.src
../../../src/gs-entbase/client.src
../../../src/gs-entbase/shared.src
../shared/include.src
predict.qc
textmenu.qc
init.qc
player.qc
entities.qc
cmds.qc
game_event.qc
../../../valve/src/client/view.qc
crosshair.qc
../../../valve/src/client/obituary.qc
hud.qc
hud_weaponselect.qc
../../../valve/src/client/scoreboard.qc
../../../valve/src/client/input.qc
radio.qc
../../../base/src/client/modelevent.qc
../../../src/client/include.src
../../../src/shared/include.src
#endlist

3
src/client/radio.h Normal file
View File

@ -0,0 +1,3 @@
void Radio_Init(void);
void Radio_PlayMessage(float);
void Radio_PlayPlayerMessage(float, float);

147
src/client/radio.qc Executable file
View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
string g_cstrikeRadioWAVs[43] = {
"radio/blow.wav",
"radio/bombdef.wav",
"radio/bombpl.wav",
"radio/circleback.wav",
"radio/clear.wav",
"radio/com_followcom.wav",
"radio/com_getinpos.wav",
"radio/com_go.wav",
"radio/com_reportin.wav",
"radio/ct_affirm.wav",
"radio/ct_backup.wav",
"radio/ct_coverme.wav",
"radio/ct_enemys.wav",
"radio/ct_fireinhole.wav",
"radio/ct_imhit.wav",
"radio/ct_inpos.wav",
"radio/ct_point.wav",
"radio/ct_reportingin.wav",
"radio/ctwin.wav",
"radio/enemydown.wav",
"radio/fallback.wav",
"radio/fireassis.wav",
"radio/followme.wav",
"radio/getout.wav",
"radio/go.wav",
"radio/hitassist.wav",
"radio/hosdown.wav",
"radio/letsgo.wav",
"radio/locknload.wav",
"radio/matedown.wav",
"radio/meetme.wav",
"radio/moveout.wav",
"radio/negative.wav",
"radio/position.wav",
"radio/regroup.wav",
"radio/rescued.wav",
"radio/roger.wav",
"radio/rounddraw.wav",
"radio/sticktog.wav",
"radio/stormfront.wav",
"radio/takepoint.wav",
"radio/terwin.wav",
"radio/vip.wav"
};
string g_cstrikeRadioChat[43] = {
_("RADIO_BLOW"),
_("RADIO_BOMBDEF"),
_("RADIO_BOMBPL"),
_("RADIO_CIRCLEBACK"),
_("RADIO_CLEAR"),
_("RADIO_COM_FOLLOWCOM"),
_("RADIO_COM_GETINPOS"),
_("RADIO_COM_GO"),
_("RADIO_COM_REPORTIN"),
_("RADIO_CT_AFFIRM"),
_("RADIO_CT_BACKUP"),
_("RADIO_CT_COVERME"),
_("RADIO_CT_ENEMYS"),
_("RADIO_CT_FIREINHOLE"),
_("RADIO_CT_IMHIT"),
_("RADIO_CT_INPOS"),
_("RADIO_CT_POINT"),
_("RADIO_CT_REPORTINGIN"),
_("RADIO_CTWIN"),
_("RADIO_ENEMYDOWN"),
_("RADIO_FALLBACK"),
_("RADIO_FIREASSIS"),
_("RADIO_FOLLOWME"),
_("RADIO_GETOUT"),
_("RADIO_GO"),
_("RADIO_HITASSIST"),
_("RADIO_HOSDOWN"),
_("RADIO_LETSGO"),
_("RADIO_LOCKNLOAD"),
_("RADIO_MATEDOWN"),
_("RADIO_MEETME"),
_("RADIO_MOVEOUT"),
_("RADIO_NEGATIVE"),
_("RADIO_POSITION"),
_("RADIO_REGROUP"),
_("RADIO_RESCUED"),
_("RADIO_ROGER"),
_("RADIO_ROUNDDRAW"),
_("RADIO_STICKTOG"),
_("RADIO_STORMFRONT"),
_("RADIO_TAKEPOINT"),
_("RADIO_TERWIN"),
_("RADIO_VIP"),
};
void
Radio_Init(void)
{
for (int i = 0; i < g_cstrikeRadioWAVs.length; i++)
precache_sound(g_cstrikeRadioWAVs[i]);
}
/*
=================
Radio_PlayMessage
Play a radio message that doesn't come from a player
=================
*/
void
Radio_PlayMessage(float fMessage)
{
sound(world, CHAN_VOICE, g_cstrikeRadioWAVs[fMessage], 1, ATTN_NONE, 0, SOUNDFLAG_NOSPACIALISE);
if (fMessage == RADIO_CTWIN || fMessage == RADIO_TERWIN || fMessage == RADIO_ROUNDDRAW) {
CSQC_Parse_CenterPrint(sprintf("%s", g_cstrikeRadioChat[fMessage]));
} else {
CSQC_Parse_Print(sprintf("^2[RADIO]^xF80: %s", g_cstrikeRadioChat[fMessage]), PRINT_CHAT);
}
}
/*
=================
Radio_PlayPlayerMessage
This radio message does come from a player
=================
*/
void
Radio_PlayPlayerMessage(float fPlayerNum, float fMessage)
{
sound(world, CHAN_VOICE, g_cstrikeRadioWAVs[fMessage], 1, ATTN_NONE, 0, SOUNDFLAG_NOSPACIALISE);
CSQC_Parse_Print(sprintf("^2[RADIO] %s%s^xF80: %s", HUD_GetChatColorHEX(stof(getplayerkeyvalue(fPlayerNum, "*team"))), getplayerkeyvalue(fPlayerNum, "name"), g_cstrikeRadioChat[fMessage]), PRINT_CHAT);
}

506
src/client/textmenu.qc Normal file
View File

@ -0,0 +1,506 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
TEAM_SELECT(int n)
{
switch (n) {
case 1:
Textmenu_Call("TERRORIST_SELECT");
break;
case 2:
Textmenu_Call("CT_SELECT");
break;
case 5:
sendevent("JoinAuto", "");
Textmenu_Call("");
break;
}
}
void
TERRORIST_SELECT(int n)
{
switch (n) {
case 1:
sendevent("JoinTeam", "f", 1);
Textmenu_Call("");
break;
case 2:
sendevent("JoinTeam", "f", 2);
Textmenu_Call("");
break;
case 3:
sendevent("JoinTeam", "f", 3);
Textmenu_Call("");
break;
case 4:
sendevent("JoinTeam", "f", 4);
Textmenu_Call("");
break;
case 5:
sendevent("JoinTeam", "f", floor(random(1,5)));
Textmenu_Call("");
break;
}
}
void
CT_SELECT(int n)
{
switch (n) {
case 1:
sendevent("JoinTeam", "f", 5);
Textmenu_Call("");
break;
case 2:
sendevent("JoinTeam", "f", 6);
Textmenu_Call("");
break;
case 3:
sendevent("JoinTeam", "f", 7);
Textmenu_Call("");
break;
case 4:
sendevent("JoinTeam", "f", 8);
Textmenu_Call("");
break;
case 5:
sendevent("JoinTeam", "f", floor(random(1,5)));
Textmenu_Call("");
break;
}
}
void
BUY(int n)
{
player pl;
pl = (player)pSeat->m_ePlayer;
int inteam = getplayerkeyfloat(pl.entnum-1, "*team");
switch (n) {
case 1:
Textmenu_Call(inteam == TEAM_T ? "T_BUYPISTOL" : "CT_BUYPISTOL");
break;
case 2:
Textmenu_Call("BUYSHOTGUN");
break;
case 3:
Textmenu_Call(inteam == TEAM_T ? "T_BUYSUBMACHINEGUN" : "CT_BUYSUBMACHINEGUN");
break;
case 4:
Textmenu_Call(inteam == TEAM_T ? "T_BUYRIFLE" : "CT_BUYRIFLE");
break;
case 5:
Textmenu_Call(inteam == TEAM_T ? "BUYMACHINEGUN" : "BUYMACHINEGUN");
break;
case 6:
sendevent("AmmoBuyPrimary", "");
Textmenu_Call("");
break;
case 7:
sendevent("AmmoBuySecondary", "");
Textmenu_Call("");
break;
case 8:
Textmenu_Call(inteam == TEAM_T ? "DT_BUYITEM" : "DCT_BUYITEM");
break;
case 10:
Textmenu_Call("");
break;
}
}
/* Equipment */
void
DT_BUYITEM(int n)
{
switch (n) {
case 1:
sendevent("BuyEquipment", "f", 0);
break;
case 2:
sendevent("BuyEquipment", "f", 1);
break;
case 3:
sendevent("BuyEquipment", "f", 2);
break;
case 4:
sendevent("BuyEquipment", "f", 3);
break;
case 5:
sendevent("BuyEquipment", "f", 4);
break;
case 7:
sendevent("BuyEquipment", "f", 6);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
void
DCT_BUYITEM(int n)
{
switch (n) {
case 1:
sendevent("BuyEquipment", "f", 0);
break;
case 2:
sendevent("BuyEquipment", "f", 1);
break;
case 3:
sendevent("BuyEquipment", "f", 2);
break;
case 4:
sendevent("BuyEquipment", "f", 3);
break;
case 5:
sendevent("BuyEquipment", "f", 4);
break;
case 6:
sendevent("BuyEquipment", "f", 5);
break;
case 7:
sendevent("BuyEquipment", "f", 6);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
/* Handguns */
void
T_BUYPISTOL(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_USP45);
break;
case 2:
sendevent("BuyWeapon", "f", WEAPON_GLOCK18);
break;
case 3:
sendevent("BuyWeapon", "f", WEAPON_DEAGLE);
break;
case 4:
sendevent("BuyWeapon", "f", WEAPON_P228);
break;
case 5:
sendevent("BuyWeapon", "f", WEAPON_ELITES);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
void
CT_BUYPISTOL(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_USP45);
break;
case 2:
sendevent("BuyWeapon", "f", WEAPON_GLOCK18);
break;
case 3:
sendevent("BuyWeapon", "f", WEAPON_DEAGLE);
break;
case 4:
sendevent("BuyWeapon", "f", WEAPON_P228);
break;
case 6:
sendevent("BuyWeapon", "f", WEAPON_FIVESEVEN);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
/* Shotguns */
void
BUYSHOTGUN(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_M3);
break;
case 2:
sendevent("BuyWeapon", "f", WEAPON_XM1014);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
/* Rifles, Sniper */
void
T_BUYRIFLE(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_AK47);
break;
case 2:
sendevent("BuyWeapon", "f", WEAPON_SG552);
break;
case 5:
sendevent("BuyWeapon", "f", WEAPON_SCOUT);
break;
case 6:
sendevent("BuyWeapon", "f", WEAPON_AWP);
break;
case 7:
sendevent("BuyWeapon", "f", WEAPON_G3SG1);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
void
CT_BUYRIFLE(int n)
{
switch (n) {
case 3:
sendevent("BuyWeapon", "f", WEAPON_M4A1);
break;
case 4:
sendevent("BuyWeapon", "f", WEAPON_AUG);
break;
case 5:
sendevent("BuyWeapon", "f", WEAPON_SCOUT);
break;
case 6:
sendevent("BuyWeapon", "f", WEAPON_AWP);
break;
case 7:
sendevent("BuyWeapon", "f", WEAPON_G3SG1);
break;
case 8:
sendevent("BuyWeapon", "f", WEAPON_SG550);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
/* SMGs */
void
T_BUYSUBMACHINEGUN(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_MP5);
break;
case 3:
sendevent("BuyWeapon", "f", WEAPON_P90);
break;
case 4:
sendevent("BuyWeapon", "f", WEAPON_MAC10);
break;
case 5:
sendevent("BuyWeapon", "f", WEAPON_UMP45);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
void
CT_BUYSUBMACHINEGUN(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_MP5);
break;
case 2:
sendevent("BuyWeapon", "f", WEAPON_TMP);
break;
case 3:
sendevent("BuyWeapon", "f", WEAPON_P90);
break;
case 5:
sendevent("BuyWeapon", "f", WEAPON_UMP45);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
/* Big and heavy */
void
BUYMACHINEGUN(int n)
{
switch (n) {
case 1:
sendevent("BuyWeapon", "f", WEAPON_PARA);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
/* Radio */
void
RADIOA(int n)
{
switch (n) {
case 1:
sendevent("Radio", "f", RADIO_CT_COVERME);
break;
case 2:
sendevent("Radio", "f", RADIO_TAKEPOINT);
break;
case 3:
sendevent("Radio", "f", RADIO_POSITION);
break;
case 4:
sendevent("Radio", "f", RADIO_REGROUP);
break;
case 5:
sendevent("Radio", "f", RADIO_FOLLOWME);
break;
case 6:
sendevent("Radio", "f", RADIO_FIREASSIS);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
void
RADIOB(int n)
{
switch (n) {
case 1:
sendevent("Radio", "f", RADIO_COM_GO);
break;
case 2:
sendevent("Radio", "f", RADIO_FALLBACK);
break;
case 3:
sendevent("Radio", "f", RADIO_STICKTOG);
break;
case 4:
sendevent("Radio", "f", RADIO_COM_GETINPOS);
break;
case 5:
sendevent("Radio", "f", RADIO_STORMFRONT);
break;
case 6:
sendevent("Radio", "f", RADIO_COM_REPORTIN);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}
void
RADIOC(int n)
{
switch (n) {
case 1:
sendevent("Radio", "f", RADIO_CT_AFFIRM);
break;
case 2:
sendevent("Radio", "f", RADIO_CT_ENEMYS);
break;
case 3:
sendevent("Radio", "f", RADIO_CT_BACKUP);
break;
case 4:
sendevent("Radio", "f", RADIO_CLEAR);
break;
case 5:
sendevent("Radio", "f", RADIO_CT_INPOS);
break;
case 6:
sendevent("Radio", "f", RADIO_COM_REPORTIN);
break;
case 7:
sendevent("Radio", "f", RADIO_BLOW);
break;
case 8:
sendevent("Radio", "f", RADIO_NEGATIVE);
break;
case 9:
sendevent("Radio", "f", RADIO_ENEMYDOWN);
break;
case 10:
Textmenu_Call("");
break;
default:
return;
}
Textmenu_Call("");
}

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
static CUIWindow winChooseTeam;
static CUIWindow winCTTeam;
static CUIWindow winTTeam;
void
T_Skin1(void)
{
sendevent("GamePlayerSpawn", "f", 1);
winTTeam.Hide();
}
void
T_Skin2(void)
{
sendevent("GamePlayerSpawn", "f", 2);
winTTeam.Hide();
}
void
T_Skin3(void)
{
sendevent("GamePlayerSpawn", "f", 3);
winTTeam.Hide();
}
void
T_Skin4(void)
{
sendevent("GamePlayerSpawn", "f", 4);
winTTeam.Hide();
}
void
CT_Skin1(void)
{
sendevent("GamePlayerSpawn", "f", 5);
winCTTeam.Hide();
}
void
CT_Skin2(void)
{
sendevent("GamePlayerSpawn", "f", 6);
winCTTeam.Hide();
}
void
CT_Skin3(void)
{
sendevent("GamePlayerSpawn", "f", 7);
winCTTeam.Hide();
}
void
CT_Skin4(void)
{
sendevent("GamePlayerSpawn", "f", 8);
winCTTeam.Hide();
}
void
VGUI_GoSpectator(void)
{
sendevent("GamePlayerSpawn", "f", 0);
winChooseTeam.Hide();
}
void
VGUI_ChooseTeam_CT(void)
{
static int initialized;
static CUIButton btnSkin1;
static CUIButton btnSkin2;
static CUIButton btnSkin3;
static CUIButton btnSkin4;
if (!initialized) {
initialized = TRUE;
winCTTeam = spawn(CUIWindow);
winCTTeam.SetTitle("Choose Skin");
winCTTeam.SetSize([420,320]);
btnSkin1 = spawn(CUIButton);
btnSkin1.SetTitle("Skin 1");
btnSkin1.SetPos([8,132]);
btnSkin1.SetFunc(CT_Skin1);
btnSkin2 = spawn(CUIButton);
btnSkin2.SetTitle("Skin 2");
btnSkin2.SetPos([8,132+30]);
btnSkin2.SetFunc(CT_Skin2);
btnSkin3 = spawn(CUIButton);
btnSkin3.SetTitle("Skin 3");
btnSkin3.SetPos([8,132+30+30]);
btnSkin3.SetFunc(CT_Skin3);
btnSkin4 = spawn(CUIButton);
btnSkin4.SetTitle("Skin 4");
btnSkin4.SetPos([8,132+30+30+30]);
btnSkin4.SetFunc(CT_Skin4);
g_uiDesktop.Add(winCTTeam);
winCTTeam.Add(btnSkin1);
winCTTeam.Add(btnSkin2);
winCTTeam.Add(btnSkin3);
winCTTeam.Add(btnSkin4);
}
winChooseTeam.Hide();
winCTTeam.Show();
winCTTeam.SetPos((video_res / 2) - (winCTTeam.GetSize() / 2));
}
void
VGUI_ChooseTeam_T(void)
{
static int initialized;
static CUIButton btnSkin1;
static CUIButton btnSkin2;
static CUIButton btnSkin3;
static CUIButton btnSkin4;
if (!initialized) {
initialized = TRUE;
winTTeam = spawn(CUIWindow);
winTTeam.SetTitle("Choose Skin");
winTTeam.SetSize([420,320]);
btnSkin1 = spawn(CUIButton);
btnSkin1.SetTitle("Skin 1");
btnSkin1.SetPos([8,132]);
btnSkin1.SetFunc(T_Skin1);
btnSkin2 = spawn(CUIButton);
btnSkin2.SetTitle("Skin 2");
btnSkin2.SetPos([8,132+30]);
btnSkin2.SetFunc(T_Skin2);
btnSkin3 = spawn(CUIButton);
btnSkin3.SetTitle("Skin 3");
btnSkin3.SetPos([8,132+30+30]);
btnSkin3.SetFunc(T_Skin3);
btnSkin4 = spawn(CUIButton);
btnSkin4.SetTitle("Skin 4");
btnSkin4.SetPos([8,132+30+30+30]);
btnSkin4.SetFunc(T_Skin4);
g_uiDesktop.Add(winTTeam);
winTTeam.Add(btnSkin1);
winTTeam.Add(btnSkin2);
winTTeam.Add(btnSkin3);
winTTeam.Add(btnSkin4);
}
winChooseTeam.Hide();
winTTeam.Show();
winTTeam.SetPos((video_res / 2) - (winTTeam.GetSize() / 2));
}
void
VGUI_ChooseTeam(void)
{
static int initialized;
static CUIButton btnGoCT;
static CUIButton btnGoT;
static CUIButton btnGoSpectator;
if (!initialized) {
initialized = TRUE;
winChooseTeam = spawn(CUIWindow);
winChooseTeam.SetTitle("Choose Team");
winChooseTeam.SetSize('420 320');
btnGoCT = spawn(CUIButton);
btnGoCT.SetTitle("Counter-Terrorists");
btnGoCT.SetPos('8 132');
btnGoCT.SetFunc(VGUI_ChooseTeam_CT);
btnGoT = spawn(CUIButton);
btnGoT.SetTitle("Terrorists");
btnGoT.SetPos('8 162');
btnGoT.SetFunc(VGUI_ChooseTeam_T);
btnGoSpectator = spawn(CUIButton);
btnGoSpectator.SetTitle("Spectator");
btnGoSpectator.SetPos('8 192');
btnGoSpectator.SetFunc(VGUI_GoSpectator);
g_uiDesktop.Add(winChooseTeam);
winChooseTeam.Add(btnGoCT);
winChooseTeam.Add(btnGoT);
winChooseTeam.Add(btnGoSpectator);
}
winChooseTeam.Show();
winChooseTeam.SetPos((video_res / 2) - (winChooseTeam.GetSize() / 2));
}

2
src/progs.src Executable file
View File

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

4
src/server/Makefile Normal file
View File

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

312
src/server/ammo.qc Normal file
View File

@ -0,0 +1,312 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Ammo information courtesy of https://wiki.alliedmods.net/CS_weapons_information */
enum
{
CALIBER_NONE,
CALIBER_50AE,
CALIBER_762MM,
CALIBER_556MM,
CALIBER_556MMBOX,
CALIBER_338MAG,
CALIBER_9MM,
CALIBER_BUCKSHOT,
CALIBER_45ACP,
CALIBER_357SIG,
CALIBER_57MM
};
typedef struct
{
int a_size;
int a_max;
int price;
} ammoinfo_t;
ammoinfo_t cs_ammoinfo[11] = {
/* CALIBER_NONE */
{
.a_size = 0,
.a_max = 0,
.price = 0
},
/* CALIBER_50AE */
{
.a_size = 7,
.a_max = 35,
.price = 40
},
/* CALIBER_762MM */
{
.a_size = 30,
.a_max = 90,
.price = 80
},
/* CALIBER_556MM */
{
.a_size = 30,
.a_max = 90,
.price = 60
},
/* CALIBER_556MMBOX */
{
.a_size = 30,
.a_max = 200,
.price = 60
},
/* CALIBER_338MAG */
{
.a_size = 10,
.a_max = 30,
.price = 125
},
/* CALIBER_9MM */
{
.a_size = 30,
.a_max = 150,
.price = 20
},
/* CALIBER_BUCKSHOT */
{
.a_size = 8,
.a_max = 32,
.price = 65
},
/* CALIBER_45ACP */
{
.a_size = 12,
.a_max = 100,
.price = 25
},
/* CALIBER_357SIG */
{
.a_size = 13,
.a_max = 52,
.price = 50
},
/* CALIBER_57MM */
{
.a_size = 50,
.a_max = 100,
.price = 50
}
};
int
Ammo_BuyCaliber(player pl, int cal, int free)
{
int *ptr_ammo = __NULL__;
int rv = 0;
while (pl.money - cs_ammoinfo[cal].price > 0) {
switch (cal) {
case CALIBER_50AE:
ptr_ammo = &pl.ammo_50ae;
break;
case CALIBER_762MM:
ptr_ammo = &pl.ammo_762mm;
break;
case CALIBER_556MM:
ptr_ammo = &pl.ammo_556mm;
break;
case CALIBER_556MMBOX:
ptr_ammo = &pl.ammo_556mmbox;
break;
case CALIBER_338MAG:
ptr_ammo = &pl.ammo_338mag;
break;
case CALIBER_9MM:
ptr_ammo = &pl.ammo_9mm;
break;
case CALIBER_BUCKSHOT:
ptr_ammo = &pl.ammo_buckshot;
break;
case CALIBER_45ACP:
ptr_ammo = &pl.ammo_45acp;
break;
case CALIBER_357SIG:
ptr_ammo = &pl.ammo_357sig;
break;
case CALIBER_57MM:
ptr_ammo = &pl.ammo_57mm;
break;
default:
error("Ammo_BuyCaliber: Impossible caliber definition.");
}
if (*ptr_ammo >= cs_ammoinfo[cal].a_max) {
break;
}
*ptr_ammo += cs_ammoinfo[cal].a_size;
/* clamp */
if (*ptr_ammo >= cs_ammoinfo[cal].a_max) {
*ptr_ammo = cs_ammoinfo[cal].a_max;
}
if (!free)
Money_AddMoney(pl, -cs_ammoinfo[cal].price);
rv = 1;
}
return rv;
}
/* We want to loop through all the possible weapons in case the server
* enabled the ability to pick up more than one primary/secondary weapon */
void
CSEv_AmmoBuySecondary(void)
{
int cal = 0;
int ps = 0;
player pl = (player)self;
CSGameRules rules = (CSGameRules)g_grMode;
if (rules.BuyingPossible(pl) == FALSE) {
return;
}
for (int i = 1; i < g_weapons.length; i++) {
if ((pl.g_items & g_weapons[i].id) && (g_weapons[i].slot == 1)) {
switch (i) {
case WEAPON_USP45:
cal = CALIBER_45ACP;
break;
case WEAPON_GLOCK18:
cal = CALIBER_9MM;
break;
case WEAPON_DEAGLE:
cal = CALIBER_50AE;
break;
case WEAPON_P228:
cal = CALIBER_357SIG;
break;
case WEAPON_ELITES:
cal = CALIBER_9MM;
break;
case WEAPON_FIVESEVEN:
cal = CALIBER_57MM;
break;
}
if (Ammo_BuyCaliber(pl, cal, FALSE) == 1) {
ps = 1;
}
}
}
if (ps) {
Sound_Play(pl, CHAN_ITEM, "buy.ammo");
}
Weapons_RefreshAmmo(pl);
}
void
CSEv_AmmoBuyPrimary(void)
{
int ps = 0;
int cal = 0;
player pl = (player)self;
CSGameRules rules = (CSGameRules)g_grMode;
if (rules.BuyingPossible(pl) == FALSE) {
return;
}
for (int i = 1; i < g_weapons.length; i++) {
if ((pl.g_items & g_weapons[i].id) && (g_weapons[i].slot == 0)) {
switch (i) {
case WEAPON_M3:
cal = CALIBER_BUCKSHOT;
break;
case WEAPON_XM1014:
cal = CALIBER_BUCKSHOT;
break;
case WEAPON_MP5:
cal = CALIBER_9MM;
break;
case WEAPON_P90:
cal = CALIBER_57MM;
break;
case WEAPON_UMP45:
cal = CALIBER_45ACP;
break;
case WEAPON_MAC10:
cal = CALIBER_45ACP;
break;
case WEAPON_TMP:
cal = CALIBER_9MM;
break;
case WEAPON_AK47:
cal = CALIBER_762MM;
break;
case WEAPON_SG552:
cal = CALIBER_556MM;
break;
case WEAPON_M4A1:
cal = CALIBER_556MM;
break;
case WEAPON_AUG:
cal = CALIBER_762MM;
break;
case WEAPON_SCOUT:
cal = CALIBER_762MM;
break;
case WEAPON_AWP:
cal = CALIBER_338MAG;
break;
case WEAPON_G3SG1:
cal = CALIBER_762MM;
break;
case WEAPON_SG550:
cal = CALIBER_556MM;
break;
case WEAPON_PARA:
cal = CALIBER_556MMBOX;
break;
}
if (Ammo_BuyCaliber(pl, cal, FALSE) == 1) {
ps = 1;
}
}
}
if (ps) {
Sound_Play(pl, CHAN_ITEM, "buy.ammo");
}
Weapons_RefreshAmmo(pl);
}
void
Ammo_AutoFill(player pl)
{
if (autocvar_fcs_fillweapons == FALSE) {
return;
}
/* TODO: */
}
void
Ammo_Clear(void)
{
}

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED armoury_entity (0 0 0.8) (-16 -16 0) (16 16 16)
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
"item" Which weapon/equipment this item will contain
"count" How many of said item will players be able to pick up from this
COUNTER-STRIKE (1999) ENTITY
Items in the armoury.
An item oriented entity that contains one or more weapon/equipment item
for players to pick up. It's limited to early Counter-Strike weapons, as
it was never updated in newer versions to add support for newly added ones.
List of available items:
0 = H&K MP5-Navy
1 = Steyr Tactical (TMP)
2 = FN P90
3 = Ingram MAC-10
4 = AK-47
5 = Sig SG-552 Commando
6 = Colt M4A1 Carbine
7 = Steyr AUG
8 = Steyr Scout
9 = H&K G3/SG-1
10 = AI Arctic Warfare/Magnum
11 = Benneli M3 Super90
12 = Benneli XM1014
13 = FN M249 Para
14 = Flashbang Grenade
15 = HE Grenade
16 = Kevlar
17 = Kevlar + Helmet
18 = Smoke Grenade
*/
var int autocvar_fcs_nopickups = FALSE;
int g_cstrike_armouryitems[19] = {
WEAPON_MP5,
WEAPON_TMP,
WEAPON_P90,
WEAPON_MAC10,
WEAPON_AK47,
WEAPON_SG552,
WEAPON_M4A1,
WEAPON_AUG,
WEAPON_SCOUT,
WEAPON_G3SG1,
WEAPON_AWP,
WEAPON_M3,
WEAPON_XM1014,
WEAPON_PARA,
WEAPON_FLASHBANG,
WEAPON_HEGRENADE,
0,/*EQUIPMENT_KEVLAR,*/
0,/*EQUIPMENT_HELMET,*/
WEAPON_SMOKEGRENADE
};
string sArmouryModels[19] = {
"models/w_mp5.mdl",
"models/w_tmp.mdl",
"models/w_p90.mdl",
"models/w_mac10.mdl",
"models/w_ak47.mdl",
"models/w_sg552.mdl",
"models/w_m4a1.mdl",
"models/w_aug.mdl",
"models/w_scout.mdl",
"models/w_g3sg1.mdl",
"models/w_awp.mdl",
"models/w_m3.mdl",
"models/w_xm1014.mdl",
"models/w_m249.mdl",
"models/w_flashbang.mdl",
"models/w_hegrenade.mdl",
"models/w_kevlar.mdl",
"models/w_assault.mdl",
"models/w_smokegrenade.mdl"
};
class armoury_entity:CBaseEntity
{
int m_iCount;
int m_iLeft;
int m_iItem;
void(void) armoury_entity;
virtual void(void) touch;
virtual void(void) Respawn;
virtual void(string, string) SpawnKey;
};
void
armoury_entity::touch(void)
{
if (other.classname != "player") {
return;
}
/* temp */
if (m_iItem == 17 || m_iItem == 16)
return;
if (Weapons_AddItem((player)other, m_iItem, -1) == FALSE) {
return;
}
Logging_Pickup(other, this, __NULL__);
sound(other, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM);
m_iLeft--;
if (m_iLeft <= 0) {
Hide();
}
}
void
armoury_entity::Respawn(void)
{
SetModel(m_oldModel);
setsize(this, [-16,-16,0], [16,16,16]);
solid = SOLID_TRIGGER;
m_iLeft = m_iCount;
droptofloor();
}
void
armoury_entity::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "count":
m_iCount = stoi(strValue);
break;
case "item":
int id = stoi(strValue);
if (id < 0 || id >= 19) {
print(sprintf("^1armoury_entity with invalid item %i. ignoring\n", m_iItem));
remove(this);
return;
}
m_iItem = g_cstrike_armouryitems[id];
model = sArmouryModels[id];
break;
default:
CBaseEntity::SpawnKey(strKey, strValue);
break;
}
}
void
armoury_entity::armoury_entity(void)
{
if (autocvar_fcs_nopickups == TRUE) {
remove(this);
return;
}
m_iCount = 1;
CBaseEntity::CBaseEntity();
}

205
src/server/buy.qc Normal file
View File

@ -0,0 +1,205 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* values courtesy of https://wiki.alliedmods.net/Cs_weapons_information */
int g_cstrikeWeaponPrice[] =
{
0, /* WEAPON_NONE */
1700, /* WEAPON_M3 */
3000, /* WEAPON_XM1014 */
1500, /* WEAPON_MP5 */
2350, /* WEAPON_P90 */
1700, /* WEAPON_UMP45 */
1400, /* WEAPON_MAC10 */
1250, /* WEAPON_TMP */
2500, /* WEAPON_AK47 */
3500, /* WEAPON_SG552 */
3100, /* WEAPON_M4A1 */
3500, /* WEAPON_AUG */
2750, /* WEAPON_SCOUT */
4750, /* WEAPON_AWP */
5000, /* WEAPON_G3SG1 */
4200, /* WEAPON_SG550 */
5750, /* WEAPON_PARA */
500, /* WEAPON_USP45 */
400, /* WEAPON_GLOCK18 */
650, /* WEAPON_DEAGLE */
600, /* WEAPON_P228 */
800, /* WEAPON_ELITES */
750, /* WEAPON_FIVESEVEN */
0, /* WEAPON_KNIFE */
300, /* WEAPON_HEGRENADE */
200, /* WEAPON_FLASHBANG */
300, /* WEAPON_SMOKEGRENADE */
0 /* WEAPON_C4BOMB */
};
void
CSEv_BuyWeapon_f(float fWeapon)
{
CSGameRules rules = (CSGameRules)g_grMode;
int iWeapon;
player pl = (player)self;
iWeapon = (int)fWeapon;
if (rules.BuyingPossible(pl) == FALSE) {
return;
}
if (pl.team == TEAM_T) {
if (iWeapon == WEAPON_M4A1) { return; }
if (iWeapon == WEAPON_AUG) { return; }
if (iWeapon == WEAPON_SG550) { return; }
if (iWeapon == WEAPON_FIVESEVEN) { return; }
if (iWeapon == WEAPON_TMP) { return; }
} else if (pl.team == TEAM_CT) {
if (iWeapon == WEAPON_AK47) { return; }
if (iWeapon == WEAPON_SG552) { return; }
if (iWeapon == WEAPON_G3SG1) { return; }
if (iWeapon == WEAPON_ELITES) { return; }
if (iWeapon == WEAPON_MAC10) { return; }
}
if (Weapons_IsPresent(pl, iWeapon))
return;
if ((pl.money - g_cstrikeWeaponPrice[iWeapon]) >= 0) {
/* let's check if we've got a limit */
int maxit;
maxit = rules.MaxItemPerSlot(g_weapons[iWeapon].slot);
if (maxit > 0) {
int wantslot = g_weapons[iWeapon].slot;
int c = 0;
for (int i = 0; i < g_weapons.length; i++) {
if (pl.g_items & g_weapons[i].id && g_weapons[i].slot == wantslot) {
c++;
/* we're over the slot limit. */
if (c >= maxit) {
pl.activeweapon = i;
Weapon_DropCurrentWeapon(pl);
}
}
}
}
Weapons_AddItem(pl, iWeapon, -1);
Money_AddMoney(pl, -g_cstrikeWeaponPrice[iWeapon]);
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
} else {
//centerprint(pl, "You have insufficient funds!");
}
}
int g_cstrikeUtilPrice[] =
{
650, /* Kevlar Vest */
1000, /* Kevlar Vest & Helmet */
200, /* Flashbang */
300, /* HE Grenade */
300, /* Smoke Grenade */
200, /* Defuse Kit */
1250 /* NightVision Goggles */
};
void
CSEv_BuyEquipment_f(float fUtil)
{
CSGameRules rules = (CSGameRules)g_grMode;
int iUtil;
player pl = (player)self;
iUtil = (int)fUtil;
if (rules.BuyingPossible(pl) == FALSE) {
return;
}
if (pl.team == TEAM_T) {
if (iUtil == 5) { return; }
}
if ((pl.money - g_cstrikeUtilPrice[iUtil]) >= 0) {
switch (iUtil) {
case 0:
if (pl.armor >= 100)
return;
pl.armor = 100;
Sound_Play(pl, CHAN_ITEM, "buy.kevlar");
break;
case 1:
if (pl.g_items & ITEM_HELMET && pl.armor >= 0)
return;
pl.armor = 100;
pl.g_items |= ITEM_HELMET;
Sound_Play(pl, CHAN_ITEM, "buy.kevlar");
break;
case 2:
if (Weapons_IsPresent(pl, WEAPON_FLASHBANG)) {
if (pl.ammo_fbgrenade >= AMMO_MAX_FLASHBANG)
return;
else
pl.ammo_fbgrenade++;
} else
Weapons_AddItem(pl, WEAPON_FLASHBANG, -1);
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
break;
case 3:
if (Weapons_IsPresent(pl, WEAPON_HEGRENADE)) {
if (pl.ammo_hegrenade >= AMMO_MAX_HENADE)
return;
else
pl.ammo_hegrenade++;
} else
Weapons_AddItem(pl, WEAPON_HEGRENADE, -1);
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
break;
case 4:
if (Weapons_IsPresent(pl, WEAPON_SMOKEGRENADE)) {
if (pl.ammo_smokegrenade >= AMMO_MAX_SMOKE)
return;
else
pl.ammo_smokegrenade++;
} else
Weapons_AddItem(pl, WEAPON_SMOKEGRENADE, -1);
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
break;
case 5:
if (pl.g_items & ITEM_DEFUSAL)
return;
pl.g_items |= ITEM_DEFUSAL;
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
break;
case 6:
if (pl.g_items & ITEM_NIGHTVISION)
return;
pl.g_items |= ITEM_NIGHTVISION;
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
break;
}
Money_AddMoney(pl, -g_cstrikeUtilPrice[iUtil]);
} else {
//centerprint(pl, "You have insufficient funds!");
}
}

84
src/server/client.qc Normal file
View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
Game_RunClientCommand(void)
{
player pl = (player)self;
pl.gflags &= ~GF_BUYZONE;
pl.gflags &= ~GF_RESCUEZONE;
pl.gflags &= ~GF_BOMBZONE;
Footsteps_Update();
PMove_Run();
}
void
SV_SendChat(entity sender, string msg, entity eEnt, float fType)
{
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, fType == 0 ? EV_CHAT:EV_CHAT_TEAM);
WriteByte(MSG_MULTICAST, num_for_edict(sender) - 1);
WriteByte(MSG_MULTICAST, sender.team);
WriteString(MSG_MULTICAST, msg);
if (eEnt) {
msg_entity = eEnt;
multicast([0,0,0], MULTICAST_ONE);
} else {
multicast([0,0,0], MULTICAST_ALL);
}
localcmd(sprintf("echo [SERVER] %s: %s\n", sender.netname, msg));
}
void
Game_ParseClientCommand(string cmd)
{
tokenize(cmd);
if (argv(1) == "timeleft") {
string msg;
string timestring;
float timeleft;
timeleft = cvar("mp_timelimit") - (time / 60);
timestring = Vox_TimeToString(timeleft);
msg = sprintf("we have %s minutes remaining", timestring);
Vox_Singlecast(self, msg);
return;
}
if (argv(0) == "say") {
SV_SendChat(self, argv(1), world, 0);
return;
} else if (argv(0) == "say_team") {
entity a;
for (a = world; (a = find(a, ::classname, "player"));) {
if (a.team == self.team) {
SV_SendChat(self, argv(1), a, 1);
}
}
return;
}
clientcommand(self, cmd);
}
void
Game_SetNewParms(void)
{
}

79
src/server/defs.h Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "gamerules.h"
#include "money.h"
#include "radio.h"
#include "../../../valve/src/server/items.h"
var int g_cstrike_buying = 0;
var float g_cstrike_bombradius = 500;
var int g_cs_vipzones;
var int g_cs_escapezones;
var int g_cs_bombzones;
var int g_cs_bombplanted;
var int g_cs_roundswon_ct;
var int g_cs_roundswon_t;
var int g_cs_roundsplayed;
var int g_cs_alive_t;
var int g_cs_alive_ct;
var int g_cs_hostagesrescued;
var int g_cs_hostagestotal;
var int g_cs_roundslost_ct;
var int g_cs_roundslost_t;
var int g_cs_winstreak_ct;
var int g_cs_winstreak_t;
var int g_cs_bonus_ct;
var int g_cs_bonus_t;
var int g_cs_gamestate;
var float g_cs_gametime;
/* Counter-Strike's own cvars */
var int autocvar_mp_winlimit = 0;
var int autocvar_mp_halftime = 0;
var int autocvar_mp_startmoney = 800;
var float autocvar_mp_buytime = 90;
var float autocvar_mp_freezetime = 6;
var float autocvar_mp_c4timer = 45;
var float autocvar_mp_roundtime = 5;
var float autocvar_mp_timelimit = 60;
var string autocvar_motdfile = "motd.txt";
var int autocvar_mp_friendlyfire = FALSE;
/* new, FreeCS exclusive variables */
var int autocvar_fcs_voxannounce = FALSE;
var int autocvar_fcs_knifeonly = FALSE; /* Disallows buying and spawning with weps */
var int autocvar_fcs_swapteams = FALSE; /* Swaps spawnpoints */
var int autocvar_fcs_nopickups = FALSE; /* Disable weapon items */
var int autocvar_fcs_reward_kill = 300;
var int autocvar_fcs_penalty_pain = -150;
var int autocvar_fcs_penalty_kill = -1500;
var int autocvar_fcs_maxmoney = 16000;
var int autocvar_fcs_fillweapons = FALSE; /* This will automatically get ammo for the weapon you buy */
var int autocvar_fcs_fix_bombtimer = TRUE; /* If true, the bomb-timer will dictate the round-end */
var int autocvar_fcs_bombaltthrow = TRUE; /* Randomize the bomb-throw every time ever so slightly */
enum
{
GAME_INACTIVE,
GAME_COMMENCING,
GAME_FREEZE,
GAME_ACTIVE,
GAME_END,
GAME_OVER
};

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED func_bomb_target (0 .5 .8) ?
"targetname" Name
"target" Target when bomb blows up.
"killtarget" Target to kill when triggered.
COUNTER-STRIKE (1999) ENTITY
Bomb target zone.
Used in the bomb defusal mode (de_* maps).
Once the bomb explodes inside this volume, it'll trigger its targets.
*/
class func_bomb_target:CBaseTrigger
{
void(void) func_bomb_target;
virtual void(void) Respawn;
virtual void(void) touch;
};
void
func_bomb_target::touch(void)
{
player pl = (player)other;
if (!(other.flags & FL_CLIENT)) {
return;
}
if (pl.team != TEAM_T) {
return;
}
pl.gflags |= GF_BOMBZONE;
}
void
func_bomb_target::Respawn(void)
{
InitBrushTrigger();
}
void
func_bomb_target::func_bomb_target(void)
{
g_cs_bombzones++;
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED func_buyzone (0 .5 .8) ?
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
"team" Limits the buyzone to be used by set team.
COUNTER-STRIKE (1999) ENTITY
Buy zone.
The buyzone is a brush volume that upon creation forces players of set team
to buy weapons in its designated area.
If this entity is not present, the game will automatically spawn buyzones
around each player spawn, unless prevented using a setting inside the
info_map_parameters entity.
Info about automatically generated buyzones:
If no func_buyzone exists, the game will create one buyzone volume with a total
width of 256 units (radius thus being 128 units) on every player spawn point.
Choices for 'team' include:
0 = All teams
1 = Terrorist
2 = Counter-Terrorist
*/
class func_buyzone:CBaseTrigger
{
void(void) func_buyzone;
virtual void(void) touch;
virtual void(void) Respawn;
};
void
func_buyzone::touch(void)
{
player pl = (player)other;
if (!(other.flags & FL_CLIENT))
return;
if (team == 0 || team == pl.team)
pl.gflags |= GF_BUYZONE;
}
void
func_buyzone::Respawn(void)
{
InitBrushTrigger();
}
void
func_buyzone::func_buyzone(void)
{
CBaseTrigger::CBaseTrigger();
InitBrushTrigger();
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED func_escapezone (0 .5 .8) ?
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
COUNTER-STRIKE (1999) ENTITY
Terrorist escape zone.
Used in the Escape mode (es_* maps).
*/
class func_escapezone:CBaseTrigger
{
virtual void(void) Respawn;
};
void
func_escapezone::Respawn(void)
{
InitBrushTrigger();
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED func_hostage_rescue (0 .5 .8) ?
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
COUNTER-STRIKE (1999) ENTITY
Hostage rescue zone.
Used in the Hostage Rescue mode (cs_* maps).
If neither a func_hostage_rescue or a info_hostage_rescue is placed,
zones will be placed in Counter-Terrorist player spawn nodes automatically.
*/
class func_hostage_rescue:CBaseTrigger
{
void(void) func_hostage_rescue;
virtual void(void) touch;
virtual void(void) Respawn;
};
void
func_hostage_rescue::touch(void)
{
if (other.flags & FL_CLIENT) {
player pl = (player)other;
pl.gflags |= GF_RESCUEZONE;
return;
}
if (other.classname != "hostage_entity") {
return;
}
CBaseNPC hosty = (CBaseNPC)other;
if (hosty.solid == SOLID_NOT) {
return;
}
if (!((player)hosty.m_eFollowing))
return;
Radio_BroadcastMessage(RADIO_RESCUED);
g_cs_hostagesrescued++;
Money_AddMoney((player)hosty.m_eFollowing, 1000);
/* In Hostage Rescue, all Counter-Terrorists receive an $850
* bonus for every hostage that was rescued, even if they lose the round. */
Money_QueTeamReward(TEAM_CT, 850);
CBaseEntity targa = (CBaseEntity)other;
targa.Hide();
}
void
func_hostage_rescue::Respawn(void)
{
InitBrushTrigger();
}
void
func_hostage_rescue::func_hostage_rescue(void)
{
CBaseTrigger::CBaseTrigger();
InitBrushTrigger();
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED func_vip_safetyzone (0 .5 .8) ?
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
COUNTER-STRIKE (1999) ENTITY
VIP safety zone.
Used in the assassination mode (as_* maps).
*/
class func_vip_safetyzone:CBaseTrigger
{
virtual void(void) Respawn;
};
void
func_vip_safetyzone::Respawn(void)
{
InitBrushTrigger();
}

156
src/server/game_money.qc Normal file
View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
Money_AddMoney(base_player pp, int iMoneyValue)
{
player pl = (player)pp;
dprint(sprintf("^2Money_AddMoney^7: giving %s $%i\n", pl.netname, iMoneyValue));
pl.money += (float)iMoneyValue;
if (pl.money > autocvar_fcs_maxmoney) {
pl.money = autocvar_fcs_maxmoney;
}
/* Because people do tend to kill hostages... */
if (pl.money < 0) {
pl.money = 0;
}
}
void
Money_QueTeamReward(int t, int iMoneyValue)
{
if (t == TEAM_T) {
g_cs_moneyreward_t += iMoneyValue;
} else {
g_cs_moneyreward_ct += iMoneyValue;
}
}
void
Money_GiveTeamReward(base_player pl)
{
if (pl.team == TEAM_T) {
Money_AddMoney(pl, g_cs_moneyreward_t);
} else {
Money_AddMoney(pl, g_cs_moneyreward_ct);
}
}
void
Money_ResetTeamReward(void)
{
g_cs_moneyreward_t = 0;
g_cs_moneyreward_ct = 0;
}
int
Money_GetLosses(int team)
{
if (team == TEAM_T) {
return g_cs_roundslost_t;
} else {
return g_cs_roundslost_ct;
}
}
int
Money_HasBonus(int team)
{
if (team == TEAM_T) {
return g_cs_bonus_t;
} else {
return g_cs_bonus_ct;
}
}
void
Money_HandleRoundReward(int winner)
{
int loser = -1;
if (winner == TEAM_CT) {
g_cs_winstreak_ct++;
g_cs_winstreak_t = 0;
g_cs_roundslost_t++;
g_cs_roundslost_ct = 0;
loser = TEAM_T;
if (g_cs_winstreak_ct >= 2) {
g_cs_bonus_ct = TRUE;
}
} else {
g_cs_winstreak_t++;
g_cs_winstreak_ct = 0;
g_cs_roundslost_ct++;
g_cs_roundslost_t = 0;
loser = TEAM_CT;
if (g_cs_winstreak_t >= 2) {
g_cs_bonus_t = TRUE;
}
}
/* After the condition of a team winning two consecutive rounds is
* satisfied then the loss bonus money changes to above where their
* first loss means they receive $1500 and not $1400. */
if (Money_HasBonus(loser)) {
switch (Money_GetLosses(loser)) {
case 1:
Money_QueTeamReward(loser, 1500);
break;
case 2:
Money_QueTeamReward(loser, 2000);
break;
case 3:
Money_QueTeamReward(loser, 2500);
break;
default:
Money_QueTeamReward(loser, 3000);
break;
}
} else {
switch (Money_GetLosses(loser)) {
case 1:
Money_QueTeamReward(loser, 1400);
break;
case 2:
Money_QueTeamReward(loser, 1900);
break;
case 3:
Money_QueTeamReward(loser, 2400);
break;
case 4:
Money_QueTeamReward(loser, 2900);
break;
default:
Money_QueTeamReward(loser, 3400);
break;
}
}
}
void
Money_ResetRoundReward(void)
{
g_cs_roundslost_ct =
g_cs_roundslost_t =
g_cs_winstreak_ct =
g_cs_winstreak_t =
g_cs_bonus_ct =
g_cs_bonus_t = 0;
}

44
src/server/game_rules.qc Executable file
View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Edit this for a custom gun-game order */
int gg_order[] = {
WEAPON_KNIFE,
WEAPON_GLOCK18,
WEAPON_USP45,
WEAPON_P228,
WEAPON_FIVESEVEN,
WEAPON_ELITES,
WEAPON_DEAGLE,
WEAPON_M3,
WEAPON_XM1014,
WEAPON_TMP,
WEAPON_MAC10,
WEAPON_MP5,
WEAPON_UMP45,
WEAPON_P90,
WEAPON_AK47,
WEAPON_SCOUT,
WEAPON_M4A1,
WEAPON_SG552,
WEAPON_AUG,
WEAPON_G3SG1,
WEAPON_SG550,
WEAPON_AWP,
WEAPON_PARA
};

81
src/server/gamerules.h Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
class CSGameRules:CGameRules
{
virtual void(base_player) PlayerConnect;
virtual void(base_player) PlayerDisconnect;
virtual void(base_player) PlayerKill;
virtual void(base_player) PlayerPostFrame;
virtual void(base_player) PlayerDeath;
virtual void(base_player) PlayerPain;
/* level transitions */
virtual void(base_player) LevelChangeParms;
virtual void(base_player) LevelDecodeParms;
virtual void(void) LevelNewParms;
virtual int(base_player) BuyingPossible;
};
class CSSingleplayerRules:CSGameRules
{
/* client */
virtual void(base_player) PlayerSpawn;
virtual void(base_player) PlayerDeath;
};
class CSMultiplayerRules:CSGameRules
{
entity m_eLastTSpawn;
entity m_eLastCTSpawn;
void() CSMultiplayerRules;
virtual void(void) InitPostEnts;
virtual void(void) FrameStart;
virtual void(base_player) PlayerDisconnect;
virtual void(base_player) PlayerSpawn;
virtual void(base_player) PlayerPreFrame;
virtual void(base_player) PlayerDeath;
virtual int(int) MaxItemPerSlot;
virtual float(base_player, string) ConsoleCommand;
/* CS specific */
virtual void(void) CreateRescueZones;
virtual void(void) CreateCTBuyzones;
virtual void(void) CreateTBuyzones;
virtual void(float, int) TimerBegin;
virtual void(void) TimerUpdate;
virtual int(base_player) BuyingPossible;
virtual void(int, int, int) RoundOver;
virtual void(int) RestartRound;
virtual void(base_player) DeathCheck;
virtual void(base_player) MakeBomber;
virtual void(base_player) MakeVIP;
virtual void(void) CountPlayers;
virtual void(void) SwitchTeams;
virtual void(void) TimeOut;
virtual void(base_player) PlayerClearWeaponry;
virtual void(base_player, int) PlayerMakePlayable;
virtual void(base_player) PlayerMakeSpectator;
virtual void(base_player, int) PlayerRespawn;
virtual entity(float) PlayerFindSpawn;
};
void CSEv_JoinAuto(void);

197
src/server/gamerules.qc Normal file
View File

@ -0,0 +1,197 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
var int autocvar_sv_playerkeepalive = TRUE;
void
CSGameRules::PlayerDeath(base_player pl)
{
}
void
CSGameRules::PlayerPain(base_player pl)
{
}
int
CSGameRules::BuyingPossible(base_player pl)
{
return FALSE;
}
/* we check what fields have changed over the course of the frame and network
* only the ones that have actually changed */
void
CSGameRules::PlayerPostFrame(base_player pp)
{
Animation_PlayerUpdate();
}
void
CSGameRules::LevelDecodeParms(base_player pp)
{
player pl = (player)pp;
g_landmarkpos[0] = parm1;
g_landmarkpos[1] = parm2;
g_landmarkpos[2] = parm3;
pl.angles[0] = parm4;
pl.angles[1] = parm5;
pl.angles[2] = parm6;
pl.velocity[0] = parm7;
pl.velocity[1] = parm8;
pl.velocity[2] = parm9;
pl.g_items = parm10;
pl.activeweapon = parm11;
pl.flags = parm64;
pl.ammo_50ae = parm12;
pl.ammo_762mm = parm13;
pl.ammo_556mm = parm14;
pl.ammo_556mmbox = parm15;
pl.ammo_338mag = parm16;
pl.ammo_9mm = parm17;
pl.ammo_buckshot = parm18;
pl.ammo_45acp = parm19;
pl.ammo_357sig = parm20;
pl.ammo_57mm = parm21;
pl.ammo_hegrenade = parm22;
pl.ammo_fbgrenade = parm23;
pl.ammo_smokegrenade = parm24;
pl.usp45_mag = parm25;
pl.glock18_mag = parm26;
pl.deagle_mag = parm27;
pl.p228_mag = parm28;
pl.elites_mag = parm29;
pl.fiveseven_mag = parm30;
pl.m3_mag = parm31;
pl.xm1014_mag = parm32;
pl.mp5_mag = parm33;
pl.p90_mag = parm34;
pl.ump45_mag = parm35;
pl.mac10_mag = parm36;
pl.tmp_mag = parm37;
pl.ak47_mag = parm38;
pl.sg552_mag = parm39;
pl.m4a1_mag = parm40;
pl.aug_mag = parm41;
pl.scout_mag = parm42;
pl.awp_mag = parm43;
pl.g3sg1_mag = parm44;
pl.sg550_mag = parm45;
pl.para_mag = parm46;
pl.gflags = parm63;
if (pl.flags & FL_CROUCHING) {
setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX);
} else {
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
}
}
void
CSGameRules::LevelChangeParms(base_player pp)
{
player pl = (player)pp;
parm1 = g_landmarkpos[0];
parm2 = g_landmarkpos[1];
parm3 = g_landmarkpos[2];
parm4 = pl.angles[0];
parm5 = pl.angles[1];
parm6 = pl.angles[2];
parm7 = pl.velocity[0];
parm8 = pl.velocity[1];
parm9 = pl.velocity[2];
parm63 = pl.gflags;
parm64 = pl.flags;
parm10 = pl.g_items;
parm11 = pl.activeweapon;
parm12 = pl.ammo_50ae;
parm13 = pl.ammo_762mm;
parm14 = pl.ammo_556mm;
parm15 = pl.ammo_556mmbox;
parm16 = pl.ammo_338mag;
parm17 = pl.ammo_9mm;
parm18 = pl.ammo_buckshot;
parm19 = pl.ammo_45acp;
parm20 = pl.ammo_357sig;
parm21 = pl.ammo_57mm;
parm22 = pl.ammo_hegrenade;
parm23 = pl.ammo_fbgrenade;
parm24 = pl.ammo_smokegrenade;
parm25 = pl.usp45_mag;
parm26 = pl.glock18_mag;
parm27 = pl.deagle_mag;
parm28 = pl.p228_mag;
parm29 = pl.elites_mag;
parm30 = pl.fiveseven_mag;
parm31 = pl.m3_mag;
parm32 = pl.xm1014_mag;
parm33 = pl.mp5_mag;
parm34 = pl.p90_mag;
parm35 = pl.ump45_mag;
parm36 = pl.mac10_mag;
parm37 = pl.tmp_mag;
parm38 = pl.ak47_mag;
parm39 = pl.sg552_mag;
parm40 = pl.m4a1_mag;
parm41 = pl.aug_mag;
parm42 = pl.scout_mag;
parm43 = pl.awp_mag;
parm44 = pl.g3sg1_mag;
parm45 = pl.sg550_mag;
parm46 = pl.para_mag;
}
void
CSGameRules::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 = parm31 = parm32 = parm33 = parm34 = parm35 =
parm36 = parm37 = parm38 = parm39 = parm40 = parm41 = parm42 =
parm43 = parm44 = parm45 = parm46 = parm63= 0;
parm64 = FL_CLIENT;
}
void
CSGameRules::PlayerConnect(base_player pl)
{
if (Plugin_PlayerConnect(pl) == FALSE)
bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname));
}
void
CSGameRules::PlayerDisconnect(base_player pl)
{
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 = PLAYER_MODELINDEX;
}
void
CSGameRules::PlayerKill(base_player pl)
{
Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
CSSingleplayerRules::PlayerDeath(base_player pl)
{
pl.movetype = MOVETYPE_NONE;
pl.solid = SOLID_NOT;
pl.takedamage = DAMAGE_NO;
pl.gflags &= ~GF_FLASHLIGHT;
pl.armor = pl.activeweapon = pl.g_items = 0;
if (pl.health < -50) {
pl.health = 0;
FX_GibHuman(pl.origin);
return;
}
pl.health = 0;
}
void
CSSingleplayerRules::PlayerSpawn(base_player pl)
{
pl.classname = "player";
pl.health = pl.max_health = 100;
pl.takedamage = DAMAGE_YES;
pl.solid = SOLID_SLIDEBOX;
pl.movetype = MOVETYPE_WALK;
pl.flags = FL_CLIENT;
pl.viewzoom = 1.0;
pl.model = "models/player.mdl";
setmodel(pl, pl.model);
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
pl.view_ofs = VEC_PLAYER_VIEWPOS;
pl.velocity = [0,0,0];
pl.gravity = __NULL__;
pl.frame = 1;
pl.SendFlags = UPDATE_ALL;
pl.customphysics = Empty;
pl.iBleeds = TRUE;
forceinfokey(pl, "*spec", "0");
forceinfokey(pl, "*deaths", ftos(pl.deaths));
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);
}

View File

@ -0,0 +1,229 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED hostage_entity (0 1 0) (-16 -16 0) (16 16 72)
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
"model" "models/hostage.mdl"
"skin" "0"
COUNTER-STRIKE (1999) ENTITY
Hostage NPC.
Used in the Hostage Rescue mode (cs_* maps).
*/
enum
{
HOSA_WALK,
HOSA_WALKSCARED,
HOSA_RUN,
HOSA_RUNSCARED,
HOSA_RUNLOOK,
HOSA_180LEFT,
HOSA_180RIGHT,
HOSA_FLINCH,
HOSA_PAIN,
HOSA_PAINLEFT,
HOSA_PAINRIGHT,
HOSA_PAINLEGLEFT,
HOSA_PAINLEGRIGHT,
HOSA_IDLE1,
HOSA_IDLE2,
HOSA_IDLE3,
HOSA_IDLE4,
HOSA_IDLE5,
HOSA_IDLE6,
HOSA_SCARED_END,
HOSA_SCARED1,
HOSA_SCARED2,
HOSA_SCARED3,
HOSA_SCARED4,
HOSA_PANIC,
HOSA_FEAR1,
HOSA_FEAR2,
HOSA_CRY,
HOSA_SCI1,
HOSA_SCI2,
HOSA_SCI3,
HOSA_DIE_SIMPLE,
HOSA_DIE_FORWARD1,
HOSA_DIE_FORWARD2,
HOSA_DIE_BACKWARD,
HOSA_DIE_HEADSHOT,
HOSA_DIE_GUTSHOT,
HOSA_LYING1,
HOSA_LYING2,
HOSA_DEADSIT,
HOSA_DEADTABLE1,
HOSA_DEADTABLE2,
HOSA_DEADTABLE3
};
class hostage_entity:CBaseNPC
{
int m_iUsedOnce;
void(void) hostage_entity;
virtual void(void) Respawn;
virtual void(void) OnPlayerUse;
virtual void(void) Pain;
virtual void(void) Death;
virtual int(void) AnimIdle;
virtual int(void) AnimWalk;
virtual int(void) AnimRun;
};
int
hostage_entity::AnimIdle(void)
{
return HOSA_IDLE1;
}
int
hostage_entity::AnimWalk(void)
{
return HOSA_WALK;
}
int
hostage_entity::AnimRun(void)
{
return HOSA_RUN;
}
void
hostage_entity::OnPlayerUse(void)
{
if (eActivator.team == TEAM_T) {
return;
}
if (m_eFollowing == world)
Sound_Speak(this, "hostage_entity.follow");
/* CT reward, first time only */
if (m_iUsedOnce == FALSE) {
Money_AddMoney((player)eActivator, 150);
m_iUsedOnce = TRUE;
}
CBaseNPC::OnPlayerUse();
}
void
hostage_entity::Pain(void)
{
switch (g_dmg_iHitBody) {
case BODY_HEAD:
case BODY_DEFAULT:
case BODY_CHEST:
case BODY_STOMACH:
AnimPlay(HOSA_PAIN);
break;
case BODY_ARMLEFT:
AnimPlay(HOSA_PAINLEFT);
break;
case BODY_ARMRIGHT:
AnimPlay(HOSA_PAINRIGHT);
break;
case BODY_LEGLEFT:
AnimPlay(HOSA_PAINLEGLEFT);
break;
case BODY_LEGRIGHT:
AnimPlay(HOSA_PAINLEGRIGHT);
break;
}
/* penalties */
if (g_dmg_eAttacker.classname != "player")
return;
Money_AddMoney((base_player)g_dmg_eAttacker, -(g_dmg_iDamage * 25));
}
void
hostage_entity::Death(void)
{
WarnAllies();
if (style != MONSTER_DEAD) {
SetFrame(HOSA_DIE_SIMPLE + floor(random(0, 6)));
}
/* now mark our state as 'dead' */
CBaseNPC::Death();
/* penalties */
if (g_dmg_eAttacker.classname != "player")
return;
if (g_dmg_iDamage >= 100)
Money_AddMoney((base_player)g_dmg_eAttacker, -2500);
else
Money_AddMoney((base_player)g_dmg_eAttacker, -500);
Radio_BroadcastMessage(RADIO_HOSDOWN);
}
void
hostage_entity::Respawn(void)
{
CBaseNPC::Respawn();
m_iFlags |= MONSTER_CANFOLLOW;
m_iUsedOnce = FALSE;
PlayerUse = OnPlayerUse;
}
void
hostage_entity::hostage_entity(void)
{
Sound_Precache("hostage_entity.follow");
m_talkAnswer = "";
m_talkAsk = "";
m_talkAllyShot = "";
m_talkGreet = "";
m_talkIdle = "";
m_talkHearing = "";
m_talkSmelling = "";
m_talkStare = "";
m_talkSurvived = "";
m_talkWounded = "";
m_talkPlayerAsk = "";
m_talkPlayerGreet = "";
m_talkPlayerIdle = "";
m_talkPlayerWounded1 = "";
m_talkPlayerWounded2 = "";
m_talkPlayerWounded3 = "";
m_talkUnfollow = "";
m_talkFollow = "";
m_talkStopFollow = "";
spawnflags |= MSF_MULTIPLAYER;
model = "models/hostage.mdl";
netname = "Hostage";
base_health = 100;
base_mins = [-16,-16,0];
base_maxs = [16,16,72];
CBaseNPC::CBaseNPC();
g_cs_hostagestotal++;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED info_buyzone (0 0 0.8) (-16 -16 0) (16 16 16)
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
COUNTER-STRIKE (1999) ENTITY
Buy zone.
See func_buyzone for more information.
*/
class info_buyzone
{
void(void) info_buyzone;
virtual void(void) touch;
};
void
info_buyzone::touch(void)
{
player pl = (player)other;
if (!(other.flags & FL_CLIENT))
return;
if (team == 0 || team == pl.team)
pl.gflags |= GF_BUYZONE;
}
void
info_buyzone::info_buyzone(void)
{
solid = SOLID_TRIGGER;
setsize(this, [-128,-128,-128], [128,128,128]);
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED info_hostage_rescue (0 0 0.8) (-16 -16 0) (16 16 16)
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
COUNTER-STRIKE (1999) ENTITY
Hostage rescue point.
Used in the Hostage Rescue mode (cs_* maps).
Creates a volume around itself with a radius of 128 units.
If neither a info_hostage_rescue or a func_hostage_rescue is placed,
zones will be placed in Counter-Terrorist player spawn nodes automatically.
*/
class info_hostage_rescue
{
void(void) info_hostage_rescue;
virtual void(void) touch;
};
void
info_hostage_rescue::touch(void)
{
if (other.flags & FL_CLIENT) {
player pl = (player)other;
pl.gflags |= GF_RESCUEZONE;
return;
}
if (other.classname != "hostage_entity") {
return;
}
CBaseNPC hosty = (CBaseNPC)other;
if (hosty.solid == SOLID_NOT) {
return;
}
/* some custom maps are very smart... */
if (!((player)hosty.m_eFollowing))
return;
Radio_BroadcastMessage(RADIO_RESCUED);
g_cs_hostagesrescued++;
Money_AddMoney((player)hosty.m_eFollowing, 1000);
/* In Hostage Rescue, all Counter-Terrorists receive an $850
* bonus for every hostage they rescue, even if they lose the round. */
Money_QueTeamReward(TEAM_CT, 850);
CBaseEntity targa = (CBaseEntity)other;
targa.Hide();
}
void
info_hostage_rescue::info_hostage_rescue(void)
{
solid = SOLID_TRIGGER;
setsize(this, [-128,-128,-128], [128,128,128]);
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED info_map_parameters (0 0 0.8) (-16 -16 0) (16 16 16)
"targetname" Name
"target" Target when triggered.
"killtarget" Target to kill when triggered.
"buying" Override for buy-behaviour.
"bombradius" Overrides the default bomb radius.
COUNTER-STRIKE (1999) ENTITY
Miscellaneous mapping parameters.
Choices for 'buying':
0 = Both teams can buy items
1 = Only Counter-Terrorists can buy items
2 = Only Terrorists can buy items
3 = Neither Counter-Terrorists nor Terrorists can buy items
*/
enum
{
BUY_BOTH,
BUY_CT,
BUY_T,
BUY_NEITHER
};
class info_map_parameters
{
void(void) info_map_parameters;
};
void
info_map_parameters::info_map_parameters(void)
{
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
switch (argv(i)) {
case "buying":
g_cstrike_buying = stoi(argv(i+1));
break;
case "bombradius":
g_cstrike_bombradius = stof(argv(i+1));
break;
default:
break;
}
}
}

93
src/server/input.qc Normal file
View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
Game_Input(void)
{
CGameRules rules = (CGameRules)g_grMode;
if (rules.m_iIntermission) {
rules.IntermissionEnd();
return;
}
if (input_buttons & INPUT_BUTTON0) {
Weapons_Primary();
} else if (input_buttons & INPUT_BUTTON4) {
Weapons_Reload();
} else if (input_buttons & INPUT_BUTTON3) {
Weapons_Secondary();
} else {
Weapons_Release();
}
if (input_buttons & INPUT_BUTTON5) {
Player_UseDown();
} else {
Player_UseUp();
}
if (self.impulse == 100) {
Flashlight_Toggle();
}
if (cvar("sv_cheats") == 1) {
player pl = (player)self;
if (self.impulse == 101) {
pl.health = 100;
pl.armor = 100;
Weapons_AddItem(pl, WEAPON_M3, -1);
Weapons_AddItem(pl, WEAPON_XM1014, -1);
Weapons_AddItem(pl, WEAPON_MP5, -1);
Weapons_AddItem(pl, WEAPON_P90, -1);
Weapons_AddItem(pl, WEAPON_UMP45, -1);
Weapons_AddItem(pl, WEAPON_MAC10, -1);
Weapons_AddItem(pl, WEAPON_TMP, -1);
Weapons_AddItem(pl, WEAPON_AK47, -1);
Weapons_AddItem(pl, WEAPON_SG552, -1);
Weapons_AddItem(pl, WEAPON_M4A1, -1);
Weapons_AddItem(pl, WEAPON_AUG, -1);
Weapons_AddItem(pl, WEAPON_SCOUT, -1);
Weapons_AddItem(pl, WEAPON_AWP, -1);
Weapons_AddItem(pl, WEAPON_G3SG1, -1);
Weapons_AddItem(pl, WEAPON_SG550, -1);
Weapons_AddItem(pl, WEAPON_PARA, -1);
Weapons_AddItem(pl, WEAPON_C4BOMB, -1);
Weapons_AddItem(pl, WEAPON_FLASHBANG, -1);
Weapons_AddItem(pl, WEAPON_HEGRENADE, -1);
Weapons_AddItem(pl, WEAPON_SMOKEGRENADE, -1);
Weapons_AddItem(pl, WEAPON_USP45, -1);
Weapons_AddItem(pl, WEAPON_GLOCK18, -1);
Weapons_AddItem(pl, WEAPON_DEAGLE, -1);
Weapons_AddItem(pl, WEAPON_P228, -1);
Weapons_AddItem(pl, WEAPON_ELITES, -1);
Weapons_AddItem(pl, WEAPON_FIVESEVEN, -1);
Weapons_AddItem(pl, WEAPON_KNIFE, -1);
}
if (self.impulse == 102) {
// Respawn all the entities
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
CBaseEntity caw = (CBaseEntity)a;
caw.Respawn();
}
bprint(PRINT_HIGH, "Respawning all map entities...\n");
}
}
self.impulse = 0;
}

69
src/server/item_suit.qc Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
class item_suit:CBaseTrigger
{
void(void) item_suit;
virtual void(void) touch;
virtual void(void) Respawn;
};
void item_suit::touch(void)
{
player pl = (player)other;
if (pl.classname != "player") {
return;
}
if (pl.g_items & ITEM_SUIT) {
return;
}
sound(other, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_NORM);
pl.g_items |= ITEM_SUIT;
UseTargets(other, TRIG_TOGGLE, m_flDelay);
if (cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
think = Respawn;
nextthink = time + 30.0f;
}
}
void item_suit::Respawn(void)
{
SetSolid(SOLID_TRIGGER);
SetMovetype(MOVETYPE_TOSS);
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
SetOrigin(m_oldOrigin);
SetModel(m_oldModel);
think = __NULL__;
nextthink = -1;
}
void item_suit::item_suit(void)
{
model = "models/w_kevlar.mdl";
precache_sound("items/tr_kevlar.wav");
CBaseTrigger::CBaseTrigger();
Respawn();
}

27
src/server/money.h Normal file
View File

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

93
src/server/player.qc Normal file
View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
====================
UseWorkaround
====================
*/
void UseWorkaround(entity eTarget)
{
eActivator = self;
entity eOldSelf = self;
self = eTarget;
self.PlayerUse();
self = eOldSelf;
}
/*
====================
Player_UseDown
====================
*/
void Player_UseDown(void)
{
if (self.health <= 0) {
return;
} else if (!(self.flags & FL_USE_RELEASED)) {
return;
}
vector vSource;
makevectors(self.v_angle);
vSource = self.origin + self.view_ofs;
traceline (vSource, vSource + (v_forward * 64), MOVE_EVERYTHING, self);
if (trace_ent.PlayerUse) {
self.flags &= ~FL_USE_RELEASED;
UseWorkaround(trace_ent);
/* Some entities want to support Use spamming */
if (!(self.flags & FL_USE_RELEASED)) {
sound(self, CHAN_ITEM, "common/wpn_select.wav", 0.25, ATTN_IDLE);
}
} else {
sound(self, CHAN_ITEM, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE);
self.flags &= ~FL_USE_RELEASED;
}
}
/*
====================
Player_UseUp
====================
*/
void Player_UseUp(void) {
if (!(self.flags & FL_USE_RELEASED)) {
self.flags |= FL_USE_RELEASED;
}
}
void Weapons_Draw(void);
void CSEv_PlayerSwitchWeapon_i(int w)
{
player pl = (player)self;
pl.activeweapon = w;
Weapons_Draw();
}
void
Player_Precache(void)
{
searchhandle pm;
pm = search_begin("models/player/*/*.mdl", TRUE, TRUE);
for (int i = 0; i < search_getsize(pm); i++) {
precache_model(search_getfilename(pm, i));
}
search_end(pm);
}

61
src/server/progs.src Executable file
View File

@ -0,0 +1,61 @@
#pragma target fte
#pragma progs_dat "../../progs.dat"
#define QWSSQC
#define SERVER
#define VALVE
#define CSTRIKE
#define BULLETPENETRATION
#define BULLETPATTERNS
#define GS_RENDERFX
#includelist
../../../src/shared/fteextensions.qc
../../../src/gs-entbase/server/defs.h
../../../src/shared/defs.h
../../../src/server/defs.h
../../../src/gs-entbase/server.src
../../../src/gs-entbase/shared.src
defs.h
../shared/include.src
player.qc
../../../valve/src/server/spectator.qc
hostage_entity.qc
armoury_entity.qc
func_bomb_target.qc
func_buyzone.qc
info_buyzone.qc
func_escapezone.qc
func_hostage_rescue.qc
info_hostage_rescue.qc
func_vip_safetyzone.qc
info_map_parameters.qc
item_suit.qc
../../../valve/src/server/items.qc
../../../src/botlib/include.src
game_money.qc
gamerules.qc
gamerules_singleplayer.qc
gamerules_multiplayer.qc
radio.qc
client.qc
ammo.qc
buy.qc
server.qc
../../../valve/src/server/damage.qc
../../../valve/src/server/rules.qc
../../../valve/src/server/flashlight.qc
../../../base/src/server/modelevent.qc
input.qc
spawn.qc
../../../src/server/include.src
../../../src/shared/include.src
#endlist

4
src/server/radio.h Normal file
View File

@ -0,0 +1,4 @@
void Radio_BroadcastMessage(float fMessage)
void Radio_TeamMessage(float fMessage, float fTeam)
float Radio_DefaultStart(void)
void Radio_StartMessage(void)

131
src/server/radio.qc Normal file
View File

@ -0,0 +1,131 @@
/*
=================
Radio_BroadcastMessage
A global radio message for all players
=================
*/
void
Radio_BroadcastMessage(float fMessage)
{
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_RADIOMSG);
WriteByte(MSG_MULTICAST, fMessage);
msg_entity = self;
multicast([0,0,0], MULTICAST_ALL);
}
/*
=================
Radio_TeamMessage
A radio message targetted at members of a specific team
=================
*/
void
Radio_TeamMessage(float fMessage, float fTeam)
{
static void Radio_TeamMessage_Send(float fMessage, entity eEnt) {
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_RADIOMSG);
WriteByte(MSG_MULTICAST, fMessage);
msg_entity = eEnt;
multicast([0,0,0], MULTICAST_ONE);
}
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
if (eFind.team == fTeam) {
Radio_TeamMessage_Send(fMessage, eFind);
} else if (eFind.team == TEAM_VIP && fTeam == TEAM_CT) {
Radio_TeamMessage_Send(fMessage, eFind);
}
}
}
/*
=================
Radio_DefaultStart
Pick a generic, random radio string for global start messages
=================
*/
float
Radio_DefaultStart(void)
{
float fRand = floor(random(1, 4));
if (fRand == 1) {
return RADIO_MOVEOUT;
} else if (fRand == 2) {
return RADIO_LOCKNLOAD;
} else {
return RADIO_LETSGO;
}
}
/*
=================
Radio_StartMessage
Decide which startmessage to play at the beginning of each round
=================
*/
void
Radio_StartMessage(void)
{
if (g_cs_vipzones > 0) {
Radio_TeamMessage(RADIO_VIP, TEAM_CT);
Radio_TeamMessage(Radio_DefaultStart(), TEAM_T);
} else if (g_cs_escapezones > 0) {
Radio_TeamMessage(RADIO_GETOUT, TEAM_T);
Radio_TeamMessage(Radio_DefaultStart(), TEAM_CT);
} else {
Radio_BroadcastMessage(Radio_DefaultStart());
}
}
/*
=================
CSEv_Radio_f
Triggered by clients, plays a message to members of the same team
=================
*/
void
CSEv_Radio_f(float fMessage)
{
static void CSEv_Radio_Send(float fMessage, entity eEnt) {
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_RADIOMSG2);
WriteByte(MSG_MULTICAST, num_for_edict(eEnt) - 1);
WriteByte(MSG_MULTICAST, fMessage);
msg_entity = eEnt;
multicast([0,0,0], MULTICAST_ONE);
}
// Don't allow spamming
/*if (self.fRadioFinished > time) {
return;
}*/
// When dead, don't talk
if (self.health <= 0) {
return;
}
// Make sure that VIPs and CTs get eachother
float fTargetTeam = self.team;
if (fTargetTeam == TEAM_VIP) {
fTargetTeam = TEAM_CT;
}
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
if (eFind.team == fTargetTeam) {
CSEv_Radio_Send(fMessage, eFind);
} else if (eFind.team == TEAM_VIP && fTargetTeam == TEAM_CT) {
CSEv_Radio_Send(fMessage, eFind);
}
}
/*self.fRadioFinished = time + 3.0f;*/
}

58
src/server/server.qc Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
Game_InitRules(void)
{
if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) {
g_grMode = spawn(CSSingleplayerRules);
} else {
g_grMode = spawn(CSMultiplayerRules);
}
}
void Game_Worldspawn(void)
{
precache_model("models/player/arctic/arctic.mdl");
precache_model("models/player/gign/gign.mdl");
precache_model("models/player/gsg9/gsg9.mdl");
precache_model("models/player/guerilla/guerilla.mdl");
precache_model("models/player/leet/leet.mdl");
precache_model("models/player/sas/sas.mdl");
precache_model("models/player/terror/terror.mdl");
precache_model("models/player/urban/urban.mdl");
precache_model("models/player/vip/vip.mdl");
precache_sound("weapons/ric_metal-2.wav");
precache_sound("player/pl_pain2.wav");
precache_sound("player/pl_pain4.wav");
Sound_Precache("buy.kevlar");
Sound_Precache("buy.weapon");
Sound_Precache("buy.ammo");
/* some Counter-Strike maps do not have weapon pickups, so we want to
* precache these regardless in case of someone dropping a weapon,
* which happens quite often (buying weapons, etc.) */
Sound_Precache("item.respawn");
Sound_Precache("weapon.pickup");
Weapons_Init();
clientstat(STAT_MONEY, EV_INTEGER, player::money);
clientstat(STAT_PROGRESS, EV_FLOAT, player::progress);
pointerstat(STAT_GAMETIME, EV_FLOAT, &g_cs_gametime);
pointerstat(STAT_GAMESTATE, EV_INTEGER, &g_cs_gamestate);
}

69
src/server/spawn.qc Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016-2019 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
info_player_start
Counter-Terrorist Spawnpoints
=================
*/
void info_player_start(void)
{
if (autocvar_fcs_swapteams == TRUE) {
self.classname = "info_player_deathmatch";
}
self.botinfo = BOTINFO_SPAWNPOINT;
}
/*
=================
info_player_deathmatch
Terrorist Spawnpoints
=================
*/
void info_player_deathmatch(void)
{
if (autocvar_fcs_swapteams == TRUE) {
self.classname = "info_player_start";
}
self.botinfo = BOTINFO_SPAWNPOINT;
}
/* Counter-Strike: Source compat */
void info_player_counterterrorist(void)
{
setorigin(self, self.origin + [0,0,32]);
self.classname = "info_player_start";
info_player_start();
}
void info_player_terrorist(void)
{
setorigin(self, self.origin + [0,0,32]);
self.classname = "info_player_deathmatch";
info_player_deathmatch();
}
/*
=================
info_vip_start
=================
*/
void info_vip_start(void)
{
}

117
src/shared/animations.h Normal file
View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
enum
{
ANIM_DUMMY1,
ANIM_IDLE,
ANIM_IDLE_CROUCH,
ANIM_WALK,
ANIM_RUN,
ANIM_RUN_CROUCH,
ANIM_JUMP,
ANIM_LONGJUMP,
ANIM_SWIM,
ANIM_TREADWATER,
ANIM_CROUCH_AIM_CARBINE,
ANIM_CROUCH_SHOOT_CARBINE,
ANIM_CROUCH_RELOAD_CARBINE,
ANIM_AIM_CARBINE,
ANIM_SHOOT_CARBINE,
ANIM_RELOAD_CARBINE,
ANIM_CROUCH_AIM_ONEHAND,
ANIM_CROUCH_SHOOT_ONEHAND,
ANIM_CROUCH_RELOAD_ONEHAND,
ANIM_AIM_ONEHAND,
ANIM_SHOOT_ONEHAND,
ANIM_RELOAD_ONEHAND,
ANIM_CROUCH_AIM_DUALPISTOLS,
ANIM_CROUCH_SHOOT_DUALPISTOLS,
ANIM_CROUCH_SHOOT2_DUALPISTOLS,
ANIM_CROUCH_RELOAD_DUALPISTOLS,
ANIM_AIM_DUALPISTOLS,
ANIM_SHOOT_DUALPISTOLS,
ANIM_SHOOT2_DUALPISTOLS,
ANIM_RELOAD_DUALPISTOLS,
ANIM_CROUCH_AIM_RIFLE,
ANIM_CROUCH_SHOOT_RIFLE,
ANIM_CROUCH_RELOAD_RIFLE,
ANIM_AIM_RIFLE,
ANIM_SHOOT_RIFLE,
ANIM_RELOAD_RIFLE,
ANIM_CROUCH_AIM_MP5,
ANIM_CROUCH_SHOOT_MP5,
ANIM_CROUCH_RELOAD_MP5,
ANIM_AIM_MP5,
ANIM_SHOOT_MP5,
ANIM_RELOAD_MP5,
ANIM_CROUCH_AIM_SHOTGUN,
ANIM_CROUCH_SHOOT_SHOTGUN,
ANIM_CROUCH_RELOAD_SHOTGUN,
ANIM_AIM_SHOTGUN,
ANIM_SHOOT_SHOTGUN,
ANIM_RELOAD_SHOTGUN,
ANIM_CROUCH_AIM_PARA,
ANIM_CROUCH_SHOOT_PARA,
ANIM_CROUCH_RELOAD_PARA,
ANIM_AIM_PARA,
ANIM_SHOOT_PARA,
ANIM_RELOAD_PARA,
ANIM_DUMMY2,
ANIM_DUMMY3,
ANIM_AIM_GRENADE,
ANIM_SHOOT_GRENADE,
ANIM_CROUCH_AIM_GRENADE,
ANIM_CROUCH_SHOOT_GRENADE,
ANIM_CROUCH_AIM_C4,
ANIM_CROUCH_SHOOT_C4,
ANIM_AIM_C4,
ANIM_SHOOT_C4,
ANIM_RELOAD_C4,
ANIM_DUPLICATE1,
ANIM_DUPLICATE2,
ANIM_DUPLICATE3,
ANIM_DUPLICATE4,
ANIM_DUPLICATE5,
ANIM_DUPLICATE6,
ANIM_DUPLICATE7,
ANIM_DUPLICATE8,
ANIM_CROUCH_AIM_KNIFE,
ANIM_CROUCH_SHOOT_KNIFE,
ANIM_AIM_KNIFE,
ANIM_SHOOT_KNIFE,
ANIM_CROUCH_AIM_AK47,
ANIM_CROUCH_SHOOT_AK47,
ANIM_CROUCH_RELOAD_AK47,
ANIM_AIM_AK47,
ANIM_SHOOT_AK47,
ANIM_RELOAD_AK47,
ANIM_GUT_FLINCH,
ANIM_HEAD_FLINCH,
ANIM_DEATH1,
ANIM_DEATH2,
ANIM_DEATH3,
ANIM_DIE_HEAD,
ANIM_DIE_GUT,
ANIM_DIE_LEFT,
ANIM_DIE_BACK,
ANIM_DIE_RIGHT,
ANIM_DIE_FORWARD,
ANIM_CROUCH_DIE
};
void Animation_PlayerTop(float);
void Animation_PlayerTopTemp(float, float);

158
src/shared/animations.qc Executable file
View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.float baseframe1time;
.float baseframe2time;
.float baseframe2;
.float baseframe_last;
.float baseframe_old;
.float baseframe_time;
.float baselerpfrac;
.float frame2;
.float frame2time;
.float frame_last;
.float fWasCrouching;
.float lerpfrac;
.float subblend2frac;
.float subblendfrac;
void Animation_Print(string sWow) {
#ifdef CLIENT
print(sprintf("[DEBUG] %s", sWow));
#else
bprint(PRINT_HIGH, sprintf("SSQC: %s", sWow) );
#endif
}
/*
=================
Animation_PlayerUpdate
Called every frame to update the animation sequences
depending on what the player is doing
=================
*/
void Animation_PlayerUpdate(void) {
self.basebone = cvar("spinebone"); // gettagindex(self, "Bip01 Spine");
if (self.baseframe_time < time) {
base_player pl = (base_player)self;
self.baseframe = Weapons_GetAim(pl.activeweapon);
self.baseframe_old = self.frame;
}
/* in order to appear jumping, we want to not be on ground,
* but also make sure we're not just going down a ramp */
if (!(self.flags & FL_ONGROUND) && (self.velocity[2] > 0 || self.frame == ANIM_JUMP)) {
self.frame = ANIM_JUMP;
} else if (vlen(self.velocity) == 0) {
if (self.flags & FL_CROUCHING) {
self.frame = ANIM_IDLE_CROUCH;
} else {
self.frame = ANIM_IDLE;
}
} else if (vlen(self.velocity) < 150) {
if (self.flags & FL_CROUCHING) {
self.frame = ANIM_RUN_CROUCH;
} else {
self.frame = ANIM_WALK;
}
} else if (vlen(self.velocity) > 150) {
if (self.flags & FL_CROUCHING) {
self.frame = ANIM_RUN_CROUCH;
} else {
self.frame = ANIM_RUN;
}
}
// Lerp it down!
if (self.lerpfrac > 0) {
self.lerpfrac -= frametime * 5;
if (self.lerpfrac < 0) {
self.lerpfrac = 0;
}
}
if (self.baselerpfrac > 0) {
self.baselerpfrac -= frametime * 5;
if (self.baselerpfrac < 0) {
self.baselerpfrac = 0;
}
}
if (self.frame != self.frame_last) {
//Animation_Print(sprintf("New Frame: %d, Last Frame: %d\n", self.frame, self.frame_last));
// Move everything over to frame 2
self.frame2time = self.frame1time;
self.frame2 = self.frame_last;
// Set frame_last to avoid this being called again
self.frame_last = self.frame;
self.lerpfrac = 1.0f;
self.frame1time = 0.0f;
}
if (self.baseframe != self.baseframe_last) {
//Animation_Print(sprintf("New Baseframe: %d, Last Baseframe: %d\n", self.baseframe, self.baseframe_last));
// Move everything over to frame 2
self.baseframe2time = self.baseframe1time;
self.baseframe2 = self.baseframe_last;
// Set frame_last to avoid this being called again
self.baseframe_last = self.baseframe;
self.baselerpfrac = 1.0f;
self.baseframe1time = 0.0f;
}
// Force the code above to update if we switched positions
if (self.fWasCrouching != (self.flags & FL_CROUCHING)) {
self.baseframe_old = 0;
self.baseframe_time = 0;
self.fWasCrouching = (self.flags & FL_CROUCHING);
}
#ifdef SERVER
// On the CSQC it's done in Player.c
self.subblendfrac =
self.subblend2frac = self.v_angle[0] / 90;
#endif
self.angles[0] = self.angles[2] = 0;
}
/*
=================
Animation_PlayerTop
Changes the animation sequence for the upper body part
=================
*/
void Animation_PlayerTop(float fFrame) {
self.baseframe = fFrame;
self.baseframe_old = fFrame;
}
void Animation_PlayerTopTemp(float fFrame, float fTime) {
self.baseframe = fFrame;
self.baseframe_time = time + fTime;
#ifdef SERVER
self.SendFlags |= PLAYER_FRAME;
#endif
}

34
src/shared/defs.h Normal file
View File

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

20
src/shared/entities.h Normal file
View File

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

114
src/shared/equipment.qc Executable file
View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef SERVER
void CSEv_PlayerBuyEquipment_f(float fID) {
/* if (Rules_BuyingPossible() == FALSE) {
return;
}
if ((self.fMoney - eqptTable[fID].iPrice) >= 0) {
if (eqptTable[fID].iID == EQUIPMENT_DEFUSALKIT) {
if (self.team == TEAM_T) { return; }
if (!(self.iEquipment & EQUIPMENT_DEFUSALKIT)) {
self.iEquipment |= EQUIPMENT_DEFUSALKIT;
Money_AddMoney(self, -200);
sound(self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE);
} else {
centerprint(self, "You already have a defusal kit!");
}
} else if (eqptTable[fID].iID == EQUIPMENT_NIGHTVISION) {
if (!(self.iEquipment & EQUIPMENT_NIGHTVISION)) {
self.iEquipment |= EQUIPMENT_NIGHTVISION;
Money_AddMoney(self, -1250);
sound(self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE);
} else {
centerprint(self, "You already have nightvision goggles!");
}
} else if (eqptTable[fID].iID == WEAPON_HEGRENADE) {
if (self.iAmmo_HEGRENADE < 2) {
self.iAmmo_HEGRENADE++;
Money_AddMoney(self, -300);
sound(self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE);
} else {
centerprint(self, "You can't carry any more!");
}
} else if (eqptTable[fID].iID == WEAPON_FLASHBANG) {
if (self.iAmmo_FLASHBANG < 2) {
self.iAmmo_FLASHBANG++;
Money_AddMoney(self, -300);
sound(self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE);
} else {
centerprint(self, "You can't carry any more!");
}
} else if (eqptTable[fID].iID == WEAPON_SMOKEGRENADE) {
if (self.iAmmo_SMOKEGRENADE < 2) {
self.iAmmo_SMOKEGRENADE++;
Money_AddMoney(self, -300);
sound(self, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE);
} else {
centerprint(self, "You can't carry any more!");
}
} else if (eqptTable[fID].iID == EQUIPMENT_KEVLAR) {
if (self.armor == 100) {
// You already own kevlar etc.
centerprint(self, "You already have kevlar!");
} else {
self.armor = 100;
Money_AddMoney(self, -650);
}
sound(self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE);
self.fAttackFinished = time + 1.0;
return;
} else if (eqptTable[fID].iID == EQUIPMENT_HELMET) {
if (self.armor == 100) {
if (self.iEquipment & EQUIPMENT_HELMET) {
// You already have full kevlar and a helmet
centerprint(self, "You already have kevlar and a helmet!");
} else {
// You have full kevlar, but no helmet
Money_AddMoney(self, -350);
sound(self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE);
centerprint(self, "You already have some kevlar,\nand now you've bought a helmet!");
self.iEquipment = self.iEquipment | EQUIPMENT_HELMET;
}
} else {
if (self.iEquipment & EQUIPMENT_HELMET) {
// Only get kevlar
self.armor = 100;
Money_AddMoney(self, -650);
sound(self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE);
centerprint(self, "You already have a helmet,\nand now you've bought some kevlar!");
} else {
// Get both
self.armor = 100;
self.iEquipment = self.iEquipment | EQUIPMENT_HELMET;
Money_AddMoney(self, -1000);
sound(self, CHAN_ITEM, "items/tr_kevlar.wav", 1, ATTN_IDLE);
}
}
self.fAttackFinished = time + 1.0;
return;
}
} else {
centerprint(self, "You have insufficient funds!");
}
self.fAttackFinished = time + 1.0;*/
}
#endif

23
src/shared/events.h Normal file
View File

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

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

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* game flags */
#define GF_SEMI_TOGGLED (1<<0)
#define GF_FLASHLIGHT (1<<1)
#define GF_BUYZONE (1<<2)
#define GF_RESCUEZONE (1<<3)
#define GF_BOMBZONE (1<<4)
#define GF_UNUSED6 (1<<5)
#define GF_UNUSED7 (1<<6)
#define GF_UNUSED8 (1<<7)
#define GF_UNUSED9 (1<<8)
#define GF_UNUSED10 (1<<9)
#define GF_UNUSED11 (1<<10)
#define GF_UNUSED12 (1<<11)
#define GF_UNUSED13 (1<<12)
#define GF_UNUSED14 (1<<14)
#define GF_UNUSED15 (1<<16)
#define GF_UNUSED16 (1<<13)
#define GF_UNUSED17 (1<<17)
#define GF_UNUSED18 (1<<18)
#define GF_UNUSED19 (1<<19)
#define GF_UNUSED20 (1<<20)
#define GF_UNUSED21 (1<<21)
#define GF_UNUSED22 (1<<22)
#define GF_UNUSED23 (1<<23)

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef SERVER
void
FX_Flashbang(vector org)
{
for (entity e = world; (e = find(e, ::classname, "player"));) {
float fov_dot;
vector val;
float blindness;
float fade;
/* wall check */
traceline(e.origin + e.view_ofs, org, FALSE, e);
if (trace_fraction < 1.0f)
continue;
/* calculate the fov in dotproduct form */
makevectors(e.v_angle);
val = normalize(org - (e.origin + e.view_ofs));
fov_dot = val * v_forward;
/* it's behind us */
if (fov_dot < 0) {
blindness = 0.1;
fade = 1.0f;
} else {
blindness = 2 * fov_dot;
fade = 4 * fov_dot;
}
/* send the blinding env_fade event */
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_FADE);
WriteFloat(MSG_MULTICAST, 1.0f);
WriteFloat(MSG_MULTICAST, 1.0f);
WriteFloat(MSG_MULTICAST, 1.0f);
WriteFloat(MSG_MULTICAST, 1.0f);
WriteFloat(MSG_MULTICAST, blindness);
WriteFloat(MSG_MULTICAST, fade);
WriteByte(MSG_MULTICAST, EVF_FADEDROM);
msg_entity = e;
multicast([0,0,0], MULTICAST_ONE_R);
}
}
#endif

116
src/shared/fx_impact.qc Normal file
View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
var int FX_IMPACT_BLACKBITS;
var int FX_IMPACT_SMOKE_BROWN;
var int FX_IMPACT_SMOKE_GREY;
var int FX_IMPACT_SPARK;
void
FX_Impact_Init(void)
{
precache_sound("weapons/ric_metal-1.wav");
precache_sound("weapons/ric_metal-2.wav");
precache_sound("weapons/ric_conc-1.wav");
precache_sound("weapons/ric_conc-2.wav");
precache_sound("weapons/knife_hitwall1.wav");
precache_sound("weapons/ric1.wav");
precache_sound("weapons/ric2.wav");
precache_sound("weapons/ric3.wav");
precache_sound("weapons/ric4.wav");
precache_sound("weapons/ric5.wav");
FX_IMPACT_BLACKBITS = particleeffectnum("fx_impact.blackbits");
FX_IMPACT_SMOKE_GREY = particleeffectnum("fx_impact.smoke_grey");
FX_IMPACT_SMOKE_BROWN = particleeffectnum("fx_impact.smoke_brown");
FX_IMPACT_SPARK = particleeffectnum("fx_impact.spark");
}
#endif
void
FX_Impact(int iType, vector vecPos, vector vNormal)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_IMPACT);
WriteByte(MSG_MULTICAST, (float)iType);
WriteCoord(MSG_MULTICAST, vecPos[0]);
WriteCoord(MSG_MULTICAST, vecPos[1]);
WriteCoord(MSG_MULTICAST, vecPos[2]);
WriteCoord(MSG_MULTICAST, vNormal[0]);
WriteCoord(MSG_MULTICAST, vNormal[1]);
WriteCoord(MSG_MULTICAST, vNormal[2]);
msg_entity = self;
multicast(vecPos, MULTICAST_PVS);
#else
/* decals */
switch (iType) {
case IMPACT_GLASS:
Decals_Place(vecPos, sprintf("{break%d", floor(random(1,4))));
break;
case IMPACT_MELEE:
Decals_Place(vecPos, sprintf("{shot%d", floor(random(1,6))));
break;
default:
Decals_Place(vecPos, sprintf("{bigshot%d", floor(random(1,6))));
break;
}
switch (iType) {
case IMPACT_MELEE:
pointsound(vecPos, "weapons/knife_hitwall1.wav", 1, ATTN_STATIC);
break;
case IMPACT_EXPLOSION:
break;
case IMPACT_GLASS:
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
break;
case IMPACT_WOOD:
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_SMOKE_BROWN, vecPos, vNormal, 1);
break;
case IMPACT_METAL:
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
break;
case IMPACT_FLESH:
FX_Blood(vecPos, vNormal);
break;
case IMPACT_DEFAULT:
default:
pointparticles(FX_IMPACT_SPARK, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_BLACKBITS, vecPos, vNormal, 1);
pointparticles(FX_IMPACT_SMOKE_GREY, vecPos, vNormal, 1);
break;
}
switch (iType) {
case IMPACT_METAL:
pointsound(vecPos, sprintf("weapons/ric_metal-%d.wav", floor((random() * 2) + 1)), 1, ATTN_STATIC);
break;
case IMPACT_CONCRETE:
pointsound(vecPos, sprintf("weapons/ric_conc-%d.wav", floor((random() * 2) + 1)), 1, ATTN_STATIC);
break;
case IMPACT_FLESH:
break;
default:
pointsound(vecPos, sprintf("weapons/ric%d.wav", floor((random() * 5) + 1)), 1, ATTN_STATIC);
break;
}
#endif
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
var int PARTICLE_SMOKEGRENADE;
void
FX_Smokenade_Init(void)
{
PARTICLE_SMOKEGRENADE = particleeffectnum("fx_smokenade.effect");
}
#endif
void
FX_Smokenade(vector vecPos)
{
#ifdef SERVER
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_SMOKE);
WriteCoord(MSG_MULTICAST, vecPos[0]);
WriteCoord(MSG_MULTICAST, vecPos[1]);
WriteCoord(MSG_MULTICAST, vecPos[2]);
msg_entity = self;
multicast([0,0,0], MULTICAST_ALL);
#else
static void Effect_CreateSmoke_Think(void) {
// HACK: This should only ever happen when rounds restart!
// Any way this can go wrong?
if (self.skin < getstatf(STAT_GAMETIME)) {
remove(self);
}
if (self.frame <= 0) {
remove(self);
return;
}
pointparticles(PARTICLE_SMOKEGRENADE, self.origin, [0,0,0], 1);
self.frame--;
self.nextthink = time + 0.2f;
self.skin = getstatf(STAT_GAMETIME);
}
entity eSmoke = spawn();
setorigin(eSmoke, vecPos);
eSmoke.think = Effect_CreateSmoke_Think;
eSmoke.nextthink = time;
eSmoke.frame = 200;
eSmoke.skin = getstatf(STAT_GAMETIME);
#endif
}

53
src/shared/include.src Normal file
View File

@ -0,0 +1,53 @@
#includelist
defs.h
flags.h
player.h
../../../valve/src/shared/weapon_common.h
animations.h
animations.qc
item_c4bomb.h
../../../valve/src/shared/fx_blood.qc
../../../valve/src/shared/fx_breakmodel.qc
../../../valve/src/shared/fx_explosion.qc
../../../valve/src/shared/fx_gibhuman.qc
../../../valve/src/shared/fx_spark.qc
fx_impact.qc
fx_flashbang.qc
fx_smokenade.qc
weapons_cstrike.qc
w_ak47.qc
w_deagle.qc
w_knife.qc
w_usp45.qc
w_glock18.qc
w_p228.qc
w_elites.qc
w_fiveseven.qc
w_m3.qc
w_xm1014.qc
w_mp5.qc
w_p90.qc
w_ump45.qc
w_mac10.qc
w_tmp.qc
w_sg552.qc
w_m4a1.qc
w_aug.qc
w_scout.qc
w_awp.qc
w_g3sg1.qc
w_sg550.qc
w_para.qc
w_c4bomb.qc
w_flashbang.qc
w_hegrenade.qc
w_smokegrenade.qc
weapons.qc
../../../valve/src/shared/weapon_common.qc
pmove.qc
../../../valve/src/shared/pmove_water.qc
item_c4bomb.qc
#endlist

8
src/shared/item_c4bomb.h Normal file
View File

@ -0,0 +1,8 @@
#ifdef SERVER
void C4Bomb_Plant(base_player);
#endif
#ifdef CLIENT
string g_c4bombled_spr;
void w_c4bomb_parse(void);
#endif

286
src/shared/item_c4bomb.qc Normal file
View File

@ -0,0 +1,286 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
class item_c4:CBaseEntity
{
#ifdef SERVER
entity m_eUser;
float m_flBeepTime;
float m_flExplodeTime;
float m_flDefusalState;
#endif
#ifdef CLIENT
float m_flAlpha;
#endif
#ifdef SERVER
void(void) item_c4;
virtual float(entity, float) SendEntity;
virtual void(void) ClearProgress;
virtual void(void) OnPlayerUse;
virtual void(void) Logic;
#endif
#ifdef CLIENT
void(void) item_c4;
virtual void(void) DrawLED;
virtual float(void) predraw;
#endif
};
#ifdef SERVER
float
item_c4::SendEntity(entity pvsent, float flags)
{
WriteByte(MSG_ENTITY, ENT_C4BOMB);
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[1]);
WriteCoord(MSG_ENTITY, origin[2]);
WriteCoord(MSG_ENTITY, angles[0]);
WriteCoord(MSG_ENTITY, angles[1]);
WriteCoord(MSG_ENTITY, angles[2]);
WriteShort(MSG_ENTITY, modelindex);
return TRUE;
}
void
item_c4::ClearProgress(void)
{
if (m_eUser != world) {
player pl = (player)m_eUser;
pl.progress = 0.0f;
pl.flags &= ~FL_FROZEN;
}
}
void
item_c4::OnPlayerUse(void)
{
player pl = (player)eActivator;
/* obvious check */
if (pl.team != TEAM_CT) {
return;
}
/* don't allow anyone else to hijack. */
if (m_eUser == world) {
m_eUser = eActivator;
sound(this, CHAN_ITEM, "weapons/c4_disarm.wav", 1.0, ATTN_NONE);
}
}
void
item_c4::Logic(void)
{
CSMultiplayerRules rules = (CSMultiplayerRules)g_grMode;
/* check if we're being used */
if (m_eUser != world) {
player pl = (player)m_eUser;
/* we need to check if the user has changed every frame. */
if (!m_eUser.button5) {
ClearProgress();
/* clear user */
m_eUser = world;
m_flDefusalState = 0.0f;
} else {
/* defusal kit always cuts the time in half */
if (pl.g_items & ITEM_DEFUSAL)
m_flDefusalState += (frametime * 2);
else
m_flDefusalState += frametime;
/* tracked stat */
pl.progress = m_flDefusalState;
pl.flags |= FL_FROZEN;
}
}
if (m_flDefusalState > 10.0f) {
ClearProgress();
sound(this, CHAN_VOICE, "weapons/c4_disarmed.wav", 1.0, ATTN_NORM);
rules.RoundOver(TEAM_CT, 3600, TRUE);
Radio_BroadcastMessage(RADIO_BOMBDEF);
m_flBeepTime = 0.0f;
m_flDefusalState = 0;
remove(this);
return;
}
/* if our time has passed, explode */
if (m_flExplodeTime < time) {
ClearProgress();
/* In Bomb Defusal, all Terrorists receive $3500
* if they won by detonating the bomb. */
rules.RoundOver(TEAM_T, 3500, FALSE);
Damage_Radius(origin, this.owner, 500, g_cstrike_bombradius, FALSE, WEAPON_C4BOMB);
Sound_Play(this, CHAN_VOICE, "weapon_c4bomb.explode");
for (entity e = world; (e = find(e, ::classname, "func_bomb_target"));) {
CBaseTrigger trigger = (CBaseTrigger)e;
if (trigger.Trigger != __NULL__) {
trigger.Trigger(this, TRIG_TOGGLE);
}
}
m_flBeepTime = 0.0f;
m_flDefusalState = 0;
remove(this);
return;
}
if (m_flBeepTime > time) {
return;
}
m_flBeepTime = time + 1.5;
if (m_flExplodeTime - time < 2) {
sound(this, CHAN_VOICE, "weapons/c4_beep5.wav", 1.0, ATTN_NONE);
} else if (m_flExplodeTime - time < 5) {
sound(this, CHAN_VOICE, "weapons/c4_beep5.wav", 1.0, ATTN_NORM);
} else if (m_flExplodeTime - time < 10) {
sound(this, CHAN_VOICE, "weapons/c4_beep4.wav", 1.0, ATTN_NORM);
} else if (m_flExplodeTime - time < 20) {
sound(this, CHAN_VOICE, "weapons/c4_beep3.wav", 1.0, ATTN_NORM);
} else if (m_flExplodeTime - time < 30) {
sound(this, CHAN_VOICE, "weapons/c4_beep2.wav", 1.0, ATTN_NORM);
} else {
sound(this, CHAN_VOICE, "weapons/c4_beep1.wav", 1.0, ATTN_NORM);
}
}
void
item_c4::item_c4(void)
{
/* throw this in with the other temporary round entities */
classname = "remove_me";
SetMovetype(MOVETYPE_NONE);
SetSolid(SOLID_BBOX);
SetModel("models/w_c4.mdl");
SetSize([-6,-6,0], [6,6,6]);
customphysics = Logic;
PlayerUse = OnPlayerUse;
m_flExplodeTime = time + 45.0f;
Sound_Play(this, CHAN_WEAPON, "weapon_c4bomb.plant");
}
void
C4Bomb_Plant(base_player planter)
{
item_c4 bomb = spawn(item_c4);
bomb.owner = planter;
/* place directly below */
traceline(planter.origin, planter.origin + [0,0,-64], FALSE, planter);
setorigin(bomb, trace_endpos);
bomb.SendFlags = -1;
Radio_BroadcastMessage(RADIO_BOMBPL);
g_cs_bombplanted = TRUE;
}
#endif
#ifdef CLIENT
void
item_c4::DrawLED(void)
{
vector vecPlayer;
int s = (float)getproperty(VF_ACTIVESEAT);
pSeat = &g_seats[s];
vecPlayer = pSeat->m_vecPredictedOrigin;
m_flAlpha -= frametime;
if (m_flAlpha <= 0.0f)
m_flAlpha = 1.0f;
if (m_flAlpha > 0) {
vector forg;
vector fsize;
float falpha;
/* Scale the glow somewhat with the players distance */
fsize = [16,16];
fsize *= bound(1, vlen(vecPlayer - origin) / 256, 4);
/* Fade out when the player is starting to move away */
falpha = 1 - bound(0, vlen(vecPlayer - origin) / 1024, 1);
falpha *= m_flAlpha;
/* Nudge this slightly towards the camera */
makevectors(vectoangles(origin - vecPlayer));
forg = (origin + [0,0,8]) + (v_forward * -16);
/* Project it, always facing the player */
makevectors(view_angles);
R_BeginPolygon(g_c4bombled_spr, 1, 0);
R_PolygonVertex(forg + v_right * fsize[0] - v_up * fsize[1],
[1,1], [1,1,1], falpha);
R_PolygonVertex(forg - v_right * fsize[0] - v_up * fsize[1],
[0,1], [1,1,1], falpha);
R_PolygonVertex(forg - v_right * fsize[0] + v_up * fsize[1],
[0,0], [1,1,1], falpha);
R_PolygonVertex(forg + v_right * fsize[0] + v_up * fsize[1],
[1,0], [1,1,1], falpha);
R_EndPolygon();
}
}
float
item_c4::predraw(void)
{
DrawLED();
addentity(this);
return PREDRAW_NEXT;
}
void
item_c4::item_c4(void)
{
solid = SOLID_BBOX;
movetype = MOVETYPE_NONE;
drawmask = MASK_ENGINE;
}
void
w_c4bomb_parse(void)
{
item_c4 tm = (item_c4)self;
spawnfunc_item_c4();
g_c4bombled_spr = spriteframe("sprites/ledglow.spr", 0, 0.0f);
tm.origin[0] = readcoord();
tm.origin[1] = readcoord();
tm.origin[2] = readcoord();
tm.angles[0] = readcoord();
tm.angles[1] = readcoord();
tm.angles[2] = readcoord();
tm.modelindex = readshort();
setorigin(tm, tm.origin);
setsize(tm, [-6,-6,0], [6,6,6]);
}
#endif

51
src/shared/items.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define ITEM_KNIFE 0x00000001i
#define ITEM_USP45 0x00000002i
#define ITEM_GLOCK18 0x00000004i
#define ITEM_DEAGLE 0x00000008i
#define ITEM_P228 0x00000010i
#define ITEM_ELITES 0x00000020i
#define ITEM_FIVESEVEN 0x00000040i
#define ITEM_M3 0x00000080i
#define ITEM_XM1014 0x00000100i
#define ITEM_MP5 0x00000200i
#define ITEM_P90 0x00000400i
#define ITEM_UMP45 0x00000800i
#define ITEM_MAC10 0x00001000i
#define ITEM_TMP 0x00002000i
#define ITEM_SUIT 0x00004000i
#define ITEM_LONGJUMP 0x00008000i
#define ITEM_AK47 0x00010000i
#define ITEM_SG552 0x00020000i
#define ITEM_M4A1 0x00040000i
#define ITEM_AUG 0x00080000i
#define ITEM_SCOUT 0x00100000i
#define ITEM_AWP 0x00200000i
#define ITEM_G3SG1 0x00400000i
#define ITEM_SG550 0x00800000i
#define ITEM_PARA 0x01000000i
#define ITEM_C4BOMB 0x02000000i
#define ITEM_FLASHBANG 0x04000000i
#define ITEM_HEGRENADE 0x08000000i
#define ITEM_SMOKEGRENADE 0x10000000i
#define ITEM_DEFUSAL 0x20000000i
#define ITEM_NIGHTVISION 0x40000000i
#define ITEM_HELMET 0x80000000i

837
src/shared/player.h Normal file
View File

@ -0,0 +1,837 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
enumflags
{
PLAYER_KEEPALIVE,
PLAYER_MODELINDEX,
PLAYER_ORIGIN,
PLAYER_ORIGIN_Z,
PLAYER_ANGLES_X,
PLAYER_ANGLES_Y,
PLAYER_ANGLES_Z,
PLAYER_VELOCITY,
PLAYER_VELOCITY_Z,
PLAYER_FLAGS,
PLAYER_WEAPON,
PLAYER_ITEMS,
PLAYER_HEALTH,
PLAYER_ARMOR,
PLAYER_MOVETYPE,
PLAYER_VIEWOFS,
PLAYER_BASEFRAME,
PLAYER_FRAME,
PLAYER_AMMO1,
PLAYER_AMMO2,
PLAYER_AMMO3,
PLAYER_CSSHOT,
PLAYER_CSSHOTTIME
};
enumflags
{
AMMO1_USP45,
AMMO1_GLOCK18,
AMMO1_DEAGLE,
AMMO1_P228,
AMMO1_ELITES,
AMMO1_FIVESEVEN,
AMMO1_M3,
AMMO1_XM1014,
AMMO1_MP5,
AMMO1_P90,
AMMO1_UMP45,
AMMO1_MAC10,
AMMO1_TMP,
AMMO1_AK47,
AMMO1_SG552,
AMMO1_M4A1,
AMMO1_AUG,
AMMO1_SCOUT,
AMMO1_AWP,
AMMO1_G3SG1,
AMMO1_SG550,
AMMO1_PARA,
};
enumflags
{
AMMO2_50AE,
AMMO2_762MM,
AMMO2_556MM,
AMMO2_556MMBOX,
AMMO2_338MAG,
AMMO2_9MM,
AMMO2_BUCKSHOT,
AMMO2_45ACP,
AMMO2_357SIG,
AMMO2_57MM,
AMMO2_HEGRENADE,
AMMO2_FBGRENADE,
AMMO2_SMOKEGRENADE,
};
enumflags
{
AMMO3_MODE_USP45,
AMMO3_MODE_M4A1,
AMMO3_MODE_GLOCK18,
};
noref int input_sequence;
class player:base_player
{
int ingame;
int ammo_50ae;
int ammo_50ae_net;
int ammo_762mm;
int ammo_762mm_net;
int ammo_556mm;
int ammo_556mm_net;
int ammo_556mmbox;
int ammo_556mmbox_net;
int ammo_338mag;
int ammo_338mag_net;
int ammo_9mm;
int ammo_9mm_net;
int ammo_buckshot;
int ammo_buckshot_net;
int ammo_45acp;
int ammo_45acp_net;
int ammo_357sig;
int ammo_357sig_net;
int ammo_57mm;
int ammo_57mm_net;
int ammo_hegrenade;
int ammo_hegrenade_net;
int ammo_fbgrenade;
int ammo_fbgrenade_net;
int ammo_smokegrenade;
int ammo_smokegrenade_net;
/* Weapon specific */
int usp45_mag;
int usp45_mag_net;
int glock18_mag;
int glock18_mag_net;
int deagle_mag;
int deagle_mag_net;
int p228_mag;
int p228_mag_net;
int elites_mag;
int elites_mag_net;
int fiveseven_mag;
int fiveseven_mag_net;
int m3_mag;
int m3_mag_net;
int xm1014_mag;
int xm1014_mag_net;
int mp5_mag;
int mp5_mag_net;
int p90_mag;
int p90_mag_net;
int ump45_mag;
int ump45_mag_net;
int mac10_mag;
int mac10_mag_net;
int tmp_mag;
int tmp_mag_net;
int ak47_mag;
int ak47_mag_net;
int sg552_mag;
int sg552_mag_net;
int m4a1_mag;
int m4a1_mag_net;
int aug_mag;
int aug_mag_net;
int scout_mag;
int scout_mag_net;
int awp_mag;
int awp_mag_net;
int g3sg1_mag;
int g3sg1_mag_net;
int sg550_mag;
int sg550_mag_net;
int para_mag;
int para_mag_net;
int mode_usp45;
int mode_usp45_net;
int mode_m4a1;
int mode_m4a1_net;
int mode_glock18;
int mode_glock18_net;
int mode_temp;
int mode_temp_net;
int cs_shotmultiplier;
int cs_shotmultiplier_net;
float cs_shottime;
float cs_shottime_net;
#ifdef CLIENT
/* External model */
entity p_model;
int playertype;
int p_hand_bone;
int p_model_bone;
float lastweapon;
int cs_cross_mindist;
int cs_cross_deltadist;
float cs_crosshairdistance;
virtual void(void) gun_offset;
virtual void(void) draw;
virtual float() predraw;
virtual void(void) postdraw;
virtual void(float) ReceiveEntity;
virtual void(void) PredictPreFrame;
virtual void(void) PredictPostFrame;
#else
virtual void(void) EvaluateEntity;
virtual float(entity, float) SendEntity;
int charmodel;
int money;
float progress;
#endif
};
#ifdef CLIENT
void Weapons_AmmoUpdate(entity);
/*
=================
player::ReceiveEntity
=================
*/
void
player::ReceiveEntity(float new)
{
float fl;
if (new == FALSE) {
/* Go through all the physics code between the last received frame
* and the newest frame and keep the changes this time around instead
* of rolling back, because we'll apply the new server-verified values
* right after anyway. */
/* FIXME: splitscreen */
if (entnum == player_localentnum) {
/* FIXME: splitscreen */
pSeat = &g_seats[0];
for (int i = sequence+1; i <= servercommandframe; i++) {
/* ...maybe the input state is too old? */
if (!getinputstate(i)) {
break;
}
input_sequence = i;
PMove_Run();
}
/* any differences in things that are read below are now
* officially from prediction misses. */
}
}
/* seed for our prediction table */
sequence = servercommandframe;
fl = readfloat();
/* HACK: we need to make this more reliable */
if (fl == UPDATE_ALL) {
/* we respawned */
gravity = __NULL__;
}
if (fl & PLAYER_MODELINDEX)
modelindex = readshort();
if (fl & PLAYER_ORIGIN) {
origin[0] = readcoord();
origin[1] = readcoord();
}
if (fl & PLAYER_ORIGIN_Z)
origin[2] = readcoord();
if (fl & PLAYER_ANGLES_X)
pitch = readfloat();
if (fl & PLAYER_ANGLES_Y)
angles[1] = readfloat();
if (fl & PLAYER_ANGLES_Z)
angles[2] = readfloat();
if (fl & PLAYER_VELOCITY) {
velocity[0] = readcoord();
velocity[1] = readcoord();
}
if (fl & PLAYER_VELOCITY_Z)
velocity[2] = readcoord();
if (fl & PLAYER_FLAGS) {
flags = readfloat();
gflags = readfloat();
}
if (fl & PLAYER_WEAPON)
activeweapon = readbyte();
if (fl & PLAYER_ITEMS)
g_items = (__variant)readfloat();
if (fl & PLAYER_HEALTH)
health = readbyte();
if (fl & PLAYER_ARMOR)
armor = readbyte();
if (fl & PLAYER_MOVETYPE)
movetype = readbyte();
if (fl & PLAYER_VIEWOFS)
view_ofs[2] = readfloat();
if (fl & PLAYER_BASEFRAME)
baseframe = readbyte();
if (fl & PLAYER_FRAME) {
frame = readbyte();
frame1time = 0.0f;
frame2time = 0.0f;
}
if (fl & PLAYER_AMMO1) {
usp45_mag = readbyte();
glock18_mag = readbyte();
deagle_mag = readbyte();
p228_mag = readbyte();
elites_mag = readbyte();
fiveseven_mag = readbyte();
m3_mag = readbyte();
xm1014_mag = readbyte();
mp5_mag = readbyte();
p90_mag = readbyte();
ump45_mag = readbyte();
mac10_mag = readbyte();
tmp_mag = readbyte();
ak47_mag = readbyte();
sg552_mag = readbyte();
m4a1_mag = readbyte();
aug_mag = readbyte();
scout_mag = readbyte();
awp_mag = readbyte();
g3sg1_mag = readbyte();
sg550_mag = readbyte();
para_mag = readbyte();
}
if (fl & PLAYER_AMMO2) {
ammo_50ae = readbyte();
ammo_762mm = readbyte();
ammo_556mm = readbyte();
ammo_556mmbox = readbyte();
ammo_338mag = readbyte();
ammo_9mm = readbyte();
ammo_buckshot = readbyte();
ammo_45acp = readbyte();
ammo_357sig = readbyte();
ammo_57mm = readbyte();
ammo_hegrenade = readbyte();
ammo_fbgrenade = readbyte();
ammo_smokegrenade = readbyte();
}
if (fl & PLAYER_AMMO3) {
mode_usp45 = readbyte();
mode_m4a1 = readbyte();
mode_glock18 = readbyte();
mode_temp = readbyte();
}
if (fl & PLAYER_CSSHOT) {
cs_shotmultiplier = readbyte();
}
if (fl & PLAYER_CSSHOTTIME) {
cs_shottime = readfloat();
}
if (fl & PLAYER_AMMO1 || fl & PLAYER_AMMO2 || fl & PLAYER_AMMO3)
Weapons_AmmoUpdate(this);
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)
{
usp45_mag_net = usp45_mag;
glock18_mag_net = glock18_mag;
deagle_mag_net = deagle_mag;
p228_mag_net = p228_mag;
elites_mag_net = elites_mag;
fiveseven_mag_net = fiveseven_mag;
m3_mag_net = m3_mag;
xm1014_mag_net = xm1014_mag;
mp5_mag_net = mp5_mag;
p90_mag_net = p90_mag;
ump45_mag_net = ump45_mag;
mac10_mag_net = mac10_mag;
tmp_mag_net = tmp_mag;
ak47_mag_net = ak47_mag;
sg552_mag_net = sg552_mag;
m4a1_mag_net = m4a1_mag;
aug_mag_net = aug_mag;
scout_mag_net = scout_mag;
awp_mag_net = awp_mag;
g3sg1_mag_net = g3sg1_mag;
sg550_mag_net = sg550_mag;
para_mag_net = para_mag;
ammo_50ae_net = ammo_50ae;
ammo_762mm_net = ammo_762mm;
ammo_556mm_net = ammo_556mm;
ammo_556mmbox_net = ammo_556mmbox;
ammo_338mag_net = ammo_338mag;
ammo_9mm_net = ammo_9mm;
ammo_buckshot_net = ammo_buckshot;
ammo_45acp_net = ammo_45acp;
ammo_357sig_net = ammo_357sig;
ammo_57mm_net = ammo_57mm;
ammo_hegrenade_net = ammo_hegrenade;
ammo_fbgrenade_net = ammo_fbgrenade;
ammo_smokegrenade_net = ammo_smokegrenade;
mode_usp45_net = mode_usp45;
mode_m4a1_net = mode_m4a1;
mode_glock18_net = mode_glock18;
mode_temp_net = mode_temp;
cs_shotmultiplier_net = cs_shotmultiplier;
cs_shottime_net = cs_shottime;
}
/*
=================
player::PredictPostFrame
Where we roll back our values to the ones last sent/verified by the server.
=================
*/
void
player::PredictPostFrame(void)
{
usp45_mag = usp45_mag_net;
glock18_mag = glock18_mag_net;
deagle_mag = deagle_mag_net;
p228_mag = p228_mag_net;
elites_mag = elites_mag_net;
fiveseven_mag = fiveseven_mag_net;
m3_mag = m3_mag_net;
xm1014_mag = xm1014_mag_net;
mp5_mag = mp5_mag_net;
p90_mag = p90_mag_net;
ump45_mag = ump45_mag_net;
mac10_mag = mac10_mag_net;
tmp_mag = tmp_mag_net;
ak47_mag = ak47_mag_net;
sg552_mag = sg552_mag_net;
m4a1_mag = m4a1_mag_net;
aug_mag = aug_mag_net;
scout_mag = scout_mag_net;
awp_mag = awp_mag_net;
g3sg1_mag = g3sg1_mag_net;
sg550_mag = sg550_mag_net;
para_mag = para_mag_net;
ammo_50ae = ammo_50ae_net;
ammo_762mm = ammo_762mm_net;
ammo_556mm = ammo_556mm_net;
ammo_556mmbox = ammo_556mmbox_net;
ammo_338mag = ammo_338mag_net;
ammo_9mm = ammo_9mm_net;
ammo_buckshot = ammo_buckshot_net;
ammo_45acp = ammo_45acp_net;
ammo_357sig = ammo_357sig_net;
ammo_57mm = ammo_57mm_net;
ammo_hegrenade = ammo_hegrenade_net;
ammo_fbgrenade = ammo_fbgrenade_net;
ammo_smokegrenade = ammo_smokegrenade_net;
mode_usp45 = mode_usp45_net;
mode_m4a1 = mode_m4a1_net;
mode_glock18 = mode_glock18_net;
mode_temp = mode_temp_net;
cs_shotmultiplier = cs_shotmultiplier_net;
cs_shottime = cs_shottime_net;
}
#else
void
player::EvaluateEntity(void)
{
SendFlags |= PLAYER_KEEPALIVE;
if (old_modelindex != modelindex)
SendFlags |= PLAYER_MODELINDEX;
if (old_origin[0] != origin[0])
SendFlags |= PLAYER_ORIGIN;
if (old_origin[1] != origin[1])
SendFlags |= PLAYER_ORIGIN;
if (old_origin[2] != origin[2])
SendFlags |= PLAYER_ORIGIN_Z;
if (old_angles[0] != v_angle[0])
SendFlags |= PLAYER_ANGLES_X;
if (old_angles[1] != angles[1])
SendFlags |= PLAYER_ANGLES_Y;
if (old_angles[2] != angles[2])
SendFlags |= PLAYER_ANGLES_Z;
if (old_velocity[0] != velocity[0])
SendFlags |= PLAYER_VELOCITY;
if (old_velocity[1] != velocity[1])
SendFlags |= PLAYER_VELOCITY;
if (old_velocity[2] != velocity[2])
SendFlags |= PLAYER_VELOCITY_Z;
if (old_flags != flags)
SendFlags |= PLAYER_FLAGS;
if (old_gflags != gflags)
SendFlags |= PLAYER_FLAGS;
if (old_activeweapon != activeweapon)
SendFlags |= PLAYER_WEAPON;
if (old_items != g_items)
SendFlags |= PLAYER_ITEMS;
if (old_health != health)
SendFlags |= PLAYER_HEALTH;
if (old_armor != armor)
SendFlags |= PLAYER_ARMOR;
if (old_movetype != movetype)
SendFlags |= PLAYER_MOVETYPE;
if (old_viewofs != view_ofs[2])
SendFlags |= PLAYER_VIEWOFS;
if (old_baseframe != baseframe)
SendFlags |= PLAYER_BASEFRAME;
if (old_frame != frame)
SendFlags |= PLAYER_FRAME;
/* ammo 1 type updates */
if (glock18_mag_net != glock18_mag)
SendFlags |= PLAYER_AMMO1;
if (usp45_mag_net != usp45_mag)
SendFlags |= PLAYER_AMMO1;
if (glock18_mag_net != glock18_mag)
SendFlags |= PLAYER_AMMO1;
if (deagle_mag_net != deagle_mag)
SendFlags |= PLAYER_AMMO1;
if (p228_mag_net != p228_mag)
SendFlags |= PLAYER_AMMO1;
if (elites_mag_net != elites_mag)
SendFlags |= PLAYER_AMMO1;
if (fiveseven_mag_net != fiveseven_mag)
SendFlags |= PLAYER_AMMO1;
if (m3_mag_net != m3_mag)
SendFlags |= PLAYER_AMMO1;
if (xm1014_mag_net != xm1014_mag)
SendFlags |= PLAYER_AMMO1;
if (mp5_mag_net != mp5_mag)
SendFlags |= PLAYER_AMMO1;
if (p90_mag_net != p90_mag)
SendFlags |= PLAYER_AMMO1;
if (ump45_mag_net != ump45_mag)
SendFlags |= PLAYER_AMMO1;
if (mac10_mag_net != mac10_mag)
SendFlags |= PLAYER_AMMO1;
if (tmp_mag_net != tmp_mag)
SendFlags |= PLAYER_AMMO1;
if (ak47_mag_net != ak47_mag)
SendFlags |= PLAYER_AMMO1;
if (sg552_mag_net != sg552_mag)
SendFlags |= PLAYER_AMMO1;
if (m4a1_mag_net != m4a1_mag)
SendFlags |= PLAYER_AMMO1;
if (aug_mag_net != aug_mag)
SendFlags |= PLAYER_AMMO1;
if (scout_mag_net != scout_mag)
SendFlags |= PLAYER_AMMO1;
if (awp_mag_net != awp_mag)
SendFlags |= PLAYER_AMMO1;
if (g3sg1_mag_net != g3sg1_mag)
SendFlags |= PLAYER_AMMO1;
if (sg550_mag_net != sg550_mag)
SendFlags |= PLAYER_AMMO1;
if (para_mag_net != para_mag)
SendFlags |= PLAYER_AMMO1;
if (ammo_50ae_net != ammo_50ae)
SendFlags |= PLAYER_AMMO2;
if (ammo_762mm_net != ammo_762mm)
SendFlags |= PLAYER_AMMO2;
if (ammo_556mm_net != ammo_556mm)
SendFlags |= PLAYER_AMMO2;
if (ammo_556mmbox_net != ammo_556mmbox)
SendFlags |= PLAYER_AMMO2;
if (ammo_338mag_net != ammo_338mag)
SendFlags |= PLAYER_AMMO2;
if (ammo_9mm_net != ammo_9mm)
SendFlags |= PLAYER_AMMO2;
if (ammo_buckshot_net != ammo_buckshot)
SendFlags |= PLAYER_AMMO2;
if (ammo_45acp_net != ammo_45acp)
SendFlags |= PLAYER_AMMO2;
if (ammo_357sig_net != ammo_357sig)
SendFlags |= PLAYER_AMMO2;
if (ammo_57mm_net != ammo_57mm)
SendFlags |= PLAYER_AMMO2;
if (ammo_hegrenade_net != ammo_hegrenade)
SendFlags |= PLAYER_AMMO2;
if (ammo_fbgrenade_net != ammo_fbgrenade)
SendFlags |= PLAYER_AMMO2;
if (ammo_smokegrenade_net != ammo_smokegrenade)
SendFlags |= PLAYER_AMMO2;
if (mode_usp45_net != mode_usp45)
SendFlags |= PLAYER_AMMO3;
if (mode_m4a1_net != mode_m4a1)
SendFlags |= PLAYER_AMMO3;
if (mode_glock18_net != mode_glock18)
SendFlags |= PLAYER_AMMO3;
if (mode_temp_net != mode_temp)
SendFlags |= PLAYER_AMMO3;
if (cs_shotmultiplier != cs_shotmultiplier_net)
SendFlags |= PLAYER_CSSHOT;
if (cs_shottime != cs_shottime_net)
SendFlags |= PLAYER_CSSHOTTIME;
old_modelindex = modelindex;
old_origin = origin;
old_angles = angles;
old_angles[0] = v_angle[0];
old_velocity = velocity;
old_flags = flags;
old_gflags = gflags;
old_activeweapon = activeweapon;
old_items = g_items;
old_health = health;
old_armor = armor;
old_movetype = movetype;
old_viewofs = view_ofs[2];
old_baseframe = baseframe;
old_frame = frame;
glock18_mag_net = glock18_mag;
usp45_mag_net = usp45_mag;
glock18_mag_net = glock18_mag;
deagle_mag_net = deagle_mag;
p228_mag_net = p228_mag;
elites_mag_net = elites_mag;
fiveseven_mag_net = fiveseven_mag;
m3_mag_net = m3_mag;
xm1014_mag_net = xm1014_mag;
mp5_mag_net = mp5_mag;
p90_mag_net = p90_mag;
ump45_mag_net = ump45_mag;
mac10_mag_net = mac10_mag;
tmp_mag_net = tmp_mag;
ak47_mag_net = ak47_mag;
sg552_mag_net = sg552_mag;
m4a1_mag_net = m4a1_mag;
aug_mag_net = aug_mag;
scout_mag_net = scout_mag;
awp_mag_net = awp_mag;
g3sg1_mag_net = g3sg1_mag;
sg550_mag_net = sg550_mag;
para_mag_net = para_mag;
ammo_50ae_net = ammo_50ae;
ammo_762mm_net = ammo_762mm;
ammo_556mm_net = ammo_556mm;
ammo_556mmbox_net = ammo_556mmbox;
ammo_338mag_net = ammo_338mag;
ammo_9mm_net = ammo_9mm;
ammo_buckshot_net = ammo_buckshot;
ammo_45acp_net = ammo_45acp;
ammo_357sig_net = ammo_357sig;
ammo_57mm_net = ammo_57mm;
ammo_hegrenade_net = ammo_hegrenade;
ammo_fbgrenade_net = ammo_fbgrenade;
ammo_smokegrenade_net = ammo_smokegrenade;
mode_usp45_net = mode_usp45;
mode_m4a1_net = mode_m4a1;
mode_glock18_net = mode_glock18;
mode_temp_net = mode_temp;
cs_shotmultiplier_net = cs_shotmultiplier;
cs_shottime_net = cs_shottime;
if (g_cs_gamestate != GAME_FREEZE) {
if (progress <= 0.0f) {
flags &= ~FL_FROZEN;
SendFlags |= PLAYER_FLAGS;
}
}
}
/*
=================
player::SendEntity
=================
*/
float
player::SendEntity(entity ePEnt, float fChanged)
{
if (health <= 0 && ePEnt != this) {
return FALSE;
}
if (clienttype(ePEnt) != CLIENTTYPE_REAL) {
return FALSE;
}
if (ePEnt != self) {
fChanged &= ~PLAYER_ITEMS;
fChanged &= ~PLAYER_HEALTH;
fChanged &= ~PLAYER_ARMOR;
fChanged &= ~PLAYER_VIEWOFS;
fChanged &= ~PLAYER_AMMO1;
fChanged &= ~PLAYER_AMMO2;
fChanged &= ~PLAYER_AMMO3;
}
WriteByte(MSG_ENTITY, ENT_PLAYER);
WriteFloat(MSG_ENTITY, fChanged);
/* really trying to get our moneys worth with 23 bits of mantissa */
if (fChanged & PLAYER_MODELINDEX)
WriteShort(MSG_ENTITY, modelindex);
if (fChanged & PLAYER_ORIGIN) {
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[1]);
}
if (fChanged & PLAYER_ORIGIN_Z)
WriteCoord(MSG_ENTITY, origin[2]);
if (fChanged & PLAYER_ANGLES_X)
WriteFloat(MSG_ENTITY, v_angle[0]);
if (fChanged & PLAYER_ANGLES_Y)
WriteFloat(MSG_ENTITY, angles[1]);
if (fChanged & PLAYER_ANGLES_Z)
WriteFloat(MSG_ENTITY, angles[2]);
if (fChanged & PLAYER_VELOCITY) {
WriteCoord(MSG_ENTITY, velocity[0]);
WriteCoord(MSG_ENTITY, velocity[1]);
}
if (fChanged & PLAYER_VELOCITY_Z)
WriteCoord(MSG_ENTITY, velocity[2]);
if (fChanged & PLAYER_FLAGS) {
WriteFloat(MSG_ENTITY, flags);
WriteFloat(MSG_ENTITY, gflags);
}
if (fChanged & PLAYER_WEAPON)
WriteByte(MSG_ENTITY, activeweapon);
if (fChanged & PLAYER_ITEMS)
WriteFloat(MSG_ENTITY, (__variant)g_items);
if (fChanged & PLAYER_HEALTH)
WriteByte(MSG_ENTITY, bound(0, health, 255));
if (fChanged & PLAYER_ARMOR)
WriteByte(MSG_ENTITY, armor);
if (fChanged & PLAYER_MOVETYPE)
WriteByte(MSG_ENTITY, movetype);
if (fChanged & PLAYER_VIEWOFS)
WriteFloat(MSG_ENTITY, view_ofs[2]);
if (fChanged & PLAYER_BASEFRAME)
WriteByte(MSG_ENTITY, baseframe);
if (fChanged & PLAYER_FRAME)
WriteByte(MSG_ENTITY, frame);
if (fChanged & PLAYER_AMMO1) {
WriteByte(MSG_ENTITY, usp45_mag);
WriteByte(MSG_ENTITY, glock18_mag);
WriteByte(MSG_ENTITY, deagle_mag);
WriteByte(MSG_ENTITY, p228_mag);
WriteByte(MSG_ENTITY, elites_mag);
WriteByte(MSG_ENTITY, fiveseven_mag);
WriteByte(MSG_ENTITY, m3_mag);
WriteByte(MSG_ENTITY, xm1014_mag);
WriteByte(MSG_ENTITY, mp5_mag);
WriteByte(MSG_ENTITY, p90_mag);
WriteByte(MSG_ENTITY, ump45_mag);
WriteByte(MSG_ENTITY, mac10_mag);
WriteByte(MSG_ENTITY, tmp_mag);
WriteByte(MSG_ENTITY, ak47_mag);
WriteByte(MSG_ENTITY, sg552_mag);
WriteByte(MSG_ENTITY, m4a1_mag);
WriteByte(MSG_ENTITY, aug_mag);
WriteByte(MSG_ENTITY, scout_mag);
WriteByte(MSG_ENTITY, awp_mag);
WriteByte(MSG_ENTITY, g3sg1_mag);
WriteByte(MSG_ENTITY, sg550_mag);
WriteByte(MSG_ENTITY, para_mag);
}
if (fChanged & PLAYER_AMMO2) {
WriteByte(MSG_ENTITY, ammo_50ae);
WriteByte(MSG_ENTITY, ammo_762mm);
WriteByte(MSG_ENTITY, ammo_556mm);
WriteByte(MSG_ENTITY, ammo_556mmbox);
WriteByte(MSG_ENTITY, ammo_338mag);
WriteByte(MSG_ENTITY, ammo_9mm);
WriteByte(MSG_ENTITY, ammo_buckshot);
WriteByte(MSG_ENTITY, ammo_45acp);
WriteByte(MSG_ENTITY, ammo_357sig);
WriteByte(MSG_ENTITY, ammo_57mm);
WriteByte(MSG_ENTITY, ammo_hegrenade);
WriteByte(MSG_ENTITY, ammo_fbgrenade);
WriteByte(MSG_ENTITY, ammo_smokegrenade);
}
if (fChanged & PLAYER_AMMO3) {
WriteByte(MSG_ENTITY, mode_usp45);
WriteByte(MSG_ENTITY, mode_m4a1);
WriteByte(MSG_ENTITY, mode_glock18);
WriteByte(MSG_ENTITY, mode_temp);
}
if (fChanged & PLAYER_CSSHOT) {
WriteByte(MSG_ENTITY, cs_shotmultiplier);
}
if (fChanged & PLAYER_CSSHOTTIME) {
WriteFloat(MSG_ENTITY, cs_shottime);
}
return TRUE;
}
#endif

162
src/shared/pmove.qc Normal file
View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define PMOVE_STEPHEIGHT 18
#define PMOVE_AIRSTEPHEIGHT 18
#define PMOVE_FRICTION 4
#define PMOVE_EDGEFRICTION 1
#define PMOVE_STOPSPEED 75
#define PMOVE_GRAVITY 800
#define PMOVE_AIRACCELERATE 10
#define PMOVE_WATERACCELERATE 8
#define PMOVE_ACCELERATE 4
#define PMOVE_MAXSPEED 250
.float waterlevel;
.float watertype;
/* values courtesy of https://wiki.alliedmods.net/Cs_weapons_information */
float
GamePMove_Maxspeed(player target)
{
float spd = serverkeyfloat("phy_maxspeed");
switch (target.activeweapon)
{
case WEAPON_M3:
spd *= 230/250;
break;
case WEAPON_XM1014:
spd *= 240/250;
break;
case WEAPON_MP5:
spd *= 250/250;
break;
case WEAPON_P90:
spd *= 245/250;
break;
case WEAPON_UMP45:
spd *= 250/250;
break;
case WEAPON_MAC10:
spd *= 250/250;
break;
case WEAPON_TMP:
spd *= 250/250;
break;
case WEAPON_AK47:
spd *= 221/250;
break;
case WEAPON_SG552:
spd *= 235/250;
break;
case WEAPON_M4A1:
spd *= 230/250;
break;
case WEAPON_AUG:
spd *= 240/250;
break;
case WEAPON_SCOUT:
spd *= 260/250;
break;
case WEAPON_AWP:
spd *= 210/250;
break;
case WEAPON_G3SG1:
spd *= 210/250;
break;
case WEAPON_SG550:
spd *= 210/250;
break;
case WEAPON_PARA:
spd *= 220/250;
break;
case WEAPON_USP45:
spd *= 250/250;
break;
case WEAPON_GLOCK18:
spd *= 250/250;
break;
case WEAPON_DEAGLE:
spd *= 250/250;
break;
case WEAPON_P228:
spd *= 250/250;
break;
case WEAPON_ELITES:
spd *= 250/250;
break;
case WEAPON_FIVESEVEN:
spd *= 250/250;
break;
case WEAPON_KNIFE:
spd *= 250/250;
break;
case WEAPON_HEGRENADE:
spd *= 250/250;
break;
case WEAPON_FLASHBANG:
spd *= 250/250;
break;
case WEAPON_SMOKEGRENADE:
spd *= 250/250;
break;
case WEAPON_C4BOMB:
spd *= 250/250;
break;
default:
}
if (target.flags & FL_CROUCHING) {
spd *= 0.5f;
}
return spd;
}
void
GamePMove_Fall(player target, float impactspeed)
{
if (impactspeed > 580) {
#ifdef SERVER
float fFallDamage = (impactspeed - 580) * (100 / (1024 - 580)) * 1.75f;
Damage_Apply(target, world, fFallDamage, 0, DMG_FALL);
if (random() < 0.5)
sound(target, CHAN_AUTO, "player/pl_pain2.wav", 1.0, ATTN_NORM);
else
sound(target, CHAN_AUTO, "player/pl_pain4.wav", 1.0, ATTN_NORM);
#endif
}
}
void
GamePMove_Jump(player target)
{
if (target.waterlevel >= 2) {
if (target.watertype == CONTENT_WATER) {
target.velocity[2] = 100;
} else if (target.watertype == CONTENT_SLIME) {
target.velocity[2] = 80;
} else {
target.velocity[2] = 50;
}
} else {
/* slow the player down a bit to prevent bhopping like crazy */
target.velocity *= 0.80f;
target.velocity[2] += 220;
}
}

47
src/shared/radio.h Normal file
View File

@ -0,0 +1,47 @@
enum
{
RADIO_BLOW,
RADIO_BOMBDEF,
RADIO_BOMBPL,
RADIO_CIRCLEBACK,
RADIO_CLEAR,
RADIO_COM_FOLLOWCOM,
RADIO_COM_GETINPOS,
RADIO_COM_GO,
RADIO_COM_REPORTIN,
RADIO_CT_AFFIRM,
RADIO_CT_BACKUP,
RADIO_CT_COVERME,
RADIO_CT_ENEMYS,
RADIO_CT_FIREINHOLE,
RADIO_CT_IMHIT,
RADIO_CT_INPOS,
RADIO_CT_POINT,
RADIO_CT_REPORTINGIN,
RADIO_CTWIN,
RADIO_ENEMYDOWN,
RADIO_FALLBACK,
RADIO_FIREASSIS,
RADIO_FOLLOWME,
RADIO_GETOUT,
RADIO_GO,
RADIO_HITASSIST,
RADIO_HOSDOWN,
RADIO_LETSGO,
RADIO_LOCKNLOAD,
RADIO_MATEDOWN,
RADIO_MEETME,
RADIO_MOVEOUT,
RADIO_NEGATIVE,
RADIO_POSITION,
RADIO_REGROUP,
RADIO_RESCUED,
RADIO_ROGER,
RADIO_ROUNDDRAW,
RADIO_STICKTOG,
RADIO_STORMFRONT,
RADIO_TAKEPOINT,
RADIO_TERWIN,
RADIO_VIP,
};

271
src/shared/w_ak47.qc Normal file
View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_ak47 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_ak47.mdl"
COUNTER-STRIKE (1999) ENTITY
AK-47 Weapon
- Buy Menu -
Price: $2500
Terrorists only weapon
*/
enum
{
AK47_IDLE,
AK47_RELOAD,
AK47_DRAW,
AK47_SHOOT1,
AK47_SHOOT2,
AK47_SHOOT3
};
void
w_ak47_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_ak47.fire");
precache_model("models/w_ak47.mdl");
#else
precache_model("models/v_ak47.mdl");
precache_model("models/p_ak47.mdl");
#endif
}
void
w_ak47_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.ak47_mag, pl.ammo_762mm, -1);
}
string
w_ak47_wmodel(void)
{
return "models/w_ak47.mdl";
}
string
w_ak47_pmodel(void)
{
return "models/p_ak47.mdl";
}
string
w_ak47_deathmsg(void)
{
return "";
}
int
w_ak47_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.ak47_mag = 30;
else
pl.ak47_mag = startammo;
} else {
if (pl.ammo_762mm < AMMO_MAX_762MM) {
pl.ammo_762mm = bound(0, pl.ammo_762mm + 30, AMMO_MAX_762MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_ak47_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_ak47.mdl");
Weapons_ViewAnimation(AK47_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 4;
pl.cs_cross_deltadist = 4;
#endif
}
void
w_ak47_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0) {
return;
}
if (!pl.ak47_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.ak47_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(AK47_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(AK47_SHOOT2);
break;
default:
Weapons_ViewAnimation(AK47_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 36, [accuracy,accuracy], WEAPON_AK47);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_AK47, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_AK47, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_ak47.fire");
#endif
pl.w_attack_next = 0.0955f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_ak47_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.ak47_mag >= 30) {
return;
}
if (!pl.ammo_762mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(AK47_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::ak47_mag, player::ammo_762mm, 30);
#endif
pl.w_attack_next = 2.4f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_ak47_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_AK47 : ANIM_AIM_AK47;
}
void
w_ak47_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [72/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_ak47_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.ak47_mag == 0 && pl.ammo_762mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_762mm, AMMO_MAX_762MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud11_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud11_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_ak47 =
{
.name = "ak47",
.id = ITEM_AK47,
.slot = 0,
.slot_pos = 7,
.allow_drop = TRUE,
.draw = w_ak47_draw,
.holster = __NULL__,
.primary = w_ak47_primary,
.secondary = __NULL__,
.reload = w_ak47_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_ak47_hud,
.precache = w_ak47_precache,
.pickup = w_ak47_pickup,
.updateammo = w_ak47_updateammo,
.wmodel = w_ak47_wmodel,
.pmodel = w_ak47_pmodel,
.deathmsg = w_ak47_deathmsg,
.aimanim = w_ak47_aimanim,
.hudpic = w_ak47_hudpic
};
#ifdef SERVER
void
weapon_ak47(void)
{
Weapons_InitItem(WEAPON_AK47);
}
#endif

296
src/shared/w_aug.qc Normal file
View File

@ -0,0 +1,296 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_aug (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_aug.mdl"
COUNTER-STRIKE (1999) ENTITY
Steyr AUG Weapon
- Buy Menu -
Price: $3500
Counter-Terrorists only weapon
*/
enum
{
AUG_IDLE,
AUG_RELOAD,
AUG_DRAW,
AUG_SHOOT1,
AUG_SHOOT2,
AUG_SHOOT3
};
void
w_aug_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_aug.fire");
precache_model("models/w_aug.mdl");
#else
precache_model("models/v_aug.mdl");
precache_model("models/p_aug.mdl");
#endif
}
void
w_aug_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.aug_mag, pl.ammo_762mm, -1);
}
string
w_aug_wmodel(void)
{
return "models/w_aug.mdl";
}
string
w_aug_pmodel(void)
{
return "models/p_aug.mdl";
}
string
w_aug_deathmsg(void)
{
return "";
}
int
w_aug_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.aug_mag = 30;
else
pl.aug_mag = startammo;
} else {
if (pl.ammo_762mm < AMMO_MAX_762MM) {
pl.ammo_762mm = bound(0, pl.ammo_762mm + 30, AMMO_MAX_762MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_aug_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_aug.mdl");
Weapons_ViewAnimation(AUG_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 3;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_aug_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.aug_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 215);
pl.aug_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(AUG_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(AUG_SHOOT2);
break;
default:
Weapons_ViewAnimation(AUG_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 32, [accuracy,accuracy], WEAPON_AUG);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_aug.fire");
#endif
if (pl.viewzoom == 1.0f) {
pl.w_attack_next = 0.0825f;
} else {
pl.w_attack_next = 0.15f;
}
pl.w_idle_next = pl.w_attack_next;
}
void
w_aug_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.2f;
} else {
pl.viewzoom = 1.0f;
}
pl.w_attack_next = 0.5f;
}
void
w_aug_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.aug_mag >= 30) {
return;
}
if (!pl.ammo_762mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(AUG_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::aug_mag, player::ammo_762mm, 30);
#endif
pl.w_attack_next = 3.3f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_aug_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_aug_hud(void)
{
#ifdef CLIENT
player pl = (player)self;
if (pl.viewzoom == 1.0f) {
Cstrike_DrawCrosshair();
} else {
Cstrike_DrawSimpleCrosshair();
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [72/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_aug_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.aug_mag == 0 && pl.ammo_762mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_762mm, AMMO_MAX_762MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud15_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud14_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_aug =
{
.name = "aug",
.id = ITEM_AUG,
.slot = 0,
.slot_pos = 10,
.allow_drop = TRUE,
.draw = w_aug_draw,
.holster = __NULL__,
.primary = w_aug_primary,
.secondary = w_aug_secondary,
.reload = w_aug_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_aug_hud,
.precache = w_aug_precache,
.pickup = w_aug_pickup,
.updateammo = w_aug_updateammo,
.wmodel = w_aug_wmodel,
.pmodel = w_aug_pmodel,
.deathmsg = w_aug_deathmsg,
.aimanim = w_aug_aimanim,
.hudpic = w_aug_hudpic
};
#ifdef SERVER
void
weapon_aug(void)
{
Weapons_InitItem(WEAPON_AUG);
}
#endif

323
src/shared/w_awp.qc Normal file
View File

@ -0,0 +1,323 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_awp (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_awp.mdl"
COUNTER-STRIKE (1999) ENTITY
AWP (AI Arctic Warfare/Magnum) Weapon
- Buy Menu -
Price: $4750
*/
enum
{
AWP_IDLE,
AWP_SHOOT1,
AWP_SHOOT2,
AWP_SHOOT3,
AWP_RELOAD,
AWP_DRAW
};
void
w_awp_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_awp.fire");
Sound_Precache("weapon_awp.zoom");
precache_model("models/w_awp.mdl");
#else
precache_model("models/v_awp.mdl");
precache_model("models/p_awp.mdl");
#endif
}
void
w_awp_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.awp_mag, pl.ammo_338mag, pl.mode_temp);
}
string
w_awp_wmodel(void)
{
return "models/w_awp.mdl";
}
string
w_awp_pmodel(void)
{
return "models/p_awp.mdl";
}
string
w_awp_deathmsg(void)
{
return "";
}
int
w_awp_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.awp_mag = 10;
else
pl.awp_mag = startammo;
} else {
if (pl.ammo_338mag < 20) {
pl.ammo_338mag = bound(0, pl.ammo_338mag + 10, 20);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_awp_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_awp.mdl");
Weapons_ViewAnimation(AWP_DRAW);
pl.mode_temp = 0;
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_awp_release(void)
{
player pl = (player)self;
w_cstrike_weaponrelease();
if (pl.w_idle_next > 0.0f) {
pl.viewzoom = 1.0f;
return;
}
if (pl.mode_temp == 1) {
pl.viewzoom = 0.45f;
} else if (pl.mode_temp == 2) {
pl.viewzoom = 0.1f;
} else {
pl.viewzoom = 1.0f;
}
}
void
w_awp_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
#ifdef SSQC
Sound_Play(pl, CHAN_WEAPON, "weapon_awp.zoom");
#endif
/* Simple toggle of fovs */
if (pl.mode_temp == 1) {
pl.mode_temp = 2;
} else if (pl.mode_temp == 2) {
pl.mode_temp = 0;
} else {
pl.mode_temp = 1;
}
pl.w_attack_next = 0.3f;
pl.w_idle_next = 0.0f;
w_awp_release();
}
void
w_awp_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
w_awp_release();
return;
}
if (!pl.awp_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, -1);
pl.awp_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(AWP_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(AWP_SHOOT2);
break;
default:
Weapons_ViewAnimation(AWP_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(2);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 115, [accuracy,accuracy], WEAPON_AWP);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_awp.fire");
#endif
pl.w_attack_next = 1.2f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_awp_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.awp_mag >= 10) {
return;
}
if (!pl.ammo_338mag) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(AWP_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::awp_mag, player::ammo_338mag, 10);
#endif
pl.w_attack_next = 2.9f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_awp_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_awp_hud(void)
{
#ifdef CLIENT
player pl = (player)self;
if (pl.viewzoom < 1.0f) {
Cstrike_DrawScope();
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [24/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_awp_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.awp_mag == 0 && pl.ammo_338mag == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_338mag, AMMO_MAX_338MAG, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud5_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud2_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_awp =
{
.name = "awp",
.id = ITEM_AWP,
.slot = 0,
.slot_pos = 12,
.allow_drop = TRUE,
.draw = w_awp_draw,
.holster = __NULL__,
.primary = w_awp_primary,
.secondary = w_awp_secondary,
.reload = w_awp_reload,
.release = w_awp_release,
.crosshair = w_awp_hud,
.precache = w_awp_precache,
.pickup = w_awp_pickup,
.updateammo = w_awp_updateammo,
.wmodel = w_awp_wmodel,
.pmodel = w_awp_pmodel,
.deathmsg = w_awp_deathmsg,
.aimanim = w_awp_aimanim,
.hudpic = w_awp_hudpic
};
#ifdef SERVER
void
weapon_awp(void)
{
Weapons_InitItem(WEAPON_AWP);
}
#endif

241
src/shared/w_c4bomb.qc Normal file
View File

@ -0,0 +1,241 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_c4bomb (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_c4.mdl"
COUNTER-STRIKE (1999) ENTITY
C4 Bomb Weapon, Bomb Defusal Gamemode Entity
Default arsenal for Terrorists
Can only be picked up by Terrorists and planted in
func_bombtarget brush entities.
*/
/* C4 weapon logic */
enum
{
C4_IDLE,
C4_DRAW,
C4_DROP,
C4_ENTERCODE
};
enum
{
C4S_NONE,
C4S_ENTERINGCODE,
C4S_DROPPING,
C4S_DONE
};
void
w_c4bomb_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_c4bomb.disarm");
Sound_Precache("weapon_c4bomb.disarmed");
Sound_Precache("weapon_c4bomb.explode");
Sound_Precache("weapon_c4bomb.plant");
precache_sound("weapons/c4_beep1.wav");
precache_sound("weapons/c4_beep2.wav");
precache_sound("weapons/c4_beep3.wav");
precache_sound("weapons/c4_beep4.wav");
precache_sound("weapons/c4_beep5.wav");
precache_sound("weapons/c4_disarmed.wav");
precache_sound("weapons/c4_disarm.wav");
precache_model("models/w_c4.mdl");
precache_model("models/w_backpack.mdl");
precache_model("sprites/ledglow.spr");
#else
precache_model("models/v_c4.mdl");
precache_model("models/p_c4.mdl");
#endif
}
void
w_c4bomb_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, -1, 1, -1);
}
string
w_c4bomb_wmodel(void)
{
return "models/w_backpack.mdl";
}
string
w_c4bomb_pmodel(void)
{
return "models/p_c4.mdl";
}
string
w_c4bomb_deathmsg(void)
{
return "";
}
void
w_c4bomb_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_c4.mdl");
Weapons_ViewAnimation(C4_DRAW);
pl.mode_temp = 0;
}
void
w_c4bomb_release(void)
{
player pl = (player)self;
if (pl.mode_temp == C4S_DROPPING) {
if (pl.w_idle_next <= 0.0f) {
pl.mode_temp = C4S_DONE;
#ifdef SERVER
C4Bomb_Plant(pl);
Weapons_RemoveItem(pl, WEAPON_C4BOMB);
#endif
}
return;
}
/* reset animation */
if (pl.mode_temp != C4S_NONE) {
Weapons_ViewAnimation(C4_IDLE);
}
pl.mode_temp = C4S_NONE;
pl.w_idle_next = 0.0f;
}
void
w_c4bomb_primary(void)
{
player pl = (player)self;
if (!(pl.gflags & GF_BOMBZONE)) {
return;
}
pl.flags |= FL_FROZEN;
switch (pl.mode_temp) {
case C4S_NONE:
pl.mode_temp = C4S_ENTERINGCODE;
Weapons_ViewAnimation(C4_ENTERCODE);
pl.w_idle_next = 3.0f;
break;
case C4S_ENTERINGCODE:
if (pl.w_idle_next <= 0.0f) {
pl.mode_temp = C4S_DROPPING;
Weapons_ViewAnimation(C4_DROP);
pl.w_idle_next = 1.0f;
}
break;
case C4S_DROPPING:
w_c4bomb_release();
return;
break;
default:
break;
}
pl.w_attack_next = 0.0f;
}
float
w_c4bomb_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_C4 : ANIM_AIM_C4;
}
void
w_c4bomb_hud(void)
{
#ifdef CLIENT
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [96/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_c4bomb_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud4_spr,
[0,0],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud1_spr,
[0,0],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_c4bomb =
{
.name = "c4",
.id = ITEM_C4BOMB,
.slot = 4,
.slot_pos = 0,
.allow_drop = TRUE,
.draw = w_c4bomb_draw,
.holster = __NULL__,
.primary = w_c4bomb_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_c4bomb_release,
.crosshair = w_c4bomb_hud,
.precache = w_c4bomb_precache,
.pickup = __NULL__,
.updateammo = w_c4bomb_updateammo,
.wmodel = w_c4bomb_wmodel,
.pmodel = w_c4bomb_pmodel,
.deathmsg = w_c4bomb_deathmsg,
.aimanim = w_c4bomb_aimanim,
.hudpic = w_c4bomb_hudpic
};
#ifdef SERVER
void
weapon_c4bomb(void)
{
Weapons_InitItem(WEAPON_C4BOMB);
}
#endif

276
src/shared/w_deagle.qc Normal file
View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_deagle (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_deagle.mdl"
COUNTER-STRIKE (1999) ENTITY
Desert Eagle .50 AE Weapon
- Buy Menu -
Price: $650
*/
enum
{
DEAGLE_IDLE,
DEAGLE_SHOOT1,
DEAGLE_SHOOT2,
DEAGLE_SHOOT_EMPTY,
DEAGLE_RELOAD,
DEAGLE_DRAW
};
void
w_deagle_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_deagle.fire");
precache_model("models/w_deagle.mdl");
#else
precache_model("models/v_deagle.mdl");
precache_model("models/p_deagle.mdl");
#endif
}
void
w_deagle_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.deagle_mag, pl.ammo_50ae, -1);
}
string
w_deagle_wmodel(void)
{
return "models/w_deagle.mdl";
}
string
w_deagle_pmodel(void)
{
return "models/p_deagle.mdl";
}
string
w_deagle_deathmsg(void)
{
return "";
}
int
w_deagle_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.deagle_mag = 7;
else
pl.deagle_mag = startammo;
} else {
if (pl.ammo_50ae < AMMO_MAX_50AE) {
pl.ammo_50ae = bound(0, pl.ammo_50ae + 7, AMMO_MAX_50AE);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_deagle_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_deagle.mdl");
Weapons_ViewAnimation(DEAGLE_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_deagle_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return;
}
if (!pl.deagle_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.deagle_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
if (pl.deagle_mag <= 0) {
Weapons_ViewAnimation(DEAGLE_SHOOT_EMPTY);
} else {
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(DEAGLE_SHOOT1);
break;
default:
Weapons_ViewAnimation(DEAGLE_SHOOT2);
break;
}
}
#else
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 54, [accuracy,accuracy], WEAPON_DEAGLE);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_ONEHAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_SHOOT_ONEHAND, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_deagle.fire");
#endif
pl.gflags |= GF_SEMI_TOGGLED;
pl.w_attack_next = 0.15f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_deagle_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.deagle_mag >= 7) {
return;
}
if (!pl.ammo_50ae) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(DEAGLE_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::deagle_mag, player::ammo_50ae, 7);
#endif
pl.w_attack_next = 2.1f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_deagle_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_ONEHAND : ANIM_AIM_ONEHAND;
}
void
w_deagle_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [24/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_deagle_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.deagle_mag == 0 && pl.ammo_50ae == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_50ae, AMMO_MAX_50AE, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud11_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud10_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_deagle =
{
.name = "deagle",
.id = ITEM_DEAGLE,
.slot = 1,
.slot_pos = 2,
.allow_drop = TRUE,
.draw = w_deagle_draw,
.holster = __NULL__,
.primary = w_deagle_primary,
.secondary = __NULL__,
.reload = w_deagle_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_deagle_hud,
.precache = w_deagle_precache,
.pickup = w_deagle_pickup,
.updateammo = w_deagle_updateammo,
.wmodel = w_deagle_wmodel,
.pmodel = w_deagle_pmodel,
.deathmsg = w_deagle_deathmsg,
.aimanim = w_deagle_aimanim,
.hudpic = w_deagle_hudpic
};
#ifdef SERVER
void
weapon_deagle(void)
{
Weapons_InitItem(WEAPON_DEAGLE);
}
#endif

328
src/shared/w_elites.qc Normal file
View File

@ -0,0 +1,328 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_elites (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_elite.mdl"
COUNTER-STRIKE (1999) ENTITY
Dual Beretta 96G (Elites) Weapon
- Buy Menu -
Price: $1000
*/
enum
{
ELITES_IDLE,
ELITES_IDLE_LEFTEMPTY,
ELITES_SHOOT_LEFT1,
ELITES_SHOOT_LEFT2,
ELITES_SHOOT_LEFT3,
ELITES_SHOOT_LEFT4,
ELITES_SHOOT_LEFT5,
ELITES_SHOOT_LEFTLAST,
ELITES_SHOOT_RIGHT1,
ELITES_SHOOT_RIGHT2,
ELITES_SHOOT_RIGHT3,
ELITES_SHOOT_RIGHT4,
ELITES_SHOOT_RIGHT5,
ELITES_SHOOT_RIGHTLAST,
ELITES_RELOAD,
ELITES_DRAW
};
void
w_elites_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_elites.fire");
precache_model("models/w_elite.mdl");
#else
precache_model("models/v_elite.mdl");
precache_model("models/p_elite.mdl");
#endif
}
void
w_elites_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.elites_mag, pl.ammo_9mm, -1);
}
string
w_elites_wmodel(void)
{
return "models/w_elites.mdl";
}
string
w_elites_pmodel(void)
{
return "models/p_elites.mdl";
}
string
w_elites_deathmsg(void)
{
return "";
}
int
w_elites_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.elites_mag = 30;
else
pl.elites_mag = startammo;
} else {
if (pl.ammo_9mm < AMMO_MAX_9MM) {
pl.ammo_9mm = bound(0, pl.ammo_9mm + 30, AMMO_MAX_9MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_elites_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_elite.mdl");
Weapons_ViewAnimation(ELITES_DRAW);
pl.mode_temp = 0;
#ifdef CLIENT
pl.cs_cross_mindist = 4;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_elites_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return;
}
if (!pl.elites_mag) {
return;
}
pl.mode_temp = 1 - pl.mode_temp;
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.elites_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 5;
if (pl.mode_temp) {
if (pl.elites_mag <= 0) {
Weapons_ViewAnimation(ELITES_SHOOT_LEFTLAST);
} else {
switch (r) {
case 0:
Weapons_ViewAnimation(ELITES_SHOOT_LEFT1);
break;
case 1:
Weapons_ViewAnimation(ELITES_SHOOT_LEFT2);
break;
case 2:
Weapons_ViewAnimation(ELITES_SHOOT_LEFT3);
break;
case 3:
Weapons_ViewAnimation(ELITES_SHOOT_LEFT4);
break;
default:
Weapons_ViewAnimation(ELITES_SHOOT_LEFT1);
break;
}
}
} else {
if (pl.elites_mag <= 0) {
Weapons_ViewAnimation(ELITES_SHOOT_RIGHTLAST);
} else {
switch (r) {
case 0:
Weapons_ViewAnimation(ELITES_SHOOT_RIGHT1);
break;
case 1:
Weapons_ViewAnimation(ELITES_SHOOT_RIGHT2);
break;
case 2:
Weapons_ViewAnimation(ELITES_SHOOT_RIGHT3);
break;
case 3:
Weapons_ViewAnimation(ELITES_SHOOT_RIGHT4);
break;
default:
Weapons_ViewAnimation(ELITES_SHOOT_RIGHT1);
break;
}
}
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 45, [accuracy,accuracy], WEAPON_ELITES);
if (self.flags & FL_CROUCHING) {
if (pl.mode_temp)
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT2_DUALPISTOLS, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_DUALPISTOLS, 0.45f);
} else {
if (pl.mode_temp)
Animation_PlayerTopTemp(ANIM_SHOOT2_DUALPISTOLS, 0.45f);
else
Animation_PlayerTopTemp(ANIM_SHOOT_DUALPISTOLS, 0.45f);
}
Sound_Play(pl, CHAN_WEAPON, "weapon_elites.fire");
#endif
pl.gflags |= GF_SEMI_TOGGLED;
pl.w_attack_next = 0.15f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_elites_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.elites_mag >= 30) {
return;
}
if (!pl.ammo_9mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(ELITES_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::elites_mag, player::ammo_9mm, 30);
#endif
pl.w_attack_next = 4.6f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_elites_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_DUALPISTOLS : ANIM_AIM_DUALPISTOLS;
}
void
w_elites_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [48/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_elites_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.elites_mag == 0 && pl.ammo_9mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_9mm, AMMO_MAX_9MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud15_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud14_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_elites =
{
.name = "elites",
.id = ITEM_ELITES,
.slot = 1,
.slot_pos = 4,
.allow_drop = TRUE,
.draw = w_elites_draw,
.holster = __NULL__,
.primary = w_elites_primary,
.secondary = __NULL__,
.reload = w_elites_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_elites_hud,
.precache = w_elites_precache,
.pickup = w_elites_pickup,
.updateammo = w_elites_updateammo,
.wmodel = w_elites_wmodel,
.pmodel = w_elites_pmodel,
.deathmsg = w_elites_deathmsg,
.aimanim = w_elites_aimanim,
.hudpic = w_elites_hudpic
};
#ifdef SERVER
void
weapon_elites(void)
{
Weapons_InitItem(WEAPON_ELITES);
}
#endif

276
src/shared/w_fiveseven.qc Normal file
View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_fiveseven (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_fiveseven.mdl"
COUNTER-STRIKE (1999) ENTITY
Five-SeveN Weapon
- Buy Menu -
Price: $750
*/
enum
{
FIVESEVEN_IDLE,
FIVESEVEN_SHOOT1,
FIVESEVEN_SHOOT2,
FIVESEVEN_SHOOT_EMPTY,
FIVESEVEN_RELOAD,
FIVESEVEN_DRAW
};
void
w_fiveseven_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_fiveseven.fire");
precache_model("models/w_fiveseven.mdl");
#else
precache_model("models/v_fiveseven.mdl");
precache_model("models/p_fiveseven.mdl");
#endif
}
void
w_fiveseven_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.fiveseven_mag, pl.ammo_57mm, -1);
}
string
w_fiveseven_wmodel(void)
{
return "models/w_fiveseven.mdl";
}
string
w_fiveseven_pmodel(void)
{
return "models/p_fiveseven.mdl";
}
string
w_fiveseven_deathmsg(void)
{
return "";
}
int
w_fiveseven_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.fiveseven_mag = 20;
else
pl.fiveseven_mag = startammo;
} else {
if (pl.ammo_57mm < AMMO_MAX_57MM) {
pl.ammo_57mm = bound(0, pl.ammo_57mm + 20, AMMO_MAX_57MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_fiveseven_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_fiveseven.mdl");
Weapons_ViewAnimation(FIVESEVEN_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_fiveseven_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return;
}
if (!pl.fiveseven_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.fiveseven_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
if (pl.fiveseven_mag <= 0) {
Weapons_ViewAnimation(FIVESEVEN_SHOOT_EMPTY);
} else {
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(FIVESEVEN_SHOOT1);
break;
default:
Weapons_ViewAnimation(FIVESEVEN_SHOOT2);
break;
}
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 25, [accuracy,accuracy], WEAPON_FIVESEVEN);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_ONEHAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_ONEHAND, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_fiveseven.fire");
#endif
pl.gflags |= GF_SEMI_TOGGLED;
pl.w_attack_next = 0.15f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_fiveseven_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.fiveseven_mag >= 20) {
return;
}
if (!pl.ammo_57mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(FIVESEVEN_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::fiveseven_mag, player::ammo_57mm, 20);
#endif
pl.w_attack_next = 3.1f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_fiveseven_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_ONEHAND : ANIM_AIM_ONEHAND;
}
void
w_fiveseven_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [120/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_fiveseven_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.fiveseven_mag == 0 && pl.ammo_57mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_57mm, AMMO_MAX_57MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud15_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud14_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_fiveseven =
{
.name = "fiveseven",
.id = ITEM_FIVESEVEN,
.slot = 1,
.slot_pos = 5,
.allow_drop = TRUE,
.draw = w_fiveseven_draw,
.holster = __NULL__,
.primary = w_fiveseven_primary,
.secondary = __NULL__,
.reload = w_fiveseven_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_fiveseven_hud,
.precache = w_fiveseven_precache,
.pickup = w_fiveseven_pickup,
.updateammo = w_fiveseven_updateammo,
.wmodel = w_fiveseven_wmodel,
.pmodel = w_fiveseven_pmodel,
.deathmsg = w_fiveseven_deathmsg,
.aimanim = w_fiveseven_aimanim,
.hudpic = w_fiveseven_hudpic
};
#ifdef SERVER
void
weapon_fiveseven(void)
{
Weapons_InitItem(WEAPON_FIVESEVEN);
}
#endif

292
src/shared/w_flashbang.qc Normal file
View File

@ -0,0 +1,292 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_flashbang (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_flashbang.mdl"
COUNTER-STRIKE (1999) ENTITY
Concussion (Flashbang) Grenade Weapon
When thrown, nearby players become blinded temporarily from the blast.
- Buy Menu -
Price: $200
*/
enum
{
FLASHBANG_IDLE,
FLASHBANG_PULLPIN,
FLASHBANG_THROW,
FLASHBANG_DRAW,
};
void
w_flashbang_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_flashbang.bounce");
Sound_Precache("weapon_flashbang.explode");
precache_model("models/w_flashbang.mdl");
#else
precache_model("models/v_flashbang.mdl");
precache_model("models/p_flashbang.mdl");
#endif
}
void
w_flashbang_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, -1, pl.ammo_fbgrenade, pl.mode_temp);
}
int
w_flashbang_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (pl.ammo_fbgrenade < AMMO_MAX_FLASHBANG) {
pl.ammo_fbgrenade = bound(0, pl.ammo_fbgrenade + 1, AMMO_MAX_FLASHBANG);
} else {
return FALSE;
}
#endif
return TRUE;
}
string
w_flashbang_wmodel(void)
{
return "models/w_flashbang.mdl";
}
string
w_flashbang_pmodel(void)
{
return "models/p_flashbang.mdl";
}
string
w_flashbang_deathmsg(void)
{
return "";
}
void
w_flashbang_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_flashbang.mdl");
Weapons_ViewAnimation(FLASHBANG_DRAW);
pl.mode_temp = 0;
}
#ifdef SERVER
void w_flashbang_throw(void)
{
static void flashbang_explode(void)
{
FX_Flashbang(self.origin);
Sound_Play(self, CHAN_BODY, "weapon_flashbang.explode");
remove(self);
}
static void flashbang_touch(void)
{
if (other.takedamage == DAMAGE_YES) {
Damage_Apply(other, self.owner, 15, WEAPON_FLASHBANG, DMG_BLUNT);
} else {
Sound_Play(self, CHAN_BODY, "weapon_flashbang.bounce");
}
self.frame = 0;
}
player pl = (player)self;
vector vPLAngle = pl.v_angle;
if (vPLAngle[0] < 0) {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 - 10) / 90.0);
} else {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 + 10) / 90.0);
}
float flVel = (90 - vPLAngle[0]) * 5;
if (flVel > 1000) {
flVel = 1000;
}
makevectors(vPLAngle);
vector vecSrc = pl.origin + pl.view_ofs + v_forward * 16;
vector vecThrow = v_forward * flVel + pl.velocity;
entity eGrenade = spawn();
eGrenade.owner = pl;
eGrenade.classname = "remove_me";
eGrenade.solid = SOLID_BBOX;
eGrenade.frame = 1;
eGrenade.velocity = vecThrow;
eGrenade.movetype = MOVETYPE_BOUNCE;
eGrenade.think = flashbang_explode;
eGrenade.touch = flashbang_touch;
eGrenade.nextthink = time + 4.0f;
setmodel(eGrenade, "models/w_flashbang.mdl");
setsize(eGrenade, [0,0,0], [0,0,0]);
setorigin(eGrenade, vecSrc);
}
#endif
void
w_flashbang_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* We're abusing this network variable for the holding check */
if (pl.mode_temp > 0) {
return;
}
/* Ammo check */
if (pl.ammo_fbgrenade <= 0) {
return;
}
Weapons_ViewAnimation(FLASHBANG_PULLPIN);
pl.mode_temp = 1;
pl.w_attack_next = 0.975f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_flashbang_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.mode_temp == 1) {
pl.ammo_fbgrenade--;
#ifdef CLIENT
Weapons_ViewAnimation(FLASHBANG_THROW);
#else
w_flashbang_throw();
#endif
pl.mode_temp = 2;
pl.w_attack_next = 1.0f;
pl.w_idle_next = 0.5f;
} else if (pl.mode_temp == 2) {
#ifdef CLIENT
Weapons_ViewAnimation(FLASHBANG_DRAW);
#else
if (!pl.ammo_fbgrenade) {
Weapons_RemoveItem(pl, WEAPON_FLASHBANG);
}
#endif
pl.w_attack_next = 0.5f;
pl.w_idle_next = 0.5f;
pl.mode_temp = 0;
}
}
float
w_flashbang_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_GRENADE : ANIM_AIM_GRENADE;
}
void
w_flashbang_hud(void)
{
#ifdef CLIENT
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [48/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_flashbang_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
HUD_DrawAmmoBar(pos, pl.ammo_fbgrenade, AMMO_MAX_FLASHBANG, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud6_spr,
[0,90/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud3_spr,
[0,90/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_flashbang =
{
.name = "flashbang",
.id = ITEM_FLASHBANG,
.slot = 3,
.slot_pos = 1,
.allow_drop = FALSE,
.draw = w_flashbang_draw,
.holster = __NULL__,
.primary = w_flashbang_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_flashbang_release,
.crosshair = w_flashbang_hud,
.precache = w_flashbang_precache,
.pickup = w_flashbang_pickup,
.updateammo = w_flashbang_updateammo,
.wmodel = w_flashbang_wmodel,
.pmodel = w_flashbang_pmodel,
.deathmsg = w_flashbang_deathmsg,
.aimanim = w_flashbang_aimanim,
.hudpic = w_flashbang_hudpic
};
#ifdef SERVER
void
weapon_flashbang(void)
{
Weapons_InitItem(WEAPON_FLASHBANG);
}
#endif

288
src/shared/w_g3sg1.qc Normal file
View File

@ -0,0 +1,288 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_g3sg1 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_g3sg1.mdl"
COUNTER-STRIKE (1999) ENTITY
Heckler & Koch G3/SG-1 Weapon
- Buy Menu -
Price: $5000
*/
enum
{
G3SG1_IDLE,
G3SG1_SHOOT1,
G3SG1_SHOOT2,
G3SG1_RELOAD,
G3SG1_DRAW
};
void
w_g3sg1_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_g3sg1.fire");
precache_model("models/w_g3sg1.mdl");
#else
precache_model("models/v_g3sg1.mdl");
precache_model("models/p_g3sg1.mdl");
#endif
}
void
w_g3sg1_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.g3sg1_mag, pl.ammo_762mm, -1);
}
string
w_g3sg1_wmodel(void)
{
return "models/w_g3sg1.mdl";
}
string
w_g3sg1_pmodel(void)
{
return "models/p_g3sg1.mdl";
}
string
w_g3sg1_deathmsg(void)
{
return "";
}
int
w_g3sg1_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.g3sg1_mag = 20;
else
pl.g3sg1_mag = startammo;
} else {
if (pl.ammo_762mm < AMMO_MAX_762MM) {
pl.ammo_762mm = bound(0, pl.ammo_762mm + 20, AMMO_MAX_762MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_g3sg1_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_g3sg1.mdl");
Weapons_ViewAnimation(G3SG1_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 6;
pl.cs_cross_deltadist = 4;
#endif
}
void
w_g3sg1_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.g3sg1_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.g3sg1_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(SCOUT_SHOOT1);
break;
default:
Weapons_ViewAnimation(SCOUT_SHOOT2);
break;
}
#else
TraceAttack_SetPenetrationPower(2);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 80, [accuracy,accuracy], WEAPON_G3SG1);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_g3sg1.fire");
#endif
pl.w_attack_next = 0.25f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_g3sg1_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.45f;
} else if (pl.viewzoom == 0.45f) {
pl.viewzoom = 0.1f;
} else {
pl.viewzoom = 1.0f;
}
pl.w_attack_next = 0.5f;
}
void
w_g3sg1_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.g3sg1_mag >= 20) {
return;
}
if (!pl.ammo_762mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(G3SG1_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::g3sg1_mag, player::ammo_762mm, 20);
Weapons_UpdateAmmo(pl, pl.g3sg1_mag, pl.ammo_762mm, -1);
#endif
pl.w_attack_next = 4.6f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_g3sg1_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_g3sg1_hud(void)
{
#ifdef CLIENT
player pl = (player)self;
if (pl.viewzoom < 1.0f) {
Cstrike_DrawScope();
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [72/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_g3sg1_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.g3sg1_mag == 0 && pl.ammo_762mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_762mm, AMMO_MAX_762MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud5_spr,
[0,180/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud2_spr,
[0,180/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_g3sg1 =
{
.name = "g3sg1",
.id = ITEM_G3SG1,
.slot = 0,
.slot_pos = 13,
.allow_drop = TRUE,
.draw = w_g3sg1_draw,
.holster = __NULL__,
.primary = w_g3sg1_primary,
.secondary = w_g3sg1_secondary,
.reload = w_g3sg1_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_g3sg1_hud,
.precache = w_g3sg1_precache,
.pickup = w_g3sg1_pickup,
.updateammo = w_g3sg1_updateammo,
.wmodel = w_g3sg1_wmodel,
.pmodel = w_g3sg1_pmodel,
.deathmsg = w_g3sg1_deathmsg,
.aimanim = w_g3sg1_aimanim,
.hudpic = w_g3sg1_hudpic
};
#ifdef SERVER
void
weapon_g3sg1(void)
{
Weapons_InitItem(WEAPON_G3SG1);
}
#endif

336
src/shared/w_glock18.qc Normal file
View File

@ -0,0 +1,336 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_glock18 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_glock18.mdl"
COUNTER-STRIKE (1999) ENTITY
Glock 18 Select Fire Weapon
Default arsenal for Terrorists
- Buy Menu -
Price: $400
*/
enum
{
GLOCK_IDLE1,
GLOCK_IDLE2,
GLOCK_IDLE3,
GLOCK_SHOOT_BURST1,
GLOCK_SHOOT_BURST2,
GLOCK_SHOOT,
GLOCK_SHOOT_EMPTY,
GLOCK_RELOAD1,
GLOCK_DRAW1,
GLOCK_UNUSED1,
GLOCK_UNUSED2,
GLOCK_DRAW2,
GLOCK_RELOAD2
};
void
w_glock18_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_glock18.fire");
Sound_Precache("weapon_glock18.burstfire");
precache_model("models/w_glock18.mdl");
#else
precache_model("models/v_glock18.mdl");
precache_model("models/p_glock18.mdl");
#endif
}
void
w_glock18_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.glock18_mag, pl.ammo_9mm, -1);
}
string
w_glock18_wmodel(void)
{
return "models/w_glock18.mdl";
}
string
w_glock18_pmodel(void)
{
return "models/p_glock18.mdl";
}
string
w_glock18_deathmsg(void)
{
return "";
}
int
w_glock18_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.glock18_mag = 20;
else
pl.glock18_mag = startammo;
} else {
if (pl.ammo_9mm < AMMO_MAX_9MM) {
pl.ammo_9mm = bound(0, pl.ammo_9mm + 20, AMMO_MAX_9MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_glock18_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_glock18.mdl");
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(GLOCK_DRAW1);
break;
default:
Weapons_ViewAnimation(GLOCK_DRAW2);
break;
}
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_glock18_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return;
}
if (!pl.glock18_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.glock18_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 25, [accuracy,accuracy], WEAPON_GLOCK18);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_ONEHAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_ONEHAND, 0.45f);
if (pl.mode_glock18) {
Sound_Play(pl, CHAN_WEAPON, "weapon_glock18.burstfire");
} else {
Sound_Play(pl, CHAN_WEAPON, "weapon_glock18.fire");
}
#endif
if (pl.mode_glock18) {
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(GLOCK_SHOOT_BURST1);
break;
default:
Weapons_ViewAnimation(GLOCK_SHOOT_BURST2);
break;
}
pl.w_attack_next = 0.5f;
} else {
if (pl.glock18_mag <= 0) {
Weapons_ViewAnimation(GLOCK_SHOOT_EMPTY);
} else {
Weapons_ViewAnimation(GLOCK_SHOOT);
}
pl.w_attack_next = 0.15f;
}
pl.gflags |= GF_SEMI_TOGGLED;
pl.w_idle_next = pl.w_attack_next;
}
void
w_glock18_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0) {
return;
}
/* toggle burst-fire */
pl.mode_glock18 = 1 - pl.mode_glock18;
#ifdef CLIENT
if (pl.mode_glock18) {
CSQC_Parse_CenterPrint("Switched to Burst-Fire mode");
} else {
CSQC_Parse_CenterPrint("Switched to Semi-Automatic mode");
}
#endif
pl.w_attack_next = 1.0f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_glock18_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.glock18_mag >= 20) {
return;
}
if (!pl.ammo_9mm) {
return;
}
#ifdef CLIENT
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(GLOCK_RELOAD1);
break;
default:
Weapons_ViewAnimation(GLOCK_RELOAD2);
break;
}
#else
Weapons_ReloadWeapon(pl, player::glock18_mag, player::ammo_9mm, 20);
Weapons_UpdateAmmo(pl, pl.glock18_mag, pl.ammo_9mm, -1);
#endif
pl.w_attack_next = 2.1f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_glock18_aimanim(void)
{
return w_deagle_aimanim();
}
void
w_glock18_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [48/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_glock18_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.glock18_mag == 0 && pl.ammo_9mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_9mm, AMMO_MAX_9MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud4_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud1_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_glock18 =
{
.name = "glock18",
.id = ITEM_GLOCK18,
.slot = 1,
.slot_pos = 1,
.allow_drop = TRUE,
.draw = w_glock18_draw,
.holster = __NULL__,
.primary = w_glock18_primary,
.secondary = w_glock18_secondary,
.reload = w_glock18_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_glock18_hud,
.precache = w_glock18_precache,
.pickup = w_glock18_pickup,
.updateammo = w_glock18_updateammo,
.wmodel = w_glock18_wmodel,
.pmodel = w_glock18_pmodel,
.deathmsg = w_glock18_deathmsg,
.aimanim = w_glock18_aimanim,
.hudpic = w_glock18_hudpic
};
#ifdef SERVER
void
weapon_glock18(void)
{
Weapons_InitItem(WEAPON_GLOCK18);
}
#endif

301
src/shared/w_hegrenade.qc Normal file
View File

@ -0,0 +1,301 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_hegrenade (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_hegrenade.mdl"
COUNTER-STRIKE (1999) ENTITY
HE (High Explosive) Grenade Weapon
When thrown, explodes with a fairly deadly blast radius to players.
- Buy Menu -
Price: $300
*/
enum
{
HEGRENADE_IDLE,
HEGRENADE_PULLPIN,
HEGRENADE_THROW,
HEGRENADE_DRAW,
};
void
w_hegrenade_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_hegrenade.bounce");
Sound_Precache("weapon_hegrenade.explode");
precache_model("models/w_hegrenade.mdl");
#else
precache_model("models/v_hegrenade.mdl");
precache_model("models/p_hegrenade.mdl");
#endif
}
void
w_hegrenade_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, -1, pl.ammo_hegrenade, pl.mode_temp);
}
int
w_hegrenade_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (pl.ammo_hegrenade < AMMO_MAX_HENADE) {
pl.ammo_hegrenade = bound(0, pl.ammo_hegrenade + 1, AMMO_MAX_HENADE);
} else {
return FALSE;
}
#endif
return TRUE;
}
string
w_hegrenade_wmodel(void)
{
return "models/w_hegrenade.mdl";
}
string
w_hegrenade_pmodel(void)
{
return "models/p_hegrenade.mdl";
}
string
w_hegrenade_deathmsg(void)
{
return "";
}
void
w_hegrenade_draw(void)
{
Weapons_SetModel("models/v_hegrenade.mdl");
Weapons_ViewAnimation(HEGRENADE_DRAW);
player pl = (player)self;
pl.mode_temp = 0;
}
#ifdef SERVER
void w_hegrenade_throw(void)
{
static void hegrenade_explode(void)
{
float dmg = 100;
FX_Explosion(self.origin);
Damage_Radius(self.origin, self.owner, dmg, dmg * 2.5f, TRUE, WEAPON_HEGRENADE);
Sound_Play(self, CHAN_BODY, "weapon_hegrenade.explode");
remove(self);
}
static void hegrenade_touch(void)
{
if (other.takedamage == DAMAGE_YES) {
Damage_Apply(other, self.owner, 15, WEAPON_HEGRENADE, DMG_BLUNT);
} else {
Sound_Play(self, CHAN_BODY, "weapon_hegrenade.bounce");
}
self.frame = 0;
}
player pl = (player)self;
vector vPLAngle = pl.v_angle;
if (vPLAngle[0] < 0) {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 - 10) / 90.0);
} else {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 + 10) / 90.0);
}
float flVel = (90 - vPLAngle[0]) * 5;
if (flVel > 1000) {
flVel = 1000;
}
makevectors(vPLAngle);
vector vecSrc = pl.origin + pl.view_ofs + v_forward * 16;
vector vecThrow = v_forward * flVel + pl.velocity;
entity eGrenade = spawn();
eGrenade.owner = pl;
eGrenade.classname = "remove_me";
eGrenade.solid = SOLID_BBOX;
eGrenade.frame = 1;
eGrenade.velocity = vecThrow;
eGrenade.movetype = MOVETYPE_BOUNCE;
eGrenade.think = hegrenade_explode;
eGrenade.touch = hegrenade_touch;
eGrenade.nextthink = time + 4.0f;
setmodel(eGrenade, "models/w_hegrenade.mdl");
setsize(eGrenade, [0,0,0], [0,0,0]);
setorigin(eGrenade, vecSrc);
}
#endif
void
w_hegrenade_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* We're abusing this network variable for the holding check */
if (pl.mode_temp > 0) {
return;
}
/* Ammo check */
#ifdef CLIENT
if (pl.ammo_hegrenade <= 0) {
return;
}
#else
if (pl.ammo_hegrenade <= 0) {
return;
}
#endif
Weapons_ViewAnimation(HEGRENADE_PULLPIN);
pl.mode_temp = 1;
pl.w_attack_next = 0.975f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_hegrenade_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.mode_temp == 1) {
#ifdef CLIENT
pl.ammo_hegrenade--;
Weapons_ViewAnimation(HEGRENADE_THROW);
#else
pl.ammo_hegrenade--;
w_hegrenade_throw();
#endif
pl.mode_temp = 2;
pl.w_attack_next = 1.0f;
pl.w_idle_next = 0.5f;
} else if (pl.mode_temp == 2) {
#ifdef CLIENT
Weapons_ViewAnimation(HEGRENADE_DRAW);
#else
if (!pl.ammo_hegrenade) {
Weapons_RemoveItem(pl, WEAPON_HEGRENADE);
}
#endif
pl.w_attack_next = 0.5f;
pl.w_idle_next = 0.5f;
pl.mode_temp = 0;
}
}
float
w_hegrenade_aimanim(void)
{
return w_flashbang_aimanim();
}
void
w_hegrenade_hud(void)
{
#ifdef CLIENT
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [72/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_hegrenade_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
HUD_DrawAmmoBar(pos, pl.ammo_hegrenade, AMMO_MAX_HENADE, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud6_spr,
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud3_spr,
[0,45/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_hegrenade =
{
.name = "hegrenade",
.id = ITEM_HEGRENADE,
.slot = 3,
.slot_pos = 0,
.allow_drop = FALSE,
.draw = w_hegrenade_draw,
.holster = __NULL__,
.primary = w_hegrenade_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_hegrenade_release,
.crosshair = w_hegrenade_hud,
.precache = w_hegrenade_precache,
.pickup = w_hegrenade_pickup,
.updateammo = w_hegrenade_updateammo,
.wmodel = w_hegrenade_wmodel,
.pmodel = w_hegrenade_pmodel,
.deathmsg = w_hegrenade_deathmsg,
.aimanim = w_hegrenade_aimanim,
.hudpic = w_hegrenade_hudpic
};
#ifdef SERVER
void
weapon_hegrenade(void)
{
Weapons_InitItem(WEAPON_HEGRENADE);
}
#endif

243
src/shared/w_knife.qc Normal file
View File

@ -0,0 +1,243 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_knife (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_knife.mdl"
COUNTER-STRIKE (1999) ENTITY
Knife Weapon
Default arsenal on both teams
*/
enum
{
KNIFE_IDLE1,
KNIFE_SLASH1,
KNIFE_SLASH2,
KNIFE_DRAW,
KNIFE_STAB,
KNIFE_STAB_MISS,
KNIFE_MIDSLASH1,
KNIFE_MIDSLASH2
};
void
w_knife_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_knife.hit");
Sound_Precache("weapon_knife.hitbody");
Sound_Precache("weapon_knife.hithard");
Sound_Precache("weapon_knife.miss");
precache_model("models/w_knife.mdl");
#else
precache_model("models/v_knife.mdl");
precache_model("models/p_knife.mdl");
#endif
}
void
w_knife_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, -1, -1, -1);
}
string
w_knife_wmodel(void)
{
return "models/w_knife.mdl";
}
string
w_knife_pmodel(void)
{
return "models/p_knife.mdl";
}
string
w_knife_deathmsg(void)
{
return "";
}
void
w_knife_draw(void)
{
#ifdef CLIENT
Weapons_SetModel("models/v_knife.mdl");
Weapons_ViewAnimation(KNIFE_DRAW);
#endif
}
void
w_knife_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
pl.w_attack_next = 0.7f;
#ifdef CLIENT
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(KNIFE_SLASH1);
break;
default:
Weapons_ViewAnimation(KNIFE_SLASH2);
break;
}
#else
vector src;
Weapons_MakeVectors();
src = pl.origin + pl.view_ofs;
traceline(src, src + (v_forward * 32), FALSE, pl);
Sound_Play(pl, CHAN_WEAPON, "weapon_knife.miss");
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_KNIFE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_SHOOT_KNIFE, 0.45f);
if (trace_fraction >= 1.0) {
return;
}
if (trace_ent.iBleeds) {
FX_Blood(trace_endpos, [1,0,0]);
Sound_Play(pl, CHAN_WEAPON, "weapon_knife.hitbody");
} else {
Sound_Play(pl, CHAN_WEAPON, "weapon_knife.hit");
}
if (trace_ent.takedamage) {
Damage_Apply(trace_ent, pl, 15, WEAPON_KNIFE, DMG_SLASH);
}
#endif
}
void
w_knife_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
pl.w_attack_next = 1.2f;
#ifdef CLIENT
Weapons_ViewAnimation(KNIFE_STAB);
#else
vector src;
Weapons_MakeVectors();
src = pl.origin + pl.view_ofs;
traceline(src, src + (v_forward * 32), FALSE, pl);
Sound_Play(pl, CHAN_WEAPON, "weapon_knife.miss");
if (trace_fraction >= 1.0) {
return;
}
/* don't bother with decals, we got squibs */
if (trace_ent.iBleeds) {
FX_Blood(trace_endpos, [1,0,0]);
Sound_Play(pl, CHAN_WEAPON, "weapon_knife.hitbody");
} else {
Sound_Play(pl, CHAN_WEAPON, "weapon_knife.hit");
}
if (trace_ent.takedamage) {
Damage_Apply(trace_ent, pl, 65, WEAPON_KNIFE, DMG_SLASH);
}
#endif
}
float
w_knife_aimanim(void)
{
return self.flags & FL_CROUCHING ? ANIM_CROUCH_AIM_KNIFE : ANIM_AIM_KNIFE;
}
void
w_knife_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud11_spr,
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud10_spr,
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_knife =
{
.name = "knife",
.id = ITEM_KNIFE,
.slot = 2,
.slot_pos = 0,
.allow_drop = FALSE,
.draw = w_knife_draw,
.holster = __NULL__,
.primary = w_knife_primary,
.secondary = w_knife_secondary,
.reload = __NULL__,
.release = __NULL__,
.crosshair = __NULL__,
.precache = w_knife_precache,
.pickup = __NULL__,
.updateammo = w_knife_updateammo,
.wmodel = w_knife_wmodel,
.pmodel = w_knife_pmodel,
.deathmsg = w_knife_deathmsg,
.aimanim = w_knife_aimanim,
.hudpic = w_knife_hudpic
};
#ifdef SERVER
void
weapon_knife(void)
{
Weapons_InitItem(WEAPON_KNIFE);
}
#endif

328
src/shared/w_m3.qc Normal file
View File

@ -0,0 +1,328 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_m3 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_m3.mdl"
COUNTER-STRIKE (1999) ENTITY
Benneli M3 Super90 Weapon
- Buy Menu -
Price: $1700
*/
enum
{
M3_IDLE,
M3_SHOOT1,
M3_SHOOT2,
M3_INSERT,
M3_RELOAD_END,
M3_RELOAD_START,
M3_DRAW
};
enum
{
M3S_IDLE,
M3S_RELOAD_START,
M3S_RELOAD,
M3S_RELOAD_END
};
void
w_m3_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_m3.fire");
precache_model("models/w_m3.mdl");
#else
precache_model("models/v_m3.mdl");
precache_model("models/p_m3.mdl");
#endif
}
void
w_m3_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.m3_mag, pl.ammo_buckshot, -1);
}
string
w_m3_wmodel(void)
{
return "models/w_m3.mdl";
}
string
w_m3_pmodel(void)
{
return "models/p_m3.mdl";
}
string
w_m3_deathmsg(void)
{
return "";
}
int
w_m3_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.m3_mag = 8;
else
pl.m3_mag = startammo;
} else {
if (pl.ammo_buckshot < AMMO_MAX_BUCKSHOT) {
pl.ammo_buckshot = bound(0, pl.ammo_buckshot + 8, AMMO_MAX_BUCKSHOT);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_m3_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_m3.mdl");
Weapons_ViewAnimation(M3_DRAW);
pl.mode_temp = 0;
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 6;
#endif
}
void
w_m3_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CLIENT
if (!pl.m3_mag) {
return;
}
#else
if (!pl.m3_mag) {
return;
}
#endif
Cstrike_ShotMultiplierAdd(pl, 9);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
#ifdef CLIENT
pl.m3_mag--;
View_SetMuzzleflash(MUZZLE_RIFLE);
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(9, pl.origin + pl.view_ofs, 26, [accuracy,accuracy], WEAPON_M3);
pl.m3_mag--;
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_SHOTGUN, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_SHOTGUN, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_m3.fire");
#endif
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(M3_SHOOT1);
break;
default:
Weapons_ViewAnimation(M3_SHOOT2);
break;
}
pl.w_attack_next = 1.0f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_m3_reload(void)
{
player pl = (player)self;
#ifdef CLIENT
if (pl.m3_mag >= 8) {
return;
}
if (pl.ammo_buckshot <= 0) {
return;
}
#else
if (pl.m3_mag >= 8) {
return;
}
if (pl.ammo_buckshot <= 0) {
return;
}
#endif
if (pl.mode_temp > M3S_IDLE) {
return;
}
pl.mode_temp = M3S_RELOAD_START;
pl.w_idle_next = 0.0f;
}
void
w_m3_release(void)
{
player pl = (player)self;
w_cstrike_weaponrelease();
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.mode_temp == M3S_RELOAD_START) {
Weapons_ViewAnimation(M3_RELOAD_START);
pl.mode_temp = M3S_RELOAD;
pl.w_idle_next = 0.65f;
} else if (pl.mode_temp == M3S_RELOAD) {
Weapons_ViewAnimation(M3_INSERT);
#ifdef CLIENT
pl.m3_mag++;
pl.ammo_buckshot--;
if (pl.ammo_buckshot <= 0 || pl.m3_mag >= 8) {
pl.mode_temp = M3S_RELOAD_END;
}
#else
pl.m3_mag++;
pl.ammo_buckshot--;
w_m3_updateammo(pl);
if (pl.ammo_buckshot <= 0 || pl.m3_mag >= 8) {
pl.mode_temp = M3S_RELOAD_END;
}
#endif
pl.w_idle_next = 0.5f;
} else if (pl.mode_temp == M3S_RELOAD_END) {
Weapons_ViewAnimation(M3_RELOAD_END);
pl.mode_temp = M3S_IDLE;
pl.w_idle_next = 10.0f;
pl.w_attack_next = 0.5f;
}
}
float
w_m3_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_m3_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [0,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_m3_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.m3_mag == 0 && pl.ammo_buckshot == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_buckshot, AMMO_MAX_BUCKSHOT, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud4_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud1_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_m3 =
{
.name = "m3",
.id = ITEM_M3,
.slot = 0,
.slot_pos = 0,
.allow_drop = TRUE,
.draw = w_m3_draw,
.holster = __NULL__,
.primary = w_m3_primary,
.secondary = __NULL__,
.reload = w_m3_reload,
.release = w_m3_release,
.crosshair = w_m3_hud,
.precache = w_m3_precache,
.pickup = w_m3_pickup,
.updateammo = w_m3_updateammo,
.wmodel = w_m3_wmodel,
.pmodel = w_m3_pmodel,
.deathmsg = w_m3_deathmsg,
.aimanim = w_m3_aimanim,
.hudpic = w_m3_hudpic
};
#ifdef SERVER
void
weapon_m3(void)
{
Weapons_InitItem(WEAPON_M3);
}
#endif

357
src/shared/w_m4a1.qc Normal file
View File

@ -0,0 +1,357 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_m4a1 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_m4a1.mdl"
COUNTER-STRIKE (1999) ENTITY
Colt M4A1 Carbine Weapon
- Buy Menu -
Price: $3100
Counter-Terrorists only weapon
*/
enum
{
M4A1_IDLE,
M4A1_SHOOT1,
M4A1_SHOOT2,
M4A1_SHOOT3,
M4A1_RELOAD,
M4A1_DRAW,
M4A1_ADDSIL,
M4A1_IDLEUNSIL,
M4A1_SHOOT1UNSIL,
M4A1_SHOOT2UNSIL,
M4A1_SHOOT3UNSIL,
M4A1_RELOADUNSIL,
M4A1_DRAWUNSIL,
M4A1_DETACHSIL
};
void
w_m4a1_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_m4a1.fire");
Sound_Precache("weapon_m4a1.silenced");
precache_model("models/w_m4a1.mdl");
#else
precache_model("models/v_m4a1.mdl");
precache_model("models/p_m4a1.mdl");
#endif
}
void
w_m4a1_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.m4a1_mag, pl.ammo_556mm, -1);
}
string
w_m4a1_wmodel(void)
{
return "models/w_m4a1.mdl";
}
string
w_m4a1_pmodel(void)
{
return "models/p_m4a1.mdl";
}
string
w_m4a1_deathmsg(void)
{
return "";
}
int
w_m4a1_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.m4a1_mag = 30;
else
pl.m4a1_mag = startammo;
} else {
if (pl.ammo_556mm < AMMO_MAX_556MM) {
pl.ammo_556mm = bound(0, pl.ammo_556mm + 30, AMMO_MAX_556MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_m4a1_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_m4a1.mdl");
if (pl.mode_m4a1 == 1) {
Weapons_ViewAnimation(M4A1_DRAW);
} else {
Weapons_ViewAnimation(M4A1_DRAWUNSIL);
}
#ifdef CLIENT
pl.cs_cross_mindist = 4;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_m4a1_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.m4a1_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 220);
pl.m4a1_mag--;
/* actual firing */
#ifdef CLIENT
if (pl.mode_m4a1 == 1) {
View_SetMuzzleflash(0);
} else {
View_SetMuzzleflash(MUZZLE_RIFLE);
}
/* this stuff is predicted */
int r = (float)input_sequence % 3;
if (pl.mode_m4a1 == 1) {
switch (r) {
case 0:
Weapons_ViewAnimation(M4A1_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(M4A1_SHOOT2);
break;
default:
Weapons_ViewAnimation(M4A1_SHOOT3);
break;
}
} else {
switch (r) {
case 0:
Weapons_ViewAnimation(M4A1_SHOOT1UNSIL);
break;
case 1:
Weapons_ViewAnimation(M4A1_SHOOT2UNSIL);
break;
default:
Weapons_ViewAnimation(M4A1_SHOOT3UNSIL);
break;
}
}
#else
/* Different sounds without silencer */
if (pl.mode_m4a1 == 1) {
Sound_Play(pl, CHAN_WEAPON, "weapon_m4a1.silenced");
} else {
Sound_Play(pl, CHAN_WEAPON, "weapon_m4a1.fire");
}
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 33, [accuracy,accuracy], WEAPON_M4A1);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
#endif
pl.w_attack_next = 0.0875f;
pl.w_idle_next = 2.0f;
}
void
w_m4a1_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0) {
return;
}
/* toggle silencer */
pl.mode_m4a1 = 1 - pl.mode_m4a1;
/* play the animation */
if (pl.mode_m4a1) {
Weapons_ViewAnimation(M4A1_ADDSIL);
} else {
Weapons_ViewAnimation(M4A1_DETACHSIL);
}
pl.w_attack_next = 2.0f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_m4a1_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.m4a1_mag >= 30) {
return;
}
if (!pl.ammo_556mm) {
return;
}
#ifdef CLIENT
if (pl.mode_m4a1 == 1) {
Weapons_ViewAnimation(M4A1_RELOAD);
} else {
Weapons_ViewAnimation(M4A1_RELOADUNSIL);
}
#else
Weapons_ReloadWeapon(pl, player::m4a1_mag, player::ammo_556mm, 30);
#endif
pl.w_attack_next = 3.1f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_m4a1_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_m4a1_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [0,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_m4a1_release(void)
{
player pl = (player)self;
w_cstrike_weaponrelease();
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.mode_m4a1) {
Weapons_ViewAnimation(M4A1_IDLE);
} else {
Weapons_ViewAnimation(M4A1_IDLEUNSIL);
}
pl.w_idle_next = 5.0f;
}
void
w_m4a1_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.m4a1_mag == 0 && pl.ammo_556mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_556mm, AMMO_MAX_556MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud5_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud2_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_m4a1 =
{
.name = "m4a1",
.id = ITEM_M4A1,
.slot = 0,
.slot_pos = 9,
.allow_drop = TRUE,
.draw = w_m4a1_draw,
.holster = __NULL__,
.primary = w_m4a1_primary,
.secondary = w_m4a1_secondary,
.reload = w_m4a1_reload,
.release = w_m4a1_release,
.crosshair = w_m4a1_hud,
.precache = w_m4a1_precache,
.pickup = w_m4a1_pickup,
.updateammo = w_m4a1_updateammo,
.wmodel = w_m4a1_wmodel,
.pmodel = w_m4a1_pmodel,
.deathmsg = w_m4a1_deathmsg,
.aimanim = w_m4a1_aimanim,
.hudpic = w_m4a1_hudpic
};
#ifdef SERVER
void
weapon_m4a1(void)
{
Weapons_InitItem(WEAPON_M4A1);
}
#endif

271
src/shared/w_mac10.qc Normal file
View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_mac10 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_mac10.mdl"
COUNTER-STRIKE (1999) ENTITY
Ingram MAC-10 Weapon
- Buy Menu -
Price: $1400
*/
enum
{
MAC10_IDLE,
MAC10_RELOAD,
MAC10_DRAW,
MAC10_SHOOT1,
MAC10_SHOOT2,
MAC10_SHOOT3
};
void
w_mac10_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_mac10.fire");
precache_model("models/w_mac10.mdl");
#else
precache_model("models/v_mac10.mdl");
precache_model("models/p_mac10.mdl");
#endif
}
void
w_mac10_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.mac10_mag, pl.ammo_45acp, -1);
}
string
w_mac10_wmodel(void)
{
return "models/w_mac10.mdl";
}
string
w_mac10_pmodel(void)
{
return "models/p_mac10.mdl";
}
string
w_mac10_deathmsg(void)
{
return "";
}
int
w_mac10_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.mac10_mag = 30;
else
pl.mac10_mag = startammo;
} else {
if (pl.ammo_45acp < AMMO_MAX_45ACP) {
pl.ammo_45acp = bound(0, pl.ammo_45acp + 30, AMMO_MAX_45ACP);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_mac10_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_mac10.mdl");
Weapons_ViewAnimation(MAC10_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 9;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_mac10_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.mac10_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.mac10_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(MAC10_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(MAC10_SHOOT2);
break;
default:
Weapons_ViewAnimation(MAC10_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 29, [accuracy,accuracy], WEAPON_MAC10);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_MP5, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_MP5, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_mac10.fire");
#endif
pl.w_attack_next = 0.07f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_mac10_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.mac10_mag >= 30) {
return;
}
if (!pl.ammo_45acp) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(MAC10_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::mac10_mag, player::ammo_45acp, 30);
Weapons_UpdateAmmo(pl, pl.mac10_mag, pl.ammo_45acp, -1);
#endif
pl.w_attack_next = 3.2f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_mac10_aimanim(void)
{
return w_deagle_aimanim();
}
void
w_mac10_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [96/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_mac10_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.mac10_mag == 0 && pl.ammo_45acp == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_45acp, AMMO_MAX_45ACP, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud15_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud14_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_mac10 =
{
.name = "mac10",
.id = ITEM_MAC10,
.slot = 0,
.slot_pos = 5,
.allow_drop = TRUE,
.draw = w_mac10_draw,
.holster = __NULL__,
.primary = w_mac10_primary,
.secondary = __NULL__,
.reload = w_mac10_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_mac10_hud,
.precache = w_mac10_precache,
.pickup = w_mac10_pickup,
.updateammo = w_mac10_updateammo,
.wmodel = w_mac10_wmodel,
.pmodel = w_mac10_pmodel,
.deathmsg = w_mac10_deathmsg,
.aimanim = w_mac10_aimanim,
.hudpic = w_mac10_hudpic
};
#ifdef SERVER
void
weapon_mac10(void)
{
Weapons_InitItem(WEAPON_MAC10);
}
#endif

271
src/shared/w_mp5.qc Normal file
View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_mp5navy (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_mp5.mdl"
COUNTER-STRIKE (1999) ENTITY
Heckler & Koch MP5-Navy Weapon
- Buy Menu -
Price: $1500
*/
enum
{
MP5_IDLE,
MP5_RELOAD,
MP5_DRAW,
MP5_SHOOT1,
MP5_SHOOT2,
MP5_SHOOT3
};
void
w_mp5_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_mp5.fire");
precache_model("models/w_mp5.mdl");
#else
precache_model("models/v_mp5.mdl");
precache_model("models/p_mp5.mdl");
#endif
}
void
w_mp5_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.mp5_mag, pl.ammo_9mm, -1);
}
string
w_mp5_wmodel(void)
{
return "models/w_mp5.mdl";
}
string
w_mp5_pmodel(void)
{
return "models/p_mp5.mdl";
}
string
w_mp5_deathmsg(void)
{
return "";
}
int
w_mp5_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.mp5_mag = 30;
else
pl.mp5_mag = startammo;
} else {
if (pl.ammo_9mm < AMMO_MAX_9MM) {
pl.ammo_9mm = bound(0, pl.ammo_9mm + 30, AMMO_MAX_9MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_mp5_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_mp5.mdl");
Weapons_ViewAnimation(MP5_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 5;
pl.cs_cross_deltadist = 2;
#endif
}
void
w_mp5_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.mp5_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 220);
pl.mp5_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(MP5_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(MP5_SHOOT2);
break;
default:
Weapons_ViewAnimation(MP5_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 26, [accuracy,accuracy], WEAPON_MP5);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_MP5, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_MP5, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_mp5.fire");
#endif
pl.w_attack_next = 0.08f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_mp5_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.mp5_mag >= 30) {
return;
}
if (!pl.ammo_9mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(MP5_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::mp5_mag, player::ammo_9mm, 30);
Weapons_UpdateAmmo(pl, pl.mp5_mag, pl.ammo_9mm, -1);
#endif
pl.w_attack_next = 2.6f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_mp5_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_mp5_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [48/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_mp5_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.mp5_mag == 0 && pl.ammo_9mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_9mm, AMMO_MAX_9MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud4_spr,
[0,180/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud1_spr,
[0,180/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_mp5 =
{
.name = "mp5navy",
.id = ITEM_MP5,
.slot = 0,
.slot_pos = 2,
.allow_drop = TRUE,
.draw = w_mp5_draw,
.holster = __NULL__,
.primary = w_mp5_primary,
.secondary = __NULL__,
.reload = w_mp5_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_mp5_hud,
.precache = w_mp5_precache,
.pickup = w_mp5_pickup,
.updateammo = w_mp5_updateammo,
.wmodel = w_mp5_wmodel,
.pmodel = w_mp5_pmodel,
.deathmsg = w_mp5_deathmsg,
.aimanim = w_mp5_aimanim,
.hudpic = w_mp5_hudpic
};
#ifdef SERVER
void
weapon_mp5navy(void)
{
Weapons_InitItem(WEAPON_MP5);
}
#endif

280
src/shared/w_p228.qc Normal file
View File

@ -0,0 +1,280 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_ (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_p228.mdl"
COUNTER-STRIKE (1999) ENTITY
SIG P228 Weapon
- Buy Menu -
Price: $600
*/
enum
{
P228_IDLE,
P228_SHOOT1,
P228_SHOOT2,
P228_SHOOT3,
P228_SHOOT_EMPTY,
P228_RELOAD,
P228_DRAW
};
void
w_p228_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_p228.fire");
precache_model("models/w_p228.mdl");
#else
precache_model("models/v_p228.mdl");
precache_model("models/p_p228.mdl");
#endif
}
void
w_p228_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.p228_mag, pl.ammo_357sig, -1);
}
string
w_p228_wmodel(void)
{
return "models/w_p228.mdl";
}
string
w_p228_pmodel(void)
{
return "models/p_p228.mdl";
}
string
w_p228_deathmsg(void)
{
return "";
}
int
w_p228_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.p228_mag = 13;
else
pl.p228_mag = startammo;
} else {
if (pl.ammo_357sig < AMMO_MAX_357SIG) {
pl.ammo_357sig = bound(0, pl.ammo_357sig + 13, AMMO_MAX_357SIG);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_p228_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_p228.mdl");
Weapons_ViewAnimation(P228_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_p228_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return;
}
if (!pl.p228_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.p228_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
if (pl.p228_mag <= 0) {
Weapons_ViewAnimation(P228_SHOOT_EMPTY);
} else {
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(P228_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(P228_SHOOT2);
break;
default:
Weapons_ViewAnimation(P228_SHOOT3);
break;
}
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 40, [accuracy,accuracy], WEAPON_P228);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_ONEHAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_ONEHAND, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_p228.fire");
#endif
pl.gflags |= GF_SEMI_TOGGLED;
pl.w_attack_next = 0.15f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_p228_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.p228_mag >= 30) {
return;
}
if (!pl.ammo_357sig) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(P228_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::p228_mag, player::ammo_357sig, 13);
Weapons_UpdateAmmo(pl, pl.p228_mag, pl.ammo_357sig, -1);
#endif
pl.w_attack_next = 2.7f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_p228_aimanim(void)
{
return w_deagle_aimanim();
}
void
w_p228_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [120/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_p228_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.p228_mag == 0 && pl.ammo_357sig == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_357sig, AMMO_MAX_357SIG, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud13_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud12_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_p228 =
{
.name = "p228",
.id = ITEM_P228,
.slot = 1,
.slot_pos = 3,
.allow_drop = TRUE,
.draw = w_p228_draw,
.holster = __NULL__,
.primary = w_p228_primary,
.secondary = __NULL__,
.reload = w_p228_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_p228_hud,
.precache = w_p228_precache,
.pickup = w_p228_pickup,
.updateammo = w_p228_updateammo,
.wmodel = w_p228_wmodel,
.pmodel = w_p228_pmodel,
.deathmsg = w_p228_deathmsg,
.aimanim = w_p228_aimanim,
.hudpic = w_p228_hudpic
};
#ifdef SERVER
void
weapon_p228(void)
{
Weapons_InitItem(WEAPON_P228);
}
#endif

271
src/shared/w_p90.qc Normal file
View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_p90 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_p90.mdl"
COUNTER-STRIKE (1999) ENTITY
FN P90 Weapon
- Buy Menu -
Price: $2350
*/
enum
{
P90_IDLE,
P90_RELOAD,
P90_DRAW,
P90_SHOOT1,
P90_SHOOT2,
P90_SHOOT3
};
void
w_p90_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_p90.fire");
precache_model("models/w_p90.mdl");
#else
precache_model("models/v_p90.mdl");
precache_model("models/p_p90.mdl");
#endif
}
void
w_p90_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.p90_mag, pl.ammo_57mm, -1);
}
string
w_p90_wmodel(void)
{
return "models/w_p90.mdl";
}
string
w_p90_pmodel(void)
{
return "models/p_p90.mdl";
}
string
w_p90_deathmsg(void)
{
return "";
}
int
w_p90_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.p90_mag = 50;
else
pl.p90_mag = startammo;
} else {
if (pl.ammo_57mm < AMMO_MAX_57MM) {
pl.ammo_57mm = bound(0, pl.ammo_57mm + 50, AMMO_MAX_57MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_p90_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_p90.mdl");
Weapons_ViewAnimation(P90_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 7;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_p90_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.p90_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 175);
pl.p90_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(P90_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(P90_SHOOT2);
break;
default:
Weapons_ViewAnimation(P90_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 26, [accuracy,accuracy], WEAPON_P90);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_MP5, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_MP5, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_p90.fire");
#endif
pl.w_attack_next = 0.07f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_p90_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.p90_mag >= 50) {
return;
}
if (!pl.ammo_57mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(P90_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::p90_mag, player::ammo_57mm, 50);
Weapons_UpdateAmmo(pl, pl.p90_mag, pl.ammo_57mm, -1);
#endif
pl.w_attack_next = 3.3f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_p90_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_p90_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [120/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_p90_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.p90_mag == 0 && pl.ammo_57mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_57mm, AMMO_MAX_57MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud13_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud12_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_p90 =
{
.name = "p90",
.id = ITEM_P90,
.slot = 0,
.slot_pos = 3,
.allow_drop = TRUE,
.draw = w_p90_draw,
.holster = __NULL__,
.primary = w_p90_primary,
.secondary = __NULL__,
.reload = w_p90_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_p90_hud,
.precache = w_p90_precache,
.pickup = w_p90_pickup,
.updateammo = w_p90_updateammo,
.wmodel = w_p90_wmodel,
.pmodel = w_p90_pmodel,
.deathmsg = w_p90_deathmsg,
.aimanim = w_p90_aimanim,
.hudpic = w_p90_hudpic
};
#ifdef SERVER
void
weapon_p90(void)
{
Weapons_InitItem(WEAPON_P90);
}
#endif

267
src/shared/w_para.qc Normal file
View File

@ -0,0 +1,267 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_m249 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_m249.mdl"
COUNTER-STRIKE (1999) ENTITY
FN M249 Para Weapon
- Buy Menu -
Price: $5750
*/
enum
{
PARA_IDLE,
PARA_SHOOT1,
PARA_SHOOT2,
PARA_RELOAD,
PARA_DRAW
};
void
w_para_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_para.fire");
precache_model("models/w_m249.mdl");
#else
precache_model("models/v_m249.mdl");
precache_model("models/p_m249.mdl");
#endif
}
void
w_para_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.para_mag, pl.ammo_556mmbox, -1);
}
string
w_para_wmodel(void)
{
return "models/w_m249.mdl";
}
string
w_para_pmodel(void)
{
return "models/p_m249.mdl";
}
string
w_para_deathmsg(void)
{
return "";
}
int
w_para_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.para_mag = 100;
else
pl.para_mag = startammo;
} else {
if (pl.ammo_556mmbox < AMMO_MAX_556MMBOX) {
pl.ammo_556mmbox = bound(0, pl.ammo_556mmbox + 100, AMMO_MAX_556MMBOX);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_para_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_m249.mdl");
Weapons_ViewAnimation(PARA_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 6;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_para_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.para_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 175);
pl.para_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(SCOUT_SHOOT1);
break;
default:
Weapons_ViewAnimation(SCOUT_SHOOT2);
break;
}
#else
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 35, [accuracy,accuracy], WEAPON_PARA);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_PARA, 0.45f);
else
Animation_PlayerTopTemp(ANIM_SHOOT_PARA, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_para.fire");
#endif
pl.w_attack_next = 0.1f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_para_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.para_mag >= 100) {
return;
}
if (!pl.ammo_556mmbox) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(PARA_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::para_mag, player::ammo_556mmbox, 100);
Weapons_UpdateAmmo(pl, pl.para_mag, pl.ammo_556mmbox, -1);
#endif
pl.w_attack_next = 3.0f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_para_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_para_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [0,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_para_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.para_mag == 0 && pl.ammo_556mmbox == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_556mmbox, AMMO_MAX_556MMBOX, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud6_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud3_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_para =
{
.name = "m249",
.id = ITEM_PARA,
.slot = 0,
.slot_pos = 15,
.allow_drop = TRUE,
.draw = w_para_draw,
.holster = __NULL__,
.primary = w_para_primary,
.secondary = __NULL__,
.reload = w_para_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_para_hud,
.precache = w_para_precache,
.pickup = w_para_pickup,
.updateammo = w_para_updateammo,
.wmodel = w_para_wmodel,
.pmodel = w_para_pmodel,
.deathmsg = w_para_deathmsg,
.aimanim = w_para_aimanim,
.hudpic = w_para_hudpic
};
#ifdef SERVER
void
weapon_m249(void)
{
Weapons_InitItem(WEAPON_PARA);
}
#endif

320
src/shared/w_scout.qc Normal file
View File

@ -0,0 +1,320 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_scout (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_scout.mdl"
COUNTER-STRIKE (1999) ENTITY
Steyr Scout Weapon
- Buy Menu -
Price: $1250
*/
enum
{
SCOUT_IDLE,
SCOUT_SHOOT1,
SCOUT_SHOOT2,
SCOUT_RELOAD,
SCOUT_DRAW
};
void
w_scout_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_scout.fire");
precache_model("models/w_scout.mdl");
#else
precache_model("models/v_scout.mdl");
precache_model("models/p_scout.mdl");
#endif
}
void
w_scout_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.scout_mag, pl.ammo_762mm, -1);
}
string
w_scout_wmodel(void)
{
return "models/w_scout.mdl";
}
string
w_scout_pmodel(void)
{
return "models/p_scout.mdl";
}
string
w_scout_deathmsg(void)
{
return "";
}
int
w_scout_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.scout_mag = 10;
else
pl.scout_mag = startammo;
} else {
if (pl.ammo_762mm < AMMO_MAX_762MM) {
pl.ammo_762mm = bound(0, pl.ammo_762mm + 10, AMMO_MAX_762MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_scout_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_scout.mdl");
Weapons_ViewAnimation(SCOUT_DRAW);
pl.mode_temp = 0;
#ifdef CLIENT
pl.cs_cross_mindist = 5;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_scout_release(void)
{
player pl = (player)self;
w_cstrike_weaponrelease();
if (pl.w_idle_next > 0.0f) {
pl.viewzoom = 1.0f;
return;
}
if (pl.mode_temp == 1) {
pl.viewzoom = 0.45f;
} else if (pl.mode_temp == 2) {
pl.viewzoom = 0.1f;
} else {
pl.viewzoom = 1.0f;
}
}
void
w_scout_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
#ifdef SSQC
Sound_Play(pl, CHAN_WEAPON, "weapon_awp.zoom");
#endif
/* Simple toggle of fovs */
if (pl.mode_temp == 1) {
pl.mode_temp = 2;
} else if (pl.mode_temp == 2) {
pl.mode_temp = 0;
} else {
pl.mode_temp = 1;
}
pl.w_attack_next = 0.3f;
pl.w_idle_next = 0.0f;
w_scout_release();
}
void
w_scout_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
w_scout_release();
return;
}
if (!pl.scout_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.scout_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(SCOUT_SHOOT1);
break;
default:
Weapons_ViewAnimation(SCOUT_SHOOT2);
break;
}
#else
TraceAttack_SetPenetrationPower(2);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 75, [accuracy,accuracy], WEAPON_SCOUT);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_scout.fire");
#endif
pl.w_attack_next = 1.25f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_scout_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.scout_mag >= 10) {
return;
}
if (!pl.ammo_762mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(SCOUT_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::scout_mag, player::ammo_762mm, 10);
Weapons_UpdateAmmo(pl, pl.scout_mag, pl.ammo_762mm, -1);
#endif
pl.w_attack_next = 2.0f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_scout_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_scout_hud(void)
{
#ifdef CLIENT
player pl = (player)self;
if (pl.viewzoom < 1.0f) {
Cstrike_DrawScope();
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [72/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_scout_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.scout_mag == 0 && pl.ammo_762mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_762mm, AMMO_MAX_762MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud13_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud12_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_scout =
{
.name = "scout",
.id = ITEM_SCOUT,
.slot = 0,
.slot_pos = 11,
.allow_drop = TRUE,
.draw = w_scout_draw,
.holster = __NULL__,
.primary = w_scout_primary,
.secondary = w_scout_secondary,
.reload = w_scout_reload,
.release = w_scout_release,
.crosshair = w_scout_hud,
.precache = w_scout_precache,
.pickup = w_scout_pickup,
.updateammo = w_scout_updateammo,
.wmodel = w_scout_wmodel,
.pmodel = w_scout_pmodel,
.deathmsg = w_scout_deathmsg,
.aimanim = w_scout_aimanim,
.hudpic = w_scout_hudpic
};
#ifdef SERVER
void
weapon_scout(void)
{
Weapons_InitItem(WEAPON_SCOUT);
}
#endif

288
src/shared/w_sg550.qc Normal file
View File

@ -0,0 +1,288 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_sg550 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_sg550.mdl"
COUNTER-STRIKE (1999) ENTITY
SIG SG 550 Weapon
- Buy Menu -
Price: $4200
*/
enum
{
SG550_IDLE,
SG550_SHOOT1,
SG550_SHOOT2,
SG550_RELOAD,
SG550_DRAW,
};
void
w_sg550_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_sg550.fire");
precache_model("models/w_sg550.mdl");
#else
precache_model("models/v_sg550.mdl");
precache_model("models/p_sg550.mdl");
#endif
}
void
w_sg550_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.sg550_mag, pl.ammo_556mm, -1);
}
string
w_sg550_wmodel(void)
{
return "models/w_sg550.mdl";
}
string
w_sg550_pmodel(void)
{
return "models/p_sg550.mdl";
}
string
w_sg550_deathmsg(void)
{
return "";
}
int
w_sg550_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.sg550_mag = 30;
else
pl.sg550_mag = startammo;
} else {
if (pl.ammo_556mm < AMMO_MAX_556MM) {
pl.ammo_556mm = bound(0, pl.ammo_556mm + 30, AMMO_MAX_556MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_sg550_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_sg550.mdl");
Weapons_ViewAnimation(SG550_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 5;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_sg550_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.sg550_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.sg550_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 2;
switch (r) {
case 0:
Weapons_ViewAnimation(SCOUT_SHOOT1);
break;
default:
Weapons_ViewAnimation(SCOUT_SHOOT2);
break;
}
#else
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 70, [accuracy,accuracy], WEAPON_SG550);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_sg550.fire");
#endif
pl.w_attack_next = 0.25f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_sg550_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.45f;
} else if (pl.viewzoom == 0.45f) {
pl.viewzoom = 0.1f;
} else {
pl.viewzoom = 1.0f;
}
pl.w_attack_next = 0.5f;
}
void
w_sg550_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.sg550_mag >= 30) {
return;
}
if (!pl.ammo_556mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(SG550_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::sg550_mag, player::ammo_556mm, 30);
Weapons_UpdateAmmo(pl, pl.sg550_mag, pl.ammo_556mm, -1);
#endif
pl.w_attack_next = 3.8f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_sg550_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_sg550_hud(void)
{
#ifdef CLIENT
player pl = (player)self;
if (pl.viewzoom < 1.0f) {
Cstrike_DrawScope();
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [0,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_sg550_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.sg550_mag == 0 && pl.ammo_556mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_556mm, AMMO_MAX_556MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud15_spr,
[0,180/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud14_spr,
[0,180/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_sg550 =
{
.name = "sg550",
.id = ITEM_SG550,
.slot = 0,
.slot_pos = 14,
.allow_drop = TRUE,
.draw = w_sg550_draw,
.holster = __NULL__,
.primary = w_sg550_primary,
.secondary = w_sg550_secondary,
.reload = w_sg550_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_sg550_hud,
.precache = w_sg550_precache,
.pickup = w_sg550_pickup,
.updateammo = w_sg550_updateammo,
.wmodel = w_sg550_wmodel,
.pmodel = w_sg550_pmodel,
.deathmsg = w_sg550_deathmsg,
.aimanim = w_sg550_aimanim,
.hudpic = w_sg550_hudpic
};
#ifdef SERVER
void
weapon_sg550(void)
{
Weapons_InitItem(WEAPON_SG550);
}
#endif

296
src/shared/w_sg552.qc Normal file
View File

@ -0,0 +1,296 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_sg552 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_sg552.mdl"
COUNTER-STRIKE (1999) ENTITY
SIG SG 552 Commando Weapon
- Buy Menu -
Price: $3500
*/
enum
{
SG552_IDLE,
SG552_RELOAD,
SG552_DRAW,
SG552_SHOOT1,
SG552_SHOOT2,
SG552_SHOOT3
};
void
w_sg552_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_sg552.fire");
precache_model("models/w_sg552.mdl");
#else
precache_model("models/v_sg552.mdl");
precache_model("models/p_sg552.mdl");
#endif
}
void
w_sg552_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.sg552_mag, pl.ammo_556mm, -1);
}
string
w_sg552_wmodel(void)
{
return "models/w_sg552.mdl";
}
string
w_sg552_pmodel(void)
{
return "models/p_sg552.mdl";
}
string
w_sg552_deathmsg(void)
{
return "";
}
int
w_sg552_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.sg552_mag = 30;
else
pl.sg552_mag = startammo;
} else {
if (pl.ammo_556mm < AMMO_MAX_556MM) {
pl.ammo_556mm = bound(0, pl.ammo_556mm + 30, AMMO_MAX_556MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_sg552_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_sg552.mdl");
Weapons_ViewAnimation(SG552_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 5;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_sg552_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (!pl.sg552_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 220);
pl.sg552_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(SG552_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(SG552_SHOOT2);
break;
default:
Weapons_ViewAnimation(SG552_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(1);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 33, [accuracy,accuracy], WEAPON_SG552);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_RIFLE, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_RIFLE, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_sg552.fire");
#endif
if (pl.viewzoom == 1.0f) {
pl.w_attack_next = 0.0825f;
} else {
pl.w_attack_next = 0.15f;
}
pl.w_idle_next = pl.w_attack_next;
}
void
w_sg552_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next) {
return;
}
/* Simple toggle of fovs */
if (pl.viewzoom == 1.0f) {
pl.viewzoom = 0.2f;
} else {
pl.viewzoom = 1.0f;
}
pl.w_attack_next = 0.5f;
}
void
w_sg552_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.sg552_mag >= 30) {
return;
}
if (!pl.ammo_556mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(SG552_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::sg552_mag, player::ammo_556mm, 30);
Weapons_UpdateAmmo(pl, pl.sg552_mag, pl.ammo_556mm, -1);
#endif
pl.w_attack_next = 3.2f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_sg552_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_sg552_hud(void)
{
#ifdef CLIENT
player pl = (player)self;
if (pl.viewzoom == 1.0f) {
Cstrike_DrawCrosshair();
} else {
Cstrike_DrawSimpleCrosshair();
}
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [0,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_sg552_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.sg552_mag == 0 && pl.ammo_556mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_556mm, AMMO_MAX_556MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud11_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud10_spr,
[0,45/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_sg552 =
{
.name = "sg552",
.id = ITEM_SG552,
.slot = 0,
.slot_pos = 8,
.allow_drop = TRUE,
.draw = w_sg552_draw,
.holster = __NULL__,
.primary = w_sg552_primary,
.secondary = w_sg552_secondary,
.reload = w_sg552_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_sg552_hud,
.precache = w_sg552_precache,
.pickup = w_sg552_pickup,
.updateammo = w_sg552_updateammo,
.wmodel = w_sg552_wmodel,
.pmodel = w_sg552_pmodel,
.deathmsg = w_sg552_deathmsg,
.aimanim = w_sg552_aimanim,
.hudpic = w_sg552_hudpic
};
#ifdef SERVER
void
weapon_sg552(void)
{
Weapons_InitItem(WEAPON_SG552);
}
#endif

View File

@ -0,0 +1,297 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_smokegrenade (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_smokegrenade.mdl"
COUNTER-STRIKE (1999) ENTITY
Smoke Grenade Weapon
When thrown, the explosion casts view-blocking smoke in that radius.
- Buy Menu -
Price: $300
*/
enum
{
SMOKEGRENADE_IDLE,
SMOKEGRENADE_PULLPIN,
SMOKEGRENADE_THROW,
SMOKEGRENADE_DRAW,
};
void
w_smokegrenade_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_smokegrenade.bounce");
Sound_Precache("weapon_smokegrenade.explode");
precache_model("models/w_smokegrenade.mdl");
#else
precache_model("models/v_smokegrenade.mdl");
precache_model("models/p_smokegrenade.mdl");
#endif
}
void
w_smokegrenade_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, -1, pl.ammo_smokegrenade, pl.mode_temp);
}
int
w_smokegrenade_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (pl.ammo_smokegrenade < AMMO_MAX_SMOKE) {
pl.ammo_smokegrenade = bound(0, pl.ammo_smokegrenade + 1, AMMO_MAX_SMOKE);
} else {
return FALSE;
}
#endif
return TRUE;
}
string
w_smokegrenade_wmodel(void)
{
return "models/w_smokegrenade.mdl";
}
string
w_smokegrenade_pmodel(void)
{
return "models/p_smokegrenade.mdl";
}
string
w_smokegrenade_deathmsg(void)
{
return "";
}
void
w_smokegrenade_draw(void)
{
Weapons_SetModel("models/v_smokegrenade.mdl");
Weapons_ViewAnimation(SMOKEGRENADE_DRAW);
player pl = (player)self;
pl.mode_temp = 0;
}
#ifdef SERVER
void w_smokegrenade_throw(void)
{
static void smokegrenade_explode(void)
{
FX_Smokenade(self.origin);
Sound_Play(self, CHAN_BODY, "weapon_smokegrenade.explode");
remove(self);
}
static void smokegrenade_touch(void)
{
if (other.takedamage == DAMAGE_YES) {
Damage_Apply(other, self.owner, 15, WEAPON_SMOKEGRENADE, DMG_BLUNT);
} else {
Sound_Play(self, CHAN_BODY, "weapon_smokegrenade.bounce");
}
self.frame = 0;
}
player pl = (player)self;
vector vPLAngle = pl.v_angle;
if (vPLAngle[0] < 0) {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 - 10) / 90.0);
} else {
vPLAngle[0] = -10 + vPLAngle[0] * ((90 + 10) / 90.0);
}
float flVel = (90 - vPLAngle[0]) * 5;
if (flVel > 1000) {
flVel = 1000;
}
makevectors(vPLAngle);
vector vecSrc = pl.origin + pl.view_ofs + v_forward * 16;
vector vecThrow = v_forward * flVel + pl.velocity;
entity eGrenade = spawn();
eGrenade.owner = pl;
eGrenade.classname = "remove_me";
eGrenade.solid = SOLID_BBOX;
eGrenade.frame = 1;
eGrenade.velocity = vecThrow;
eGrenade.movetype = MOVETYPE_BOUNCE;
eGrenade.think = smokegrenade_explode;
eGrenade.touch = smokegrenade_touch;
eGrenade.nextthink = time + 4.0f;
setmodel(eGrenade, "models/w_smokegrenade.mdl");
setsize(eGrenade, [0,0,0], [0,0,0]);
setorigin(eGrenade, vecSrc);
}
#endif
void
w_smokegrenade_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* We're abusing this network variable for the holding check */
if (pl.mode_temp > 0) {
return;
}
/* Ammo check */
#ifdef CLIENT
if (pl.ammo_smokegrenade <= 0) {
return;
}
#else
if (pl.ammo_smokegrenade <= 0) {
return;
}
#endif
Weapons_ViewAnimation(SMOKEGRENADE_PULLPIN);
pl.mode_temp = 1;
pl.w_attack_next = 0.975f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_smokegrenade_release(void)
{
player pl = (player)self;
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.mode_temp == 1) {
#ifdef CLIENT
pl.ammo_smokegrenade--;
Weapons_ViewAnimation(SMOKEGRENADE_THROW);
#else
pl.ammo_smokegrenade--;
w_smokegrenade_throw();
#endif
pl.mode_temp = 2;
pl.w_attack_next = 1.0f;
pl.w_idle_next = 0.5f;
} else if (pl.mode_temp == 2) {
#ifdef CLIENT
Weapons_ViewAnimation(SMOKEGRENADE_DRAW);
#else
if (!pl.ammo_smokegrenade) {
Weapons_RemoveItem(pl, WEAPON_SMOKEGRENADE);
}
#endif
pl.w_attack_next = 0.5f;
pl.w_idle_next = 0.5f;
pl.mode_temp = 0;
}
}
float
w_smokegrenade_aimanim(void)
{
return w_flashbang_aimanim();
}
void
w_smokegrenade_hud(void)
{
#ifdef CLIENT
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [144/256,96/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_smokegrenade_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
HUD_DrawAmmoBar(pos, pl.ammo_smokegrenade, AMMO_MAX_SMOKE, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud6_spr,
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud3_spr,
[0,135/256],
[170/256,45/256],
g_hud_color,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_smokegrenade =
{
.name = "smokegrenade",
.id = ITEM_SMOKEGRENADE,
.slot = 3,
.slot_pos = 2,
.allow_drop = FALSE,
.draw = w_smokegrenade_draw,
.holster = __NULL__,
.primary = w_smokegrenade_primary,
.secondary = __NULL__,
.reload = __NULL__,
.release = w_smokegrenade_release,
.crosshair = w_smokegrenade_hud,
.precache = w_smokegrenade_precache,
.pickup = w_smokegrenade_pickup,
.updateammo = w_smokegrenade_updateammo,
.wmodel = w_smokegrenade_wmodel,
.pmodel = w_smokegrenade_pmodel,
.deathmsg = w_smokegrenade_deathmsg,
.aimanim = w_smokegrenade_aimanim,
.hudpic = w_smokegrenade_hudpic
};
#ifdef SERVER
void
weapon_smokegrenade(void)
{
Weapons_InitItem(WEAPON_SMOKEGRENADE);
}
#endif

273
src/shared/w_tmp.qc Normal file
View File

@ -0,0 +1,273 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_tmp (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_tmp.mdl"
COUNTER-STRIKE (1999) ENTITY
Steyr Tactical Weapon
- Buy Menu -
Price: $1250
*/
enum
{
TMP_IDLE,
TMP_RELOAD,
TMP_DRAW,
TMP_SHOOT1,
TMP_SHOOT2,
TMP_SHOOT3
};
void
w_tmp_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_tmp.fire");
precache_model("models/w_tmp.mdl");
#else
precache_model("models/v_tmp.mdl");
precache_model("models/p_tmp.mdl");
#endif
}
void
w_tmp_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.tmp_mag, pl.ammo_9mm, -1);
}
string
w_tmp_wmodel(void)
{
return "models/w_tmp.mdl";
}
string
w_tmp_pmodel(void)
{
return "models/p_tmp.mdl";
}
string
w_tmp_deathmsg(void)
{
return "";
}
int
w_tmp_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.tmp_mag = 30;
else
pl.tmp_mag = startammo;
} else {
if (pl.ammo_9mm < AMMO_MAX_9MM) {
pl.ammo_9mm = bound(0, pl.ammo_9mm + 30, AMMO_MAX_9MM);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_tmp_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_tmp.mdl");
Weapons_ViewAnimation(TMP_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 7;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_tmp_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* ammo check */
if (!pl.tmp_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.tmp_mag--;
#ifdef CLIENT
View_SetMuzzleflash(MUZZLE_RIFLE);
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(TMP_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(TMP_SHOOT2);
break;
default:
Weapons_ViewAnimation(TMP_SHOOT3);
break;
}
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 26, [accuracy,accuracy], WEAPON_TMP);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_MP5, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_MP5, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_tmp.fire");
#endif
pl.w_attack_next = 0.07f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_tmp_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.tmp_mag >= 30) {
return;
}
if (!pl.ammo_9mm) {
return;
}
#ifdef CLIENT
Weapons_ViewAnimation(TMP_RELOAD);
#else
Weapons_ReloadWeapon(pl, player::tmp_mag, player::ammo_9mm, 30);
Weapons_UpdateAmmo(pl, pl.tmp_mag, pl.ammo_9mm, -1);
#endif
pl.w_attack_next = 2.1f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_tmp_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_tmp_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [48/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_tmp_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.tmp_mag == 0 && pl.ammo_9mm == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_9mm, AMMO_MAX_9MM, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud5_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud2_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_tmp =
{
.name = "tmp",
.id = ITEM_TMP,
.slot = 0,
.slot_pos = 6,
.allow_drop = TRUE,
.draw = w_tmp_draw,
.holster = __NULL__,
.primary = w_tmp_primary,
.secondary = __NULL__,
.reload = w_tmp_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_tmp_hud,
.precache = w_tmp_precache,
.pickup = w_tmp_pickup,
.updateammo = w_tmp_updateammo,
.wmodel = w_tmp_wmodel,
.pmodel = w_tmp_pmodel,
.deathmsg = w_tmp_deathmsg,
.aimanim = w_tmp_aimanim,
.hudpic = w_tmp_hudpic
};
#ifdef SERVER
void
weapon_tmp(void)
{
Weapons_InitItem(WEAPON_TMP);
}
#endif

287
src/shared/w_ump45.qc Normal file
View File

@ -0,0 +1,287 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_ump45 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_ump45.mdl"
COUNTER-STRIKE (1999) ENTITY
Heckler & Koch UMP .45 ACP Weapon
- Buy Menu -
Price: $1700
*/
enum
{
UMP45_IDLE,
UMP45_RELOAD,
UMP45_DRAW,
UMP45_SHOOT1,
UMP45_SHOOT2,
UMP45_SHOOT3
};
void
w_ump45_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_ump45.fire");
precache_model("models/w_ump45.mdl");
#else
precache_model("models/v_ump45.mdl");
precache_model("models/p_ump45.mdl");
#endif
}
void
w_ump45_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.ump45_mag, pl.ammo_45acp, -1);
}
string
w_ump45_wmodel(void)
{
return "models/w_ump45.mdl";
}
string
w_ump45_pmodel(void)
{
return "models/p_ump45.mdl";
}
string
w_ump45_deathmsg(void)
{
return "";
}
int
w_ump45_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.ump45_mag = 25;
else
pl.ump45_mag = startammo;
} else {
if (pl.ammo_45acp < AMMO_MAX_45ACP) {
pl.ammo_45acp = bound(0, pl.ammo_45acp + 25, AMMO_MAX_45ACP);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_ump45_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_ump45.mdl");
Weapons_ViewAnimation(UMP45_DRAW);
#ifdef CLIENT
pl.cs_cross_mindist = 6;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_ump45_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* ammo check */
#ifdef CLIENT
if (!pl.ump45_mag) {
return;
}
#else
if (!pl.ump45_mag) {
return;
}
#endif
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 210);
#ifdef CLIENT
pl.ump45_mag--;
View_SetMuzzleflash(MUZZLE_RIFLE);
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 30, [accuracy,accuracy], WEAPON_UMP45);
pl.ump45_mag--;
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_MP5, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_MP5, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_ump45.fire");
#endif
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(UMP45_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(UMP45_SHOOT2);
break;
default:
Weapons_ViewAnimation(UMP45_SHOOT3);
break;
}
pl.w_attack_next = 0.105f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_ump45_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
#ifdef CLIENT
if (pl.ump45_mag >= 25) {
return;
}
if (!pl.ammo_45acp) {
return;
}
#else
if (pl.ump45_mag >= 25) {
return;
}
if (!pl.ammo_45acp) {
return;
}
Weapons_ReloadWeapon(pl, player::ump45_mag, player::ammo_45acp, 25);
Weapons_UpdateAmmo(pl, pl.ump45_mag, pl.ammo_45acp, -1);
#endif
Weapons_ViewAnimation(UMP45_RELOAD);
pl.w_attack_next = 3.5f;
pl.w_idle_next = pl.w_attack_next;
}
float
w_ump45_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_ump45_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [96/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_ump45_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.ump45_mag == 0 && pl.ammo_45acp == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_45acp, AMMO_MAX_45ACP, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud16_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud16_spr,
[0,0],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_ump45 =
{
.name = "ump45",
.id = ITEM_UMP45,
.slot = 0,
.slot_pos = 4,
.allow_drop = TRUE,
.draw = w_ump45_draw,
.holster = __NULL__,
.primary = w_ump45_primary,
.secondary = __NULL__,
.reload = w_ump45_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_ump45_hud,
.precache = w_ump45_precache,
.pickup = w_ump45_pickup,
.updateammo = w_ump45_updateammo,
.wmodel = w_ump45_wmodel,
.pmodel = w_ump45_pmodel,
.deathmsg = w_ump45_deathmsg,
.aimanim = w_ump45_aimanim,
.hudpic = w_ump45_hudpic
};
#ifdef SERVER
void
weapon_ump45(void)
{
Weapons_InitItem(WEAPON_UMP45);
}
#endif

354
src/shared/w_usp45.qc Normal file
View File

@ -0,0 +1,354 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_usp45 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_usp45.mdl"
COUNTER-STRIKE (1999) ENTITY
Heckler & Koch USP .45 Tactical Weapon
Default arsenal for Counter-Terrorists
- Buy Menu -
Price: $500
*/
enum
{
USP45_IDLE,
USP45_SHOOT1,
USP45_SHOOT2,
USP45_SHOOT3,
USP45_SHOOTLAST,
USP45_RELOAD,
USP45_DRAW,
USP45_ADDSIL,
USP45_IDLEUNSIL,
USP45_SHOOT1UNSIL,
USP45_SHOOT2UNSIL,
USP45_SHOOT3UNSIL,
USP45_SHOOTLASTUNSIL,
USP45_RELOADUNSIL,
USP45_DRAWUNSIL,
USP45_DETACHSIL
};
void
w_usp45_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_usp45.fire");
Sound_Precache("weapon_usp45.silenced");
precache_model("models/w_usp.mdl");
#else
precache_model("models/v_usp.mdl");
precache_model("models/p_usp.mdl");
#endif
}
void
w_usp45_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.usp45_mag, pl.ammo_45acp, -1);
}
string
w_usp45_wmodel(void)
{
return "models/w_usp.mdl";
}
string
w_usp45_pmodel(void)
{
return "models/p_usp.mdl";
}
string
w_usp45_deathmsg(void)
{
return "";
}
int
w_usp45_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.usp45_mag = 12;
else
pl.usp45_mag = startammo;
} else {
if (pl.ammo_45acp < AMMO_MAX_45ACP) {
pl.ammo_45acp = bound(0, pl.ammo_45acp + 12, AMMO_MAX_45ACP);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_usp45_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_usp.mdl");
if (pl.mode_usp45 == 1) {
Weapons_ViewAnimation(USP45_DRAW);
} else {
Weapons_ViewAnimation(USP45_DRAWUNSIL);
}
#ifdef CLIENT
pl.cs_cross_mindist = 8;
pl.cs_cross_deltadist = 3;
#endif
}
void
w_usp45_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.gflags & GF_SEMI_TOGGLED) {
return;
}
/* ammo check */
if (!pl.usp45_mag) {
return;
}
Cstrike_ShotMultiplierAdd(pl, 1);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
pl.usp45_mag--;
/* actual firing */
#ifdef CLIENT
if (pl.mode_usp45 == 1) {
View_SetMuzzleflash(0);
} else {
View_SetMuzzleflash(MUZZLE_SMALL);
}
#else
/* Different sounds without silencer */
if (pl.mode_usp45 == 1) {
Sound_Play(pl, CHAN_WEAPON, "weapon_usp45.silenced");
} else {
Sound_Play(pl, CHAN_WEAPON, "weapon_usp45.fire");
}
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 33, [accuracy,accuracy], WEAPON_USP45);
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_ONEHAND, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_ONEHAND, 0.45f);
#endif
/* this stuff is predicted */
int r = (float)input_sequence % 3;
if (pl.mode_usp45 == 1) {
if (pl.usp45_mag <= 0) {
Weapons_ViewAnimation(USP45_SHOOTLAST);
} else {
switch (r) {
case 0:
Weapons_ViewAnimation(USP45_SHOOT1);
break;
case 1:
Weapons_ViewAnimation(USP45_SHOOT2);
break;
default:
Weapons_ViewAnimation(USP45_SHOOT3);
break;
}
}
} else {
if (pl.usp45_mag <= 0) {
Weapons_ViewAnimation(USP45_SHOOTLASTUNSIL);
} else {
switch (r) {
case 0:
Weapons_ViewAnimation(USP45_SHOOT1UNSIL);
break;
case 1:
Weapons_ViewAnimation(USP45_SHOOT2UNSIL);
break;
default:
Weapons_ViewAnimation(USP45_SHOOT3UNSIL);
break;
}
}
}
pl.gflags |= GF_SEMI_TOGGLED;
pl.w_attack_next = 0.15f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_usp45_secondary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0) {
return;
}
/* toggle silencer */
pl.mode_usp45 = 1 - pl.mode_usp45;
/* play the animation */
if (pl.mode_usp45) {
Weapons_ViewAnimation(USP45_ADDSIL);
} else {
Weapons_ViewAnimation(USP45_DETACHSIL);
}
pl.w_attack_next = 3.1f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_usp45_reload(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
if (pl.usp45_mag >= 12) {
return;
}
if (!pl.ammo_45acp) {
return;
}
#ifdef CLIENT
if (pl.mode_usp45 == 1) {
Weapons_ViewAnimation(USP45_RELOAD);
} else {
Weapons_ViewAnimation(USP45_RELOADUNSIL);
}
#else
Weapons_ReloadWeapon(pl, player::usp45_mag, player::ammo_45acp, 12);
#endif
pl.w_attack_next = 2.5f;
}
float
w_usp45_aimanim(void)
{
return w_deagle_aimanim();
}
void
w_usp45_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [96/256,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_usp45_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.usp45_mag == 0 && pl.ammo_45acp == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_45acp, AMMO_MAX_45ACP, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud4_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud1_spr,
[0,90/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_usp45 =
{
.name = "usp",
.id = ITEM_USP45,
.slot = 1,
.slot_pos = 0,
.allow_drop = TRUE,
.draw = w_usp45_draw,
.holster = __NULL__,
.primary = w_usp45_primary,
.secondary = w_usp45_secondary,
.reload = w_usp45_reload,
.release = w_cstrike_weaponrelease,
.crosshair = w_usp45_hud,
.precache = w_usp45_precache,
.pickup = w_usp45_pickup,
.updateammo = w_usp45_updateammo,
.wmodel = w_usp45_wmodel,
.pmodel = w_usp45_pmodel,
.deathmsg = w_usp45_deathmsg,
.aimanim = w_usp45_aimanim,
.hudpic = w_usp45_hudpic
};
#ifdef SERVER
void
weapon_usp45(void)
{
Weapons_InitItem(WEAPON_USP45);
}
#endif

331
src/shared/w_xm1014.qc Normal file
View File

@ -0,0 +1,331 @@
/*
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED weapon_xm1014 (0 0 1) (-16 -16 0) (16 16 32)
"model" "models/w_xm1014.mdl"
COUNTER-STRIKE (1999) ENTITY
Benneli XM1014 Weapon
- Buy Menu -
Price: $3000
*/
enum
{
XM1014_IDLE,
XM1014_SHOOT1,
XM1014_SHOOT2,
XM1014_INSERT,
XM1014_RELOAD_END,
XM1014_RELOAD_START,
XM1014_DRAW
};
enum
{
XM1014S_IDLE,
XM1014S_RELOAD_START,
XM1014S_RELOAD,
XM1014S_RELOAD_END
};
void
w_xm1014_precache(void)
{
#ifdef SERVER
Sound_Precache("weapon_xm1014.fire");
Sound_Precache("weapon_xm1014.insertshell");
precache_model("models/w_xm1014.mdl");
#else
precache_model("models/v_xm1014.mdl");
precache_model("models/p_xm1014.mdl");
#endif
}
void
w_xm1014_updateammo(player pl)
{
Weapons_UpdateAmmo(pl, pl.xm1014_mag, pl.ammo_buckshot, -1);
}
string
w_xm1014_wmodel(void)
{
return "models/w_xm1014.mdl";
}
string
w_xm1014_pmodel(void)
{
return "models/p_xm1014.mdl";
}
string
w_xm1014_deathmsg(void)
{
return "";
}
int
w_xm1014_pickup(int new, int startammo)
{
#ifdef SERVER
player pl = (player)self;
if (new) {
if (startammo == -1)
pl.xm1014_mag = 7;
else
pl.xm1014_mag = startammo;
} else {
if (pl.ammo_buckshot < AMMO_MAX_BUCKSHOT) {
pl.ammo_buckshot = bound(0, pl.ammo_buckshot + 7, AMMO_MAX_BUCKSHOT);
} else {
return FALSE;
}
}
#endif
return TRUE;
}
void
w_xm1014_draw(void)
{
player pl = (player)self;
Weapons_SetModel("models/v_xm1014.mdl");
Weapons_ViewAnimation(XM1014_DRAW);
pl.mode_temp = 0;
#ifdef CLIENT
pl.cs_cross_mindist = 9;
pl.cs_cross_deltadist = 4;
#endif
}
void
w_xm1014_primary(void)
{
player pl = (player)self;
if (pl.w_attack_next > 0.0) {
return;
}
/* ammo check */
#ifdef CLIENT
if (!pl.xm1014_mag) {
return;
}
#else
if (!pl.xm1014_mag) {
return;
}
#endif
Cstrike_ShotMultiplierAdd(pl, 6);
float accuracy = Cstrike_CalculateAccuracy(pl, 200);
#ifdef CLIENT
pl.xm1014_mag--;
View_SetMuzzleflash(MUZZLE_RIFLE);
#else
TraceAttack_SetPenetrationPower(0);
TraceAttack_FireBullets(6, pl.origin + pl.view_ofs, 22, [accuracy,accuracy], WEAPON_XM1014);
pl.xm1014_mag--;
if (self.flags & FL_CROUCHING)
Animation_PlayerTopTemp(ANIM_SHOOT_SHOTGUN, 0.45f);
else
Animation_PlayerTopTemp(ANIM_CROUCH_SHOOT_SHOTGUN, 0.45f);
Sound_Play(pl, CHAN_WEAPON, "weapon_xm1014.fire");
#endif
int r = (float)input_sequence % 3;
switch (r) {
case 0:
Weapons_ViewAnimation(XM1014_SHOOT1);
break;
default:
Weapons_ViewAnimation(XM1014_SHOOT2);
break;
}
pl.w_attack_next = 0.25f;
pl.w_idle_next = pl.w_attack_next;
}
void
w_xm1014_reload(void)
{
player pl = (player)self;
#ifdef CLIENT
if (pl.xm1014_mag >= 7) {
return;
}
if (pl.ammo_buckshot <= 0) {
return;
}
#else
if (pl.xm1014_mag >= 7) {
return;
}
if (pl.ammo_buckshot <= 0) {
return;
}
#endif
if (pl.mode_temp > XM1014S_IDLE) {
return;
}
pl.mode_temp = XM1014S_RELOAD_START;
pl.w_idle_next = 0.0f;
}
void
w_xm1014_release(void)
{
player pl = (player)self;
w_cstrike_weaponrelease();
if (pl.w_idle_next > 0.0) {
return;
}
if (pl.mode_temp == XM1014S_RELOAD_START) {
Weapons_ViewAnimation(XM1014_RELOAD_START);
pl.mode_temp = XM1014S_RELOAD;
pl.w_idle_next = 0.65f;
} else if (pl.mode_temp == XM1014S_RELOAD) {
Weapons_ViewAnimation(XM1014_INSERT);
#ifdef CLIENT
pl.xm1014_mag++;
pl.ammo_buckshot--;
if (pl.ammo_buckshot <= 0 || pl.xm1014_mag >= 7) {
pl.mode_temp = XM1014S_RELOAD_END;
}
#else
pl.xm1014_mag++;
pl.ammo_buckshot--;
w_xm1014_updateammo(pl);
Sound_Play(pl, CHAN_WEAPON, "weapon_xm1014.insertshell");
if (pl.ammo_buckshot <= 0 || pl.xm1014_mag >= 7) {
pl.mode_temp = XM1014S_RELOAD_END;
}
#endif
pl.w_idle_next = 0.5f;
} else if (pl.mode_temp == XM1014S_RELOAD_END) {
Weapons_ViewAnimation(XM1014_RELOAD_END);
pl.mode_temp = XM1014S_IDLE;
pl.w_idle_next = 10.0f;
pl.w_attack_next = 0.5f;
}
}
float
w_xm1014_aimanim(void)
{
return w_ak47_aimanim();
}
void
w_xm1014_hud(void)
{
#ifdef CLIENT
Cstrike_DrawCrosshair();
HUD_DrawAmmo1();
HUD_DrawAmmo2();
vector aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
drawsubpic(aicon_pos, [24,24], g_hud7_spr, [0,72/256], [24/256, 24/256], g_hud_color, pSeat->m_flAmmo2Alpha, DRAWFLAG_ADDITIVE);
#endif
}
void
w_xm1014_hudpic(int selected, vector pos, float a)
{
#ifdef CLIENT
player pl = (player)self;
vector hud_col;
if (pl.xm1014_mag == 0 && pl.ammo_buckshot == 0)
hud_col = [1,0,0];
else
hud_col = g_hud_color;
HUD_DrawAmmoBar(pos, pl.ammo_buckshot, AMMO_MAX_BUCKSHOT, a);
if (selected) {
drawsubpic(
pos,
[170,45],
g_hud13_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
} else {
drawsubpic(
pos,
[170,45],
g_hud12_spr,
[0,135/256],
[170/256,45/256],
hud_col,
1.0f,
DRAWFLAG_ADDITIVE
);
}
#endif
}
weapon_t w_xm1014 =
{
.name = "xm1014",
.id = ITEM_XM1014,
.slot = 0,
.slot_pos = 1,
.allow_drop = TRUE,
.draw = w_xm1014_draw,
.holster = __NULL__,
.primary = w_xm1014_primary,
.secondary = __NULL__,
.reload = w_xm1014_reload,
.release = w_xm1014_release,
.crosshair = w_xm1014_hud,
.precache = w_xm1014_precache,
.pickup = w_xm1014_pickup,
.updateammo = w_xm1014_updateammo,
.wmodel = w_xm1014_wmodel,
.pmodel = w_xm1014_pmodel,
.deathmsg = w_xm1014_deathmsg,
.aimanim = w_xm1014_aimanim,
.hudpic = w_xm1014_hudpic
};
#ifdef SERVER
void
weapon_xm1014(void)
{
Weapons_InitItem(WEAPON_XM1014);
}
#endif

62
src/shared/weapons.h Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Weapon Indices for the weapon table */
enum
{
WEAPON_NONE,
WEAPON_M3,
WEAPON_XM1014,
WEAPON_MP5,
WEAPON_P90,
WEAPON_UMP45,
WEAPON_MAC10,
WEAPON_TMP,
WEAPON_AK47,
WEAPON_SG552,
WEAPON_M4A1,
WEAPON_AUG,
WEAPON_SCOUT,
WEAPON_AWP,
WEAPON_G3SG1,
WEAPON_SG550,
WEAPON_PARA,
WEAPON_USP45,
WEAPON_GLOCK18,
WEAPON_DEAGLE,
WEAPON_P228,
WEAPON_ELITES,
WEAPON_FIVESEVEN,
WEAPON_KNIFE,
WEAPON_HEGRENADE,
WEAPON_FLASHBANG,
WEAPON_SMOKEGRENADE,
WEAPON_C4BOMB
};
#define AMMO_MAX_50AE 35
#define AMMO_MAX_762MM 90
#define AMMO_MAX_556MM 90
#define AMMO_MAX_556MMBOX 200
#define AMMO_MAX_338MAG 30
#define AMMO_MAX_9MM 120
#define AMMO_MAX_BUCKSHOT 32
#define AMMO_MAX_45ACP 100
#define AMMO_MAX_357SIG 52
#define AMMO_MAX_57MM 100
#define AMMO_MAX_FLASHBANG 2
#define AMMO_MAX_SMOKE 1
#define AMMO_MAX_HENADE 1

Some files were not shown because too many files have changed in this diff Show More