Move CS gamerules into their own progs using multiprogs. Clean up scripts.

This commit is contained in:
Marco Cawthorne 2024-10-16 23:11:24 -07:00
parent 73638fd197
commit d376999f6c
105 changed files with 2816 additions and 4767 deletions

View file

@ -3,3 +3,4 @@ CC=fteqcc
all:
cd client && $(MAKE)
cd server && $(MAKE)
cd rules && $(MAKE)

View file

@ -115,164 +115,7 @@ ClientGame_ConsoleCommand(void)
case "drop":
sendevent("DropWeapon", "");
break;
case "glock":
sendevent("CSBuy", "f", BUY_GLOCK18);
break;
case "usp":
sendevent("CSBuy", "f", BUY_USP45);
break;
case "p228":
sendevent("CSBuy", "f", BUY_P228);
break;
case "deagle":
sendevent("CSBuy", "f", BUY_DEAGLE);
break;
case "fn57":
sendevent("CSBuy", "f", BUY_FIVESEVEN);
break;
case "elites":
sendevent("CSBuy", "f", BUY_ELITES);
break;
case "m3":
sendevent("CSBuy", "f", BUY_M3);
break;
case "xm1014":
sendevent("CSBuy", "f", BUY_XM1014);
break;
case "tmp":
sendevent("CSBuy", "f", BUY_TMP);
break;
case "mac10":
sendevent("CSBuy", "f", BUY_MAC10);
break;
case "mp5":
sendevent("CSBuy", "f", BUY_MP5);
break;
case "ump45":
sendevent("CSBuy", "f", BUY_UMP45);
break;
case "p90":
sendevent("CSBuy", "f", BUY_P90);
break;
case "ak47":
sendevent("CSBuy", "f", BUY_AK47);
break;
case "m4a1":
sendevent("CSBuy", "f", BUY_M4A1);
break;
case "sg552":
sendevent("CSBuy", "f", BUY_SG552);
break;
case "aug":
sendevent("CSBuy", "f", BUY_AUG);
break;
case "scout":
sendevent("CSBuy", "f", BUY_SCOUT);
break;
case "sg550":
sendevent("CSBuy", "f", BUY_SG550);
break;
case "awp":
sendevent("CSBuy", "f", BUY_AWP);
break;
case "g3sg1":
sendevent("CSBuy", "f", BUY_G3SG1);
break;
case "m249":
sendevent("CSBuy", "f", BUY_PARA);
break;
case "buyammo1":
case "primammo":
sendevent("CSBuy", "f", BUY_PRIMARYAMMO);
break;
case "buyammo2":
case "secammo":
sendevent("CSBuy", "f", BUY_SECONDARYAMMO);
break;
case "vest":
sendevent("CSBuy", "f", BUY_VEST);
break;
case "vesthelm":
sendevent("CSBuy", "f", BUY_VESTHELMET);
break;
case "flash":
sendevent("CSBuy", "f", BUY_FLASHBANG);
break;
case "hegren":
sendevent("CSBuy", "f", BUY_HEGRENADE);
break;
case "vsgren":
sendevent("CSBuy", "f", BUY_SMOKEGRENADE);
break;
case "defuser":
sendevent("CSBuy", "f", BUY_DEFUSALKIT);
break;
case "nvg":
sendevent("CSBuy", "f", BUY_NIGHTVISION);
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 (0);
}

View file

@ -94,3 +94,9 @@ void HUD_DrawAmmoBar(vector pos, float val, float max, float a);
void Cstrike_DrawSimpleCrosshair(void);
void Cstrike_DrawScope(void);
void Textmenu_Call(string);
float
GetGameTime(void)
{
return max(0.0f, serverkeyfloat("cs_gametime") - time);
}

View file

