Example #1
0
//QUAKED trigger_counter (.5 .5 .5) ? NOMESSAGE NOSOUNDS
//Acts as an intermediary for an action that takes multiple inputs. Example: a sequence of several buttons to activate a event
//-------- KEYS --------
//target : this points to the entity to activate.
//targetname : activating trigger points to this.
//count : number of actions to count (default 2)
//noise_start : sound to play each time a event happens
//noise_stop : sound to play at the last event in the count
//notsingle : when set to 1, entity will not spawn in Single Player mode
//notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
//notduel : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. (jaltodo)
//notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
//notctf : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes. (jaltodo)
//-------- SPAWNFLAGS --------
//NOMESSAGE : &1 if not set, it will print "1 more.. " etc when triggered and "sequence complete" when finished.
//NOSOUNDS : &2 if not set, it will try to play the noise_start and noise_stop sounds
//-------- NOTES --------
//Sounds like this one should be a target and not a trigger, but well...
static void trigger_counter_use( edict_t *self, edict_t *other, edict_t *activator )
{
	if( self->count == 0 )
		return;

	self->count--;

	if( self->count )
	{
		if( !( self->spawnflags & 1 ) )
			G_CenterPrintMsg( activator, "%i more to go...", self->count );
		if( !( self->spawnflags & 2 ) )
			G_Sound( activator, CHAN_AUTO, self->moveinfo.sound_start, ATTN_NORM );

		return;
	}

	if( !( self->spawnflags & 1 ) )
		G_CenterPrintMsg( activator, "Sequence completed!" );
	if( !( self->spawnflags & 2 ) )
		G_Sound( activator, CHAN_AUTO, self->moveinfo.sound_end, ATTN_NORM );

	self->activator = activator;
	multi_trigger( self );
}
Example #2
0
//==========================================
// AITools_ShowPlinks
// Draws lines from the current node to it's plinks nodes
//==========================================
static void AITools_ShowPlinks( edict_t *target )
{
	static unsigned int debugdrawplinks_timeout;
	int current_node;
	int plink_node;
	int i;
	nav_ents_t *goalEnt;

	if( !target || !target->r.client || !target->r.client->level.showPLinks )
		return;

	//do it
	current_node = AI_FindClosestReachableNode( target->s.origin, target, NODE_DENSITY * 3, NODE_ALL );

	// draw the axis where the node is
	if( nodes[current_node].flags & NODEFLAGS_SERVERLINK )
		AITools_DrawAxis( nodes[current_node].origin, COLOR_RGBA( 255, 25, 25, 255 ) );
	else
		AITools_DrawAxis( nodes[current_node].origin, COLOR_RGBA( 210, 250, 250, 255 ) );

	//don't draw the links every frame (flood)
	if( level.time < debugdrawplinks_timeout )
		return;
	debugdrawplinks_timeout = level.time + 4 * game.snapFrameTime;

	if( nav.editmode || !nav.loaded )
		return;

	FOREACH_GOALENT( goalEnt )
	{
		i = goalEnt->id;
		if( goalEnt->node == current_node )
		{
			if( !goalEnt->ent->classname )
				G_CenterPrintMsg( target, "no classname" );
			else
				G_CenterPrintMsg( target, "%s", goalEnt->ent->classname );
			break;
		}
	}

	// no links to draw
	if( !pLinks[current_node].numLinks )
		return;

	for( i = 0; i < pLinks[current_node].numLinks; i++ )
	{
		plink_node = pLinks[current_node].nodes[i];
		if( pLinks[current_node].moveType[i] == LINK_ROCKETJUMP )
			AITools_DrawColorLine( nodes[current_node].origin,
			nodes[plink_node].origin, COLOR_RGBA( 0xff, 0x00, 0x00, 0x80 ), 0 );
		else if( pLinks[current_node].moveType[i] == LINK_JUMP )
			AITools_DrawColorLine( nodes[current_node].origin,
			nodes[plink_node].origin, COLOR_RGBA( 0x00, 0x00, 0xff, 0x80 ), 0 );
		else
			AITools_DrawColorLine( nodes[current_node].origin,
			nodes[plink_node].origin, COLOR_RGBA( 0x00, 0xff, 0x00, 0x80 ), 0 );
	}
}
Example #3
0
/*
* G_Teams_ExecuteChallengersQueue
*/
void G_Teams_ExecuteChallengersQueue( void )
{
	edict_t *ent;
	edict_t **challengers;
	bool restartmatch = false;

	// Medar fixme: this is only really makes sense, if playerlimit per team is one
	if( GS_MatchState() == MATCH_STATE_PLAYTIME )
		return;

	if( !GS_HasChallengers() )
		return;

	if( game.realtime < level.spawnedTimeStamp + G_CHALLENGERS_MIN_JOINTEAM_MAPTIME )
	{
		static int time, lasttime;
		time = (int)( ( G_CHALLENGERS_MIN_JOINTEAM_MAPTIME - ( game.realtime - level.spawnedTimeStamp ) )*0.001 );
		if( lasttime && time == lasttime )
			return;
		lasttime = time;
		if( lasttime )
			G_CenterPrintMsg( NULL, "Waiting... %i", lasttime );
		else
			G_CenterPrintMsg( NULL, "" );
		return;
	}

	// pick players in join order and try to put them in the
	// game until we get the first refused one.
	challengers = G_Teams_ChallengersQueue();
	if( challengers )
	{
		int i;

		for( i = 0; challengers[i]; i++ )
		{
			ent = challengers[i];
			if( !G_Teams_JoinAnyTeam( ent, true ) )
				break;

			// if we successfully execute the challengers queue during the countdown, revert to warmup
			if( GS_MatchState() == MATCH_STATE_COUNTDOWN )
			{
				restartmatch = true;
			}
		}
	}

	if( restartmatch == true )
	{
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
	}
}
Example #4
0
static void SP_target_print_print( edict_t *self, edict_t *activator )
{
	if( self->helpmessage && self->mapmessage_index <= MAX_HELPMESSAGES ) {
		G_SetPlayerHelpMessage( activator, self->mapmessage_index );
		return;
	}

	G_CenterPrintMsg( activator, self->message );
}
Example #5
0
static void G_Gametype_GENERIC_ThinkRules( void )
{
	if( G_Match_ScorelimitHit() || G_Match_TimelimitHit() || G_Match_SuddenDeathFinished() )
{
	G_CenterPrintMsg( NULL, "ENDOOOOOOOOOOOOOOOOO saaaaan!!!!!!!!!!\n" );
		G_Match_LaunchState( GS_MatchState() + 1 );
}

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
		return;
}
Example #6
0
/*
* G_Match_CheckExtendPlayTime
*/
bool G_Match_CheckExtendPlayTime( void )
{
	// check for extended time/sudden death
	if( GS_MatchState() != MATCH_STATE_PLAYTIME )
		return false;

	if( GS_TeamBasedGametype() && !level.forceExit )
	{
		if( G_Match_Tied() )
		{
			GS_GamestatSetFlag( GAMESTAT_FLAG_MATCHEXTENDED, true );
			gs.gameState.stats[GAMESTAT_MATCHSTATE] = MATCH_STATE_PLAYTIME;
			gs.gameState.longstats[GAMELONG_MATCHSTART] = game.serverTime;

			if( g_match_extendedtime->value )
			{
				if( !GS_MatchExtended() )  // first one
					G_AnnouncerSound( NULL, trap_SoundIndex( S_ANNOUNCER_OVERTIME_GOING_TO_OVERTIME ), GS_MAX_TEAMS, true, NULL );
				else
					G_AnnouncerSound( NULL, trap_SoundIndex( S_ANNOUNCER_OVERTIME_OVERTIME ), GS_MAX_TEAMS, true, NULL );

				G_PrintMsg( NULL, "Match tied. Timelimit extended by %i minutes!\n", g_match_extendedtime->integer );
				G_CenterPrintMsg( NULL, "%i MINUTE OVERTIME\n", g_match_extendedtime->integer );
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = (unsigned int)( ( fabs( g_match_extendedtime->value ) * 60 ) * 1000 );
			}
			else
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_OVERTIME_SUDDENDEATH_1_to_2, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, true, NULL );
				G_PrintMsg( NULL, "Match tied. Sudden death!\n" );
				G_CenterPrintMsg( NULL, "SUDDEN DEATH\n" );
				gs.gameState.longstats[GAMELONG_MATCHDURATION] = 0;
			}

			return true;
		}
	}

	return false;
}
Example #7
0
static void SP_target_print_print( edict_t *self, edict_t *activator )
{
	if( self->spawnflags & 8 ) {
		G_SetPlayerHelpMessage( activator, 0 );
		return;
	}

	if( self->mapmessage_index && self->mapmessage_index <= MAX_HELPMESSAGES ) {
		G_SetPlayerHelpMessage( activator, self->mapmessage_index );
	}
	else if( self->message && self->message[0] ) {
		G_CenterPrintMsg( activator, self->message );
	}
}
Example #8
0
static void SP_target_print_use( edict_t *self, edict_t *other, edict_t *activator )
{
	int n;
	edict_t *player;

	if( activator->r.client && ( self->spawnflags & 4 ) )
	{
		G_CenterPrintMsg( activator, self->message );
		return;
	}

	// print to team
	if( activator->r.client && self->spawnflags & 3 )
	{
		edict_t *e;
		for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
		{
			if( e->r.inuse && e->s.team )
			{
				if( self->spawnflags & 1 && e->s.team == activator->s.team )
					G_CenterPrintMsg( e, self->message );
				if( self->spawnflags & 2 && e->s.team != activator->s.team )
					G_CenterPrintMsg( e, self->message );
			}
		}
		return;
	}

	for( n = 1; n <= gs.maxclients; n++ )
	{
		player = &game.edicts[n];
		if( !player->r.inuse )
			continue;

		G_CenterPrintMsg( player, self->message );
	}
}
Example #9
0
/*
* G_CheckEvenTeam
*/
static void G_CheckEvenTeam( void )
{
	int max = 0;
	int min = gs.maxclients + 1;
	int uneven_team = TEAM_SPECTATOR;
	int i;

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
		return;

	if( !GS_TeamBasedGametype() )
		return;

	if( g_teams_allow_uneven->integer )
		return;

	for( i = TEAM_ALPHA; i < GS_MAX_TEAMS; i++ )
	{
		if( max < teamlist[i].numplayers )
		{
			max = teamlist[i].numplayers;
			uneven_team = i;
		}
		if( min > teamlist[i].numplayers )
			min = teamlist[i].numplayers;
	}

	if( max - min > 1 )
	{
		for( i = 0; i < teamlist[uneven_team].numplayers; i++ )
		{
			edict_t	*e = game.edicts + teamlist[uneven_team].playerIndices[i];
			if( !e->r.inuse )
				continue;
			G_CenterPrintMsg( e, "Teams are uneven. Please switch into another team." ); // FIXME: need more suitable message :P
			G_PrintMsg( e, "%sTeams are uneven. Please switch into another team.\n", S_COLOR_CYAN ); // FIXME: need more suitable message :P
		}
		// FIXME: switch team forcibly?
	}
}
Example #10
0
void G_Gametype_GENERIC_SetUpMatch( void )
{
	int i;

	level.gametype.readyAnnouncementEnabled = false;
	level.gametype.scoreAnnouncementEnabled = true;
	level.gametype.countdownEnabled = true;
	level.gametype.pickableItemsMask = ( level.gametype.spawnableItemsMask|level.gametype.dropableItemsMask );
	if( GS_Instagib() )
		level.gametype.pickableItemsMask &= ~G_INSTAGIB_NEGATE_ITEMMASK;

	// clear player stats and scores, team scores and respawn clients in team lists
	for( i = TEAM_PLAYERS; i < GS_MAX_TEAMS; i++ )
	{
		int j;
		g_teamlist_t *team = &teamlist[i];
		memset( &team->stats, 0, sizeof( team->stats ) );

		// respawn all clients inside the playing teams
		for( j = 0; j < team->numplayers; j++ )
		{
			edict_t *ent = &game.edicts[ team->playerIndices[j] ];
			G_ClientClearStats( ent );
			G_ClientRespawn( ent, false );
		}
	}

	// set items to be spawned with a delay
	G_Items_RespawnByType( IT_ARMOR, ARMOR_RA, 15 );
	G_Items_RespawnByType( IT_ARMOR, ARMOR_RA, 15 );
	G_Items_RespawnByType( IT_HEALTH, HEALTH_MEGA, 15 );
	G_Items_RespawnByType( IT_HEALTH, HEALTH_ULTRA, 15 );
	G_Items_RespawnByType( IT_POWERUP, 0, brandom( 20, 40 ) );
	G_Match_FreeBodyQueue();

	G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_FIGHT_1_to_2, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, false, NULL );
	G_CenterPrintMsg( NULL, "FIGHT!" );
}
Example #11
0
/*
* G_Match_CheckStateAbort
*/
static void G_Match_CheckStateAbort( void )
{
	bool any = false;
	bool enough;

	if( GS_MatchState() <= MATCH_STATE_NONE || GS_MatchState() >= MATCH_STATE_POSTMATCH
		|| level.gametype.mathAbortDisabled )
	{
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false );
		return;
	}

	if( GS_TeamBasedGametype() )
	{
		int team, emptyteams = 0;

		for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
		{
			if( !teamlist[team].numplayers )
				emptyteams++;
			else
				any = true;
		}

		enough = ( emptyteams == 0 );
	}
	else
	{
		enough = ( teamlist[TEAM_PLAYERS].numplayers > 1 );
		any = ( teamlist[TEAM_PLAYERS].numplayers > 0 );
	}

	// if waiting, turn on match states when enough players joined
	if( GS_MatchWaiting() && enough )
	{
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false );
		G_UpdatePlayersMatchMsgs();
	}
	// turn off active match states if not enough players left
	else if( GS_MatchState() == MATCH_STATE_WARMUP && !enough && GS_MatchDuration() )
	{
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, true );
		G_UpdatePlayersMatchMsgs();
	}
	else if( GS_MatchState() == MATCH_STATE_COUNTDOWN && !enough )
	{
		if( any ) {
			G_PrintMsg( NULL, "Not enough players left. Countdown aborted.\n" );
			G_CenterPrintMsg( NULL, "COUNTDOWN ABORTED" );
		}
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, true );
		G_UpdatePlayersMatchMsgs();
	}
	// match running, but not enough players left
	else if( GS_MatchState() == MATCH_STATE_PLAYTIME && !enough )
	{
		if( any ) {
			G_PrintMsg( NULL, "Not enough players left. Match aborted.\n" );
			G_CenterPrintMsg( NULL, "MATCH ABORTED" );
		}
		G_EndMatch();
	}
}
Example #12
0
/*
* G_Match_CheckReadys
*/
void G_Match_CheckReadys( void )
{
	edict_t *e;
	bool allready;
	int readys, notreadys, teamsready;
	int team, i;

	if( GS_MatchState() != MATCH_STATE_WARMUP && GS_MatchState() != MATCH_STATE_COUNTDOWN )
		return;

	if( GS_MatchState() == MATCH_STATE_COUNTDOWN && level.forceStart )
		return; // never stop countdown if we have run out of warmup_timelimit

	teamsready = 0;
	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
	{
		readys = notreadys = 0;
		for( i = 0; i < teamlist[team].numplayers; i++ )
		{
			e = game.edicts + teamlist[team].playerIndices[i];

			if( !e->r.inuse )
				continue;
			if( e->s.team == TEAM_SPECTATOR )  //ignore spectators
				continue;

			if( level.ready[PLAYERNUM( e )] )
				readys++;
			else
				notreadys++;
		}
		if( !notreadys && readys )
			teamsready++;
	}

	// everyone has commited
	if( GS_TeamBasedGametype() )
	{
		if( teamsready == GS_MAX_TEAMS - TEAM_ALPHA )
			allready = true;
		else
			allready = false;
	}
	else
	{       //ffa
		if( teamsready && teamlist[TEAM_PLAYERS].numplayers > 1 )
			allready = true;
		else
			allready = false;
	}

	if( allready == true && GS_MatchState() != MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( NULL, "All players are ready.  Match starting!\n" );
		G_Match_LaunchState( MATCH_STATE_COUNTDOWN );
	}
	else if( allready == false && GS_MatchState() == MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( NULL, "Countdown aborted.\n" );
		G_CenterPrintMsg( NULL, "COUNTDOWN ABORTED" );
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
	}
}
Example #13
0
/*
* G_ChasePlayer
*/
void G_ChasePlayer( edict_t *ent, const char *name, bool teamonly, int followmode )
{
	int i;
	edict_t *e;
	gclient_t *client;
	int targetNum = -1;
	int oldTarget;
	bool can_follow = true;
	char colorlessname[MAX_NAME_BYTES];

	client = ent->r.client;

	oldTarget = client->resp.chase.target;

	if( teamonly && !client->teamstate.is_coach )
		can_follow = false;

	if( !can_follow && followmode )
	{
		G_PrintMsg( ent, "Chasecam follow mode unavailable\n" );
		followmode = false;
	}

	if( ent->r.client->resp.chase.followmode && !followmode )
		G_PrintMsg( ent, "Disabling chasecam follow mode\n" );

	// always disable chasing as a start
	memset( &client->resp.chase, 0, sizeof( chasecam_t ) );

	// locate the requested target
	if( name && name[0] )
	{
		// find it by player names
		for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
		{
			if( !G_Chase_IsValidTarget( ent, e, teamonly ) )
				continue;

			Q_strncpyz( colorlessname, COM_RemoveColorTokens( e->r.client->netname ), sizeof(colorlessname) );

			if( !Q_stricmp( COM_RemoveColorTokens( name ), colorlessname ) )
			{
				targetNum = PLAYERNUM( e );
				break;
			}
		}

		// didn't find it by name, try by numbers
		if( targetNum == -1 )
		{
			i = atoi( name );
			if( i >= 0 && i < gs.maxclients )
			{
				e = game.edicts + 1 + i;
				if( G_Chase_IsValidTarget( ent, e, teamonly ) )
					targetNum = PLAYERNUM( e );
			}
		}

		if( targetNum == -1 )
			G_PrintMsg( ent, "Requested chasecam target is not available\n" );
	}

	// try to reuse old target if we didn't find a valid one
	if( targetNum == -1 && oldTarget > 0 && oldTarget < gs.maxclients )
	{
		e = game.edicts + 1 + oldTarget;
		if( G_Chase_IsValidTarget( ent, e, teamonly ) )
			targetNum = PLAYERNUM( e );
	}

	// if we still don't have a target, just pick the first valid one
	if( targetNum == -1 )
	{
		for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
		{
			if( !G_Chase_IsValidTarget( ent, e, teamonly ) )
				continue;

			targetNum = PLAYERNUM( e );
			break;
		}
	}

	// make the client a ghost
	G_GhostClient( ent );
	if( targetNum != -1 )
	{
		// we found a target, set up the chasecam
		client->resp.chase.target = targetNum + 1;
		client->resp.chase.teamonly = teamonly;
		client->resp.chase.followmode = followmode;
		G_Chase_SetChaseActive( ent, true );
	}
	else
	{
		// stay as observer
		if( !teamonly )
			ent->movetype = MOVETYPE_NOCLIP;
		client->level.showscores = false;
		G_Chase_SetChaseActive( ent, false );
		G_CenterPrintMsg( ent, "No one to chase" );
	}
}
Example #14
0
/*
* G_Timeout_Update
* 
* Updates the timeout struct and informs clients about the status of the pause
*/
static void G_Timeout_Update( unsigned int msec )
{
	static int timeout_printtime = 0;
	static int timeout_last_endtime = 0;
	static int countdown_set = 1;

	if( !GS_MatchPaused() )
		return;

	game.frametime = 0;

	if( timeout_last_endtime != level.timeout.endtime ) // force print when endtime is changed
	{
		timeout_printtime = 0;
		timeout_last_endtime = level.timeout.endtime;
	}

	level.timeout.time += msec;
	if( level.timeout.endtime && level.timeout.time >= level.timeout.endtime )
	{
		level.timeout.time = 0;
		level.timeout.caller = -1;
		GS_GamestatSetFlag( GAMESTAT_FLAG_PAUSED, false );

		timeout_printtime = 0;
		timeout_last_endtime = -1;

		G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, ( rand()&1 )+1 ) ),
			GS_MAX_TEAMS, true, NULL );
		G_CenterPrintMsg( NULL, "Match resumed" );
		G_PrintMsg( NULL, "Match resumed\n" );
	}
	else if( timeout_printtime == 0 || level.timeout.time - timeout_printtime >= 1000 )
	{
		if( level.timeout.endtime )
		{
			int seconds_left = (int)( ( level.timeout.endtime - level.timeout.time ) / 1000.0 + 0.5 );

			if( seconds_left == ( TIMEIN_TIME * 2 ) / 1000 )
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, ( rand()&1 )+1 ) ),
					GS_MAX_TEAMS, false, NULL );
				countdown_set = ( rand()&1 )+1;
			}
			else if( seconds_left >= 1 && seconds_left <= 3 )
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, seconds_left,
					countdown_set ) ), GS_MAX_TEAMS, false, NULL );
			}

			if( seconds_left > 1 )
				G_CenterPrintFormatMsg( NULL, "Match will resume in %s seconds", va( "%i", seconds_left ), NULL );
			else
				G_CenterPrintMsg( NULL, "Match will resume in 1 second" );
		}
		else
		{
			G_CenterPrintMsg( NULL, "Match paused" );
		}

		timeout_printtime = level.timeout.time;
	}
}