CBaseMonster: support for spawnflag MSF_IGNOREPLAYER (64).

This commit is contained in:
Marco Cawthorne 2021-05-10 08:14:10 +02:00
parent f4bbfe2e69
commit a3ecd78f17
22 changed files with 227 additions and 164 deletions

View File

@ -21,7 +21,7 @@ ClientGame_ConsoleCommand(void)
{
switch(argv(0)) {
default:
return FALSE;
return (0);
}
return TRUE;
return (1);
}

View File

@ -19,10 +19,10 @@ ClientGame_EntityUpdate(float id, float new)
{
switch (id) {
default:
return FALSE;
return (0);
}
return TRUE;
return (1);
}
void

View File

@ -94,31 +94,31 @@ Damage_CheckTrace(entity t, vector vecHitPos)
{
/* We're lazy. Who cares */
if (t.solid == SOLID_BSP) {
return TRUE;
return (1);
}
traceline(vecHitPos, t.origin, 1, self);
if (trace_fraction == 1) {
return TRUE;
return (1);
}
traceline(vecHitPos, t.origin + [15,15,0], 1, self);
if (trace_fraction == 1) {
return TRUE;
return (1);
}
traceline(vecHitPos, t.origin + [-15,-15,0], 1, self);
if (trace_fraction == 1) {
return TRUE;
return (1);
}
traceline(vecHitPos, t.origin + [-15,15,0], 1, self);
if (trace_fraction == 1) {
return TRUE;
return (1);
}
traceline(vecHitPos, t.origin + [15,-15,0], 1, self);
if (trace_fraction == 1) {
return TRUE;
return (1);
}
return FALSE;
return (0);
}
/* even more pain and suffering, mostly used for explosives */

View File

@ -109,8 +109,8 @@ MultiplayerRules::ConsoleCommand(base_player pp, string cmd)
Bot_AddQuick();
break;
default:
return FALSE;
return (0);
}
return TRUE;
return (1);
}

View File

@ -16,5 +16,5 @@
int Rules_IsTeamPlay(void)
{
return cvar("teamplay");
return (int)(cvar("teamplay"));
}

View File

@ -14,13 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
Input_Handle
Handles impulse and whatnot
=================
*/
void
Game_Input(void)
{
@ -32,34 +25,23 @@ Game_Input(void)
return;
}
if (self.impulse == 100) {
Flashlight_Toggle();
}
if (input_buttons & INPUT_BUTTON5) {
if (input_buttons & INPUT_BUTTON5)
Player_UseDown();
} else {
else
Player_UseUp();
}
if (cvar("sv_cheats") == 1) {
player pl = (player)self;
if (self.impulse == 101) {
pl.health = 100;
pl.armor = 100;
}
}
if (self.impulse == 100)
Flashlight_Toggle();
self.impulse = 0;
#endif
if (input_buttons & INPUT_BUTTON0) {
if (input_buttons & INPUT_BUTTON0)
Weapons_Primary();
} else if (input_buttons & INPUT_BUTTON4) {
else if (input_buttons & INPUT_BUTTON4)
Weapons_Reload();
} else if (input_buttons & INPUT_BUTTON3) {
else if (input_buttons & INPUT_BUTTON3)
Weapons_Secondary();
} else {
else
Weapons_Release();
}
}

View File

@ -121,12 +121,12 @@ player::SendEntity(entity ePEnt, float fChanged)
{
/* remove our entity to other clients if we're dead */
if (health <= 0 && ePEnt != this) {
return FALSE;
return (0);
}
/* target client isn't real, they have no client-side. abandon */
if (clienttype(ePEnt) != CLIENTTYPE_REAL) {
return FALSE;
return (0);
}
/* other players don't need to know about these attributes */
@ -142,6 +142,6 @@ player::SendEntity(entity ePEnt, float fChanged)
/* the generic client attributes */
base_player::SendEntity(ePEnt, fChanged);
return TRUE;
return (1);
}
#endif

View File