@ -127,12 +127,12 @@ HUD_DrawTimer(int NSClientSpectator)
time_pos = g_hudmins + [(g_hudres[0] / 2) - 62, g_hudres[1] - 42];
}
if (getstatf(STAT_GAMETIME) == -1) {
if (GetGameTime() < -1) {
return;
}
iMinutes = getstatf(STAT_GAMETIME) / 60;
iSeconds = getstatf(STAT_GAMETIME) - 60 * iMinutes;
iMinutes = GetGameTime() / 60;
iSeconds = GetGameTime() - 60 * iMinutes;
iTens = iSeconds / 10;
iUnits = iSeconds - 10 * iTens;
@ -190,31 +190,32 @@ HUD_DrawMoney(void)
{
vector money_pos;
float endalpha;
float moneyValue = getplayerkeyfloat(player_localnum, "*money");
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) > pSeatLocal->m_iMoneyOld) {
if (moneyValue > pSeatLocal->m_iMoneyOld) {
/* effect already in progress from something else, go add on top of it! */
if (pSeatLocal->m_flMoneyAlpha > 0) {
pSeatLocal->m_iMoneyDelta += (pSeatLocal->m_iMoneyOld - getstati(STAT_MONEY));
pSeatLocal->m_iMoneyDelta += (pSeatLocal->m_iMoneyOld - moneyValue);
} else {
pSeatLocal->m_iMoneyDelta = pSeatLocal->m_iMoneyOld - getstati(STAT_MONEY);
pSeatLocal->m_iMoneyDelta = pSeatLocal->m_iMoneyOld - moneyValue;
}
/* make it green for a short time */
pSeatLocal->m_vecMoneyColor = [0,1,0];
pSeatLocal->m_flMoneyAlpha = 1.0;
} else if (getstati(STAT_MONEY) < pSeatLocal->m_iMoneyOld) {
} else if (moneyValue < pSeatLocal->m_iMoneyOld) {
/* same one as above */
if (pSeatLocal->m_flMoneyAlpha > 0) {
pSeatLocal->m_iMoneyDelta += (pSeatLocal->m_iMoneyOld - getstati(STAT_MONEY));
pSeatLocal->m_iMoneyDelta += (pSeatLocal->m_iMoneyOld - moneyValue);
} else {
pSeatLocal->m_iMoneyDelta = pSeatLocal->m_iMoneyOld - getstati(STAT_MONEY);
pSeatLocal->m_iMoneyDelta = pSeatLocal->m_iMoneyOld - moneyValue;
}
/* make it red */
pSeatLocal->m_vecMoneyColor = [1,0,0];
pSeatLocal->m_flMoneyAlpha = 1.0;
pSeatLocal->m_iMoneyDelta = pSeatLocal->m_iMoneyOld - getstati(STAT_MONEY);
pSeatLocal->m_iMoneyDelta = pSeatLocal->m_iMoneyOld - moneyValue;
}
/* maximum alpha is variable. */
@ -259,7 +260,7 @@ HUD_DrawMoney(void)
money_pos[0] += (24 * 5);
/* draw the red/green overlay numbers on top of ours */
HUD_DrawNums(getstati(STAT_MONEY), money_pos, endalpha, pSeatLocal->m_vecMoneyColor);
HUD_DrawNums(moneyValue, money_pos, endalpha, pSeatLocal->m_vecMoneyColor);
/* draw above how much money we've lost/gotten from all this */
HUD_DrawNums(fabs(pSeatLocal->m_iMoneyDelta), money_pos + [0,-32], endalpha, pSeatLocal->m_vecMoneyColor);
@ -269,13 +270,13 @@ HUD_DrawMoney(void)
/* regular number */
HUD_DrawNums(
getstati(STAT_MONEY),
moneyValue,
money_pos,
HUD_ALPHA - endalpha,
g_hud_color
);
pSeatLocal->m_iMoneyOld = getstati(STAT_MONEY);
pSeatLocal->m_iMoneyOld = moneyValue;
pSeatLocal->m_flMoneyAlpha = max(0, pSeatLocal->m_flMoneyAlpha - (clframetime * 0.5));
}
@ -345,7 +346,7 @@ HUD_DrawArmor(void)
pSeatLocal->m_flArmorAlpha = HUD_ALPHA;
}
if (pl.g_items & ITEM_HELMET) {
if (pl.HasItem("item_kevlar_helmet")) {
drawsubpic(
pos + [-80,1],
[24,24],
@ -370,7 +371,7 @@ HUD_DrawArmor(void)
}
if (pl.armor > 0) {
if (pl.g_items & ITEM_HELMET) {
if (pl.HasItem("item_kevlar_helmet")) {
drawsubpic(
pos + [-80,1],
[24, 24 * (pl.armor / 100)],
@ -536,13 +537,13 @@ HUD_DrawZones(void)
if (pl.gflags & GF_BUYZONE) {
zc++;
}
if (pl.g_items & ITEM_C4BOMB) {
if (pl.HasItem("weapon_c4")) {
zc++;
}
if (pl.gflags & GF_RESCUEZONE) {
zc++;
}
if (pl.g_items & ITEM_DEFUSAL) {
if (pl.HasItem("item_defuse")) {
zc++;
}
@ -561,7 +562,7 @@ HUD_DrawZones(void)
);
pos[1] += 32;
}
if (pl.g_items & ITEM_C4BOMB) {
if (pl.HasItem("item_defuse")) {
bool isRed = false;
if (pl.gflags & GF_BOMBZONE) {
@ -607,7 +608,7 @@ HUD_DrawZones(void)
);
pos[1] += 32;
}
if (pl.g_items & ITEM_DEFUSAL) {
if (pl.HasItem("item_defuse")) {
drawsubpic(
pos,
[32,32],
@ -695,17 +696,13 @@ HUD_PlayerNames(void)
float own_team = getplayerkeyfloat(player_localnum, "*team");
string strAlliance;
if ((own_team == TEAM_CT || own_team == TEAM_VIP) &&
(player_team == TEAM_VIP || player_team == TEAM_CT)) {
strAlliance = "Friend";
if (own_team != player_team) {
strAlliance = "Enemy";
} else {
if (own_team != player_team) {
strAlliance = "Enemy";
} else {
strAlliance = "Friend";
}
strAlliance = "Friend";
}
if (player_team == TEAM_T) {
Font_DrawText(vecTextPos, sprintf("%s%s: %s", \
HUD_GetChatColorHEX (TEAM_T), strAlliance, getplayerkeyvalue(player_num, "name")), FONT_CON);

View file

@ -99,7 +99,7 @@ HUD_AmmoNotify_Insert(int type, int count)
/* called whenever we should check for pickup updates */
void
HUD_AmmoNotify_Check(CSPlayer pl)
HUD_AmmoNotify_Check(NSClientPlayer pl)
{
#if 0
HUD_AmmoNotify_Insert(0, pl.ammo_50ae - pl.ammo_50ae_net);
@ -116,4 +116,9 @@ HUD_AmmoNotify_Check(CSPlayer pl)
HUD_AmmoNotify_Insert(11, pl.ammo_fbgrenade - pl.ammo_fbgrenade_net);
HUD_AmmoNotify_Insert(12, pl.ammo_smokegrenade - pl.ammo_smokegrenade_net);
#endif
}
void
HUD_ItemNotify_Check(NSClientPlayer pl)
{
}

View file

@ -36,76 +36,6 @@ ClientGame_Init(float apilevel, string enginename, float engineversion)
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");
/* hud */
registercommand("lastinv");
registercommand("invnext");

View file

@ -1,11 +1,10 @@
#pragma target fte_5768
//#pragma flag enable assumeint
#pragma progs_dat "../../zpak001.pk3dir/csprogs.dat"
#pragma progs_dat "../../csprogs.dat"
#define CSQC
#define CLIENT
#define CSTRIKE
#define CLASSIC_VGUI
#includelist
../../../src/shared/fteextensions.qc

View file

@ -20,12 +20,14 @@ TEAM_SELECT(int n)
switch (n) {
case 1:
Textmenu_Call("TERRORIST_SELECT");
localcmd("cmd joinTeam 1\n");
break;
case 2:
Textmenu_Call("CT_SELECT");
localcmd("cmd joinTeam 2\n");
break;
case 5:
sendevent("JoinAuto", "");
localcmd("cmd joinTeam 9\n");
Textmenu_Call("");
break;
}
@ -33,55 +35,54 @@ TEAM_SELECT(int n)
void
TERRORIST_SELECT(int n)
{
if (n == 5)
n = floor(random(1, 5));
switch (n) {
case 1:
sendevent("JoinTeam", "f", 1);
localcmd("cmd terror\n");
Textmenu_Call("");
break;
case 2:
sendevent("JoinTeam", "f", 2);
localcmd("cmd leet\n");
Textmenu_Call("");
break;
case 3:
sendevent("JoinTeam", "f", 3);
localcmd("cmd arctic\n");
Textmenu_Call("");
break;
case 4:
sendevent("JoinTeam", "f", 4);
Textmenu_Call("");
break;
case 5:
sendevent("JoinTeam", "f", floor(random(1,5)));
localcmd("cmd guerilla\n");
Textmenu_Call("");
break;
}
}
void
CT_SELECT(int n)
CT_SELECT(int classSelection)
{
switch (n) {
if (classSelection == 5)
classSelection = floor(random(1, 5));
switch (classSelection) {
case 1:
sendevent("JoinTeam", "f", 5);
localcmd("cmd urban\n");
Textmenu_Call("");
break;
case 2:
sendevent("JoinTeam", "f", 6);
localcmd("cmd gsg9\n");
Textmenu_Call("");
break;
case 3:
sendevent("JoinTeam", "f", 7);
localcmd("cmd sas\n");
Textmenu_Call("");
break;
case 4:
sendevent("JoinTeam", "f", 8);
Textmenu_Call("");
break;
case 5:
sendevent("JoinTeam", "f", floor(random(1,5)));
localcmd("cmd gign\n");
Textmenu_Call("");
break;
}
}
void
BUY(int n)
{

View file

@ -59,7 +59,21 @@ CSClassButtonCT::OnMouseUp(void)
if (classSelection == 5)
classSelection = floor(random(1, 5));
sendevent("JoinTeam", "f", (float)classSelection + 4);
switch (classSelection) {
case 1:
localcmd("cmd urban\n");
break;
case 2:
localcmd("cmd gsg9\n");
break;
case 3:
localcmd("cmd sas\n");
break;
case 4:
localcmd("cmd gign\n");
break;
}
winClassSelectionCT.Hide();
}
@ -193,4 +207,4 @@ VGUI_ChooseClassCT(void)
winClassSelectionCT.Show();
winClassSelectionCT.SetPos((g_vidsize / 2) - (winClassSelectionCT.GetSize() / 2));
}
}

View file

@ -60,7 +60,21 @@ CSClassButtonT::OnMouseUp(void)
if (classSelection == 5)
classSelection = floor(random(1, 5));
sendevent("JoinTeam", "f", (float)classSelection);
switch (classSelection) {
case 1:
localcmd("cmd terror\n");
break;
case 2:
localcmd("cmd leet\n");
break;
case 3:
localcmd("cmd arctic\n");
break;
case 4:
localcmd("cmd guerilla\n");
break;
}
winClassSelection.Hide();
}
@ -194,4 +208,4 @@ VGUI_ChooseClassT(void)
winClassSelection.Show();
winClassSelection.SetPos((g_vidsize / 2) - (winClassSelection.GetSize() / 2));
}
}

View file

@ -73,24 +73,23 @@ VGUI_ChooseTeam(void)
static VGUILabel lblMapInfo;
static void VGUI_ChooseTeam_CT(void) {
localcmd("cmd joinTeam 2\n");
VGUI_ChooseClassCT();
winChooseTeam.Hide();
}
static void VGUI_ChooseTeam_T(void) {
localcmd("cmd joinTeam 1\n");
VGUI_ChooseClassT();
winChooseTeam.Hide();
}
static void VGUI_ChooseTeam_Auto(void) {
if (VGUI_ChooseTeam_AutoQuery())
VGUI_ChooseTeam_CT();
else
VGUI_ChooseTeam_T();
localcmd("cmd joinTeam 9\n");
}
static void VGUI_ChooseTeam_Spec(void) {
sendevent("JoinSpectator", "");
localcmd("cmd joinTeam 1002\n");
winChooseTeam.Hide();
}

View file

@ -40,6 +40,7 @@ CSSpectateHUD::Draw(void)
string strText;
int iMinutes, iSeconds;
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
float moneyValue = getplayerkeyfloat(player_localnum, "*money");
/* parts on top and bottom */
drawfill(m_vecOrigin, [m_vecSize[0], 32], [0,0,0], 0.75f, DRAWFLAG_NORMAL);
@ -70,7 +71,7 @@ CSSpectateHUD::Draw(void)
#endif
/* money */
strText = sprintf("$ %i", getstati(STAT_MONEY));
strText = sprintf("$ %d", moneyValue);
flSep = stringwidth(strText, TRUE, [12,12]);
if (flSep < 42)
@ -99,8 +100,8 @@ CSSpectateHUD::Draw(void)
/* time display */
drawpic([flSep + 8, 15], "gfx/vgui/640_timer", [14, 14], [1,1,1], 1.0f, DRAWFLAG_NORMAL);
iMinutes = getstatf(STAT_GAMETIME) / 60;
iSeconds = getstatf(STAT_GAMETIME) - 60 * iMinutes;
iMinutes = GetGameTime() / 60;
iSeconds = GetGameTime() - 60 * iMinutes;
strText = sprintf("%i:%02i", iMinutes, iSeconds);
vecPos[0] = flSep + 8 + 17;
vecPos[1] = g_hudmins[1] + 17;

5
src/rules/Makefile Normal file
View file

@ -0,0 +1,5 @@
QCC=fteqcc
all:
mkdir -pv ../../zpak001.pk3dir/progs/
$(QCC) counterstrike.qc

1077
src/rules/counterstrike.qc Normal file

File diff suppressed because it is too large Load diff

238
src/rules/money.h Normal file
View file

@ -0,0 +1,238 @@
/*
* Copyright (c) 2016-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
var int g_cs_moneyreward_t;
var int g_cs_moneyreward_ct;
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 bool g_cs_bonus_ct;
var bool g_cs_bonus_t;
void
Money_AddMoney(entity targetPlayer, int addCash)
{
int currentCash = userinfo.GetInteger(targetPlayer, "*money");
currentCash += addCash;
/* clamp at the classic 160000. */
if (currentCash > 16000i) {
currentCash = 16000i;
} else if (currentCash < 0i) {
currentCash = 0i;
}
if (addCash > 0i) {
NSLog("Paying %s ^7$%i. Cash = $%i\n", targetPlayer.netname, addCash, currentCash);
} else if (addCash < 0i) {
NSLog("Fining %s ^7$%i. Cash = $%i\n", targetPlayer.netname, addCash, currentCash);
}
userinfo.SetInteger(targetPlayer, "*money", currentCash);
}
int
Money_GetCapital(entity targetPlayer)
{
return userinfo.GetInteger(targetPlayer, "*money");
}
void
Money_QueTeamReward(int targetTeam, int iMoneyValue)
{
if (targetTeam == TEAM_T) {
g_cs_moneyreward_t += iMoneyValue;
} else {
g_cs_moneyreward_ct += iMoneyValue;
}
}
void
Money_GiveTeamReward(entity targetPlayer)
{
if (targetPlayer.team == TEAM_T) {
Money_AddMoney(targetPlayer, g_cs_moneyreward_t);
} else {
Money_AddMoney(targetPlayer, g_cs_moneyreward_ct);
}
}
void
Money_ResetTeamReward(void)
{
g_cs_moneyreward_t = 0i;
g_cs_moneyreward_ct = 0i;
}
int
Money_GetLosses(int queryTeam)
{
if (queryTeam == TEAM_T) {
return (g_cs_roundslost_t);
} else {
return (g_cs_roundslost_ct);
}
}
bool
Money_HasBonus(int queryTeam)
{
if (queryTeam == TEAM_T) {
return (g_cs_bonus_t);
} else {
return (g_cs_bonus_ct);
}
}
void
Money_HandleRoundReward(int winningTeam)
{
int losingTeam = -1i; /* womp */
if (winningTeam == TEAM_CT) {
g_cs_winstreak_ct++;
g_cs_winstreak_t = 0i;
g_cs_roundslost_t++;
g_cs_roundslost_ct = 0i;
losingTeam = TEAM_T;
if (g_cs_winstreak_ct >= 2i) {
g_cs_bonus_ct = true;
}
} else {
g_cs_winstreak_t++;
g_cs_winstreak_ct = 0i;
g_cs_roundslost_ct++;
g_cs_roundslost_t = 0i;
losingTeam = TEAM_CT;
if (g_cs_winstreak_t >= 2i) {
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(losingTeam)) {
switch (Money_GetLosses(losingTeam)) {
case 1i:
Money_QueTeamReward(losingTeam, 1500i);
break;
case 2i:
Money_QueTeamReward(losingTeam, 2000i);
break;
case 3i:
Money_QueTeamReward(losingTeam, 2500i);
break;
default:
Money_QueTeamReward(losingTeam, 3000i);
break;
}
} else {
switch (Money_GetLosses(losingTeam)) {
case 1i:
Money_QueTeamReward(losingTeam, 1400i);
break;
case 2i:
Money_QueTeamReward(losingTeam, 1900i);
break;
case 3i:
Money_QueTeamReward(losingTeam, 2400i);
break;
case 4i:
Money_QueTeamReward(losingTeam, 2900i);
break;
default:
Money_QueTeamReward(losingTeam, 3400i);
break;
}
}
}
void
Money_ResetRoundReward(void)
{
g_cs_roundslost_ct =
g_cs_roundslost_t =
g_cs_winstreak_ct =
g_cs_winstreak_t = 0i;
g_cs_bonus_ct =
g_cs_bonus_t = false;
}
void
Money_WipeProgress(entity targetPlayer)
{
userinfo.SetInteger(targetPlayer, "*money", 0i);
Money_AddMoney(targetPlayer, cvars.GetInteger("mp_startmoney"));
}
void
Money_PurchaseAmmoForSlot(entity customer, int slot)
{
string inventory = actor.GetInventory(customer);
/* we get to iterate over the whole inventory */
for (int i = 0; i < tokenize(inventory); i++) {
string declName = argv(i);
int slotNum = entityDef.GetInteger(declName, "hudSlot");
string ammoType = entityDef.GetString(declName, "ammoType");
/* validity check */
if (slotNum != slot || !STRING_SET(ammoType)) {
continue;
}
/* we found a weapon that will get filled up. */
int itemPrice = entityDef.GetInteger(ammoType, "price");
int ammoAmount = entityDef.GetInteger(ammoType, strcat("inv_", ammoType));
int ammoID = ammo.NumForName(ammoType);
/* invalid weapon. */
if (itemPrice <= 0i || ammoAmount <= 0i) {
return;
}
/* as long as we're not full... */
while (actor.MaxAmmo(customer, ammoID) == false) {
/* and we can afford it... */
if ((Money_GetCapital(customer) - itemPrice) >= 0) {
ents.Input(customer, "GiveAmmo", sprintf("%s %i", ammoType, ammoAmount), world);
Money_AddMoney(customer, -itemPrice);
} else {
break;
}
}
}
}
void
Money_Purchase(entity customer, string desiredItem)
{
int itemPrice = entityDef.GetInteger(desiredItem, "price");
/* no free things in CS */
if (itemPrice <= 0i) {
return;
}
if ((Money_GetCapital(customer) - itemPrice) >= 0) {
ents.Input(customer, "GiveItem", desiredItem, world);
Money_AddMoney(customer, -itemPrice);
}
}

121
src/rules/radio.h Normal file
View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../shared/radio.h"
#include "../shared/events.h"
/*
=================
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)
{
for (entity teamPlayer = world; (teamPlayer = find(teamPlayer, classname, "player"));) {
if (teamPlayer.team == fTeam) {
ents.Input(teamPlayer, "RadioMessage", ftos(fMessage), world);
}
}
}
/*
=================
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 (IsAssassination()) {
Radio_TeamMessage(RADIO_VIP, TEAM_CT);
Radio_TeamMessage(Radio_DefaultStart(), TEAM_T);
} else if (IsEscape()) {
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)
{
// Don't allow spamming
/*if (self.fRadioFinished > time) {
return;
}*/
// When dead, don't talk
if (self.health <= 0) {
return;
}
for (entity teamPlayer = world; (teamPlayer = find(teamPlayer, classname, "player"));) {
ents.Input(teamPlayer, "RadioTeamMessage", sprintf("%d %d", num_for_edict(teamPlayer) - 1, fMessage), world);
}
/*self.fRadioFinished = time + 3.0f;*/
}

View file

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

View file

@ -1,349 +0,0 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* 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;
#if 0
ammoinfo_t cs_ammoinfo[11] = {
/* CALIBER_NONE */
{
.a_size = 0,
.a_max = 0,
.price = 0
},
/* CALIBER_50AE */
{
.a_size = 7,
.a_max = AMMO_MAX_50AE,
.price = 40
},
/* CALIBER_762MM */
{
.a_size = 30,
.a_max = AMMO_MAX_762MM,
.price = 80
},
/* CALIBER_556MM */
{
.a_size = 30,
.a_max = AMMO_MAX_556MM,
.price = 60
},
/* CALIBER_556MMBOX */
{
.a_size = 30,
.a_max = AMMO_MAX_556MMBOX,
.price = 60
},
/* CALIBER_338MAG */
{
.a_size = 10,
.a_max = AMMO_MAX_338MAG,
.price = 125
},
/* CALIBER_9MM */
{
.a_size = 30,
.a_max = AMMO_MAX_9MM,
.price = 20
},
/* CALIBER_BUCKSHOT */
{
.a_size = 8,
.a_max = AMMO_MAX_BUCKSHOT,
.price = 65
},
/* CALIBER_45ACP */
{
.a_size = 12,
.a_max = AMMO_MAX_45ACP,
.price = 25
},
/* CALIBER_357SIG */
{
.a_size = 13,
.a_max = AMMO_MAX_357SIG,
.price = 50
},
/* CALIBER_57MM */
{
.a_size = 50,
.a_max = AMMO_MAX_57MM,
.price = 50
}
};
#endif
int
Ammo_BuyCaliber(CSPlayer pl, int cal, int free)
{
int *ptr_ammo = __NULL__;
int rv = 0;
#if 0
while (pl.money - cs_ammoinfo[cal].price > 0 || free) {
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;
}
#endif
return rv;
}
void
Ammo_BuySecondary(NSClientPlayer pp, int free)
{
#if 0
int cal = 0;
int ps = 0;
CSPlayer pl = (CSPlayer)pp;
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 && !free) {
Sound_Play(pl, CHAN_ITEM, "buy.ammo");
}
Weapons_RefreshAmmo(pl);
#endif
}
/* 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)
{
CSPlayer pl = (CSPlayer)self;
CSGameRules rules = (CSGameRules)g_grMode;
if (rules.BuyingPossible(pl) == FALSE) {
return;
}
Ammo_BuySecondary(pl, FALSE);
}
void
Ammo_BuyPrimary(NSClientPlayer pp, int free)
{
#if 0
int ps = 0;
int cal = 0;
CSPlayer pl = (CSPlayer)pp;
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;
#if defined(CZERO) || defined(CSSOURCE)
case WEAPON_GALIL:
cal = CALIBER_762MM;
break;
case WEAPON_FAMAS:
cal = CALIBER_762MM;
break;
#endif
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, free) == 1) {
ps = 1;
}
}
}
if (ps && !free) {
Sound_Play(pl, CHAN_ITEM, "buy.ammo");
}
Weapons_RefreshAmmo(pl);
#endif
}
void
CSEv_AmmoBuyPrimary(void)
{
CSPlayer pl = (CSPlayer)self;
CSGameRules rules = (CSGameRules)g_grMode;
if (rules.BuyingPossible(pl) == FALSE) {
return;
}
//Ammo_BuyPrimary(pl, FALSE);
}
void
Ammo_AutoFill(NSClientPlayer pp)
{
CSPlayer pl = (CSPlayer)pp;
if (autocvar_fcs_fillweapons == FALSE) {
return;
}
//Ammo_BuyPrimary(pl, true);
//Ammo_BuySecondary(pl, true);
}
void
Ammo_Clear(void)
{
}

View file

@ -183,8 +183,8 @@ armoury_entity::Touch(entity eToucher)
}
/* we may need a helmet though */
if (!(pl.g_items & ITEM_HELMET) && m_iID == 17) {
pl.g_items |= ITEM_HELMET;
if (pl.HasItem("item_kevlar_helmet") == false && m_iID == 17) {
pl.GiveItem("item_kevlar_helmet");
picked_up = true;
}

View file

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

View file

@ -1,587 +0,0 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/** @brief Get the absolute center pos of a entity */
vector getEntityCenterPos(entity e) {
vector newVec;
newVec[0] = e.absmin[0] + (0.5 * (e.absmax[0] - e.absmin[0]));
newVec[1] = e.absmin[1] + (0.5 * (e.absmax[1] - e.absmin[1]));
newVec[2] = e.absmin[2] + (0.5 * (e.absmax[2] - e.absmin[2]));
return newVec;
}
class csbot:NSBot
{
void(void) csbot;
/* some objectives */
virtual void(void) RunToConfront;
virtual void(void) RunToBomb;
virtual void(int) RunToBombsite;
virtual void(void) RunToRandomBombsite;
virtual void(int) RunToEscapeZone;
virtual void(void) RunToRandomEscapeZone;
virtual void(int) RunToVIPSafetyZone;
virtual void(void) RunToRandomVIPSafetyZone;
virtual void(void) RunToHostages;
virtual void(vector, int) Roam;
virtual void(void) CreateObjective;
virtual void(void) PostFrame;
virtual void(void) WeaponThink;
/* helpers */
virtual entity(string, int) GetEntityByNameAndIndex;
virtual entity(int) GetBombsiteByIndex;
virtual entity(int) GetEscapeZoneByIndex;
virtual entity(int) GetVIPSafetyZoneByIndex;
virtual void(vector, float) AimLerp;
int m_actionIsPlanting;
int m_actionIsDefusing;
/* Workaround:
* gflags is not yet set when CSBot_BuyStart_Shop() or CreateObjective()
* are called, so we back it up on PostFrame() and use that instead.
* Known issues it solves:
* - Check if the bot is in a Bomb Zone (gflags & GF_BOMBZONE)
* - Check if the bot is in a Buy Zone (gflags & GF_BUYZONE) */
int m_gflagsBackup;
};
void
csbot::RunToConfront(void)
{
entity t;
if (team == TEAM_T) {
t = Route_SelectRandom("info_player_start");
} else {
t = Route_SelectRandom("info_player_deathmatch");
}
ChatSayTeam("Going to run to the Enemy Spawn!");
if (t)
RouteToPosition(t.origin);
}
/* go to the planted bomb */
void
csbot::RunToBomb(void)
{
entity e = world;
e = find(e, ::model, "models/w_c4.mdl");
if (e) {
RouteToPosition(e.origin);
ChatSayTeam("Going to run to the Bomb!");
}
}
/* go to given bombsite */
void
csbot::RunToBombsite(int bombsiteIndex)
{
entity e = GetBombsiteByIndex(bombsiteIndex);
RouteToPosition(getEntityCenterPos(e));
ChatSayTeam(strcat("Going to run to Bomb Site ", itos(bombsiteIndex), "!"));
}
/* go to random bombsite */
void
csbot::RunToRandomBombsite(void)
{
RunToBombsite(random(0, g_cs_bombzones));
}
/* go to given escape zone */
void
csbot::RunToEscapeZone(int index)
{
entity e = GetEscapeZoneByIndex(index);
RouteToPosition(getEntityCenterPos(e));
ChatSayTeam(strcat("Going to run to Escape Zone ", itos(index), "!"));
}
/* go to a random escape zone */
void
csbot::RunToRandomEscapeZone(void)
{
RunToEscapeZone(random(0, g_cs_escapezones));
}
/* go to given VIP Safety Zone */
void
csbot::RunToVIPSafetyZone(int index)
{
entity e = GetVIPSafetyZoneByIndex(index);
RouteToPosition(getEntityCenterPos(e));
ChatSayTeam(strcat("Going to run to VIP Safety Zone ", itos(index), "!"));
}
/* go to a random VIP Safety Zone */
void
csbot::RunToRandomVIPSafetyZone(void)
{
RunToVIPSafetyZone(random(0, g_cs_vipzones));
}
void
csbot::RunToHostages(void)
{
entity e = world;
e = find(e, ::classname, "hostage_entity");
RouteToPosition(e.origin);
ChatSayTeam("Going to run to the hostages!");
}
/** @brief Let the bot roam within a maximum distance from a given origin. */
void csbot::Roam(vector roamOrigin, int maxDistance) {
/* Get random point whitin a radius from the given origin */
int angle = random(0, 360); /* random angle. */
int distance = random(0, maxDistance); /* random distance */
float radian = angle * 3.145238095238 / 180;
vector randLoc = roamOrigin;
randLoc.x += sin(radian) * distance;
randLoc.y += cos(radian) * distance;
/* Go to the random waypoint. */
RouteToPosition(Nodes_PositionOfClosestNode(randLoc));
}
void
csbot::CreateObjective(void)
{
/* Bomb defuse map */
if (g_cs_bombzones > 0) {
/* Bomb is planted */
if (g_cs_bombplanted) {
entity eBomb = find(world, ::model, "models/w_c4.mdl");
if (eBomb == world) {
/* No bomb model found, but it is/was planted */
/* RoundOver: Bomb is defused */
if (g_cs_gamestate == GAME_END) {
RunToRandomBombsite();
return;
}
/* Error */
print("WARNING! g_cs_bombplanted == TRUE, but bomb model "
"cannot be found in the world.\n");
return;
}
if (team == TEAM_CT) {
if (g_cs_bombbeingdefused && m_actionIsDefusing == FALSE) {
/* Bomb is being defused but not by this bot */
/* Go and roam the defuser */
Roam(eBomb.origin, 300);
return;
}
if (m_actionIsDefusing) {
if (!g_cs_bombbeingdefused) {
/* Defusing complete or somehow failed. */
m_actionIsDefusing = FALSE;
} else {
/* Continue defusing. */
input_buttons |= (INPUT_BUTTON5 | INPUT_BUTTON8);
input_movevalues = [0,0,0];
button5 = input_buttons & INPUT_BUTTON5; // don't release button5
}
}
else {
int distToBomb = floor(vlen(eBomb.origin - origin));
if (distToBomb > 60) {
/* To far away from the bomb to defuse it, run to it! */
RunToBomb();
} else {
/* Aim at the bomb. */
input_buttons |= INPUT_BUTTON8; // duck
if ((HasVFlags(VFL_ONUSABLE))) {
// Aimed at the bomb, ready to defuse!
ChatSayTeam("Defusing!");
input_buttons |= INPUT_BUTTON5;
input_movevalues = [0,0,0];
button5 = input_buttons & INPUT_BUTTON5; // don't release button5
m_actionIsDefusing = TRUE;
} else {
// Do the real aiming
float flLerp = bound(0.0f, frametime * 45, 1.0f); // aim speed
AimLerp(eBomb.origin + [0, 0, -6], flLerp);
}
}
}
}
/* team == TEAM_T */
else {
/* Let T bots roam around the planted bomb */
Roam(eBomb.origin, 500);
}
return;
}
/* Bomb is NOT planted */
else {
if (team == TEAM_T) {
/* T-bot: plant bomb */
if (HasItem("weapon_c4")) {
/* We carry the bomb */
if (m_gflagsBackup & GF_BOMBZONE) {
/* We are at a bombsite and ready to plant the bomb */
if (GetCurrentWeapon() != "weapon_c4") {
/* TODO: REPLACE THIS WITH NSNAVAI METHOD */
SwitchToWeapon("weapon_c4");
//Weapons_Draw((CSPlayer)self);
}
if (!m_actionIsPlanting) {
ChatSayTeam("Going to plant the bomb!");
m_actionIsPlanting = TRUE;
}
/* Workaround */
gflags = m_gflagsBackup;
/* Duck and plant bomb. */
input_buttons = (INPUT_BUTTON0 | INPUT_BUTTON8);
input_movevalues = [0,0,0];
}
else {
/* Go to a bombsite first */
RunToRandomBombsite();
}
return;
}
else {
/* T-bot: check if the bomb has been dropped */
entity e = find(world, ::model, "models/w_backpack.mdl");
if (e != world) {
/* The bomb backpack has been dropped */
/* Go fetch dropped bomb! */
ChatSayTeam("Arrr! Bomb on the ground, going to fetch it!");
RouteToPosition(getEntityCenterPos(e));
return;
}
}
}
}
}
if (g_cs_escapezones && team == TEAM_T) {
RunToRandomEscapeZone();
return;
}
if (random() < 0.5 && g_cs_escapezones > 0 && team == TEAM_CT) {
RunToRandomEscapeZone();
return;
}
if (g_cs_vipzones > 0 && team == TEAM_CT) {
RunToRandomVIPSafetyZone();
return;
}
if (random() < 0.5 && g_cs_vipzones > 0 && team == TEAM_T) {
RunToRandomVIPSafetyZone();
return;
}
if (random() < 0.5) {
if (g_cs_hostagestotal > 0)
RunToHostages();
if (g_cs_bombzones > 0)
RunToRandomBombsite();
} else {
RunToConfront();
}
}
/** @brief Aim towards a given (vector)aimpos with a given (float)lerp speed.
*
* @note
* Copied code from nuclide botlib (inside bot::RunAI), maybe make this a
* method there, could be usefull for other stuff?
**/
void csbot::AimLerp(vector aimpos, float flLerp) {
vector aimdir, vecNewAngles;
vector oldAngle = v_angle;
/* that's the old angle */
vecNewAngles = anglesToForward(v_angle);
/* aimdir = new final angle */
aimdir = vectorToAngles(aimpos - origin);
/* slowly lerp towards the final angle */
vecNewAngles = vectorLerp(vecNewAngles, anglesToForward(aimdir), flLerp);
/* make sure we're aiming tight */
v_angle = vectorToAngles(vecNewAngles);
input_angles = angles = v_angle = fixAngle(v_angle);
}
void
csbot::PostFrame(void)
{
if (team == 0) {
CSEv_JoinAuto();
}
team = infokeyf(this, "*team");
m_gflagsBackup = gflags;
};
void
csbot::WeaponThink(void)
{
if (GetCurrentWeapon() == "weapon_knife")
return;
#if FIXME
/* clip empty */
if (a_ammo1 == 0) {
/* still got ammo left, reload! */
if (a_ammo2 != 0) {
input_buttons &= ~INPUT_BUTTON0;
input_buttons |= INPUT_BUTTON4;
} else {
Weapons_SwitchBest(this);
}
}
#endif
};
/** @brief Get entity by class name and index **/
entity
csbot::GetEntityByNameAndIndex(string name, int index)
{
int curIndex = 0;
for (entity a = world; (a = find(a, ::classname, name));) {
if (curIndex == index) {
return a;
}
++curIndex;
}
print("WARNING: cstrike/server/bot.qc GetEntityByNameAndIndex: no entity '",
name, "' with index ", itos(index), "!\n");
return world;
}
/** @brief Get bombsite entity by bombsite index
*
* @note
* When there are for example 2 bombsites (g_cs_bombzones == 2) then valid
* indexes would be 0 and 1.
* */
entity
csbot::GetBombsiteByIndex(int index)
{
return GetEntityByNameAndIndex("func_bomb_target", index);
}
/** @brief Get Escape Zone entity by index **/
entity
csbot::GetEscapeZoneByIndex(int index)
{
return GetEntityByNameAndIndex("func_escapezone", index);
}
/** @brief Get VIP Safety Zone entity by index **/
entity
csbot::GetVIPSafetyZoneByIndex(int index)
{
return GetEntityByNameAndIndex("func_vip_safetyzone", index);
}
void
csbot::csbot(void)
{
targetname = "_csbot_";
team = infokeyf(this, "*team");
m_actionIsPlanting = FALSE;
m_actionIsDefusing = FALSE;
m_gflagsBackup = 0;
}
void
CSBot_BombPlantedNotify(void)
{
for (entity a = world; (a = find(a, classname, "player"));) {
if (clienttype(a) != CLIENTTYPE_REAL) {
csbot targ;
targ = (csbot)a;
if (targ.team == TEAM_T)
continue;
if (targ.health <= 0)
continue;
targ.RunToRandomBombsite();
}
}
}
void
CSBot_HostageRescueNotify(void)
{
for (entity a = world; (a = find(a, classname, "player"));) {
if (clienttype(a) != CLIENTTYPE_REAL) {
csbot targ;
targ = (csbot)a;
if (targ.team == TEAM_T)
continue;
if (targ.health <= 0)
continue;
targ.RunToHostages();
}
}
}
void
CSBot_BuyStart_Shop(void)
{
int done = 0;
int count = 0;
CSPlayer pl = (CSPlayer)self;
pl.team = infokeyf(pl, "*team");
/* Workaround */
pl.gflags = ((csbot)pl).m_gflagsBackup;
count = 0;
while (done != 1) {
int r = floor(random(1,17));
if (pl.team == TEAM_T) {
if (r == BUY_M4A1) { continue; }
if (r == BUY_AUG) { continue; }
if (r == BUY_SG550) { continue; }
if (r == BUY_FIVESEVEN) { continue; }
if (r == BUY_TMP) { continue; }
} else if (pl.team == TEAM_CT) {
if (r == BUY_AK47) { continue; }
if (r == BUY_SG552) { continue; }
if (r == BUY_G3SG1) { continue; }
if (r == BUY_ELITES) { continue; }
if (r == BUY_MAC10) { continue; }
}
if (cs_buyprices[r] <= pl.money) {
CSEv_CSBuy_f((float)r);
done = 1;
}
count++;
/* give it enough attempts */
if (count > 17)
done = 1;
}
/* CT: Random buy bomb defuse kit when enough money left */
if (pl.team == TEAM_CT && g_cs_bombzones > 0 &&
cs_buyprices[BUY_DEFUSALKIT] <= pl.money &&
random() < 0.5)
{
CSEv_CSBuy_f(BUY_DEFUSALKIT); // ITEM_DEFUSAL
}
/* need armor */
if (pl.armor < 100) {
if (pl.money >= cs_buyprices[1]) /* kevlar and helmet */
CSEv_CSBuy_f(BUY_VESTHELMET);
else if (pl.money >= cs_buyprices[0]) /* just kevlar */
CSEv_CSBuy_f(BUY_VEST);
} else if (!(pl.g_items & ITEM_HELMET)) { /* we need helmet */
if (pl.money >= 350) /* kevlar and helmet */
CSEv_CSBuy_f(BUY_VESTHELMET);
}
#if FIXME
/* make SURE we switch to it */
for (int i = 0; i < g_weapons.length; i++)
if (pl.g_items & g_weapons[i].id) {
pl.activeweapon = i;
Weapons_Draw(pl);
return;
}
#endif
/* force buy right now */
CSEv_CSBuy_f(BUY_PRIMARYAMMO);
CSEv_CSBuy_f(BUY_SECONDARYAMMO);
}
void
CSBot_BuyStart(void)
{
for (entity a = world; (a = find(a, classname, "player"));) {
if (clienttype(a) != CLIENTTYPE_REAL) {
if (a.health <= 0)
continue;
a.think = CSBot_BuyStart_Shop;
a.nextthink = time + random(0, autocvar_mp_freezetime);
}
}
}
void
CSBot_RoundStart(void)
{
/* if (g_cs_bombzones <= 0) {
return;
}
for (entity a = world; (a = find(a, classname, "player"));) {
if (clienttype(a) != CLIENTTYPE_REAL) {
csbot targ;
targ = (csbot)a;
if (targ.team == TEAM_T)
continue;
if (targ.health <= 0)
continue;
targ.RunToRandomBombsite();
}
}
} */
}
void
CSBot_RestartRound(void)
{
// Reset some variables for all bots
for (entity a = world; (a = find(a, classname, "player"));) {
if (clienttype(a) != CLIENTTYPE_REAL) {
csbot targ;
targ = (csbot)a;
if (targ.team == TEAM_T) {
targ.m_actionIsPlanting = FALSE;
}
else {
targ.m_actionIsDefusing = FALSE;
}
}
}
}

View file

@ -1,56 +0,0 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* values courtesy of https://wiki.alliedmods.net/Cs_weapons_information */
int cs_buyprices[] =
{
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 */
0, /* padding */
0, /* padding */
650, /* Kevlar Vest */
1000, /* Kevlar Vest & Helmet */
200, /* Defuse Kit */
1250 /* NightVision Goggles */
};
void CSEv_CSBuy_f(float itemID);

View file

@ -1,180 +0,0 @@
/*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
CSEv_CSBuy_f(float fWeapon)
{
#if 0
CSGameRules rules = (CSGameRules)g_grMode;
int iWeapon;
CSPlayer pl = (CSPlayer)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");
if (autocvar_fcs_fillweapons) {
if (g_weapons[iWeapon].slot == 0)
Ammo_BuyPrimary(pl, TRUE);
else if (g_weapons[iWeapon].slot == 1)
Ammo_BuySecondary(pl, TRUE);
}
} else {
//centerprint(pl, "You have insufficient funds!");
}
#endif
}
void
CSEv_BuyEquipment_f(float fUtil)
{
#if 0
CSGameRules rules = (CSGameRules)g_grMode;
int iUtil;
CSPlayer pl = (CSPlayer)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 we already have a helmet, buy just armor */
if (pl.g_items & ITEM_HELMET && pl.armor >= 0) {
CSEv_BuyEquipment_f(0);
return;
} else if (!(pl.g_items & ITEM_HELMET) && pl.armor >= 100) { /* only need helmet, so add it */
pl.g_items |= ITEM_HELMET;
Money_AddMoney(pl, -350);
Sound_Play(pl, CHAN_ITEM, "buy.kevlar");
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.m_bHasNightvision == true)
return;
pl.m_bHasNightvision = true;
Sound_Play(pl, CHAN_ITEM, "buy.weapon");
break;
}
Money_AddMoney(pl, -g_cstrikeUtilPrice[iUtil]);
} else {
centerprint(pl, "You have insufficient funds!");
}
#endif
}

View file

@ -14,47 +14,9 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ammo.h"
#include "bot.h"
#include "buy.h"
#include "gamerules.h"
#include "money.h"
#include "radio.h"
#include "../../../valve/src/server/items.h"
#include "../../../valve/src/server/flashlight.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_bombbeingdefused;
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_total_t;
var int g_cs_total_ct;
var int g_total_players;
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;

View file

@ -38,7 +38,6 @@ func_bomb_target:NSBrushTrigger
void
func_bomb_target::func_bomb_target(void)
{
g_cs_bombzones++;
}
void
@ -54,7 +53,7 @@ func_bomb_target::Touch(entity eToucher)
return;
}
if (g_csMode.ShowHints() && pl.m_seenBombSite == false) {
if (serverinfo.GetBool("cs_hints") && pl.m_seenBombSite == false) {
env_message_single(pl, "Hint_you_are_in_targetzone");
pl.m_seenBombSite = true;
}

View file

@ -84,7 +84,7 @@ func_buyzone::Touch(entity eToucher)
if (team == 0 || team == pl.team)
pl.gflags |= GF_BUYZONE;
if (g_csMode.ShowHints() == true)
if (serverinfo.GetBool("cs_hints") == true)
if (pl.m_buyMessage == false) {
env_message_single(pl, "Hint_press_buy_to_purchase");
pl.m_buyMessage = true;

View file

@ -38,7 +38,6 @@ func_escapezone:NSBrushTrigger
void
func_escapezone::func_escapezone(void)
{
g_cs_escapezones++;
}
void
@ -51,51 +50,14 @@ func_escapezone::Respawn(void)
void
func_escapezone::Touch(entity eToucher)
{
CSMultiplayerRules rule = (CSMultiplayerRules)g_grMode;
int to_escape = 0;
rule.CountPlayers();
to_escape = g_cs_total_t;
/* only 3 Ts need to escape, max */
if (to_escape > 3)
to_escape = 3;
CSPlayer pl = (CSPlayer)eToucher;
/* don't matter when rules are not active */
if (g_cs_gamestate != GAME_ACTIVE)
return;
/* disallow the wrong players */
if (pl.classname != "player")
return;
if (pl.team != TEAM_T)
return;
rule.m_iEscapedTerrorists++;
g_grMode.Input(eToucher, "Escaped", "");
/* balancing tweak: for every escaped T, each and every CT will lose funds */
if (autocvar_fcs_escapepenalty != 0) {
for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) {
CSPlayer ct = (CSPlayer)eFind;
if (ct.team == TEAM_CT) {
Money_AddMoney(ct, autocvar_fcs_escapepenalty);
}
}
}
/* mark player as spectator for the end of this 'round' */
pl.MakeTempSpectator();
pl.gflags &= ~GF_FLASHLIGHT;
/* threshold has been met to trigger the end of the round */
if (rule.m_iEscapedTerrorists >= to_escape) {
/* reset */
rule.m_iEscapedTerrorists = 0;
/* Ts win the round */
rule.RoundOver(TEAM_T, 3600, FALSE);
}
}

View file

@ -70,15 +70,7 @@ func_hostage_rescue::Touch(entity eToucher)
if (!(hosty.m_eFollowing))
return;
Radio_BroadcastMessage(RADIO_RESCUED);
g_cs_hostagesrescued++;
Money_AddMoney((CSPlayer)hosty.m_eFollowing, 1000);
CSBot_HostageRescueNotify();
/* 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);
g_grMode.Input(hosty.m_eFollowing, "HostageRescued", "");
hosty.Disappear();
}

View file

@ -38,7 +38,6 @@ class func_vip_safetyzone:NSBrushTrigger
void
func_vip_safetyzone::func_vip_safetyzone(void)
{
g_cs_vipzones++;
}
void
@ -50,12 +49,11 @@ func_vip_safetyzone::Respawn(void)
void
func_vip_safetyzone::Touch(entity eToucher)
{
CSMultiplayerRules rule = (CSMultiplayerRules)g_grMode;
CSPlayer pl = (CSPlayer)eToucher;
if (pl.classname != "player")
return;
#if 0
if (pl.team != TEAM_VIP)
return;
@ -67,4 +65,5 @@ func_vip_safetyzone::Touch(entity eToucher)
/* mark player as spectator for the end of this 'round' */
pl.MakeTempSpectator();
pl.gflags &= ~GF_FLASHLIGHT;
#endif
}

View file

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

View file

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

View file

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

View file

@ -1,115 +0,0 @@
/*
* Copyright (c) 2016-2021 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
CSGameRules::PlayerDeath(NSClientPlayer pl)
{
}
void
CSGameRules::PlayerPain(NSClientPlayer pl)
{
}
bool
CSGameRules::ShowHints(void)
{
return (true);
}
bool
CSGameRules::BuyingPossible(NSClientPlayer 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::PlayerPreFrame(NSClientPlayer pp)
{
pp.gflags &= ~GF_BUYZONE;
pp.gflags &= ~GF_RESCUEZONE;
pp.gflags &= ~GF_BOMBZONE;
}
void
CSGameRules::LevelDecodeParms(NSClientPlayer pp)
{
CSPlayer pl = (CSPlayer)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.gflags = parm63;
if (pl.IsCrouching()) {
setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX);
} else {
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
}
}
void
CSGameRules::LevelChangeParms(NSClientPlayer pp)
{
CSPlayer pl = (CSPlayer)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;
}
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;
}
bool
CSGameRules::ImpulseCommand(NSClient bp, float num)
{
switch (num) {
default:
return super::ImpulseCommand(bp, num);
}
return true;
}

View file

@ -1,292 +0,0 @@
/*
* Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
string
CSDeathmatchRules::Title(void)
{
return "Deathmatch";
}
bool
CSDeathmatchRules::ShowHints(void)
{
return (false);
}
bool
CSDeathmatchRules::IsMultiplayer(void)
{
return (true);
}
bool
CSDeathmatchRules::PlayerRequestRespawn(NSClientPlayer bp)
{
if (bp.TimeSinceDeath() > 0.5f) {
bp.ScheduleThink(PutClientInServer, 0.0f);
return (true);
}
return (false);
}
bool
CSDeathmatchRules::IsTeamplay(void)
{
return cvar("mp_teamplay") == 1 ? true : false;
}
void
CSDeathmatchRules::InitPostEnts(void)
{
MOTD_LoadDefault();
forceinfokey(world, "scorepoints", "0");
if (IsTeamplay() == true) {
forceinfokey(world, "teams", "2");
forceinfokey(world, "team_1", "Counter-Terrorist");
forceinfokey(world, "teamscore_1", "0");
forceinfokey(world, "team_2", "Terrorist");
forceinfokey(world, "teamscore_2", "0");
} else {
forceinfokey(world, "teams", "0");
}
}
void
CSDeathmatchRules::FrameStart(void)
{
if (cvar("timelimit"))
if (time >= (cvar("timelimit") * 60)) {
IntermissionStart();
}
IntermissionCycle();
}
void
CSDeathmatchRules::CheckRules(void)
{
/* last person who killed somebody has hit the limit */
if (cvar("fraglimit"))
if (g_dmg_eAttacker.frags >= cvar("fraglimit"))
IntermissionStart();
}
void
CSDeathmatchRules::PlayerDeath(NSClientPlayer pl)
{
/* obituary networking */
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_OBITUARY);
WriteString(MSG_MULTICAST, (g_dmg_eAttacker.netname) ? g_dmg_eAttacker.netname : g_dmg_eAttacker.classname);
WriteString(MSG_MULTICAST, pl.netname);
WriteByte(MSG_MULTICAST, g_dmg_iWeapon);
WriteByte(MSG_MULTICAST, 0);
msg_entity = world;
multicast([0,0,0], MULTICAST_ALL);
Plugin_PlayerObituary(g_dmg_eAttacker, g_dmg_eTarget, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage);
/* death-counter */
pl.deaths++;
pl.SetInfoKey("*deaths", ftos(pl.deaths));
/* update score-counter */
if (pl.flags & FL_CLIENT || pl.flags & FL_MONSTER)
if (g_dmg_eAttacker.flags & FL_CLIENT) {
if (pl == g_dmg_eAttacker)
g_dmg_eAttacker.frags--;
else
g_dmg_eAttacker.frags++;
}
#if 0
/* explode all satchels */
s_satchel_detonate((entity)pl);
/* drop their posessions into a weaponbox item */
weaponbox_spawn((CSPlayer)pl);
#endif
/* either gib, or make a corpse */
if (pl.health < -50) {
vector gibDir = vectoangles(pl.origin - g_dmg_eAttacker.origin);
float gibStrength = g_dmg_iDamage * 2.0f;
BreakModel_Entity(pl, gibDir, gibStrength);
} else {
FX_Corpse_Spawn((CSPlayer)pl, ANIM_DEATH1);
//FX_Corpse_Spawn((CSPlayer)pl, ANIM_DIESIMPLE);
}
/* now let's make the real client invisible */
//pl.Death();
pl.SetTakedamage(DAMAGE_NO);
pl.gflags &= ~GF_FLASHLIGHT;
Sound_Play(pl, CHAN_AUTO, "player.die");
/* force respawn */
pl.ScheduleThink(PutClientInServer, 4.0f);
/* have we gone over the fraglimit? */
CheckRules();
}
void
CSDeathmatchRules::PlayerSpawn(NSClientPlayer pp)
{
CSPlayer pl = (CSPlayer)pp;
/* this is where the mods want to deviate */
entity spot;
pl.classname = "player";
pl.SetMaxHealth(100);
pl.SetHealth(100);
pl.SetArmor(100);
pl.SetTakedamage(DAMAGE_YES);
pl.SetSolid(SOLID_SLIDEBOX);
pl.SetMovetype(MOVETYPE_WALK);
pl.AddFlags(FL_CLIENT);
pl.viewzoom = 1.0;
/* player model selection */
if (IsTeamplay() == true) {
int teamCount = tokenizebyseparator(m_strTeamList, ";");
int playerTeam = (int)pl.GetTeam();
/* not part of a team? pick one of the ones we have */
/* TODO: this should sort us into the lowest team */
if (playerTeam == 0) {
playerTeam = 1i + (int)floor(random(0, (float)teamCount)); /* teams start at 1 after all */
pl.SetTeam(random() < 0.5 ? TEAM_CT : TEAM_T);
}
if (playerTeam == TEAM_T)
pl.charmodel = floor(random(1,5));
else
pl.charmodel = floor(random(5,9));
} else {
pl.charmodel = rint(random(1,9));
}
switch (pl.charmodel) {
case 1:
pl.model = "models/player/terror/terror.mdl";
break;
case 2:
pl.model = "models/player/leet/leet.mdl";
break;
case 3:
pl.model = "models/player/arctic/arctic.mdl";
break;
case 4:
pl.model = "models/player/guerilla/guerilla.mdl";
break;
case 5:
pl.model = "models/player/urban/urban.mdl";
break;
case 6:
pl.model = "models/player/gsg9/gsg9.mdl";
break;
case 7:
pl.model = "models/player/sas/sas.mdl";
break;
case 8:
pl.model = "models/player/gign/gign.mdl";
break;
default:
pl.model = "models/player/vip/vip.mdl";
}
pl.SetModel(pl.model);
pl.SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
pl.ClearVelocity();
pl.gravity = __NULL__;
pl.SetFrame(1);
pl.SendFlags = UPDATE_ALL;
pl.SetInfoKey("*spec", "0");
pl.SetInfoKey("*dead", "0");
pl.SetInfoKey("*deaths", ftos(pl.deaths));
pl.SetPropData("actor_human");
pl.EnableBleeding();
LevelNewParms();
LevelDecodeParms(pl);
pl.GiveItem("item_suit");
pl.GiveItem("weapon_knife");
#if 0
int randomGun = (int)rint(random(WEAPON_USP45, WEAPON_FIVESEVEN));
//Weapons_AddItem(pl, randomGun, -1);
randomGun = (int)rint(random(WEAPON_M3, WEAPON_PARA));
//Weapons_AddItem(pl, randomGun, -1);
pl.activeweapon = randomGun;
#endif
Ammo_BuyPrimary(pl, TRUE);
Ammo_BuySecondary(pl, TRUE);
spot = Spawn_SelectRandom("info_player_deathmatch");
pl.Transport(spot.origin, spot.angles);
Client_FixAngle(pl, pl.angles);
}
bool
CSDeathmatchRules::ConsoleCommand(NSClientPlayer pp, string cmd)
{
tokenize(cmd);
switch (argv(0)) {
#if 0
case "bot_add":
bot pete = (bot)Bot_AddQuick();
Bot_RandomColormap(pete);
searchhandle pm = search_begin("models/player/*/*.mdl", TRUE, TRUE);
int r = floor(random(0, search_getsize(pm)));
string mdl = substring(search_getfilename(pm, r), 0, -5);
tokenizebyseparator(mdl, "/");
pete.SetInfoKey("model", argv(2));
search_end(pm);
break;
#endif
case "jumptest":
makevectors(pp.v_angle);
traceline(pp.origin + pp.view_ofs, pp.origin + pp.view_ofs + v_forward * 1024, FALSE, pp);
pp.velocity = Route_GetJumpVelocity(pp.origin, trace_endpos, pp.gravity);
break;
default:
return (false);
}
return (true);
}
bool
CSDeathmatchRules::MonstersSpawn(void)
{
return (autocvar(mp_allowmonsters, 0)) ? true : false;
}
void
CSDeathmatchRules::CSDeathmatchRules(void)
{
/* these lines do nothing but tell the server to register those cvars */
autocvar(timelimit, 15, "Timelimit for multiplayer rounds");
autocvar(fraglimit, 15, "Points limit for multiplayer rounds");
}

File diff suppressed because it is too large Load diff

View file

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

View file

@ -81,7 +81,7 @@ enum
class CSHostage:NSTalkMonster
{
int m_iUsedOnce;
bool m_bUsedOnce;
void CSHostage(void);
@ -91,13 +91,21 @@ class CSHostage:NSTalkMonster
};
void
CSHostage::CSHostage(void)
{
Sound_Precache("hostage_entity.follow");
m_bUsedOnce = false;
}
void
CSHostage::OnPlayerUse(void)
{
if (eActivator.team == TEAM_T) {
CSPlayer pl = (CSPlayer)eActivator;
if (g_csMode.ShowHints() == true)
if (serverinfo.GetBool("cs_hints") == true)
if (pl.m_hostMessageT == false) {
env_message_single(pl, "Only_CT_Can_Move_Hostages");
pl.m_hostMessageT = true;
@ -110,9 +118,9 @@ CSHostage::OnPlayerUse(void)
}
/* CT reward, first time only */
if (m_iUsedOnce == FALSE) {
Money_AddMoney((CSPlayer)eActivator, 150);
m_iUsedOnce = TRUE;
if (m_bUsedOnce == false) {
g_grMode.Input(eActivator, "HostageContacted", "");
m_bUsedOnce = true;
}
NSTalkMonster::OnPlayerUse();
@ -153,7 +161,7 @@ CSHostage::Pain(entity inflictor, entity attacker, int damageDealt, vector dir,
return;
}
Money_AddMoney((NSClientPlayer)attacker, -(damageDealt * 25i));
g_grMode.Input(attacker, "HostageInjured", itos(damageDealt));
}
void
@ -175,13 +183,7 @@ CSHostage::Death(entity inflictor, entity attacker, int damageDealt, vector dir,
}
if (isPlayer(attacker) == true) {
if (damageDealt >= 100) {
Money_AddMoney((NSClientPlayer)attacker, -2500);
} else {
Money_AddMoney((NSClientPlayer)attacker, -500);
}
Radio_BroadcastMessage(RADIO_HOSDOWN);
g_grMode.Input(attacker, "HostageKilled", itos(damageDealt));
}
}
@ -192,10 +194,3 @@ CSHostage::Death(entity inflictor, entity attacker, int damageDealt, vector dir,
super::Death(inflictor, attacker, damageDealt, dir, location);
SetSolid(SOLID_NOT);
}
void
CSHostage::CSHostage(void)
{
Sound_Precache("hostage_entity.follow");
g_cs_hostagestotal++;
}

View file

@ -72,14 +72,6 @@ info_hostage_rescue::Touch(entity eToucher)
if (!((CSPlayer)hosty.m_eFollowing))
return;
Radio_BroadcastMessage(RADIO_RESCUED);
CSBot_HostageRescueNotify();
g_cs_hostagesrescued++;
Money_AddMoney((CSPlayer)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);
g_grMode.Input(hosty.m_eFollowing, "HostageRescued", "");
hosty.Disappear();
}

View file

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

View file

@ -1,6 +1,6 @@
#pragma target fte_5768
//#pragma flag enable assumeint
#pragma progs_dat "../../zpak001.pk3dir/progs.dat"
#pragma progs_dat "../../progs.dat"
#define QWSSQC
#define SERVER
@ -30,17 +30,7 @@ info_hostage_rescue.qc
func_vip_safetyzone.qc
info_map_parameters.qc
../../../src/botlib/include.src
bot.qc
game_money.qc
gamerules.qc
gamerules_singleplayer.qc
gamerules_deathmatch.qc
gamerules_multiplayer.qc
radio.qc
ammo.qc
buy.qc
server.qc
../../../valve/src/server/flashlight.qc
../../../src/server/include.src
../../../src/shared/include.src
#endlist

View file

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

View file

@ -52,8 +52,6 @@ Radio_TeamMessage(float fMessage, float fTeam)
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);
}
}
}
@ -131,15 +129,11 @@ CSEv_Radio_f(float fMessage)
// 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, self, eFind);
} else if (eFind.team == TEAM_VIP && fTargetTeam == TEAM_CT) {
CSEv_Radio_Send(fMessage, self, eFind);
}
}

