djcev.com

//

Git Repos / fte_dogmode / qc / cl_entry.qc

Last update to this file was on 2024-03-24 at 02:40.

Show cl_entry.qc

//==============================================================================
// CSQC entrypoints
//==============================================================================

//======================================================================
// globals
//======================================================================

#ifdef CSQC
float nocsqc; // CSQC State (0=on, 1=off)
float sitems; // CSQC copy of .items
float sitems2; // CSQC copy of .items2 (or serverflags)
float sweapon; // CSQC copy of .weapon
float shealth; // CSQC copy of .health

float painfinishtime; // Track player damage for hud face

float intermission; // in intermission
float intermission_time; // when the intermission started

float numclientseats; // coop or splitscreen?
float maxclients; // max players possible on this server
float cltime; // inc. regardless of pause or gamespeed

// float player_localnum; // Player slot that is assigned to us
float player_localentnum; // Ent number that csqc is attached to

float sb_showscores; // Show lower tab scores

// This is the input-frame sequence. frames < clientcommandframe have been
// sent to the server. frame==clientcommandframe is still being generated
// and can still change.
float clientcommandframe;
// This is the input-frame that was last acknowledged by the server.
// Input frames greater than this should be applied to the player's entity.
float servercommandframe;

string CSQC_PING = "csqcping"; // Test command to check if CSCQ alive

entity viewentity; // camera -- CEV
vector view_origin; // origin for viewentity -- CEV
vector view_angles; // +x=DOWN

entity player_local; // handle to the local player entity

vector player_org; // prediction -- from CSQCTest -- CEV
vector player_vel;
float player_flags;
float player_doublejump_timer;
float player_pmove_flags;
float player_sequence;
float player_step;
float player_steptime;
float player_step_oldz;
vector pmove_error;
float pmove_errortime;
float pmove_frame;
#endif

//======================================================================
// fields
//======================================================================

#ifdef CSQC
.float drawmask; // a filter in the addentities call
.float entnum; // The entnum as its known on the server
.float ext_csqc; // Client Server Quake C HUD alive!
.float renderflags;

// The current frame the entity is meant to be displayed in. In CSQC,
// note the lerpfrac and frame2 fields as well. if it specifies a
// framegroup, the framegroup will autoanimate in ssqc, but not in csqc.
// .float frame; // already defined in entvars_t -- CEV
.float frame1time; // absolute time into anim/framegroup
.float frame2; // alt frame visible when lerpfrac is 1
.float frame2time; // absolute time into anim/group frame2
.float oldframe;
.float lerpfrac; // if 0 use frame1, if 1 use frame2,
.float lerptime; // mix together for values between

.string oldskin;

// Called by addentities after the filter and before the entity is actually
// drawn. Do your interpolation and animation in here. Should return one of
// the PREDRAW_* constants.
.float() predraw;

.void() removefunc;
#endif

//======================================================================
// forward declarations
//======================================================================

#ifdef CSQC
float(string cmd) CSQC_ConsoleCommand;
// float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent;
// float(float save, float take, vector dir) CSQC_Parse_Damage;
void(string printmsg, float printlvl) CSQC_Parse_Print;
void(string str) SV_ParseClientCommand;
void(entity ent) CSQC_DrawViewModel;
void(float vwidth, float vheight, float notmenu) CSQC_UpdateView;
// float() CSQC_Parse_TempEntity;
void(float isnew) CSQC_Ent_Update;
void(float apilevel, string enginename, float engineversion) CSQC_Init;
__wrap void(float apilevel, string enginename, float engineversion) CSQC_Init;
__wrap float(string str) CSQC_ConsoleCommand;
#endif

//------------------------------------------------------------------------------

#ifdef CSQC
//----------------------------------------------------------------------
// stubs for server-side entry functions (silences compiler warnings)
//----------------------------------------------------------------------
void() main = sub_null;
void() StartFrame = sub_null;
void() PlayerPreThink = sub_null;
void() PlayerPostThink = sub_null;
void() ClientKill = sub_null;
void() ClientConnect = sub_null;
void() PutClientInServer = sub_null;
void() ClientDisconnect = sub_null;
void() SetNewParms = sub_null;
void() SetChangeParms = sub_null;
#endif

#ifdef CSQC
//----------------------------------------------------------------------
// Stubs for extra CSQC functions (not all supported)
//----------------------------------------------------------------------

// Can query or check anything types on the console here
float(string cmd) CSQC_ConsoleCommand =
{
tokenize_console (cmd);
return FALSE;
};

// Can query/check keyboard/mouse/joystick input with this function
// For key events, scanx is one of the KEY_* values
// chary is the character code (chr2str to shove it into a string)
// For mouse events then x+y are the mouse delta/position values
/*
float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent =
{
return FALSE;
};
*/

