2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/shared/config.h>
|
|
|
|
#include <game/mapitems.h>
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/generated/protocol.h>
|
2007-10-05 00:05:21 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
#include "entities/pickup.h"
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "gamecontroller.h"
|
|
|
|
#include "gamecontext.h"
|
2008-08-14 18:25:44 +00:00
|
|
|
|
2010-08-20 20:40:12 +00:00
|
|
|
#include "entities/light.h"
|
2010-08-21 17:32:42 +00:00
|
|
|
#include "entities/dragger.h"
|
2010-08-20 20:40:12 +00:00
|
|
|
#include "entities/gun.h"
|
|
|
|
#include "entities/projectile.h"
|
|
|
|
#include "entities/plasma.h"
|
|
|
|
#include "entities/door.h"
|
2010-07-29 05:21:18 +00:00
|
|
|
#include <game/layers.h>
|
|
|
|
|
2008-08-27 20:04:07 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
IGameController::IGameController(class CGameContext *pGameServer)
|
2008-08-27 20:04:07 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pGameServer = pGameServer;
|
|
|
|
m_pServer = m_pGameServer->Server();
|
|
|
|
m_pGameType = "unknown";
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-08-27 20:04:07 +00:00
|
|
|
//
|
2010-05-29 07:25:38 +00:00
|
|
|
DoWarmup(g_Config.m_SvWarmup);
|
|
|
|
m_GameOverTick = -1;
|
|
|
|
m_SuddenDeath = 0;
|
|
|
|
m_RoundStartTick = Server()->Tick();
|
|
|
|
m_RoundCount = 0;
|
|
|
|
m_GameFlags = 0;
|
2011-01-04 20:30:15 +00:00
|
|
|
//m_aTeamscore[TEAM_RED] = 0;
|
|
|
|
//m_aTeamscore[TEAM_BLUE] = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aMapWish[0] = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_UnbalancedTick = -1;
|
|
|
|
m_ForceBalanced = false;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_aNumSpawnPoints[0] = 0;
|
|
|
|
m_aNumSpawnPoints[1] = 0;
|
|
|
|
m_aNumSpawnPoints[2] = 0;
|
2010-08-28 20:53:42 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
m_CurrentRecord = 0;
|
2008-08-27 20:04:07 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
IGameController::~IGameController()
|
2008-10-02 14:44:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float Score = 0.0f;
|
2011-01-19 17:27:50 +00:00
|
|
|
CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
|
2010-05-29 07:25:38 +00:00
|
|
|
for(; pC; pC = (CCharacter *)pC->TypeNext())
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
|
|
|
// team mates are not as dangerous as enemies
|
2010-05-29 07:25:38 +00:00
|
|
|
float Scoremod = 1.0f;
|
|
|
|
if(pEval->m_FriendlyTeam != -1 && pC->GetPlayer()->GetTeam() == pEval->m_FriendlyTeam)
|
|
|
|
Scoremod = 0.5f;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float d = distance(Pos, pC->m_Pos);
|
2011-01-17 14:55:23 +00:00
|
|
|
Score += Scoremod * (d == 0 ? 1000000000.0f : 1.0f/d);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return Score;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2011-02-21 11:35:14 +00:00
|
|
|
void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
|
|
|
// get spawn point
|
2011-04-13 18:37:12 +00:00
|
|
|
for(int i = 0; i < m_aNumSpawnPoints[Type]; i++)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2011-02-10 11:05:55 +00:00
|
|
|
// check if the position is occupado
|
2011-06-14 23:03:14 +00:00
|
|
|
CCharacter *aEnts[MAX_CLIENTS];
|
|
|
|
int Num = GameServer()->m_World.FindEntities(m_aaSpawnPoints[Type][i], 64, (CEntity**)aEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
|
|
|
|
vec2 Positions[5] = { vec2(0.0f, 0.0f), vec2(-32.0f, 0.0f), vec2(0.0f, -32.0f), vec2(32.0f, 0.0f), vec2(0.0f, 32.0f) }; // start, left, up, right, down
|
|
|
|
int Result = -1;
|
|
|
|
for(int Index = 0; Index < 5 && Result == -1; ++Index)
|
|
|
|
{
|
|
|
|
Result = Index;
|
|
|
|
for(int c = 0; c < Num; ++c)
|
|
|
|
if(GameServer()->Collision()->CheckPoint(m_aaSpawnPoints[Type][i]+Positions[Index]) ||
|
|
|
|
distance(aEnts[c]->m_Pos, m_aaSpawnPoints[Type][i]+Positions[Index]) <= aEnts[c]->m_ProximityRadius)
|
|
|
|
{
|
|
|
|
Result = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(Result == -1)
|
|
|
|
continue; // try next spawn point
|
2011-02-10 11:05:55 +00:00
|
|
|
|
2011-06-14 23:03:14 +00:00
|
|
|
vec2 P = m_aaSpawnPoints[Type][i]+Positions[Result];
|
2010-05-29 07:25:38 +00:00
|
|
|
float S = EvaluateSpawnPos(pEval, P);
|
|
|
|
if(!pEval->m_Got || pEval->m_Score > S)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
pEval->m_Got = true;
|
|
|
|
pEval->m_Score = S;
|
|
|
|
pEval->m_Pos = P;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-14 07:43:44 +00:00
|
|
|
bool IGameController::CanSpawn(int Team, vec2 *pOutPos)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CSpawnEval Eval;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-11-21 14:18:55 +00:00
|
|
|
// spectators can't spawn
|
2011-02-10 11:05:55 +00:00
|
|
|
if(Team == TEAM_SPECTATORS)
|
2008-11-21 14:18:55 +00:00
|
|
|
return false;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
/*if(IsTeamplay())
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2011-02-14 07:43:44 +00:00
|
|
|
Eval.m_FriendlyTeam = Team;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-14 07:43:44 +00:00
|
|
|
// first try own team spawn, then normal spawn and then enemy
|
|
|
|
EvaluateSpawnType(&Eval, 1+(Team&1));
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!Eval.m_Got)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
EvaluateSpawnType(&Eval, 0);
|
|
|
|
if(!Eval.m_Got)
|
2011-02-14 07:43:44 +00:00
|
|
|
EvaluateSpawnType(&Eval, 1+((Team+1)&1));
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2010-07-29 05:21:18 +00:00
|
|
|
{*/
|
2010-05-29 07:25:38 +00:00
|
|
|
EvaluateSpawnType(&Eval, 0);
|
|
|
|
EvaluateSpawnType(&Eval, 1);
|
|
|
|
EvaluateSpawnType(&Eval, 2);
|
2010-07-29 05:21:18 +00:00
|
|
|
//}
|
2011-02-21 11:35:14 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
*pOutPos = Eval.m_Pos;
|
|
|
|
return Eval.m_Got;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
//bool IGameController::OnEntity(int Index, vec2 Pos)
|
2010-11-13 13:22:19 +00:00
|
|
|
bool IGameController::OnEntity(int Index, vec2 Pos, int Layer, int Flags, int Number)
|
2008-01-13 11:43:43 +00:00
|
|
|
{
|
2011-04-11 22:27:52 +00:00
|
|
|
if (Index < 0)
|
|
|
|
return false;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int Type = -1;
|
|
|
|
int SubType = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-12 11:01:57 +00:00
|
|
|
int x,y;
|
|
|
|
x=(Pos.x-16.0f)/32.0f;
|
2010-08-20 20:40:12 +00:00
|
|
|
y=(Pos.y-16.0f)/32.0f;
|
2010-08-12 11:01:57 +00:00
|
|
|
int sides[8];
|
2010-11-13 13:22:19 +00:00
|
|
|
sides[0]=GameServer()->Collision()->Entity(x,y+1, Layer);
|
|
|
|
sides[1]=GameServer()->Collision()->Entity(x+1,y+1, Layer);
|
|
|
|
sides[2]=GameServer()->Collision()->Entity(x+1,y, Layer);
|
|
|
|
sides[3]=GameServer()->Collision()->Entity(x+1,y-1, Layer);
|
|
|
|
sides[4]=GameServer()->Collision()->Entity(x,y-1, Layer);
|
|
|
|
sides[5]=GameServer()->Collision()->Entity(x-1,y-1, Layer);
|
|
|
|
sides[6]=GameServer()->Collision()->Entity(x-1,y, Layer);
|
|
|
|
sides[7]=GameServer()->Collision()->Entity(x-1,y+1, Layer);
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Index == ENTITY_SPAWN)
|
|
|
|
m_aaSpawnPoints[0][m_aNumSpawnPoints[0]++] = Pos;
|
|
|
|
else if(Index == ENTITY_SPAWN_RED)
|
|
|
|
m_aaSpawnPoints[1][m_aNumSpawnPoints[1]++] = Pos;
|
|
|
|
else if(Index == ENTITY_SPAWN_BLUE)
|
|
|
|
m_aaSpawnPoints[2][m_aNumSpawnPoints[2]++] = Pos;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-11-13 13:22:19 +00:00
|
|
|
else if(Index == ENTITY_DOOR)
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
for(int i = 0; i < 8;i++)
|
2010-11-13 13:22:19 +00:00
|
|
|
{
|
|
|
|
if (sides[i] >= ENTITY_LASER_SHORT && sides[i] <= ENTITY_LASER_LONG)
|
|
|
|
{
|
|
|
|
new CDoor
|
|
|
|
(
|
2011-01-29 00:59:50 +00:00
|
|
|
&GameServer()->m_World, //GameWorld
|
|
|
|
Pos, //Pos
|
|
|
|
pi / 4 * i, //Rotation
|
|
|
|
32 * 3 + 32 *(sides[i] - ENTITY_LASER_SHORT) * 3, //Length
|
|
|
|
Number //Number
|
2010-11-13 13:22:19 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(Index == ENTITY_CRAZY_SHOTGUN_EX)
|
2010-08-14 10:46:54 +00:00
|
|
|
{
|
2010-11-01 01:51:17 +00:00
|
|
|
int Dir;
|
|
|
|
if(!Flags)
|
|
|
|
Dir = 0;
|
|
|
|
else if(Flags == ROTATION_90)
|
|
|
|
Dir = 1;
|
|
|
|
else if(Flags == ROTATION_180)
|
|
|
|
Dir = 2;
|
|
|
|
else
|
|
|
|
Dir = 3;
|
2011-01-29 00:59:50 +00:00
|
|
|
float Deg = Dir * (pi / 2);
|
2010-11-01 01:51:17 +00:00
|
|
|
CProjectile *bullet = new CProjectile
|
|
|
|
(
|
|
|
|
&GameServer()->m_World,
|
|
|
|
WEAPON_SHOTGUN, //Type
|
|
|
|
-1, //Owner
|
|
|
|
Pos, //Pos
|
2011-01-29 00:59:50 +00:00
|
|
|
vec2(sin(Deg), cos(Deg)), //Dir
|
2010-11-01 01:51:17 +00:00
|
|
|
-2, //Span
|
|
|
|
true, //Freeze
|
|
|
|
true, //Explosive
|
2011-01-29 00:59:50 +00:00
|
|
|
0, //Force
|
2010-11-01 01:51:17 +00:00
|
|
|
(g_Config.m_SvShotgunBulletSound)?SOUND_GRENADE_EXPLODE:-1,//SoundImpact
|
2010-11-13 13:22:19 +00:00
|
|
|
WEAPON_SHOTGUN,//Weapon
|
|
|
|
Layer,
|
|
|
|
Number
|
2010-11-01 01:51:17 +00:00
|
|
|
);
|
|
|
|
bullet->SetBouncing(2 - (Dir % 2));
|
2010-08-14 10:46:54 +00:00
|
|
|
}
|
2010-11-01 01:51:17 +00:00
|
|
|
else if(Index == ENTITY_CRAZY_SHOTGUN)
|
2010-08-14 10:46:54 +00:00
|
|
|
{
|
2010-11-01 01:51:17 +00:00
|
|
|
int Dir;
|
|
|
|
if(!Flags)
|
|
|
|
Dir=0;
|
|
|
|
else if(Flags == (TILEFLAG_ROTATE))
|
|
|
|
Dir = 1;
|
|
|
|
else if(Flags == (TILEFLAG_VFLIP|TILEFLAG_HFLIP))
|
|
|
|
Dir = 2;
|
|
|
|
else
|
|
|
|
Dir = 3;
|
2011-01-29 00:59:50 +00:00
|
|
|
float Deg = Dir * ( pi / 2);
|
2010-11-13 13:22:19 +00:00
|
|
|
CProjectile *bullet = new CProjectile
|
|
|
|
(
|
|
|
|
&GameServer()->m_World,
|
2010-11-01 01:51:17 +00:00
|
|
|
WEAPON_SHOTGUN, //Type
|
|
|
|
-1, //Owner
|
|
|
|
Pos, //Pos
|
2011-01-29 00:59:50 +00:00
|
|
|
vec2(sin(Deg), cos(Deg)), //Dir
|
2010-11-01 01:51:17 +00:00
|
|
|
-2, //Span
|
|
|
|
true, //Freeze
|
|
|
|
false, //Explosive
|
|
|
|
0,
|
|
|
|
SOUND_GRENADE_EXPLODE,
|
2011-01-29 00:59:50 +00:00
|
|
|
WEAPON_SHOTGUN, //Weapon
|
2010-11-13 13:22:19 +00:00
|
|
|
Layer,
|
|
|
|
Number
|
|
|
|
);
|
2010-11-01 01:51:17 +00:00
|
|
|
bullet->SetBouncing(2 - (Dir % 2));
|
2010-08-14 10:46:54 +00:00
|
|
|
}
|
2010-08-20 20:40:12 +00:00
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
if(Index == ENTITY_ARMOR_1)
|
|
|
|
Type = POWERUP_ARMOR;
|
|
|
|
else if(Index == ENTITY_HEALTH_1)
|
|
|
|
Type = POWERUP_HEALTH;
|
|
|
|
else if(Index == ENTITY_WEAPON_SHOTGUN)
|
|
|
|
{
|
|
|
|
Type = POWERUP_WEAPON;
|
|
|
|
SubType = WEAPON_SHOTGUN;
|
|
|
|
}
|
|
|
|
else if(Index == ENTITY_WEAPON_GRENADE)
|
|
|
|
{
|
|
|
|
Type = POWERUP_WEAPON;
|
|
|
|
SubType = WEAPON_GRENADE;
|
|
|
|
}
|
|
|
|
else if(Index == ENTITY_WEAPON_RIFLE)
|
|
|
|
{
|
|
|
|
Type = POWERUP_WEAPON;
|
|
|
|
SubType = WEAPON_RIFLE;
|
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
//else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
|
2010-07-29 05:21:18 +00:00
|
|
|
else if(Index == ENTITY_POWERUP_NINJA)
|
|
|
|
{
|
|
|
|
Type = POWERUP_NINJA;
|
|
|
|
SubType = WEAPON_NINJA;
|
|
|
|
}
|
2010-08-20 20:40:12 +00:00
|
|
|
else if(Index >= ENTITY_LASER_FAST_CW && Index <= ENTITY_LASER_FAST_CCW)
|
2010-11-13 13:22:19 +00:00
|
|
|
{
|
2010-08-12 11:01:57 +00:00
|
|
|
int sides2[8];
|
2011-01-29 00:59:50 +00:00
|
|
|
sides2[0]=GameServer()->Collision()->Entity(x, y + 2, Layer);
|
|
|
|
sides2[1]=GameServer()->Collision()->Entity(x + 2, y + 2, Layer);
|
|
|
|
sides2[2]=GameServer()->Collision()->Entity(x + 2, y, Layer);
|
|
|
|
sides2[3]=GameServer()->Collision()->Entity(x + 2, y - 2, Layer);
|
|
|
|
sides2[4]=GameServer()->Collision()->Entity(x,y - 2, Layer);
|
|
|
|
sides2[5]=GameServer()->Collision()->Entity(x - 2, y - 2, Layer);
|
|
|
|
sides2[6]=GameServer()->Collision()->Entity(x - 2, y, Layer);
|
|
|
|
sides2[7]=GameServer()->Collision()->Entity(x - 2, y + 2, Layer);
|
2010-08-20 20:40:12 +00:00
|
|
|
|
2011-01-06 12:13:49 +00:00
|
|
|
float AngularSpeed = 0.0;
|
2010-10-07 13:28:29 +00:00
|
|
|
int Ind=Index-ENTITY_LASER_STOP;
|
|
|
|
int M;
|
2011-01-29 00:59:50 +00:00
|
|
|
if( Ind < 0)
|
2010-10-07 13:28:29 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
Ind = -Ind;
|
|
|
|
M = 1;
|
2010-10-07 13:28:29 +00:00
|
|
|
}
|
2011-01-29 00:59:50 +00:00
|
|
|
else if(Ind == 0)
|
|
|
|
M = 0;
|
2010-10-07 13:28:29 +00:00
|
|
|
else
|
2011-01-29 00:59:50 +00:00
|
|
|
M = -1;
|
2010-10-07 13:28:29 +00:00
|
|
|
|
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
if(Ind == 0)
|
|
|
|
AngularSpeed = 0.0f;
|
|
|
|
else if(Ind == 1)
|
|
|
|
AngularSpeed = pi / 360;
|
|
|
|
else if(Ind == 2)
|
|
|
|
AngularSpeed = pi / 180;
|
|
|
|
else if(Ind == 3)
|
|
|
|
AngularSpeed = pi / 90;
|
|
|
|
AngularSpeed *= M;
|
2010-10-07 13:28:29 +00:00
|
|
|
|
2010-08-20 20:40:12 +00:00
|
|
|
for(int i=0; i<8;i++)
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
if(sides[i] >= ENTITY_LASER_SHORT && sides[i] <= ENTITY_LASER_LONG)
|
|
|
|
{
|
|
|
|
CLight *Lgt = new CLight(&GameServer()->m_World, Pos, pi / 4 * i, 32 * 3 + 32 * (sides[i] - ENTITY_LASER_SHORT) * 3, Layer, Number);
|
|
|
|
Lgt->m_AngularSpeed = AngularSpeed;
|
|
|
|
if(sides2[i] >= ENTITY_LASER_C_SLOW && sides2[i] <= ENTITY_LASER_C_FAST)
|
|
|
|
{
|
|
|
|
Lgt->m_Speed = 1 + (sides2[i] - ENTITY_LASER_C_SLOW) * 2;
|
|
|
|
Lgt->m_CurveLength = Lgt->m_Length;
|
|
|
|
}
|
|
|
|
else if(sides2[i] >= ENTITY_LASER_O_SLOW && sides2[i] <= ENTITY_LASER_O_FAST)
|
|
|
|
{
|
|
|
|
Lgt->m_Speed = 1 + (sides2[i] - ENTITY_LASER_O_SLOW) * 2;
|
|
|
|
Lgt->m_CurveLength = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Lgt->m_CurveLength = Lgt->m_Length;
|
|
|
|
}
|
2010-08-20 20:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2011-01-29 00:59:50 +00:00
|
|
|
else if(Index >= ENTITY_DRAGGER_WEAK && Index <= ENTITY_DRAGGER_STRONG)
|
|
|
|
{
|
2013-08-06 03:14:53 +00:00
|
|
|
CDraggerTeam(&GameServer()->m_World, Pos, Index - ENTITY_DRAGGER_WEAK + 1, false, Layer, Number);
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
|
|
|
else if(Index >= ENTITY_DRAGGER_WEAK_NW && Index <= ENTITY_DRAGGER_STRONG_NW)
|
|
|
|
{
|
2013-08-06 03:14:53 +00:00
|
|
|
CDraggerTeam(&GameServer()->m_World, Pos, Index - ENTITY_DRAGGER_WEAK_NW + 1, true, Layer, Number);
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
|
|
|
else if(Index == ENTITY_PLASMAE)
|
|
|
|
{
|
|
|
|
new CGun(&GameServer()->m_World, Pos, false, true, Layer, Number);
|
|
|
|
}
|
|
|
|
else if(Index == ENTITY_PLASMAF)
|
|
|
|
{
|
|
|
|
new CGun(&GameServer()->m_World, Pos, true, false, Layer, Number);
|
|
|
|
}
|
|
|
|
else if(Index == ENTITY_PLASMA)
|
|
|
|
{
|
|
|
|
new CGun(&GameServer()->m_World, Pos, true, true, Layer, Number);
|
|
|
|
}
|
|
|
|
else if(Index == ENTITY_PLASMAU)
|
|
|
|
{
|
|
|
|
new CGun(&GameServer()->m_World, Pos, false, false, Layer, Number);
|
|
|
|
}
|
2008-01-13 11:43:43 +00:00
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
if(Type != -1)
|
|
|
|
{
|
2011-04-09 06:41:31 +00:00
|
|
|
//CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType);
|
2010-11-13 13:22:19 +00:00
|
|
|
CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType, Layer, Number);
|
2010-07-29 05:21:18 +00:00
|
|
|
pPickup->m_Pos = Pos;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::EndRound()
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Warmup) // game can't end when we are running warmup
|
2007-10-06 17:36:24 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_World.m_Paused = true;
|
|
|
|
m_GameOverTick = Server()->Tick();
|
|
|
|
m_SuddenDeath = 0;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::ResetGame()
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_World.m_ResetRequested = true;
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
const char *IGameController::GetTeamName(int Team)
|
2011-01-29 00:59:50 +00:00
|
|
|
{/*
|
|
|
|
if(IsTeamplay())
|
|
|
|
{
|
|
|
|
if(Team == TEAM_RED)
|
|
|
|
return "red team";
|
|
|
|
else if(Team == TEAM_BLUE)
|
|
|
|
return "blue team";
|
2008-07-06 11:21:21 +00:00
|
|
|
}
|
|
|
|
else
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
|
|
|
if(Team == 0)
|
|
|
|
return "game";
|
2011-04-09 06:41:31 +00:00
|
|
|
}*/
|
|
|
|
|
2011-01-04 20:30:15 +00:00
|
|
|
if(Team == 0)
|
|
|
|
return "game";
|
2008-07-06 11:21:21 +00:00
|
|
|
return "spectators";
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2011-02-05 01:33:53 +00:00
|
|
|
//static bool IsSeparator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
|
2007-10-05 00:05:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::StartRound()
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
ResetGame();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_RoundStartTick = Server()->Tick();
|
|
|
|
m_SuddenDeath = 0;
|
|
|
|
m_GameOverTick = -1;
|
|
|
|
GameServer()->m_World.m_Paused = false;
|
2011-01-04 20:30:15 +00:00
|
|
|
//m_aTeamscore[TEAM_RED] = 0;
|
|
|
|
//m_aTeamscore[TEAM_BLUE] = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ForceBalanced = false;
|
2011-07-22 21:17:16 +00:00
|
|
|
Server()->DemoRecorder_HandleAutoStart();
|
2010-08-17 22:06:00 +00:00
|
|
|
char aBuf[256];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS);
|
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::ChangeMap(const char *pToMap)
|
2008-10-22 14:31:46 +00:00
|
|
|
{
|
2010-10-08 20:12:12 +00:00
|
|
|
/*str_copy(m_aMapWish, pToMap, sizeof(m_aMapWish));
|
|
|
|
EndRound();*/
|
|
|
|
str_copy(g_Config.m_SvMap, pToMap, sizeof(m_aMapWish));
|
2008-10-22 14:31:46 +00:00
|
|
|
}
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
/*void IGameController::CycleMap()
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_aMapWish[0] != 0)
|
2008-10-22 14:31:46 +00:00
|
|
|
{
|
2010-08-17 22:06:00 +00:00
|
|
|
char aBuf[256];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "rotating map to %s", m_aMapWish);
|
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
2010-05-29 07:25:38 +00:00
|
|
|
str_copy(g_Config.m_SvMap, m_aMapWish, sizeof(g_Config.m_SvMap));
|
|
|
|
m_aMapWish[0] = 0;
|
|
|
|
m_RoundCount = 0;
|
2008-10-22 14:31:46 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!str_length(g_Config.m_SvMaprotation))
|
2007-10-05 00:05:21 +00:00
|
|
|
return;
|
2008-03-01 20:21:34 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_RoundCount < g_Config.m_SvRoundsPerMap-1)
|
2011-12-30 21:47:26 +00:00
|
|
|
{
|
|
|
|
if(g_Config.m_SvRoundSwap)
|
|
|
|
GameServer()->SwapTeams();
|
2008-03-29 21:46:38 +00:00
|
|
|
return;
|
2011-12-30 21:47:26 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2007-10-05 00:05:21 +00:00
|
|
|
// handle maprotation
|
2010-05-29 07:25:38 +00:00
|
|
|
const char *pMapRotation = g_Config.m_SvMaprotation;
|
|
|
|
const char *pCurrentMap = g_Config.m_SvMap;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int CurrentMapLen = str_length(pCurrentMap);
|
|
|
|
const char *pNextMap = pMapRotation;
|
|
|
|
while(*pNextMap)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int WordLen = 0;
|
|
|
|
while(pNextMap[WordLen] && !IsSeparator(pNextMap[WordLen]))
|
|
|
|
WordLen++;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(WordLen == CurrentMapLen && str_comp_num(pNextMap, pCurrentMap, CurrentMapLen) == 0)
|
2008-03-01 20:21:34 +00:00
|
|
|
{
|
|
|
|
// map found
|
2010-05-29 07:25:38 +00:00
|
|
|
pNextMap += CurrentMapLen;
|
|
|
|
while(*pNextMap && IsSeparator(*pNextMap))
|
|
|
|
pNextMap++;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-03-01 20:21:34 +00:00
|
|
|
break;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
pNextMap++;
|
2008-03-01 20:21:34 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-03-01 20:21:34 +00:00
|
|
|
// restart rotation
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pNextMap[0] == 0)
|
|
|
|
pNextMap = pMapRotation;
|
2008-03-01 20:21:34 +00:00
|
|
|
|
2011-04-13 18:37:12 +00:00
|
|
|
// cut out the next map
|
2010-08-17 22:06:00 +00:00
|
|
|
char aBuf[512];
|
2008-03-01 20:21:34 +00:00
|
|
|
for(int i = 0; i < 512; i++)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-08-17 22:06:00 +00:00
|
|
|
aBuf[i] = pNextMap[i];
|
2010-05-29 07:25:38 +00:00
|
|
|
if(IsSeparator(pNextMap[i]) || pNextMap[i] == 0)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-08-17 22:06:00 +00:00
|
|
|
aBuf[i] = 0;
|
2007-10-05 00:05:21 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-03-01 20:21:34 +00:00
|
|
|
// skip spaces
|
|
|
|
int i = 0;
|
2010-08-17 22:06:00 +00:00
|
|
|
while(IsSeparator(aBuf[i]))
|
2007-10-05 00:05:21 +00:00
|
|
|
i++;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_RoundCount = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-17 22:06:00 +00:00
|
|
|
char aBufMsg[256];
|
|
|
|
str_format(aBufMsg, sizeof(aBufMsg), "rotating map to %s", &aBuf[i]);
|
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
|
|
|
str_copy(g_Config.m_SvMap, &aBuf[i], sizeof(g_Config.m_SvMap));
|
2011-04-09 06:41:31 +00:00
|
|
|
}*/
|
2007-10-05 00:05:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::PostReset()
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(GameServer()->m_apPlayers[i])
|
2008-10-25 08:36:55 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_apPlayers[i]->Respawn();
|
2010-07-29 05:21:18 +00:00
|
|
|
//GameServer()->m_apPlayers[i]->m_Score = 0;
|
|
|
|
//GameServer()->m_apPlayers[i]->m_ScoreStartTick = Server()->Tick();
|
|
|
|
//GameServer()->m_apPlayers[i]->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
|
2008-10-25 08:36:55 +00:00
|
|
|
}
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-04-09 20:45:34 +00:00
|
|
|
/*void IGameController::OnPlayerInfoChange(class CPlayer *pP)
|
2007-11-18 14:24:34 +00:00
|
|
|
{
|
2011-04-09 20:45:34 +00:00
|
|
|
const int aTeamColors[2] = {65387, 10223467};
|
2010-05-29 07:25:38 +00:00
|
|
|
if(IsTeamplay())
|
2007-11-18 14:24:34 +00:00
|
|
|
{
|
2011-03-27 09:52:16 +00:00
|
|
|
pP->m_TeeInfos.m_UseCustomColor = 1;
|
2011-01-03 11:50:38 +00:00
|
|
|
if(pP->GetTeam() >= TEAM_RED && pP->GetTeam() <= TEAM_BLUE)
|
2007-11-18 14:24:34 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
pP->m_TeeInfos.m_ColorBody = aTeamColors[pP->GetTeam()];
|
|
|
|
pP->m_TeeInfos.m_ColorFeet = aTeamColors[pP->GetTeam()];
|
2007-11-18 14:24:34 +00:00
|
|
|
}
|
2011-03-27 09:52:16 +00:00
|
|
|
else
|
2011-04-09 20:45:34 +00:00
|
|
|
{
|
2011-03-27 09:52:16 +00:00
|
|
|
pP->m_TeeInfos.m_ColorBody = 12895054;
|
|
|
|
pP->m_TeeInfos.m_ColorFeet = 12895054;
|
2011-04-09 20:45:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
2007-11-18 14:24:34 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int IGameController::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2011-04-09 06:41:31 +00:00
|
|
|
/*// do scoreing
|
2010-06-03 21:08:05 +00:00
|
|
|
if(!pKiller || Weapon == WEAPON_GAME)
|
2007-11-18 23:29:34 +00:00
|
|
|
return 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pKiller == pVictim->GetPlayer())
|
|
|
|
pVictim->GetPlayer()->m_Score--; // suicide
|
2007-10-05 00:05:21 +00:00
|
|
|
else
|
2007-12-11 21:19:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(IsTeamplay() && pVictim->GetPlayer()->GetTeam() == pKiller->GetTeam())
|
|
|
|
pKiller->m_Score--; // teamkill
|
2007-12-11 21:19:52 +00:00
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
pKiller->m_Score++; // normal kill
|
2007-12-11 21:19:52 +00:00
|
|
|
}
|
2011-03-26 21:38:05 +00:00
|
|
|
if(Weapon == WEAPON_SELF)
|
2011-04-09 06:41:31 +00:00
|
|
|
pVictim->GetPlayer()->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3.0f;*/
|
2007-11-18 23:29:34 +00:00
|
|
|
return 0;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::OnCharacterSpawn(class CCharacter *pChr)
|
2008-08-27 20:04:07 +00:00
|
|
|
{
|
2008-08-27 20:17:04 +00:00
|
|
|
// default health
|
2010-05-29 07:25:38 +00:00
|
|
|
pChr->IncreaseHealth(10);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-08-27 20:04:07 +00:00
|
|
|
// give default weapons
|
2010-05-29 07:25:38 +00:00
|
|
|
pChr->GiveWeapon(WEAPON_HAMMER, -1);
|
2010-07-29 05:21:18 +00:00
|
|
|
pChr->GiveWeapon(WEAPON_GUN, -1);
|
2008-08-27 20:04:07 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::DoWarmup(int Seconds)
|
2007-10-06 17:36:24 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Seconds < 0)
|
|
|
|
m_Warmup = 0;
|
|
|
|
else
|
|
|
|
m_Warmup = Seconds*Server()->TickSpeed();
|
2007-10-06 17:36:24 +00:00
|
|
|
}
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
/*bool IGameController::IsFriendlyFire(int ClientID1, int ClientID2)
|
2007-12-10 20:53:37 +00:00
|
|
|
{
|
2011-02-12 10:40:36 +00:00
|
|
|
if(ClientID1 == ClientID2)
|
2007-12-10 20:53:37 +00:00
|
|
|
return false;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(IsTeamplay())
|
2007-12-10 20:53:37 +00:00
|
|
|
{
|
2011-02-12 10:40:36 +00:00
|
|
|
if(!GameServer()->m_apPlayers[ClientID1] || !GameServer()->m_apPlayers[ClientID2])
|
2008-12-19 08:26:58 +00:00
|
|
|
return false;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
if(GameServer()->m_apPlayers[ClientID1]->GetTeam() == GameServer()->m_apPlayers[ClientID2]->GetTeam())
|
2007-12-10 20:53:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2007-12-10 20:53:37 +00:00
|
|
|
return false;
|
2011-04-09 06:41:31 +00:00
|
|
|
}*/
|
2007-10-05 00:05:21 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool IGameController::IsForceBalanced()
|
2008-09-07 08:57:59 +00:00
|
|
|
{
|
2010-07-29 19:51:58 +00:00
|
|
|
/*if(m_ForceBalanced)
|
2008-09-07 08:57:59 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ForceBalanced = false;
|
2008-09-07 08:57:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
2010-07-29 19:51:58 +00:00
|
|
|
else*/
|
2008-09-07 08:57:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
bool IGameController::CanBeMovedOnBalance(int ClientID)
|
2010-05-29 07:25:38 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IGameController::Tick()
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2007-10-06 17:36:24 +00:00
|
|
|
// do warmup
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Warmup)
|
2007-10-06 17:36:24 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Warmup--;
|
|
|
|
if(!m_Warmup)
|
|
|
|
StartRound();
|
2007-10-06 17:36:24 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_GameOverTick != -1)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
|
|
|
// game over.. wait for restart
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Server()->Tick() > m_GameOverTick+Server()->TickSpeed()*10)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2010-07-29 05:21:18 +00:00
|
|
|
//CycleMap();
|
2010-05-29 07:25:38 +00:00
|
|
|
StartRound();
|
|
|
|
m_RoundCount++;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2012-04-12 00:09:31 +00:00
|
|
|
/*
|
2012-01-09 23:49:31 +00:00
|
|
|
// game is Paused
|
|
|
|
if(GameServer()->m_World.m_Paused)
|
|
|
|
++m_RoundStartTick;
|
|
|
|
|
2008-10-19 16:51:16 +00:00
|
|
|
// do team-balancing
|
2012-01-09 23:49:31 +00:00
|
|
|
if(IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60)
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2010-08-17 22:06:00 +00:00
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", "Balancing teams");
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int aT[2] = {0,0};
|
2010-05-31 20:35:47 +00:00
|
|
|
float aTScore[2] = {0,0};
|
|
|
|
float aPScore[MAX_CLIENTS] = {0.0f};
|
2008-09-07 08:10:56 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2011-01-03 11:50:38 +00:00
|
|
|
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
|
2008-10-19 16:14:12 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
aT[GameServer()->m_apPlayers[i]->GetTeam()]++;
|
2010-05-31 20:35:47 +00:00
|
|
|
aPScore[i] = GameServer()->m_apPlayers[i]->m_Score*Server()->TickSpeed()*60.0f/
|
|
|
|
(Server()->Tick()-GameServer()->m_apPlayers[i]->m_ScoreStartTick);
|
|
|
|
aTScore[GameServer()->m_apPlayers[i]->GetTeam()] += aPScore[i];
|
2008-10-19 16:14:12 +00:00
|
|
|
}
|
2008-09-07 08:10:56 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-10-19 18:38:23 +00:00
|
|
|
// are teams unbalanced?
|
2010-05-29 07:25:38 +00:00
|
|
|
if(absolute(aT[0]-aT[1]) >= 2)
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int M = (aT[0] > aT[1]) ? 0 : 1;
|
|
|
|
int NumBalance = absolute(aT[0]-aT[1]) / 2;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-10-19 18:38:23 +00:00
|
|
|
do
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CPlayer *pP = 0;
|
2010-08-16 00:21:18 +00:00
|
|
|
float PD = aTScore[M];
|
2008-10-19 18:38:23 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2010-05-31 20:35:47 +00:00
|
|
|
if(!GameServer()->m_apPlayers[i] || !CanBeMovedOnBalance(i))
|
2008-10-19 18:38:23 +00:00
|
|
|
continue;
|
|
|
|
// remember the player who would cause lowest score-difference
|
2010-05-31 20:35:47 +00:00
|
|
|
if(GameServer()->m_apPlayers[i]->GetTeam() == M && (!pP || absolute((aTScore[M^1]+aPScore[i]) - (aTScore[M]-aPScore[i])) < PD))
|
2008-10-19 18:38:23 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
pP = GameServer()->m_apPlayers[i];
|
2010-05-31 20:35:47 +00:00
|
|
|
PD = absolute((aTScore[M^1]+aPScore[i]) - (aTScore[M]-aPScore[i]));
|
2008-10-19 18:38:23 +00:00
|
|
|
}
|
2008-09-07 08:10:56 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-06-06 22:08:40 +00:00
|
|
|
// move the player to the other team
|
2010-10-09 17:14:42 +00:00
|
|
|
int Temp = pP->m_LastActionTick;
|
2010-05-29 07:25:38 +00:00
|
|
|
pP->SetTeam(M^1);
|
2010-10-09 17:14:42 +00:00
|
|
|
pP->m_LastActionTick = Temp;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
pP->Respawn();
|
|
|
|
pP->m_ForceBalanced = true;
|
|
|
|
} while (--NumBalance);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ForceBalanced = true;
|
2008-10-19 18:38:23 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
m_UnbalancedTick = -1;
|
2008-09-07 08:10:56 +00:00
|
|
|
}
|
2010-07-29 05:21:18 +00:00
|
|
|
*/
|
2010-10-09 17:14:42 +00:00
|
|
|
// check for inactive players
|
|
|
|
if(g_Config.m_SvInactiveKickTime > 0)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; ++i)
|
|
|
|
{
|
2012-01-08 14:26:37 +00:00
|
|
|
#ifdef CONF_DEBUG
|
|
|
|
if(g_Config.m_DbgDummies)
|
|
|
|
{
|
|
|
|
if(i >= MAX_CLIENTS-g_Config.m_DbgDummies)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2011-01-03 11:50:38 +00:00
|
|
|
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS && !Server()->IsAuthed(i))
|
2010-10-09 17:14:42 +00:00
|
|
|
{
|
|
|
|
if(Server()->Tick() > GameServer()->m_apPlayers[i]->m_LastActionTick+g_Config.m_SvInactiveKickTime*Server()->TickSpeed()*60)
|
|
|
|
{
|
|
|
|
switch(g_Config.m_SvInactiveKick)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
{
|
|
|
|
// move player to spectator
|
2011-01-03 11:50:38 +00:00
|
|
|
GameServer()->m_apPlayers[i]->SetTeam(TEAM_SPECTATORS);
|
2010-10-09 17:14:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
// move player to spectator if the reserved slots aren't filled yet, kick him otherwise
|
|
|
|
int Spectators = 0;
|
|
|
|
for(int j = 0; j < MAX_CLIENTS; ++j)
|
2011-01-03 11:50:38 +00:00
|
|
|
if(GameServer()->m_apPlayers[j] && GameServer()->m_apPlayers[j]->GetTeam() == TEAM_SPECTATORS)
|
2010-10-09 17:14:42 +00:00
|
|
|
++Spectators;
|
|
|
|
if(Spectators >= g_Config.m_SvSpectatorSlots)
|
2010-11-16 23:44:04 +00:00
|
|
|
Server()->Kick(i, "Kicked for inactivity");
|
2010-10-09 17:14:42 +00:00
|
|
|
else
|
2011-01-03 11:50:38 +00:00
|
|
|
GameServer()->m_apPlayers[i]->SetTeam(TEAM_SPECTATORS);
|
2010-10-09 17:14:42 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
// kick the player
|
|
|
|
Server()->Kick(i, "Kicked for inactivity");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-06-19 15:32:00 +00:00
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
//DoWincheck();
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2008-08-31 14:37:35 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
/*bool IGameController::IsTeamplay() const
|
2008-08-31 14:37:35 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
return m_GameFlags&GAMEFLAG_TEAMS;
|
2011-04-09 06:41:31 +00:00
|
|
|
}*/
|
2008-08-31 14:37:35 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void IGameController::Snap(int SnappingClient)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2011-03-04 16:08:10 +00:00
|
|
|
CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo));
|
|
|
|
if(!pGameInfoObj)
|
2010-12-16 02:29:08 +00:00
|
|
|
return;
|
|
|
|
|
2011-03-04 16:08:10 +00:00
|
|
|
pGameInfoObj->m_GameFlags = m_GameFlags;
|
|
|
|
pGameInfoObj->m_GameStateFlags = 0;
|
|
|
|
if(m_GameOverTick != -1)
|
|
|
|
pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_GAMEOVER;
|
|
|
|
if(m_SuddenDeath)
|
|
|
|
pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_SUDDENDEATH;
|
|
|
|
if(GameServer()->m_World.m_Paused)
|
|
|
|
pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_PAUSED;
|
|
|
|
pGameInfoObj->m_RoundStartTick = m_RoundStartTick;
|
|
|
|
pGameInfoObj->m_WarmupTimer = m_Warmup;
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
//pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit;
|
|
|
|
//pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
pGameInfoObj->m_RoundNum = /*(str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap :*/ 0;
|
2011-03-04 16:08:10 +00:00
|
|
|
pGameInfoObj->m_RoundCurrent = m_RoundCount+1;
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
|
|
|
|
CCharacter *pChr;
|
|
|
|
CPlayer *pPlayer = GameServer()->m_apPlayers[SnappingClient];
|
2012-02-14 20:38:06 +00:00
|
|
|
if(pPlayer && (pPlayer->m_TimerType == 0 || pPlayer->m_TimerType == 2) && SnappingClient >= 0)
|
Added the following settings to Close #123.
sv_time_in_broadcast, 1, 0, 1, CFGFLAG_SERVER, "Whether to display time in broadcast every interval or not by default, later the choice can be changed by players via chat commands"
sv_time_in_broadcast_interval, 1, 0, 60, CFGFLAG_SERVER, "How often to update the broadcast time"
sv_time_in_gametimer, 0, 0, 1, CFGFLAG_SERVER, "Whether to display time in the round/game timer or not by default, later the choice can be changed by players via chat commands"
Added the following Chat commands to give the player the choice over their settings:
"saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race"
"saytimeall", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTimeAll, this, "Publicly messages everyone your current time in this current running race"
"time", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTime, this, "Privately shows you your current time in this current running race in the broadcast message"
"broadcasttime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetBroadcastTime, this, "Personal Setting of showing time in the broadcast, broadcasttime s, where s = on for on, off for off, toggle for toggle and nothing to show current status"
"servergametime", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSetServerGameTime, this, "Personal Setting of showing time in the round/game timer, servergametime s, where s = on for on off for off, toggle for toggle and nothing to show current status"
Fixed Chat Command "eyeemote" and made it a set + toggle instead of just toggle for better bin techneques
Moved some vars from CCharacter to CPlayer to keep their status evern after death but not after disconnect.
So now players have the choice to see which timer they wanna see if any.
Note: These changes are all untested Stay away from this update on your main server until they are tested, i don't even know if they will compile propperly
2011-12-29 12:17:34 +00:00
|
|
|
if((pChr = pPlayer->GetCharacter()))
|
|
|
|
pGameInfoObj->m_RoundStartTick = (pChr->m_DDRaceState == DDRACE_STARTED)?pChr->m_StartTime:m_RoundStartTick;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
int IGameController::GetAutoTeam(int NotThisID)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2008-12-19 08:26:58 +00:00
|
|
|
// this will force the auto balancer to work overtime aswell
|
2010-05-29 07:25:38 +00:00
|
|
|
if(g_Config.m_DbgStress)
|
2008-12-19 08:26:58 +00:00
|
|
|
return 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int aNumplayers[2] = {0,0};
|
2007-10-05 00:05:21 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2011-02-12 10:40:36 +00:00
|
|
|
if(GameServer()->m_apPlayers[i] && i != NotThisID)
|
2007-10-05 00:05:21 +00:00
|
|
|
{
|
2011-01-03 11:50:38 +00:00
|
|
|
if(GameServer()->m_apPlayers[i]->GetTeam() >= TEAM_RED && GameServer()->m_apPlayers[i]->GetTeam() <= TEAM_BLUE)
|
2010-05-29 07:25:38 +00:00
|
|
|
aNumplayers[GameServer()->m_apPlayers[i]->GetTeam()]++;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int Team = 0;
|
2010-07-29 05:21:18 +00:00
|
|
|
//if(IsTeamplay())
|
2011-01-04 20:30:15 +00:00
|
|
|
//Team = aNumplayers[TEAM_RED] > aNumplayers[TEAM_BLUE] ? TEAM_BLUE : TEAM_RED;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
if(CanJoinTeam(Team, NotThisID))
|
2010-05-29 07:25:38 +00:00
|
|
|
return Team;
|
2008-03-23 14:59:58 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
bool IGameController::CanJoinTeam(int Team, int NotThisID)
|
2008-03-23 14:59:58 +00:00
|
|
|
{
|
2011-02-12 10:40:36 +00:00
|
|
|
if(Team == TEAM_SPECTATORS || (GameServer()->m_apPlayers[NotThisID] && GameServer()->m_apPlayers[NotThisID]->GetTeam() != TEAM_SPECTATORS))
|
2010-05-29 07:25:38 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
int aNumplayers[2] = {0,0};
|
2008-03-23 14:59:58 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2011-02-12 10:40:36 +00:00
|
|
|
if(GameServer()->m_apPlayers[i] && i != NotThisID)
|
2008-03-23 14:59:58 +00:00
|
|
|
{
|
2011-01-03 11:50:38 +00:00
|
|
|
if(GameServer()->m_apPlayers[i]->GetTeam() >= TEAM_RED && GameServer()->m_apPlayers[i]->GetTeam() <= TEAM_BLUE)
|
2010-05-29 07:25:38 +00:00
|
|
|
aNumplayers[GameServer()->m_apPlayers[i]->GetTeam()]++;
|
2008-03-23 14:59:58 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-12-04 15:51:33 +00:00
|
|
|
return (aNumplayers[0] + aNumplayers[1]) < Server()->MaxClients()-g_Config.m_SvSpectatorSlots;
|
2007-10-05 00:05:21 +00:00
|
|
|
}
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
/*bool IGameController::CheckTeamBalance()
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime)
|
2008-09-07 08:10:56 +00:00
|
|
|
return true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int aT[2] = {0, 0};
|
2008-09-07 08:10:56 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CPlayer *pP = GameServer()->m_apPlayers[i];
|
2011-01-03 11:50:38 +00:00
|
|
|
if(pP && pP->GetTeam() != TEAM_SPECTATORS)
|
2010-05-29 07:25:38 +00:00
|
|
|
aT[pP->GetTeam()]++;
|
2008-09-07 08:10:56 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-17 22:06:00 +00:00
|
|
|
char aBuf[256];
|
2010-05-29 07:25:38 +00:00
|
|
|
if(absolute(aT[0]-aT[1]) >= 2)
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2011-01-17 11:56:49 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "Teams are NOT balanced (red=%d blue=%d)", aT[0], aT[1]);
|
2010-08-17 22:06:00 +00:00
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
2010-05-29 07:25:38 +00:00
|
|
|
if(GameServer()->m_pController->m_UnbalancedTick == -1)
|
|
|
|
GameServer()->m_pController->m_UnbalancedTick = Server()->Tick();
|
2008-09-07 08:10:56 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-01-17 11:56:49 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "Teams are balanced (red=%d blue=%d)", aT[0], aT[1]);
|
2010-08-17 22:06:00 +00:00
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
2010-05-29 07:25:38 +00:00
|
|
|
GameServer()->m_pController->m_UnbalancedTick = -1;
|
2008-09-07 08:10:56 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam)
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int aT[2] = {0, 0};
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-03 11:50:38 +00:00
|
|
|
if (!IsTeamplay() || JoinTeam == TEAM_SPECTATORS || !g_Config.m_SvTeambalanceTime)
|
2008-09-07 08:10:56 +00:00
|
|
|
return true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-09-07 08:10:56 +00:00
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CPlayer *pP = GameServer()->m_apPlayers[i];
|
2011-01-03 11:50:38 +00:00
|
|
|
if(pP && pP->GetTeam() != TEAM_SPECTATORS)
|
2010-05-29 07:25:38 +00:00
|
|
|
aT[pP->GetTeam()]++;
|
2008-09-07 08:10:56 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-09-07 08:10:56 +00:00
|
|
|
// simulate what would happen if changed team
|
2010-05-29 07:25:38 +00:00
|
|
|
aT[JoinTeam]++;
|
2011-01-03 11:50:38 +00:00
|
|
|
if (pPlayer->GetTeam() != TEAM_SPECTATORS)
|
2010-05-29 07:25:38 +00:00
|
|
|
aT[JoinTeam^1]--;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-09-07 08:10:56 +00:00
|
|
|
// there is a player-difference of at least 2
|
2010-05-29 07:25:38 +00:00
|
|
|
if(absolute(aT[0]-aT[1]) >= 2)
|
2008-09-07 08:10:56 +00:00
|
|
|
{
|
|
|
|
// player wants to join team with less players
|
2011-01-03 11:50:38 +00:00
|
|
|
if ((aT[0] < aT[1] && JoinTeam == TEAM_RED) || (aT[0] > aT[1] && JoinTeam == TEAM_BLUE))
|
2008-09-07 08:10:56 +00:00
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2011-06-19 15:32:00 +00:00
|
|
|
void IGameController::DoWincheck()
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2011-07-04 16:30:24 +00:00
|
|
|
if(m_GameOverTick == -1 && !m_Warmup && !GameServer()->m_World.m_ResetRequested)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2011-06-19 15:32:00 +00:00
|
|
|
if(IsTeamplay())
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2011-06-19 15:32:00 +00:00
|
|
|
// check score win condition
|
|
|
|
if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[TEAM_RED] >= g_Config.m_SvScorelimit || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvScorelimit)) ||
|
|
|
|
(g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2011-06-19 15:32:00 +00:00
|
|
|
if(m_aTeamscore[TEAM_RED] != m_aTeamscore[TEAM_BLUE])
|
|
|
|
EndRound();
|
|
|
|
else
|
|
|
|
m_SuddenDeath = 1;
|
2008-01-17 23:09:49 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-19 15:32:00 +00:00
|
|
|
else
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2011-08-13 00:11:06 +00:00
|
|
|
// gather some stats
|
|
|
|
int Topscore = 0;
|
|
|
|
int TopscoreCount = 0;
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
{
|
|
|
|
if(GameServer()->m_apPlayers[i])
|
2011-06-19 15:32:00 +00:00
|
|
|
{
|
2011-08-13 00:11:06 +00:00
|
|
|
if(GameServer()->m_apPlayers[i]->m_Score > Topscore)
|
2011-06-19 15:32:00 +00:00
|
|
|
{
|
2011-08-13 00:11:06 +00:00
|
|
|
Topscore = GameServer()->m_apPlayers[i]->m_Score;
|
|
|
|
TopscoreCount = 1;
|
2011-06-19 15:32:00 +00:00
|
|
|
}
|
2011-08-13 00:11:06 +00:00
|
|
|
else if(GameServer()->m_apPlayers[i]->m_Score == Topscore)
|
|
|
|
TopscoreCount++;
|
2011-06-19 15:32:00 +00:00
|
|
|
}
|
2011-08-13 00:11:06 +00:00
|
|
|
}
|
2008-01-17 23:09:49 +00:00
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
// check score win condition
|
|
|
|
if((g_Config.m_SvScorelimit > 0 && Topscore >= g_Config.m_SvScorelimit) ||
|
|
|
|
(g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
|
|
|
|
{
|
|
|
|
if(TopscoreCount == 1)
|
|
|
|
EndRound();
|
|
|
|
else
|
|
|
|
m_SuddenDeath = 1;
|
|
|
|
}
|
2007-11-26 20:47:49 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-13 00:11:06 +00:00
|
|
|
}
|
2010-07-29 05:21:18 +00:00
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
*/
|
2010-05-29 07:25:38 +00:00
|
|
|
int IGameController::ClampTeam(int Team)
|
2007-12-18 23:21:57 +00:00
|
|
|
{
|
2011-01-03 11:50:38 +00:00
|
|
|
if(Team < 0)
|
|
|
|
return TEAM_SPECTATORS;
|
2010-07-29 05:21:18 +00:00
|
|
|
//if(IsTeamplay())
|
2011-01-29 00:59:50 +00:00
|
|
|
//return Team&1;
|
2011-01-03 11:50:38 +00:00
|
|
|
return 0;
|
2010-08-20 20:40:12 +00:00
|
|
|
}
|