
Timed Clan Match Mode!
This
little modification lets the server run timed matches! Upon entering the
server, players will be able to pick up weapons and shoot, but no damage will
be delt. Once the pre-match timer expires, everyone will respawn and the
match will begin!
For this tutorial you need to have added .ini file support
to your mod.
It must be working! You may find the .ini
file tutorial at Inside 3d:
Now if you have completed
the .ini file tutorial and it WORKS, we'll get started.
Add in the blue code and take out any pink code.
P_CLIENT.C modifications:
Inside ClientBeginDeathmatch after:
ClientEndServerFrame (ent);
put this:
![]()
if (ent == &g_edicts[1] && clanmatch->value)// first player to
connect, set prematch timers if in clanmatch
{
char *p;
int t;
// first we make sure that the .ini
file is open
if (ini_file.ini_file_read)
{
p =
Ini_GetValue(&ini_file, "Clanmatch", "PreDMTime");
// check that what was returned
wasn't NULL
if (p != NULL)
{
t = atoi(p);
}
else
gi.dprintf("Value of PreDMTime in MYMOD.INI = NULL\n"); // change
this
}
else
gi.error("Ini file not loaded, in Pre DM Time Setup");
if (t < 30) // you have to have
at LEAST a 30 second timer
predmtime =
level.time + 65; // set dm timer
else
predmtime =
level.time + t; // add it
timer = true;
}
![]()
This sets up the Pre DM
Timer if you are the first player to connect. Now in ClientThink after:
client = ent->client;
put this:
![]()
if (timer && clanmatch->value && ent == &g_edicts[1]) //
dm timer is on and we're the first client
{
int time_left = (predmtime -
level.time);
static int last_time_left;
if (time_left > 0) // timer is
clicking
{
if
(time_left == 300 && last_time_left != 300)
{
last_time_left = 300;
gi.bprintf(PRINT_HIGH, "Five Minutes until match.\n");
}
else if
(time_left == 120 && last_time_left != 120)
{
last_time_left = 120;
gi.bprintf(PRINT_HIGH, "Two Minutes until match.\n");
}
else if (time_left
== 60 && last_time_left != 60)
{
last_time_left = 60;
gi.bprintf(PRINT_HIGH, "One Minute until match.\n");
}
else if
(time_left == 30 && last_time_left != 30)
{
last_time_left = 30;
gi.bprintf(PRINT_HIGH, "Thirty seconds until match.\n");
}
else if
(time_left == 15 && last_time_left != 15)
{
last_time_left = 15;
gi.bprintf(PRINT_HIGH, "Fifteen seconds until match.\n");
}
else if
(time_left == 10 && last_time_left != 10)
{
last_time_left = 10;
gi.bprintf(PRINT_HIGH, "Ten seconds until match.\n");
}
else if
(time_left == 9 && last_time_left != 9)
{
last_time_left = 9;
gi.bprintf(PRINT_HIGH, "Nine seconds until match.\n");
}
else if
(time_left == 8 && last_time_left != 8)
{
last_time_left = 8;
gi.bprintf(PRINT_HIGH, "Eight seconds until match.\n");
}
else if
(time_left == 7 && last_time_left != 7)
{
last_time_left = 7;
gi.bprintf(PRINT_HIGH, "Seven seconds until match.\n");
}
else if
(time_left == 6 && last_time_left != 6)
{
last_time_left = 6;
gi.bprintf(PRINT_HIGH, "Six seconds until match.\n");
}
else if
(time_left == 5 && last_time_left != 5)
{
last_time_left = 5;
gi.bprintf(PRINT_HIGH, "Five seconds until match.\n");
}
else if
(time_left == 4 && last_time_left != 4)
{
last_time_left = 4;
gi.bprintf(PRINT_HIGH, "Four seconds until match.\n");
}
else if
(time_left == 3 && last_time_left != 3)
{
last_time_left = 3;
gi.bprintf(PRINT_HIGH, "Three seconds until match.\n");
}
else if
(time_left == 2 && last_time_left != 2 && last_time_left != 5)
{
last_time_left = 2;
gi.bprintf(PRINT_HIGH, "Two seconds until match.\n");
}
else if
(time_left == 1 && last_time_left != 1)
{
last_time_left = 1;
gi.bprintf(PRINT_HIGH, "One second until match.\n");
}
}
else // timer done
{
edict_t
*tokill;
int i;
level.framenum = 0;
centerprint_all("<<< LOCK AND LOAD!!! >>>\n");
for_each_player(tokill, i)
{
PutClientInServer (tokill);
// send effect
gi.WriteByte (svc_muzzleflash);
gi.WriteShort (tokill-g_edicts);
gi.WriteByte (MZ_LOGIN);
gi.multicast (tokill->s.origin, MULTICAST_PVS);
tokill->svflags &= ~SVF_NOCLIENT;
}
timer =
false;
}
}
![]()
Notice that
level.framenum is set to 0, thereby making the round last as long as the
timelimit. Before, it would be counting the time while waiting for the
match to start. Now it will be timed accordingly.
G_SAVE.C modifications:
Inside InitGame after it initializes the deathmatch cvar:
![]()
clanmatch = gi.cvar ("clanmatch", "0", CVAR_LATCH);
![]()
G_MAIN.C modifications:
At the top after it does the cvar_t for deathmatch:
![]()
cvar_t
*clanmatch;
![]()
And now inside
CheckDMRules after if says:
if (timelimit->value)
{
and INSIDE this if brace, put this:
![]()
if (clanmatch->value)
{
if
((level.time == ((timelimit->value - 2) * 60)) && last_time != 200)
{
last_time = 200;
gi.bprintf(PRINT_HIGH, "Two minutes left in match.\n");
}
else if
((level.time == ((timelimit->value - 1) * 60)) && last_time != 100)
{
last_time = 100;
gi.bprintf(PRINT_HIGH, "One minute left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 30)) && last_time != 30)
{
last_time = 30;
gi.bprintf(PRINT_HIGH, "30 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 10)) && last_time != 10)
{
last_time = 10;
gi.bprintf(PRINT_HIGH, "10 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 9)) && last_time != 9)
{
last_time = 9;
gi.bprintf(PRINT_HIGH, "9 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 8)) && last_time != 8)
{
last_time = 8;
gi.bprintf(PRINT_HIGH, "8 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 7)) && last_time != 7)
{
last_time = 7;
gi.bprintf(PRINT_HIGH, "7 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 6)) && last_time != 6)
{
last_time = 6;
gi.bprintf(PRINT_HIGH, "6 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 5)) && last_time != 5)
{
last_time = 5;
gi.bprintf(PRINT_HIGH, "5 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 4)) && last_time != 4)
{
last_time = 4;
gi.bprintf(PRINT_HIGH, "4 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 3)) && last_time != 3)
{
last_time = 3;
gi.bprintf(PRINT_HIGH, "3 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 2)) && last_time != 2)
{
last_time = 2;
gi.bprintf(PRINT_HIGH, "2 seconds left in match.\n");
}
else if
((level.time == ((timelimit->value * 60) - 1)) && last_time != 1)
{
last_time = 1;
gi.bprintf(PRINT_HIGH, "1 second left in match.\n");
}
}
if (level.time >=
timelimit->value*60)
{
if
(clanmatch->value)
gi.bprintf (PRINT_HIGH, "The match is over.\n");
else
gi.bprintf (PRINT_HIGH, "Timelimit hit.\n");
EndDMLevel
();
return;
}
if (level.time >= timelimit->value*60)
{
gi.bprintf
(PRINT_HIGH, "Timelimit hit.\n");
EndDMLevel
();
return;
}
![]()
G_COMBAT.C modifications:
Now at the top of T_Damage put this:
![]()
if (clanmatch->value && timer)
return;
![]()
This provides you can't
be damaged in the pre-dm mode.
P_HUD.C modifications:
Inside G_SetStats after:
ent->client->ps.stats[STAT_HEALTH] = ent->health;
put:
![]()
if (timer)
ent->client->ps.stats[STAT_PREDM]
= 1;
else
ent->client->ps.stats[STAT_PREDM] = 0;
![]()
This sets up the
PRE-DEATHMATCH MODE display.
G_LOCAL.H modifications:
Inside the extern cvar_t definitions after the one for deathmatch put:
![]()
extern
cvar_t *clanmatch;
![]()
And at the bottom of the
file put this:
![]()
qboolean
timer;
int predmtime;
int last_time;
void
centerprint_all (char *msg);
#define for_each_player(TOKILL,INDEX)\
for(INDEX=1;INDEX<=maxclients->value;INDEX++)\
if ((TOKILL=&g_edicts[i]) && TOKILL->inuse)
![]()
That sets up the variables.
Q_SHARED.H modifications:
Inside the STAT_x declarations put this (if 31 is not used, else make those
substitutions below):
![]()
#define
STAT_PREDM
31
![]()
G_SPAWN.C modifications:
Iniside the dm_statusbar macro, find this section of code:
// chase camera
"if 16 "
"xv 0 "
"yb -68 "
"string \"Chasing\" "
"xv 64 "
"stat_string 16 "
"endif "
;
and change it to this:
![]()
// chase camera
"if 16 "
"xv 0 "
"yb -68 "
"string \"Chasing\" "
"xv 64 "
"stat_string 16 "
"endif "
"if
31 " // if in predm timer
"xv 0 " // set the x
"yb -58 " // and y positions
"string2 \"PREDM COUNTDOWN MODE\" " // and print this in
green
"endif "
;
![]()
G_UTILS.C modifications:
Add this function to the
bottom of g_utils.c:
![]()
/*
===================
Centerprint_All
===================
*/
void
centerprint_all (char *msg)
{
int i;
edict_t *tokill;
for_each_player(tokill,i)
{
gi.centerprintf (tokill, msg);
}
}
![]()
That's it! MAKE SURE YOU
HAVE FOLLOWED THE INI FILE TUTORIAL ON INSIDE3D.COM AND HAVE YOUR INI FILE
SET UP, INITIALIZED, AND IN THE VARIABLE ini_file. IT __WILL NOT WORK__ IF YOU
HAVE NOT DONE THIS!
Aside from that, you have clanmatch mode now.
This mode is fully transparent, meaning let's say you have DM, Team DM, and CTF
(using my mod FireTeam
as an example). With the addition of clanmatch, with no extra coding, you can
have Clan DM, Clan Team DM,
and Clan CTF, just by adding +set clanmatch 1.
Hope you guys use this!
Tutorial by Psykotik