// This is linked to client dmg_take / dmg_save / dmg_inflictor fields
// returning TRUE will block the red flash damage stuff
/*
float(float save, float take, vector dir) CSQC_Parse_Damage =
{
painfinishtime = time + 0.2;
return FALSE;
};
*/

// Can query/check server MSG events
// CSQC_Parse_Event is called when the client sees a
// #define svcfte_cgamepacket (83) message from the server
// Not supported for DP, is called from only QSS/FTE
// void() CSQC_Parse_Event = { };

// Can intercept printed messages from the server (top of screen)
// printlvl (text filtering) 0=low, 1=medium, 2=high, 3=chat
// con_notifytime = amount of time the text remains on screen
// ONLY define this function, if doing something with the text!!
void(string printmsg, float printlvl) CSQC_Parse_Print =
{
print (printmsg);
};

// Running on the Server side of CSQC listening for commands back
// This is never called on the client side of the progs
void(string str) SV_ParseClientCommand =
{
local string ostr, cmd;
// Save command string for later
ostr = str;
// Search for tokens in string
tokenize_console (str);
// Find the first argument of the command
cmd = argv (0);
// Is this my (AD CSQC) command?
if (cmd == CSQC_PING)
self.ext_csqc = TRUE;
else
// Pass through original command
clientcommand (self, ostr);
};

//----------------------------------------------------------------------
// TODO CEV
//----------------------------------------------------------------------
void(entity ent) CSQC_DrawViewModel =
{
float newframe, newmodel;

newframe = getstatf (STAT_WEAPONFRAME);
newmodel = getstatf (STAT_WEAPONMODELI);

if (newmodel != ent.modelindex)
{
// changed entirely
ent.modelindex = newmodel;
ent.frame2 = ent.frame = newframe;
ent.lerptime = time;
}
else if (newframe != ent.frame)
{
ent.frame2 = ent.frame;
ent.frame = newframe;
ent.lerptime = time;
}

ent.lerpfrac = 1 - (time - ent.lerptime) * 10;

ent.origin = '0 0 0';
ent.angles = '0 0 0';
ent.effects = player_local.effects;

addentity (ent);
};

//----------------------------------------------------------------------
void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
{
local vector ssize;

ssize_x = vwidth;
ssize_y = vheight;
ssize_z = 0;

// Is the CSQC functionality enabled/disabled?
nocsqc = cvar ("cl_nocsqc");

clearscene ();

// TODO CEV
// addentities (MASK_ENGINE|MASK_VIEWMODEL);
// addentities (MASK_NORMAL | MASK_ENGINE);
setproperty (VF_DRAWWORLD, (float)1);
setproperty (VF_MIN, '0 0');
setproperty (VF_SIZE, ssize);

// If hud is disabled, draw engine hud instead
setproperty (VF_DRAWENGINESBAR, nocsqc);
setproperty (VF_DRAWCROSSHAIR, TRUE);

// TODO CEV
if (self.entnum == player_localentnum)
{
// read our smoothed & predicted view origin
setproperty (VF_VIEWENTITY, viewentity.entnum);
setproperty (VF_ORIGIN, viewentity.origin);
setproperty (VF_ANGLES, viewentity.angles);
setproperty (VF_CL_VIEWANGLES, view_angles);

makevectors (viewentity.angles);
SetListener (view_origin, v_forward, v_right, v_up);

if (intermission)
{
// don't draw crosshair in intermission
setproperty (VF_DRAWCROSSHAIR, FALSE);
}
else
{
// draw view model when not in intermission
CSQC_DrawViewModel (viewentity);
}

if (player_local.effects & EF_MUZZLEFLASH)
dprint ("CSQC_UpdateView: muzzleflash\n");

// setproperty (VF_VIEWENTITY, player_localentnum);
addentities (MASK_ENGINE | MASK_VIEWMODEL | MASK_NORMAL);
}
else
{
// engine didn't tell us about our player entity.
// that's not right...
dprint ("CSQC_UpdateView: no player_local\n");
addentities (MASK_ENGINE | MASK_VIEWMODEL | MASK_NORMAL);
}

renderscene ();

// Revert back to using engine HUD?
if (nocsqc > 0)
return;

// Used on intermission screen later
if (!intermission)
intermission_time = time;

// Read deathmatch variable and create csprogs coop variable
// csprogs has no knowledge of the coop variable
deathmatch = stof (serverkey("deathmatch"));
coop = !deathmatch && maxclients > 1;

// Draw the HUDs and scoreboards
CSQC_DrawHud (ssize, sb_showscores);
CSQC_DrawScores (ssize, sb_showscores);
};