@ -24,7 +24,7 @@
float
GamePMove_Maxspeed(player target)
{
return (target.flags & FL_CROUCHING) ? 135 : 270;
return ((target.flags & FL_CROUCHING) ? 135 : 270);
}
void

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -45,6 +45,8 @@ void Weapons_Secondary(void);
void Weapons_Reload(void);
void Weapons_Release(void);
float Weapons_GetAim(int);
void Weapons_Reload(void);
void Weapons_DrawCrosshair(void);
void Weapons_MakeVectors(void);
vector Weapons_GetCameraPos(void);
@ -53,6 +55,7 @@ void Weapons_ViewPunchAngle(vector);
int Weapons_IsPresent(player, int);
void Weapons_SetModel(string);
void Weapons_SetGeomset(string);
void Weapons_UpdateAmmo(base_player, int, int, int);
int Weapons_GetAnimation(void);
#ifdef CLIENT

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -14,10 +14,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef SERVER
void Decals_Init(void);
#endif
void
Weapons_Init(void)
{
@ -47,11 +43,9 @@ Weapons_Init(void)
fclose(fh);
}*/
for (int i = 0; i < g_weapons.length; i++) {
if (g_weapons[i].precache != __NULL__) {
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].precache != __NULL__)
g_weapons[i].precache();
}
}
}
void
@ -80,17 +74,21 @@ Weapons_Draw(void)
pl.w_idle_next = 2.5f;
pl.viewzoom = 1.0f;
#ifdef CLIENT
entity eold = self;
self = pSeat->m_pWeaponFX;
spawnfunc_CBaseFX();
self = eold;
#endif
/* make sure this is all wiped */
pl.a_ammo1 = pl.a_ammo2 = pl.a_ammo3 = 0;
if (g_weapons[i].draw != __NULL__) {
if (g_weapons[i].draw != __NULL__)
g_weapons[i].draw();
}
#ifdef SERVER
if (g_weapons[i].updateammo != __NULL__) {
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
#endif
}
void
@ -98,9 +96,9 @@ Weapons_Holster(void)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].holster != __NULL__) {
if (g_weapons[i].holster != __NULL__)
g_weapons[i].holster();
}
}
void
@ -112,15 +110,22 @@ Weapons_Primary(void)
if (pl.flags & FL_NOATTACK)
return;
if (g_weapons[i].primary != __NULL__) {
if (g_weapons[i].primary != __NULL__)
g_weapons[i].primary();
}
#ifdef SERVER
if (g_weapons[i].updateammo != __NULL__) {
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
#endif
}
void
Weapons_AmmoUpdate(entity target)
{
player pl = (player)target;
int i = pl.activeweapon;
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
void
@ -132,14 +137,11 @@ Weapons_Secondary(void)
if (pl.flags & FL_NOATTACK)
return;
if (g_weapons[i].secondary != __NULL__) {
if (g_weapons[i].secondary != __NULL__)
g_weapons[i].secondary();
}
#ifdef SERVER
if (g_weapons[i].updateammo != __NULL__) {
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
#endif
}
void
@ -151,14 +153,11 @@ Weapons_Reload(void)
if (pl.flags & FL_NOATTACK)
return;
if (g_weapons[i].reload != __NULL__) {
if (g_weapons[i].reload != __NULL__)
g_weapons[i].reload();
}
#ifdef SERVER
if (g_weapons[i].updateammo != __NULL__) {
if (g_weapons[i].updateammo != __NULL__)
g_weapons[i].updateammo(pl);
}
#endif
}
void
@ -166,10 +165,10 @@ Weapons_Release(void)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].release != __NULL__) {
if (g_weapons[i].release != __NULL__)
g_weapons[i].release();
}
pl.gflags &= ~GF_SEMI_TOGGLED;
}
@ -178,60 +177,53 @@ Weapons_DrawCrosshair(void)
{
player pl = (player)self;
int i = pl.activeweapon;
if (g_weapons[i].crosshair != __NULL__) {
if (g_weapons[i].crosshair != __NULL__)
g_weapons[i].crosshair();
}
}
string
Weapons_GetWorldmodel(int id)
{
if (g_weapons[id].wmodel != __NULL__) {
if (g_weapons[id].wmodel != __NULL__)
return g_weapons[id].wmodel();
}
return "";
}
string
Weapons_GetPlayermodel(int id)
{
if (g_weapons[id].pmodel != __NULL__) {
if (g_weapons[id].pmodel != __NULL__)
return g_weapons[id].pmodel();
}
return "";
}
string
Weapons_GetDeathmessage(int id)
{
if (g_weapons[id].deathmsg != __NULL__) {
if (g_weapons[id].deathmsg != __NULL__)
return g_weapons[id].deathmsg();
}
return "";
}
#ifdef SERVER
float
Weapons_GetAim(int id)
{
if (g_weapons[id].aimanim != __NULL__) {
if (g_weapons[id].aimanim != __NULL__)
return g_weapons[id].aimanim();
}
return 0;
return (0);
}
#endif
#ifdef CLIENT
void
Weapons_HUDPic(int id, int s, vector pos, float a)
{
if (g_weapons[id].hudpic != __NULL__) {
if (g_weapons[id].hudpic != __NULL__)
g_weapons[id].hudpic(s, pos, a);
}
}
#endif
@ -250,7 +242,7 @@ vector
Weapons_GetCameraPos(void)
{
#ifdef SERVER
return self.origin + self.view_ofs;
return (self.origin + self.view_ofs);
#else
return getproperty(VF_ORIGIN);
#endif
@ -259,11 +251,9 @@ Weapons_GetCameraPos(void)
void
Weapons_ViewAnimation(int i)
{
#ifdef CLIENT
player pl = (player)pSeat->m_ePlayer;
View_PlayAnimation(i);
#else
player pl = (player)self;
#ifdef CLIENT
View_PlayAnimation(i);
#endif
pl.weapontime = 0.0f;
}
@ -278,26 +268,24 @@ Weapons_GetAnimation(void)
#ifdef CLIENT
return View_GetAnimation();
#else
return 0;
return (0);
#endif
}
void
Weapons_ViewPunchAngle(vector add)
{
#ifdef CLIENT
player pl = (player)self;
pl.punchangle += add;
#endif
}
int
Weapons_IsPresent(player pl, int w)
{
if (pl.g_items & g_weapons[w].id) {
return TRUE;
return (1);
} else {
return FALSE;
return (0);
}
}
/*
@ -311,15 +299,12 @@ void
Weapons_UpdateAmmo(base_player pl, int a1, int a2, int a3)
{
/* no change */
if (a1 == -1) {
if (a1 == -1)
a1 = pl.a_ammo1;
}
if (a2 == -1) {
if (a2 == -1)
a2 = pl.a_ammo2;
}
if (a3 == -1) {
if (a3 == -1)
a3 = pl.a_ammo3;
}
/* networked as bytes, since we don't need more. Clamp to avoid errors */
pl.a_ammo1 = bound(0, a1, 255);

