Added action commands, cvars

This commit is contained in:
Aaron Dean 2023-09-08 12:11:03 -04:00
parent 5f2599e9ba
commit b98d645717
4 changed files with 974 additions and 2 deletions

View file

@ -1926,6 +1926,628 @@ static void Cmd_ListMonsters_f(edict_t *ent)
}
}
/*
=================
Action Commands
=================
*/
static void Cmd_Streak_f (edict_t * ent) {
gi.LocClient_Print(ent, PRINT_HIGH, "Your Killing Streak is: %d\n", ent->client->resp.streakKills);
}
void Cmd_Choose_f(edict_t * ent)
{
const char *s;
const char *wpnText, *itmText;
int itemNum = 0;
gitem_t *item;
// only works in teamplay
if (!(gameSettings & GS_WEAPONCHOOSE))
return;
// s = gi.args();
// if (*s) {
// itemNum = GetItemNumFromArg(s);
// if (!itemNum)
// itemNum = GetWeaponNumFromArg(s);
// }
// switch(itemNum) {
// case DUAL_NUM:
// case M3_NUM:
// case HC_NUM:
// case MP5_NUM:
// case SNIPER_NUM:
// case KNIFE_NUM:
// case M4_NUM:
// // Weapon bans maybe later
// // if (!WPF_ALLOWED(itemNum)) {
// // gi.LocClient_Print(ent, PRINT_HIGH, "Weapon disabled on this server.\n");
// // return;
// // }
// // ent->client->pers.chosenWeapon = GET_ITEM(itemNum);
// // break;
// case LASER_NUM:
// case KEV_NUM:
// case SLIP_NUM:
// case SIL_NUM:
// case HELM_NUM:
// case BAND_NUM:
// // Item bans maybe later
// // if (!ITF_ALLOWED(itemNum)) {
// // gi.LocClient_Print(ent, PRINT_HIGH, "Item disabled on this server.\n");
// // return;
// // }
// // ent->client->pers.chosenItem = GET_ITEM(itemNum);
// // break;
// default:
// gi.LocClient_Print(ent, PRINT_HIGH, "Invalid weapon or item choice.\n");
// return;
// }
item = ent->client->pers.chosenWeapon;
//item = ent->client->pers.weapon;
wpnText = (item && item->pickup_name) ? item->pickup_name : "NONE";
item = ent->client->pers.chosenItem;
itmText = (item && item->pickup_name) ? item->pickup_name : "NONE";
}
// AQ:TNG - JBravo adding tkok
void Cmd_TKOk(edict_t * ent)
{
if (!ent->enemy || !ent->enemy->inuse || !ent->enemy->client || (ent == ent->enemy)) {
gi.LocClient_Print(ent, PRINT_HIGH, "Nothing to forgive\n");
} else if (ent->client->resp.team == ent->enemy->client->resp.team) {
if (ent->enemy->client->resp.team_kills) {
gi.LocClient_Print(ent, PRINT_HIGH, "You forgave %s\n", ent->enemy->client->pers.netname);
gi.LocClient_Print(ent->enemy, PRINT_HIGH, "%s forgave you\n", ent->client->pers.netname);
ent->enemy->client->resp.team_kills--;
if (ent->enemy->client->resp.team_wounds)
ent->enemy->client->resp.team_wounds /= 2;
}
} else {
gi.LocClient_Print(ent, PRINT_HIGH, "That's very noble of you...\n");
gi.LocBroadcast_Print(PRINT_HIGH, "%s turned the other cheek\n", ent->client->pers.netname);
}
ent->enemy = NULL;
return;
}
void Cmd_FF_f( edict_t *ent )
{
if( teamplay->value )
gi.LocClient_Print(ent, PRINT_MEDIUM, "Friendly Fire {}\n", g_friendly_fire->integer ? "OFF" : "ON");
else
gi.LocClient_Print( ent, PRINT_MEDIUM, "FF only applies to teamplay.\n" );
}
void Cmd_Time(edict_t * ent)
{
int mins = 0, secs = 0, remaining = 0, rmins = 0, rsecs = 0, gametime = 0;
gametime = level.matchTime;
mins = gametime / 60;
secs = gametime % 60;
remaining = (timelimit->value * 60) - gametime;
if( remaining >= 0 )
{
rmins = remaining / 60;
rsecs = remaining % 60;
}
if( timelimit->value )
gi.LocClient_Print( ent, PRINT_HIGH, "Elapsed time: %d:%02d. Remaining time: %d:%02d\n", mins, secs, rmins, rsecs );
else
gi.LocClient_Print( ent, PRINT_HIGH, "Elapsed time: %d:%02d\n", mins, secs );
}
void Cmd_Roundtimeleft_f(edict_t * ent)
{
int remaining;
if(!teamplay->value) {
gi.LocClient_Print(ent, PRINT_HIGH, "This command need teamplay to be enabled\n");
return;
}
if (!(gameSettings & GS_ROUNDBASED) || !team_round_going)
return;
if ((int)roundtimelimit->value <= 0)
return;
remaining = (roundtimelimit->value * 60) - (current_round_length/10);
gi.LocClient_Print(ent, PRINT_HIGH, "There is %d:%02i left in this round\n", remaining / 60, remaining % 60);
}
void Cmd_Voice_f (edict_t * self)
{
const char *s;
char fullpath[MAX_QPATH];
if (!use_voice->integer)
return;
s = gi.args ();
//check if no sound is given
if (!*s)
{
gi.LocClient_Print (self, PRINT_MEDIUM,
"\nCommand needs argument, use voice <soundfile.wav>.\n");
return;
}
if (strlen (s) > 32)
{
gi.LocClient_Print (self, PRINT_MEDIUM,
"\nArgument is too long. Maximum length is 32 characters.\n");
return;
}
// AQ2:TNG Disabled this message: why? -M
if (strstr (s, ".."))
{
gi.LocClient_Print (self, PRINT_MEDIUM,
"\nArgument must not contain \"..\".\n");
return;
}
//check if player is dead
if (!IS_ALIVE(self))
return;
strcpy(fullpath, PG_SNDPATH);
strcat(fullpath, s);
// SLIC2 Taking this out.
/*if (radio_repeat->value)
{
if ((d = CheckForRepeat (self, s)) == false)
return;
}*/
if (radio_max->value)
{
if (CheckForFlood (self)== false)
return;
}
// AQ2:TNG Deathwatch - This should be IDLE not NORM
gi.sound (self, CHAN_VOICE, gi.soundindex (fullpath), 1, ATTN_IDLE, 0);
// AQ2:TNG END
}
void Cmd_WhereAmI_f( edict_t * self )
{
char location[ 128 ] = "";
bool found = GetPlayerLocation( self, location );
if( found )
gi.LocClient_Print( self, PRINT_MEDIUM, "Location: %s\n", location );
else if( ! sv_cheats->value )
gi.LocClient_Print( self, PRINT_MEDIUM, "Location unknown.\n" );
if( sv_cheats->value )
{
gi.LocClient_Print( self, PRINT_MEDIUM, "Origin: %5.0f,%5.0f,%5.0f Facing: %3.0f\n",
self->s.origin[0], self->s.origin[1], self->s.origin[2], self->s.angles[1] );
}
}
// Timing here may be broken, test!
void Cmd_Punch_f (edict_t * self)
{
if (!use_punch->value || !IS_ALIVE(self) || self->client->resp.sniper_mode != SNIPER_1X)
return;
if (self->client->weaponstate != WEAPON_READY && self->client->weaponstate != WEAPON_END_MAG)
return;
float punch_delay = 0.5;
if ((level.time.milliseconds() + punch_delay) > self->client->punch_framenum) {
self->client->punch_framenum = level.time.milliseconds(); // Update the punch_framenum to the current time
self->client->punch_desired = true;
}
}
// void _Cmd_Rules_f (edict_t * self, const char *argument)
// {
// char section[32], mbuf[1024], *p, buf[30][INI_STR_LEN];
// int i, j = 0;
// ini_t ini;
// strcpy (mbuf, "\n");
// if (*argument)
// Q_strncpyz(section, argument, sizeof(section));
// else
// strcpy (section, "main");
// if (OpenIniFile (GAMEVERSION "/prules.ini", &ini))
// {
// i = ReadIniSection (&ini, section, buf, 30);
// while (j < i)
// {
// p = buf[j++];
// if (*p == '.')
// p++;
// Q_strncatz(mbuf, p, sizeof(mbuf));
// Q_strncatz(mbuf, "\n", sizeof(mbuf));
// }
// CloseIniFile (&ini);
// }
// if (!j)
// gi.LocClient_Print (self, PRINT_MEDIUM, "No rules on %s available\n", section);
// else
// gi.LocClient_Print (self, PRINT_MEDIUM, "%s", mbuf);
// }
// void Cmd_Rules_f (edict_t * self)
// {
// const char *s;
// s = gi.args ();
// _Cmd_Rules_f (self, s);
// }
static void Cmd_Ent_Count_f (edict_t * ent)
{
int x = 0;
edict_t *e;
for (e = g_edicts; e < &g_edicts[globals.num_edicts]; e++)
{
if (e->inuse)
x++;
}
gi.LocClient_Print(ent, PRINT_HIGH, "%d entities counted\n", x);
}
void _SetSniper(edict_t * ent, int zoom)
{
int desired_fov, sniper_mode, oldmode;
switch (zoom) {
default:
case 1:
desired_fov = SNIPER_FOV1;
sniper_mode = SNIPER_1X;
break;
case 2:
desired_fov = SNIPER_FOV2;
sniper_mode = SNIPER_2X;
break;
case 4:
desired_fov = SNIPER_FOV4;
sniper_mode = SNIPER_4X;
break;
case 6:
desired_fov = SNIPER_FOV6;
sniper_mode = SNIPER_6X;
break;
}
oldmode = ent->client->resp.sniper_mode;
if (sniper_mode == oldmode)
return;
//Moved here, no need to make sound if zoom isnt changed -M
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/lensflik.wav"), 1, ATTN_NORM, 0);
ent->client->resp.sniper_mode = sniper_mode;
ent->client->desired_fov = desired_fov;
if (sniper_mode == SNIPER_1X && ent->client->pers.weapon)
ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model);
//show the model if switching to 1x
if (oldmode == SNIPER_1X && ent->client->weaponstate != WEAPON_RELOADING) {
//do idleness stuff when switching from 1x, see function below
ent->client->weaponstate = WEAPON_BUSY;
// if(zoom_comp->value) {
// ent->client->idle_weapon = calc_zoom_comp(ent);
// } else {
// ent->client->idle_weapon = 6;
// }
ent->client->ps.gunframe = 22;
}
}
//tempfile END
void Cmd_New_Weapon_f(edict_t * ent)
{
ent->client->weapon_attempts++;
if (ent->client->weapon_attempts == 1)
Cmd_Weapon_f(ent);
}
int _SniperMode(edict_t *ent)
{
switch (ent->client->desired_zoom) { //lets update old desired zoom
case 1:
return SNIPER_1X;
case 2:
return SNIPER_2X;
case 4:
return SNIPER_4X;
case 6:
return SNIPER_6X;
}
return ent->client->resp.sniper_mode;
}
void _ZoomIn(edict_t * ent, bool overflow)
{
switch (_SniperMode(ent)) {
case SNIPER_1X:
ent->client->desired_zoom = 2;
break;
case SNIPER_2X:
ent->client->desired_zoom = 4;
break;
case SNIPER_4X:
ent->client->desired_zoom = 6;
break;
case SNIPER_6X:
if (overflow)
ent->client->desired_zoom = 1;
break;
}
}
void _ZoomOut(edict_t * ent, bool overflow)
{
switch (_SniperMode(ent)) {
case SNIPER_1X:
if (overflow)
ent->client->desired_zoom = 6;
break;
case SNIPER_2X:
ent->client->desired_zoom = 1;
break;
case SNIPER_4X:
ent->client->desired_zoom = 2;
break;
case SNIPER_6X:
ent->client->desired_zoom = 4;
break;
}
}
// void Cmd_NextMap_f(edict_t * ent)
// {
// int map_num = -1;
// const char *next_map = level.nextmap;
// const char *rot_type = "in rotation";
// votelist_t *voted = NULL;
// if( next_map[0] )
// rot_type = "selected";
// else if( vrot->value && ((voted = MapWithMostAllVotes())) )
// {
// next_map = voted->mapname;
// rot_type = "by votes";
// }
// if( next_map[0] )
// {
// int i;
// for( i = 0; i < num_maps; i ++ )
// {
// if( Q_stricmp( map_rotation[i], next_map ) == 0 )
// {
// map_num = i;
// break;
// }
// }
// }
// else if( num_maps )
// {
// map_num = (cur_map + (rrot->value ? rand_map : 1)) % num_maps;
// next_map = map_rotation[ map_num ];
// rot_type = rrot->value ? "randomly" : "in rotation";
// }
// if( DMFLAGS(DF_SAME_LEVEL) )
// {
// map_num = cur_map;
// next_map = level.mapname;
// rot_type = "repeated";
// }
// gi.LocClient_Print( ent, PRINT_HIGH, "Next map %s is %s (%i/%i).\n", rot_type, next_map, map_num+1, num_maps );
// }
void Cmd_Weapon_f(edict_t * ent)
{
int dead;
if (!ent->client->pers.weapon)
return;
dead = !IS_ALIVE(ent);
ent->client->weapon_attempts--;
if (ent->client->weapon_attempts < 0)
ent->client->weapon_attempts = 0;
if (ent->client->bandaging || ent->client->bandage_stopped) {
if (!ent->client->weapon_after_bandage_warned) {
ent->client->weapon_after_bandage_warned = true;
gi.LocClient_Print(ent, PRINT_HIGH, "You'll get to your weapon when you're done bandaging!\n");
}
ent->client->weapon_attempts++;
return;
}
ent->client->weapon_after_bandage_warned = false;
if (ent->client->weaponstate == WEAPON_FIRING || ent->client->weaponstate == WEAPON_BUSY)
{
//gi.LocClient_Print(ent, PRINT_HIGH, "Try again when you aren't using your weapon.\n");
ent->client->weapon_attempts++;
return;
}
switch(ent->client->pers.weapon->id) {
case IT_WEAPON_MK23:
if (!dead)
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/click.wav"), 1, ATTN_NORM, 0);
ent->client->pers.mk23_mode = !(ent->client->pers.mk23_mode);
if (ent->client->pers.mk23_mode)
gi.LocClient_Print(ent, PRINT_HIGH, "MK23 Pistol set for semi-automatic action\n");
else
gi.LocClient_Print(ent, PRINT_HIGH, "MK23 Pistol set for automatic action\n");
break;
case IT_WEAPON_MP5:
if (!dead)
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/click.wav"), 1, ATTN_NORM, 0);
ent->client->pers.mp5_mode = !(ent->client->pers.mp5_mode);
if (ent->client->pers.mp5_mode)
gi.LocClient_Print(ent, PRINT_HIGH, "MP5 set to 3 Round Burst mode\n");
else
gi.LocClient_Print(ent, PRINT_HIGH, "MP5 set to Full Automatic mode\n");
break;
case IT_WEAPON_M4:
if (!dead)
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/click.wav"), 1, ATTN_NORM, 0);
ent->client->pers.m4_mode = !(ent->client->pers.m4_mode);
if (ent->client->pers.m4_mode)
gi.LocClient_Print(ent, PRINT_HIGH, "M4 set to 3 Round Burst mode\n");
else
gi.LocClient_Print(ent, PRINT_HIGH, "M4 set to Full Automatic mode\n");
break;
case IT_WEAPON_SNIPER:
if (dead)
return;
if (!ent->client->desired_zoom)
_ZoomIn(ent, true); // standard behaviour
_SetSniper(ent, ent->client->desired_zoom);
ent->client->desired_zoom = 0;
break;
case IT_WEAPON_HANDCANNON:
// AQ2:TNG Deathwatch - Single Barreled HC
if(!hc_single->value)
return;
if (!dead)
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/click.wav"), 1, ATTN_NORM, 0);
ent->client->pers.hc_mode = !(ent->client->pers.hc_mode);
if (ent->client->pers.hc_mode)
gi.LocClient_Print(ent, PRINT_HIGH, "Single Barreled Handcannon\n");
else
gi.LocClient_Print(ent, PRINT_HIGH, "Double Barreled Handcannon\n");
// AQ2:TNG End
break;
case IT_WEAPON_KNIFE:
if (dead)
return;
if (ent->client->weaponstate == WEAPON_READY) {
ent->client->pers.knife_mode = !(ent->client->pers.knife_mode);
ent->client->weaponstate = WEAPON_ACTIVATING;
if (ent->client->pers.knife_mode) {
gi.LocClient_Print(ent, PRINT_HIGH, "Switching to throwing\n");
ent->client->ps.gunframe = 0;
} else {
gi.LocClient_Print(ent, PRINT_HIGH, "Switching to slashing\n");
ent->client->ps.gunframe = 106;
}
}
break;
case IT_WEAPON_GRENADES:
if (ent->client->pers.grenade_mode == 0) {
gi.LocClient_Print(ent, PRINT_HIGH, "Prepared to make a medium range throw\n");
ent->client->pers.grenade_mode = 1;
} else if (ent->client->pers.grenade_mode == 1) {
gi.LocClient_Print(ent, PRINT_HIGH, "Prepared to make a long range throw\n");
ent->client->pers.grenade_mode = 2;
} else {
gi.LocClient_Print(ent, PRINT_HIGH, "Prepared to make a short range throw\n");
ent->client->pers.grenade_mode = 0;
}
break;
}
}
void Cmd_IR_f(edict_t * ent)
{
int band = 0;
if (!ir->value) {
gi.LocClient_Print(ent, PRINT_HIGH, "IR vision not enabled on this server.\n");
return;
}
if (INV_AMMO(ent, BAND_NUM))
band = 1;
ent->client->pers.irvision = !ent->client->pers.irvision;
if (ent->client->pers.irvision == 0)
{
if (band)
gi.LocClient_Print(ent, PRINT_HIGH, "IR vision disabled.\n");
else
gi.LocClient_Print(ent, PRINT_HIGH, "IR vision will be disabled when you get a bandolier.\n");
}
else
{
if (band)
gi.LocClient_Print(ent, PRINT_HIGH, "IR vision enabled.\n");
else
gi.LocClient_Print(ent, PRINT_HIGH, "IR vision will be enabled when you get a bandolier.\n");
}
}
// sets variable to toggle nearby door status
void Cmd_OpenDoor_f(edict_t * ent)
{
ent->client->doortoggle = 1;
return;
}
void Cmd_Lens_f(edict_t * ent)
{
int nArg;
char args[8];
if (!ent->client->pers.weapon != IT_WEAPON_SNIPER)
return;
nArg = atoi(gi.args());
if (nArg == 0) {
Q_strlcpy(args, gi.args(), sizeof(args));
//perhaps in or out? let's see.
if (Q_strcasecmp(args, "in") == 0)
_ZoomIn(ent, false);
else if (Q_strcasecmp(args, "out") == 0)
_ZoomOut(ent, false);
else
_ZoomIn(ent, true);
if(!ent->client->desired_zoom)
return;
}
else if ((nArg == 1) || (!(nArg % 2) && (nArg <= 6)))
ent->client->desired_zoom = nArg;
else
_ZoomIn(ent, true);
if(ent->client->weapon_attempts > 0)
return; //Already waiting to change the zoom, otherwise it
//first change to desired zoom and then usual zoomin -M
ent->client->weapon_attempts++;
if (ent->client->weapon_attempts == 1)
Cmd_Weapon_f(ent);
}
/*
=================
ClientCommand
@ -2079,6 +2701,135 @@ void ClientCommand(edict_t *ent)
// ZOID
else if (Q_strcasecmp(cmd, "switchteam") == 0)
Cmd_Switchteam_f(ent);
// Action add
else if (Q_strcasecmp(cmd, "streak") == 0)
Cmd_Streak_f(ent);
else if (Q_strcasecmp(cmd, "reload") == 0)
Cmd_New_Reload_f(ent);
else if (Q_strcasecmp(cmd, "weapon") == 0)
Cmd_New_Weapon_f(ent);
else if (Q_strcasecmp(cmd, "opendoor") == 0)
Cmd_OpenDoor_f(ent);
else if (Q_strcasecmp(cmd, "bandage") == 0)
Cmd_Bandage_f(ent);
else if (Q_strcasecmp(cmd, "irvision") == 0)
Cmd_IR_f(ent);
else if (Q_strcasecmp(cmd, "radio") == 0)
Cmd_Radio_f(ent);
else if (Q_strcasecmp(cmd, "radiogender") == 0)
Cmd_Radiogender_f(ent);
else if (Q_strcasecmp(cmd, "radio_power") == 0)
Cmd_Radio_power_f(ent);
else if (Q_strcasecmp(cmd, "radio_team") == 0)
Cmd_Radioteam_f(ent);
else if (Q_strcasecmp(cmd, "channel") == 0)
Cmd_Channel_f(ent);
else if (Q_strcasecmp(cmd, "motd") == 0)
PrintMOTD(ent);
else if (Q_strcasecmp(cmd, "deny") == 0)
Cmd_Deny_f(ent);
else if (Q_strcasecmp(cmd, "choose") == 0)
Cmd_Choose_f(ent);
else if (Q_strcasecmp(cmd, "tkok") == 0)
Cmd_TKOk(ent);
else if (Q_strcasecmp(cmd, "forgive") == 0)
Cmd_TKOk(ent);
else if (Q_strcasecmp(cmd, "ff") == 0)
Cmd_FF_f(ent);
else if (Q_strcasecmp(cmd, "time") == 0)
Cmd_Time(ent);
else if (Q_strcasecmp(cmd, "voice") == 0)
Cmd_Voice_f(ent);
else if (Q_strcasecmp(cmd, "whereami") == 0)
Cmd_WhereAmI_f(ent);
else if (Q_strcasecmp(cmd, "setflag1") == 0)
Cmd_SetFlag1_f(ent);
else if (Q_strcasecmp(cmd, "setflag2") == 0)
Cmd_SetFlag2_f(ent);
else if (Q_strcasecmp(cmd, "saveflags") == 0)
Cmd_SaveFlags_f(ent);
else if (Q_strcasecmp(cmd, "punch") == 0)
Cmd_Punch_f(ent);
// else if (Q_strcasecmp(cmd, "rules") == 0)
// Cmd_Rules_f(ent);
else if (Q_strcasecmp(cmd, "lens") == 0)
Cmd_Lens_f(ent);
// else if (Q_strcasecmp(cmd, "nextmap") == 0)
// Cmd_NextMap_f(ent);
// Matchmode stuff
// else if (Q_strcasecmp(cmd, "sub") == 0)
// Cmd_Sub_f(ent);
// else if (Q_strcasecmp(cmd, "captain") == 0)
// Cmd_Captain_f(ent);
// else if (Q_strcasecmp(cmd, "ready") == 0)
// Cmd_Ready_f(ent);
// else if (Q_strcasecmp(cmd, "teamname") == 0)
// Cmd_Teamname_f(ent);
// else if (Q_strcasecmp(cmd, "teamskin") == 0)
// Cmd_Teamskin_f(ent);
// else if (Q_strcasecmp(cmd, "lock") == 0)
// Cmd_LockTeam_f(ent);
// else if (Q_strcasecmp(cmd, "unlock") == 0)
// Cmd_UnlockTeam_f(ent);
else if (Q_strcasecmp(cmd, "entcount") == 0)
Cmd_Ent_Count_f(ent);
// else if (Q_strcasecmp(cmd, "stats") == 0)
// Cmd_PrintStats_f(ent);
// else if (Q_strcasecmp(cmd, "flashlight") == 0)
// Use_Flashlight(ent);
// else if (Q_strcasecmp(cmd, "matchadmin") == 0)
// Cmd_SetAdmin_f(ent);
else if (Q_strcasecmp(cmd, "roundtimeleft") == 0)
Cmd_Roundtimeleft_f(ent);
// else if (Q_strcasecmp(cmd, "autorecord") == 0)
// Cmd_AutoRecord_f(ent);
// else if (Q_strcasecmp(cmd, "stat_mode") == 0)
// Cmd_Statmode_f(ent);
// else if (Q_strcasecmp(cmd, "cmd_stat_mode") == 0)
// Cmd_Statmode_f(ent);
// else if (Q_strcasecmp(cmd, "ghost") == 0)
// Cmd_Ghost_f(ent);
// else if (Q_strcasecmp(cmd, "resetscores") == 0)
// Cmd_ResetScores_f(ent);
// else if (Q_strcasecmp(cmd, "gamesettings") == 0)
// Cmd_PrintSettings_f(ent);
// else if (Q_strcasecmp(cmd, "follow") == 0)
// Cmd_Follow_f(ent);
//vote stuff
// else if (Q_strcasecmp(cmd, "menu") == 0)
// Cmd_Menu_f(ent);
// else if (Q_strcasecmp(cmd, "votemap") == 0)
// Cmd_Votemap_f(ent);
// else if (Q_strcasecmp(cmd, "maplist") == 0)
// Cmd_Maplist_f(ent);
// else if (Q_strcasecmp(cmd, "votekick") == 0)
// Cmd_Votekick_f(ent);
// else if (Q_strcasecmp(cmd, "votekicknum") == 0)
// Cmd_Votekicknum_f(ent);
// else if (Q_strcasecmp(cmd, "kicklist") == 0)
// Cmd_Kicklist_f(ent);
// else if (Q_strcasecmp(cmd, "ignore") == 0)
// Cmd_Ignore_f(ent);
// else if (Q_strcasecmp(cmd, "ignorenum") == 0)
// Cmd_Ignorenum_f(ent);
// else if (Q_strcasecmp(cmd, "ignorelist") == 0)
// Cmd_Ignorelist_f(ent);
// else if (Q_strcasecmp(cmd, "ignoreclear") == 0)
// Cmd_Ignoreclear_f(ent);
// else if (Q_strcasecmp(cmd, "ignorepart") == 0)
// Cmd_IgnorePart_f(ent);
// else if (Q_strcasecmp(cmd, "voteconfig") == 0)
// Cmd_Voteconfig_f(ent);
// else if (Q_strcasecmp(cmd, "configlist") == 0)
// Cmd_Configlist_f(ent);
// else if (Q_strcasecmp(cmd, "votescramble") == 0)
// Cmd_Votescramble_f(ent);
// Espionage, aliased command so it's easy to remember
// else if (Q_strcasecmp(cmd, "volunteer") == 0)
// Cmd_Volunteer_f(ent);
// else if (Q_strcasecmp(cmd, "leader") == 0)
// Cmd_Volunteer_f(ent);
// End Action add
#ifndef KEX_Q2_GAME
else // anything that doesn't match a command will be a chat
Cmd_Say_f(ent, true);

View file

@ -747,6 +747,25 @@ enum award_t {
EXCELLENT
};
enum action_gamemodes_t
{
GM_TEAMPLAY,
GM_TEAMDM,
GM_CTF,
GM_TOURNEY,
GM_DEATHMATCH,
GM_DOMINATION,
GM_ESPIONAGE
};
enum action_gamemodeflags_t
{
GMF_NONE,
GMF_3TEAMS,
GMF_DARKMATCH,
GMF_MATCHMODE
};
enum gender_t {
GENDER_MALE,
GENDER_FEMALE,
@ -1789,6 +1808,7 @@ extern cvar_t *warmup;
extern cvar_t *rrot;
extern cvar_t *vrot;
extern cvar_t *e_enhancedSlippers;
extern cvar_t *use_voice;
//extern mod_id_t meansOfDeath;
// zucc for hitlocation of death
@ -2091,6 +2111,8 @@ extern gitem_t itemlist[IT_TOTAL];
#define CROUCHING_VIEWHEIGHT 8
#define STANDING_VIEWHEIGHT 22
#define PG_SNDPATH "user/"
extern int gameSettings; // Round based, deathmatch, etc?
extern cvar_t *allitem;

View file

@ -301,7 +301,7 @@ void ActionInit()
rrot = gi.cvar("rrot", "0", CVAR_NOFLAGS);
vrot = gi.cvar("vrot", "0", CVAR_NOFLAGS);
e_enhancedSlippers = gi.cvar("e_enhancedSlippers", "0", CVAR_SERVERINFO);
use_voice = gi.cvar("use_voice", "0", CVAR_NOFLAGS);
}
/*

View file

@ -1412,6 +1412,204 @@ static void G_InitStatusbar()
}
static void PrecacheUserSounds(void)
{
int count = 0;
size_t length;
//FILE *soundlist;
char buf[1024], fullpath[MAX_QPATH];
std::string filename = fmt::format("{}/sndlist.ini", GAMEVERSION);
FILE* soundlist = fopen(filename.c_str(), "r");
//soundlist = fopen(GAMEVERSION "/sndlist.ini", "r");
if (!soundlist) { // no "sndlist.ini" file...
gi.Com_PrintFmt("Cannot load %s, sound download is disabled.\n", GAMEVERSION "/sndlist.ini");
return;
}
// read the sndlist.ini file
while (fgets(buf, sizeof(buf), soundlist) != NULL)
{
length = strlen(buf);
//first remove trailing spaces
while (length > 0 && buf[length - 1] <= ' ')
buf[--length] = '\0';
//Comments are marked with # or // at line start
if (length < 5 || buf[0] == '#' || !strncmp(buf, "//", 2))
continue;
Q_strlcpy(fullpath, PG_SNDPATH, sizeof(fullpath));
Q_strlcat(fullpath, buf, sizeof(fullpath));
gi.soundindex(fullpath);
//gi.dprintf("Sound %s: precache %i",fullpath, gi.soundindex(fullpath));
count++;
if (count == 100)
break;
}
fclose(soundlist);
if (!count)
gi.Com_PrintFmt("%s is empty, no sounds to precache.\n", GAMEVERSION "/sndlist.ini");
else
gi.Com_PrintFmt("%i user sounds precached.\n", count);
}
void G_LoadLocations( void )
{
//AQ2:TNG New Location Code
char locfile[MAX_QPATH], buffer[256];
FILE *f;
int i, x, y, z, rx, ry, rz;
char *locationstr, *param, *line;
cvar_t *game_cvar;
placedata_t *loc;
memset( ml_creator, 0, sizeof( ml_creator ) );
ml_count = 0;
game_cvar = gi.cvar ("game", "action", 0);
if (!*game_cvar->string)
snprintf(locfile, sizeof(locfile), "%s/tng/%s.aqg", GAMEVERSION, level.mapname);
else
snprintf(locfile, sizeof(locfile), "%s/tng/%s.aqg", game_cvar->string, level.mapname);
f = fopen( locfile, "r" );
if (!f) {
gi.Com_PrintFmt( "No location file for %s\n", level.mapname );
return;
}
gi.Com_PrintFmt( "Location file: %s\n", level.mapname );
do
{
line = fgets( buffer, sizeof( buffer ), f );
if (!line) {
break;
}
if (strlen( line ) < 12)
continue;
if (line[0] == '#')
{
param = line + 1;
while (*param == ' ') { param++; }
if (*param && (strncasecmp(param, "creator", 7) == 0))
{
param += 8;
while (*param == ' ') { param++; }
for (i = 0; *param >= ' ' && i < sizeof( ml_creator ) - 1; i++) {
ml_creator[i] = *param++;
}
ml_creator[i] = 0;
while (i > 0 && ml_creator[i - 1] == ' ') //Remove railing spaces
ml_creator[--i] = 0;
}
continue;
}
param = strtok( line, " :\r\n\0" );
// TODO: better support for file comments
if (!param || param[0] == '#')
continue;
x = atoi( param );
param = strtok( NULL, " :\r\n\0" );
if (!param)
continue;
y = atoi( param );
param = strtok( NULL, " :\r\n\0" );
if (!param)
continue;
z = atoi( param );
param = strtok( NULL, " :\r\n\0" );
if (!param)
continue;
rx = atoi( param );
param = strtok( NULL, " :\r\n\0" );
if (!param)
continue;
ry = atoi( param );
param = strtok( NULL, " :\r\n\0" );
if (!param)
continue;
rz = atoi( param );
param = strtok( NULL, "\r\n\0" );
if (!param)
continue;
locationstr = param;
loc = &locationbase[ml_count++];
loc->x = x;
loc->y = y;
loc->z = z;
loc->rx = rx;
loc->ry = ry;
loc->rz = rz;
Q_strlcpy( loc->desc, locationstr, sizeof( loc->desc ) );
if (ml_count >= MAX_LOCATIONS_IN_BASE) {
gi.Com_PrintFmt( "Cannot read more than %d locations.\n", MAX_LOCATIONS_IN_BASE );
break;
}
} while (1);
fclose( f );
gi.Com_PrintFmt( "Found %d locations.\n", ml_count );
}
int Gamemode(void) // These are distinct game modes; you cannot have a teamdm tourney mode, for example
{
int gamemode = 0;
if (teamdm->value) {
gamemode = GM_TEAMDM;
} else if (ctf->value) {
gamemode = GM_CTF;
// } else if (use_tourney->value) {
// gamemode = GM_TOURNEY;
} else if (teamplay->value) {
gamemode = GM_TEAMPLAY;
// } else if (dom->value) {
// gamemode = GM_DOMINATION;
// } else if (esp->value) {
// gamemode = GM_ESPIONAGE;
} else if (deathmatch->value) {
gamemode = GM_DEATHMATCH;
}
return gamemode;
}
int Gamemodeflag(void)
// These are gamemode flags that change the rules of gamemodes.
// For example, you can have a darkmatch matchmode 3team teamplay server
{
int gamemodeflag = 0;
char gmfstr[16];
// if (use_3teams->value) {
// gamemodeflag += GMF_3TEAMS;
// }
// if (darkmatch->value) {
// gamemodeflag += GMF_DARKMATCH;
// }
if (matchmode->value) {
gamemodeflag += GMF_MATCHMODE;
}
sprintf(gmfstr, "%d", gamemodeflag);
gi.cvar_forceset("gmf", gmfstr);
return gamemodeflag;
}
/*QUAKED worldspawn (0 0 0) ?
Only used for the world.
@ -1572,7 +1770,8 @@ void SP_worldspawn(edict_t *ent)
level.snd_teamwins[3] = gi.soundindex("tng/team3_wins.wav");
PrecacheItem(GetItemByIndex(IT_WEAPON_MK23));
PrecacheRadioSounds();
PrecacheUserSounds();
if (g_dm_random_items->integer)
for (item_id_t i = static_cast<item_id_t>(IT_NULL + 1); i < IT_TOTAL; i = static_cast<item_id_t>(i + 1))