View file

@ -18,30 +18,19 @@ void
Game_InitRules(void)
{
if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) {
g_grMode = spawn(CSSingleplayerRules);
g_grMode = NSGameRules::InitFromProgs("progs/singleplayer.dat");
} else {
if (cvar("fcs_deathmatch") == 1) {
g_grMode = spawn(CSDeathmatchRules);
g_grMode = NSGameRules::InitFromProgs("progs/deathmatch.dat");
} else {
g_grMode = spawn(CSMultiplayerRules);
g_grMode = NSGameRules::InitFromProgs("progs/counterstrike.dat");
}
}
g_csMode = (CSGameRules)g_grMode;
}
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");
@ -54,17 +43,5 @@ Game_Worldspawn(void)
Sound_Precache("Player.FlashLightOff");
Sound_Precache("Player.FlashLightOn");
/* 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");
FX_Corpse_Init();
clientstat(STAT_MONEY, EV_INTEGER, CSPlayer::money);
clientstat(STAT_PROGRESS, EV_FLOAT, CSPlayer::progress);
pointerstat(STAT_GAMETIME, EV_FLOAT, &g_cs_gametime);
pointerstat(STAT_GAMESTATE, EV_INTEGER, &g_cs_gamestate);
}

View file

@ -40,7 +40,7 @@ void Animation_Print(string sWow) {
}
void
Animation_TimerUpdate(CSPlayer pl, float ftime)
Animation_TimerUpdate(HLPlayer pl, float ftime)
{
makevectors([0, pl.v_angle[1], 0]);
@ -65,7 +65,7 @@ depending on what the player is doing
=================
*/
void
Animation_PlayerUpdate(CSPlayer pl)
Animation_PlayerUpdate(HLPlayer pl)
{
pl.basebone = gettagindex(pl, "-- R shoulder outside");
@ -128,7 +128,7 @@ Animation_PlayerUpdate(CSPlayer pl)
}
void
Animation_PlayerTop(CSPlayer pl, float topanim, float timer)
Animation_PlayerTop(HLPlayer pl, float topanim, float timer)
{
#if 0
pl.anim_top = topanim;
@ -138,7 +138,7 @@ Animation_PlayerTop(CSPlayer pl, float topanim, float timer)
}
void
Animation_PlayerBottom(CSPlayer pl, float botanim, float timer)
Animation_PlayerBottom(HLPlayer pl, float botanim, float timer)
{
pl.anim_bottom = botanim;
}

