Exemple #1
0
void G_PlayerAward( edict_t *ent, const char *awardMsg )
{
	edict_t *other;
	char cmd[MAX_STRING_CHARS];
	gameaward_t *ga;
	int i, size;
	score_stats_t *stats;

	if( !awardMsg || !awardMsg[0] || !ent->r.client )
		return;

	Q_snprintfz( cmd, sizeof( cmd ), "aw \"%s\"", awardMsg );
	trap_GameCmd( ent, cmd );

	if( dedicated->integer )
		G_Printf( "%s", COM_RemoveColorTokens( va( "%s receives a '%s' award.\n", ent->r.client->netname, awardMsg ) ) );

	ent->r.client->level.stats.awards++;
	teamlist[ent->s.team].stats.awards++;
	G_Gametype_ScoreEvent( ent->r.client, "award", awardMsg );

	stats = &ent->r.client->level.stats;
	if( !stats->awardAllocator )
		stats->awardAllocator = LinearAllocator( sizeof( gameaward_t ), 0, _G_LevelMalloc, _G_LevelFree );

	// ch : this doesnt work for race right?
	if( GS_MatchState() == MATCH_STATE_PLAYTIME || GS_MatchState() == MATCH_STATE_POSTMATCH )
	{
		// ch : we store this locally to send to MM
		// first check if we already have this one on the clients list
		size = LA_Size( stats->awardAllocator );
		ga = NULL;
		for( i = 0; i < size; i++ )
		{
			ga = ( gameaward_t * )LA_Pointer( stats->awardAllocator, i );
			if( !strncmp( ga->name, awardMsg, sizeof(ga->name)-1 ) )
				break;
		}

		if( i >= size )
		{
			ga = ( gameaward_t * )LA_Alloc( stats->awardAllocator );
			memset( ga, 0, sizeof(*ga) );
			ga->name = G_RegisterLevelString( awardMsg );
		}

		if( ga )
			ga->count++;
	}

	// add it to every player who's chasing this player
	for( other = game.edicts + 1; PLAYERNUM( other ) < gs.maxclients; other++ )
	{
		if( !other->r.client || !other->r.inuse || !other->r.client->resp.chase.active )
			continue;

		if( other->r.client->resp.chase.target == ENTNUM( ent ) )
			trap_GameCmd( other, cmd );
	}
}
/*
* G_Match_NotReady
*/
void G_Match_NotReady( edict_t *ent )
{
	if( ent->s.team == TEAM_SPECTATOR )
	{
		G_PrintMsg( ent, "Join the game first\n" );
		return;
	}

	if( GS_MatchState() != MATCH_STATE_WARMUP && GS_MatchState() != MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( ent, "A match is not being setup.\n" );
		return;
	}

	if( !level.ready[PLAYERNUM( ent )] )
	{
		G_PrintMsg( ent, "You weren't ready.\n" );
		return;
	}

	level.ready[PLAYERNUM( ent )] = false;

	G_PrintMsg( NULL, "%s%s is no longer ready.\n", ent->r.client->netname, S_COLOR_WHITE );

	G_UpdatePlayerMatchMsg( ent );

	G_Match_CheckReadys();
}
static void G_Gametype_GENERIC_ThinkRules( void )
{
	if( G_Match_ScorelimitHit() || G_Match_TimelimitHit() || G_Match_SuddenDeathFinished() )
		G_Match_LaunchState( GS_MatchState() + 1 );

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
		return;
}
Exemple #4
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_CenterPrintFormatMsg( NULL, "Waiting... %s", va( "%i", lasttime ), NULL );
		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 );
	}
}
static bool G_Gametype_GENERIC_MatchStateFinished( int incomingMatchState )
{
	if( GS_MatchState() <= MATCH_STATE_WARMUP && incomingMatchState > MATCH_STATE_WARMUP
		&& incomingMatchState < MATCH_STATE_POSTMATCH )
		G_Match_Autorecord_Start();

	if( GS_MatchState() == MATCH_STATE_POSTMATCH )
		G_Match_Autorecord_Stop();

	return true;
}
Exemple #6
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;
}
Exemple #7
0
/*
* ClientDisconnect
* Called when a player drops from the server.
* Will not be called between levels.
*/
void ClientDisconnect( edict_t *ent, const char *reason )
{
	int team;

	if( !ent->r.client || !ent->r.inuse )
		return;

	// always report in RACE mode
	if( GS_RaceGametype() 
		|| ( ent->r.client->team != TEAM_SPECTATOR && ( GS_MatchState() == MATCH_STATE_PLAYTIME || GS_MatchState() == MATCH_STATE_POSTMATCH ) ) )
		G_AddPlayerReport( ent, GS_MatchState() == MATCH_STATE_POSTMATCH );

	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
		G_Teams_UnInvitePlayer( team, ent );

	if( !level.gametype.disableObituaries || !(ent->r.svflags & SVF_FAKECLIENT ) )
	{
		if( !reason )
			G_PrintMsg( NULL, "%s" S_COLOR_WHITE " disconnected\n", ent->r.client->netname );
		else
			G_PrintMsg( NULL, "%s" S_COLOR_WHITE " disconnected (%s" S_COLOR_WHITE ")\n", ent->r.client->netname, reason );
	}

	// send effect
	if( ent->s.team > TEAM_SPECTATOR )
		G_TeleportEffect( ent, false );

	ent->r.client->team = TEAM_SPECTATOR;
	G_ClientRespawn( ent, true ); // respawn as ghost
	ent->movetype = MOVETYPE_NOCLIP; // allow freefly

	// let the gametype scripts know this client just disconnected
	G_Gametype_ScoreEvent( ent->r.client, "disconnect", NULL );

	G_FreeAI( ent );
	AI_EnemyRemoved( ent );

	ent->r.inuse = false;
	ent->r.svflags = SVF_NOCLIENT;

	memset( ent->r.client, 0, sizeof( *ent->r.client ) );
	ent->r.client->ps.playerNum = PLAYERNUM( ent );

	trap_ConfigString( CS_PLAYERINFOS+PLAYERNUM( ent ), "" );
	GClip_UnlinkEntity( ent );

	G_Match_CheckReadys();
}
Exemple #8
0
/*
* Cmd_Say_f
*/
void Cmd_Say_f( edict_t *ent, bool arg0, bool checkflood )
{
	char *p;
	char text[2048];
	size_t arg0len = 0;

#ifdef AUTHED_SAY
	if( sv_mm_enable->integer && ent->r.client && ent->r.client->mm_session <= 0 )
	{
		// unauthed players are only allowed to chat to public at non play-time
		if( GS_MatchState() == MATCH_STATE_PLAYTIME )
		{
			G_PrintMsg( ent, "%s", S_COLOR_YELLOW "You must authenticate to be able to communicate to other players during the match.\n");
			return;
		}
	}
#endif

	if( checkflood )
	{
		if( CheckFlood( ent, false ) )
			return;
	}

	if( ent->r.client && ( ent->r.client->muted & 1 ) )
		return;

	if( trap_Cmd_Argc() < 2 && !arg0 )
		return;

	text[0] = 0;

	if( arg0 )
	{
		Q_strncatz( text, trap_Cmd_Argv( 0 ), sizeof( text ) );
		Q_strncatz( text, " ", sizeof( text ) );
		arg0len = strlen( text );
		Q_strncatz( text, trap_Cmd_Args(), sizeof( text ) );
	}
	else
	{
		p = trap_Cmd_Args();

		if( *p == '"' )
		{
			if( p[strlen( p )-1] == '"' )
				p[strlen( p )-1] = 0;
			p++;
		}
		Q_strncatz( text, p, sizeof( text ) );
	}

	// don't let text be too long for malicious reasons
	text[arg0len + (MAX_CHAT_BYTES - 1)] = 0;

	if( !Q_stricmp( text, "gg" ) || !Q_stricmp( text, "good game" ) )
		G_AwardFairPlay( ent );

	G_ChatMsg( NULL, ent, false, "%s", text );
}
Exemple #9
0
void SetRespawn( edict_t *ent, int delay )
{
	if( !ent->item )
		return;

	if( delay < 0 )
	{
		G_FreeEdict( ent );
		return;
	}

	ent->r.solid = SOLID_NOT;
	ent->nextThink = level.time + delay;
	ent->think = DoRespawn;
	if( GS_MatchState() == MATCH_STATE_WARMUP ) {
		ent->s.effects |= EF_GHOST;
	}
	else {
		ent->r.svflags |= SVF_NOCLIENT;
	}

	// megahealth is different
	if( ( ent->spawnflags & ITEM_TIMED ) && ent->r.owner )
	{
		if( ent->item->type == IT_HEALTH )
		{
			ent->think = MegaHealth_think;
			ent->nextThink = level.time + 1;
		}
	}

	GClip_LinkEntity( ent );
}
Exemple #10
0
void G_AwardFairPlay( edict_t *ent )
{
	// only award during postmatch
	if( GS_MatchState() != MATCH_STATE_POSTMATCH ) {
		return;
	}
	if( level.finalMatchDuration <= SIGNIFICANT_MATCH_DURATION ) {
		return;
	}

	gclient_t *client = ent->r.client;
	// don't try to give the award to the server console
	if( !client ) {
		return;
	}

	// already awarded
	if( client->resp.awardInfo.fairplay_award ) {
		return;
	}

	// the player must not be muted during the match
	if( client->level.stats.muted_count > 0 ) {
		return;
	}

	// has he actually played?
	if( !client->level.stats.had_playtime ) {
		return;
	}

	client->level.stats.fairplay_count++;
	client->resp.awardInfo.fairplay_award = true;
	G_PlayerAward( ent, S_COLOR_CYAN "Fair Play!" );
}
Exemple #11
0
/*
* G_Teams_SetTeam - sets clients team without any checking
*/
void G_Teams_SetTeam( edict_t *ent, int team )
{
	assert( ent && ent->r.inuse && ent->r.client );
	assert( team >= TEAM_SPECTATOR && team < GS_MAX_TEAMS );

	// if player was on a team, send partial report to matchmaker
	if( ent->r.client->team != TEAM_SPECTATOR && ent->r.client->team != team && GS_MatchState() == MATCH_STATE_PLAYTIME )
	{
		G_Printf("Sending teamchange to MM, team %d to team %d\n", ent->r.client->team, team );
		G_AddPlayerReport( ent, false );
		// trap_MR_SendPartialReport();
	}

	// clear scores at changing team
	memset( &ent->r.client->level.stats, 0, sizeof( ent->r.client->level.stats ) );

	memset( &ent->r.client->teamstate, 0, sizeof( ent->r.client->teamstate ) );
	ent->r.client->team = team;
	ent->r.client->teamstate.timeStamp = level.time;
	G_Teams_UnInvitePlayer( team, ent );

	G_ClientRespawn( ent, true ); // make ghost using G_ClientRespawn so team is updated at ghosting
	G_SpawnQueue_AddClient( ent );

	level.ready[PLAYERNUM( ent )] = false;

	G_Match_CheckReadys();
	G_UpdatePlayerMatchMsg( ent );
}
/*
* G_Match_ScorelimitHit
*/
bool G_Match_ScorelimitHit( void )
{
	edict_t	*e;

	if( GS_MatchState() != MATCH_STATE_PLAYTIME )
		return false;

	if( g_scorelimit->integer )
	{
		if( !GS_TeamBasedGametype() )
		{
			for( e = game.edicts+1; PLAYERNUM( e ) < gs.maxclients; e++ )
			{
				if( !e->r.inuse )
					continue;

				if( e->r.client->level.stats.score >= g_scorelimit->integer )
					return true;
			}
		}
		else
		{
			int team;

			for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
			{
				if( teamlist[team].stats.score >= g_scorelimit->integer )
					return true;
			}
		}
	}

	return false;
}
/*
* G_Match_Ready
*/
void G_Match_Ready( edict_t *ent )
{
	if( ent->r.svflags & SVF_FAKECLIENT && level.ready[PLAYERNUM( ent )] == true )
		return;

	if( ent->s.team == TEAM_SPECTATOR )
	{
		G_PrintMsg( ent, "Join the game first\n" );
		return;
	}

	if( GS_MatchState() != MATCH_STATE_WARMUP )
	{
		if( !( ent->r.svflags & SVF_FAKECLIENT ) )
			G_PrintMsg( ent, "We're not in warmup.\n" );
		return;
	}

	if( level.ready[PLAYERNUM( ent )] )
	{
		G_PrintMsg( ent, "You are already ready.\n" );
		return;
	}

	level.ready[PLAYERNUM( ent )] = true;

	G_PrintMsg( NULL, "%s%s is ready!\n", ent->r.client->netname, S_COLOR_WHITE );

	G_UpdatePlayerMatchMsg( ent );

	G_Match_CheckReadys();
}
/*
* G_Match_TimelimitHit
*/
bool G_Match_TimelimitHit( void )
{
	// check for timelimit hit
	if( !GS_MatchDuration() || game.serverTime < GS_MatchEndTime() )
		return false;

	if( GS_MatchState() == MATCH_STATE_WARMUP )
		level.forceStart = true; // force match starting when timelimit is up, even if someone goes unready

	if( GS_MatchState() == MATCH_STATE_WAITEXIT )
	{
		level.exitNow = true;
		return false; // don't advance into next state. The match will be restarted
	}

	return true;
}
Exemple #15
0
/*
* G_ClientEndSnapFrame
* 
* Called for each player at the end of the server frame
* and right after spawning
*/
void G_ClientEndSnapFrame( edict_t *ent )
{
	gclient_t *client;
	int i;

	if( trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
		return;

	client = ent->r.client;

	// set fov
	if( !client->ps.pmove.stats[PM_STAT_ZOOMTIME] )
		client->ps.fov = ent->r.client->fov;
	else
	{
		float frac = (float)client->ps.pmove.stats[PM_STAT_ZOOMTIME] / (float)ZOOMTIME;
		client->ps.fov = client->fov - ( (float)( client->fov - client->zoomfov ) * frac );
	}

	// If the end of unit layout is displayed, don't give
	// the player any normal movement attributes
	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
	{
		G_SetClientStats( ent );
	}
	else
	{
		if( G_IsDead( ent ) && !level.gametype.customDeadBodyCam )
		{
			G_Client_DeadView( ent );
		}

		G_PlayerWorldEffects( ent ); // burn from lava, etc
		G_ClientDamageFeedback( ent ); // show damage taken along the snap
		G_SetClientStats( ent );
		G_SetClientEffects( ent );
		G_SetClientSound( ent );
		G_SetClientFrame( ent );

		client->ps.plrkeys = client->resp.snap.plrkeys;
	}

	G_ReleaseClientPSEvent( client );

	// set the delta angle
	for( i = 0; i < 3; i++ )
		client->ps.pmove.delta_angles[i] = ANGLE2SHORT( client->ps.viewangles[i] ) - client->ucmd.angles[i];

	// this is pretty hackish. We exploit the fact that servers *do not* transmit
	// origin2/old_origin for ET_PLAYER/ET_CORPSE entities, and we use it for sending the player velocity
	if( !G_ISGHOSTING( ent ) )
	{
		ent->r.svflags |= SVF_TRANSMITORIGIN2;
		VectorCopy( ent->velocity, ent->s.origin2 );
	}
	else
		ent->r.svflags &= ~SVF_TRANSMITORIGIN2;
}
void G_Gametype_GENERIC_ClientRespawn( edict_t *self, int old_team, int new_team )
{
	int i;
	gclient_t *client = self->r.client;
	gs_weapon_definition_t *weapondef;

	if( G_ISGHOSTING( self ) )
		return;

	//give default items
	if( self->s.team != TEAM_SPECTATOR )
	{
		if( GS_Instagib() )
		{
			client->ps.inventory[WEAP_INSTAGUN] = 1;
			client->ps.inventory[AMMO_INSTAS] = 1;
			client->ps.inventory[AMMO_WEAK_INSTAS] = 1;
		}
		else
		{
			if( GS_MatchState() <= MATCH_STATE_WARMUP )
			{
				for( i = WEAP_GUNBLADE; i < WEAP_TOTAL; i++ )
				{
					if( i == WEAP_INSTAGUN )  // dont add instagun...
						continue;

					weapondef = GS_GetWeaponDef( i );
					client->ps.inventory[i] = 1;
					if( weapondef->firedef_weak.ammo_id )
						client->ps.inventory[weapondef->firedef_weak.ammo_id] = weapondef->firedef_weak.ammo_max;
					if( weapondef->firedef.ammo_id )
						client->ps.inventory[weapondef->firedef.ammo_id] = weapondef->firedef.ammo_max;
				}

				client->resp.armor = GS_Armor_MaxCountForTag( ARMOR_YA );
			}
			else
			{
				weapondef = GS_GetWeaponDef( WEAP_GUNBLADE );
				client->ps.inventory[WEAP_GUNBLADE] = 1;
				client->ps.inventory[AMMO_GUNBLADE] = weapondef->firedef.ammo_max;;
				client->ps.inventory[AMMO_WEAK_GUNBLADE] = 0;
			}
		}
	}

	// select rocket launcher if available
	if( GS_CheckAmmoInWeapon( &client->ps, WEAP_ROCKETLAUNCHER ) )
		client->ps.stats[STAT_PENDING_WEAPON] = WEAP_ROCKETLAUNCHER;
	else
		client->ps.stats[STAT_PENDING_WEAPON] = GS_SelectBestWeapon( &client->ps );

	// add a teleportation effect
	if( self->r.solid != SOLID_NOT )
		G_RespawnEffect( self );
}
Exemple #17
0
/*
* G_GameTypes_DenyJoinTeam
*/
static int G_GameTypes_DenyJoinTeam( edict_t *ent, int team )
{
	if( team < 0 || team >= GS_MAX_TEAMS )
	{
		G_Printf( "WARNING: 'G_GameTypes_CanJoinTeam' parsing a unrecognized team value\n" );
		return ER_TEAM_INVALID;
	}

	if( team == TEAM_SPECTATOR )
		return ER_TEAM_OK;

	if( GS_MatchState() > MATCH_STATE_PLAYTIME )
		return ER_TEAM_MATCHSTATE;

	// waiting for chanllengers queue to be executed
	if( GS_HasChallengers() &&
		game.realtime < level.spawnedTimeStamp + (unsigned)( G_CHALLENGERS_MIN_JOINTEAM_MAPTIME + game.snapFrameTime ) )
		return ER_TEAM_CHALLENGERS;

	// force eveyone to go through queue so things work on map change
	if( GS_HasChallengers() && !ent->r.client->queueTimeStamp )
		return ER_TEAM_CHALLENGERS;

	//see if team is locked
	if( G_Teams_TeamIsLocked( team ) && !G_Teams_PlayerIsInvited( team, ent ) )
		return ER_TEAM_LOCKED;

	if( GS_TeamBasedGametype() )
	{
		if( team >= TEAM_ALPHA && team < GS_MAX_TEAMS )
		{
			// see if team is full
			int count = teamlist[team].numplayers;

			if( ( count + 1 > level.gametype.maxPlayersPerTeam &&
				level.gametype.maxPlayersPerTeam > 0 ) ||
				( count + 1 > g_teams_maxplayers->integer &&
				g_teams_maxplayers->integer > 0 ) )
				return ER_TEAM_FULL;

			if( !g_teams_allow_uneven->integer && !G_Teams_CanKeepEvenTeam( ent->s.team, team ) )
				return ER_TEAM_UNEVEN;

			return ER_TEAM_OK;
		}
		else
		{
			return ER_TEAM_INVALID;
		}
	}
	else if( team == TEAM_PLAYERS )
	{
		return ER_TEAM_OK;
	}

	return ER_TEAM_INVALID;
}
Exemple #18
0
/*
* SelectSpawnPoint
* 
* Chooses a player start, deathmatch start, etc
*/
void SelectSpawnPoint( edict_t *ent, edict_t **spawnpoint, vec3_t origin, vec3_t angles )
{
	edict_t	*spot = NULL;

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
	{
		spot = G_SelectIntermissionSpawnPoint();
	}
	else 
	{
		if( game.asEngine != NULL )
			spot = GT_asCallSelectSpawnPoint( ent );

		if( !spot )
			spot = SelectDeathmatchSpawnPoint( ent );
	}

	// find a single player start spot
	if( !spot )
	{
		spot = G_Find( spot, FOFS( classname ), "info_player_start" );
		if( !spot )
		{
			spot = G_Find( spot, FOFS( classname ), "team_CTF_alphaspawn" );
			if( !spot )
				spot = G_Find( spot, FOFS( classname ), "team_CTF_betaspawn" );
			if( !spot )
				spot = world;
		}
	}

	*spawnpoint = spot;
	VectorCopy( spot->s.origin, origin );
	VectorCopy( spot->s.angles, angles );

	if( !Q_stricmp( spot->classname, "info_player_intermission" ) )
	{
		// if it has a target, look towards it
		if( spot->target )
		{
			vec3_t dir;
			edict_t *target;

			target = G_PickTarget( spot->target );
			if( target )
			{
				VectorSubtract( target->s.origin, origin, dir );
				VecToAngles( dir, angles );
			}
		}
	}

	// SPAWN TELEFRAGGING PROTECTION.
	if( ent->r.solid == SOLID_YES && ( level.gametype.spawnpointRadius > ( playerbox_stand_maxs[0] - playerbox_stand_mins[0] ) ) )
		G_OffsetSpawnPoint( origin, playerbox_stand_mins, playerbox_stand_maxs, level.gametype.spawnpointRadius, 
			!( spot->spawnflags & 1 ) ? true : false );
}
Exemple #19
0
void Bot::ActiveFrame()
{
    //get ready if in the game
    if(GS_MatchState() <= MATCH_STATE_WARMUP && !IsReady() && self->r.client->teamstate.timeStamp + 4000 < level.time)
        G_Match_Ready(self);

    ApplyPendingTurnToLookAtPoint();

    const CombatTask &combatTask = botBrain.combatTask;

    bool inhibitShooting, inhibitCombatMove;
    SetCombatInhibitionFlags(&inhibitShooting, &inhibitCombatMove);

    // ucmd modification in FireWeapon() will be overwritten by MoveFrame()
    bool fireButtonPressed = false;
    if (!inhibitShooting)
    {
        SetCloakEnabled(false);
        // If bot fired builtin or script weapon, save builtin fire button status
        FireWeapon(&fireButtonPressed);
    }
    else
    {
        if (!combatTask.Empty())
        {
            SetCloakEnabled(true);
        }
        else if (botBrain.HasGoal())
        {
            if (botBrain.IsCloseToAnyGoal(768.0f, true))
                SetCloakEnabled(true);
            else if (botBrain.IsCloseToAnyGoal(384.0f, false))
                SetCloakEnabled(true);
            else
                SetCloakEnabled(false);
        }
        else
        {
            SetCloakEnabled(false);
        }
    }

    bool beSilent = ShouldBeSilent(inhibitShooting);

    // Do not modify pmove features by beSilent value, features may be changed dynamically by script.
    usercmd_t ucmd;
    memset(&ucmd, 0, sizeof(ucmd));
    MoveFrame(&ucmd, inhibitCombatMove, beSilent);

    if (fireButtonPressed)
        ucmd.buttons |= BUTTON_ATTACK;

    CallActiveClientThink(&ucmd);

    SayVoiceMessages();
}
/*
* G_Match_SuddenDeathFinished
*/
bool G_Match_SuddenDeathFinished( void )
{
	if( GS_MatchState() != MATCH_STATE_PLAYTIME )
		return false;

	if( !GS_MatchExtended() || GS_MatchDuration() )
		return false;

	return G_Match_Tied() ? false : true;
}
Exemple #21
0
/*
* G_PlayerCanTeleport
*
* Checks if the player can be teleported.
*/
bool G_PlayerCanTeleport( edict_t *player )
{
	if ( !player->r.client )
		return false;
	if ( player->r.client->ps.pmove.pm_type > PM_SPECTATOR )
		return false;
	if ( GS_MatchState( ) == MATCH_STATE_COUNTDOWN ) // match countdown
		return false;
	return true;
}
Exemple #22
0
/**
 * Checks if the scoreboard column of the specific type needs to be skipped.
 *
 * @param type the column type
 * @return whether the column needs to be skipped
 */
static bool SCR_SkipColumn( char type )
{
	switch( type )
	{
	case 'r':
		return GS_MatchState() != MATCH_STATE_WARMUP;
	}

	return false;
}
Exemple #23
0
/*
* G_Killed
*/
void G_Killed( edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t point, int mod )
{
	if( targ->health < -999 )
		targ->health = -999;

	if( targ->deadflag == DEAD_DEAD )
		return;

	targ->deadflag = DEAD_DEAD;
	targ->enemy = attacker;

	if( targ->r.client )
	{
		if( attacker && targ != attacker )
		{
			if( GS_IsTeamDamage( &targ->s, &attacker->s ) )
				attacker->snap.teamkill = qtrue;
			else
				attacker->snap.kill = qtrue;
		}

		// count stats
		if( GS_MatchState() == MATCH_STATE_PLAYTIME )
		{
			targ->r.client->level.stats.deaths++;
			teamlist[targ->s.team].stats.deaths++;

			if( !attacker || !attacker->r.client || attacker == targ || attacker == world )
			{
				targ->r.client->level.stats.suicides++;
				teamlist[targ->s.team].stats.suicides++;
			}
			else
			{
				if( GS_IsTeamDamage( &targ->s, &attacker->s ) )
				{
					attacker->r.client->level.stats.teamfrags++;
					teamlist[attacker->s.team].stats.teamfrags++;
				}
				else
				{
					attacker->r.client->level.stats.frags++;
					teamlist[attacker->s.team].stats.frags++;
					G_AwardPlayerKilled( targ, inflictor, attacker, mod );
				}
			}
		}
	}

	G_Gametype_ScoreEvent( attacker ? attacker->r.client : NULL, "kill", va( "%i %i %i", targ->s.number, ( inflictor == world ) ? -1 : ENTNUM( inflictor ), ENTNUM( attacker ) ) );

	G_CallDie( targ, inflictor, attacker, damage, point );
}
Exemple #24
0
/*
* CG_IsScoreboardShown
*/
bool CG_IsScoreboardShown( void )
{
	if( !cgs.configStrings[CS_SCB_PLAYERTAB_LAYOUT][0] ) // no layout defined
		return false;

	if( scoreboardString[0] != '&' ) // nothing to draw
		return false;

	if( cgs.demoPlaying || cg.frame.multipov || cgs.tv )
		return cg.showScoreboard || ( GS_MatchState() > MATCH_STATE_PLAYTIME );

	return ( cg.predictedPlayerState.stats[STAT_LAYOUTS] & STAT_LAYOUT_SCOREBOARD ) ? true : false;
}
char *G_Gametype_GENERIC_ScoreboardMessage( void )
{
	char entry[MAX_TOKEN_CHARS];
	size_t len;
	int i;
	edict_t	*e;
	int carrierIcon;

	*scoreboardString = 0;
	len = 0;

	Q_snprintfz( entry, sizeof(entry), "&t %i 0 0 ", TEAM_PLAYERS );
	if( SCOREBOARD_MSG_MAXSIZE - len > strlen( entry ) )
	{
		Q_strncatz( scoreboardString, entry, sizeof( scoreboardString ) );
		len = strlen( scoreboardString );
	}

	// players
	for( i = 0; i < teamlist[TEAM_PLAYERS].numplayers; i++ )
	{
		e = game.edicts + teamlist[TEAM_PLAYERS].playerIndices[i];

		if( e->s.effects & EF_CARRIER )
			carrierIcon = trap_ImageIndex( ( e->s.team == TEAM_BETA ) ? PATH_ALPHAFLAG_ICON : PATH_BETAFLAG_ICON );
		else if( e->s.effects & EF_QUAD )
			carrierIcon = trap_ImageIndex( PATH_QUAD_ICON );
		else if( e->s.effects & EF_SHELL )
			carrierIcon = trap_ImageIndex( PATH_SHELL_ICON );
		else if( e->s.effects & EF_REGEN )
			carrierIcon = trap_ImageIndex( PATH_REGEN_ICON );
		else
			carrierIcon = 0;

		Q_snprintfz( entry, sizeof( entry ), "&p %i %i %i %i %i ",
			PLAYERNUM( e ),
			e->r.client->level.stats.score,
			e->r.client->r.ping > 999 ? 999 : e->r.client->r.ping,
			carrierIcon,
			( level.ready[PLAYERNUM( e )] || GS_MatchState() >= MATCH_STATE_PLAYTIME ) ? trap_ImageIndex( PATH_VSAY_YES_ICON ) : 0
			);

		if( SCOREBOARD_MSG_MAXSIZE - len > strlen( entry ) )
		{
			Q_strncatz( scoreboardString, entry, sizeof( scoreboardString ) );
			len = strlen( scoreboardString );
		}
	}

	return scoreboardString;
}
Exemple #26
0
/*
* G_SetClientEffects
*/
static void G_SetClientEffects( edict_t *ent )
{
	gclient_t *client = ent->r.client;

	if( G_IsDead( ent ) || GS_MatchState() >= MATCH_STATE_POSTMATCH )
		return;

	if( client->ps.inventory[POWERUP_QUAD] > 0 )
	{
		ent->s.effects |= EF_QUAD;
		if( client->ps.inventory[POWERUP_QUAD] < 6 )
			ent->s.effects |= EF_EXPIRING_QUAD;
	}

	if( client->ps.inventory[POWERUP_SHELL] > 0 )
	{
		ent->s.effects |= EF_SHELL;
		if( client->ps.inventory[POWERUP_SHELL] < 6 )
			ent->s.effects |= EF_EXPIRING_SHELL;			
	}

	if( client->ps.inventory[POWERUP_REGEN] > 0 )
	{
		ent->s.effects |= EF_REGEN;
		if( client->ps.inventory[POWERUP_REGEN] < 6 )
			ent->s.effects |= EF_EXPIRING_REGEN;			
	}

	if( ent->s.weapon )
	{
		firedef_t *firedef = GS_FiredefForPlayerState( &client->ps, ent->s.weapon );
		if( firedef && firedef->fire_mode == FIRE_MODE_STRONG )
			ent->s.effects |= EF_STRONG_WEAPON;
	}

	if( client->ps.pmove.stats[PM_STAT_STUN] )
		ent->s.effects |= EF_PLAYER_STUNNED;
	else
		ent->s.effects &= ~EF_PLAYER_STUNNED;

	// show cheaters!!!
	if( ent->flags & FL_GODMODE )
		ent->s.effects |= EF_GODMODE;

	// add chatting icon effect
	if( ent->r.client->resp.snap.buttons & BUTTON_BUSYICON )
		ent->s.effects |= EF_BUSYICON;
}
Exemple #27
0
/*
* G_Client_InactivityRemove
*/
void G_Client_InactivityRemove( gclient_t *client )
{
	if( !client )
		return;

	// racesow
	if( !level.gametype.autoInactivityRemove )
		return;
	// !racesow

	if( client->ps.pmove.pm_type != PM_NORMAL )
		return;

	if( g_inactivity_maxtime->modified )
	{
		if( g_inactivity_maxtime->value <= 0.0f )
			trap_Cvar_ForceSet( "g_inactivity_maxtime", "0.0" );
		else if( g_inactivity_maxtime->value < 15.0f )
			trap_Cvar_ForceSet( "g_inactivity_maxtime", "15.0" );

		g_inactivity_maxtime->modified = false;
	}

	if( g_inactivity_maxtime->value == 0.0f )
		return;

	if( ( GS_MatchState() != MATCH_STATE_PLAYTIME ) || !level.gametype.removeInactivePlayers )
		return;

	// inactive for too long
	if( client->level.last_activity && client->level.last_activity + ( g_inactivity_maxtime->value * 1000 ) < level.time )
	{
		if( client->team >= TEAM_PLAYERS && client->team < GS_MAX_TEAMS )
		{
			edict_t *ent = &game.edicts[ client - game.clients + 1 ];

			// move to spectators and reset the queue time, effectively removing from the challengers queue
			G_Teams_SetTeam( ent, TEAM_SPECTATOR );
			G_SpawnQueue_RemoveClient( ent ); // racesow - set player in free-view
			client->queueTimeStamp = 0;

			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " has been moved to spectator after %.1f seconds of inactivity\n", client->netname, g_inactivity_maxtime->value );
		}
	}
}
Exemple #28
0
void G_PlayerMetaAward( edict_t *ent, const char *awardMsg )
{
    int i, size;
    gameaward_t *ga;
    score_stats_t *stats;

    /*
    * ch : meta-award is an award that isn't announced but
    * it is sent to MM
    */

    if( !awardMsg || !awardMsg[0] || !ent->r.client )
        return;

    stats = &ent->r.client->level.stats;
    if( !stats->awardAllocator )
        stats->awardAllocator = LinearAllocator( sizeof( gameaward_t ), 0, _G_LevelMalloc, _G_LevelFree );

    // ch : this doesnt work for race right?
    if( GS_MatchState() == MATCH_STATE_PLAYTIME )
    {
        // ch : we store this locally to send to MM
        // first check if we already have this one on the clients list
        size = LA_Size( stats->awardAllocator );
        ga = NULL;
        for( i = 0; i < size; i++ )
        {
            ga = LA_Pointer( stats->awardAllocator, i );
            if( !strncmp( ga->name, awardMsg, sizeof(ga->name)-1 ) )
                break;
        }

        if( i >= size )
        {
            ga = LA_Alloc( stats->awardAllocator );
            memset( ga, 0, sizeof(*ga) );
            ga->name = G_RegisterLevelString( awardMsg );
        }

        if( ga )
            ga->count++;
    }
}
Exemple #29
0
void G_Teams_Coach( edict_t *ent )
{
	if( GS_TeamBasedGametype() && !GS_InvidualGameType() && ent->s.team != TEAM_SPECTATOR )
	{
		if( !teamlist[ent->s.team].has_coach )
		{
			if( GS_MatchState() > MATCH_STATE_WARMUP && !GS_MatchPaused() )
			{
				G_PrintMsg( ent, "Can't set coach mode with the match in progress\n" );
			}
			else
			{
				// move to coach mode
				ent->r.client->teamstate.is_coach = true;
				G_GhostClient( ent );
				ent->health = ent->max_health;
				ent->deadflag = DEAD_NO;

				G_ChasePlayer( ent, NULL, true, 0 );

				//clear up his scores
				G_Match_Ready( ent ); // set ready and check readys
				memset( &ent->r.client->level.stats, 0, sizeof( ent->r.client->level.stats ) );

				teamlist[ent->s.team].has_coach = true;
				G_PrintMsg( NULL, "%s%s is now team %s coach \n", ent->r.client->netname,
					S_COLOR_WHITE, GS_TeamName( ent->s.team ) );
			}
		}
		else if( ent->r.client->teamstate.is_coach )
		{                            // if you are this team coach, resign
			ent->r.client->teamstate.is_coach = false;
			G_PrintMsg( NULL, "%s%s is no longer team %s coach \n", ent->r.client->netname,
				S_COLOR_WHITE, GS_TeamName( ent->s.team ) );

			G_Teams_SetTeam( ent, ent->s.team );
		}
		else
			G_PrintMsg( ent, "Your team already has a coach.\n" );
	}
	else
		G_PrintMsg( ent, "Coaching only valid while on a team in Team based Gametypes.\n" );
}
static void G_Gametype_GENERIC_MatchStateStarted( void )
{
	switch( GS_MatchState() )
	{
//	case MATCH_STATE_WAITING:
	case MATCH_STATE_WARMUP:
		G_Gametype_GENERIC_SetUpWarmup();
		break;
	case MATCH_STATE_COUNTDOWN:
		G_Gametype_GENERIC_SetUpCountdown();
		break;
	case MATCH_STATE_PLAYTIME:
		G_Gametype_GENERIC_SetUpMatch();
		break;
	case MATCH_STATE_POSTMATCH:
		G_Gametype_GENERIC_SetUpEndMatch();
		break;
	default:
		break;
	}
}