From 594ba56f02a11ff71630bb719364ac55e08abcbb Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Tue, 14 Apr 2020 03:12:09 +0200 Subject: [PATCH] Started moving gamerule logic into classes, so we can manage seperate modes of play better. This will be much appreciated too by anyone modding CS to add additional gamemodes later for example. --- src/Makefile | 6 +- src/client/cstrike/cmds.c | 44 ++-- src/client/sentences.c | 5 +- src/gs-entbase/client/func_dustmotes.cpp | 2 +- .../server/func_physbox_multiplayer.cpp | 27 +++ src/server/cstrike.old/main.c | 2 +- src/server/cstrike/buy.c | 85 ++++++++ src/server/cstrike/client.c | 180 +--------------- src/server/cstrike/func_buyzone.cpp | 12 ++ src/server/cstrike/game_rules.c | 1 + src/server/cstrike/gamerules.c | 77 ------- src/server/cstrike/gamerules.cpp | 176 ++++++++++++++++ src/server/cstrike/gamerules_multiplayer.cpp | 105 ++++++++++ .../gamerules_singleplayer.cpp} | 86 +++++--- src/server/cstrike/progs.src | 9 +- src/server/cstrike/server.c | 32 +-- src/server/entry.c | 55 ++--- src/server/gamerules.cpp | 130 ++++++++++++ src/server/gearbox/gamerules.cpp | 174 ++++++++++++++++ src/server/gearbox/gamerules_multiplayer.cpp | 114 ++++++++++ ...gamerules.c => gamerules_singleplayer.cpp} | 90 ++++---- src/server/gearbox/progs.src | 6 +- src/server/hunger/gamerules.c | 133 ------------ src/server/hunger/progs.src | 6 +- src/server/poke646/gamerules.cpp | 174 ++++++++++++++++ src/server/poke646/gamerules_multiplayer.cpp | 80 +++++++ ...gamerules.c => gamerules_singleplayer.cpp} | 88 ++++---- src/server/poke646/progs.src | 6 +- src/server/rewolf/gamerules.cpp | 174 ++++++++++++++++ src/server/rewolf/gamerules_multiplayer.cpp | 80 +++++++ .../gamerules_singleplayer.cpp} | 85 +++++--- src/server/rewolf/progs.src | 6 +- src/server/scihunt/gamerules_multiplayer.cpp | 115 +++++++++++ src/server/scihunt/progs.src | 5 +- src/server/scihunt/server.c | 10 +- src/server/sentences.c | 5 +- src/server/spawn.c | 8 +- src/server/tfc/gamerules.c | 127 ------------ src/server/tfc/gamerules.cpp | 195 ++++++++++++++++++ src/server/tfc/progs.src | 6 +- src/server/tfc/server.c | 37 ++++ src/server/valve/client.c | 183 +--------------- src/server/valve/damage.c | 2 +- src/server/valve/gamerules.cpp | 174 ++++++++++++++++ src/server/valve/gamerules_multiplayer.cpp | 114 ++++++++++ ...gamerules.c => gamerules_singleplayer.cpp} | 82 ++++---- src/server/valve/input.c | 2 +- src/server/valve/progs.src | 6 +- src/server/valve/server.c | 18 +- src/server/vote.c | 6 +- tfc/data.pk3dir/sound/weapons_tfc.sndshd | 5 + 51 files changed, 2359 insertions(+), 991 deletions(-) create mode 100644 src/server/cstrike/buy.c delete mode 100644 src/server/cstrike/gamerules.c create mode 100644 src/server/cstrike/gamerules.cpp create mode 100644 src/server/cstrike/gamerules_multiplayer.cpp rename src/server/{rewolf/gamerules.c => cstrike/gamerules_singleplayer.cpp} (51%) create mode 100644 src/server/gamerules.cpp create mode 100644 src/server/gearbox/gamerules.cpp create mode 100644 src/server/gearbox/gamerules_multiplayer.cpp rename src/server/gearbox/{gamerules.c => gamerules_singleplayer.cpp} (68%) delete mode 100644 src/server/hunger/gamerules.c create mode 100644 src/server/poke646/gamerules.cpp create mode 100644 src/server/poke646/gamerules_multiplayer.cpp rename src/server/poke646/{gamerules.c => gamerules_singleplayer.cpp} (59%) create mode 100644 src/server/rewolf/gamerules.cpp create mode 100644 src/server/rewolf/gamerules_multiplayer.cpp rename src/server/{scihunt/gamerules.c => rewolf/gamerules_singleplayer.cpp} (51%) create mode 100644 src/server/scihunt/gamerules_multiplayer.cpp delete mode 100644 src/server/tfc/gamerules.c create mode 100644 src/server/tfc/gamerules.cpp create mode 100644 src/server/tfc/server.c create mode 100644 src/server/valve/gamerules.cpp create mode 100644 src/server/valve/gamerules_multiplayer.cpp rename src/server/valve/{gamerules.c => gamerules_singleplayer.cpp} (66%) diff --git a/src/Makefile b/src/Makefile index 867c1614..48c0f2d5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,15 +14,15 @@ games: mkdir -p ../valve/data.pk3dir $(CC) client/valve/progs.src $(CC) server/valve/progs.src + mkdir -p ../tfc/data.pk3dir + $(CC) client/tfc/progs.src + $(CC) server/tfc/progs.src mkdir -p ../rewolf/data.pk3dir $(CC) client/rewolf/progs.src $(CC) server/rewolf/progs.src mkdir -p ../gearbox/data.pk3dir $(CC) client/gearbox/progs.src $(CC) server/gearbox/progs.src - mkdir -p ../tfc/data.pk3dir - $(CC) client/tfc/progs.src - $(CC) server/tfc/progs.src mods: mkdir -p ../cstrike/data.pk3dir diff --git a/src/client/cstrike/cmds.c b/src/client/cstrike/cmds.c index e2b6f270..7e3cb60d 100644 --- a/src/client/cstrike/cmds.c +++ b/src/client/cstrike/cmds.c @@ -51,70 +51,70 @@ Game_ConsoleCommand(void) sendevent("WeaponDrop", ""); break; case "glock": - sendevent("PlayerBuyWeapon", "f", WEAPON_GLOCK18); + sendevent("BuyWeapon", "f", WEAPON_GLOCK18); break; case "usp": - sendevent("PlayerBuyWeapon", "f", WEAPON_USP45); + sendevent("BuyWeapon", "f", WEAPON_USP45); break; case "p228": - sendevent("PlayerBuyWeapon", "f", WEAPON_P228); + sendevent("BuyWeapon", "f", WEAPON_P228); break; case "deagle": - sendevent("PlayerBuyWeapon", "f", WEAPON_DEAGLE); + sendevent("BuyWeapon", "f", WEAPON_DEAGLE); break; case "fn57": - sendevent("PlayerBuyWeapon", "f", WEAPON_FIVESEVEN); + sendevent("BuyWeapon", "f", WEAPON_FIVESEVEN); break; case "elites": - sendevent("PlayerBuyWeapon", "f", WEAPON_ELITES); + sendevent("BuyWeapon", "f", WEAPON_ELITES); break; case "m3": - sendevent("PlayerBuyWeapon", "f", WEAPON_M3); + sendevent("BuyWeapon", "f", WEAPON_M3); break; case "xm1014": - sendevent("PlayerBuyWeapon", "f", WEAPON_XM1014); + sendevent("BuyWeapon", "f", WEAPON_XM1014); break; case "tmp": - sendevent("PlayerBuyWeapon", "f", WEAPON_TMP); + sendevent("BuyWeapon", "f", WEAPON_TMP); break; case "mac10": - sendevent("PlayerBuyWeapon", "f", WEAPON_MAC10); + sendevent("BuyWeapon", "f", WEAPON_MAC10); break; case "mp5": - sendevent("PlayerBuyWeapon", "f", WEAPON_MP5); + sendevent("BuyWeapon", "f", WEAPON_MP5); break; case "ump45": - sendevent("PlayerBuyWeapon", "f", WEAPON_UMP45); + sendevent("BuyWeapon", "f", WEAPON_UMP45); break; case "p90": - sendevent("PlayerBuyWeapon", "f", WEAPON_P90); + sendevent("BuyWeapon", "f", WEAPON_P90); break; case "ak47": - sendevent("PlayerBuyWeapon", "f", WEAPON_AK47); + sendevent("BuyWeapon", "f", WEAPON_AK47); break; case "m4a1": - sendevent("PlayerBuyWeapon", "f", WEAPON_M4A1); + sendevent("BuyWeapon", "f", WEAPON_M4A1); break; case "sg552": - sendevent("PlayerBuyWeapon", "f", WEAPON_SG552); + sendevent("BuyWeapon", "f", WEAPON_SG552); break; case "aug": - sendevent("PlayerBuyWeapon", "f", WEAPON_AUG); + sendevent("BuyWeapon", "f", WEAPON_AUG); break; case "scout": - sendevent("PlayerBuyWeapon", "f", WEAPON_SCOUT); + sendevent("BuyWeapon", "f", WEAPON_SCOUT); break; case "sg550": - sendevent("PlayerBuyWeapon", "f", WEAPON_SG550); + sendevent("BuyWeapon", "f", WEAPON_SG550); break; case "awp": - sendevent("PlayerBuyWeapon", "f", WEAPON_AWP); + sendevent("BuyWeapon", "f", WEAPON_AWP); break; case "g3sg1": - sendevent("PlayerBuyWeapon", "f", WEAPON_G3SG1); + sendevent("BuyWeapon", "f", WEAPON_G3SG1); break; case "m249": - sendevent("PlayerBuyWeapon", "f", WEAPON_PARA); + sendevent("BuyWeapon", "f", WEAPON_PARA); break; case "buyammo1": case "primammo": diff --git a/src/client/sentences.c b/src/client/sentences.c index ae442456..178c8a92 100644 --- a/src/client/sentences.c +++ b/src/client/sentences.c @@ -83,10 +83,11 @@ Sentences_Init(void) /* allocate memory and increase count */ #ifdef DYNAMIC_SENTENCES + g_sentences_count++; g_sentences = memrealloc(g_sentences, sizeof(sentences_t), - g_sentences_count, - ++g_sentences_count); + x, + g_sentences_count); #else if (g_sentences_count + 1 >= SENTENCES_LIMIT) { print("^1WARNING: ^7Reached limit of max sentences!\n"); diff --git a/src/gs-entbase/client/func_dustmotes.cpp b/src/gs-entbase/client/func_dustmotes.cpp index d7208865..1dc184ad 100644 --- a/src/gs-entbase/client/func_dustmotes.cpp +++ b/src/gs-entbase/client/func_dustmotes.cpp @@ -14,7 +14,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/*QUAKED func_dustmotes (1 0 0) (-8 -8 -8) (8 8 8) ? +/*QUAKED func_dustmotes (0 .5 .8) ? Dustmote emitting brush volume. */ diff --git a/src/gs-entbase/server/func_physbox_multiplayer.cpp b/src/gs-entbase/server/func_physbox_multiplayer.cpp index 90b17b6d..4d9183a5 100644 --- a/src/gs-entbase/server/func_physbox_multiplayer.cpp +++ b/src/gs-entbase/server/func_physbox_multiplayer.cpp @@ -1,3 +1,30 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*QUAKED func_physbox_multiplayer (0 .5 .8) ? +"targetname" Name + +Physics brush (server) - same for all player on server +*/ + +/*QUAKED func_physbox (0 .5 .8) ? +"targetname" Name + +Physics brush (client) +*/ class func_physbox:CBaseEntity { diff --git a/src/server/cstrike.old/main.c b/src/server/cstrike.old/main.c index 6aa5b6b0..1a98f058 100644 --- a/src/server/cstrike.old/main.c +++ b/src/server/cstrike.old/main.c @@ -111,7 +111,7 @@ void Game_StartFrame(void) if (!iRescueZones && iHostagesMax > 0) { Game_CreateRescueZones(); } - + if (iBuyZones == 0) { Game_CreateBuyZones(); } diff --git a/src/server/cstrike/buy.c b/src/server/cstrike/buy.c new file mode 100644 index 00000000..8ada65f8 --- /dev/null +++ b/src/server/cstrike/buy.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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_cstrikeWeaponPrice[] = +{ + WEAPON_NONE, + WEAPON_M3, + WEAPON_XM1014, + WEAPON_MP5, + WEAPON_P90, + WEAPON_UMP45, + WEAPON_MAC10, + WEAPON_TMP, + WEAPON_AK47, + WEAPON_SG552, + WEAPON_M4A1, + WEAPON_AUG, + WEAPON_SCOUT, + WEAPON_AWP, + WEAPON_G3SG1, + WEAPON_SG550, + WEAPON_PARA, + WEAPON_USP45, + WEAPON_GLOCK18, + WEAPON_DEAGLE, + WEAPON_P228, + WEAPON_ELITES, + WEAPON_FIVESEVEN, + WEAPON_KNIFE, + WEAPON_HEGRENADE, + WEAPON_FLASHBANG, + WEAPON_SMOKEGRENADE, + WEAPON_C4BOMB +}; + +void +CSEv_BuyWeapon_f(float fWeapon) +{ + int iWeapon; + player pl = (player)self; + iWeapon = (int)fWeapon; + + if (Rules_BuyingPossible() == 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 ((pl.money - g_cstrikeWeaponPrice[iWeapon]) >= 0) { + Weapons_AddItem(pl, iWeapon); + //Ammo_AutoFill(iWeapon); + + //Weapon_Draw(iWeapon); + Money_AddMoney(pl, -g_cstrikeWeaponPrice[iWeapon]); + + sound(pl, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_IDLE); + } else { + //centerprint(pl, "You have insufficient funds!"); + } +} diff --git a/src/server/cstrike/client.c b/src/server/cstrike/client.c index 35fb52d9..3388438f 100644 --- a/src/server/cstrike/client.c +++ b/src/server/cstrike/client.c @@ -14,190 +14,16 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -var int autocvar_sv_networkeverything = FALSE; - -void -Game_ClientConnect(void) -{ - entity a; - bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname)); - - int playercount = 0; - for (a = world; (a = find(a, classname, "player"));) { - playercount++; - } - - /* we're the first. respawn all entities? */ - if (playercount == 0) { - for (a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { - CBaseEntity caw = (CBaseEntity)a; - caw.Respawn(); - } - } -} - -void -Game_ClientDisconnect(void) -{ - bprint(PRINT_HIGH, sprintf("%s disconnected\n", self.netname)); - - /* Make this unusable */ - self.solid = SOLID_NOT; - self.movetype = MOVETYPE_NONE; - self.modelindex = 0; - self.health = 0; - self.takedamage = 0; - self.SendFlags = PLAYER_MODELINDEX; -} - -void -Game_ClientKill(player pl) -{ - Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); -} - -void -Game_PlayerPreThink(player pl) -{ - -} - -void -Game_PlayerPostThink(player pl) -{ - Animation_PlayerUpdate(); - - pl.SendFlags |= PLAYER_KEEPALIVE; - - if (pl.old_modelindex != pl.modelindex) { - pl.SendFlags |= PLAYER_MODELINDEX; - } - if (pl.old_origin[0] != pl.origin[0]) { - pl.SendFlags |= PLAYER_ORIGIN; - } - if (pl.old_origin[1] != pl.origin[1]) { - pl.SendFlags |= PLAYER_ORIGIN; - } - if (pl.old_origin[2] != pl.origin[2]) { - pl.SendFlags |= PLAYER_ORIGIN_Z; - } - if (pl.old_angles[0] != pl.angles[0]) { - pl.SendFlags |= PLAYER_ANGLES_X; - } - if (pl.old_angles[1] != pl.angles[1]) { - pl.SendFlags |= PLAYER_ANGLES_Y; - } - if (pl.old_angles[2] != pl.angles[2]) { - pl.SendFlags |= PLAYER_ANGLES_Z; - } - if (pl.old_velocity[0] != pl.velocity[0]) { - pl.SendFlags |= PLAYER_VELOCITY; - } - if (pl.old_velocity[1] != pl.velocity[1]) { - pl.SendFlags |= PLAYER_VELOCITY; - } - if (pl.old_velocity[2] != pl.velocity[2]) { - pl.SendFlags |= PLAYER_VELOCITY_Z; - } - if (pl.old_flags != pl.flags) { - pl.SendFlags |= PLAYER_FLAGS; - } - if (pl.old_activeweapon != pl.activeweapon) { - pl.SendFlags |= PLAYER_WEAPON; - } - if (pl.old_items != pl.g_items) { - pl.SendFlags |= PLAYER_ITEMS; - } - if (pl.old_health != pl.health) { - pl.SendFlags |= PLAYER_HEALTH; - } - if (pl.old_armor != pl.armor) { - pl.SendFlags |= PLAYER_ARMOR; - } - if (pl.old_movetype != pl.movetype) { - pl.SendFlags |= PLAYER_MOVETYPE; - } - if (pl.old_viewofs != pl.view_ofs[2]) { - pl.SendFlags |= PLAYER_VIEWOFS; - } - if (pl.old_baseframe != pl.baseframe) { - pl.SendFlags |= PLAYER_BASEFRAME; - } - if (pl.old_frame != pl.frame) { - pl.SendFlags |= PLAYER_FRAME; - } - if (pl.old_a_ammo1 != pl.a_ammo1) { - pl.SendFlags |= PLAYER_AMMO1; - } - if (pl.old_a_ammo2 != pl.a_ammo2) { - pl.SendFlags |= PLAYER_AMMO2; - } - if (pl.old_a_ammo3 != pl.a_ammo3) { - pl.SendFlags |= PLAYER_AMMO3; - } - if (pl.old_cs_shotmultiplier != pl.cs_shotmultiplier) { - pl.SendFlags |= PLAYER_CSSHOT; - } - if (pl.old_cs_shottime != pl.cs_shottime) { - pl.SendFlags |= PLAYER_CSSHOTTIME; - } - - pl.old_modelindex = pl.modelindex; - pl.old_origin = pl.origin; - pl.old_angles = pl.angles; - pl.old_velocity = pl.velocity; - pl.old_flags = pl.flags; - pl.old_activeweapon = pl.activeweapon; - pl.old_items = pl.g_items; - pl.old_health = pl.health; - pl.old_armor = pl.armor; - pl.old_movetype = pl.movetype; - pl.old_viewofs = pl.view_ofs[2]; - pl.old_baseframe = pl.baseframe; - pl.old_frame = pl.frame; - pl.old_a_ammo1 = pl.a_ammo1; - pl.old_a_ammo2 = pl.a_ammo2; - pl.old_a_ammo3 = pl.a_ammo3; - pl.old_cs_shotmultiplier = pl.cs_shotmultiplier; - pl.old_cs_shottime = pl.cs_shottime; -} - void Game_RunClientCommand(void) { + player pl = (player)self; + pl.buyzone = FALSE; + Footsteps_Update(); QPhysics_Run(self); } -void -Game_PutClientInServer(player pl) -{ - pl.classname = "spectator"; - pl.health = 0; - pl.armor = 0; - pl.takedamage = DAMAGE_NO; - pl.solid = SOLID_NOT; - pl.movetype = MOVETYPE_NOCLIP; - pl.SendEntity = Player_SendEntity; - pl.flags = FL_CLIENT; - pl.weapon = 0; - pl.viewzoom = 1.0f; - pl.model = 0; - setsize (pl, [-16,-16,-16], [16,16,16]); - pl.view_ofs = pl.velocity = [0,0,0]; - forceinfokey(pl, "*spec", "2"); - entity eTarget = world; - - Spawn_MakeSpectator(); - Spawn_ObserverCam(); - - // Because we don't want to reset these when we die - Money_AddMoney(pl, autocvar_mp_startmoney); - - pl.team = 0; - forceinfokey(pl, "*team", "0"); -} - void SV_SendChat(entity sender, string msg, entity eEnt, float fType) { diff --git a/src/server/cstrike/func_buyzone.cpp b/src/server/cstrike/func_buyzone.cpp index 9f6c7315..cad505a3 100644 --- a/src/server/cstrike/func_buyzone.cpp +++ b/src/server/cstrike/func_buyzone.cpp @@ -42,9 +42,21 @@ Choices for 'team' include: class func_buyzone:CBaseTrigger { + virtual void(void) touch; virtual void(void) Respawn; }; +void +func_buyzone::touch(void) +{ + player pl = (player)other; + if (!(other.flags & FL_CLIENT)) { + return; + } + + pl.buyzone = TRUE; +} + void func_buyzone::Respawn(void) { diff --git a/src/server/cstrike/game_rules.c b/src/server/cstrike/game_rules.c index d5b907fe..6142f81c 100755 --- a/src/server/cstrike/game_rules.c +++ b/src/server/cstrike/game_rules.c @@ -92,6 +92,7 @@ Rules_BuyingPossible(void) } if (pl.buyzone == FALSE) { + centerprint(pl, "Sorry, you aren't in a buyzone.\n"); return FALSE; } diff --git a/src/server/cstrike/gamerules.c b/src/server/cstrike/gamerules.c deleted file mode 100644 index 3cfb06e1..00000000 --- a/src/server/cstrike/gamerules.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016-2020 Marco Hladik - * - * 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. - */ - -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ -void -Gamerules_DecodeChangeParms(player pl) -{ - 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; -} - -/* prepare the client-info for level-transition */ -void -Gamerules_SetChangeParms(player pl) -{ - 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]; - parm10 = pl.g_items; - parm11 = pl.activeweapon; -} - -/* yuck, whenever 'changelevel' does not happen. */ -void -Gamerules_SetNewParms(void) -{ - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; -} - -void -CSEv_JoinT_f(float c) -{ - player pl = (player)self; - pl.charmodel = c; - CSEv_GamePlayerSpawn_f(pl.charmodel); -}; - -void -CSEv_JoinCT_f(float c) -{ - player pl = (player)self; - pl.charmodel = c + 4; - CSEv_GamePlayerSpawn_f(pl.charmodel); -} diff --git a/src/server/cstrike/gamerules.cpp b/src/server/cstrike/gamerules.cpp new file mode 100644 index 00000000..ecaf35f9 --- /dev/null +++ b/src/server/cstrike/gamerules.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +class HLGameRules:CGameRules +{ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerKill; + virtual void(player) PlayerPostFrame; + + virtual void(void) LevelNewParms; +}; + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +HLGameRules::PlayerPostFrame(player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; + pl.old_cs_shotmultiplier = pl.cs_shotmultiplier; + pl.old_cs_shottime = pl.cs_shottime; +} + +void +HLGameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +void +HLGameRules::PlayerConnect(entity pl) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + int playercount = 0; + for (a = world; (a = find(a, ::classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + Nodes_Init(); + } +} + +void +HLGameRules::PlayerDisconnect(entity pl) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = PLAYER_MODELINDEX; +} + +void +HLGameRules::PlayerKill(player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} diff --git a/src/server/cstrike/gamerules_multiplayer.cpp b/src/server/cstrike/gamerules_multiplayer.cpp new file mode 100644 index 00000000..77b0c462 --- /dev/null +++ b/src/server/cstrike/gamerules_multiplayer.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 CSMultiplayerRules:HLGameRules +{ + virtual void(void) FrameStart; + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelDecodeParms; +}; + +void +CSMultiplayerRules::FrameStart(void) +{ + if ((g_cs_alive_t + g_cs_alive_ct) == 0) { + int iInGamePlayers = 0; + for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) { + iInGamePlayers++; + } + + if ((iInGamePlayers > 0) && (g_cs_gamestate != GAME_COMMENCING && g_cs_gamestate != GAME_END)) { + Timer_Begin(2, GAME_COMMENCING); + } else if (iInGamePlayers == 0) { + g_cs_gamestate = GAME_INACTIVE; + g_cs_gametime = 0; + g_cs_roundswon_t = 0; + g_cs_roundswon_ct = 0; + g_cs_roundsplayed = 0; + } else { + Timer_Update(); // Timer that happens once players have started joining + } + } else { + Timer_Update(); // Normal gameplay timer + } +} + +void +CSMultiplayerRules::LevelDecodeParms(player pl) +{ + +} + +void +CSMultiplayerRules::PlayerSpawn(player pl) +{ + pl.classname = "spectator"; + pl.health = 0; + pl.armor = 0; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NOCLIP; + pl.SendEntity = Player_SendEntity; + pl.flags = FL_CLIENT; + pl.weapon = 0; + pl.viewzoom = 1.0f; + pl.model = 0; + setsize (pl, [-16,-16,-16], [16,16,16]); + pl.view_ofs = pl.velocity = [0,0,0]; + forceinfokey(pl, "*spec", "2"); + entity eTarget = world; + + Spawn_MakeSpectator(); + Spawn_ObserverCam(); + + // Because we don't want to reset these when we die + Money_AddMoney(pl, autocvar_mp_startmoney); + + pl.team = 0; + forceinfokey(pl, "*team", "0"); +} + +void weaponbox_spawn(player pl) +{ +} + +void +CSEv_JoinT_f(float c) +{ + player pl = (player)self; + pl.charmodel = c; + CSEv_GamePlayerSpawn_f(pl.charmodel); +}; + +void +CSEv_JoinCT_f(float c) +{ + player pl = (player)self; + pl.charmodel = c + 4; + CSEv_GamePlayerSpawn_f(pl.charmodel); +} diff --git a/src/server/rewolf/gamerules.c b/src/server/cstrike/gamerules_singleplayer.cpp similarity index 51% rename from src/server/rewolf/gamerules.c rename to src/server/cstrike/gamerules_singleplayer.cpp index 4194bbc3..a13833a9 100644 --- a/src/server/rewolf/gamerules.c +++ b/src/server/cstrike/gamerules_singleplayer.cpp @@ -14,10 +14,18 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ +class CSSingleplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelChangeParms; + virtual void(player) LevelDecodeParms; +}; + void -Gamerules_DecodeChangeParms(player pl) +CSSingleplayerRules::LevelDecodeParms(player pl) { g_landmarkpos[0] = parm1; g_landmarkpos[1] = parm2; @@ -30,11 +38,17 @@ Gamerules_DecodeChangeParms(player pl) pl.velocity[2] = parm9; pl.g_items = parm10; pl.activeweapon = parm11; + pl.flags = parm64; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } } -/* prepare the client-info for level-transition */ void -Gamerules_SetChangeParms(player pl) +CSSingleplayerRules::LevelChangeParms(player pl) { parm1 = g_landmarkpos[0]; parm2 = g_landmarkpos[1]; @@ -45,46 +59,50 @@ Gamerules_SetChangeParms(player pl) parm7 = pl.velocity[0]; parm8 = pl.velocity[1]; parm9 = pl.velocity[2]; + parm64 = pl.flags; parm10 = pl.g_items; parm11 = pl.activeweapon; } -/* yuck, whenever 'changelevel' does not happen. */ void -Gamerules_SetNewParms(void) +CSSingleplayerRules::PlayerSpawn(player pl) { - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; -} + 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); -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* this is where the mods want to deviate */ entity spot; - if (cvar("sv_playerslots") == 1) { - if (startspot != "") { - Gamerules_DecodeChangeParms(pl); - setorigin(pl, Landmark_GetSpot()); - } else { - spot = find(world, classname, "info_player_start"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - } + if (startspot != "") { + dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); + LevelDecodeParms(pl); + setorigin(pl, Landmark_GetSpot()); } else { - spot = Spawn_SelectRandom("info_player_deathmatch"); + LevelNewParms(); + spot = find(world, ::classname, "info_player_start"); setorigin(pl, spot.origin); pl.angles = spot.angles; - pl.g_items |= ITEM_SUIT; } - Client_FixAngle(pl, pl.angles); -} -void weaponbox_spawn(player pl) -{ - -} + Weapons_RefreshAmmo(pl); + Client_FixAngle(pl, pl.angles); +} diff --git a/src/server/cstrike/progs.src b/src/server/cstrike/progs.src index 33606c3b..139e8e10 100755 --- a/src/server/cstrike/progs.src +++ b/src/server/cstrike/progs.src @@ -84,11 +84,18 @@ ../spawn.c ../vox.c ../../shared/valve/animations.c + +../gamerules.cpp ../cstrike/game_money.c ../cstrike/game_timer.c ../cstrike/game_rules.c -../cstrike/gamerules.c + +../cstrike/gamerules.cpp +../cstrike/gamerules_singleplayer.cpp +../cstrike/gamerules_multiplayer.cpp + ../cstrike/client.c +../cstrike/buy.c ../client.c ../cstrike/server.c ../server.c diff --git a/src/server/cstrike/server.c b/src/server/cstrike/server.c index 168780e0..ed5cf93f 100644 --- a/src/server/cstrike/server.c +++ b/src/server/cstrike/server.c @@ -14,33 +14,15 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void Game_StartFrame(void) -{ - if ((g_cs_alive_t + g_cs_alive_ct) == 0) { - int iInGamePlayers = 0; - for (entity eFind = world; (eFind = find(eFind, classname, "player"));) { - iInGamePlayers++; - } - - if ((iInGamePlayers > 0) && (g_cs_gamestate != GAME_COMMENCING && g_cs_gamestate != GAME_END)) { - Timer_Begin(2, GAME_COMMENCING); - } else if (iInGamePlayers == 0) { - g_cs_gamestate = GAME_INACTIVE; - g_cs_gametime = 0; - g_cs_roundswon_t = 0; - g_cs_roundswon_ct = 0; - g_cs_roundsplayed = 0; - } else { - Timer_Update(); // Timer that happens once players have started joining - } - } else { - Timer_Update(); // Normal gameplay timer - } -} -float Game_ConsoleCmd(string cmd) +void +Game_InitRules(void) { - return FALSE; + if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { + g_grMode = spawn(CSSingleplayerRules); + } else { + g_grMode = spawn(CSMultiplayerRules); + } } void Game_Worldspawn(void) diff --git a/src/server/entry.c b/src/server/entry.c index 32b44ec3..97644382 100644 --- a/src/server/entry.c +++ b/src/server/entry.c @@ -21,29 +21,29 @@ void main(void) void StartFrame(void) { - for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { + for (entity a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { CBaseEntity ent = (CBaseEntity)a; ent.ParentUpdate(); } - Game_StartFrame(); + g_grMode.FrameStart(); Vote_Frame(); } void ClientConnect(float csqc_active) { - Game_ClientConnect(); + g_grMode.PlayerConnect(self); } void ClientDisconnect(void) { - Game_ClientDisconnect(); + g_grMode.PlayerDisconnect(self); } void ClientKill(void) { player pl = (player)self; - Game_ClientKill(pl); + g_grMode.PlayerKill(pl); } void SpectatorThink(void) @@ -69,30 +69,30 @@ void PutClientInServer(void) } pl = (player)self; - Game_PutClientInServer(pl); + g_grMode.PlayerSpawn(pl); } void PlayerPreThink(void) { player pl = (player)self; - Game_PlayerPreThink(pl); + g_grMode.PlayerPreFrame(pl); } void PlayerPostThink(void) { player pl = (player)self; - Game_PlayerPostThink(pl); + g_grMode.PlayerPostFrame(pl); } void SetNewParms(void) { - Gamerules_SetNewParms(); + g_grMode.LevelNewParms(); } void SetChangeParms(void) { player pl = (player)self; - Gamerules_SetChangeParms(pl); + g_grMode.LevelChangeParms(pl); } void SV_RunClientCommand(void) @@ -110,6 +110,20 @@ void SV_ParseClientCommand(string cmd) } void init(float prevprogs) +{ + Plugin_Init(); +} + +void init_respawn(void) +{ + for (entity a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity ent = (CBaseEntity)a; + ent.Respawn(); + } + remove(self); +} + +void initents(void) { string sTemp; @@ -117,10 +131,11 @@ void init(float prevprogs) // Let's load materials.txt because someone thought this was the best idea filestream fileMaterial = fopen("sound/materials.txt", FILE_READ); + hashMaterials = __NULL__; hashMaterials = hash_createtab(2, HASH_ADD); if (fileMaterial >= 0) { - while ((sTemp = fgets(fileMaterial))) { + while ((sTemp = fgets(fileMaterial))) { // Tokenize and just parse this stuff in if (tokenize_console(sTemp) == 2) { hash_add(hashMaterials, strtolower(argv(1)), str2chr(argv(0), 0)); @@ -134,20 +149,7 @@ void init(float prevprogs) } PMove_Init(); - Plugin_Init(); -} -void init_respawn(void) -{ - for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { - CBaseEntity ent = (CBaseEntity)a; - ent.Respawn(); - } - remove(self); -} - -void initents(void) -{ precache_sound("weapons/explode3.wav"); precache_sound("weapons/explode4.wav"); precache_sound("weapons/explode5.wav"); @@ -214,6 +216,7 @@ void initents(void) precache_sound("items/flashlight1.wav"); precache_sound("common/null.wav"); + Game_InitRules(); Game_Worldspawn(); Decals_Init(); Sentences_Init(); @@ -241,6 +244,6 @@ void worldspawn(void) float ConsoleCmd(string cmd) { - return Game_ConsoleCmd(cmd); + player pl = (player)self; + return g_grMode.ConsoleCommand(pl, cmd); } - diff --git a/src/server/gamerules.cpp b/src/server/gamerules.cpp new file mode 100644 index 00000000..5e24baf9 --- /dev/null +++ b/src/server/gamerules.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 CGameRules +{ + void() CGameRules; + + /* logic */ + virtual void() FrameStart; + virtual float(player,string) ConsoleCommand; + + /* client */ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerKill; + virtual void(player) PlayerSpawn; + virtual void(player) PlayerPreFrame; + virtual void(player) PlayerPostFrame; + + /* level transitions */ + virtual void(void) LevelNewParms; + virtual void(player) LevelChangeParms; + + /* spectator */ + /*virtual void(player) SpectatorConnect; + virtual void(player) SpectatorDisconnect; + virtual void(player) SpectatorThink;*/ +}; + +/* init */ +void +CGameRules::Init(void) +{ + //print("Init!\n"); +} + +/* logic */ +void +CGameRules::FrameStart(void) +{ + //print("StartFrame!\n"); +} +float +CGameRules::ConsoleCommand(player pl, string cmd) +{ + return FALSE; +} + +/* client */ +void +CGameRules::PlayerConnect(entity pl) +{ + //print("ClientConnect!\n"); +} +void +CGameRules::PlayerDisconnect(entity pl) +{ + //print("ClientDisconnect!\n"); +} +void +CGameRules::PlayerKill(player pl) +{ + //print("ClientKill!\n"); +} +void +CGameRules::PlayerSpawn(player pl) +{ + //print("PutClientInServer!\n"); +} +void +CGameRules::PlayerPreFrame(player pl) +{ + //print("PlayerPreThink!\n"); +} +void +CGameRules::PlayerPostFrame(player pl) +{ + //print("PlayerPostThink!\n"); +} + +/* level transitions */ +void +CGameRules::LevelNewParms(void) +{ + //print("LevelNewParms!\n"); +} +void +CGameRules::LevelChangeParms(player pl) +{ + //print("LevelChangeParms!\n"); +} + +/* spectator */ +/*void +CGameRules::SpectatorConnect(player pl) +{ + //print("SpectatorConnect!\n"); +} +void +CGameRules::SpectatorDisconnect(player pl) +{ + //print("SpectatorDisconnect!\n"); +} +void +CGameRules::SpectatorThink(player pl) +{ + //print("SpectatorThink!\n"); +}*/ + +void +CGameRules::CGameRules(void) +{ + //print("CGameRules!\n"); +} + +/* our currently running mode */ +CGameRules g_grMode; diff --git a/src/server/gearbox/gamerules.cpp b/src/server/gearbox/gamerules.cpp new file mode 100644 index 00000000..0c17cdbd --- /dev/null +++ b/src/server/gearbox/gamerules.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +class HLGameRules:CGameRules +{ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerKill; + virtual void(player) PlayerPostFrame; + + virtual void(void) LevelNewParms; +}; + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +HLGameRules::PlayerPostFrame(player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} + +void +HLGameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +void +HLGameRules::PlayerConnect(entity pl) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + int playercount = 0; + for (a = world; (a = find(a, ::classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + Nodes_Init(); + } +} + +void +HLGameRules::PlayerDisconnect(entity pl) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = PLAYER_MODELINDEX; +} + +void +HLGameRules::PlayerKill(player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} diff --git a/src/server/gearbox/gamerules_multiplayer.cpp b/src/server/gearbox/gamerules_multiplayer.cpp new file mode 100644 index 00000000..c933a234 --- /dev/null +++ b/src/server/gearbox/gamerules_multiplayer.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 HLMultiplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelDecodeParms; +}; + +void +HLMultiplayerRules::LevelDecodeParms(player pl) +{ + 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 = ITEM_CROWBAR | ITEM_GLOCK | ITEM_SUIT; + pl.activeweapon = WEAPON_GLOCK; + pl.flags = parm64; + + pl.ammo_9mm = 44; + pl.ammo_357 = parm13; + pl.ammo_buckshot = parm14; + pl.ammo_m203_grenade = parm15; + pl.ammo_bolt = parm16; + pl.ammo_rocket = parm17; + pl.ammo_uranium = parm18; + pl.ammo_handgrenade = parm19; + pl.ammo_satchel = parm20; + pl.ammo_tripmine = parm21; + pl.ammo_snark = parm22; + pl.ammo_hornet = parm23; + + pl.glock_mag = 18; + pl.mp5_mag = parm25; + pl.python_mag = parm26; + pl.shotgun_mag = parm27; + pl.crossbow_mag = parm28; + pl.rpg_mag = parm29; + pl.satchel_chg = parm30; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } +} + +void +HLMultiplayerRules::PlayerSpawn(player pl) +{ + /* this is where the mods want to deviate */ + entity spot; + + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + string mymodel = infokey(pl, "model"); + + if (mymodel) { + mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); + if (whichpack(mymodel)) { + pl.model = mymodel; + } + } + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + LevelNewParms(); + LevelDecodeParms(pl); + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + Weapons_RefreshAmmo(pl); + + Client_FixAngle(pl, pl.angles); +} diff --git a/src/server/gearbox/gamerules.c b/src/server/gearbox/gamerules_singleplayer.cpp similarity index 68% rename from src/server/gearbox/gamerules.c rename to src/server/gearbox/gamerules_singleplayer.cpp index c0451534..ccd0a5a8 100644 --- a/src/server/gearbox/gamerules.c +++ b/src/server/gearbox/gamerules_singleplayer.cpp @@ -14,10 +14,18 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ +class HLSingleplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelChangeParms; + virtual void(player) LevelDecodeParms; +}; + void -Gamerules_DecodeChangeParms(player pl) +HLSingleplayerRules::LevelDecodeParms(player pl) { g_landmarkpos[0] = parm1; g_landmarkpos[1] = parm2; @@ -30,6 +38,7 @@ Gamerules_DecodeChangeParms(player pl) pl.velocity[2] = parm9; pl.g_items = parm10; pl.activeweapon = parm11; + pl.flags = parm64; pl.ammo_9mm = parm12; pl.ammo_357 = parm13; @@ -62,11 +71,16 @@ Gamerules_DecodeChangeParms(player pl) pl.sniper_mag = parm37; pl.m249_mag = parm38; pl.sporelauncher_mag = parm39; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } } -/* prepare the client-info for level-transition */ void -Gamerules_SetChangeParms(player pl) +HLSingleplayerRules::LevelChangeParms(player pl) { parm1 = g_landmarkpos[0]; parm2 = g_landmarkpos[1]; @@ -77,6 +91,7 @@ Gamerules_SetChangeParms(player pl) parm7 = pl.velocity[0]; parm8 = pl.velocity[1]; parm9 = pl.velocity[2]; + parm64 = pl.flags; parm10 = pl.g_items; parm11 = pl.activeweapon; parm12 = pl.ammo_9mm; @@ -111,46 +126,45 @@ Gamerules_SetChangeParms(player pl) parm39 = pl.sporelauncher_mag; } -/* yuck, whenever 'changelevel' does not happen. */ void -Gamerules_SetNewParms(void) +HLSingleplayerRules::PlayerSpawn(player pl) { - 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 = parm39 = parm39 = 0; -} + 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); -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* this is where the mods want to deviate */ entity spot; - if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { - if (startspot != "") { - Gamerules_DecodeChangeParms(pl); - setorigin(pl, Landmark_GetSpot()); - } else { - Gamerules_SetNewParms(); - spot = find(world, classname, "info_player_start"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - } - Weapons_RefreshAmmo(pl); + if (startspot != "") { + dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); + LevelDecodeParms(pl); + setorigin(pl, Landmark_GetSpot()); } else { - Gamerules_SetNewParms(); - Gamerules_DecodeChangeParms(pl); - spot = Spawn_SelectRandom("info_player_deathmatch"); + LevelNewParms(); + spot = find(world, ::classname, "info_player_start"); setorigin(pl, spot.origin); pl.angles = spot.angles; - - pl.ammo_9mm = 68; - Weapons_AddItem(pl, WEAPON_CROWBAR); - Weapons_AddItem(pl, WEAPON_GLOCK); - pl.g_items |= ITEM_SUIT; } + + Weapons_RefreshAmmo(pl); Client_FixAngle(pl, pl.angles); -} +} diff --git a/src/server/gearbox/progs.src b/src/server/gearbox/progs.src index 47106732..ca8fd3bf 100755 --- a/src/server/gearbox/progs.src +++ b/src/server/gearbox/progs.src @@ -115,7 +115,11 @@ ../spawn.c ../vox.c ../../shared/valve/animations.c -../valve/gamerules.c + +../gamerules.cpp +../gearbox/gamerules.cpp +../gearbox/gamerules_singleplayer.cpp +../gearbox/gamerules_multiplayer.cpp ../valve/client.c ../client.c ../valve/server.c diff --git a/src/server/hunger/gamerules.c b/src/server/hunger/gamerules.c deleted file mode 100644 index fe7e53d5..00000000 --- a/src/server/hunger/gamerules.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2016-2020 Marco Hladik - * - * 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. - */ - -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ -void -Gamerules_DecodeChangeParms(player pl) -{ - 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.ammo_9mm = parm12; - pl.ammo_357 = parm13; - pl.ammo_buckshot = parm14; - pl.ammo_m203_grenade = parm15; - pl.ammo_bolt = parm16; - pl.ammo_rocket = parm17; - pl.ammo_uranium = parm18; - pl.ammo_handgrenade = parm19; - pl.ammo_satchel = parm20; - pl.ammo_tripmine = parm21; - pl.ammo_snark = parm22; - pl.ammo_hornet = parm23; - - pl.glock_mag = parm24; - pl.mp5_mag = parm25; - pl.python_mag = parm26; - pl.shotgun_mag = parm27; - pl.crossbow_mag = parm28; - pl.rpg_mag = parm29; - pl.satchel_chg = parm30; -} - -/* prepare the client-info for level-transition */ -void -Gamerules_SetChangeParms(player pl) -{ - 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]; - parm10 = pl.g_items; - parm11 = pl.activeweapon; - parm12 = pl.ammo_9mm; - parm13 = pl.ammo_357; - parm14 = pl.ammo_buckshot; - parm15 = pl.ammo_m203_grenade; - parm16 = pl.ammo_bolt; - parm17 = pl.ammo_rocket; - parm18 = pl.ammo_uranium; - parm19 = pl.ammo_handgrenade; - parm20 = pl.ammo_satchel; - parm21 = pl.ammo_tripmine; - parm22 = pl.ammo_snark; - parm23 = pl.ammo_hornet; - parm24 = pl.glock_mag; - parm25 = pl.mp5_mag; - parm26 = pl.python_mag; - parm27 = pl.shotgun_mag; - parm28 = pl.crossbow_mag; - parm29 = pl.rpg_mag; - parm30 = pl.satchel_chg; -} - -/* yuck, whenever 'changelevel' does not happen. */ -void -Gamerules_SetNewParms(void) -{ - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; -} - -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ - entity spot; - - if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { - if (startspot != "") { - Gamerules_DecodeChangeParms(pl); - setorigin(pl, Landmark_GetSpot()); - } else { - Gamerules_SetNewParms(); - spot = find(world, classname, "info_player_start"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - } - Weapons_RefreshAmmo(pl); - } else { - Gamerules_SetNewParms(); - Gamerules_DecodeChangeParms(pl); - spot = Spawn_SelectRandom("info_player_deathmatch"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - - pl.ammo_9mm = 68; - Weapons_AddItem(pl, WEAPON_CROWBAR); - Weapons_AddItem(pl, WEAPON_GLOCK); - pl.g_items |= ITEM_SUIT; - } - Client_FixAngle(pl, pl.angles); -} diff --git a/src/server/hunger/progs.src b/src/server/hunger/progs.src index 0a3ce52a..540a08a2 100755 --- a/src/server/hunger/progs.src +++ b/src/server/hunger/progs.src @@ -112,7 +112,11 @@ ../spawn.c ../vox.c ../../shared/valve/animations.c -../valve/gamerules.c + +../gamerules.cpp +../valve/gamerules.cpp +../valve/gamerules_singleplayer.cpp +../valve/gamerules_multiplayer.cpp ../valve/client.c ../client.c ../valve/server.c diff --git a/src/server/poke646/gamerules.cpp b/src/server/poke646/gamerules.cpp new file mode 100644 index 00000000..0c17cdbd --- /dev/null +++ b/src/server/poke646/gamerules.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +class HLGameRules:CGameRules +{ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerKill; + virtual void(player) PlayerPostFrame; + + virtual void(void) LevelNewParms; +}; + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +HLGameRules::PlayerPostFrame(player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} + +void +HLGameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +void +HLGameRules::PlayerConnect(entity pl) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + int playercount = 0; + for (a = world; (a = find(a, ::classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + Nodes_Init(); + } +} + +void +HLGameRules::PlayerDisconnect(entity pl) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = PLAYER_MODELINDEX; +} + +void +HLGameRules::PlayerKill(player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} diff --git a/src/server/poke646/gamerules_multiplayer.cpp b/src/server/poke646/gamerules_multiplayer.cpp new file mode 100644 index 00000000..0db6d4a0 --- /dev/null +++ b/src/server/poke646/gamerules_multiplayer.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 HLMultiplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelDecodeParms; +}; + +void +HLMultiplayerRules::LevelDecodeParms(player pl) +{ + +} + +void +HLMultiplayerRules::PlayerSpawn(player pl) +{ + /* this is where the mods want to deviate */ + entity spot; + + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + string mymodel = infokey(pl, "model"); + + if (mymodel) { + mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); + if (whichpack(mymodel)) { + pl.model = mymodel; + } + } + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + LevelNewParms(); + LevelDecodeParms(pl); + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + Weapons_RefreshAmmo(pl); + + Client_FixAngle(pl, pl.angles); +} + +void weaponbox_spawn(player pl) +{ +} diff --git a/src/server/poke646/gamerules.c b/src/server/poke646/gamerules_singleplayer.cpp similarity index 59% rename from src/server/poke646/gamerules.c rename to src/server/poke646/gamerules_singleplayer.cpp index 40a85627..03e59b8b 100644 --- a/src/server/poke646/gamerules.c +++ b/src/server/poke646/gamerules_singleplayer.cpp @@ -14,10 +14,18 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ +class HLSingleplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelChangeParms; + virtual void(player) LevelDecodeParms; +}; + void -Gamerules_DecodeChangeParms(player pl) +HLSingleplayerRules::LevelDecodeParms(player pl) { g_landmarkpos[0] = parm1; g_landmarkpos[1] = parm2; @@ -30,6 +38,7 @@ Gamerules_DecodeChangeParms(player pl) pl.velocity[2] = parm9; pl.g_items = parm10; pl.activeweapon = parm11; + pl.flags = parm64; pl.ammo_nail = parm12; pl.ammo_buckshot = parm13; @@ -43,11 +52,16 @@ Gamerules_DecodeChangeParms(player pl) pl.cmlwbr_mag = parm20; pl.xs_mag = parm21; pl.satchel_chg = parm22; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } } -/* prepare the client-info for level-transition */ void -Gamerules_SetChangeParms(player pl) +HLSingleplayerRules::LevelChangeParms(player pl) { parm1 = g_landmarkpos[0]; parm2 = g_landmarkpos[1]; @@ -58,6 +72,7 @@ Gamerules_SetChangeParms(player pl) parm7 = pl.velocity[0]; parm8 = pl.velocity[1]; parm9 = pl.velocity[2]; + parm64 = pl.flags; parm10 = pl.g_items; parm11 = pl.activeweapon; parm12 = pl.ammo_nail; @@ -73,44 +88,45 @@ Gamerules_SetChangeParms(player pl) parm22 = pl.satchel_chg; } -/* yuck, whenever 'changelevel' does not happen. */ void -Gamerules_SetNewParms(void) +HLSingleplayerRules::PlayerSpawn(player pl) { - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; -} + 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); -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* this is where the mods want to deviate */ entity spot; - if (cvar("sv_playerslots") == 1) { - if (startspot != "") { - Gamerules_DecodeChangeParms(pl); - setorigin(pl, Landmark_GetSpot()); - } else { - Gamerules_SetNewParms(); - spot = find(world, classname, "info_player_start"); - setorigin(pl, spot.origin); - pl.fixangle = TRUE; - } + if (startspot != "") { + dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); + LevelDecodeParms(pl); + setorigin(pl, Landmark_GetSpot()); } else { - Gamerules_SetNewParms(); - spot = Spawn_SelectRandom("info_player_deathmatch"); + LevelNewParms(); + spot = find(world, ::classname, "info_player_start"); setorigin(pl, spot.origin); pl.angles = spot.angles; - pl.g_items |= ITEM_SUIT; } - Client_FixAngle(pl, pl.angles); -} -void weaponbox_spawn(player pl) -{ - -} + Weapons_RefreshAmmo(pl); + Client_FixAngle(pl, pl.angles); +} diff --git a/src/server/poke646/progs.src b/src/server/poke646/progs.src index 584a2d10..4ad528f3 100755 --- a/src/server/poke646/progs.src +++ b/src/server/poke646/progs.src @@ -94,7 +94,11 @@ ../spawn.c ../vox.c ../../shared/valve/animations.c -gamerules.c + +../gamerules.cpp +../poke646/gamerules.cpp +../poke646/gamerules_singleplayer.cpp +../poke646/gamerules_multiplayer.cpp ../valve/client.c ../client.c ../valve/server.c diff --git a/src/server/rewolf/gamerules.cpp b/src/server/rewolf/gamerules.cpp new file mode 100644 index 00000000..0c17cdbd --- /dev/null +++ b/src/server/rewolf/gamerules.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +class HLGameRules:CGameRules +{ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerKill; + virtual void(player) PlayerPostFrame; + + virtual void(void) LevelNewParms; +}; + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +HLGameRules::PlayerPostFrame(player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} + +void +HLGameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +void +HLGameRules::PlayerConnect(entity pl) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + int playercount = 0; + for (a = world; (a = find(a, ::classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + Nodes_Init(); + } +} + +void +HLGameRules::PlayerDisconnect(entity pl) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = PLAYER_MODELINDEX; +} + +void +HLGameRules::PlayerKill(player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} diff --git a/src/server/rewolf/gamerules_multiplayer.cpp b/src/server/rewolf/gamerules_multiplayer.cpp new file mode 100644 index 00000000..0db6d4a0 --- /dev/null +++ b/src/server/rewolf/gamerules_multiplayer.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 HLMultiplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelDecodeParms; +}; + +void +HLMultiplayerRules::LevelDecodeParms(player pl) +{ + +} + +void +HLMultiplayerRules::PlayerSpawn(player pl) +{ + /* this is where the mods want to deviate */ + entity spot; + + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + string mymodel = infokey(pl, "model"); + + if (mymodel) { + mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); + if (whichpack(mymodel)) { + pl.model = mymodel; + } + } + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + LevelNewParms(); + LevelDecodeParms(pl); + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + Weapons_RefreshAmmo(pl); + + Client_FixAngle(pl, pl.angles); +} + +void weaponbox_spawn(player pl) +{ +} diff --git a/src/server/scihunt/gamerules.c b/src/server/rewolf/gamerules_singleplayer.cpp similarity index 51% rename from src/server/scihunt/gamerules.c rename to src/server/rewolf/gamerules_singleplayer.cpp index 5db60b6c..8bbe34ae 100644 --- a/src/server/scihunt/gamerules.c +++ b/src/server/rewolf/gamerules_singleplayer.cpp @@ -14,10 +14,18 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ +class HLSingleplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelChangeParms; + virtual void(player) LevelDecodeParms; +}; + void -Gamerules_DecodeChangeParms(player pl) +HLSingleplayerRules::LevelDecodeParms(player pl) { g_landmarkpos[0] = parm1; g_landmarkpos[1] = parm2; @@ -30,11 +38,17 @@ Gamerules_DecodeChangeParms(player pl) pl.velocity[2] = parm9; pl.g_items = parm10; pl.activeweapon = parm11; + pl.flags = parm64; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } } -/* prepare the client-info for level-transition */ void -Gamerules_SetChangeParms(player pl) +HLSingleplayerRules::LevelChangeParms(player pl) { parm1 = g_landmarkpos[0]; parm2 = g_landmarkpos[1]; @@ -45,45 +59,50 @@ Gamerules_SetChangeParms(player pl) parm7 = pl.velocity[0]; parm8 = pl.velocity[1]; parm9 = pl.velocity[2]; + parm64 = pl.flags; parm10 = pl.g_items; parm11 = pl.activeweapon; } -/* yuck, whenever 'changelevel' does not happen. */ void -Gamerules_SetNewParms(void) +HLSingleplayerRules::PlayerSpawn(player pl) { - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; -} + 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); -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* this is where the mods want to deviate */ entity spot; - if (cvar("sv_playerslots") == 1) { - if (startspot != "") { - Gamerules_DecodeChangeParms(pl); - setorigin(pl, Landmark_GetSpot()); - } else { - Gamerules_SetNewParms(); - spot = find(world, classname, "info_player_start"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - } + if (startspot != "") { + dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); + LevelDecodeParms(pl); + setorigin(pl, Landmark_GetSpot()); } else { - Gamerules_SetNewParms(); - spot = Spawn_SelectRandom("info_player_deathmatch"); + LevelNewParms(); + spot = find(world, ::classname, "info_player_start"); setorigin(pl, spot.origin); pl.angles = spot.angles; - pl.g_items |= ITEM_SUIT; - - SHData_GetItems(); } + + Weapons_RefreshAmmo(pl); Client_FixAngle(pl, pl.angles); -} +} diff --git a/src/server/rewolf/progs.src b/src/server/rewolf/progs.src index 341a3e2e..13c45a87 100755 --- a/src/server/rewolf/progs.src +++ b/src/server/rewolf/progs.src @@ -63,7 +63,11 @@ monster_human_unarmed.cpp ../spawn.c ../vox.c ../../shared/valve/animations.c -../rewolf/gamerules.c + +../gamerules.cpp +../valve/gamerules.cpp +../rewolf/gamerules_singleplayer.cpp +../rewolf/gamerules_multiplayer.cpp ../valve/client.c ../client.c ../valve/server.c diff --git a/src/server/scihunt/gamerules_multiplayer.cpp b/src/server/scihunt/gamerules_multiplayer.cpp new file mode 100644 index 00000000..f7bae332 --- /dev/null +++ b/src/server/scihunt/gamerules_multiplayer.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 SHMultiplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelDecodeParms; +}; + +void +SHMultiplayerRules::LevelDecodeParms(player pl) +{ + 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 = ITEM_CROWBAR | ITEM_GLOCK | ITEM_SUIT; + pl.activeweapon = WEAPON_GLOCK; + pl.flags = parm64; + + pl.ammo_9mm = 44; + pl.ammo_357 = parm13; + pl.ammo_buckshot = parm14; + pl.ammo_m203_grenade = parm15; + pl.ammo_bolt = parm16; + pl.ammo_rocket = parm17; + pl.ammo_uranium = parm18; + pl.ammo_handgrenade = parm19; + pl.ammo_satchel = parm20; + pl.ammo_tripmine = parm21; + pl.ammo_snark = parm22; + pl.ammo_hornet = parm23; + + pl.glock_mag = 18; + pl.mp5_mag = parm25; + pl.python_mag = parm26; + pl.shotgun_mag = parm27; + pl.crossbow_mag = parm28; + pl.rpg_mag = parm29; + pl.satchel_chg = parm30; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } +} + +void +SHMultiplayerRules::PlayerSpawn(player pl) +{ + /* this is where the mods want to deviate */ + entity spot; + + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + string mymodel = infokey(pl, "model"); + + if (mymodel) { + mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); + if (whichpack(mymodel)) { + pl.model = mymodel; + } + } + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + LevelNewParms(); + LevelDecodeParms(pl); + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + Weapons_RefreshAmmo(pl); + SHData_GetItems(); + + Client_FixAngle(pl, pl.angles); +} diff --git a/src/server/scihunt/progs.src b/src/server/scihunt/progs.src index 4b4b38e3..ef611e8d 100755 --- a/src/server/scihunt/progs.src +++ b/src/server/scihunt/progs.src @@ -109,7 +109,10 @@ shdata_parse.c ../vox.c ../../shared/valve/animations.c -../scihunt/gamerules.c + +../gamerules.cpp +../valve/gamerules.cpp +../scihunt/gamerules_multiplayer.cpp ../valve/client.c ../client.c diff --git a/src/server/scihunt/server.c b/src/server/scihunt/server.c index a1f2a9b3..d3aa5889 100644 --- a/src/server/scihunt/server.c +++ b/src/server/scihunt/server.c @@ -14,14 +14,10 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void Game_StartFrame(void) +void +Game_InitRules(void) { - -} - -float Game_ConsoleCmd(string cmd) -{ - return FALSE; + g_grMode = spawn(SHMultiplayerRules); } void Game_Worldspawn(void) diff --git a/src/server/sentences.c b/src/server/sentences.c index 947f40d0..07995bd9 100644 --- a/src/server/sentences.c +++ b/src/server/sentences.c @@ -72,10 +72,11 @@ Sentences_Init(void) /* allocate memory and increase count */ #ifdef DYNAMIC_SENTENCES + g_sentences_count++; g_sentences = memrealloc(g_sentences, sizeof(string), - g_sentences_count, - ++g_sentences_count); + x, + g_sentences_count); #else if (g_sentences_count + 1 >= SENTENCES_LIMIT) { print("^1WARNING: ^7Reached limit of max sentences!\n"); diff --git a/src/server/spawn.c b/src/server/spawn.c index 8d8fa43a..e429efb6 100644 --- a/src/server/spawn.c +++ b/src/server/spawn.c @@ -20,13 +20,13 @@ Spawn_ObserverCam(void) entity eTarget; // Go find a camera if we aren't dead - entity eCamera = find(world, classname, "trigger_camera"); + entity eCamera = find(world, ::classname, "trigger_camera"); if (eCamera) { self.origin = eCamera.origin; if (eCamera.target) { - eTarget = find(world, targetname, eCamera.target); + eTarget = find(world, ::targetname, eCamera.target); if (eTarget) { self.angles = vectoangles(eTarget.origin - eCamera.origin); self.angles[0] *= -1; @@ -34,13 +34,13 @@ Spawn_ObserverCam(void) } } else { // Can't find a camera? Just do this lazy thing, CS seems to do the same - eCamera = find (world, classname, "info_player_start"); + eCamera = find (world, ::classname, "info_player_start"); if (eCamera) { self.origin = eCamera.origin; if (eCamera.target) { - eTarget = find(world, targetname, eCamera.target); + eTarget = find(world, ::targetname, eCamera.target); if (eTarget) { self.angles = vectoangles(eTarget.origin - eCamera.origin); self.angles[0] *= -1; diff --git a/src/server/tfc/gamerules.c b/src/server/tfc/gamerules.c deleted file mode 100644 index 1bbd007b..00000000 --- a/src/server/tfc/gamerules.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016-2020 Marco Hladik - * - * 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. - */ - -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ -void -Gamerules_DecodeChangeParms(player pl) -{ - 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.ammo_9mm = parm12; - pl.ammo_357 = parm13; - pl.ammo_buckshot = parm14; - pl.ammo_m203_grenade = parm15; - pl.ammo_bolt = parm16; - pl.ammo_rocket = parm17; - pl.ammo_uranium = parm18; - pl.ammo_handgrenade = parm19; - pl.ammo_satchel = parm20; - pl.ammo_tripmine = parm21; - pl.ammo_snark = parm22; - pl.ammo_hornet = parm23; - - pl.glock_mag = parm24; - pl.mp5_mag = parm25; - pl.python_mag = parm26; - pl.shotgun_mag = parm27; - pl.crossbow_mag = parm28; - pl.rpg_mag = parm29; - pl.satchel_chg = parm30; -} - -/* prepare the client-info for level-transition */ -void -Gamerules_SetChangeParms(player pl) -{ - 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]; - parm10 = pl.g_items; - parm11 = pl.activeweapon; - parm12 = pl.ammo_9mm; - parm13 = pl.ammo_357; - parm14 = pl.ammo_buckshot; - parm15 = pl.ammo_m203_grenade; - parm16 = pl.ammo_bolt; - parm17 = pl.ammo_rocket; - parm18 = pl.ammo_uranium; - parm19 = pl.ammo_handgrenade; - parm20 = pl.ammo_satchel; - parm21 = pl.ammo_tripmine; - parm22 = pl.ammo_snark; - parm23 = pl.ammo_hornet; - parm24 = pl.glock_mag; - parm25 = pl.mp5_mag; - parm26 = pl.python_mag; - parm27 = pl.shotgun_mag; - parm28 = pl.crossbow_mag; - parm29 = pl.rpg_mag; - parm30 = pl.satchel_chg; -} - -/* yuck, whenever 'changelevel' does not happen. */ -void -Gamerules_SetNewParms(void) -{ - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; -} - -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ - pl.classname = "spectator"; - pl.health = 0; - pl.armor = 0; - pl.takedamage = DAMAGE_NO; - pl.solid = SOLID_NOT; - pl.movetype = MOVETYPE_NOCLIP; - pl.SendEntity = Player_SendEntity; - pl.flags = FL_CLIENT; - pl.weapon = 0; - pl.viewzoom = 1.0f; - pl.model = 0; - setsize (pl, '-16 -16 -16', '16 16 16'); - pl.view_ofs = pl.velocity = '0 0 0'; - forceinfokey(pl, "*spec", "2"); - Spawn_ObserverCam(); -} - -void weaponbox_spawn(player pl) -{ - -} diff --git a/src/server/tfc/gamerules.cpp b/src/server/tfc/gamerules.cpp new file mode 100644 index 00000000..29b65426 --- /dev/null +++ b/src/server/tfc/gamerules.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +class TFCGameRules:CGameRules +{ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerPostFrame; + virtual void(player) PlayerSpawn; + virtual void(player) PlayerKill; + + virtual void(void) LevelNewParms; +}; + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +TFCGameRules::PlayerPostFrame(player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} + +void +TFCGameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +void +TFCGameRules::PlayerConnect(entity pl) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + int playercount = 0; + for (a = world; (a = find(a, ::classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + Nodes_Init(); + } +} + +void +TFCGameRules::PlayerDisconnect(entity pl) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = PLAYER_MODELINDEX; +} + +void +TFCGameRules::PlayerKill(player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} + +void +TFCGameRules::PlayerSpawn(player pl) +{ + pl.classname = "spectator"; + pl.health = 0; + pl.armor = 0; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NOCLIP; + pl.SendEntity = Player_SendEntity; + pl.flags = FL_CLIENT; + pl.weapon = 0; + pl.viewzoom = 1.0f; + pl.model = 0; + setsize (pl, '-16 -16 -16', '16 16 16'); + pl.view_ofs = pl.velocity = '0 0 0'; + forceinfokey(pl, "*spec", "2"); + Spawn_ObserverCam(); +} diff --git a/src/server/tfc/progs.src b/src/server/tfc/progs.src index f70ae445..97a1c1ae 100755 --- a/src/server/tfc/progs.src +++ b/src/server/tfc/progs.src @@ -66,10 +66,12 @@ info_player_teamspawn.cpp spawn.c ../vox.c ../../shared/valve/animations.c -../tfc/gamerules.c + +../gamerules.cpp +../tfc/gamerules.cpp ../valve/client.c ../client.c -../valve/server.c +../tfc/server.c ../server.c ../valve/damage.c ../traceattack.c diff --git a/src/server/tfc/server.c b/src/server/tfc/server.c new file mode 100644 index 00000000..6f1d6ff7 --- /dev/null +++ b/src/server/tfc/server.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +Game_InitRules(void) +{ + g_grMode = spawn(TFCGameRules); +} + +void +Game_Worldspawn(void) +{ + Sound_Precache("ammo.pickup"); + Sound_Precache("ammo.respawn"); + precache_model("models/player.mdl"); + precache_model("models/w_weaponbox.mdl"); + precache_sound("fvox/flatline.wav"); + Weapons_Init(); + Player_Precache(); +} + +void weaponbox_spawn(player pl) +{ +} diff --git a/src/server/valve/client.c b/src/server/valve/client.c index d2ce6aab..6aefc49e 100644 --- a/src/server/valve/client.c +++ b/src/server/valve/client.c @@ -13,149 +13,6 @@ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -var int autocvar_sv_playerkeepalive = TRUE; - -void -Game_ClientConnect(void) -{ - entity a; - bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname)); - - int playercount = 0; - for (a = world; (a = find(a, classname, "player"));) { - playercount++; - } - - /* we're the first. respawn all entities? */ - if (playercount == 0) { - for (a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { - CBaseEntity caw = (CBaseEntity)a; - caw.Respawn(); - } - Nodes_Init(); - } -} - -void -Game_ClientDisconnect(void) -{ - bprint(PRINT_HIGH, sprintf("%s disconnected\n", self.netname)); - - /* Make this unusable */ - self.solid = SOLID_NOT; - self.movetype = MOVETYPE_NONE; - self.modelindex = 0; - self.health = 0; - self.takedamage = 0; - self.SendFlags = PLAYER_MODELINDEX; -} - -void -Game_ClientKill(player pl) -{ - Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); -} - -void -Game_PlayerPreThink(player pl) -{ - -} - -/* we check what fields have changed over the course of the frame and network - * only the ones that have actually changed */ -void -Game_PlayerPostThink(player pl) -{ - Animation_PlayerUpdate(); - - if (autocvar_sv_playerkeepalive) - pl.SendFlags |= PLAYER_KEEPALIVE; - - if (pl.old_modelindex != pl.modelindex) - pl.SendFlags |= PLAYER_MODELINDEX; - - if (pl.old_origin[0] != pl.origin[0]) - pl.SendFlags |= PLAYER_ORIGIN; - - if (pl.old_origin[1] != pl.origin[1]) - pl.SendFlags |= PLAYER_ORIGIN; - - if (pl.old_origin[2] != pl.origin[2]) - pl.SendFlags |= PLAYER_ORIGIN_Z; - - if (pl.old_angles[0] != pl.v_angle[0]) - pl.SendFlags |= PLAYER_ANGLES_X; - - if (pl.old_angles[1] != pl.angles[1]) - pl.SendFlags |= PLAYER_ANGLES_Y; - - if (pl.old_angles[2] != pl.angles[2]) - pl.SendFlags |= PLAYER_ANGLES_Z; - - if (pl.old_velocity[0] != pl.velocity[0]) - pl.SendFlags |= PLAYER_VELOCITY; - - if (pl.old_velocity[1] != pl.velocity[1]) - pl.SendFlags |= PLAYER_VELOCITY; - - if (pl.old_velocity[2] != pl.velocity[2]) - pl.SendFlags |= PLAYER_VELOCITY_Z; - - if (pl.old_flags != pl.flags) - pl.SendFlags |= PLAYER_FLAGS; - - if (pl.old_activeweapon != pl.activeweapon) - pl.SendFlags |= PLAYER_WEAPON; - - if (pl.old_items != pl.g_items) - pl.SendFlags |= PLAYER_ITEMS; - - if (pl.old_health != pl.health) - pl.SendFlags |= PLAYER_HEALTH; - - if (pl.old_armor != pl.armor) - pl.SendFlags |= PLAYER_ARMOR; - - if (pl.old_movetype != pl.movetype) - pl.SendFlags |= PLAYER_MOVETYPE; - - if (pl.old_viewofs != pl.view_ofs[2]) - pl.SendFlags |= PLAYER_VIEWOFS; - - if (pl.old_baseframe != pl.baseframe) - pl.SendFlags |= PLAYER_BASEFRAME; - - if (pl.old_frame != pl.frame) - pl.SendFlags |= PLAYER_FRAME; - - if (pl.old_a_ammo1 != pl.a_ammo1) - pl.SendFlags |= PLAYER_AMMO1; - - if (pl.old_a_ammo2 != pl.a_ammo2) - pl.SendFlags |= PLAYER_AMMO2; - - if (pl.old_a_ammo3 != pl.a_ammo3) - pl.SendFlags |= PLAYER_AMMO3; - - pl.old_modelindex = pl.modelindex; - pl.old_origin = pl.origin; - pl.old_angles = pl.angles; - pl.old_angles[0] = pl.v_angle[0]; - pl.old_velocity = pl.velocity; - pl.old_flags = pl.flags; - pl.old_activeweapon = pl.activeweapon; - pl.old_items = pl.g_items; - pl.old_health = pl.health; - pl.old_armor = pl.armor; - pl.old_movetype = pl.movetype; - pl.old_viewofs = pl.view_ofs[2]; - pl.old_baseframe = pl.baseframe; - pl.old_frame = pl.frame; - pl.old_a_ammo1 = pl.a_ammo1; - pl.old_a_ammo2 = pl.a_ammo2; - pl.old_a_ammo3 = pl.a_ammo3; -} /* called every input frame */ void @@ -165,44 +22,6 @@ Game_RunClientCommand(void) QPhysics_Run(self); } -/* called whenever we respawn, or connect */ -void -Game_PutClientInServer(player pl) -{ - pl.classname = "player"; - pl.health = pl.max_health = 100; - pl.takedamage = DAMAGE_YES; - pl.solid = SOLID_SLIDEBOX; - pl.movetype = MOVETYPE_WALK; - pl.flags = FL_CLIENT; - pl.viewzoom = 1.0; - pl.model = "models/player.mdl"; - string mymodel = infokey(pl, "model"); - - if (mymodel) { - mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); - if (whichpack(mymodel)) { - pl.model = mymodel; - } - } - setmodel(pl, pl.model); - - setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); - pl.view_ofs = VEC_PLAYER_VIEWPOS; - pl.velocity = [0,0,0]; - pl.gravity = __NULL__; - pl.frame = 1; - pl.SendEntity = Player_SendEntity; - pl.SendFlags = UPDATE_ALL; - pl.customphysics = Empty; - pl.iBleeds = TRUE; - forceinfokey(pl, "*spec", "0"); - forceinfokey(pl, "*deaths", ftos(pl.deaths)); - - /* this is where the mods want to deviate */ - Gamerules_Spawn(pl); -} - /* custom chat packet */ void SV_SendChat(entity sender, string msg, entity eEnt, float fType) @@ -244,7 +63,7 @@ Game_ParseClientCommand(string cmd) return; } else if (argv(0) == "say_team") { entity a; - for (a = world; (a = find(a, classname, "player"));) { + for (a = world; (a = find(a, ::classname, "player"));) { if (a.team == self.team) { SV_SendChat(self, argv(1), a, 1); } diff --git a/src/server/valve/damage.c b/src/server/valve/damage.c index 02fdaeff..7757a64d 100644 --- a/src/server/valve/damage.c +++ b/src/server/valve/damage.c @@ -147,7 +147,7 @@ Damage_Radius(vector org, entity attacker, float dmg, float r, int check, int w) float diff; vector pos; - for (entity e = world; (e = findfloat(e, takedamage, DAMAGE_YES));) { + for (entity e = world; (e = findfloat(e, ::takedamage, DAMAGE_YES));) { pos[0] = e.absmin[0] + (0.5 * (e.absmax[0] - e.absmin[0])); pos[1] = e.absmin[1] + (0.5 * (e.absmax[1] - e.absmin[1])); pos[2] = e.absmin[2] + (0.5 * (e.absmax[2] - e.absmin[2])); diff --git a/src/server/valve/gamerules.cpp b/src/server/valve/gamerules.cpp new file mode 100644 index 00000000..0c17cdbd --- /dev/null +++ b/src/server/valve/gamerules.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +class HLGameRules:CGameRules +{ + virtual void(entity) PlayerConnect; + virtual void(entity) PlayerDisconnect; + virtual void(player) PlayerKill; + virtual void(player) PlayerPostFrame; + + virtual void(void) LevelNewParms; +}; + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +HLGameRules::PlayerPostFrame(player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} + +void +HLGameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +void +HLGameRules::PlayerConnect(entity pl) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + int playercount = 0; + for (a = world; (a = find(a, ::classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + Nodes_Init(); + } +} + +void +HLGameRules::PlayerDisconnect(entity pl) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = PLAYER_MODELINDEX; +} + +void +HLGameRules::PlayerKill(player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} diff --git a/src/server/valve/gamerules_multiplayer.cpp b/src/server/valve/gamerules_multiplayer.cpp new file mode 100644 index 00000000..c933a234 --- /dev/null +++ b/src/server/valve/gamerules_multiplayer.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * 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 HLMultiplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelDecodeParms; +}; + +void +HLMultiplayerRules::LevelDecodeParms(player pl) +{ + 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 = ITEM_CROWBAR | ITEM_GLOCK | ITEM_SUIT; + pl.activeweapon = WEAPON_GLOCK; + pl.flags = parm64; + + pl.ammo_9mm = 44; + pl.ammo_357 = parm13; + pl.ammo_buckshot = parm14; + pl.ammo_m203_grenade = parm15; + pl.ammo_bolt = parm16; + pl.ammo_rocket = parm17; + pl.ammo_uranium = parm18; + pl.ammo_handgrenade = parm19; + pl.ammo_satchel = parm20; + pl.ammo_tripmine = parm21; + pl.ammo_snark = parm22; + pl.ammo_hornet = parm23; + + pl.glock_mag = 18; + pl.mp5_mag = parm25; + pl.python_mag = parm26; + pl.shotgun_mag = parm27; + pl.crossbow_mag = parm28; + pl.rpg_mag = parm29; + pl.satchel_chg = parm30; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } +} + +void +HLMultiplayerRules::PlayerSpawn(player pl) +{ + /* this is where the mods want to deviate */ + entity spot; + + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + string mymodel = infokey(pl, "model"); + + if (mymodel) { + mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); + if (whichpack(mymodel)) { + pl.model = mymodel; + } + } + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + LevelNewParms(); + LevelDecodeParms(pl); + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + Weapons_RefreshAmmo(pl); + + Client_FixAngle(pl, pl.angles); +} diff --git a/src/server/valve/gamerules.c b/src/server/valve/gamerules_singleplayer.cpp similarity index 66% rename from src/server/valve/gamerules.c rename to src/server/valve/gamerules_singleplayer.cpp index 893648c4..8bc3c4e9 100644 --- a/src/server/valve/gamerules.c +++ b/src/server/valve/gamerules_singleplayer.cpp @@ -14,10 +14,18 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* after a level-change is done we need to pick up the scraps and fill the - * info back in. */ +class HLSingleplayerRules:HLGameRules +{ + /* client */ + virtual void(player) PlayerSpawn; + + /* level transitions */ + virtual void(player) LevelChangeParms; + virtual void(player) LevelDecodeParms; +}; + void -Gamerules_DecodeChangeParms(player pl) +HLSingleplayerRules::LevelDecodeParms(player pl) { g_landmarkpos[0] = parm1; g_landmarkpos[1] = parm2; @@ -60,9 +68,8 @@ Gamerules_DecodeChangeParms(player pl) } } -/* prepare the client-info for level-transition */ void -Gamerules_SetChangeParms(player pl) +HLSingleplayerRules::LevelChangeParms(player pl) { parm1 = g_landmarkpos[0]; parm2 = g_landmarkpos[1]; @@ -97,48 +104,45 @@ Gamerules_SetChangeParms(player pl) parm30 = pl.satchel_chg; } -/* yuck, whenever 'changelevel' does not happen. */ void -Gamerules_SetNewParms(void) +HLSingleplayerRules::PlayerSpawn(player pl) { - parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = - parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = - parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = - parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = - parm29 = parm30 = 0; + 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); - parm64 = FL_CLIENT; -} + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); -/* called when the player first spawns/respawns */ -void -Gamerules_Spawn(player pl) -{ + /* this is where the mods want to deviate */ entity spot; - if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { - if (startspot != "") { - dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); - Gamerules_DecodeChangeParms(pl); - setorigin(pl, Landmark_GetSpot()); - } else { - Gamerules_SetNewParms(); - spot = find(world, classname, "info_player_start"); - setorigin(pl, spot.origin); - pl.angles = spot.angles; - } - Weapons_RefreshAmmo(pl); + if (startspot != "") { + dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); + LevelDecodeParms(pl); + setorigin(pl, Landmark_GetSpot()); } else { - Gamerules_SetNewParms(); - Gamerules_DecodeChangeParms(pl); - spot = Spawn_SelectRandom("info_player_deathmatch"); + LevelNewParms(); + spot = find(world, ::classname, "info_player_start"); setorigin(pl, spot.origin); pl.angles = spot.angles; - - pl.ammo_9mm = 68; - Weapons_AddItem(pl, WEAPON_CROWBAR); - Weapons_AddItem(pl, WEAPON_GLOCK); - pl.g_items |= ITEM_SUIT; } + + Weapons_RefreshAmmo(pl); Client_FixAngle(pl, pl.angles); -} +} diff --git a/src/server/valve/input.c b/src/server/valve/input.c index 4dfa2b9b..f614482d 100644 --- a/src/server/valve/input.c +++ b/src/server/valve/input.c @@ -67,7 +67,7 @@ void Game_Input(void) if (self.impulse == 102) { // Respawn all the entities - for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { + for (entity a = world; (a = findfloat(a, ::gflags, GF_CANRESPAWN));) { CBaseEntity caw = (CBaseEntity)a; caw.Respawn(); caw.SendFlags |= diff --git a/src/server/valve/progs.src b/src/server/valve/progs.src index 7eb3aeb9..5a657a9f 100755 --- a/src/server/valve/progs.src +++ b/src/server/valve/progs.src @@ -100,7 +100,11 @@ ammo.cpp ../spawn.c ../vox.c ../../shared/valve/animations.c -../valve/gamerules.c + +../gamerules.cpp +../valve/gamerules.cpp +../valve/gamerules_singleplayer.cpp +../valve/gamerules_multiplayer.cpp ../valve/client.c ../client.c server.c diff --git a/src/server/valve/server.c b/src/server/valve/server.c index 26139294..ab3dc58d 100644 --- a/src/server/valve/server.c +++ b/src/server/valve/server.c @@ -14,17 +14,19 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -void Game_StartFrame(void) +void +Game_InitRules(void) { - + print("Game_InitRules!\n"); + if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { + g_grMode = spawn(HLSingleplayerRules); + } else { + g_grMode = spawn(HLMultiplayerRules); + } } -float Game_ConsoleCmd(string cmd) -{ - return FALSE; -} - -void Game_Worldspawn(void) +void +Game_Worldspawn(void) { Sound_Precache("ammo.pickup"); Sound_Precache("ammo.respawn"); diff --git a/src/server/vote.c b/src/server/vote.c index e00dfc55..16083db2 100644 --- a/src/server/vote.c +++ b/src/server/vote.c @@ -55,7 +55,7 @@ Vote_Reset(void) forceinfokey(world, "votes_n", "0"); forceinfokey(world, "vote_cmd", ""); - for (entity e = world; (e = find(e, classname, "player"));) { + for (entity e = world; (e = find(e, ::classname, "player"));) { e.flags &= ~FL_VOTED; } } @@ -145,7 +145,7 @@ CSEv_VoteY(void) /* HACK: Is there a better way to do this? */ float playernums = 0; - for (entity eFind = world; (eFind = find(eFind, classname, "player"));) { + for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) { playernums++; } @@ -188,7 +188,7 @@ CSEv_VoteN(void) /* HACK: Is there a better way to do this? */ float playernums = 0; - for (entity eFind = world; (eFind = find(eFind, classname, "player"));) { + for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) { playernums++; } diff --git a/tfc/data.pk3dir/sound/weapons_tfc.sndshd b/tfc/data.pk3dir/sound/weapons_tfc.sndshd index 4cdc08b4..e49af201 100644 --- a/tfc/data.pk3dir/sound/weapons_tfc.sndshd +++ b/tfc/data.pk3dir/sound/weapons_tfc.sndshd @@ -1,3 +1,8 @@ +weapon_dbs.fire +{ + sample weapons/shotgn2.wav +} + weapon_sbs.cock { sample weapons/scock1.wav