View file

@ -17,16 +17,13 @@
#include "animations.h"
#include "radio.h"
#include "buying.h"
#include "items.h"
#include "entities.h"
#include "events.h"
#include "CSProjectile.h"
#include "../../../valve/src/shared/HLWeapon.h"
#define TEAM_SPECTATOR 0
#define TEAM_T 1
#define TEAM_CT 2
#define TEAM_VIP 3
enum
{

View file

@ -1,19 +1,18 @@
#includelist
flags.h
player.h
animations.h
animations.qc
item_c4bomb.h
../../../cstrike/src/shared/flags.h
../../../cstrike/src/shared/skeleton.h
../../../valve/src/shared/player.qc
../../../cstrike/src/shared/player.h
../../../cstrike/src/shared/animations.h
../../../cstrike/src/shared/animations.qc
../../../cstrike/src/shared/item_c4bomb.h
../../../valve/src/shared/fx_blood.qc
../../../valve/src/shared/fx_corpse.qc
fx_flashbang.qc
fx_smokenade.qc
item_c4bomb.qc
weapons_cstrike.qc
CSProjectile.qc
../../../cstrike/src/shared/fx_flashbang.qc
../../../cstrike/src/shared/fx_smokenade.qc
../../../cstrike/src/shared/item_c4bomb.qc
../../../cstrike/src/shared/weapons_cstrike.qc
../../../cstrike/src/shared/CSProjectile.qc
../../../valve/src/shared/HLWeapon.qc
CSWeapon.qc
pmove.qc
../../../cstrike/src/shared/CSWeapon.qc
#endlist

View file

@ -98,8 +98,6 @@ CSBombEntity::OnPlayerUse(void)
void
CSBombEntity::Logic(void)
{
CSMultiplayerRules rules = (CSMultiplayerRules)g_grMode;
/* check if we're being used */
if (m_eUser != world) {
CSPlayer pl = (CSPlayer)m_eUser;
@ -111,11 +109,11 @@ CSBombEntity::Logic(void)
/* clear user */
m_eUser = world;
m_flDefusalState = 0.0f;
g_cs_bombbeingdefused = FALSE;
serverinfo.SetBool("cs_bombbeingdefused", false);
} else {
/* defusal kit always cuts the time in half */
if (pl.g_items & ITEM_DEFUSAL)
if (pl.HasItem("item_defuse"))
m_flDefusalState += (frametime * 2);
else
m_flDefusalState += frametime;
@ -123,15 +121,13 @@ CSBombEntity::Logic(void)
/* tracked stat */
pl.progress = m_flDefusalState;
pl.AddVFlags(VFL_FROZEN);
g_cs_bombbeingdefused = TRUE;
serverinfo.SetBool("cs_bombbeingdefused", true);
}
}
if (m_flDefusalState > 10.0f) {
StartSoundDef("weapon_c4bomb.disarmed", CHAN_VOICE, true);
rules.RoundOver(TEAM_CT, 3600, TRUE);
Radio_BroadcastMessage(RADIO_BOMBDEF);
g_grMode.Input(m_eUser, "BombDisarmed", "");
Destroy();
return;
}
@ -140,12 +136,9 @@ CSBombEntity::Logic(void)
if (m_flExplodeTime < time) {
float bestDist = 9999.0f;
NSEntity bestTarget = __NULL__;
g_grMode.Input(m_eUser, "BombExploded", "");
/* In Bomb Defusal, all Terrorists receive $3500
* if they won by detonating the bomb. */
rules.RoundOver(TEAM_T, 3500, FALSE);
radiusDamage(origin, -g_cstrike_bombradius, 0i, 500i, real_owner);
combat.RadiusDamage(origin, -g_cstrike_bombradius, 0i, 500i, real_owner, "");
//Damage_Radius(origin, this.real_owner, 500, g_cstrike_bombradius, false, WEAPON_C4BOMB);
@ -193,8 +186,8 @@ CSBombEntity::OnRemoveEntity(void)
ClearProgress();
m_flBeepTime = 0.0f;
m_flDefusalState = 0;
g_cs_bombbeingdefused = FALSE;
g_cs_bombplanted = false;
serverinfo.SetBool("cs_bombbeingdefused", false);
serverinfo.SetBool("cs_bombplanted", false);
}
void
@ -214,6 +207,7 @@ CSBombEntity::Spawned(void)
PlayerUse = OnPlayerUse;
m_flExplodeTime = time + 45.0f;
StartSoundDef("c4.plant", CHAN_WEAPON, true);
serverinfo.SetBool("cs_bombplanted", true);
}
#endif

