game-source/paroxysm/quake/rankings.qc
2004-02-08 06:18:03 +00:00

486 lines
13 KiB
C++

/*
==============================================================================
RANKINGS.QC by Alan Kivlin <e-mail: alan.kivlin@cybersurf.co.uk>
07 / JUNE / 1997
Copyright (C) 1997 by Alan Kivlin.
==============================================================================
*/
// client number of the player/bot
.float fClientNo;
// bit flags for the (maximum) sixteen clients in standard quake
float fActiveClients;
// number of client entities available for the current game
float fMaxClients;
//----------------------------------------------------------------------------
// stores in fMaxClients, the maximum number of client's allowed in the game
void() clientInitMaxClients;
// returns the client's bit flag
float( float fClientNo ) clientBitFlag;
// returns TRUE if the client number specified is in use by a bot or player
float( float fClientNo ) clientIsActive;
// marks the client's bit flag as being in use
void( float fClientNo ) clientSetUsed;
// marks the client's bit flag as being available
void( float fClientNo ) clientSetFree;
// returns the next available free client number (-1 = none available)
float() clientNextAvailable;
//----------------------------------------------------------------------------
// bot's shirt and pants color
.float fShirt;
.float fPants;
//----------------------------------------------------------------------------
// sample routine for connecting a bot
//void() botConnect;
// sample routine for disconnecting a bot
void( entity bot ) botDisconnect;
// moves the conflicting bot over to a free client number, if none it disconnects
void( float clientno ) botInvalidClientNo;
//----------------------------------------------------------------------------
float MSG_UPDATENAME = 13; // message id for update name
float MSG_UPDATEFRAGS = 14; // message id for update frags
float MSG_UPDATECOLORS = 17; // message id for update colors
//----------------------------------------------------------------------------
// sends an update client name message to a player in the game
void( entity player, float clientno, string clientname ) msgUpdateNameToPlayer;
// sends an update client colors message to a player in the game
void( entity player, float clientno, float clientshirt, float clientpants ) msgUpdateColorsToPlayer;
// sends an update client frags message to a player in the game
void( entity player, float clientno, float clientfrags ) msgUpdateFragsToPlayer;
// sends an update client name message to all players in the game
void( float clientno, string clientname ) msgUpdateNameToAll;
// sends an update client colors message to all players in the game
void( float clientno, float clientshirt, float clientpants ) msgUpdateColorsToAll;
// sends an update client frags message to all players in the game
void( float clientno, float clientfrags ) msgUpdateFragsToAll;
//----------------------------------------------------------------------------
/*
==============================================================================
clientInitMaxClients
stores in fMaxClients, the maximum number of client's allowed in the game
==============================================================================
*/
void() clientInitMaxClients =
{
local entity ent;
// this works by counting the number of entities created after world
// so you must call it right at the beginning of worldspawn in WORLD.QC
ent = nextent( world );
while( ent.classname != "worldspawn" )
{
fMaxClients = fMaxClients + 1;
ent = nextent( ent );
}
};
/*
==============================================================================
clientBitFlag
returns the client's bit flag
==============================================================================
*/
float( float clientno ) clientBitFlag =
{
local float bitflag;
bitflag = 1;
while( clientno > 0 )
{
bitflag = bitflag * 2;
clientno = clientno - 1;
}
return bitflag;
};
/*
==============================================================================
clientIsActive
returns TRUE if the client number specified is in use by a bot or player
==============================================================================
*/
float( float clientno ) clientIsActive =
{
if( fActiveClients & clientBitFlag( clientno ) )
return TRUE;
return FALSE;
};
/*
==============================================================================
clientSetUsed
marks the client's bit flag as being in use
==============================================================================
*/
void( float clientno ) clientSetUsed =
{
fActiveClients |= clientBitFlag( clientno );
};
/*
==============================================================================
clientSetFree
marks the client's bit flag as being available
==============================================================================
*/
void( float clientno ) clientSetFree =
{
fActiveClients = fActiveClients -
( fActiveClients & clientBitFlag( clientno ) );
};
/*
==============================================================================
clientNextAvailable
returns the next available free client number (-1 = none available)
==============================================================================
*/
float() clientNextAvailable =
{
local float clientno;
clientno = 0;
while( clientno < fMaxClients )
{
if( ! clientIsActive( clientno ) )
return clientno;
clientno = clientno + 1;
}
return -1;
};
//----------------------------------------------------------------------------
/*
==============================================================================
botConnect
sample routine for connecting a bot
==============================================================================
void() botConnect =
{
local float clientno;
local entity bot;
clientno = clientNextAvailable();
if( clientno == -1 )
{
bprint( "Unable to connect a bot, server is full.\n" );
return;
}
clientSetUsed( clientno );
bot = spawn();
bot.fClientNo = clientno;
bot.colormap = clientno + 1;
// give the bot a name - you provide this routine
// botSetName( bot );
bot.fShirt = floor( random() * 13 );
bot.fPants = floor( random() * 13 );
msgUpdateNameToAll( bot.fClientNo, bot.netname );
msgUpdateColorsToAll( bot.fClientNo, bot.fShirt, bot.fPants );
msgUpdateFragsToAll( bot.fClientNo, bot.frags );
bprint( bot.netname );
bprint( " entered the game\n" );
// add code to initialise the bot
};
*/
/*
==============================================================================
botDisconnect
sample routine for disconnecting a bot
==============================================================================
*/
void(string gibname, float dm) ThrowGib;
void( entity bot ) botDisconnect =
{
if( bot.fClientNo != -1 )
{
// the bot's client number is not in use by a real player so we
// must remove it's entry in the rankings
msgUpdateNameToAll( bot.fClientNo, string_null );
msgUpdateColorsToAll( bot.fClientNo, 0, 0 );
msgUpdateFragsToAll( bot.fClientNo, 0 );
clientSetFree( bot.fClientNo );
bot.fClientNo = -1;
}
bprint( bot.netname );
bprint( " left the game with " );
bprint( ftos( bot.frags ) );
bprint( " frags\n" );
botcounter = botcounter - 1;
//sound( bot, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE );
//POX - 1.01b - Just gib the fucker...
//POX - make a nice gib in Gib mode
if (deathmatch & DM_GIB)
bot.health = bot.health - 40;
//POX-changed self to head model for multi skin support
ThrowGib ("progs/gib3.mdl", bot.health);
ThrowGib ("progs/gib1.mdl", bot.health);
ThrowGib ("progs/gib2.mdl", bot.health);
setmodel (bot, "progs/h_player.mdl");
setsize (bot, '0 0 0', '0 0 0');
bot.solid = SOLID_NOT;
bot.movetype = MOVETYPE_TOSS;
bot.deadflag = DEAD_DEAD;
bot.nextthink = -1;
if (random() < 0.5)
sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
else
sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
/*
// add code to set the bot's suicide frame, copy it to the bodyque, etc
//set_bot_suicide_frame (bot);
bodyque_head.angles = bot.angles;
bodyque_head.model = bot.model;
bodyque_head.modelindex = bot.modelindex;
bodyque_head.frame = bot.frame;
bodyque_head.colormap = bot.colormap;
bodyque_head.movetype = bot.movetype;
bodyque_head.velocity = bot.velocity;
bodyque_head.skin = bot.skin;
bodyque_head.flags = 0;
setorigin (bodyque_head, bot.origin);
setsize (bodyque_head, bot.mins, bot.maxs);
bodyque_head = bodyque_head.owner;
*/
remove (bot);
};
/*
==============================================================================
botInvalidClientNo
moves the conflicting bot over to a free client number, if none it disconnects
==============================================================================
*/
void( float clientno ) botInvalidClientNo =
{
local entity bot;
bot = find( world, classname, "bot" );
while( bot )
{
if( bot.fClientNo == clientno )
{
clientno = clientNextAvailable();
if( clientno != -1 )
{
clientSetUsed( clientno );
bot.fClientNo = clientno;
bot.colormap = bot.fClientNo + 1;
msgUpdateNameToAll( bot.fClientNo, bot.netname );
msgUpdateColorsToAll( bot.fClientNo, bot.fShirt, bot.fPants );
msgUpdateFragsToAll( bot.fClientNo, bot.frags );
}
else
{
bot.fClientNo = -1;
botDisconnect( bot );
}
return;
}
bot = bot.chain; //POX v1.1 Does this make more sense?
//bot = find( bot, classname, "bot" );
}
};
//----------------------------------------------------------------------------
/*
==============================================================================
The following player specific update routines didn't work as I expected.
For some reason, sending messages via MSG_ONE to a player that's just
connected has no effect. My first thought was that the player would still be
in the init stage so I sent via MSG_INIT but this also had no effect.
Messages sent via MSG_ALL *DO* get to a player that's just connected so these
routines aren't really necessary but I left them in anyway and made them call
the relevent ToAll routines.
==============================================================================
*/
/*
==============================================================================
msgUpdateNameToPlayer
sends an update client name message to a player in the game
==============================================================================
*/
void( entity player, float clientno, string clientname ) msgUpdateNameToPlayer =
{
msgUpdateNameToAll( clientno, clientname );
return;
//msg_entity = player;
//WriteByte( MSG_ONE, MSG_UPDATENAME );
//WriteByte( MSG_ONE, clientno );
//WriteString( MSG_ONE, clientname );
};
/*
==============================================================================
msgUpdateColorsToPlayer
sends an update client colors message to a player in the game
==============================================================================
*/
void( entity player, float clientno, float clientshirt, float clientpants ) msgUpdateColorsToPlayer =
{
msgUpdateColorsToAll( clientno, clientshirt, clientpants );
return;
//msg_entity = player;
//WriteByte( MSG_ONE, MSG_UPDATECOLORS );
// WriteByte( MSG_ONE, clientno );
// WriteByte( MSG_ONE, clientshirt * 16 + clientpants );
};
/*
==============================================================================
msgUpdateFragsToPlayer
sends an update client frags message to a player in the game
==============================================================================
*/
void( entity player, float clientno, float clientfrags ) msgUpdateFragsToPlayer =
{
msgUpdateFragsToAll( clientno, clientfrags );
return;
// msg_entity = player;
//WriteByte( MSG_ONE, MSG_UPDATEFRAGS );
// WriteByte( MSG_ONE, clientno );
//WriteShort( MSG_ONE, clientfrags );
};
/*
==============================================================================
msgUpdateNameToAll
sends an update client name message to all players in the game
==============================================================================
*/
void( float clientno, string clientname ) msgUpdateNameToAll =
{
WriteByte (MSG_ALL, MSG_UPDATENAME);
WriteByte (MSG_ALL, clientno);
WriteString (MSG_ALL, clientname);
};
/*
==============================================================================
msgUpdateColorsToAll
sends an update client colors message to all players in the game
==============================================================================
*/
void( float clientno, float clientshirt, float clientpants ) msgUpdateColorsToAll =
{
WriteByte (MSG_ALL, MSG_UPDATECOLORS);
WriteByte (MSG_ALL, clientno);
WriteByte (MSG_ALL, clientshirt * 16 + clientpants);
};
/*
==============================================================================
msgUpdateFragsToAll
sends an update client frags message to all players in the game
==============================================================================
*/
void( float clientno, float clientfrags ) msgUpdateFragsToAll =
{
WriteByte (MSG_ALL, MSG_UPDATEFRAGS);
WriteByte (MSG_ALL, clientno);
WriteShort (MSG_ALL, clientfrags);
};