Change the inheritance graph of NSBot, NSClient etc.

This commit is contained in:
Marco Cawthorne 2024-04-22 22:47:54 -07:00
parent bd7e78ab94
commit bab74ba6fd
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
33 changed files with 188 additions and 325 deletions

View File

@ -90,7 +90,7 @@ Camera_AddLean(vector viewAngle)
vector output; vector output;
vector srcPos; vector srcPos;
float heightChange; float heightChange;
player pl = (player)pSeat->m_ePlayer; NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer;
if (pSeat->m_iLeanDir > 0i) { if (pSeat->m_iLeanDir > 0i) {
pSeat->m_flLeaning += frametime * 5; pSeat->m_flLeaning += frametime * 5;

View File

@ -27,7 +27,7 @@ Scores_Init(void)
} }
void void
Scores_DrawTeam(player pl, vector pos) Scores_DrawTeam(NSClientPlayer pl, vector pos)
{ {
drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE); drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE);
@ -88,7 +88,7 @@ Scores_DrawTeam(player pl, vector pos)
} }
void void
Scores_DrawNormal(player pl, vector pos) Scores_DrawNormal(NSClientPlayer pl, vector pos)
{ {
drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE); drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE);
@ -141,9 +141,9 @@ void
Scores_Draw(void) Scores_Draw(void)
{ {
vector pos; vector pos;
player pl; NSClientPlayer pl;
pl = (player)pSeat->m_ePlayer; pl = (NSClientPlayer)pSeat->m_ePlayer;
if (autocvar_cl_centerscores) { if (autocvar_cl_centerscores) {
int c = 10; int c = 10;

View File

@ -21,9 +21,8 @@ GameRules::GameRules(void)
} }
void void
GameRules::LevelDecodeParms(NSClientPlayer pp) GameRules::LevelDecodeParms(NSClientPlayer pl)
{ {
player pl = (player)pp;
g_landmarkpos[0] = parm1; g_landmarkpos[0] = parm1;
g_landmarkpos[1] = parm2; g_landmarkpos[1] = parm2;
g_landmarkpos[2] = parm3; g_landmarkpos[2] = parm3;
@ -36,18 +35,11 @@ GameRules::LevelDecodeParms(NSClientPlayer pp)
pl.g_items = parm10; pl.g_items = parm10;
pl.activeweapon = parm11; pl.activeweapon = parm11;
pl.flags = parm64; pl.flags = parm64;
if (pl.vv_flags & VFL_CROUCHING) {
setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX);
} else {
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
}
} }
void void
GameRules::LevelChangeParms(NSClientPlayer pp) GameRules::LevelChangeParms(NSClientPlayer pl)
{ {
player pl = (player)pp;
parm1 = g_landmarkpos[0]; parm1 = g_landmarkpos[0];
parm2 = g_landmarkpos[1]; parm2 = g_landmarkpos[1];
parm3 = g_landmarkpos[2]; parm3 = g_landmarkpos[2];

View File

@ -66,9 +66,8 @@ MultiplayerRules::PlayerDeath(NSClientPlayer pl)
} }
void void
MultiplayerRules::PlayerSpawn(NSClientPlayer pp) MultiplayerRules::PlayerSpawn(NSClientPlayer pl)
{ {
player pl = (player)pp;
/* this is where the mods want to deviate */ /* this is where the mods want to deviate */
entity spot; entity spot;

View File

@ -21,7 +21,7 @@ void item_pickup::Touch(entity eToucher)
} }
/* don't remove if AddItem fails */ /* don't remove if AddItem fails */
if (Weapons_AddItem((player)eToucher, id, m_iClip) == FALSE) { if (Weapons_AddItem(eToucher, id, m_iClip) == FALSE) {
return; return;
} }

View File

@ -10,7 +10,6 @@
../../../src/shared/fteextensions.qc ../../../src/shared/fteextensions.qc
../../../src/shared/defs.h ../../../src/shared/defs.h
../../../src/server/defs.h ../../../src/server/defs.h
../../../src/botlib/botinfo.h
../../../src/gs-entbase/server.src ../../../src/gs-entbase/server.src
../../../src/gs-entbase/shared.src ../../../src/gs-entbase/shared.src

View File

@ -45,7 +45,7 @@ FX_Corpse_Next(void)
} }
entity entity
FX_Corpse_Spawn(player pl, float anim) FX_Corpse_Spawn(NSClientPlayer pl, float anim)
{ {
NSRenderableEntity body_next = (NSRenderableEntity)FX_Corpse_Next(); NSRenderableEntity body_next = (NSRenderableEntity)FX_Corpse_Next();
setorigin(body_next, pl.origin + [0,0,32]); setorigin(body_next, pl.origin + [0,0,32]);

View File

@ -1,5 +1,4 @@
#includelist #includelist
player.qc
weapons.h weapons.h
flags.h flags.h
fx_blood.qc fx_blood.qc

View File

@ -1,150 +0,0 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* all potential SendFlags bits we can possibly send */
enumflags
{
PLAYER_AMMO1 = PLAYER_CUSTOMFIELDSTART,
PLAYER_AMMO2,
PLAYER_AMMO3,
PLAYER_UNUSED5,
PLAYER_UNUSED6,
PLAYER_UNUSED7,
PLAYER_UNUSED7,
PLAYER_UNUSED8
};
class player:NSClientPlayer
{
PREDICTED_INT(mode_tempstate)
#ifdef CLIENT
virtual void(float,float) ReceiveEntity;
virtual void(void) PredictPreFrame;
virtual void(void) PredictPostFrame;
virtual void(void) UpdateAliveCam;
#else
virtual void(void) EvaluateEntity;
virtual float(entity, float) SendEntity;
#endif
};
#ifdef CLIENT
void Shake_Update(NSClientPlayer);
vector Camera_RunBob(vector);
vector Camera_StrafeRoll(vector);
vector Camera_AddCamBob(vector);
vector Camera_AddLean(vector);
void View_DisableViewmodel(void);
void
player::UpdateAliveCam(void)
{
vector cam_pos = GetEyePos();
g_view.SetCameraAngle(view_angles);
g_view.SetCameraOrigin(cam_pos + Camera_AddCamBob(view_angles) + Camera_AddLean(view_angles));
if (vehicle) {
NSVehicle veh = (NSVehicle)vehicle;
if (veh.UpdateView)
veh.UpdateView();
} else if (health) {
if (autocvar_pm_thirdPerson == TRUE) {
makevectors(view_angles);
vector vStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4);
vector vEnd = vStart + (v_forward * -48) + [0,0,16] + (v_right * 4);
traceline(vStart, vEnd, FALSE, this);
g_view.SetCameraOrigin(trace_endpos + (v_forward * 5));
}
}
Shake_Update(this);
g_view.AddPunchAngle(punchangle);
}
/*
=================
player::ReceiveEntity
=================
*/
void
player::ReceiveEntity(float new, float fl)
{
NSClientPlayer::ReceiveEntity(new, fl);
setorigin(this, origin);
}
/*
=================
player::PredictPostFrame
Save the last valid server values away in the _net variants of each field
so we can roll them back later.
=================
*/
void
player::PredictPreFrame(void)
{
NSClientPlayer::PredictPreFrame();
}
/*
=================
player::PredictPostFrame
Where we roll back our values to the ones last sent/verified by the server.
=================
*/
void
player::PredictPostFrame(void)
{
NSClientPlayer::PredictPostFrame();
}
#else
void
player::EvaluateEntity(void)
{
NSClientPlayer::EvaluateEntity();
}
/*
=================
player::SendEntity
=================
*/
float
player::SendEntity(entity ePEnt, float fChanged)
{
/* don't broadcast invisible players */
if (IsFakeSpectator() && ePEnt != this)
return (0);
if (!GetModelindex() && ePEnt != this)
return (0);
fChanged = OptimiseChangedFlags(ePEnt, fChanged);
WriteByte(MSG_ENTITY, ENT_PLAYER);
WriteFloat(MSG_ENTITY, fChanged);
/* the generic client attributes */
NSClientPlayer::SendEntity(ePEnt, fChanged);
return (1);
}
#endif

View File

@ -1,4 +1,4 @@
entityDef player entityDef player
{ {
"spawnclass" "NSClientPlayer" "spawnclass" "NSClientPlayer"
} }

View File

@ -41,8 +41,57 @@ typedef enum
/** A virtual multiplayer opponent. Base class for all bots. /** A virtual multiplayer opponent. Base class for all bots.
*/ */
class NSBot:player class NSBot:NSNavAI
{ {
public:
void(void) NSBot;
#ifdef SERVER
virtual void(botstate_t) SetState;
virtual botstate_t(void) GetState;
virtual botpersonality_t(void) GetPersonality;
virtual float GetForwardSpeed(void);
virtual float GetSideSpeed(void);
virtual float GetBackSpeed(void);
virtual void(string) ChatSay;
virtual void(string) ChatSayTeam;
virtual void(void) Pain;
virtual void(void) RouteClear;
virtual void(void) WeaponThink;
virtual void(void) WeaponAttack;
virtual void(void) SeeThink;
virtual void(int, int) BrainThink;
virtual void(void) RunAI;
virtual void(void) CreateObjective;
virtual void(void) CheckRoute;
virtual void(void) PreFrame;
virtual void(void) PostFrame;
virtual void(void) UseButton;
virtual void(entity) SetEnemy;
virtual float(void) GetRunSpeed;
virtual float(void) GetWalkSpeed;
nonvirtual void ForceWeaponAttack(vector, float);
virtual void(string) SetName;
/** Server: Set the value of an InfoKey. */
nonvirtual void SetInfoKey(string, string);
/** Server: Floating point based version of SetInfoKey(). */
nonvirtual void SetInfoKeyFloat(string, float);
#endif
/** Get the string value of an InfoKey. */
nonvirtual string GetInfoKey(string);
/** Floating point based version of GetInfoKey(). */
nonvirtual float GetInfoKeyFloat(string);
#ifdef SERVER
private:
/* routing */ /* routing */
int m_iNodes; int m_iNodes;
int m_iCurNode; int m_iCurNode;
@ -73,41 +122,13 @@ class NSBot:player
vector m_vecLastPOI; vector m_vecLastPOI;
float m_flForceWeaponAttack; float m_flForceWeaponAttack;
vector m_vecForceWeaponAttackPos; vector m_vecForceWeaponAttackPos;
#endif
void(void) NSBot;
virtual void(botstate_t) SetState;
virtual botstate_t(void) GetState;
virtual botpersonality_t(void) GetPersonality;
virtual float GetForwardSpeed(void);
virtual float GetSideSpeed(void);
virtual float GetBackSpeed(void);
virtual void(string) ChatSay;
virtual void(string) ChatSayTeam;
virtual void(void) Pain;
virtual void(void) RouteClear;
virtual void(void) WeaponThink;
virtual void(void) WeaponAttack;
virtual void(void) SeeThink;
virtual void(int, int) BrainThink;
virtual void(void) RunAI;
virtual void(void) CreateObjective;
virtual void(void) CheckRoute;
virtual void(void) PreFrame;
virtual void(void) PostFrame;
virtual void(void) UseButton;
virtual void(entity) SetEnemy;
virtual float(void) GetRunSpeed;
virtual float(void) GetWalkSpeed;
nonvirtual void ForceWeaponAttack(vector, float);
virtual void(string) SetName;
}; };
#ifdef SERVER
/** Adds a bot to the game with some basic info. Returns the resulting entity. __NULL__ if unavailable. */ /** Adds a bot to the game with some basic info. Returns the resulting entity. __NULL__ if unavailable. */
entity Bot_AddQuick(void); entity Bot_AddQuick(void);
void BotLib_Init(void);
/** Applies random custom colors to the given bot entity. */ /** Applies random custom colors to the given bot entity. */
void void
@ -120,3 +141,4 @@ Bot_RandomColormap(NSBot target)
forceinfokey(target, "topcolor", sprintf("0x%x", top)); forceinfokey(target, "topcolor", sprintf("0x%x", top));
forceinfokey(target, "bottomcolor", sprintf("0x%x", bottom)); forceinfokey(target, "bottomcolor", sprintf("0x%x", bottom));
} }
#endif