View file

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

View file

@ -14,88 +14,47 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef CLIENT
/* Here's a list of bone names that we are aware of on HL player models.
Usually we'd use skeletalobjects to share the same skeleton/anim with
another model - but because FTEQW does not support that for HLMDL we
are forced to manually position the bones of our attachnment
by iterating over them and manually setting their position in 3D-space.
*/
string g_pbones[] =
/** @brief Get entity by class name and index **/
NSEntity
GetEntityByNameAndIndex(string name, int index)
{
"Bip01",
"Bip01 Footsteps",
"Bip01 Pelvis",
"Bip01 L Leg",
"Bip01 L Leg1",
"Bip01 L Foot",
"Bip01 L Toe0",
"Bip01 L Toe01",
"Bip01 L Toe02",
"Dummy16",
"Bip01 R Leg",
"Bip01 R Leg1",
"Bip01 R Foot",
"Bip01 R Toe0",
"Bip01 R Toe01",
"Bip01 R Toe02",
"Dummy11",
"Bip01 Spine",
"Bip01 Spine1",
"Bip01 Spine2",
"Bip01 Spine3",
"Bip01 Neck",
"Bip01 Head",
"Dummy21",
"Dummy08",
"Bone02",
"Bone03",
"Bone04",
"Dummy05",
"Bone09",
"Bone10",
"Dummy04",
"Bone05",
"Bone06",
"Dummy03",
"Bone07",
"Bone08",
"Dummy09",
"Bone11",
"Bone12",
"Dummy10",
"Bone13",
"Bone14",
"Bone15",
"Bip01 L Arm",
"Bip01 L Arm1",
"Bip01 L Arm2",
"Bip01 L Hand",
"Bip01 L Finger0",
"Bip01 L Finger01",
"Bip01 L Finger02",
"Dummy06",
"Bip01 L Finger1",
"Bip01 L Finger11",
"Bip01 L Finger12",
"Dummy07",
"Bip01 R Arm",
"Bip01 R Arm1",
"Bip01 R Arm2",
"Bip01 R Hand",
"Bip01 R Finger0",
"Bip01 R Finger01",
"Bip01 R Finger02",
"Dummy01",
"Bip01 R Finger1",
"Bip01 R Finger11",
"Bip01 R Finger12",
"Dummy02",
"Box02",
"Bone08",
"Bone15"
};
#endif
int curIndex = 0;
for (entity a = world; (a = find(a, ::classname, name));) {
if (curIndex == index) {
return (NSEntity)a;
}
++curIndex;
}
print("WARNING: cstrike/server/bot.qc GetEntityByNameAndIndex: no entity '",
name, "' with index ", itos(index), "!\n");
return __NULL__;
}
/** @brief Get bombsite entity by bombsite index
*
* @note
* When there are for example 2 bombsites (g_cs_bombzones == 2) then valid
* indexes would be 0 and 1.
* */
NSEntity
GetBombsiteByIndex(int index)
{
return GetEntityByNameAndIndex("func_bomb_target", index);
}
/** @brief Get Escape Zone entity by index **/
NSEntity
GetEscapeZoneByIndex(int index)
{
return GetEntityByNameAndIndex("func_escapezone", index);
}
/** @brief Get VIP Safety Zone entity by index **/
NSEntity
GetVIPSafetyZoneByIndex(int index)
{
return GetEntityByNameAndIndex("func_vip_safetyzone", index);
}
/* all potential SendFlags bits we can possibly send */
enumflags
@ -105,27 +64,23 @@ enumflags
PLAYER_CSTIMERS = PLAYER_CUSTOMFIELDSTART
};
class CSPlayer:NSClientPlayer
class
CSPlayer:HLPlayer
{
int ingame;
void CSPlayer(void);
PREDICTED_FLOAT(cs_shotmultiplier)
PREDICTED_FLOAT(cs_shottime)
PREDICTED_FLOAT(cs_prev_hor_rec)
PREDICTED_INT(cs_hor_rec_sign)
PREDICTED_FLOAT(cs_rec_reverse_chance)
PREDICTED_FLOAT(anim_top)
PREDICTED_FLOAT(anim_top_time)
PREDICTED_FLOAT(anim_top_delay)
PREDICTED_FLOAT(anim_bottom)
PREDICTED_FLOAT(anim_bottom_time)
virtual void(float) Physics_Fall;
virtual void(void) Physics_Jump;
virtual void(void) Physics_InputPostMove;
virtual void UpdatePlayerAnimation(float);
#ifdef CLIENT
int playertype;
@ -134,17 +89,29 @@ class CSPlayer:NSClientPlayer
int cs_cross_deltadist;
float cs_crosshairdistance;
virtual void UpdatePlayerAttachments(bool);
virtual void ReceiveEntity(float, float);
virtual void PredictPreFrame(void);
virtual void PredictPostFrame(void);
virtual void UpdateAliveCam(void);
virtual void ClientInputFrame(void);
#else
virtual void Input(entity, string, string);
virtual void ServerInputFrame(void);
virtual void EvaluateEntity(void);
virtual float SendEntity(entity, float);
nonvirtual void Bot_RunToConfront(void);
nonvirtual void Bot_RunToBomb(void);
nonvirtual void Bot_RunToBombsite(int);
nonvirtual void Bot_RunToRandomBombsite(void);
nonvirtual void Bot_RunToEscapeZone(int);
nonvirtual void Bot_RunToRandomEscapeZone(void);
nonvirtual void Bot_RunToVIPSafetyZone(int);
nonvirtual void Bot_RunToRandomVIPSafetyZone(void);
nonvirtual void Bot_RunToHostages(void);
nonvirtual void Bot_Roam(vector, int);
nonvirtual void Bot_CreateObjective(void);
nonvirtual void Bot_Buy(void);
nonvirtual void Bot_AimLerp(vector, float);
int charmodel;
int money;
float progress;
@ -156,9 +123,54 @@ class CSPlayer:NSClientPlayer
bool m_seenHostage;
bool m_seenBombSite;
bool m_bHasNightvision;
/* bot related vars */
int m_actionIsPlanting;
int m_actionIsDefusing;
/* Workaround:
* gflags is not yet set when CSBot_BuyStart_Shop() or Bot_CreateObjective()
* are called, so we back it up on PostFrame() and use that instead.
* Known issues it solves:
* - Check if the bot is in a Bomb Zone (gflags & GF_BOMBZONE)
* - Check if the bot is in a Buy Zone (gflags & GF_BUYZONE) */
int m_gflagsBackup;
#endif
};
void
CSPlayer::CSPlayer(void)
{
ingame = false;
cs_shotmultiplier = 0;
cs_shottime = 0;
cs_prev_hor_rec = 0;
cs_hor_rec_sign = 0;
cs_rec_reverse_chance = 0;
#ifdef CLIENT
playertype = 0;
cs_cross_mindist = 0;
cs_cross_deltadist = 0;
cs_crosshairdistance = 0;
#else
charmodel = 0;
money = 0;
progress = 0;
m_buyMessage = 0;
m_hostMessageT = 0;
m_seenFriend = 0;
m_seenEnemy = 0;
m_seenHostage = 0;
m_seenBombSite = 0;
m_bHasNightvision = 0;
/* bot related maps */
m_actionIsPlanting = FALSE;
m_actionIsDefusing = FALSE;
m_gflagsBackup = 0;
#endif
}
float punchangle_recovery(float punchangle) {
return 0.05 * (-0.2 * pow(1.2, fabs(punchangle)) + 4);
}
@ -183,166 +195,20 @@ CSPlayer::Physics_InputPostMove(void)
RemoveVFlags(VFL_FROZEN);
RemoveVFlags(VFL_NOATTACK);
#ifdef SERVER
if (g_cs_gamestate == GAME_FREEZE) {
#else
if (getstati(STAT_GAMESTATE) == GAME_FREEZE) {
#endif
if (serverkeyfloat("cs_gamestate") == GAME_FREEZE) {
AddVFlags(VFL_FROZEN);
AddVFlags(VFL_NOATTACK);
if (input_buttons & INPUT_BUTTON0) {
w_attack_next = (w_attack_next > 0.1) ? w_attack_next : 0.1f;
}
}
ProcessInput();
}
void Animation_PlayerUpdate(CSPlayer);
void Animation_TimerUpdate(CSPlayer, float);
void
CSPlayer::UpdatePlayerAnimation(float timelength)
{
/* calculate our skeletal progression */
Animation_PlayerUpdate(this);
/* advance animation timers */
Animation_TimerUpdate(this, timelength);
}
#ifdef CLIENT
void
CSPlayer::ClientInputFrame(void)
{
if (pSeatLocal->weaponSelectionHUD.Active()) {
if (input_buttons & INPUT_PRIMARY) {
pSeatLocal->weaponSelectionHUD.Trigger();
} else if (input_buttons & INPUT_SECONDARY) {
pSeatLocal->weaponSelectionHUD.Deactivate();
}
pSeat->m_flInputBlockTime = time + 0.2;
}
super::ClientInputFrame();
}
void Camera_RunPosBob(vector angles, __inout vector camera_pos);
void Camera_StrafeRoll(__inout vector camera_angle);
void Shake_Update(NSClientPlayer);
void
CSPlayer::UpdateAliveCam(void)
{
vector cam_pos = GetEyePos();
Camera_RunPosBob(view_angles, cam_pos);
g_view.SetCameraOrigin(cam_pos);
Camera_StrafeRoll(view_angles);
g_view.SetCameraAngle(view_angles);
if (vehicle) {
NSVehicle veh = (NSVehicle)vehicle;
if (veh.UpdateView)
veh.UpdateView();
} else if (health) {
if (autocvar_pm_thirdPerson == TRUE) {
makevectors(view_angles);
vector vStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4);
vector vEnd = vStart + (v_forward * -48) + [0,0,16] + (v_right * 4);
traceline(vStart, vEnd, FALSE, this);
g_view.SetCameraOrigin(trace_endpos + (v_forward * 5));
}
}
Shake_Update(this);
g_view.AddPunchAngle(punchangle);
}
.string oldmodel;
///string Weapons_GetPlayermodel(NSClientPlayer, int);
void
CSPlayer::UpdatePlayerAttachments(bool visible)
{
/* draw the flashlight */
if (gflags & GF_FLASHLIGHT) {
vector src;
vector ang;
if (entnum != player_localentnum) {
src = origin + view_ofs;
ang = v_angle;
} else {
src = pSeat->m_vecPredictedOrigin + [0,0,-8];
ang = view_angles;
}
makevectors(ang);
traceline(src, src + (v_forward * 8096), MOVE_NORMAL, this);
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);
}
}
/* FIXME: this needs to be incorporated and simplified, now that we can handle it all in-class */
if (!visible)
return;
/* what's the current weapon model supposed to be anyway? */
p_model.oldmodel = 0;//Weapons_GetPlayermodel(this, activeweapon);
/* we changed weapons, update skeletonindex */
if (p_model.model != p_model.oldmodel) {
/* free memory */
if (p_model.skeletonindex)
skel_delete(p_model.skeletonindex);
/* set the new model and mark us updated */
setmodel(p_model, p_model.oldmodel);
p_model.model = p_model.oldmodel;
/* set the new skeletonindex */
p_model.skeletonindex = skel_create(p_model.modelindex);
/* hack this thing in here FIXME: this should be done when popping in/out of a pvs */
if (autocvar(cl_himodels, 1, "Use high-quality thisayer models over lower-definition ones"))
setcustomskin(this, "", "geomset 0 2\n");
else
setcustomskin(this, "", "geomset 0 1\n");
}
/* follow thisayer at all times */
setorigin(p_model, origin);
p_model.angles = angles;
skel_build(p_model.skeletonindex, p_model, p_model.modelindex,0, 0, -1);
/* we have to loop through all valid bones of the weapon model and match them
* to the thisayer one */
for (float i = 0; i < g_pbones.length; i++) {
vector bpos;
float pbone = gettagindex(this, g_pbones[i]);
float wbone = gettagindex(p_model, g_pbones[i]);
/* if the bone doesn't ignore in either skeletal mesh, ignore */
if (wbone <= 0 || pbone <= 0)
continue;
bpos = gettaginfo(this, pbone);
/* the most expensive bit */
skel_set_bone_world(p_model, wbone, bpos, v_forward, v_right, v_up);
}
}
void HUD_AmmoNotify_Check(CSPlayer pl);
/*
=================
CSPlayer::ReceiveEntity
@ -351,7 +217,7 @@ CSPlayer::ReceiveEntity
void
CSPlayer::ReceiveEntity(float flIsNew, float flChanged)
{
super::ReceiveEntity(flIsNew, flChanged);
NSClientPlayer::ReceiveEntity(flIsNew, flChanged);
/* animation */
READENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
@ -393,11 +259,6 @@ CSPlayer::PredictPreFrame(void)
SAVE_STATE(cs_prev_hor_rec)
SAVE_STATE(cs_hor_rec_sign)
SAVE_STATE(cs_rec_reverse_chance)
SAVE_STATE(anim_top)
SAVE_STATE(anim_top_time)
SAVE_STATE(anim_top_delay)
SAVE_STATE(anim_bottom)
SAVE_STATE(anim_bottom_time)
}
/*
@ -417,14 +278,429 @@ CSPlayer::PredictPostFrame(void)
ROLL_BACK(cs_prev_hor_rec)
ROLL_BACK(cs_hor_rec_sign)
ROLL_BACK(cs_rec_reverse_chance)
ROLL_BACK(anim_top)
ROLL_BACK(anim_top_time)
ROLL_BACK(anim_top_delay)
ROLL_BACK(anim_bottom)
ROLL_BACK(anim_bottom_time)
}
#else
/** @brief Aim towards a given (vector)aimpos with a given (float)lerp speed.
*
* @note
* Copied code from nuclide botlib (inside bot::RunAI), maybe make this a
* method there, could be usefull for other stuff?
**/
void CSPlayer::Bot_AimLerp(vector aimpos, float flLerp) {
vector aimdir, vecNewAngles;
vector oldAngle = v_angle;
/* that's the old angle */
vecNewAngles = anglesToForward(v_angle);
/* aimdir = new final angle */
aimdir = vectorToAngles(aimpos - origin);
/* slowly lerp towards the final angle */
vecNewAngles = vectorLerp(vecNewAngles, anglesToForward(aimdir), flLerp);
/* make sure we're aiming tight */
v_angle = vectorToAngles(vecNewAngles);
input_angles = angles = v_angle = fixAngle(v_angle);
}
void
CSPlayer::Bot_RunToConfront(void)
{
entity t;
if (team == TEAM_T) {
t = Route_SelectRandom(teams.SpawnPoint(TEAM_CT));
} else {
t = Route_SelectRandom(teams.SpawnPoint(TEAM_T));
}
ChatSayTeam("Going to run to the Enemy Spawn!");
if (t)
RouteToPosition(t.origin);
}
/* go to the planted bomb */
void
CSPlayer::Bot_RunToBomb(void)
{
NSEntity e = __NULL__;
e = (NSEntity)find(e, ::model, "models/w_c4.mdl");
if (e) {
RouteToPosition(e.WorldSpaceCenter());
ChatSayTeam("Going to run to the Bomb!");
}
}
/* go to given bombsite */
void
CSPlayer::Bot_RunToBombsite(int bombsiteIndex)
{
NSEntity e = GetBombsiteByIndex(bombsiteIndex);
RouteToPosition(e.WorldSpaceCenter());
ChatSayTeam(strcat("Going to run to Bomb Site ", itos(bombsiteIndex), "!"));
}
/* go to random bombsite */
void
CSPlayer::Bot_RunToRandomBombsite(void)
{
Bot_RunToBombsite(random(0, serverinfo.GetInteger("cs_bombzones")));
}
/* go to given escape zone */
void
CSPlayer::Bot_RunToEscapeZone(int index)
{
NSEntity e = GetEscapeZoneByIndex(index);
RouteToPosition(e.WorldSpaceCenter());
ChatSayTeam(strcat("Going to run to Escape Zone ", itos(index), "!"));
}
/* go to a random escape zone */
void
CSPlayer::Bot_RunToRandomEscapeZone(void)
{
Bot_RunToEscapeZone(random(0, serverinfo.GetInteger("cs_escapezones")));
}
/* go to given VIP Safety Zone */
void
CSPlayer::Bot_RunToVIPSafetyZone(int index)
{
NSEntity e = GetVIPSafetyZoneByIndex(index);
RouteToPosition(e.WorldSpaceCenter());
ChatSayTeam(strcat("Going to run to VIP Safety Zone ", itos(index), "!"));
}
/* go to a random VIP Safety Zone */
void
CSPlayer::Bot_RunToRandomVIPSafetyZone(void)
{
Bot_RunToVIPSafetyZone(random(0, serverinfo.GetInteger("cs_vipzones")));
}
void
CSPlayer::Bot_RunToHostages(void)
{
NSEntity e = __NULL__;
e = (NSEntity)find(e, ::classname, "hostage_entity");
RouteToPosition(e.origin);
ChatSayTeam("Going to run to the hostages!");
}
/** @brief Let the bot roam within a maximum distance from a given origin. */
void CSPlayer::Bot_Roam(vector roamOrigin, int maxDistance) {
/* Get random point whitin a radius from the given origin */
int angle = random(0, 360); /* random angle. */
int distance = random(0, maxDistance); /* random distance */
float radian = angle * 3.145238095238 / 180;
vector randLoc = roamOrigin;
randLoc.x += sin(radian) * distance;
randLoc.y += cos(radian) * distance;
/* Go to the random waypoint. */
RouteToPosition(Nodes_PositionOfClosestNode(randLoc));
}
void
CSPlayer::Bot_CreateObjective(void)
{
/* Bomb defuse map */
if (serverinfo.GetInteger("cs_bombzones") > 0) {
/* Bomb is planted */
if (serverinfo.GetBool("cs_bombplanted")) {
entity eBomb = find(world, ::model, "models/w_c4.mdl");
if (eBomb == world) {
/* No bomb model found, but it is/was planted */
/* RoundOver: Bomb is defused */
if (serverkeyfloat("cs_gamestate") == GAME_END) {
Bot_RunToRandomBombsite();
return;
}
/* Error */
print("WARNING! g_cs_bombplanted == TRUE, but bomb model "
"cannot be found in the world.\n");
return;
}
if (team == TEAM_CT) {
if (serverinfo.GetBool("cs_bombbeingdefused") && m_actionIsDefusing == FALSE) {
/* Bomb is being defused but not by this bot */
/* Go and roam the defuser */
Bot_Roam(eBomb.origin, 300);
return;
}
if (m_actionIsDefusing) {
if (serverinfo.GetBool("cs_bombbeingdefused") == false) {
/* Defusing complete or somehow failed. */
m_actionIsDefusing = FALSE;
} else {
/* Continue defusing. */
input_buttons |= (INPUT_BUTTON5 | INPUT_BUTTON8);
input_movevalues = [0,0,0];
button5 = input_buttons & INPUT_BUTTON5; // don't release button5
}
}
else {
int distToBomb = floor(vlen(eBomb.origin - origin));
if (distToBomb > 60) {
/* To far away from the bomb to defuse it, run to it! */
Bot_RunToBomb();
} else {
/* Aim at the bomb. */
input_buttons |= INPUT_BUTTON8; // duck
if ((HasVFlags(VFL_ONUSABLE))) {
// Aimed at the bomb, ready to defuse!
ChatSayTeam("Defusing!");
input_buttons |= INPUT_BUTTON5;
input_movevalues = [0,0,0];
button5 = input_buttons & INPUT_BUTTON5; // don't release button5
m_actionIsDefusing = TRUE;
} else {
// Do the real aiming
float flLerp = bound(0.0f, frametime * 45, 1.0f); // aim speed
Bot_AimLerp(eBomb.origin + [0, 0, -6], flLerp);
}
}
}
}
/* team == TEAM_T */
else {
/* Let T bots roam around the planted bomb */
Bot_Roam(eBomb.origin, 500);
}
return;
}
/* Bomb is NOT planted */
else {
if (team == TEAM_T) {
/* T-bot: plant bomb */
if (HasItem("weapon_c4")) {
/* We carry the bomb */
if (m_gflagsBackup & GF_BOMBZONE) {
/* We are at a bombsite and ready to plant the bomb */
if (GetCurrentWeapon() != "weapon_c4") {
/* TODO: REPLACE THIS WITH NSNAVAI METHOD */
SwitchToWeapon("weapon_c4");
//Weapons_Draw((CSPlayer)self);
}
if (!m_actionIsPlanting) {
ChatSayTeam("Going to plant the bomb!");
m_actionIsPlanting = TRUE;
}
/* Workaround */
gflags = m_gflagsBackup;
/* Duck and plant bomb. */
input_buttons = (INPUT_BUTTON0 | INPUT_BUTTON8);
input_movevalues = [0,0,0];
}
else {
/* Go to a bombsite first */
Bot_RunToRandomBombsite();
}
return;
}
else {
/* T-bot: check if the bomb has been dropped */
NSEntity e = (NSEntity)find(world, ::model, "models/w_backpack.mdl");
if (e != __NULL__) {
/* The bomb backpack has been dropped */
/* Go fetch dropped bomb! */
ChatSayTeam("Arrr! Bomb on the ground, going to fetch it!");
RouteToPosition(e.WorldSpaceCenter());
return;
}
}
}
}
}
if (serverinfo.GetInteger("cs_escapezones") > 0i && team == TEAM_T) {
Bot_RunToRandomEscapeZone();
return;
}
if (random() < 0.5 && serverinfo.GetInteger("cs_escapezones") > 0i && team == TEAM_CT) {
Bot_RunToRandomEscapeZone();
return;
}
if (serverinfo.GetInteger("cs_vipzones") > 0i && team == TEAM_CT) {
Bot_RunToRandomVIPSafetyZone();
return;
}
if (random() < 0.5 && serverinfo.GetInteger("cs_vipzones") > 0i && team == TEAM_T) {
Bot_RunToRandomVIPSafetyZone();
return;
}
if (random() < 0.5) {
if (serverinfo.GetInteger("cs_hostages") > 0) {
Bot_RunToHostages();
}
if (serverinfo.GetInteger("cs_bombzones") > 0) {
Bot_RunToRandomBombsite();
}
} else {
Bot_RunToConfront();
}
}
float ConsoleCmd(string cmd);
void
CSPlayer::Bot_Buy(void)
{
int done = 0;
int count = 0;
CSPlayer pl = (CSPlayer)self;
int playerMoney = userinfo.GetInteger(pl, "*money");
string weaponToBuy = "";
int weaponPrice = 0i;
if (pl.team == TEAM_T) {
weaponToBuy = userinfo.GetString(pl, "fav_primary_ct");
} else if (pl.team == TEAM_CT) {
weaponToBuy = userinfo.GetString(pl, "fav_primary_t");
}
/* Workaround */
pl.gflags = m_gflagsBackup;
if (STRING_SET(weaponToBuy)) {
weaponPrice = entityDef.GetInteger(weaponToBuy, "price");
if (weaponPrice <= userinfo.GetInteger(pl, "*money")) {
ConsoleCmd(strcat("buy ", weaponToBuy));
playerMoney = userinfo.GetInteger(pl, "*money");
} else {
weaponToBuy = "";
}
}
/* CT: Random buy bomb defuse kit when enough money left */
if (pl.team == TEAM_CT && serverinfo.GetInteger("cs_bombzones") > 0 &&
entityDef.GetInteger("item_defuse", "price") <= playerMoney &&
random() < 0.5)
{
ConsoleCmd("item_defuse");
playerMoney = userinfo.GetInteger(pl, "*money");
}
/* need armor */
if (pl.armor < 100) {
if (playerMoney >= entityDef.GetInteger("item_kevlar_helmet", "price")) {
ConsoleCmd("buy item_kevlar_helmet");
} else if (playerMoney >= entityDef.GetInteger("item_kevlar", "price")) {
ConsoleCmd("buy item_kevlar");
}
} else if (pl.HasItem("item_kevlar_helmet") == false) {
if (playerMoney >= 350) {
ConsoleCmd("buy item_kevlar_helmet");
}
}
if (STRING_SET(weaponToBuy)) {
SwitchToWeapon(weaponToBuy);
}
/* force buy right now */
ConsoleCmd("buyammo 0");
ConsoleCmd("buyammo 1");
}
void
CSPlayer::Input(entity eAct, string strInput, string strData)
{
switch (strInput) {
case "RadioMessage":
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_RADIOMSG);
WriteByte(MSG_MULTICAST, stof(strData));
msg_entity = this;
multicast([0,0,0], MULTICAST_ONE);
break;
case "RadioTeamMessage":
tokenize(strData);
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EV_RADIOMSG2);
WriteByte(MSG_MULTICAST, stof(argv(0)));
WriteByte(MSG_MULTICAST, stof(argv(1)));
msg_entity = this;
multicast([0,0,0], MULTICAST_ONE);
break;
case "NotifyBuyStart":
if (IsAlive() == false) {
return;
}
ScheduleThink(Bot_Buy, random(0, cvars.GetFloat("mp_freezetime")));
break;
case "NotifyRoundStarted":
if (clienttype(this) != CLIENTTYPE_REAL) {
if (IsAlive() == false) {
return;
}
if (GetTeam() == TEAM_T) {
return;
}
Bot_RunToRandomBombsite();
}
break;
case "NotifyRoundRestarted":
/* bot stuff */
m_actionIsPlanting = FALSE;
m_actionIsDefusing = FALSE;
break;
case "NotifyBombPlanted":
if (clienttype(this) != CLIENTTYPE_REAL) {
if (IsAlive() == false) {
return;
}
if (GetTeam() == TEAM_T) {
return;
}
Bot_RunToRandomBombsite();
}
break;
case "NotifyHostageRescued":
if (clienttype(this) != CLIENTTYPE_REAL) {
if (IsAlive() == false) {
return;
}
if (GetTeam() == TEAM_T) {
return;
}
Bot_RunToHostages();
}
break;
default:
super::Input(eAct, strInput, strData);
}
}
void
CSPlayer::ServerInputFrame(void)
{
@ -465,7 +741,7 @@ CSPlayer::SendEntity(entity ePEnt, float flChanged)
flChanged = OptimiseChangedFlags(ePEnt, flChanged);
super::SendEntity(ePEnt, flChanged);
NSClientPlayer::SendEntity(ePEnt, flChanged);
SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
@ -481,3 +757,50 @@ CSPlayer::SendEntity(entity ePEnt, float flChanged)
return (1);
}
#endif
void
CSPlayer::Physics_Fall(float impactspeed)
{
/* apply some predicted punch to the player */
if (impactspeed >= 580)
punchangle += [15,0,(input_sequence & 1) ? 15 : -15];
else if (impactspeed >= 400)
punchangle += [15,0,0];
impactspeed *= 1.25f;
/* basic server-side falldamage */
#ifdef SERVER
/* if we've reached a fallheight of PHY_FALLDMG_DISTANCE qu, start applying damage */
if (impactspeed >= 580) {
float impactDamage = (impactspeed - 580) * (100 / (1024 - 580)) * 0.75f;
/* this is kinda ugly, but worth the price */
NSDict damageDecl = spawn(NSDict);
damageDecl.AddKey("damage", ftos((int)impactDamage));
Damage(this, this, damageDecl, 1.0, g_vec_null, origin);
remove(damageDecl);
StartSoundDef("Player.FallDamage", CHAN_VOICE, true);
} else if (impactspeed >= 400) {
StartSoundDef("Player.LightFall", CHAN_VOICE, true);
}
#endif
}
void
CSPlayer::Physics_Jump(void)
{
if (waterlevel >= 2) {
if (watertype == CONTENT_WATER) {
velocity[2] = 100;
} else if (watertype == CONTENT_SLIME) {
velocity[2] = 80;
} else {
velocity[2] = 50;
}
} else {
/* slow the player down a bit to prevent bhopping like crazy */
velocity *= 0.80f;
velocity[2] += 260;
}
}