/*
//----------------------------------------------------------------------
// Handle SVC_TEMPENTITY data from the server -- CEV
//
// Based on code by PrimalLove found at:
// https://forums.insideqc.com/viewtopic.php?p=55772#p55772
//----------------------------------------------------------------------
float() CSQC_Parse_TempEntity =
{
float teid, eid;
vector pos, end, vel;
entity e;

teid = ReadByte ();

switch (teid)
{
case 6:
eid = ReadEntityNum ();
pos_x = ReadCoord ();
pos_y = ReadCoord ();
pos_z = ReadCoord ();
end_x = ReadCoord ();
end_y = ReadCoord ();
end_z = ReadCoord ();

trailparticles (particleeffectnum("TE_LIGHTNING2"),
edict_num(eid), pos, end);

// pointparticles (
// particleeffectnum("TE_LIGHTNING2"),
// pos, end, 1);

// if (player_local && player_local.entnum == eid)
// te_lightning2 (player_local, pos, end);
// else
// return FALSE;

return TRUE;
default:
return FALSE;
}

return FALSE;
};
*/

//----------------------------------------------------------------------
// Handle incoming MSG_ENTITY data from the server -- CEV
//----------------------------------------------------------------------
void(float isnew) CSQC_Ent_Update =
{
local float classtype;

classtype = ReadByte ();

switch (classtype)
{
case CT_PLAYER:
PlayerUpdate (isnew);
break;
case CT_TRIGGER_LADDER:
break;
}
};

//----------------------------------------------------------------------
void() CSQC_WorldLoaded =
{
world_latched_cvars ();
};

//----------------------------------------------------------------------
// Registers HUD gfx images (all setup in string arrays)
//----------------------------------------------------------------------
void(float apilevel, string enginename, float engineversion) CSQC_Init =
{
local float i, wadonly;

// Is the CSQC functionality enabled/disabled?
nocsqc = cvar ("cl_nocsqc");
// Revert back to using engine HUD?
if (nocsqc > 0)
return;

// Send ping back to server that CSQC client is alive
// This can be used on the server side to detect CSQC
// and change functions for new features
localcmd (strcat("cmd ", CSQC_PING, "\n"));

// precache from gfx.wad ONLY!?!
wadonly = TRUE;

// Cache all string tables
for (i = 0; i < 14; i++)
{
// HUD background images (320 wide+)
if (i < backgrd.length)
precache_pic (backgrd[i], wadonly);
// Large 24x24 brown/red numbers
if (i < number.length)
{
precache_pic (number[i], wadonly);
precache_pic (anumber[i], wadonly);
}
// Large 24x24 extra font characters (intermission)
if (i < extrachar.length)
precache_pic (extrachar[i], wadonly);
// Large 24x24 player face
if (i < facetab.length)
precache_pic (facetab[i], wadonly);
// Large 24x24 icons
if (i < sbitems.length)
precache_pic (sbitems[i], wadonly);
// Small 16x16 icons
if (i < ibitems.length)
precache_pic (ibitems[i], wadonly);
// Special 8x16 runes
if (i < ibrunes.length)
precache_pic (ibrunes[i], wadonly);
// All weapon setups (on/off/flashing)
if (i < wpnnames.length)
{
precache_pic(strcat(wpnselect[0], wpnnames[i]),wadonly);
precache_pic(strcat(wpnselect[1], wpnnames[i]),wadonly);
precache_pic(strcat(wpnflash[0], wpnnames[i]), wadonly);
precache_pic(strcat(wpnflash[1], wpnnames[i]), wadonly);
precache_pic(strcat(wpnflash[2], wpnnames[i]), wadonly);
precache_pic(strcat(wpnflash[3], wpnnames[i]), wadonly);
precache_pic(strcat(wpnflash[4], wpnnames[i]), wadonly);
}
}

// TODO CEV
precache_model ("progs/player.mdl");

viewentity = spawn ();
viewentity.renderflags = RF_VIEWMODEL|RF_DEPTHHACK|RF_NOSHADOW;
};

//----------------------------------------------------------------------
// Wrapper for CSQC_Init to try and detect DP engine
//----------------------------------------------------------------------
__wrap void(float apilevel, string enginename, float engineversion) CSQC_Init =
{
// Execute previous CSQC_Init function
prior (apilevel, enginename, engineversion);

registercommand ("+showscores");
registercommand ("+showscores");
registercommand ("+showteamscores");
registercommand ("+showteamscores");
};

//----------------------------------------------------------------------
// Wrapper for CSQC_ConsoleCommand to show different scoreboards
//----------------------------------------------------------------------
__wrap float(string str) CSQC_ConsoleCommand =
{
if (prior(str))
return TRUE;

string c = argv(0);

if (c == "+showscores")
sb_showscores |= 1;
else if (c == "-showscores")
sb_showscores &~= 1;
else if (c == "+showteamscores")
sb_showscores |= 2;
else if (c == "-showteamscores")
sb_showscores &~= 2;
else
return FALSE;

return TRUE;
};
#endif

Return to the top of this page or return to the overview of this repo.

Log cl_entry.qc

Date Commit Message Author + -
2024-03-24 2nd pass refactor, rework QC class structure cev +487  

Return to the top of this page or return to the overview of this repo.