View File

@ -900,25 +900,8 @@ CSQC_Ent_Update(float new)
pSeat = &g_seats[s];
pSeatLocal = &g_seatslocal[s];
if (new || self.classname != "player") {
spawnfunc_player();
pl.classname = "player";
pl.solid = SOLID_SLIDEBOX;
pl.drawmask = MASK_ENGINE;
pl.customphysics = Empty;
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
} else {
if (pl.entnum == player_localentnum) {
for (int i = pl.sequence+1; i <= servercommandframe; i++) {
/* ...maybe the input state is too old? */
if (!getinputstate(i)) {
break;
}
input_sequence = i;
PMove_Run();
}
}
}
Predict_EntityUpdate(pl, new);
/* any differences in things that are read below are now
officially from prediction misses. */

View File

@ -14,6 +14,54 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
=================
Predict_EntityUpdate
We're part way through parsing new player data.
Propagate our pmove state to whatever the current frame before its stomped on
(so any non-networked state updates locally).
=================
*/
void
Predict_EntityUpdate(player pl, float new)
{
/* this is a new client entity, let's set it up right */
if (new || self.classname != "player") {
spawnfunc_player();
pl.classname = "player";
if (pl.entnum == player_localentnum) {
pl.solid = SOLID_SLIDEBOX;
pl.movetype = MOVETYPE_NONE;
pl.customphysics = Empty;
} else {
/* other players will act like missiles for interpolation purposes */
pl.solid = SOLID_SLIDEBOX;
pl.movetype = MOVETYPE_FLY;
pl.customphysics = __NULL__;
}
pl.drawmask = MASK_ENGINE;
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
return;
}
/* this is us, so we know about this clients' input_ fields */
if (pl.entnum == player_localentnum) {
/* run the player physics from the last approved servercommandframe to the current one */
for (int i = pl.sequence+1; i <= servercommandframe; i++) {
/* ...maybe the input state is too old? */
if (!getinputstate(i)) {
break;
}
input_sequence = i;
PMove_Run();
}
}
}
/*
=================
Predict_PreFrame

View File

@ -32,7 +32,7 @@ typedef enumflags
MSF_RESERVED1,
MSF_PRISONER,
MSF_RESERVED2,
MSF_RESERVED3,
MSF_IGNOREPLAYER,
MSF_WAITFORSCRIPT,
MSF_PREDISASTER,
MSF_FADECORPSE,

View File

@ -99,6 +99,9 @@ CBaseMonster::SeeThink(void)
if (w.health <= 0)
continue;
if ((w.flags & FL_CLIENT) && (spawnflags & MSF_IGNOREPLAYER))
continue;
/* first, is the potential enemy in our field of view? */
makevectors(v_angle);
vector v = normalize(w.origin - origin);