View file

@ -1,75 +0,0 @@
/*
* Copyright (c) 2016-2024 Marco Cawthorne <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define PMOVE_STEPHEIGHT 18
#define PMOVE_AIRSTEPHEIGHT 0
#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
#define PMOVE_STEP_WALKSPEED 270
#define PMOVE_STEP_CROUCHSPEED 90
#define PMOVE_BOXCENTER true
#define PMOVE_NORMAL_HEIGHT 72
#define PMOVE_NORMAL_VIEWHEIGHT 54
#define PMOVE_CROUCH_HEIGHT 36
#define PMOVE_CROUCH_VIEWHEIGHT 30
/* disable prone, run and lean */
#define PMOVE_STEP_RUNSPEED 0
#define PMOVE_PRONE_HEIGHT 0
.float waterlevel;
.float watertype;
void
CSPlayer::Physics_Fall(float impactspeed)
{
impactspeed *= 1.25f;
if (impactspeed > 580) {
#ifdef SERVER
float fFallDamage = (impactspeed - 580) * (100 / (1024 - 580)) * 0.75f;
//Damage_Apply(this, world, fFallDamage, 0, DMG_FALL | DMG_SKIP_ARMOR);
if (random() < 0.5)
sound(this, CHAN_AUTO, "player/pl_pain2.wav", 1.0, ATTN_NORM);
else
sound(this, CHAN_AUTO, "player/pl_pain4.wav", 1.0, ATTN_NORM);
#endif
}
}
void
CSPlayer::Physics_Jump(void)
{
if (waterlevel >= 2) {
if (watertype == CONTENT_WATER) {
velocity[2] = 100;
} else if (watertype == CONTENT_SLIME) {
velocity[2] = 80;
} else {
velocity[2] = 50;
}
} else {
/* slow the player down a bit to prevent bhopping like crazy */
velocity *= 0.80f;
velocity[2] += 260;
}
}

