summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <trem.redman@gmail.com>2013-09-12 18:28:16 +0200
committerPaweł Redman <trem.redman@gmail.com>2013-09-12 18:28:16 +0200
commit85d99859798982dd88c7de8d8b7a71d4ac4b4a2b (patch)
treebb44591d336ee20d4944f59db8ea0fdb98aeb237
parent37b8af1e6eb90378f1290b5130c8b6882b06a219 (diff)
0.1.4
-rw-r--r--assets/credits.txt11
-rw-r--r--assets/sound/feedback/1minremains.wavbin0 -> 119268 bytes
-rw-r--r--assets/sound/feedback/5minremain.wavbin0 -> 118884 bytes
-rw-r--r--assets/sound/feedback/aliensadmit.wavbin0 -> 147930 bytes
-rw-r--r--assets/sound/feedback/alienslocked.wavbin0 -> 116276 bytes
-rw-r--r--assets/sound/feedback/aliensunlocked.wavbin0 -> 143696 bytes
-rw-r--r--assets/sound/feedback/alienswin.wavbin0 -> 132486 bytes
-rw-r--r--assets/sound/feedback/humansadmit.wavbin0 -> 139476 bytes
-rw-r--r--assets/sound/feedback/humanslocked.wavbin0 -> 121954 bytes
-rw-r--r--assets/sound/feedback/humansunlocked.wavbin0 -> 141744 bytes
-rw-r--r--assets/sound/feedback/humanswin.wavbin0 -> 132486 bytes
-rw-r--r--assets/sound/feedback/sdimminent.wavbin0 -> 135560 bytes
-rw-r--r--assets/sound/feedback/stalemate.wavbin0 -> 88386 bytes
-rw-r--r--assets/sound/feedback/suddendeath.wavbin0 -> 97206 bytes
-rw-r--r--src/cgame/cg_event.c18
-rw-r--r--src/cgame/cg_local.h17
-rw-r--r--src/cgame/cg_main.c3
-rw-r--r--src/cgame/cg_servercmds.c57
-rw-r--r--src/cgame/cg_view.c3
-rw-r--r--src/game/bg_misc.c5
-rw-r--r--src/game/g_admin.c263
-rw-r--r--src/game/g_admin.h9
-rw-r--r--src/game/g_cmds.c13
-rw-r--r--src/game/g_combat.c11
-rw-r--r--src/game/g_local.h1
-rw-r--r--src/game/g_main.c15
-rw-r--r--src/game/g_svcmds.c3
27 files changed, 377 insertions, 52 deletions
diff --git a/assets/credits.txt b/assets/credits.txt
index 2e6cd27..e4a63c5 100644
--- a/assets/credits.txt
+++ b/assets/credits.txt
@@ -6,6 +6,13 @@ Cuboid - a Tremulous 1.2 mod focused on cuboids and fixing balance issues.
Version Release date
______________________________________________________________________________________________
+0.1.4 Sep 12 2013
+NON-GAMEPLAY:
+- Announcer now announces things like "Aliens win" or "1 minute remaining", not just votes.
+- /register was implemented
+- Admin titles were implemented (/settitle, /listplayers).
+- Death obituaries were improved (now show killer's health and victim's class (if alien)).
+
0.1.3 Sep 10 2013
GAMEPLAY:
- It's not longer possible to avoid buildtimer by reconnecting.
@@ -15,8 +22,6 @@ NON-GAMEPLAY:
- A lot of visual changes in the voting system.
- Added vote sounds.
-
-______________________________________________________________________________________________
0.1.2 Sep 09 2013
GAMEPLAY:
- Wall impact effects no longer appear on players or buildables (the MD passing through players bug).
@@ -145,7 +150,7 @@ sound/cuboid/slime/dstr0.wav Michael Manzke @ freesound.org
sound/cuboid/slime/dstr1.wav Audionautics @ freesound.org cc-by
sound/cuboid/slime/pain0.wav anechoix @ freesound.org cc-by-nc
sound/cuboid/slime/pain1.wav anechoix @ freesound.org cc-by-nc
-sound/feedback/vote*.wav ?? ??
+sound/feedback/*.wav Pikachu cc0
sound/player/alienhatch.wav Darklegion Development, theinvsblman cc-by-sa
sound/player/alienfailedhatch.wav Darklegion Development, theinvsblman cc-by-sa
sound/upgrades/jetpack/hi.wav Pikachu cc0
diff --git a/assets/sound/feedback/1minremains.wav b/assets/sound/feedback/1minremains.wav
new file mode 100644
index 0000000..155da04
--- /dev/null
+++ b/assets/sound/feedback/1minremains.wav
Binary files differ
diff --git a/assets/sound/feedback/5minremain.wav b/assets/sound/feedback/5minremain.wav
new file mode 100644
index 0000000..545ec43
--- /dev/null
+++ b/assets/sound/feedback/5minremain.wav
Binary files differ
diff --git a/assets/sound/feedback/aliensadmit.wav b/assets/sound/feedback/aliensadmit.wav
new file mode 100644
index 0000000..0389669
--- /dev/null
+++ b/assets/sound/feedback/aliensadmit.wav
Binary files differ
diff --git a/assets/sound/feedback/alienslocked.wav b/assets/sound/feedback/alienslocked.wav
new file mode 100644
index 0000000..2063f2c
--- /dev/null
+++ b/assets/sound/feedback/alienslocked.wav
Binary files differ
diff --git a/assets/sound/feedback/aliensunlocked.wav b/assets/sound/feedback/aliensunlocked.wav
new file mode 100644
index 0000000..a56acdf
--- /dev/null
+++ b/assets/sound/feedback/aliensunlocked.wav
Binary files differ
diff --git a/assets/sound/feedback/alienswin.wav b/assets/sound/feedback/alienswin.wav
new file mode 100644
index 0000000..cce0617
--- /dev/null
+++ b/assets/sound/feedback/alienswin.wav
Binary files differ
diff --git a/assets/sound/feedback/humansadmit.wav b/assets/sound/feedback/humansadmit.wav
new file mode 100644
index 0000000..e8f0e16
--- /dev/null
+++ b/assets/sound/feedback/humansadmit.wav
Binary files differ
diff --git a/assets/sound/feedback/humanslocked.wav b/assets/sound/feedback/humanslocked.wav
new file mode 100644
index 0000000..2b35168
--- /dev/null
+++ b/assets/sound/feedback/humanslocked.wav
Binary files differ
diff --git a/assets/sound/feedback/humansunlocked.wav b/assets/sound/feedback/humansunlocked.wav
new file mode 100644
index 0000000..7d74f63
--- /dev/null
+++ b/assets/sound/feedback/humansunlocked.wav
Binary files differ
diff --git a/assets/sound/feedback/humanswin.wav b/assets/sound/feedback/humanswin.wav
new file mode 100644
index 0000000..bd4cd37
--- /dev/null
+++ b/assets/sound/feedback/humanswin.wav
Binary files differ
diff --git a/assets/sound/feedback/sdimminent.wav b/assets/sound/feedback/sdimminent.wav
new file mode 100644
index 0000000..f90ca15
--- /dev/null
+++ b/assets/sound/feedback/sdimminent.wav
Binary files differ
diff --git a/assets/sound/feedback/stalemate.wav b/assets/sound/feedback/stalemate.wav
new file mode 100644
index 0000000..5ee654f
--- /dev/null
+++ b/assets/sound/feedback/stalemate.wav
Binary files differ
diff --git a/assets/sound/feedback/suddendeath.wav b/assets/sound/feedback/suddendeath.wav
new file mode 100644
index 0000000..c75aca9
--- /dev/null
+++ b/assets/sound/feedback/suddendeath.wav
Binary files differ
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index 40df8b9..c8ca2e6 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -41,7 +41,7 @@ static void CG_Obituary( entityState_t *ent )
const char *attackerInfo;
char targetName[ MAX_NAME_LENGTH ];
char attackerName[ MAX_NAME_LENGTH ];
- char className[ 64 ];
+ char className[ 64 ], victimClassName[ 64 ];
gender_t gender;
clientInfo_t *ci;
qboolean teamKill = qfalse;
@@ -77,6 +77,12 @@ static void CG_Obituary( entityState_t *ent )
message2 = "";
+ if( ent->modelindex >= PCL_ALIEN_BUILDER0 &&
+ ent->modelindex <= PCL_ALIEN_LEVEL4 )
+ Com_sprintf( victimClassName, 64, "'s %s", BG_ClassConfig( ent->modelindex )->humanName );
+ else
+ victimClassName[ 0 ] = '\0';
+
// check for single client messages
switch( mod )
@@ -196,7 +202,7 @@ static void CG_Obituary( entityState_t *ent )
if( message )
{
- CG_Printf( "%s" S_COLOR_WHITE " %s\n", targetName, message );
+ CG_Printf( "%s" S_COLOR_WHITE "%s %s\n", targetName, victimClassName, message );
return;
}
@@ -360,10 +366,10 @@ static void CG_Obituary( entityState_t *ent )
if( message )
{
- CG_Printf( "%s" S_COLOR_WHITE " %s %s%s" S_COLOR_WHITE "%s\n",
- targetName, message,
+ CG_Printf( "%s" S_COLOR_WHITE "%s %s %s%s" S_COLOR_WHITE "%s, %iHP left\n",
+ targetName, victimClassName, message,
( teamKill ) ? S_COLOR_RED "TEAMMATE " S_COLOR_WHITE : "",
- attackerName, message2 );
+ attackerName, message2, ent->groundEntityNum );
if( teamKill && attacker == cg.clientNum )
{
CG_CenterPrint( va ( "You killed " S_COLOR_RED "TEAMMATE "
@@ -375,7 +381,7 @@ static void CG_Obituary( entityState_t *ent )
}
// we don't know what it was
- CG_Printf( "%s" S_COLOR_WHITE " died\n", targetName );
+ CG_Printf( "%s" S_COLOR_WHITE "%s died\n", targetName, victimClassName );
}
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 7dd951b..43e1701 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -941,6 +941,8 @@ typedef struct
// After this many msec the crosshair name fades out completely
#define CROSSHAIR_CLIENT_TIMEOUT 1000
+#define MAX_ANNOUNCER_STACK 16
+
typedef struct
{
int clientFrame; // incremented each frame
@@ -1185,9 +1187,15 @@ typedef struct
qboolean forbidCuboids; //if true then dont let player build a cuboid
int latestCBNumber; //wait for this number from server before building a cuboid
int lastCuboidError; //last time error sound was played
+
+ qhandle_t announcerStack[ MAX_ANNOUNCER_STACK ];
+ int announcerStackPos;
+ int announcerStackLatest;
} cg_t;
+
+
// all of the model, shader, and sound references that are
// loaded at gamestate time are stored in cgMedia_t
// Other media that can be tied to clients, weapons, or items are
@@ -1939,6 +1947,10 @@ void CG_WritePTRCode( int code );
const char *CG_TutorialText( void );
//
+// cg_svcmds.c
+void CG_ProcessAnnouncer( void );
+
+//
//===============================================
//
@@ -2171,12 +2183,13 @@ typedef enum
// mod version data
-#define MODVER_CURRENT 4
+#define MODVER_CURRENT 5
+#define MODVER_C2_0_1_4 5
#define MODVER_C2_0_1_3 4
#define MODVER_C2_0_1_2 3
#define MODVER_C2_0_1_1 2
#define MODVER_C2_0_1_0 1
-#define MODVER_TITLE "0.1.3 (Sep 10)"
+#define MODVER_TITLE "0.1.4 (Sep 12)"
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 4191cc7..427a571 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -1921,6 +1921,9 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum )
CG_ShaderStateChanged( );
trap_S_ClearLoopingSounds( qtrue );
+
+ cg.announcerStackLatest = -1;
+ cg.announcerStackPos = -1;
}
/*
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index f11aa7e..2a71b62 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -1261,12 +1261,36 @@ static void CG_PoisonCloud_f( void )
/*
=================
-CG_VoteEvent_f
+CG_ProcessAnnouncer
+=================
+*/
+#define ANNOUNCER_DELAY 2000
+void CG_ProcessAnnouncer( void )
+{
+ static int last = -ANNOUNCER_DELAY;
+
+ if( cg.announcerStackPos == cg.announcerStackLatest )
+ return;
-Vote sounds use commands to save on events and entities
+ if( last + ANNOUNCER_DELAY > cg.time )
+ return;
+
+ cg.announcerStackPos++;
+ cg.announcerStackPos %= MAX_ANNOUNCER_STACK;
+
+ trap_S_StartLocalSound( cg.announcerStack[ cg.announcerStackPos ], CHAN_VOICE );
+
+ last = cg.time;
+}
+
+/*
+=================
+CG_Announce_f
+
+Play an announcer sound
=================
*/
-static void CG_VoteEvent( void )
+static void CG_Announce( void )
{
const char *event, *soundName;
@@ -1278,12 +1302,31 @@ static void CG_VoteEvent( void )
if( !Q_stricmp( event, "votenow" ) ||
!Q_stricmp( event, "votecancelled" ) ||
!Q_stricmp( event, "votefailed" ) ||
- !Q_stricmp( event, "votepassed" ) )
+ !Q_stricmp( event, "votepassed" ) ||
+ !Q_stricmp( event, "timelimit_hit" ) ||
+ !Q_stricmp( event, "timelimit_1min" ) ||
+ !Q_stricmp( event, "timelimit_5min" ) ||
+ !Q_stricmp( event, "suddendeath" ) ||
+ !Q_stricmp( event, "sdimminent" ) ||
+ !Q_stricmp( event, "alienswin" ) ||
+ !Q_stricmp( event, "aliensadmit" ) ||
+ !Q_stricmp( event, "alienslocked" ) ||
+ !Q_stricmp( event, "aliensunlocked" ) ||
+ !Q_stricmp( event, "humanswin" ) ||
+ !Q_stricmp( event, "humansadmit" ) ||
+ !Q_stricmp( event, "humanslocked" ) ||
+ !Q_stricmp( event, "humansunlocked" ) ||
+ !Q_stricmp( event, "stalemate" ) ||
+ !Q_stricmp( event, "1minremains" ) ||
+ !Q_stricmp( event, "5minremains" ) )
soundName = va( "sound/feedback/%s.wav", event );
else
return;
- trap_S_StartLocalSound( trap_S_RegisterSound( soundName, qfalse ), CHAN_VOICE );
+ cg.announcerStackLatest++;
+ cg.announcerStackLatest %= MAX_ANNOUNCER_STACK;
+
+ cg.announcerStack[ cg.announcerStackLatest ] = trap_S_RegisterSound( soundName, qfalse );
}
static void CG_GameCmds_f( void )
@@ -1303,6 +1346,7 @@ static void CG_GameCmds_f( void )
static consoleCommand_t svcommands[ ] =
{
+ { "announce", CG_Announce },
{ "cb2", CG_Cuboid_Response }, // set local cuboid
{ "cb3", CG_Cuboid_Response }, // set local cuboid and print a "limit exceeded" warning
{ "chat", CG_Chat_f },
@@ -1317,8 +1361,7 @@ static consoleCommand_t svcommands[ ] =
{ "serverclosemenus", CG_ServerCloseMenus_f },
{ "servermenu", CG_ServerMenu_f },
{ "tinfo", CG_ParseTeamInfo },
- { "voice", CG_ParseVoice },
- { "voteevent", CG_VoteEvent }
+ { "voice", CG_ParseVoice }
};
/*
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index cd5e384..4b2b254 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -1459,6 +1459,9 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// update audio positions
trap_S_Respatialize( cg.snap->ps.clientNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater );
+
+ // update announcer
+ CG_ProcessAnnouncer( );
// make sure the lagometerSample and frame timing isn't done twice when in stereo
if( stereoView != STEREO_RIGHT )
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 3b667a9..a9ae715 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -2781,11 +2781,12 @@ static const upgradeAttributes_t bg_upgrades[ ] =
{
UP_BIORES, //int upgradeNum;
BIORES_PRICE, //int price;
- ( 1 << S2 )|( 1 << S3 ), //int stages
+ ( 1 << S2 )|( 1 << S3 ),//int stages
SLOT_NONE, //int slots;
"biores", //char *upgradeName;
"Biores", //char *humanName;
- "figure out a description later",
+ "A bioresistance implant that enhances the user's natural ability "
+ "to heal",
"icons/iconu_biokit",
qtrue, //qboolean purchasable
qfalse, //qboolean usable
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 35d57ed..cdc87c3 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -160,6 +160,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
""
},
+ {"register", G_admin_register, qfalse, "register",
+ "register your name",
+ ""
+ },
+
{"rename", G_admin_rename, qfalse, "rename",
"rename a player",
"[^3name|slot#^7] [^3new name^7]"
@@ -180,6 +185,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
"[^3name|slot#|admin#^7] [^3level^7]"
},
+ {"settitle", G_admin_settitle, qfalse, "settitle",
+ "sets the title of a player",
+ "[^3name|slot#|admin#^7] [^3title^7]"
+ },
+
{"showbans", G_admin_showbans, qtrue, "showbans",
"display a (partial) list of active bans",
"(^5name|IP(/mask)^7) (^5start at ban#^7)"
@@ -440,6 +450,9 @@ static qboolean admin_higher_admin( g_admin_admin_t *a, g_admin_admin_t *b )
if( !b )
return qtrue;
+ if( a == b )
+ return qfalse;
+
if( admin_permission( b->flags, ADMF_IMMUTABLE, &perm ) )
return !perm;
@@ -458,6 +471,9 @@ static qboolean admin_higher( gentity_t *admin, gentity_t *victim )
// console always wins
if( !admin )
return qtrue;
+
+ if( admin == victim )
+ return qfalse;
return admin_higher_admin( admin->client->pers.admin,
victim->client->pers.admin );
@@ -526,6 +542,8 @@ static void admin_writeconfig( void )
admin_writeconfig_int( a->level, f );
trap_FS_Write( "flags = ", 10, f );
admin_writeconfig_string( a->flags, f );
+ trap_FS_Write( "title = ", 10, f );
+ admin_writeconfig_string( a->title, f );
trap_FS_Write( "\n", 1, f );
}
for( b = g_admin_bans; b; b = b->next )
@@ -805,14 +823,23 @@ static void admin_out( void *admin, char *str )
{
g_admin_admin_t *a = (g_admin_admin_t *)admin;
g_admin_level_t *l = G_admin_level( a->level );
+ char *title;
int lncol = 0, i;
for( i = 0; l && l->name[ i ]; i++ )
{
if( Q_IsColorString( l->name + i ) )
lncol += 2;
}
- Com_sprintf( str, MAX_STRING_CHARS, "%-6d %*s^7 %s",
- a->level, admin_level_maxname + lncol - 1, l ? l->name : "(null)",
+
+ if( Q_stricmp( a->title, "" ) )
+ title = a->title;
+ else if ( l )
+ title = l->name;
+ else
+ title = "(null)";
+
+ Com_sprintf( str, MAX_STRING_CHARS, "%-2d %*s^7 %s",
+ a->level, admin_level_maxname + lncol - 1, title,
a->name );
}
static int admin_listadmins( gentity_t *ent, int start, char *search )
@@ -1166,6 +1193,13 @@ qboolean G_admin_readconfig( gentity_t *ent )
{
admin_readconfig_string( &cnf, a->flags, sizeof( a->flags ) );
}
+ else if( !Q_stricmp( t, "title" ) )
+ {
+ admin_readconfig_string( &cnf, a->title, sizeof( a->title ) );
+ len = Q_PrintStrlen( a->title );
+ if( len > admin_level_maxname )
+ admin_level_maxname = len;
+ }
else
{
COM_ParseError( "[admin] unrecognized token \"%s\"", t );
@@ -1399,8 +1433,7 @@ qboolean G_admin_setlevel( gentity_t *ent )
if( ent && !admin_higher_admin( ent->client->pers.admin, a ) )
{
- ADMP( "^3setlevel: ^7sorry, but your intended victim has a higher"
- " admin level than you\n" );
+ ADMP( "^3setlevel: ^7indented victim is immune to your actions\n" );
return qfalse;
}
@@ -1563,8 +1596,7 @@ qboolean G_admin_kick( gentity_t *ent )
vic = &g_entities[ pid ];
if( !admin_higher( ent, vic ) )
{
- ADMP( "^3kick: ^7sorry, but your intended victim has a higher admin"
- " level than you\n" );
+ ADMP( "^3kick: ^7indented victim is immune to your actions\n" );
return qfalse;
}
if( vic->client->pers.localClient )
@@ -1676,8 +1708,7 @@ qboolean G_admin_ban( gentity_t *ent )
if( ent && !admin_higher_guid( ent->client->pers.guid, match->guid ) )
{
- ADMP( "^3ban: ^7sorry, but your intended victim has a higher admin"
- " level than you\n" );
+ ADMP( "^3ban: ^7indented victim is immune to your actions\n" );
return qfalse;
}
if( match->slot > -1 && level.clients[ match->slot ].pers.localClient )
@@ -1930,8 +1961,7 @@ qboolean G_admin_putteam( gentity_t *ent )
vic = &g_entities[ pid ];
if( !admin_higher( ent, vic ) )
{
- ADMP( "^3putteam: ^7sorry, but your intended victim has a higher "
- " admin level than you\n" );
+ ADMP( "^3putteam: ^7indented victim is immune to your actions\n" );
return qfalse;
}
teamnum = G_TeamFromString( team );
@@ -2018,8 +2048,7 @@ qboolean G_admin_mute( gentity_t *ent )
if( ent && !admin_higher_admin( ent->client->pers.admin,
G_admin_admin( vic->guid ) ) )
{
- ADMP( va( "^3%s: ^7sorry, but your intended victim has a higher admin"
- " level than you\n", command ) );
+ ADMP( va( "^3%s: ^7indented victim is immune to your actions\n", command ) );
return qfalse;
}
if( vic->muted )
@@ -2194,7 +2223,7 @@ qboolean G_admin_listplayers( gentity_t *ent )
gclient_t *p;
char c, t; // color and team letter
char *registeredname;
- char lname[ MAX_NAME_LENGTH ];
+ char lname[ MAX_ADMIN_TITLE ];
char muted, denied;
int colorlen;
char namecleaned[ MAX_NAME_LENGTH ];
@@ -2250,7 +2279,9 @@ qboolean G_admin_listplayers( gentity_t *ent )
}
}
- if( l )
+ if( Q_stricmp( p->pers.admin->title, "" ) )
+ Q_strncpyz( lname, p->pers.admin->title, sizeof( lname ) );
+ else if( l )
Q_strncpyz( lname, l->name, sizeof( lname ) );
for( colorlen = j = 0; lname[ j ]; j++ )
@@ -2272,7 +2303,7 @@ qboolean G_admin_listplayers( gentity_t *ent )
p->pers.netname,
( registeredname ) ? "(a.k.a. " : "",
( registeredname ) ? registeredname : "",
- ( registeredname ) ? S_COLOR_WHITE ")" : "" ) );
+ ( registeredname ) ? S_COLOR_WHITE ")" : "" ) ) ;
}
ADMBP_end();
@@ -2454,6 +2485,7 @@ qboolean G_admin_adminhelp( gentity_t *ent )
qboolean G_admin_admintest( gentity_t *ent )
{
g_admin_level_t *l;
+ char *title;
if( !ent )
{
@@ -2463,12 +2495,19 @@ qboolean G_admin_admintest( gentity_t *ent )
l = G_admin_level( ent->client->pers.admin ? ent->client->pers.admin->level : 0 );
- AP( va( "print \"^3admintest: ^7%s^7 is a level %d admin %s%s^7%s\n\"",
+ if( !l )
+ return qfalse;
+
+ if( ent->client->pers.admin &&
+ Q_stricmp( ent->client->pers.admin->title, "" ) )
+ title = ent->client->pers.admin->title;
+ else
+ title = l->name;
+
+ AP( va( "print \"^3admintest: ^7%s^7 is %s^7 (level %d)\n\"",
ent->client->pers.netname,
- l ? l->level : 0,
- l ? "(" : "",
- l ? l->name : "",
- l ? ")" : "" ) );
+ title,
+ l->level ) );
return qtrue;
}
@@ -2931,6 +2970,21 @@ qboolean G_admin_lock( gentity_t *ent )
command, BG_TeamName( team ), lock ? "" : "un",
ent ? ent->client->pers.netname : "console" ) );
+ if( team == TEAM_ALIENS )
+ {
+ if( lock )
+ trap_SendServerCommand( -1, "announce alienslocked" );
+ else
+ trap_SendServerCommand( -1, "announce aliensunlocked" );
+ }
+ else
+ {
+ if( lock )
+ trap_SendServerCommand( -1, "announce humanslocked" );
+ else
+ trap_SendServerCommand( -1, "announce humansunlocked" );
+ }
+
return qtrue;
}
@@ -3276,3 +3330,172 @@ void G_admin_cleanup( void )
g_admin_commands = NULL;
BG_DefragmentMemory( );
}
+
+/*
+================
+G_admin_settitle
+================
+*/
+qboolean G_admin_settitle( gentity_t *ent )
+{
+ char title[ MAX_ADMIN_TITLE ];
+ char name[ MAX_NAME_LENGTH ];
+ char testname[ MAX_NAME_LENGTH ];
+ int i;
+ gentity_t *vic = NULL;
+ g_admin_admin_t *a = NULL;
+ g_admin_level_t *l = NULL;
+ int na;
+ int len;
+
+
+ if( trap_Argc() < 3 )
+ {
+ ADMP( "^3settitle: ^7usage: settitle [name|slot#] [title]\n" );
+ return qfalse;
+ }
+
+ trap_Argv( 1, testname, sizeof( testname ) );
+ trap_Argv( 2, title, sizeof( title ) );
+
+ for( na = 0, a = g_admin_admins; a; na++, a = a->next );
+ for( i = 0; testname[ i ] && isdigit( testname[ i ] ); i++ );
+ if( !testname[ i ] )
+ {
+ int id = atoi( testname );
+ if( id < MAX_CLIENTS )
+ {
+ vic = &g_entities[ id ];
+ if( !vic || !vic->client || vic->client->pers.connected == CON_DISCONNECTED )
+ {
+ ADMP( va( "^3settitle: ^7no player connected in slot %d\n", id ) );
+ return qfalse;
+ }
+ }
+ else if( id < na + MAX_CLIENTS )
+ for( i = 0, a = g_admin_admins; i < id - MAX_CLIENTS; i++, a = a->next );
+ else
+ {
+ ADMP( va( "^3settitle: ^7%s not in range 1-%d\n",
+ testname, na + MAX_CLIENTS - 1 ) );
+ return qfalse;
+ }
+ }
+ else
+ G_SanitiseString( testname, name, sizeof( name ) );
+
+ if( vic )
+ a = vic->client->pers.admin;
+ else if( !a )
+ {
+ g_admin_admin_t *wa;
+ int matches = 0;
+
+ for( wa = g_admin_admins; wa && matches < 2; wa = wa->next )
+ {
+ G_SanitiseString( wa->name, testname, sizeof( testname ) );
+ if( strstr( testname, name ) )
+ {
+ a = wa;
+ matches++;
+ }
+ }
+
+ for( i = 0; i < level.maxclients && matches < 2; i++ )
+ {
+ if( level.clients[ i ].pers.connected == CON_DISCONNECTED )
+ continue;
+
+ if( matches && level.clients[ i ].pers.admin &&
+ level.clients[ i ].pers.admin == a )
+ {
+ vic = &g_entities[ i ];
+ continue;
+ }
+
+ G_SanitiseString( level.clients[ i ].pers.netname, testname,
+ sizeof( testname ) );
+ if( strstr( testname, name ) )
+ {
+ vic = &g_entities[ i ];
+ a = vic->client->pers.admin;
+ matches++;
+ }
+ }
+
+ if( matches == 0 )
+ {
+ ADMP( "^3settitle:^7 no match. use listplayers or listadmins to "
+ "find an appropriate number to use instead of name.\n" );
+ return qfalse;
+ }
+ if( matches > 1 )
+ {
+ ADMP( "^3settitle:^7 more than one match. Use the admin number "
+ "instead:\n" );
+ admin_listadmins( ent, 0, name );
+ return qfalse;
+ }
+ }
+
+ if( !a )
+ {
+ ADMP( "^3settitle: ^7indented victim has no admin record\n" );
+ return qfalse;
+ }
+
+ if( ent && admin_higher_admin( a, ent->client->pers.admin ) )
+ {
+ ADMP( "^3settitle: ^7indented victim is immune to your actions\n" );
+ return qfalse;
+ }
+
+ Q_strncpyz( a->title, title, sizeof( title ) );
+
+ len = Q_PrintStrlen( a->title );
+ if( len > admin_level_maxname )
+ admin_level_maxname = len;
+
+ AP( va( "print \"^3settitle: ^7%s^7 was granted the title '%s^7' by %s^7\n\"",
+ a->name, a->title, ( ent ) ? ent->client->pers.netname : "console" ) );
+
+ admin_writeconfig();
+ return qtrue;
+}
+
+/*
+================
+G_admin_register
+================
+*/
+qboolean G_admin_register( gentity_t *ent )
+{
+ if( !ent )
+ return qfalse;
+
+ if( !ent->client->pers.admin )
+ {
+ g_admin_admin_t *a;
+
+ for( a = g_admin_admins; a && a->next; a = a->next );
+
+ if( a )
+ a = a->next = BG_Alloc( sizeof( g_admin_admin_t ) );
+ else
+ a = g_admin_admins = BG_Alloc( sizeof( g_admin_admin_t ) );
+
+ ent->client->pers.admin = a;
+ Q_strncpyz( a->guid, ent->client->pers.guid, sizeof( a->guid ) );
+ a->level = g_adminRegisterLevel.integer;
+
+ AP( va( "print \"^3register: ^7'%s'^7 is now a registered nickname\n\"", ent->client->pers.netname ) );
+ }
+ else
+ ADMP( "^3register: ^7you have updated your nick protection" );
+
+ Q_strncpyz( ent->client->pers.admin->name,
+ ent->client->pers.netname,
+ sizeof( ent->client->pers.admin->name ) );
+
+ return qtrue;
+}
diff --git a/src/game/g_admin.h b/src/game/g_admin.h
index 8024fc8..9a0fedf 100644
--- a/src/game/g_admin.h
+++ b/src/game/g_admin.h
@@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MAX_ADMIN_FLAGS 1024
#define MAX_ADMIN_CMD_LEN 20
#define MAX_ADMIN_BAN_REASON 50
+#define MAX_ADMIN_TITLE 30
/*
* IMMUNITY - cannot be vote kicked, vote muted
@@ -50,7 +51,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* INCOGNITO - does not show up as an admin in !listplayers
* ALLFLAGS - all flags (including command flags) apply to this player
* ADMINCHAT - receieves and can send /a admin messages
- * ALWAYSFRIEND - always marked as a friendly entity during buildgames
*/
#define ADMF_IMMUNITY "IMMUNITY"
#define ADMF_NOCENSORFLOOD "NOCENSORFLOOD"
@@ -66,8 +66,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define ADMF_ALLFLAGS "ALLFLAGS"
#define ADMF_ADMINCHAT "ADMINCHAT"
-#define ADMF_ALWAYSFRIEND "ALWAYSFRIEND"
-
#define MAX_ADMIN_LISTITEMS 20
#define MAX_ADMIN_SHOWBANS 10
@@ -100,6 +98,7 @@ typedef struct g_admin_admin
char guid[ 33 ];
char name[ MAX_NAME_LENGTH ];
char flags[ MAX_ADMIN_FLAGS ];
+ char title[ MAX_ADMIN_TITLE ];
}
g_admin_admin_t;
@@ -186,6 +185,10 @@ qboolean G_admin_builder( gentity_t *ent );
qboolean G_admin_buildlog( gentity_t *ent );
qboolean G_admin_revert( gentity_t *ent );
+qboolean G_admin_settitle( gentity_t *ent );
+qboolean G_admin_register( gentity_t *ent );
+
+
void G_admin_print( gentity_t *ent, char *m );
void G_admin_buffer_print( gentity_t *ent, char *m );
void G_admin_buffer_begin( void );
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index c9c6213..ef5a864 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -1572,7 +1572,7 @@ void Cmd_CallVote_f( gentity_t *ent )
G_Vote( ent, team, qtrue );
level.voteAborted[ team ] = qfalse;
- trap_SendServerCommand( -1, "voteevent votenow" );
+ trap_SendServerCommand( -1, "announce votenow" );
}
/*
@@ -3295,9 +3295,16 @@ void Cmd_Damage_f( gentity_t *ent )
Cmd_Debug1_f
=================
*/
-void Cmd_Debug1_f( gentity_t *ent )
+void Cmd_Debug1_f( gentity_t *self )
{
- AddScore( ent, random() * 15000.0f );
+ gentity_t *ent;
+ ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
+ ent->s.eventParm = MOD_MACHINEGUN;
+ ent->s.otherEntityNum = self->s.number;
+ ent->s.modelindex = self->client->ps.stats[ STAT_CLASS ];
+ ent->s.otherEntityNum2 = 1;
+ ent->s.groundEntityNum = 666;
+ ent->r.svFlags = SVF_BROADCAST; // send to everyone
}
/*
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index a9e8e68..1b6708f 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -235,7 +235,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
{
gentity_t *ent, *ent2;
int anim;
- int killer;
+ int killer, killerHP;
int i;
char *killerName, *obit;
vec3_t dir;
@@ -254,14 +254,17 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
killer = attacker->s.number;
if( attacker->client )
- killerName = attacker->client->pers.netname;
+ killerName = attacker->client->pers.netname,
+ killerHP = attacker->health;
else
- killerName = "<world>";
+ killerName = "<world>",
+ killerHP = 0;
}
else
{
killer = ENTITYNUM_WORLD;
killerName = "<world>";
+ killerHP = 0;
}
if( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) )
@@ -287,7 +290,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
ent->s.eventParm = meansOfDeath;
ent->s.otherEntityNum = self->s.number;
+ ent->s.modelindex = self->client->ps.stats[ STAT_CLASS ];
ent->s.otherEntityNum2 = killer;
+ ent->s.groundEntityNum = killerHP;
ent->r.svFlags = SVF_BROADCAST; // send to everyone
self->enemy = attacker;
diff --git a/src/game/g_local.h b/src/game/g_local.h
index f836875..3bd8642 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -1209,6 +1209,7 @@ extern vmCvar_t g_emoticonsAllowedInNames;
extern vmCvar_t g_admin;
extern vmCvar_t g_adminTempBan;
extern vmCvar_t g_adminMaxBan;
+extern vmCvar_t g_adminRegisterLevel;
extern vmCvar_t g_privateMessages;
extern vmCvar_t g_specChat;
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 7775fc8..1750e26 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -138,6 +138,7 @@ vmCvar_t g_emoticonsAllowedInNames;
vmCvar_t g_admin;
vmCvar_t g_adminTempBan;
vmCvar_t g_adminMaxBan;
+vmCvar_t g_adminRegisterLevel;
vmCvar_t g_privateMessages;
vmCvar_t g_specChat;
@@ -281,6 +282,7 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_admin, "g_admin", "admin.dat", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminTempBan, "g_adminTempBan", "2m", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminMaxBan, "g_adminMaxBan", "2w", CVAR_ARCHIVE, 0, qfalse },
+ { &g_adminRegisterLevel, "g_adminRegisterLevel", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_privateMessages, "g_privateMessages", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_specChat, "g_specChat", "1", CVAR_ARCHIVE, 0, qfalse },
@@ -1220,6 +1222,7 @@ void G_CalculateBuildPoints( void )
G_LogPrintf( "Beginning Sudden Death\n" );
trap_SendServerCommand( -1, "cp \"Sudden Death!\"" );
trap_SendServerCommand( -1, "print \"Beginning Sudden Death.\n\"" );
+ trap_SendServerCommand( -1, "announce suddendeath" );
level.suddenDeathWarning = TW_PASSED;
G_ClearDeconMarks( );
@@ -1237,6 +1240,7 @@ void G_CalculateBuildPoints( void )
(int)( G_TimeTilSuddenDeath( ) / 1000 ) ) );
trap_SendServerCommand( -1, va( "print \"Sudden Death will begin in %d seconds.\n\"",
(int)( G_TimeTilSuddenDeath( ) / 1000 ) ) );
+ trap_SendServerCommand( -1, "announce sdimminent" );
level.suddenDeathWarning = TW_IMMINENT;
}
@@ -2112,6 +2116,7 @@ void CheckExitRules( void )
{
level.lastWin = TEAM_NONE;
trap_SendServerCommand( -1, "print \"Timelimit hit\n\"" );
+ trap_SendServerCommand( -1, "announce stalemate" );
trap_SetConfigstring( CS_WINNER, "Stalemate" );
LogExit( "Timelimit hit." );
return;
@@ -2120,12 +2125,14 @@ void CheckExitRules( void )
level.timelimitWarning < TW_IMMINENT )
{
trap_SendServerCommand( -1, "cp \"5 minutes remaining!\"" );
+ trap_SendServerCommand( -1, "announce 5minremain" );
level.timelimitWarning = TW_IMMINENT;
}
else if( level.time - level.startTime >= ( g_timelimit.integer - 1 ) * 60000 &&
level.timelimitWarning < TW_PASSED )
{
trap_SendServerCommand( -1, "cp \"1 minute remaining!\"" );
+ trap_SendServerCommand( -1, "announce 1minremains" );
level.timelimitWarning = TW_PASSED;
}
}
@@ -2140,6 +2147,7 @@ void CheckExitRules( void )
//humans win
level.lastWin = TEAM_HUMANS;
trap_SendServerCommand( -1, "print \"Humans win\n\"");
+ trap_SendServerCommand( -1, "announce humanswin" );
trap_SetConfigstring( CS_WINNER, "Humans Win" );
LogExit( "Humans win." );
}
@@ -2152,6 +2160,7 @@ void CheckExitRules( void )
//aliens win
level.lastWin = TEAM_ALIENS;
trap_SendServerCommand( -1, "print \"Aliens win\n\"");
+ trap_SendServerCommand( -1, "announce alienswin" );
trap_SetConfigstring( CS_WINNER, "Aliens Win" );
LogExit( "Aliens win." );
}
@@ -2265,15 +2274,15 @@ void G_CheckVote( team_t team )
if( pass )
{
if( !level.voteAborted[ team ] )
- trap_SendServerCommand( -1, "voteevent votepassed" );
+ trap_SendServerCommand( -1, "announce votepassed" );
level.voteExecuteTime[ team ] = level.time + level.voteDelay[ team ];
}
else
{
if( !level.voteAborted[ team ] )
- trap_SendServerCommand( -1, "voteevent votefailed" );
+ trap_SendServerCommand( -1, "announce votefailed" );
else
- trap_SendServerCommand( -1, "voteevent votecancelled" );
+ trap_SendServerCommand( -1, "announce votecancelled" );
}
G_LogPrintf( "EndVote: %s %s %d %d %d %f %f\n",
diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c
index 16cb6b8..da32326 100644
--- a/src/game/g_svcmds.c
+++ b/src/game/g_svcmds.c
@@ -285,11 +285,13 @@ static void Svcmd_AdmitDefeat_f( void )
{
G_TeamCommand( TEAM_ALIENS, "cp \"Hivemind Link Broken\" 1");
trap_SendServerCommand( -1, "print \"Alien team has admitted defeat\n\"" );
+ trap_SendServerCommand( -1, "announce aliensadmit" );
}
else if( team == TEAM_HUMANS )
{
G_TeamCommand( TEAM_HUMANS, "cp \"Life Support Terminated\" 1");
trap_SendServerCommand( -1, "print \"Human team has admitted defeat\n\"" );
+ trap_SendServerCommand( -1, "announce humansadmit" );
}
else
{
@@ -324,6 +326,7 @@ static void Svcmd_TeamWin_f( void )
static void Svcmd_Evacuation_f( void )
{
trap_SendServerCommand( -1, "print \"Evacuation ordered\n\"" );
+ trap_SendServerCommand( -1, "announce stalemate" );
level.lastWin = TEAM_NONE;
trap_SetConfigstring( CS_WINNER, "Evacuation" );
LogExit( "Evacuation." );