ef2-sdk/dlls/game/mp_modeTeamBase.cpp
2003-11-05 00:00:00 +00:00

1164 lines
30 KiB
C++

//-----------------------------------------------------------------------------
//
// $Logfile:: /EF2/Code/DLLs/game/mp_modeTeamBase.cpp $
// $Revision:: 59 $
// $Author:: Singlis $
// $Date:: 9/26/03 2:36p $
//
// Copyright (C) 2002 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// Description:
//
#include "_pch_cpp.h"
#include "mp_manager.hpp"
#include "mp_modeBase.hpp"
#include "mp_modeTeamBase.hpp"
CLASS_DECLARATION( MultiplayerModeBase, ModeTeamBase, NULL )
{
{ NULL, NULL }
};
//-----------------------------------------------------------------
// T E A M A R E N A
//-----------------------------------------------------------------
//================================================================
// Name: ModeTeamBase
// Class: ModeTeamBase
//
// Description: Constructor
//
// Parameters: const str& -- name of the arena
//
// Returns: None
//
//================================================================
ModeTeamBase::ModeTeamBase()
{
_maxTeams = 2;
_leadTeam = NULL;
_useTeamSpawnpoints = false;
_redTeamIconIndex = gi.imageindex( "sysimg/icons/mp/team_red" );
_blueTeamIconIndex = gi.imageindex( "sysimg/icons/mp/team_blue" );
_redTeamHudIconIndex = gi.imageindex( "sysimg/icons/mp/team_red_hud" );
_blueTeamHudIconIndex = gi.imageindex( "sysimg/icons/mp/team_blue_hud" );
_redTeamSpectatorHudIconIndex = gi.imageindex( "sysimg/icons/mp/team_red_spectator" );
_blueTeamSpectatorHudIconIndex = gi.imageindex( "sysimg/icons/mp/team_blue_spectator" );
}
//================================================================
// Name: ~ModeTeamBase
// Class: ModeTeamBase
//
// Description: Destructor
//
// Parameters: None
//
// Returns: None
//
//================================================================
ModeTeamBase::~ModeTeamBase()
{
_deleteTeams();
}
void ModeTeamBase::init( int maxPlayers )
{
MultiplayerModeBase::init( maxPlayers );
multiplayerManager.cacheMultiplayerFiles( "mp_teamBase" );
}
//================================================================
// Name: isEndOfMatch
// Class: ModeTeamBase
//
// Description: Determines if either team has met the frag limit.
// If so, announces a winner (should the base team
// arena be so bold?).
//
// If there is no frag limit set, no check is made.
//
// Parameters: None
//
// Returns: bool -- true if the match has ended based on fraglimit
//
//================================================================
bool ModeTeamBase::isEndOfMatch( void )
{
if (!getPointLimit())
{
return false ;
}
for (int idx=1; idx <= _teamList.NumObjects(); idx++)
{
Team* team = _teamList.ObjectAt(idx);
if (team->getDeaths() > getPointLimit())
{
multiplayerManager.centerPrintAllClients(va("$$%s$$ $$TeamLoses$$\n", team->getName().c_str() ), CENTERPRINT_IMPORTANCE_NORMAL );
if ( team->getName() == "Red" )
multiplayerManager.broadcastSound( "localization/sound/dialog/dm/comp_redtlose.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, NULL, 1.5f );
else
multiplayerManager.broadcastSound( "localization/sound/dialog/dm/comp_bltlose.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, NULL, 1.5f );
return true ;
}
}
return false ;
}
//================================================================
// Name: AddPlayer
// Class: ModeTeamBase
//
// Description: Adds a player to the arena. If force join is on,
// this player will be force to join with the fewest
// players.
//
// Parameters: Player* -- player to add
//
// Returns: None
//
//================================================================
void ModeTeamBase::AddPlayer( Player *player )
{
// Make sure everything is ok
assert(player);
if ( !player )
{
warning("ModeDeathmatch::AddPlayer", "NULL Player\n");
return ;
}
// Make sure player hasn't alrady been added
if ( !needToAddPlayer( player ) )
return;
MultiplayerModeBase::AddPlayer(player);
// Add player to a team or make him a spectator
if ( playersLastTeam[ player->entnum ].length() )
{
addPlayerToTeam( player, getTeam( playersLastTeam[ player->entnum ] ) );
}
else if ( !multiplayerManager.checkFlag( MP_FLAG_NO_AUTO_JOIN_TEAM ) || multiplayerManager.checkFlag( MP_FLAG_AUTO_BALANCE_TEAMS ) || ( player->edict->svflags & SVF_BOT ) )
{
Team* pickedTeam = 0 ;
Team* team = 0 ;
int minimumPlayers = 0 ;
// Automatically add this player to one of the teams
for (int idx = 1; idx <= _teamList.NumObjects(); idx++)
{
team = _teamList.ObjectAt(idx);
assert(team);
if (!team)
{
continue ;
}
int players = team->getActivePlayers();
if ( (players < minimumPlayers) || (!pickedTeam) )
{
pickedTeam = team ;
minimumPlayers = players ;
}
}
if (pickedTeam)
{
addPlayerToTeam( player, pickedTeam );
}
}
else
{
// Not force joining of teams, start as a spectator
addPlayerToTeam( player, NULL );
}
//if ( _playerGameData[ player->entnum ]._currentTeam )
// addPlayerToTeam( player, _playerGameData[ player->entnum ]._currentTeam );
// If the game hasn't started yet just make the player a spectator
if ( !_gameStarted )
{
multiplayerManager.makePlayerSpectator( player );
}
}
void ModeTeamBase::addPlayerToTeam( Player *player, Team *team )
{
Team *oldTeam;
Entity *spawnPoint;
MultiplayerModeBase::AddPlayer(player);
oldTeam = _playerGameData[ player->entnum ]._currentTeam;
if ( team && ( oldTeam != team ) )
{
// Inform all of the players that the player has changed teams
multiplayerManager.HUDPrintAllClients(va("%s $$Joined$$ $$%s$$ $$Team$$.\n", player->client->pers.netname, team->getName().c_str() ) );
}
if ( oldTeam )
{
_playerGameData[ player->entnum ]._currentTeam = NULL;
player->SurfaceCommand( "all", "-skin1" );
player->SurfaceCommand( "all", "-skin2" );
oldTeam->RemovePlayer(player);
}
if ( team )
{
// Since the player is now on a team add him to the game
if ( _gameStarted )
multiplayerManager.playerEnterArena( player->entnum, player->health );
else
multiplayerManager.makePlayerSpectator( player );
// Add the player to the team
team->AddPlayer(player);
_playerGameData[ player->entnum ]._currentTeam = team;
updatePlayerSkin( player );
if ( team->getName() == "Red" )
{
if ( multiplayerManager.isPlayerSpectator( player ) )
multiplayerManager.setTeamHud( player, "mp_teamredspec" );
else
multiplayerManager.setTeamHud( player, "mp_teamred" );
}
else
{
if ( multiplayerManager.isPlayerSpectator( player ) )
multiplayerManager.setTeamHud( player, "mp_teambluespec" );
else
multiplayerManager.setTeamHud( player, "mp_teamblue" );
}
multiplayerManager.playerSpawned( player );
playersLastTeam[ player->entnum ] = team->getName();
}
else
{
// No team selected so make the player a spectator
multiplayerManager.makePlayerSpectator( player, SPECTATOR_TYPE_FOLLOW, true );
/* team = _playerGameData[ player->entnum ]._currentTeam;
if ( !team )
multiplayerManager.setTeamHud( player, "mp_teamspec" );
else if ( team->getName() == "Red" )
multiplayerManager.setTeamHud( player, "mp_teamredspec" );
else
multiplayerManager.setTeamHud( player, "mp_teambluespec" ); */
}
// Warp player to a spawn point
spawnPoint = getSpawnPoint( player );
if ( spawnPoint )
{
player->WarpToPoint( spawnPoint );
}
if ( team && _gameStarted )
{
KillBox( player );
ActivatePlayer( player );
}
}
void ModeTeamBase::changeTeams( Player *player, Team *team )
{
RemovePlayer( player );
addPlayerToTeam( player, team );
}
void ModeTeamBase::respawnPlayer( Player *player )
{
Entity *spawnPoint;
if ( !player )
{
assert(player);
warning("ModeDeathmatch::respawnPlayer", "NULL player\n");
return;
}
// Make sure we are allowed to respawn the player
if ( !multiplayerManager.checkRule( "respawnPlayer", true, player ) )
{
if ( multiplayerManager.checkRule( "allowSpectator", true ) )
{
multiplayerManager.makePlayerSpectator( player );
}
return;
}
MultiplayerModeBase::respawnPlayer( player );
multiplayerManager.initPlayer( player );
spawnPoint = getSpawnPoint( player );
if ( spawnPoint )
{
player->WarpToPoint( spawnPoint );
}
KillBox( player );
ActivatePlayer( player );
}
Entity *ModeTeamBase::getSpawnPoint( Player *player )
{
Entity *spawnPoint = NULL;
int i;
int numSpawnPoints = 0;
str spawnpointName;
int randomStartingSpot;
int spawnPointIndex;
// Determine what kind of spawn point we want to use
if ( multiplayerManager.checkRule( "spawnpoints-special", false, player ) )
{
spawnpointName = multiplayerManager.getSpawnPointType( player );
numSpawnPoints = getNumNamedSpawnpoints( spawnpointName );
}
if ( !numSpawnPoints && multiplayerManager.checkRule( "spawnpoints-team", _useTeamSpawnpoints ) && _playerGameData[ player->entnum ]._currentTeam )
{
if ( stricmp( _playerGameData[ player->entnum ]._currentTeam->getName(), "red" ) == 0 )
spawnpointName = "red";
else
spawnpointName = "blue";
numSpawnPoints = getNumNamedSpawnpoints( spawnpointName );
}
if ( !numSpawnPoints )
{
spawnpointName = "";
numSpawnPoints = getNumNamedSpawnpoints( spawnpointName );
}
randomStartingSpot = ( (int)( G_Random() * numSpawnPoints ) );
for( i = 0 ; i < numSpawnPoints ; i++ )
{
spawnPointIndex = ( randomStartingSpot + i ) % numSpawnPoints;
spawnPoint = getNamedSpawnpointbyIndex( spawnpointName, spawnPointIndex );
// Make sure we don't telefrag someone on our team
if ( spawnPoint )
{
int j;
int num;
int touch[ MAX_GENTITIES ];
gentity_t *hit;
Vector min;
Vector max;
bool badSpot;
min = spawnPoint->origin + player->mins + Vector( 0, 0, 1 );
max = spawnPoint->origin + player->maxs + Vector( 0, 0, 1 );
num = gi.AreaEntities( min, max, touch, MAX_GENTITIES, qfalse );
badSpot = false;
for( j = 0 ; j < num ; j++ )
{
hit = &g_entities[ touch[ j ] ];
if ( !hit->inuse || ( hit->entity == player ) || !hit->entity || ( hit->entity == world ) || ( !hit->entity->edict->solid ) )
{
continue;
}
if ( hit->entity->isSubclassOf( Player ) )
{
badSpot = true;
break;
}
}
if ( badSpot )
{
continue;
}
}
// This is a good spawn point so use it
return spawnPoint;
}
// Just return the last spawn point found
return spawnPoint;
}
//================================================================
// Name: AddTeam
// Class: ModeTeamBase
//
// Description: Adds a team to the arena. Checks to ensure that the
// max number of teams has not yet been exceeded.
//
// Parameters: const str& -- new name of team
//
// Returns: Team* -- Created team (NULL if failed to create)
//
//================================================================
Team* ModeTeamBase::AddTeam( const str& teamName )
{
Team* team = _findTeamByName(teamName);
if (team)
{
warning( "ModeTeamBase::AddTeam", va("Team %s already exists\n", teamName.c_str() ) );
return NULL ;
}
team = new Team(teamName);
team->setMaxPlayers(getMaxPlayers() / getMaxTeams());
_teamList.AddObject( team );
return team ;
}
Team *ModeTeamBase::getTeam( const str & teamName )
{
int i;
Team *team;
for ( i = 1 ; i <= _teamList.NumObjects() ; i++ )
{
team = _teamList.ObjectAt( i );
if ( team->getName() == teamName )
{
return team;
}
}
return NULL;
}
//================================================================
// Name: RemoveTeam
// Class: ModeTeamBase
//
// Description: Removes and deletes the team specified by name from
// the arena. Calls _deleteTeam to do actual removal.
//
// Parameters:
//
// Returns:
//
//================================================================
void ModeTeamBase::RemoveTeam( const str& teamName )
{
Team* team = _findTeamByName(teamName);
_deleteTeam(team);
}
//================================================================
// Name: AddTeamStartingAmmo
// Class: ModeTeamBase
//
// Description: Adds team-specific ammo. This enables a particular
// team to receive a specific amount and/or type of ammo.
// Calls _addTeamStartingAmmo() to actually give it to the team.
//
// Parameters: const str& teamName -- team to receive the ammo
// const str& ammoName -- name of ammo to give
// int amount -- amount of ammo to give
//
// Returns: None
//
//================================================================
void ModeTeamBase::AddTeamStartingAmmo( const str& teamName, const str& ammoName, int amount )
{
Team* team = _findTeamByName(teamName);
SimpleAmmoType ammoType(ammoName, amount);
_addTeamStartingAmmo(team, ammoType);
}
//================================================================
// Name: AddTeamStartingWeapon
// Class: ModeTeamBase
//
// Description: Adds team-specific weapon. This enables a particular
// team to receive a specific weapon. Calls _addTeamStartingWeapon()
// to actually give it to the team.
//
// Parameters: const str& teamName -- team to receive the ammo
// const str& weaponName -- name of weapon to give
//
// Returns: None
//
//================================================================
void ModeTeamBase::AddTeamStartingWeapon( const str& teamName, const str& weaponName )
{
Team* team = _findTeamByName(teamName);
_addTeamStartingWeapon(team, weaponName);
}
//================================================================
// Name: setTeamStartingHealth
// Class: ModeTeamBase
//
// Description: Sets the starting health for the team. Calls
// _setTeamStartingHealth to do actual work.
//
// Parameters: const str& -- team name
// unsigned int -- amount of health
//
// Returns: None
//
//================================================================
void ModeTeamBase::SetTeamStartingHealth( const str &teamName, unsigned int startingHealth )
{
Team* team = _findTeamByName(teamName);
_setTeamStartingHealth(team, startingHealth);
}
//----------------------------------------------------------------
// P R O T E C T E D M E T H O D S
//----------------------------------------------------------------
//================================================================
// Name: _addTeamStartingAmmo
// Class: ModeTeamBase
//
// Description: Adds the specified ammo to the specified team.
//
// Parameters: Team* -- team to receive the ammo
// SimpleAmmoType -- ammo to receive
//
// Returns: None
//
//================================================================
void ModeTeamBase::_addTeamStartingAmmo( Team* team, const SimpleAmmoType &ammo )
{
// Check for valid team
assert(team);
if (!team)
{
warning("ModeTeamBase::_addTeamStartingAmmo", "NULL team passed\n");
return ;
}
// Check for valid ammo type
assert(ammo.type.length());
if (!ammo.type.length())
{
warning("ModeTeamBase::_addTeamStartingAmmo", "No ammo type specified\n");
return ;
}
// Check for valid amount
assert(ammo.amount > 0);
if (ammo.amount < 0)
{
warning("ModeTeamBase::_addTeamStartingAmmo", "Negative ammo amount specified\n");
return ;
}
team->AddStartingAmmo(ammo);
}
//================================================================
// Name: _addTeamStartingWeapon
// Class: ModeTeamBase
//
// Description: Adds the specified weapon to the specified team.
//
// Parameters: Team* -- team to receive the ammo
// const str& -- weapon to receive
//
// Returns: None
//
//================================================================
void ModeTeamBase::_addTeamStartingWeapon( Team* team, const str& weaponName )
{
// Check for valid team
assert(team);
if (!team)
{
warning("ModeTeamBase::_addTeamStartingWeapon", "NULL team passed\n");
return ;
}
// Check for valid weaponName
assert(weaponName.length());
if (!weaponName.length())
{
warning("ModeTeamBase::_addTeamStartingWeapon", "No weapon specified\n");
return ;
}
team->AddStartingWeapon(weaponName);
}
//================================================================
// Name: _setTeamStartingHealth
// Class: ModeTeamBase
//
// Description: Sets the specified team's starting health to the
// specified value. A starting health of 0 means to
// use the arena's default value (typicaly 100).
//
// Parameters: Team* -- team to affect
// unsigned int -- amount of starting health (must be >= 0)
//
// Returns: None
//
//================================================================
void ModeTeamBase::_setTeamStartingHealth( Team* team, unsigned int startingHealth )
{
// Check for valid team
assert(team);
if (!team)
{
warning("ModeTeamBase::_addTeamStartingWeapon", "NULL team passed\n");
return ;
}
/* assert(startingHealth >= 0);
if (startingHealth < 0)
{
warning("ModeTeamBase::_setTeamStartingHealth", va("Cannot set health to %d\n", startingHealth));
return ;
} */
team->setStartingHealth(startingHealth);
}
//================================================================
// Name: _deleteTeams
// Class: ModeTeamBase
//
// Description: Deletes all the teams currently in the arena.
//
// Parameters: None
//
// Returns: None
//
//================================================================
void ModeTeamBase::_deleteTeams()
{
for (int idx = 1; idx <= _teamList.NumObjects(); idx++)
{
Team* team = _teamList.ObjectAt(idx);
_deleteTeam(team);
}
}
//================================================================
// Name: _deleteTeam
// Class: ModeTeamBase
//
// Description: Removes the specified team from the arena and deletes it.
// Minimal error checking since it is an internal function.
//
// Parameters: Team* -- team to remove and delete
//
// Returns: None
//
//================================================================
void ModeTeamBase::_deleteTeam( Team* team )
{
assert(team);
if (!team)
{
warning("ModeTeamBase::_removeTeam", "NULL Team passed\n");
return ;
}
_teamList.RemoveObject(team);
delete team ;
}
//================================================================
// Name: _beginMatch
// Class: ModeTeamBase
//
// Description: Called when a match begins. Calls BeginMatch on
// every team in the arena. The teams are responsible
// for preparing the participants for battle.
//
// Parameters: None
//
// Returns: None
//
//================================================================
void ModeTeamBase::_beginMatch()
{
for (int idx = 1; idx <= _teamList.NumObjects(); idx++)
{
Team* team = _teamList.ObjectAt(idx);
team->BeginMatch();
}
}
//================================================================
// Name: _endMatch
// Class: ModeTeamBase
//
// Description: Called when a match ends. Calls EndMatch on
// every team in the arena. The teams are responsible
// for removing the players from battle-readiness.
//
// Parameters: None
//
// Returns: None
//
//================================================================
void ModeTeamBase::_endMatch()
{
for (int idx = 1; idx <= _teamList.NumObjects(); idx++)
{
Team* team = _teamList.ObjectAt(idx);
team->EndMatch();
}
}
void ModeTeamBase::declareWinner( void )
{
int redPoints;
int bluePoints;
redPoints = getTeamPoints( "Red" );
bluePoints = getTeamPoints( "Blue" );
if ( redPoints > bluePoints )
{
multiplayerManager.broadcastSound( "localization/sound/dialog/dm/comp_rtwins.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, NULL, 1.5f );
}
else if ( bluePoints > redPoints )
{
multiplayerManager.broadcastSound( "localization/sound/dialog/dm/comp_btwins.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, NULL, 1.5f );
}
/* else
{
multiplayerManager.broadcastSound( "localization/sound/dialog/dm/comp_matover.mp3" );
} */
}
//================================================================
// Name: _findTeamByName
// Class: ModeTeamBase
//
// Description: Retrieves a pointer to the team having the specified name.
//
// Parameters: const str& -- name of the team to retrieve
//
// Returns: Team* -- pointer to team found (NULL if not found)
//
//================================================================
Team* ModeTeamBase::_findTeamByName( const str& teamName )
{
assert(teamName.length());
if (!teamName.length())
{
warning("ModeTeamBase::_findTeamByName", "Team name not specified\n");
return NULL ;
}
Team* team = NULL ;
for (int idx = 1; idx <= _teamList.NumObjects(); idx++)
{
team = _teamList.ObjectAt(idx);
if ( stricmp( team->getName().c_str(), teamName.c_str() ) == 0 )
{
return team ;
}
}
return NULL ;
}
int ModeTeamBase::getIcon( Player *player, int statNum, int value )
{
/* if ( statNum == STAT_MP_TEAMHUD_ICON )
{
Team *team;
team = _playerGameData[ player->entnum ]._currentTeam;
if ( team )
{
// Player is on a team so return the appropriate team icon
if ( multiplayerManager.isPlayerSpectator( player ) )
{
if ( team->getName() == "Red" )
return _redTeamSpectatorHudIconIndex;
else if ( team->getName() == "Blue" )
return _blueTeamSpectatorHudIconIndex;
}
else
{
if ( team->getName() == "Red" )
return _redTeamHudIconIndex;
else if ( team->getName() == "Blue" )
return _blueTeamHudIconIndex;
}
}
}
else */ if ( statNum == STAT_MP_TEAM_ICON )
{
Team *team;
team = _playerGameData[ player->entnum ]._currentTeam;
if ( team )
{
// Player is on a team so return the appropriate team icon
if ( team->getName() == "Red" )
return _redTeamIconIndex;
else if ( team->getName() == "Blue" )
return _blueTeamIconIndex;
}
}
else if ( statNum == STAT_MP_OTHERTEAM_ICON )
{
Team *team;
team = _playerGameData[ player->entnum ]._currentTeam;
if ( team )
{
// Player is on a team so return the appropriate team icon
if ( team->getName() == "Red" )
return _blueTeamIconIndex;
else if ( team->getName() == "Blue" )
return _redTeamIconIndex;
}
}
// We didn't return an icon so let the base mode have a chance
return MultiplayerModeBase::getIcon( player, statNum, value );
}
int ModeTeamBase::getInfoIcon( Player *player )
{
Team *team;
// Make sure entity is not invisible
if ( player->_affectingViewModes & gi.GetViewModeMask( "forcevisible" ) )
return 0;
team = _playerGameData[ player->entnum ]._currentTeam;
if ( team )
{
if ( team->getName() == "Red" )
return _redTeamIconIndex;
else if ( team->getName() == "Blue" )
return _blueTeamIconIndex;
}
return 0;
}
bool ModeTeamBase::canJoinTeam( Player *player, const str &teamName )
{
Team *team;
if ( multiplayerManager.checkFlag( MP_FLAG_AUTO_BALANCE_TEAMS ) )
{
Team *team;
Team *redTeam;
Team *blueTeam;
int redTeamPlayers;
int blueTeamPlayers;
// Get all of the teams
team = getTeam( teamName );
redTeam = getTeam( "Red" );
blueTeam = getTeam( "Blue" );
// Get the number of players
redTeamPlayers = redTeam->getActivePlayers();
blueTeamPlayers = blueTeam->getActivePlayers();
if ( _playerGameData[ player->entnum ]._currentTeam == redTeam )
redTeamPlayers -= 1;
else if ( _playerGameData[ player->entnum ]._currentTeam == blueTeam )
blueTeamPlayers -= 1;
// Don't allow switch unless it's to the team that has less people
if ( ( redTeamPlayers > blueTeamPlayers ) && ( team == redTeam ) )
{
multiplayerManager.centerPrint( player->entnum, "$$CannotJoinAutoBalanceRed$$", CENTERPRINT_IMPORTANCE_HIGH );
return false;
}
else if ( ( blueTeamPlayers > redTeamPlayers ) && ( team == blueTeam ) )
{
multiplayerManager.centerPrint( player->entnum, "$$CannotJoinAutoBalanceBlue$$", CENTERPRINT_IMPORTANCE_HIGH );
return false;
}
}
if ( !multiplayerManager.checkRule( "respawnPlayer", true, player ) )
{
return false;
}
team = _findTeamByName( teamName );
if ( _playerGameData[ player->entnum ]._currentTeam == team )
return false;
else
return true;
}
void ModeTeamBase::joinTeam( Player *player, const str &teamName )
{
Team *team;
team = _findTeamByName( teamName );
changeTeams( player, team );
}
float ModeTeamBase::playerDamaged( Player *damagedPlayer, Player *attackingPlayer, float damage, int meansOfDeath )
{
// Always take telefrag damage
if ( meansOfDeath == MOD_TELEFRAG )
return damage;
// Player can always hurt himself
if ( damagedPlayer == attackingPlayer )
return damage;
// If on same team and not allowing team damage
if ( ( _playerGameData[ damagedPlayer->entnum ]._currentTeam == _playerGameData[ attackingPlayer->entnum ]._currentTeam ) &&
( !multiplayerManager.checkFlag( MP_FLAG_FRIENDLY_FIRE ) ) )
return 0;
else
return damage;
}
int ModeTeamBase::getTeamPoints( Player *player )
{
Team *team;
// Return the points for this team
team = _playerGameData[ player->entnum ]._currentTeam;
if ( team )
return team->getPoints();
else
return 0;
}
int ModeTeamBase::getTeamPoints( const str & teamName )
{
int i;
Team *team;
// Return the points for this team
for ( i = 1 ; i <= _teamList.NumObjects() ; i++ )
{
team = _teamList.ObjectAt( i );
if ( team->getName() == teamName )
{
return team->getPoints();
}
}
return 0;
}
void ModeTeamBase::addTeamPoints( const str & teamName, int points )
{
int i;
Team *team;
// Return the points for this team
for ( i = 1 ; i <= _teamList.NumObjects() ; i++ )
{
team = _teamList.ObjectAt( i );
if ( team->getName() == teamName )
{
team->addPoints( NULL, points );
}
}
}
void ModeTeamBase::teamPointsChanged( Team *team, int oldPoints, int newPoints )
{
Team *otherTeam;
int otherTeamPoints;
if ( team->getName() == "Red" )
otherTeam = getTeam( "Blue" );
else
otherTeam = getTeam( "Red" );
otherTeamPoints = otherTeam->getPoints();
// Play a dialog for this team if necessary
if ( ( newPoints == otherTeamPoints ) && ( oldPoints != otherTeamPoints ) )
{
// Now tied for the lead
multiplayerManager.broadcastSound( "localization/sound/dialog/dm/comp_teamstied.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, NULL, 1.0f );
}
else if ( ( newPoints > otherTeamPoints ) && ( oldPoints <= otherTeamPoints ) )
{
// Now in first place
multiplayerManager.teamSound( team, "localization/sound/dialog/dm/comp_team1stplace.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, 1.0f );
// No longer in the lead
multiplayerManager.teamSound( otherTeam, "localization/sound/dialog/dm/comp_teamnolead.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, 1.0f );
}
else if ( ( newPoints < otherTeamPoints ) && ( oldPoints >= otherTeamPoints ) )
{
// No longer in the lead
multiplayerManager.teamSound( team, "localization/sound/dialog/dm/comp_teamnolead.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, 1.0f );
// Now in first place
multiplayerManager.teamSound( otherTeam, "localization/sound/dialog/dm/comp_team1stplace.mp3", CHAN_AUTO, DEFAULT_VOL, DEFAULT_MIN_DIST, 1.0f );
}
}
void ModeTeamBase::RemovePlayer( Player *player )
{
Team *team;
team = _playerGameData[ player->entnum ]._currentTeam;
if ( team )
{
team->RemovePlayer( player );
}
MultiplayerModeBase::RemovePlayer( player );
}
int ModeTeamBase::getHighestPoints( void )
{
int i;
int highestPoints = -999999999;
Team *team;
for ( i = 1 ; i <= _teamList.NumObjects() ; i++ )
{
team = _teamList.ObjectAt( i );
if ( team->getPoints() > highestPoints )
{
highestPoints = team->getPoints();
}
}
return highestPoints;
}
void ModeTeamBase::updatePlayerSkin( Player *player )
{
Team *team;
team = getPlayersTeam( player );
player->SurfaceCommand( "all", "-skin1" );
player->SurfaceCommand( "all", "-skin2" );
if ( !team )
return;
if ( team->getName() == "Red" )
{
player->SurfaceCommand( "all", "+skin1" );
}
else
{
player->SurfaceCommand( "all", "+skin2" );
}
}
void ModeTeamBase::playerChangedModel( Player *player )
{
updatePlayerSkin( player );
}