82
src/shared/skeleton.h Normal file
View file

@ -0,0 +1,82 @@
#ifdef CLIENT
/* Here's a list of bone names that we are aware of on HL player models.
Usually we'd use skeletalobjects to share the same skeleton/anim with
another model - but because FTEQW does not support that for HLMDL we
are forced to manually position the bones of our attachnment
by iterating over them and manually setting their position in 3D-space.
*/
string g_pbones[] =
{
"Bip01",
"Bip01 Footsteps",
"Bip01 Pelvis",
"Bip01 L Leg",
"Bip01 L Leg1",
"Bip01 L Foot",
"Bip01 L Toe0",
"Bip01 L Toe01",
"Bip01 L Toe02",
"Dummy16",
"Bip01 R Leg",
"Bip01 R Leg1",
"Bip01 R Foot",
"Bip01 R Toe0",
"Bip01 R Toe01",
"Bip01 R Toe02",
"Dummy11",
"Bip01 Spine",
"Bip01 Spine1",
"Bip01 Spine2",
"Bip01 Spine3",
"Bip01 Neck",
"Bip01 Head",
"Dummy21",
"Dummy08",
"Bone02",
"Bone03",
"Bone04",
"Dummy05",
"Bone09",
"Bone10",
"Dummy04",
"Bone05",
"Bone06",
"Dummy03",
"Bone07",
"Bone08",
"Dummy09",
"Bone11",
"Bone12",
"Dummy10",
"Bone13",
"Bone14",
"Bone15",
"Bip01 L Arm",
"Bip01 L Arm1",
"Bip01 L Arm2",
"Bip01 L Hand",
"Bip01 L Finger0",
"Bip01 L Finger01",
"Bip01 L Finger02",
"Dummy06",
"Bip01 L Finger1",
"Bip01 L Finger11",
"Bip01 L Finger12",
"Dummy07",
"Bip01 R Arm",
"Bip01 R Arm1",
"Bip01 R Arm2",
"Bip01 R Hand",
"Bip01 R Finger0",
"Bip01 R Finger01",
"Bip01 R Finger02",
"Dummy01",
"Bip01 R Finger1",
"Bip01 R Finger11",
"Bip01 R Finger12",
"Dummy02",
"Box02",
"Bone08",
"Bone15"
};
#endif

View file

@ -1,116 +1,69 @@
// these have to be defined by the game.
// these have to be defined by the game.
// Counter-Strike ammo data courtesy of https://wiki.alliedmods.net/CS_weapons_information
entityDef ammo_types {
"ammo_none" "0"
"ammo_338magnum" "1"
"ammo_357sig" "2"
"ammo_45acp" "3"
"ammo_50ae" "4"
"ammo_556nato" "5"
"ammo_556natobox" "6"
"ammo_57mm" "7"
"ammo_762nato" "8"
"ammo_9mm" "9"
"ammo_buckshot" "10"
"ammo_hegrenade" "11"
"ammo_smokegrenade" "12"
"ammo_flashbang" "13"
"ammo_338magnum" "1"
"ammo_357sig" "2"
"ammo_45acp" "3"
"ammo_50ae" "4"
"ammo_556nato" "5"
"ammo_556natobox" "6"
"ammo_57mm" "7"
"ammo_762nato" "8"
"ammo_9mm" "9"
"ammo_buckshot" "10"
"ammo_hegrenade" "11"
"ammo_smokegrenade" "12"
"ammo_flashbang" "13"
}
entityDef ammo_names {
"ammo_none" "None"
"ammo_338magnum" ".338 Lapua Magnum"
"ammo_357sig" ".357 SIG"
"ammo_45acp" ".45 ACP"
"ammo_50ae" ".50 Action Express"
"ammo_556nato" "5.56×45mm NATO"
"ammo_556natobox" "5.56×45mm NATO BOX"
"ammo_57mm" "FN 5.7×28mm"
"ammo_762nato" "7.62×51mm NATO"
"ammo_9mm" "9×19mm Parabellum"
"ammo_buckshot" "Buckshot"
"ammo_hegrenade" "HE Grenade"
"ammo_smokegrenade" "Smoke Grenade"
"ammo_flashbang" "Flashbang"
"ammo_338magnum" ".338 Lapua Magnum"
"ammo_357sig" ".357 SIG"
"ammo_45acp" ".45 ACP"
"ammo_50ae" ".50 Action Express"
"ammo_556nato" "5.56×45mm NATO"
"ammo_556natobox" "5.56×45mm NATO BOX"
"ammo_57mm" "FN 5.7×28mm"
"ammo_762nato" "7.62×51mm NATO"
"ammo_9mm" "9×19mm Parabellum"
"ammo_buckshot" "Buckshot"
"ammo_hegrenade" "HE Grenade"
"ammo_smokegrenade" "Smoke Grenade"
"ammo_flashbang" "Flashbang"
}
entityDef ammo_base
{
"spawnclass" "NSItem"
"snd_acquire" "ammo.pickup"
"snd_respawn" "ammo.respawn"
"mins" "-16 -16 0"
"maxs" "16 16 16"
"model" "models/w_backpack.mdl"
}
// these don't exist as pickups in the game, but
// might be helpful nonetheless
entityDef ammo_338magnum
{
"editor_usage" "Ammo used by weapon_awp"
"inherit" "ammo_base"
"inv_ammo_338magnum" "10"
}
entityDef ammo_357sig
{
"editor_usage" "Ammo used by weapon_p228"
"inherit" "ammo_base"
"inv_ammo_357sig" "13"
}
entityDef ammo_45acp
{
"editor_usage" "Ammo used by weapon_mac10, weapon_ump45, weapon_usp45"
"inherit" "ammo_base"
"inv_ammo_45acp" "12"
}
entityDef ammo_50ae
{
"editor_usage" "Ammo used by weapon_deagle"
"inherit" "ammo_base"
"inv_ammo_50ae" "7"
}
entityDef ammo_556nato
{
"editor_usage" "Ammo used by weapon_m4a1, weapon_sg550, weapon_sg552"
"inherit" "ammo_base"
"inv_ammo_556nato" "30"
}
entityDef ammo_556natobox
{
"editor_usage" "Ammo used by weapon_m249"
"inherit" "ammo_base"
"inv_ammo_556natobox" "30"
}
entityDef ammo_57mm
{
"editor_usage" "Ammo used by weapon_fiveseven, weapon_p90"
"inherit" "ammo_base"
"inv_ammo_57mm" "50"
}
entityDef ammo_762nato
{
"editor_usage" "Ammo used by weapon_aug, weapon_famas, weapon_g3sg1, weapon_galil, weapon_ak47, weapon_scout"
"inherit" "ammo_base"
"inv_ammo_762nato" "30"
}
entityDef ammo_9mm
{
"editor_usage" "Ammo used by weapon_elites, weapon_glock18, weapon_mp5navy, weapon_tmp"
"inherit" "ammo_base"
"inv_ammo_9mm" "30"
}
entityDef ammo_buckshot
{
"editor_usage" "Ammo used by weapon_m3, weapon_xm1014"
"inherit" "ammo_base"
"inv_ammo_buckshot" "8"
}
entityDef ammo_max {
"ammo_none" "0"
"ammo_338magnum" "30"
"ammo_357sig" "52"
"ammo_45acp" "100"
"ammo_50ae" "35"
"ammo_556nato" "90"
"ammo_556natobox" "200"
"ammo_57mm" "100"
"ammo_762nato" "90"
"ammo_9mm" "120"
"ammo_buckshot" "32"
"ammo_hegrenade" "1"
"ammo_smokegrenade" "1"
"ammo_flashbang" "2"
}
// these don't exist as pickups in the game, but
// might be helpful nonetheless for level designers
#include "ammo/base.def"
#include "ammo/556natobox.def"
#include "ammo/338magnum.def"
#include "ammo/9mm.def"
#include "ammo/556nato.def"
#include "ammo/762nato.def"
#include "ammo/50ae.def"
#include "ammo/45acp.def"
#include "ammo/buckshot.def"
#include "ammo/base.def"
#include "ammo/57mm.def"
#include "ammo/357sig.def"

View file

