From 37b8af1e6eb90378f1290b5130c8b6882b06a219 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Mon, 9 Sep 2013 23:24:54 +0200 Subject: 0.1.3 --- assets/credits.txt | 17 ++++++++++++++- assets/sound/feedback/votecancelled.wav | Bin 0 -> 141306 bytes assets/sound/feedback/votefailed.wav | Bin 0 -> 114846 bytes assets/sound/feedback/votenow.wav | Bin 0 -> 114846 bytes assets/sound/feedback/votepassed.wav | Bin 0 -> 123666 bytes src/cgame/cg_local.h | 5 +++-- src/cgame/cg_servercmds.c | 30 +++++++++++++++++++++++++- src/game/g_admin.c | 1 + src/game/g_buildable.c | 33 ++++++++++++++++++++++++++++ src/game/g_cmds.c | 23 +++++++++++++++++++- src/game/g_combat.c | 22 +------------------ src/game/g_local.h | 8 +++++++ src/game/g_main.c | 37 +++++++++++++++++++++++++++----- src/game/g_team.c | 2 ++ 14 files changed, 147 insertions(+), 31 deletions(-) create mode 100644 assets/sound/feedback/votecancelled.wav create mode 100644 assets/sound/feedback/votefailed.wav create mode 100644 assets/sound/feedback/votenow.wav create mode 100644 assets/sound/feedback/votepassed.wav diff --git a/assets/credits.txt b/assets/credits.txt index 21f6a68..2e6cd27 100644 --- a/assets/credits.txt +++ b/assets/credits.txt @@ -5,9 +5,20 @@ Cuboid - a Tremulous 1.2 mod focused on cuboids and fixing balance issues. CHANGELOG Version Release date +______________________________________________________________________________________________ +0.1.3 Sep 10 2013 +GAMEPLAY: +- It's not longer possible to avoid buildtimer by reconnecting. +NON-GAMEPLAY: +- Customizable vote percentages: g_[map/restart/draw]VotePercent, default: 67. +- Customizable vote timelimits: g_[map/restart]Timelimit, default: 5 for map votes, 10 for restart votes. +- A lot of visual changes in the voting system. +- Added vote sounds. + + ______________________________________________________________________________________________ 0.1.2 Sep 09 2013 -GAMEPLAY +GAMEPLAY: - Wall impact effects no longer appear on players or buildables (the MD passing through players bug). - Now it takes longer for Biores to start healing after the human is hurt. NON-GAMEPLAY: @@ -104,6 +115,9 @@ models/weapons/level2upg/weapon.cfg Darklegion Development, theinvsblman models/weapons/level4/weapon.cfg Darklegion Development, theinvsblman cc-by-sa scripts/cuboid.shader theinvsblman cc-by scripts/cuboid.particle Darklegion Development, theinvsblman cc-by-sa +sound/buildables/mgturret/spinup_a... Darklegion Development, Pikachu cc-by-sa +sound/buildables/mgturret/spinup_b... Darklegion Development, Pikachu cc-by-sa +sound/buildables/mgturret/turretki... Pikachu cc0 sound/cuboid/axischange.wav Ongitak @ freesound.org cc-by sound/cuboid/concrete/dstr0.wav Michael Manzke @ freesound.org cc-by-nc sound/cuboid/concrete/pain0.wav Benboncan @ freesound.org cc-by @@ -131,6 +145,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/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/votecancelled.wav b/assets/sound/feedback/votecancelled.wav new file mode 100644 index 0000000..12cc548 Binary files /dev/null and b/assets/sound/feedback/votecancelled.wav differ diff --git a/assets/sound/feedback/votefailed.wav b/assets/sound/feedback/votefailed.wav new file mode 100644 index 0000000..6dcffa2 Binary files /dev/null and b/assets/sound/feedback/votefailed.wav differ diff --git a/assets/sound/feedback/votenow.wav b/assets/sound/feedback/votenow.wav new file mode 100644 index 0000000..c9d0e6d Binary files /dev/null and b/assets/sound/feedback/votenow.wav differ diff --git a/assets/sound/feedback/votepassed.wav b/assets/sound/feedback/votepassed.wav new file mode 100644 index 0000000..fa0f555 Binary files /dev/null and b/assets/sound/feedback/votepassed.wav differ diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 11133bf..7dd951b 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -2171,11 +2171,12 @@ typedef enum // mod version data -#define MODVER_CURRENT 3 +#define MODVER_CURRENT 4 +#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.2 (Sep 09)" +#define MODVER_TITLE "0.1.3 (Sep 10)" diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index 48a5a60..f11aa7e 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -1259,6 +1259,33 @@ static void CG_PoisonCloud_f( void ) } } +/* +================= +CG_VoteEvent_f + +Vote sounds use commands to save on events and entities +================= +*/ +static void CG_VoteEvent( void ) +{ + const char *event, *soundName; + + if( trap_Argc( ) != 2 ) + return; + + event = CG_Argv( 1 ); + + if( !Q_stricmp( event, "votenow" ) || + !Q_stricmp( event, "votecancelled" ) || + !Q_stricmp( event, "votefailed" ) || + !Q_stricmp( event, "votepassed" ) ) + soundName = va( "sound/feedback/%s.wav", event ); + else + return; + + trap_S_StartLocalSound( trap_S_RegisterSound( soundName, qfalse ), CHAN_VOICE ); +} + static void CG_GameCmds_f( void ) { int i; @@ -1290,7 +1317,8 @@ static consoleCommand_t svcommands[ ] = { "serverclosemenus", CG_ServerCloseMenus_f }, { "servermenu", CG_ServerMenu_f }, { "tinfo", CG_ParseTeamInfo }, - { "voice", CG_ParseVoice } + { "voice", CG_ParseVoice }, + { "voteevent", CG_VoteEvent } }; /* diff --git a/src/game/g_admin.c b/src/game/g_admin.c index e753f19..35d57ed 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -2528,6 +2528,7 @@ qboolean G_admin_endvote( gentity_t *ent ) admin_log( BG_TeamName( team ) ); level.voteNo[ team ] = cancel ? level.numVotingClients[ team ] : 0; level.voteYes[ team ] = cancel ? 0 : level.numVotingClients[ team ]; + level.voteAborted[ team ] = qtrue; G_CheckVote( team ); if( team == TEAM_NONE ) AP( msg ); diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index beb7e37..b13c54a 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -4548,3 +4548,36 @@ void G_BuildLogRevert( int id ) } } +/* +============ +G_RemoveUnbuiltBuildables + +Kill all player's buildables if they havent spawned yet +============ +*/ +void G_RemoveUnbuiltBuildables( gentity_t *self ) +{ + int i; + vec3_t dir; + gentity_t *ent; + + dir[0] = dir[1] = 0.0f; + dir[2] = 1.0f; + + for( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ ) + { + if( ent->s.eType != ET_BUILDABLE ) + continue; + + if( ent == self ) + continue; + + if( ent->spawned ) + continue; + + if( ent->builtBy != self->client->ps.clientNum ) + continue; + + G_Damage( ent, self, NULL, dir, dir, ent->health, 0, MOD_DECONSTRUCT ); + } +} diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index aebb975..c9c6213 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1363,12 +1363,28 @@ void Cmd_CallVote_f( gentity_t *ent ) } else if( !Q_stricmp( vote, "map_restart" ) ) { + if( level.time / 60000 >= g_restartVoteTimelimit.integer ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"%s: It's not allowed to call a restart vote after %i minute%s.\n\"", + cmd, g_restartVoteTimelimit.integer, ( g_restartVoteTimelimit.integer == 1 ? "" : "s" ) ) ); + return; + } strcpy( level.voteString[ team ], vote ); strcpy( level.voteDisplayString[ team ], "Restart current map" ); + level.voteThreshold[ team ] = g_restartVotePercent.integer; // map_restart comes with a default delay } else if( !Q_stricmp( vote, "map" ) ) { + if( level.time / 60000 >= g_mapVoteTimelimit.integer ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"%s: It's not allowed to call a map vote after %i minute%s. Call a ^1nextmap^7 vote instead\n\"", + cmd, g_mapVoteTimelimit.integer, ( g_mapVoteTimelimit.integer == 1 ? "" : "s" ) ) ); + return; + } + if( !G_MapExists( arg ) ) { trap_SendServerCommand( ent-g_entities, @@ -1383,6 +1399,7 @@ void Cmd_CallVote_f( gentity_t *ent ) sizeof( level.voteDisplayString[ team ] ), "Change to map '%s'", arg ); level.voteDelay[ team ] = 3000; + level.voteThreshold[ team ] = g_mapVotePercent.integer; } else if( !Q_stricmp( vote, "nextmap" ) ) { @@ -1406,13 +1423,14 @@ void Cmd_CallVote_f( gentity_t *ent ) "set g_nextMap \"%s\"", arg ); Com_sprintf( level.voteDisplayString[ team ], sizeof( level.voteDisplayString[ team ] ), - "Set the next map to '%s'", arg ); + "Set the ^1next^7 map to '%s'", arg ); } else if( !Q_stricmp( vote, "draw" ) ) { strcpy( level.voteString[ team ], "evacuation" ); strcpy( level.voteDisplayString[ team ], "End match in a draw" ); level.voteDelay[ team ] = 3000; + level.voteThreshold[ team ] = g_drawVotePercent.integer; } else if( !Q_stricmp( vote, "sudden_death" ) ) { @@ -1552,6 +1570,9 @@ void Cmd_CallVote_f( gentity_t *ent ) ent->client->pers.namelog->voteCount++; ent->client->pers.vote |= 1 << team; G_Vote( ent, team, qtrue ); + + level.voteAborted[ team ] = qfalse; + trap_SendServerCommand( -1, "voteevent votenow" ); } /* diff --git a/src/game/g_combat.c b/src/game/g_combat.c index b5963ab..a9e8e68 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -281,27 +281,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) BG_DeactivateUpgrade( i, self->client->ps.stats ); - // kill all player's buildables if they havent spawned yet - // this should eliminate build timer hacks for ever - dir[0] = dir[1] = 0.0f; - dir[2] = 1.0f; - - for( i = MAX_CLIENTS, ent = g_entities + i; i < level.num_entities; i++, ent++ ) - { - if( ent->s.eType != ET_BUILDABLE ) - continue; - - if( ent == self ) - continue; - - if( ent->spawned ) - continue; - - if( ent->builtBy != self->client->ps.clientNum ) - continue; - - G_Damage( ent, self, attacker, dir, dir, ent->health, 0, MOD_DECONSTRUCT ); - } + G_RemoveUnbuiltBuildables( self ); // broadcast the death event to everyone ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY ); diff --git a/src/game/g_local.h b/src/game/g_local.h index a8c78b0..f836875 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -597,6 +597,7 @@ typedef struct int voteYes[ NUM_TEAMS ]; int voteNo[ NUM_TEAMS ]; int numVotingClients[ NUM_TEAMS ];// set by CalculateRanks + qboolean voteAborted[ NUM_TEAMS ]; // true if ended by an admin // spawn variables qboolean spawning; // the G_Spawn*() functions are valid @@ -833,6 +834,7 @@ void G_BuildLogAuto( gentity_t *actor, gentity_t *buildable, buildF void G_BuildLogRevert( int id ); const char *G_CuboidName(buildable_t buildable, const vec3_t cuboidSize, qboolean verbose); void G_LayoutBuildItem( buildable_t buildable, vec3_t origin, vec3_t angles, vec3_t origin2, vec3_t angles2 ); +void G_RemoveUnbuiltBuildables( gentity_t *self ); // // g_utils.c @@ -1143,6 +1145,11 @@ extern vmCvar_t g_allowVote; extern vmCvar_t g_voteLimit; extern vmCvar_t g_suddenDeathVotePercent; extern vmCvar_t g_suddenDeathVoteDelay; +extern vmCvar_t g_mapVotePercent; +extern vmCvar_t g_mapVoteTimelimit; +extern vmCvar_t g_restartVotePercent; +extern vmCvar_t g_restartVoteTimelimit; +extern vmCvar_t g_drawVotePercent; extern vmCvar_t g_teamForceBalance; extern vmCvar_t g_smoothClients; extern vmCvar_t pmove_fixed; @@ -1217,6 +1224,7 @@ extern vmCvar_t g_cuboidSizeLimit; extern vmCvar_t g_buildableDensityLimit; extern vmCvar_t g_buildableDensityLimitRange; + void trap_Print( const char *fmt ); void trap_Error( const char *fmt ); int trap_Milliseconds( void ); diff --git a/src/game/g_main.c b/src/game/g_main.c index 4bc03b5..7775fc8 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -72,6 +72,11 @@ vmCvar_t g_allowVote; vmCvar_t g_voteLimit; vmCvar_t g_suddenDeathVotePercent; vmCvar_t g_suddenDeathVoteDelay; +vmCvar_t g_mapVotePercent; +vmCvar_t g_mapVoteTimelimit; +vmCvar_t g_restartVotePercent; +vmCvar_t g_restartVoteTimelimit; +vmCvar_t g_drawVotePercent; vmCvar_t g_teamForceBalance; vmCvar_t g_smoothClients; vmCvar_t pmove_fixed; @@ -210,6 +215,12 @@ static cvarTable_t gameCvarTable[ ] = { &g_voteLimit, "g_voteLimit", "5", CVAR_ARCHIVE, 0, qfalse }, { &g_suddenDeathVotePercent, "g_suddenDeathVotePercent", "74", CVAR_ARCHIVE, 0, qfalse }, { &g_suddenDeathVoteDelay, "g_suddenDeathVoteDelay", "180", CVAR_ARCHIVE, 0, qfalse }, + { &g_mapVotePercent, "g_mapVotePercent", "67", CVAR_ARCHIVE, 0, qfalse }, + { &g_mapVoteTimelimit, "g_mapVoteTimelimit", "5", CVAR_ARCHIVE, 0, qfalse }, + { &g_restartVotePercent, "g_restartVotePercent", "67", CVAR_ARCHIVE, 0, qfalse }, + { &g_restartVoteTimelimit, "g_restartVoteTimelimit", "10", CVAR_ARCHIVE, 0, qfalse }, + { &g_drawVotePercent, "g_drawVotePercent", "67", CVAR_ARCHIVE, 0, qfalse }, + { &g_minNameChangePeriod, "g_minNameChangePeriod", "5", 0, 0, qfalse}, { &g_maxNameChanges, "g_maxNameChanges", "5", 0, 0, qfalse}, @@ -2215,6 +2226,7 @@ G_CheckVote void G_CheckVote( team_t team ) { float votePassThreshold = (float)level.voteThreshold[ team ] / 100.0f; + float threshold; qboolean pass = qfalse; char *msg; int i; @@ -2247,18 +2259,33 @@ void G_CheckVote( team_t team ) return; } } + + threshold = (float)level.voteYes[ team ] / ( (float)level.voteNo[ team ] + level.voteYes[ team ] ); if( pass ) + { + if( !level.voteAborted[ team ] ) + trap_SendServerCommand( -1, "voteevent votepassed" ); level.voteExecuteTime[ team ] = level.time + level.voteDelay[ team ]; + } + else + { + if( !level.voteAborted[ team ] ) + trap_SendServerCommand( -1, "voteevent votefailed" ); + else + trap_SendServerCommand( -1, "voteevent votecancelled" ); + } - G_LogPrintf( "EndVote: %s %s %d %d %d\n", + G_LogPrintf( "EndVote: %s %s %d %d %d %f %f\n", team == TEAM_NONE ? "global" : BG_TeamName( team ), pass ? "pass" : "fail", - level.voteYes[ team ], level.voteNo[ team ], level.numVotingClients[ team ] ); + level.voteYes[ team ], level.voteNo[ team ], level.numVotingClients[ team ], + threshold, votePassThreshold ); - msg = va( "print \"%sote %sed (%d - %d)\n\"", - team == TEAM_NONE ? "V" : "Team v", pass ? "pass" : "fail", - level.voteYes[ team ], level.voteNo[ team ] ); + msg = va( "print \"%sote %sed^7: %d - %d (%.0f%%/%.0f%%)\n\"", + team == TEAM_NONE ? "V" : "Team v", pass ? "^2pass" : "^1fail", + level.voteYes[ team ], level.voteNo[ team ], threshold * 100, + votePassThreshold * 100 ); if( team == TEAM_NONE ) trap_SendServerCommand( -1, msg ); diff --git a/src/game/g_team.c b/src/game/g_team.c index fd15aa7..f46436d 100644 --- a/src/game/g_team.c +++ b/src/game/g_team.c @@ -209,6 +209,8 @@ void G_LeaveTeam( gentity_t *self ) // cut all relevant zap beams G_ClearPlayerZapEffects( self ); + G_RemoveUnbuiltBuildables( self ); + G_namelog_update_score( self->client ); } -- cgit