View File

@ -14,6 +14,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef SERVER
/* default client side player movement values */ /* default client side player movement values */
var float autocvar_bot_forwardspeed = 190; var float autocvar_bot_forwardspeed = 190;
var float autocvar_bot_sidespeed = 152; var float autocvar_bot_sidespeed = 152;
@ -297,7 +298,7 @@ NSBot::RunAI(void)
input_angles = [0,0,0]; input_angles = [0,0,0];
/* attempt to respawn when dead */ /* attempt to respawn when dead */
if (IsDead() == true || health <= 0) { if (IsAlive() == false || health <= 0) {
RouteClear(); RouteClear();
WeaponAttack(); WeaponAttack();
SetEnemy(__NULL__); SetEnemy(__NULL__);
@ -511,7 +512,7 @@ NSBot::PreFrame(void)
void void
NSBot::PostFrame(void) NSBot::PostFrame(void)
{ {
#ifndef NEW_INVENTORY #if 0
/* we've picked something new up */ /* we've picked something new up */
if (m_iOldItems != g_items) { if (m_iOldItems != g_items) {
Weapons_SwitchBest(this); Weapons_SwitchBest(this);
@ -531,13 +532,54 @@ NSBot::SetName(string nickname)
} }
void void
NSBot::NSBot(void) NSBot::SetInfoKey(string strKey, string strValue)
{ {
classname = "player"; forceinfokey(this, strKey, strValue);
targetname = "_nuclide_bot_";
SetInfoKey("*bot", "1");
} }
void
NSBot::SetInfoKeyFloat(string strKey, float floatValue)
{
forceinfokey(this, strKey, ftos(floatValue));
}
#endif
string
NSBot::GetInfoKey(string strKey)
{
#ifdef SERVER
return infokey(this, strKey);
#endif
#ifdef CLIENT
return getplayerkeyvalue(entnum-1, strKey);
#endif
}
float
NSBot::GetInfoKeyFloat(string strKey)
{
#ifdef SERVER
return infokeyf(this, strKey);
#endif
#ifdef CLIENT
return getplayerkeyfloat(entnum-1, strKey);
#endif
}
void
NSBot::NSBot(void)
{
#ifdef SERVER
targetname = "_nuclide_bot_";
SetInfoKey("*bot", "1");
#endif
}
#ifdef SERVER
void void
Bot_KickRandom(void) Bot_KickRandom(void)
{ {
@ -594,3 +636,4 @@ BotLib_Init(void)
bot_spawner.think = bot_spawner_think; bot_spawner.think = bot_spawner_think;
bot_spawner.nextthink = time + 1.0f; bot_spawner.nextthink = time + 1.0f;
} }
#endif

View File

@ -58,6 +58,7 @@ NSBot::SetEnemy(entity en)
void void
NSBot::WeaponThink(void) NSBot::WeaponThink(void)
{ {
#if 0
int r = Weapons_IsEmpty(this, activeweapon); int r = Weapons_IsEmpty(this, activeweapon);
/* clip empty, but the whole weapon isn't */ /* clip empty, but the whole weapon isn't */
@ -71,6 +72,7 @@ NSBot::WeaponThink(void)
} }
m_wtWeaponType = Weapons_GetType(this, activeweapon); m_wtWeaponType = Weapons_GetType(this, activeweapon);
#endif
} }
void void

View File

@ -15,7 +15,6 @@
*/ */
#include "cvars.h" #include "cvars.h"
#include "NSBot.h"
vector Route_SelectDestination( NSBot target ); vector Route_SelectDestination( NSBot target );

View File

@ -3,7 +3,6 @@
#includelist #includelist
defs.h defs.h
profiles.qc profiles.qc
NSBot.qc
chat.qc chat.qc
combat.qc combat.qc
route.qc route.qc

View File

@ -38,7 +38,7 @@ Bot_AddBot_f(string botName, float teamValue, float spawnDelay, string newName)
int extraCount = 0i; int extraCount = 0i;
int foundID = -1i; int foundID = -1i;
entity oldSelf; entity oldSelf;
NSBot newBot; NSClientPlayer newBot;
int i = 0i; int i = 0i;
if (!botName) { if (!botName) {
@ -73,7 +73,7 @@ Bot_AddBot_f(string botName, float teamValue, float spawnDelay, string newName)
return (false); return (false);
} }
newBot = (NSBot)self; newBot = (NSClientPlayer)self;
newBot.SetInfoKey("name", g_bots[foundID].m_strNetName); newBot.SetInfoKey("name", g_bots[foundID].m_strNetName);
extraCount = tokenize(g_bots[foundID].m_strExtra); extraCount = tokenize(g_bots[foundID].m_strExtra);

View File

@ -64,7 +64,7 @@ Cross_DrawSubRGBA(string materialPath, vector sizeXY, vector sourcePosXY, vector
} else { } else {
vector vecSrc; vector vecSrc;
vector vecDst; vector vecDst;
player pl = (player)pSeat->m_ePlayer; NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer;
vecSrc = pSeat->m_vecPredictedOrigin + pSeat->m_ePlayer.view_ofs; vecSrc = pSeat->m_vecPredictedOrigin + pSeat->m_ePlayer.view_ofs;
makevectors(view_angles); makevectors(view_angles);

View File

@ -78,6 +78,7 @@ Entity_EntityUpdate(float type, float new)
break; break;
case ENT_PLAYER: case ENT_PLAYER:
NSClientPlayer pl = (NSClientPlayer)self; NSClientPlayer pl = (NSClientPlayer)self;
spawnfunc_NSClientPlayer();
/* splitscreen */ /* splitscreen */
CSQC_UpdateSeat(); CSQC_UpdateSeat();

View File

@ -50,7 +50,7 @@ Client_IsPlayer(NSClient cl)
bool bool
Client_InVehicle(void) Client_InVehicle(void)
{ {
player pl = (player)pSeat->m_ePlayer; NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer;
return (pl.vehicle != world) ? true : false; return (pl.vehicle != world) ? true : false;
} }

View File

@ -119,7 +119,7 @@ View_HandleAnimEvent(float flTimeStamp, int iCode, string strData)
} }
void void
View_ForceChange(player pl, int targetWeapon) View_ForceChange(NSClientPlayer pl, int targetWeapon)
{ {
NSRenderableEntity m_eViewModel = (NSRenderableEntity)pSeat->m_eViewModel; NSRenderableEntity m_eViewModel = (NSRenderableEntity)pSeat->m_eViewModel;
NSRenderableEntity m_eViewModelL = (NSRenderableEntity)pSeat->m_eViewModelL; NSRenderableEntity m_eViewModelL = (NSRenderableEntity)pSeat->m_eViewModelL;
@ -186,7 +186,7 @@ View_DrawViewModel(void)
if (pl.activeweapon) { if (pl.activeweapon) {
/* hack, we changed the wep, move this into Game_Input/PMove */ /* hack, we changed the wep, move this into Game_Input/PMove */
Weapons_Draw((player)pl); Weapons_Draw((NSClientPlayer)pl);
} else { } else {
pSeat->m_eViewModel.modelindex = pSeat->m_eViewModel.modelindex =
pSeat->m_eViewModelL.modelindex = 0; pSeat->m_eViewModelL.modelindex = 0;

View File

@ -145,17 +145,17 @@ NSGameRules::LevelChangeParms(NSClientPlayer pl)
/* spectator */ /* spectator */
/*void /*void
NSGameRules::SpectatorConnect(player pl) NSGameRules::SpectatorConnect(NSClientSpectator pl)
{ {
//print("SpectatorConnect!\n"); //print("SpectatorConnect!\n");
} }
void void
NSGameRules::SpectatorDisconnect(player pl) NSGameRules::SpectatorDisconnect(NSClientSpectator pl)
{ {
//print("SpectatorDisconnect!\n"); //print("SpectatorDisconnect!\n");
} }
void void
NSGameRules::SpectatorThink(player pl) NSGameRules::SpectatorThink(NSClientSpectator pl)
{ {
//print("SpectatorThink!\n"); //print("SpectatorThink!\n");
}*/ }*/
@ -423,13 +423,13 @@ NSGameRules::DamageApply(entity t, entity c, float dmg, int w, damageType_t type
/* they died */ /* they died */
if (eTarget.GetHealth() <= 0) { if (eTarget.GetHealth() <= 0) {
if (eTarget.flags & FL_CLIENT) { if (eTarget.flags & FL_CLIENT) {
PlayerDeath((player)eTarget); PlayerDeath(eTarget);
} else { } else {
eTarget.Death(); eTarget.Death();
} }
} else { } else {
if (eTarget.flags & FL_CLIENT) { if (eTarget.flags & FL_CLIENT) {
PlayerPain((player)eTarget); PlayerPain(eTarget);
} else { } else {
eTarget.Pain(); eTarget.Pain();
} }

View File

@ -34,14 +34,14 @@ Cmd_ParseClientCommand(NSClient sender, string cmd, int commandArguments)
if (sender.classname != "player") if (sender.classname != "player")
break; break;
player pl = (player)sender; NSClientPlayer pl = (NSClientPlayer)sender;
pl.MakeSpectator(); pl.MakeSpectator();
break; break;
case "play": case "play":
if (sender.classname != "spectator") if (sender.classname != "spectator")
break; break;
spawnfunc_player(); EntityDef_SpawnClassname("player");
PutClientInServer(); PutClientInServer();
break; break;
case "setpos": case "setpos":

View File

@ -49,17 +49,9 @@ ClientConnect(void)
/* don't carry over team settings from a previous session */ /* don't carry over team settings from a previous session */
forceinfokey(self, "*team", "0"); forceinfokey(self, "*team", "0");
/* bot needs special init */
#ifdef BOT_INCLUDED
if (clienttype(self) == CLIENTTYPE_BOT) {
/* from now on we're of type NSBot */
EntityDef_SpawnClassname("bot");
} else
#endif
/* make sure you never change the classname. ever. */ /* make sure you never change the classname. ever. */
if (self.classname != "player") { if (self.classname != "player") {
spawnfunc_player(); EntityDef_SpawnClassname("player");
} }
if (g_ents_initialized) if (g_ents_initialized)
@ -80,7 +72,7 @@ ClientDisconnect(void)
g_grMode.PlayerDisconnect((NSClientPlayer)self); g_grMode.PlayerDisconnect((NSClientPlayer)self);
/* this will hide/remove the player from other clients */ /* this will hide/remove the player from other clients */
player pl = (player)self; NSClientPlayer pl = (NSClientPlayer)self;
pl.SetSolid(SOLID_NOT); pl.SetSolid(SOLID_NOT);
pl.SetMovetype(MOVETYPE_NONE); pl.SetMovetype(MOVETYPE_NONE);
pl.SetModelindex(0); pl.SetModelindex(0);
@ -233,7 +225,7 @@ PlayerPostThink(void)
#endif #endif
if (g_ents_initialized) { if (g_ents_initialized) {
player pl = (player)self; NSClientPlayer pl = (NSClientPlayer)self;
g_grMode.PlayerPostFrame((NSClientPlayer)self); g_grMode.PlayerPostFrame((NSClientPlayer)self);
pl.EvaluateEntity(); pl.EvaluateEntity();
forceinfokey(pl, "*score", ftos(pl.score)); forceinfokey(pl, "*score", ftos(pl.score));
@ -467,7 +459,7 @@ The client-side equivalent is `CSQC_ConsoleCommand` (src/client/entry.qc)
float float
ConsoleCmd(string cmd) ConsoleCmd(string cmd)
{ {
player pl; NSClientPlayer pl;
/* some sv commands can only be executed by a player in-world */ /* some sv commands can only be executed by a player in-world */
if ( !self ) { if ( !self ) {
@ -488,7 +480,7 @@ ConsoleCmd(string cmd)
} }
} }
pl = (player)self; pl = (NSClientPlayer)self;
/* give the game-mode a chance to override us */ /* give the game-mode a chance to override us */
if (g_ents_initialized) if (g_ents_initialized)

View File

@ -56,7 +56,7 @@ Vote_Reset(void)
forceinfokey(world, "vote_cmd", ""); forceinfokey(world, "vote_cmd", "");
for (entity e = world; (e = find(e, ::classname, "player"));) { for (entity e = world; (e = find(e, ::classname, "player"));) {
player pl = (player)e; NSClientPlayer pl = (NSClientPlayer)e;
pl.voted = 0; pl.voted = 0;
} }
} }
@ -128,7 +128,7 @@ CSEv_VoteY
void void
CSEv_VoteY(void) CSEv_VoteY(void)
{ {
player pl = (player)self; NSClientPlayer pl = (NSClientPlayer)self;
/* No vote is in progress */ /* No vote is in progress */
if (g_iVoteState != VOTE_INPROGRESS) { if (g_iVoteState != VOTE_INPROGRESS) {
@ -173,7 +173,7 @@ CSEv_VoteN
void void
CSEv_VoteN(void) CSEv_VoteN(void)
{ {
player pl = (player)self; NSClientPlayer pl = (NSClientPlayer)self;
/* No vote is in progress */ /* No vote is in progress */
if (g_iVoteState != VOTE_INPROGRESS) { if (g_iVoteState != VOTE_INPROGRESS) {

View File

@ -72,7 +72,7 @@ void
Weapons_RefreshAmmo(NSClientPlayer pl) Weapons_RefreshAmmo(NSClientPlayer pl)
{ {
if (g_weapons[pl.activeweapon].updateammo != __NULL__) { if (g_weapons[pl.activeweapon].updateammo != __NULL__) {
g_weapons[pl.activeweapon].updateammo((player)pl); g_weapons[pl.activeweapon].updateammo(pl);
} }
} }
@ -99,7 +99,7 @@ Weapons_SwitchBest(NSClientPlayer pl, optional float skip = 0)
continue; continue;
/* do we have the weapon and is not not empty? */ /* do we have the weapon and is not not empty? */
if ((pl.g_items & g_weapons[x].id) && (Weapons_IsEmpty((player)pl, x) == 0)) { if ((pl.g_items & g_weapons[x].id) && (Weapons_IsEmpty(pl, x) == 0)) {
pl.activeweapon = x; pl.activeweapon = x;
break; break;
} }
@ -108,7 +108,7 @@ Weapons_SwitchBest(NSClientPlayer pl, optional float skip = 0)
if (old == pl.activeweapon) if (old == pl.activeweapon)
return; return;
Weapons_Draw((player)pl); Weapons_Draw(pl);
self = oldself; self = oldself;
pl.gflags |= GF_SEMI_TOGGLED; pl.gflags |= GF_SEMI_TOGGLED;
} }
@ -159,7 +159,7 @@ Weapons_AddItem(NSClientPlayer pl, int w, int startammo)
/* it's new, so autoswitch? */ /* it's new, so autoswitch? */
if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) { if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) {
pl.activeweapon = w; pl.activeweapon = w;
Weapons_Draw((player)pl); Weapons_Draw(pl);
} else { } else {
Weapons_PickupNotify(pl, w); Weapons_PickupNotify(pl, w);
} }
@ -168,21 +168,21 @@ Weapons_AddItem(NSClientPlayer pl, int w, int startammo)
/* call pickup to handle the ammo */ /* call pickup to handle the ammo */
if (pl.g_items & g_weapons[w].id) { if (pl.g_items & g_weapons[w].id) {
/* we have the item already, se let's see if we hit maxammo */ /* we have the item already, se let's see if we hit maxammo */
value = g_weapons[w].pickup((player)pl, FALSE, startammo); value = g_weapons[w].pickup(pl, FALSE, startammo);
/* FALSE means maxammo is hit */ /* FALSE means maxammo is hit */
if (!value) if (!value)
return value; return value;
} else if (over_limit == false) { } else if (over_limit == false) {
/* new to our arsenal */ /* new to our arsenal */
if (g_weapons[w].pickup((player)pl, TRUE, startammo) == TRUE) { if (g_weapons[w].pickup(pl, TRUE, startammo) == TRUE) {
pl.g_items |= g_weapons[w].id; pl.g_items |= g_weapons[w].id;
value = TRUE; value = TRUE;
/* it's new, so autoswitch? */ /* it's new, so autoswitch? */
if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) { if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) {
pl.activeweapon = w; pl.activeweapon = w;
Weapons_Draw((player)pl); Weapons_Draw(pl);
} else { } else {
Weapons_PickupNotify(pl, w); Weapons_PickupNotify(pl, w);
} }
@ -239,28 +239,28 @@ Weapons_AddItemSilent(NSClientPlayer pl, int w, int startammo)
/* it's new, so autoswitch? */ /* it's new, so autoswitch? */
if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) { if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) {
pl.activeweapon = w; pl.activeweapon = w;
Weapons_Draw((player)pl); Weapons_Draw(pl);
} }
} }
} else { } else {
/* call pickup to handle the ammo */ /* call pickup to handle the ammo */
if (pl.g_items & g_weapons[w].id) { if (pl.g_items & g_weapons[w].id) {
/* we have the item already, se let's see if we hit maxammo */ /* we have the item already, se let's see if we hit maxammo */
value = g_weapons[w].pickup((player)pl, FALSE, startammo); value = g_weapons[w].pickup(pl, FALSE, startammo);
/* FALSE means maxammo is hit */ /* FALSE means maxammo is hit */
if (!value) if (!value)
return value; return value;
} else if (over_limit == false) { } else if (over_limit == false) {
/* new to our arsenal */ /* new to our arsenal */
if (g_weapons[w].pickup((player)pl, TRUE, startammo) == TRUE) { if (g_weapons[w].pickup(pl, TRUE, startammo) == TRUE) {
pl.g_items |= g_weapons[w].id; pl.g_items |= g_weapons[w].id;
value = TRUE; value = TRUE;
/* it's new, so autoswitch? */ /* it's new, so autoswitch? */
if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) { if (pl.activeweapon == 0 && autocvar_sv_forceweapondraw == 1) {
pl.activeweapon = w; pl.activeweapon = w;
Weapons_Draw((player)pl); Weapons_Draw(pl);
} }
} else { } else {
/* cannot pickup this weapon (weapon says no) */ /* cannot pickup this weapon (weapon says no) */
@ -379,7 +379,7 @@ The 'drop' command from the client-module calls this.
void void
CSEv_DropWeapon(void) CSEv_DropWeapon(void)
{ {
player pl = (player)self; NSClientPlayer pl = (NSClientPlayer)self;
Weapon_DropCurrentWeapon(pl); Weapon_DropCurrentWeapon(pl);
} }
#endif #endif
@ -387,7 +387,7 @@ CSEv_DropWeapon(void)
void void
CSEv_PlayerSwitchWeapon_i(int w) CSEv_PlayerSwitchWeapon_i(int w)
{ {
player pl = (player)self; NSClientPlayer pl = (NSClientPlayer)self;
if (pl.activeweapon != w) { if (pl.activeweapon != w) {
pl.activeweapon = w; pl.activeweapon = w;

View File

@ -20,7 +20,7 @@ It is mostly concerned with the features shared between players
and spectating clients alike. and spectating clients alike.
*/ */
class class
NSClient:NSNavAI NSClient:NSBot
{ {
public: public:
void NSClient(void); void NSClient(void);
@ -65,21 +65,10 @@ public:
virtual float predraw(void); virtual float predraw(void);
#endif #endif
/** Get the string value of an InfoKey. */
nonvirtual string GetInfoKey(string);
/** Floating point based version of GetInfoKey(). */
nonvirtual float GetInfoKeyFloat(string);
#ifdef SERVER #ifdef SERVER
/** Server: This is where the input* variables arrive after sending them out from the client (see ClientInputFrame). This is also where we will instruct the server to run physics on the client. */ /** Server: This is where the input* variables arrive after sending them out from the client (see ClientInputFrame). This is also where we will instruct the server to run physics on the client. */
virtual void ServerInputFrame(void); virtual void ServerInputFrame(void);
/** Server: Set the value of an InfoKey. */
nonvirtual void SetInfoKey(string, string);
/** Server: Floating point based version of SetInfoKey(). */
nonvirtual void SetInfoKeyFloat(string, float);
/* overrides */ /* overrides */
virtual void Save(float); virtual void Save(float);
virtual void Restore(string,string); virtual void Restore(string,string);

View File

@ -62,46 +62,8 @@ void
NSClient::ServerInputFrame(void) NSClient::ServerInputFrame(void)
{ {
} }
void
NSClient::SetInfoKey(string strKey, string strValue)
{
forceinfokey(this, strKey, strValue);
}
void
NSClient::SetInfoKeyFloat(string strKey, float floatValue)
{
forceinfokey(this, strKey, ftos(floatValue));
}
#endif #endif
string
NSClient::GetInfoKey(string strKey)
{
#ifdef SERVER
return infokey(this, strKey);
#endif
#ifdef CLIENT
return getplayerkeyvalue(entnum-1, strKey);
#endif
}
float
NSClient::GetInfoKeyFloat(string strKey)
{
#ifdef SERVER
return infokeyf(this, strKey);
#endif
#ifdef CLIENT
return getplayerkeyfloat(entnum-1, strKey);
#endif
}
void void
NSClient::SharedInputFrame(void) NSClient::SharedInputFrame(void)
{ {

View File

@ -144,7 +144,7 @@ private:
* effects of some bits. Such as invisibility, quad, etc. * effects of some bits. Such as invisibility, quad, etc.
* also, modders probably want 32 bits for items. */ * also, modders probably want 32 bits for items. */
PREDICTED_INT(g_items) PREDICTED_INT(g_items)
PREDICTED_FLOAT(activeweapon) PREDICTED_FLOAT_N(activeweapon)
#ifdef NEW_INVENTORY #ifdef NEW_INVENTORY
NSWeapon m_weapons[MAX_WEAPONS]; NSWeapon m_weapons[MAX_WEAPONS];

View File

@ -198,19 +198,19 @@ NSClientPlayer::ProcessInput(void)
canfire = false; canfire = false;
if (canfire == false) { if (canfire == false) {
Weapons_Release((player)this); Weapons_Release(this);
return; return;
} }
/* weapon system */ /* weapon system */
if (input_buttons & INPUT_SECONDARY) if (input_buttons & INPUT_SECONDARY)
Weapons_Secondary((player)this); Weapons_Secondary(this);
else if (input_buttons & INPUT_PRIMARY) else if (input_buttons & INPUT_PRIMARY)
Weapons_Primary((player)this); Weapons_Primary(this);
else if (input_buttons & INPUT_RELOAD) else if (input_buttons & INPUT_RELOAD)
Weapons_Reload((player)this); Weapons_Reload(this);
else else
Weapons_Release((player)this); Weapons_Release(this);
} }
/* this is where it gets mod specific really fast, /* this is where it gets mod specific really fast,
@ -315,7 +315,7 @@ NSClientPlayer::predraw(void)
/* draw a 3D voice blob over its head */ /* draw a 3D voice blob over its head */
Voice_Draw3D(this); Voice_Draw3D(this);
Weapons_PreDraw((player)this, true); Weapons_PreDraw(this, true);
/* force drawing us if it's our local player and we're meant to show */ /* force drawing us if it's our local player and we're meant to show */
if (entnum == player_localentnum) if (entnum == player_localentnum)
@ -328,7 +328,7 @@ NSClientPlayer::predraw(void)
/* give mods a chance to de-render attachments */ /* give mods a chance to de-render attachments */
UpdatePlayerAttachments(true); UpdatePlayerAttachments(true);
Weapons_PreDraw((player)this, false); Weapons_PreDraw(this, false);
/* this is here just to make sure our view hides us if it's the local player */ /* this is here just to make sure our view hides us if it's the local player */
if (entnum == player_localentnum) if (entnum == player_localentnum)
@ -1067,6 +1067,17 @@ at the top of player::SendEntity
float float
NSClientPlayer::SendEntity(entity ePEnt, float flChanged) NSClientPlayer::SendEntity(entity ePEnt, float flChanged)
{ {
/* don't broadcast invisible players */
if (IsFakeSpectator() && ePEnt != this)
return (0);
if (!GetModelindex() && ePEnt != this)
return (0);
flChanged = OptimiseChangedFlags(ePEnt, flChanged);
WriteByte(MSG_ENTITY, ENT_PLAYER);
WriteFloat(MSG_ENTITY, flChanged);
SENDENTITY_INT(modelindex, PLAYER_MODELINDEX) SENDENTITY_INT(modelindex, PLAYER_MODELINDEX)
SENDENTITY_BYTE(colormap, PLAYER_MODELINDEX) SENDENTITY_BYTE(colormap, PLAYER_MODELINDEX)
@ -1149,9 +1160,6 @@ NSClientPlayer::OptimiseChangedFlags(entity ePEnt, float flChanged)
flChanged &= ~PLAYER_ITEMS; flChanged &= ~PLAYER_ITEMS;
//flChanged &= ~PLAYER_HEALTH; //flChanged &= ~PLAYER_HEALTH;
flChanged &= ~PLAYER_TIMINGS; flChanged &= ~PLAYER_TIMINGS;
flChanged &= ~PLAYER_AMMO1;
flChanged &= ~PLAYER_AMMO2;
flChanged &= ~PLAYER_AMMO3;
//flChanged &= ~PLAYER_FLAGS; //flChanged &= ~PLAYER_FLAGS;
flChanged &= ~PLAYER_PUNCHANGLE; flChanged &= ~PLAYER_PUNCHANGLE;
flChanged &= ~PLAYER_VIEWZOOM; flChanged &= ~PLAYER_VIEWZOOM;

View File

@ -29,6 +29,18 @@ _NSNavAI_Log(string className, string functionName, float edictNum, string warnM
#define MAX_AMMO_TYPES 16 #define MAX_AMMO_TYPES 16
#endif #endif
/* for AI identification purposes */
typedef enum
{
WPNTYPE_INVALID, /* no logic */
WPNTYPE_RANGED, /* will want to keep their distance mostly */
WPNTYPE_THROW, /* has to keep some distance, but not too far */
WPNTYPE_CLOSE, /* have to get really close */
WPNTYPE_FULLAUTO, /* for things that need to be held down */
WPNTYPE_SEMI /* semi automatic */
} weapontype_t;
/** This entity class represents a moving/pathfinding object. /** This entity class represents a moving/pathfinding object.
It knows how to deal with waypoint based nodes and possibly other It knows how to deal with waypoint based nodes and possibly other
types of pathfinding in the future. types of pathfinding in the future.
@ -140,4 +152,5 @@ private:
/* These are defined in side defs\*.def, ammo_types and ammo_names */ /* These are defined in side defs\*.def, ammo_types and ammo_names */
int m_iAmmoTypes[MAX_AMMO_TYPES]; int m_iAmmoTypes[MAX_AMMO_TYPES];
NSItem m_itemList; NSItem m_itemList;
float activeweapon;
}; };

View File

@ -106,6 +106,7 @@ string __fullspawndata;
#include "NSDebris.h" #include "NSDebris.h"
#include "../xr/defs.h" #include "../xr/defs.h"
#include "../botlib/NSBot.h"
#include "NSClient.h" #include "NSClient.h"
#include "NSClientSpectator.h" #include "NSClientSpectator.h"
#include "NSClientPlayer.h" #include "NSClientPlayer.h"

View File

@ -41,4 +41,5 @@ motd.qc
weapon_common.qc weapon_common.qc
../xr/include.src ../xr/include.src
../botlib/NSBot.qc
#endlist #endlist

View File

@ -1,14 +1,6 @@
#ifdef NEW_INVENTORY #ifdef NEW_INVENTORY
/* for AI identification purposes */
typedef enum
{
WPNTYPE_INVALID, /* no logic */
WPNTYPE_RANGED, /* will want to keep their distance mostly */
WPNTYPE_THROW, /* has to keep some distance, but not too far */
WPNTYPE_CLOSE, /* have to get really close */
WPNTYPE_FULLAUTO, /* for things that need to be held down */
WPNTYPE_SEMI /* semi automatic */
} weapontype_t;
void Weapons_Draw(NSClientPlayer); void Weapons_Draw(NSClientPlayer);
void Weapons_Release(NSClientPlayer); void Weapons_Release(NSClientPlayer);