View File

@ -271,7 +271,7 @@ Menu_InputEvent(float evtype, float scanx, float chary, float devid)
}
main_input(evtype, scanx, chary, devid);
return TRUE;
return (1);
}
void
@ -342,7 +342,7 @@ m_consolecommand(string cmd)
argv(1)));
break;
default:
return FALSE;
return (0);
}
return TRUE;
return (1);
}

View File

@ -46,7 +46,7 @@ game_getpackageid(string pkgname)
}
/* no package id whatsoever */
return -1;
return (-1);
}
/* return 1 if any of the packages are pending, installing, or corrupt */
@ -66,31 +66,31 @@ game_updatesavailable(void)
switch (status) {
case "":
if (updates[id].installed == "") {
return 1;
return (1);
} else if (updates[id].installed == "pending") {
return 1;
return (1);
}
break;
case "pending":
return 1;
return (1);
break;
case "enabled":
break;
case "present":
return 1;
return (1);
break;
case "corrupt":
return 1;
return (1);
break;
default:
/* we're currently installing stuff */
return 1;
return (1);
break;
}
}
/* everything is installed */
return 0;
return (0);
}
int
@ -100,7 +100,7 @@ game_updateinstallcount(void)
/* always return something positive when no packages are defined */
if (games[gameinfo_current].pkgname == "") {
return 1;
return (1);
}
/* look for the valid packages in the gameinfo pkgname */

View File

@ -31,7 +31,7 @@ memrealloc(__variant *oldptr, int elementsize, int old_num, int new_num)
if (!n) {
print("^1memrealloc^7: Out of memory\n");
return 0;
return (0);
}
memcpy(n, oldptr, elementsize * old_num);

View File

@ -18,13 +18,13 @@ int
Server_IsLan(string address)
{
#if 0
return FALSE;
return (0);
#endif
tokenizebyseparator(address, ".");
if (argv(0) == "192" && argv(1) == "168") {
return TRUE;
return (1);
} else {
return FALSE;
return (0);
}
}

View File

@ -62,18 +62,18 @@ TCP_Send(tcpinfo_t *in, string msg)
{
if (in.m_iState == STATE_DISCONNECTED) {
dprint("^1TCP_Send^7: Can't send, we're disconnected\n");
return 0;
return (0);
}
/* the buffer is full. we've been unable to send messages for a while */
if (in.m_iBufferLines >= (TCP_BUFFER_LENGTH - 1)) {
dprint("^1TCP_Send^7: Buffer full.\n");
return 0;
return (0);
}
in.m_strBuffer[in.m_iBufferLines] = msg;
in.m_iBufferLines++;
return 1;
return (1);
}
string

View File

@ -30,11 +30,11 @@ Util_CheckMouse(int x, int y, int sx, int sy)
if (g_mousepos[0] >= mins[0] && g_mousepos[0] <= maxs[0]) {
if (g_mousepos[1] >= mins[1] && g_mousepos[1] <= maxs[1]) {
return TRUE;
return (1);
}
}
return FALSE;
return (0);
}
string

View File

@ -23,7 +23,7 @@ FMX_PlayerConnect(entity cl)
sound(g_cnspk, CHAN_VOICE, "sound/buttons/bell1.wav", 1.0f, ATTN_NONE);
strIP = infokey(cl, INFOKEY_P_IP);
bprint(PRINT_CHAT, sprintf("%s joined (%s)\n", cl.netname, strIP));
return TRUE;
return (1);
}
int
@ -33,7 +33,7 @@ FMX_PlayerDisconnect(entity cl)
sound(g_cnspk, CHAN_VOICE, "sound/buttons/blip1.wav", 1.0f, ATTN_NONE);
strIP = infokey(cl, INFOKEY_P_IP);
bprint(PRINT_CHAT, sprintf("%s left (%s)\n", cl.netname, strIP));
return TRUE;
return (1);
}
void