@ -0,0 +1,7 @@
entityDef ammo_338magnum
{
"editor_usage" "Ammo used by weapon_awp"
"inherit" "ammo_base"
"inv_ammo_338magnum" "10"
"price" "125"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_357sig
{
"editor_usage" "Ammo used by weapon_p228"
"inherit" "ammo_base"
"inv_ammo_357sig" "13"
"price" "50"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_45acp
{
"editor_usage" "Ammo used by weapon_mac10, weapon_ump45, weapon_usp45"
"inherit" "ammo_base"
"inv_ammo_45acp" "12"
"price" "25"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_50ae
{
"editor_usage" "Ammo used by weapon_deagle"
"inherit" "ammo_base"
"inv_ammo_50ae" "7"
"price" "40"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_556nato
{
"editor_usage" "Ammo used by weapon_m4a1, weapon_sg550, weapon_sg552"
"inherit" "ammo_base"
"inv_ammo_556nato" "30"
"price" "60"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_556natobox
{
"editor_usage" "Ammo used by weapon_m249"
"inherit" "ammo_base"
"inv_ammo_556natobox" "30"
"price" "60"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_57mm
{
"editor_usage" "Ammo used by weapon_fiveseven, weapon_p90"
"inherit" "ammo_base"
"inv_ammo_57mm" "50"
"price" "50"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_762nato
{
"editor_usage" "Ammo used by weapon_aug, weapon_famas, weapon_g3sg1, weapon_galil, weapon_ak47, weapon_scout"
"inherit" "ammo_base"
"inv_ammo_762nato" "30"
"price" "80"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_9mm
{
"editor_usage" "Ammo used by weapon_elites, weapon_glock18, weapon_mp5navy, weapon_tmp"
"inherit" "ammo_base"
"inv_ammo_9mm" "30"
"price" "20"
}

View file

@ -0,0 +1,9 @@
entityDef ammo_base
{
"spawnclass" "NSItem"
"snd_acquire" "ammo.pickup"
"snd_respawn" "ammo.respawn"
"mins" "-16 -16 0"
"maxs" "16 16 16"
"model" "models/w_backpack.mdl"
}

View file

@ -0,0 +1,7 @@
entityDef ammo_buckshot
{
"editor_usage" "Ammo used by weapon_m3, weapon_xm1014"
"inherit" "ammo_base"
"inv_ammo_buckshot" "8"
"price" "65"
}

View file

@ -0,0 +1 @@
// we have none! go away!

View file

@ -2,3 +2,80 @@ entityDef player
{
"spawnclass" "CSPlayer"
}
entityDef player_mp
{
"inherit" "player"
"def_precache" "weapon_ak47"
"def_precache" "weapon_aug"
"def_precache" "weapon_awp"
"def_precache" "weapon_c4"
"def_precache" "weapon_deagle"
"def_precache" "weapon_elite"
"def_precache" "weapon_famas"
"def_precache" "weapon_fiveseven"
"def_precache" "weapon_flashbang"
"def_precache" "weapon_g3sg1"
"def_precache" "weapon_galil"
"def_precache" "weapon_glock18"
"def_precache" "weapon_hegrenade"
"def_precache" "weapon_knife"
"def_precache" "weapon_m249"
"def_precache" "weapon_m3"
"def_precache" "weapon_m4a1"
"def_precache" "weapon_mac10"
"def_precache" "weapon_mp5navy"
"def_precache" "weapon_p228"
"def_precache" "weapon_p90"
"def_precache" "weapon_scout"
"def_precache" "weapon_sg550"
"def_precache" "weapon_sg552"
"def_precache" "weapon_smokegrenade"
"def_precache" "weapon_tmp"
"def_precache" "weapon_ump45"
"def_precache" "weapon_usp"
"def_precache" "weapon_xm1014"
}
entityDef player_terrorist
{
"inherit" "player_mp"
"ammo_9mm" "40"
"current_weapon" "1"
"item" "item_suit"
"spawnpoint" "info_player_deathmatch"
"team" "1"
"weapon" "weapon_knife,weapon_glock18"
"model_class1" "models/player/terror/terror.mdl"
"model_class2" "models/player/leet/leet.mdl"
"model_class3" "models/player/arctic/arctic.mdl"
"model_class4" "models/player/guerilla/guerilla.mdl"
}
entityDef player_counterterrorist
{
"inherit" "player_mp"
"ammo_45acp" "24"
"current_weapon" "1"
"item" "item_suit"
"spawnpoint" "info_player_start"
"team" "2"
"weapon" "weapon_knife,weapon_usp"
"model_class1" "models/player/urban/urban.mdl"
"model_class2" "models/player/gsg9/gsg9.mdl"
"model_class3" "models/player/sas/sas.mdl"
"model_class4" "models/player/gign/gign.mdl"
}
entityDef player_vip
{
"inherit" "player_mp"
"ammo_45acp" "24"
"current_weapon" "1"
"item" "item_suit"
"model" "models/player/vip/vip.mdl"
"team" "2"
"weapon" "weapon_knife,weapon_usp"
}

View file

@ -10,10 +10,10 @@ entityDef weapon_ak47
"def_fireInfo" "fireInfo_ak47"
"clipSize" "30"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_AK47.Single"

View file

@ -10,10 +10,10 @@ entityDef weapon_aug
"def_fireInfo" "fireInfo_aug"
"clipSize" "30"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_AUG.Single"

View file

@ -10,12 +10,12 @@ entityDef weapon_awp
"def_fireInfo" "fireInfo_awp"
"clipSize" "5"
"actFire" "1,2,3"
"act_fire" "1,2,3"
"actAltFire" ""
"actHolster" ""
"actReload" "4"
"actDraw" "5"
"actIdle" "0"
"act_holster" ""
"act_reload" "4"
"act_draw" "5"
"act_idle" "0"
"snd_fire" "Weapon_AWP.Single"

View file

@ -17,9 +17,9 @@ entityDef weapon_c4
"clipSize" "1"
"trigger_delay" "3" // takes three seconds to charge
"actFire" "2"
"actDraw" "1"
"actIdle" "0"
"act_fire" "2"
"act_draw" "1"
"act_idle" "0"
"actDelay" "3"
"snd_fire" "C4.PlantSound"

View file

@ -9,11 +9,11 @@ entityDef weapon_deagle
"def_fireInfo" "fireInfo_deagle"
"clipSize" "7"
"actFire" "1,2"
"actFireLast" "3"
"actReload" "4"
"actDraw" "5"
"actIdle" "0"
"act_fire" "1,2"
"act_fireLast" "3"
"act_reload" "4"
"act_draw" "5"
"act_idle" "0"
"snd_fire" "Weapon_DEagle.Single"

View file

@ -11,11 +11,11 @@ entityDef weapon_elite
"def_altFireInfo" "fireInfo_elite_alt"
"clipSize" "30"
"actFire" "2,3,4,5,6"
"actFireLast" "7"
"actReload" "14"
"actDraw" "15"
"actIdle" "0"
"act_fire" "2,3,4,5,6"
"act_fireLast" "7"
"act_reload" "14"
"act_draw" "15"
"act_idle" "0"
"snd_fire" "Weapon_ELITE.Single"
"snd_altfire" "Weapon_ELITE.Single"
@ -61,6 +61,6 @@ entityDef fireInfo_elite
entityDef fireInfo_elite_alt
{
"inherit" "fireInfo_elite"
"actFire" "8,9,10,11,12"
"actFireLast" "13"
"act_fire" "8,9,10,11,12"
"act_fireLast" "13"
}

View file

@ -10,12 +10,12 @@ entityDef weapon_famas
"def_fireInfo" "fireInfo_famas"
"clipSize" ""
"actFire" ""
"act_fire" ""
"actAltFire" ""
"actHolster" ""
"actReload" ""
"actDraw" ""
"actIdle" ""
"act_holster" ""
"act_reload" ""
"act_draw" ""
"act_idle" ""
"snd_fire" "Weapon_FAMAS.Single"

View file

@ -10,11 +10,11 @@ entityDef weapon_fiveseven
"def_fireInfo" "fireInfo_fiveseven"
"clipSize" "20"
"actFire" "1,2"
"actFireLast" "3"
"actReload" "4"
"actDraw" "5"
"actIdle" "0"
"act_fire" "1,2"
"act_fireLast" "3"
"act_reload" "4"
"act_draw" "5"
"act_idle" "0"
"snd_fire" "Weapon_FiveSeven.Single"

View file

@ -19,8 +19,8 @@ entityDef weapon_flashbang
"silent_fire" "1"
"primed_fuse" "4"
"actIdle" "0"
"actDraw" "3"
"act_idle" "0"
"act_draw" "3"
"actPull" "1"
"actThrow" "2"

View file

@ -10,10 +10,10 @@ entityDef weapon_g3sg1
"def_fireInfo" "fireInfo_g3sg1"
"clipSize" "20"
"actFire" "1,2"
"actReload" "3"
"actDraw" "4"
"actIdle" "0"
"act_fire" "1,2"
"act_reload" "3"
"act_draw" "4"
"act_idle" "0"
"snd_fire" "Weapon_G3SG1.Single"

View file

@ -12,12 +12,12 @@ entityDef weapon_galil
"clipSizeDefault" "25"
"ammoType" "ammo_762nato"
"actFire" "5,6,7"
"act_fire" "5,6,7"
"actAltFire" "2"
"actHolster" "4"
"actReload" "3"
"actDraw" "4"
"actIdle" "0,1"
"act_holster" "4"
"act_reload" "3"
"act_draw" "4"
"act_idle" "0,1"
"snd_fire" "Weapon_Galil.Single"

View file

@ -13,12 +13,12 @@ entityDef weapon_glock18
"ammoRequired" "1"
"model_flash" "sprites/muzzleflash2.spr"
"actFire" "5"
"actFireLast" "6"
"actHolster" "9"
"actReload" "7,12"
"actDraw" "9,11"
"actIdle" "0,1,2"
"act_fire" "5"
"act_fireLast" "6"
"act_holster" "9"
"act_reload" "7,12"
"act_draw" "9,11"
"act_idle" "0,1,2"
"snd_fire" "Weapon_Glock.Single"
@ -64,6 +64,6 @@ entityDef fireInfo_altglock18
"numProjectiles" "3"
"fireRate" "0.5"
"accuracyDivisor" "75"
"actFire" "3,4"
"act_fire" "3,4"
"snd_fire" "Weapon_Glock.Burst"
}

View file

@ -17,8 +17,8 @@ entityDef weapon_hegrenade
"silent_fire" "1"
"primed_fuse" "4"
"actIdle" "0"
"actDraw" "3"
"act_idle" "0"
"act_draw" "3"
"actPull" "1"
"actThrow" "2"

View file

@ -1,40 +1,38 @@
entityDef weapon_knife
{
"inherit" "CSBaseMelee"
"inherit" "CSBaseMelee"
"editor_usage" "Knife Weapon"
"model" "models/w_knife.mdl"
"model" "models/w_knife.mdl"
"model_view" "models/v_knife.mdl"
// weapon specific
"def_melee" "damage_knife"
"melee_distance" "48"
"inv_name" "Knife Weapon"
"clipSize" "6"
"ammoType" ""
"def_onFire" "projectile_knife"
"testDistance" "-48"
"inv_name" "Knife Weapon"
"ammoRequired" "0"
"clipSize" "0"
"clipSize" "0"
"silent_fire" "1"
"meleeRateMiss" "0.7"
"meleeRateHit" "0.7"
"actIdle" "0"
"actDraw" "3"
"actMeleeMiss" "1,2"
"actMeleeHit" "1,2"
"hudSlot" "2"
"hudSlotPos" "0"
}
entityDef damage_knife
{
"damage" "skill:plr_knife"
// "kickDir" "-1 0 0"
// "knockback" "20"
// "push" "20000"
"failRate" "0.7"
"fireRate" "0.7"
"snd_hit" "Weapon_Knife.Hit"
"snd_miss" "Weapon_Knife.Slash"
"snd_failed" "Weapon_Knife.Slash"
"act_idle" "0"
"act_draw" "3"
"act_fireFailed" "1,2"
"act_fire" "1,2"
"hudSlot" "2"
"hudSlotPos" "0"
}
entityDef projectile_knife
{
"spawnclass" "NSProjectile"
"damage" "skill:plr_knife"
"is_bullet" "1"
"decal_impact" "Impact.Shot"
"detonate_on_world" "1"
}

View file

@ -10,10 +10,10 @@ entityDef weapon_m249
"def_fireInfo" "fireInfo_m249"
"clipSize" "100"
"actFire" "1,2"
"actReload" "3"
"actDraw" "4"
"actIdle" "0"
"act_fire" "1,2"
"act_reload" "3"
"act_draw" "4"
"act_idle" "0"
"snd_fire" "Weapon_M249.Single"

View file

@ -10,12 +10,12 @@ entityDef weapon_m3
"def_fireInfo" "fireInfo_m3"
"clipSize" "8"
"actFire" "1,2"
"actReloadStart" "5"
"actReload" "3"
"actReloadEnd" "4"
"actDraw" "6"
"actIdle" "0"
"act_fire" "1,2"
"act_reloadStart" "5"
"act_reload" "3"
"act_reloadEnd" "4"
"act_draw" "6"
"act_idle" "0"
"snd_fire" "Weapon_M3.Single"

View file

@ -15,15 +15,15 @@ entityDef weapon_m4a1
"ammoPerShot" "1"
"fireRate" "0.0875"
"altSilences" "1"
"actAddSil" "6"
"actDetachSil" "13"
"altMode" "1"
"act_modeOn" "6"
"act_modeOff" "13"
// Unsilenced
"actFire" "8,9,10"
"actReload" "11"
"actDraw" "12"
"actIdle" "7"
"act_fire" "8,9,10"
"act_reload" "11"
"act_draw" "12"
"act_idle" "7"
"snd_fire" "Weapon_M4A1.Single"
@ -62,9 +62,9 @@ entityDef fireInfo_m4a1
entityDef fireInfo_m4a1_silenced
{
"inherit" "fireInfo_m4a1"
"actFire" "1,2,3"
"actReload" "4"
"actDraw" "5"
"actIdle" "0"
"act_fire" "1,2,3"
"act_reload" "4"
"act_draw" "5"
"act_idle" "0"
"snd_fire" "Weapon_M4A1.Silenced"
}

View file

@ -10,10 +10,10 @@ entityDef weapon_mac10
"def_fireInfo" "fireInfo_mac10"
"clipSize" "30"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_MAC10.Single"

View file

@ -10,10 +10,10 @@ entityDef weapon_mp5navy
"def_fireInfo" "fireInfo_mp5navy"
"clipSize" "30"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_MP5Navy.Single"

View file

@ -11,11 +11,11 @@ entityDef weapon_p228
"clipSize" "13"
"actFire" "1,2,3"
"actFireLast" "4"
"actReload" "5"
"actDraw" "6"
"actIdle" "0"
"act_fire" "1,2,3"
"act_fireLast" "4"
"act_reload" "5"
"act_draw" "6"
"act_idle" "0"
"snd_fire" "Weapon_P228.Single"

View file

@ -10,10 +10,10 @@ entityDef weapon_p90
"def_fireInfo" "fireInfo_p90"
"clipSize" "50"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_P90.Single"

View file

@ -11,10 +11,10 @@ entityDef weapon_scout
"clipSize" "10"
"actFire" "1,2"
"actReload" "3"
"actDraw" "4"
"actIdle" "0"
"act_fire" "1,2"
"act_reload" "3"
"act_draw" "4"
"act_idle" "0"
"snd_fire" "Weapon_Scout.Single"

View file

@ -10,10 +10,10 @@ entityDef weapon_sg550
"def_fireInfo" "fireInfo_sg550"
"clipSize" "30"
"actFire" "1,2"
"actReload" "3"
"actDraw" "4"
"actIdle" "0"
"act_fire" "1,2"
"act_reload" "3"
"act_draw" "4"
"act_idle" "0"
"snd_fire" "Weapon_SG550.Single"

View file

@ -11,10 +11,10 @@ entityDef weapon_sg552
"clipSize" "30"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_SG552.Single"

View file

@ -17,12 +17,12 @@ entityDef weapon_smokegrenade
"clipSize" "50"
"clipSizeDefault" "25"
"actFire" "5,6,7"
"act_fire" "5,6,7"
"actAltFire" "2"
"actHolster" "4"
"actReload" "3"
"actDraw" "4"
"actIdle" "0,1"
"act_holster" "4"
"act_reload" "3"
"act_draw" "4"
"act_idle" "0,1"
"snd_fire" "weapon_smokegrenade.shoot"
"snd_altfire" "weapon_smokegrenade.gl"

View file

@ -11,10 +11,10 @@ entityDef weapon_tmp
"clipSize" "30"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_TMP.Single"

View file

@ -11,10 +11,10 @@ entityDef weapon_ump45
"clipSize" "25"
"actFire" "3,4,5"
"actReload" "1"
"actDraw" "2"
"actIdle" "0"
"act_fire" "3,4,5"
"act_reload" "1"
"act_draw" "2"
"act_idle" "0"
"snd_fire" "Weapon_UMP45.Single"

View file

@ -32,9 +32,9 @@ entityDef weapon_usp
"semiAuto" "1"
"ammoRequired" "1"
"altSilences" "1"
"actAddSil" "7"
"actDetachSil" "15"
"altMode" "1"
"act_modeOn" "7"
"act_modeOff" "15"
"crossMinDist" "4"
"crossDeltaDist" "4"
@ -49,11 +49,11 @@ entityDef weapon_usp
"multiplierInaccuracy" "0.5"
// Unsilenced
"actDraw" "14"
"actIdle" "8"
"actFire" "9,10,11"
"actFireLast" "12"
"actReload" "13"
"act_draw" "14"
"act_idle" "8"
"act_fire" "9,10,11"
"act_fireLast" "12"
"act_reload" "13"
"snd_fire" "Weapon_USP.Single"
"hudSlot" "1"
@ -77,10 +77,10 @@ entityDef fireInfo_usp45_sil
{
"def_onFire" "projectile_usp45"
"model_flash" "sprites/muzzleflash2.spr"
"actDraw" "6"
"actIdle" "0"
"actReload" "5"
"actFire" "1,2,3"
"actFireLast" "4"
"act_draw" "6"
"act_idle" "0"
"act_reload" "5"
"act_fire" "1,2,3"
"act_fireLast" "4"
"snd_fire" "Weapon_USP.SilencedShot"
}

View file

@ -12,12 +12,12 @@ entityDef weapon_xm1014
"ammoType" "ammo_buckshot"
"actFire" "1,2"
"actReloadStart" "5"
"actReload" "3"
"actReloadEnd" "4"
"actDraw" "6"
"actIdle" "0"
"act_fire" "1,2"
"act_reloadStart" "5"
"act_reload" "3"
"act_reloadEnd" "4"
"act_draw" "6"
"act_idle" "0"
"snd_fire" "Weapon_XM1014.Single"

View file

@ -15,6 +15,15 @@ player.hitarmor
sample player/bhit_kevlar-1.wav
}
Player.Pain
{
sample player/pl_pain2.wav
sample player/pl_pain4.wav
sample player/pl_pain5.wav
sample player/pl_pain6.wav
sample player/pl_pain7.wav
}
Player.FallDamage
{
sample player/pl_pain2.wav
@ -139,4 +148,4 @@ Player.Swim
Player.PickupWeapon
{
sample items/gunpickup2.wav
}
}

View file

@ -0,0 +1,19 @@
typeInfo material
{
"C" "gs_material_concrete"
"D" "gs_material_dirt"
"F" "gs_material_flesh"
"G" "gs_material_grate"
"H" "gs_material_alien"
"M" "gs_material_metal"
"O" "gs_material_foliage"
"P" "gs_material_computer"
"R" "gs_material_rocks"
"S" "gs_material_slosh"
"T" "gs_material_tile"
"V" "gs_material_vent"
"W" "gs_material_wood"
"Y" "gs_material_glass"
"N" "gs_material_sand"
"K" "gs_material_snow"
}

View file

@ -1,45 +1,5 @@
exec default_controls.cfg
// game specific binds
bind "b" "buy"
bind "m" "chooseteam"
bind "g" "drop"
exec cvar_defaults.cfg
// game specific cvars
seta "hostname" "FreeCS Server"
seta "maxplayers" "8"
seta "mp_startmoney" "800"
seta "mp_buytime" "90"
seta "mp_freezetime" "6"
seta "mp_c4timer" "45"
seta "mp_roundtime" "5"
seta "fcs_knifeonly" "0"
seta "fcs_swapteams" "0"
seta "fcs_nopickups" "0"
seta "fcs_reward_kill" "300"
seta "fcs_penalty_pain" "-150"
seta "fcs_penalty_kill" "-1500"
seta "fcs_maxmoney" "16000"
seta "fcs_fillweapons" "0"
seta "fcs_autoreload" "0"
// cosmetic branding changes
seta "con_color" "255 150 0"
seta "vgui_color" "255 170 0"
seta "cross_color" "0 255 0"
// physics differences from valve/
seta pm_accelerate "4"
seta pm_airaccelerate "10"
seta pm_airstepsize "18"
seta pm_crouchviewheight "30"
seta pm_edgefriction "1"
seta pm_friction "4"
seta pm_gravity "800"
seta pm_normalviewheight "54"
seta pm_stepsize "18"
seta pm_stopspeed "75"
seta pm_walkspeed "250"
seta pm_wateraccelerate "8"
exec default_cvar.cfg
exec default_video.cfg
exec default_cstrike.cfg
exec default_aliases.cfg

View file

@ -0,0 +1,57 @@
// buy commands
alias ak47 "cmd buy weapon_ak47"
alias aug "cmd buy weapon_aug"
alias awp "cmd buy weapon_awp"
alias deagle "cmd buy weapon_deagle"
alias elites "cmd buy weapon_elite"
alias fn57 "cmd buy weapon_fiveseven"
alias g3sg1 "cmd buy weapon_g3sg1"
alias glock "cmd buy weapon_glock18"
alias m249 "cmd buy weapon_m249"
alias m3 "cmd buy weapon_m3"
alias m4a1 "cmd buy weapon_m4a1"
alias mac10 "cmd buy weapon_mac10"
alias mp5 "cmd buy weapon_mp5"
alias p228 "cmd buy weapon_p228"
alias p90 "cmd buy weapon_p90"
alias scout "cmd buy weapon_scout"
alias sg550 "cmd buy weapon_sg550"
alias sg552 "cmd buy weapon_sg552"
alias tmp "cmd buy weapon_tmp"
alias ump45 "cmd buy weapon_ump45"
alias usp "cmd buy weapon_usp"
alias xm1014 "cmd buy weapon_xm1014"
alias primammo "cmd buyammo 0"
alias secammo "cmd buyammo 1"
alias buyammo1 "primammo"
alias buyammo2 "secammo"
alias vest "cmd buy item_kevlar"
alias vesthelm "cmd buy item_kevlar_helmet"
alias flash "cmd buy weapon_flashbang"
alias hegren "cmd buy weapon_hegrenade"
alias vsgren "cmd buy weapon_smokegrenade"
alias defuser "cmd buy item_defuse"
alias nvg "cmd buy item_nightvision"
// radio commands
alias coverme "cmd coverme"
alias takepoint "cmd takepoint"
alias regroup "cmd regroup"
alias followme "cmd followme"
alias takingfire "cmd takingfire"
alias go "cmd go"
alias fallback "cmd fallback"
alias sticktog "cmd sticktog"
alias getinpos "cmd getinpos"
alias stormfront "cmd stormfront"
alias report "cmd report"
alias roger "cmd roger"
alias enemyspot "cmd enemyspot"
alias needbackup "cmd needbackup"
alias sectorclear "cmd sectorclear"
alias inposition "cmd inposition"
alias reportingin "cmd reportingin"
alias getout "cmd getout"
alias negative "cmd negative"
alias enemydown "cmd enemydown"

View file

@ -0,0 +1,41 @@
// game specific binds
bind b "buy"
bind m "chooseteam"
bind g "drop"
// game specific cvars
set hostname "FreeCS Server"
set maxplayers "8"
set mp_startmoney "800"
set mp_buytime "90"
set mp_freezetime "6"
set mp_c4timer "45"
set mp_roundtime "5"
set fcs_knifeonly "0"
set fcs_swapteams "0"
set fcs_nopickups "0"
set fcs_reward_kill "300"
set fcs_penalty_pain "-150"
set fcs_penalty_kill "-1500"
set fcs_maxmoney "16000"
set fcs_fillweapons "0"
set fcs_autoreload "0"
// cosmetic branding changes
set con_color "255 150 0"
set vgui_color "255 170 0"
set cross_color "0 255 0"
// physics differences from valve/
set pm_accelerate "4"
set pm_airaccelerate "10"
set pm_airstepsize "18"
set pm_crouchviewheight "30"
set pm_edgefriction "1"
set pm_friction "4"
set pm_gravity "800"
set pm_normalviewheight "54"
set pm_stepsize "18"
set pm_stopspeed "75"
set pm_walkspeed "250"
set pm_wateraccelerate "8"

View file

@ -9,6 +9,10 @@
{
name marco
funname "]I[ M4RC0 ]I["
fav_primary_ct weapon_mp5
fav_primary_t weapon_mac10
fav_secondary_ct weapon_deagle
fav_secondary_t weapon_elite
}
{
name rich
@ -56,4 +60,4 @@
}
{
name DEViL
}
}

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