View File

@ -15,10 +15,21 @@
*/
#ifdef CLIENT
/*
=================
base_player::ReceiveEntity
Receive the generic client attributes from the server.
If you want to override this, do not call this
at the top of player::ReceiveEntity
=================
*/
void
base_player::ReceiveEntity(float new, float fl)
{
/* seed for our prediction table */
/* store which input sequence we're on, this helps us
* later when we run prediction again between last/latest
* servercommandframe */
sequence = servercommandframe;
/* HACK: we need to make this more reliable */
@ -79,6 +90,15 @@ base_player::ReceiveEntity(float new, float fl)
punchangle[2] = readfloat();
}
/*
=================
base_player::PredictPreFrame
Save the state of the last server-confirmed attributes.
If you want to override this, do not call this
at the top of player::PredictPreFrame
=================
*/
void
base_player::PredictPreFrame(void)
{
@ -105,6 +125,16 @@ base_player::PredictPreFrame(void)
SAVE_STATE(punchangle);
}
/*
=================
base_player::PredictPostFrame
After running prediction on the client, roll back the values
to the server's confirmed saved attributes from PredictPreFrame.
If you want to override this, do not call this
at the top of player::PredictPostFrame
=================
*/
void
base_player::PredictPostFrame(void)
{
@ -130,8 +160,16 @@ base_player::PredictPostFrame(void)
ROLL_BACK(w_idle_next);
ROLL_BACK(punchangle);
}
#else
/*
=================
base_player::EvaluateEntity
Check which attributes have changed and flag the ones that did.
If you want to override this, do not call this
at the top of player::EvaluateEntity
=================
*/
void
base_player::EvaluateEntity(void)
{
@ -213,18 +251,32 @@ base_player::EvaluateEntity(void)
SAVE_STATE(punchangle);
}
/*
=================
base_player::SendEntity
Network any attributes that have been flagged for networking.
If you want to override this, do not call this
at the top of player::SendEntity
=================
*/
float
base_player::SendEntity(entity ePEnt, float fChanged)
{
/* really trying to get our moneys worth with 23 bits of mantissa */
if (fChanged & PLAYER_MODELINDEX)
WriteShort(MSG_ENTITY, modelindex);
/* if origin[0] changes, it's very likely [1] changes too, since
* we rarely ever walk in a straight line on the world grid */
if (fChanged & PLAYER_ORIGIN) {
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[1]);
}
/* the height doesn't change as much */
if (fChanged & PLAYER_ORIGIN_Z)
WriteCoord(MSG_ENTITY, origin[2]);
if (fChanged & PLAYER_ANGLES_X)
WriteFloat(MSG_ENTITY, v_angle[0]);
if (fChanged & PLAYER_ANGLES_Y)
@ -232,11 +284,11 @@ base_player::SendEntity(entity ePEnt, float fChanged)
if (fChanged & PLAYER_ANGLES_Z)
WriteFloat(MSG_ENTITY, angles[2]);
/* similar as with origin, we separate x/y from z */
if (fChanged & PLAYER_VELOCITY) {
WriteCoord(MSG_ENTITY, velocity[0]);
WriteCoord(MSG_ENTITY, velocity[1]);
}
if (fChanged & PLAYER_VELOCITY_Z)
WriteCoord(MSG_ENTITY, velocity[2]);
@ -246,14 +298,21 @@ base_player::SendEntity(entity ePEnt, float fChanged)
}
if (fChanged & PLAYER_WEAPON)
WriteByte(MSG_ENTITY, activeweapon);
/* g_items is a proper integer, so we can't let WriteFloat truncate it (hence __variant) */
if (fChanged & PLAYER_ITEMS)
WriteFloat(MSG_ENTITY, (__variant)g_items);
/* only got byte precision, clamp to avoid weird values on the client-side */
if (fChanged & PLAYER_HEALTH)
WriteByte(MSG_ENTITY, bound(0, health, 255));
if (fChanged & PLAYER_ARMOR)
WriteByte(MSG_ENTITY, bound(0, armor, 255));
if (fChanged & PLAYER_MOVETYPE)
WriteByte(MSG_ENTITY, movetype);
/* the view_ofs[0] and [1] are rarely changed */
if (fChanged & PLAYER_VIEWOFS)
WriteFloat(MSG_ENTITY, view_ofs[2]);