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. */
|
2008-08-14 18:46:52 +00:00
|
|
|
#include <new>
|
2011-01-18 18:09:53 +00:00
|
|
|
#include <engine/shared/config.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "player.h"
|
2008-08-14 18:46:52 +00:00
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
#include <engine/server.h>
|
2010-07-30 12:50:09 +00:00
|
|
|
#include <engine/server/server.h>
|
2010-07-29 05:21:18 +00:00
|
|
|
#include "gamecontext.h"
|
|
|
|
#include <game/gamecore.h>
|
2010-07-29 14:53:25 +00:00
|
|
|
#include "gamemodes/DDRace.h"
|
2011-03-22 19:56:52 +00:00
|
|
|
#include <stdio.h>
|
2008-08-14 18:46:52 +00:00
|
|
|
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
MACRO_ALLOC_POOL_ID_IMPL(CPlayer, MAX_CLIENTS)
|
2008-08-14 18:46:52 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
IServer *CPlayer::Server() const { return m_pGameServer->Server(); }
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, int Team)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pGameServer = pGameServer;
|
|
|
|
m_RespawnTick = Server()->Tick();
|
|
|
|
m_DieTick = Server()->Tick();
|
2010-05-31 20:35:47 +00:00
|
|
|
m_ScoreStartTick = Server()->Tick();
|
2010-05-29 07:25:38 +00:00
|
|
|
Character = 0;
|
2011-02-12 10:40:36 +00:00
|
|
|
this->m_ClientID = ClientID;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Team = GameServer()->m_pController->ClampTeam(Team);
|
2011-03-10 09:08:14 +00:00
|
|
|
m_SpectatorID = SPEC_FREEVIEW;
|
2010-10-09 17:14:42 +00:00
|
|
|
m_LastActionTick = Server()->Tick();
|
2011-04-09 06:41:31 +00:00
|
|
|
|
|
|
|
// DDRace
|
|
|
|
|
2011-03-22 19:49:12 +00:00
|
|
|
m_LastPlaytime = time_get();
|
|
|
|
m_LastTarget_x = 0;
|
|
|
|
m_LastTarget_y = 0;
|
|
|
|
m_SentAfkWarning = 0;
|
|
|
|
m_SentAfkWarning2 = 0;
|
2011-02-03 13:39:00 +00:00
|
|
|
m_ChatScore = 0;
|
2010-08-22 13:17:57 +00:00
|
|
|
m_PauseInfo.m_Respawn = false;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-02-13 05:35:13 +00:00
|
|
|
GameServer()->Score()->PlayerData(ClientID)->Reset();
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-09-14 16:56:28 +00:00
|
|
|
m_Invisible = false;
|
2010-10-29 21:28:15 +00:00
|
|
|
m_IsUsingDDRaceClient = false;
|
2011-01-06 05:08:12 +00:00
|
|
|
m_ShowOthers = false;
|
2010-12-13 22:16:53 +00:00
|
|
|
|
|
|
|
// Variable initialized:
|
|
|
|
m_Last_Pause = 0;
|
2011-01-24 20:22:04 +00:00
|
|
|
m_Last_Team = 0;
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CPlayer::~CPlayer()
|
2008-09-24 09:03:49 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
delete Character;
|
|
|
|
Character = 0;
|
2008-09-24 09:03:49 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::Tick()
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2011-01-18 18:09:53 +00:00
|
|
|
#ifdef CONF_DEBUG
|
|
|
|
if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
|
|
|
|
#endif
|
2010-09-21 23:00:33 +00:00
|
|
|
if(!Server()->ClientIngame(m_ClientID))
|
|
|
|
return;
|
|
|
|
|
2011-02-03 13:39:00 +00:00
|
|
|
if (m_ChatScore > 0)
|
|
|
|
m_ChatScore--;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
Server()->SetClientScore(m_ClientID, m_Score);
|
2008-08-14 18:46:52 +00:00
|
|
|
|
|
|
|
// do latency stuff
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
IServer::CClientInfo Info;
|
|
|
|
if(Server()->GetClientInfo(m_ClientID, &Info))
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Latency.m_Accum += Info.m_Latency;
|
|
|
|
m_Latency.m_AccumMax = max(m_Latency.m_AccumMax, Info.m_Latency);
|
|
|
|
m_Latency.m_AccumMin = min(m_Latency.m_AccumMin, Info.m_Latency);
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
// each second
|
|
|
|
if(Server()->Tick()%Server()->TickSpeed() == 0)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Latency.m_Avg = m_Latency.m_Accum/Server()->TickSpeed();
|
|
|
|
m_Latency.m_Max = m_Latency.m_AccumMax;
|
|
|
|
m_Latency.m_Min = m_Latency.m_AccumMin;
|
|
|
|
m_Latency.m_Accum = 0;
|
|
|
|
m_Latency.m_AccumMin = 1000;
|
|
|
|
m_Latency.m_AccumMax = 0;
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!Character && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick())
|
|
|
|
m_Spawning = true;
|
2008-09-24 14:54:51 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Character)
|
2008-09-24 14:54:51 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Character->IsAlive())
|
2008-09-24 14:54:51 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ViewPos = Character->m_Pos;
|
2008-09-24 14:54:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
delete Character;
|
|
|
|
Character = 0;
|
2008-09-24 14:54:51 +00:00
|
|
|
}
|
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(m_Spawning && m_RespawnTick <= Server()->Tick())
|
|
|
|
TryRespawn();
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2011-03-10 09:08:14 +00:00
|
|
|
void CPlayer::PostTick()
|
|
|
|
{
|
|
|
|
// update latency value
|
|
|
|
if(m_PlayerFlags&PLAYERFLAG_SCOREBOARD)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; ++i)
|
|
|
|
{
|
|
|
|
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
|
|
|
|
m_aActLatency[i] = GameServer()->m_apPlayers[i]->m_Latency.m_Min;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// update view pos for spectators
|
|
|
|
if(m_Team == TEAM_SPECTATORS && m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID])
|
|
|
|
m_ViewPos = GameServer()->m_apPlayers[m_SpectatorID]->m_ViewPos;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::Snap(int SnappingClient)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2011-01-18 18:09:53 +00:00
|
|
|
#ifdef CONF_DEBUG
|
|
|
|
if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
|
|
|
|
#endif
|
2010-09-21 23:00:33 +00:00
|
|
|
if(!Server()->ClientIngame(m_ClientID))
|
|
|
|
return;
|
|
|
|
|
2010-12-16 02:29:08 +00:00
|
|
|
CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, m_ClientID, sizeof(CNetObj_ClientInfo)));
|
|
|
|
if(!pClientInfo)
|
|
|
|
return;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
2011-03-15 10:23:49 +00:00
|
|
|
StrToInts(&pClientInfo->m_Name0, 4, Server()->ClientName(m_ClientID));
|
|
|
|
StrToInts(&pClientInfo->m_Clan0, 3, Server()->ClientClan(m_ClientID));
|
|
|
|
pClientInfo->m_Country = Server()->ClientCountry(m_ClientID);
|
2010-12-16 02:29:08 +00:00
|
|
|
StrToInts(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_SkinName);
|
|
|
|
pClientInfo->m_UseCustomColor = m_TeeInfos.m_UseCustomColor;
|
|
|
|
pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
|
|
|
|
pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
|
2010-08-23 19:37:27 +00:00
|
|
|
|
2010-12-16 02:29:08 +00:00
|
|
|
CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, m_ClientID, sizeof(CNetObj_PlayerInfo)));
|
|
|
|
if(!pPlayerInfo)
|
|
|
|
return;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
2011-03-01 17:31:20 +00:00
|
|
|
pPlayerInfo->m_Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
|
2010-12-16 02:29:08 +00:00
|
|
|
pPlayerInfo->m_Local = 0;
|
2011-02-12 10:40:36 +00:00
|
|
|
pPlayerInfo->m_ClientID = m_ClientID;
|
2010-12-16 02:29:08 +00:00
|
|
|
pPlayerInfo->m_Score = m_Score;
|
|
|
|
pPlayerInfo->m_Team = m_Team;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
|
|
|
if(m_ClientID == SnappingClient)
|
2011-03-10 09:08:14 +00:00
|
|
|
pPlayerInfo->m_Local = 1;
|
|
|
|
|
2011-03-12 17:07:57 +00:00
|
|
|
if(m_ClientID == SnappingClient && m_Team == TEAM_SPECTATORS)
|
2011-03-10 09:08:14 +00:00
|
|
|
{
|
|
|
|
CNetObj_SpectatorInfo *pSpectatorInfo = static_cast<CNetObj_SpectatorInfo *>(Server()->SnapNewItem(NETOBJTYPE_SPECTATORINFO, m_ClientID, sizeof(CNetObj_SpectatorInfo)));
|
|
|
|
if(!pSpectatorInfo)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pSpectatorInfo->m_SpectatorID = m_SpectatorID;
|
|
|
|
pSpectatorInfo->m_X = m_ViewPos.x;
|
|
|
|
pSpectatorInfo->m_Y = m_ViewPos.y;
|
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-10-11 18:53:56 +00:00
|
|
|
// send 0 if times of others are not shown
|
|
|
|
if(SnappingClient != m_ClientID && g_Config.m_SvHideScore)
|
2010-12-16 04:06:23 +00:00
|
|
|
pPlayerInfo->m_Score = 0;
|
2010-08-23 19:37:27 +00:00
|
|
|
else
|
2010-12-16 04:06:23 +00:00
|
|
|
pPlayerInfo->m_Score = m_Score;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-12-16 04:06:23 +00:00
|
|
|
pPlayerInfo->m_Team = m_Team;
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2011-02-14 18:41:32 +00:00
|
|
|
void CPlayer::OnDisconnect(const char *pReason)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
KillCharacter();
|
|
|
|
|
|
|
|
if(Server()->ClientIngame(m_ClientID))
|
|
|
|
{
|
2010-12-23 05:57:26 +00:00
|
|
|
char aBuf[512];
|
2011-02-14 18:41:32 +00:00
|
|
|
if(pReason && *pReason)
|
2011-04-13 18:37:12 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "'%s' has left the game (%s)", Server()->ClientName(m_ClientID), pReason);
|
2011-02-14 18:41:32 +00:00
|
|
|
else
|
2011-04-13 18:37:12 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "'%s' has left the game", Server()->ClientName(m_ClientID));
|
2010-12-23 05:57:26 +00:00
|
|
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
2011-01-29 00:59:50 +00:00
|
|
|
|
2010-12-23 05:57:26 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "leave player='%d:%s'", m_ClientID, Server()->ClientName(m_ClientID));
|
|
|
|
GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "game", aBuf);
|
2010-05-29 07:25:38 +00:00
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-02-14 21:34:46 +00:00
|
|
|
CGameControllerDDRace* Controller = (CGameControllerDDRace*)GameServer()->m_pController;
|
|
|
|
Controller->m_Teams.m_Core.Team(m_ClientID, 0);
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::OnPredictedInput(CNetObj_PlayerInput *NewInput)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Character)
|
|
|
|
Character->OnPredictedInput(NewInput);
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2011-03-01 17:31:20 +00:00
|
|
|
m_PlayerFlags = NewInput->m_PlayerFlags;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Character)
|
|
|
|
Character->OnDirectInput(NewInput);
|
2008-08-14 18:46:52 +00:00
|
|
|
|
2011-01-03 11:50:38 +00:00
|
|
|
if(!Character && m_Team != TEAM_SPECTATORS && (NewInput->m_Fire&1))
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Spawning = true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-03-10 09:08:14 +00:00
|
|
|
if(!Character && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW)
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ViewPos = vec2(NewInput->m_TargetX, NewInput->m_TargetY);
|
2010-10-10 12:36:56 +00:00
|
|
|
|
2010-10-09 17:14:42 +00:00
|
|
|
// check for activity
|
|
|
|
if(NewInput->m_Direction || m_LatestActivity.m_TargetX != NewInput->m_TargetX ||
|
|
|
|
m_LatestActivity.m_TargetY != NewInput->m_TargetY || NewInput->m_Jump ||
|
|
|
|
NewInput->m_Fire&1 || NewInput->m_Hook)
|
|
|
|
{
|
|
|
|
m_LatestActivity.m_TargetX = NewInput->m_TargetX;
|
|
|
|
m_LatestActivity.m_TargetY = NewInput->m_TargetY;
|
|
|
|
m_LastActionTick = Server()->Tick();
|
|
|
|
}
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CCharacter *CPlayer::GetCharacter()
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Character && Character->IsAlive())
|
|
|
|
return Character;
|
2008-08-14 18:46:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::KillCharacter(int Weapon)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Character)
|
2008-09-23 18:08:19 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Character->Die(m_ClientID, Weapon);
|
|
|
|
delete Character;
|
|
|
|
Character = 0;
|
2008-09-23 18:08:19 +00:00
|
|
|
}
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::Respawn()
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2011-01-03 11:50:38 +00:00
|
|
|
if(m_Team != TEAM_SPECTATORS)
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Spawning = true;
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::SetTeam(int Team)
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
|
|
|
// clamp the team
|
2010-05-29 07:25:38 +00:00
|
|
|
Team = GameServer()->m_pController->ClampTeam(Team);
|
|
|
|
if(m_Team == Team)
|
2008-08-14 18:46:52 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-08-17 22:06:00 +00:00
|
|
|
char aBuf[512];
|
2010-09-12 11:34:30 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "'%s' joined the %s", Server()->ClientName(m_ClientID), GameServer()->m_pController->GetTeamName(Team));
|
2011-04-13 18:37:12 +00:00
|
|
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
KillCharacter();
|
2010-06-03 14:35:18 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Team = Team;
|
2010-10-09 17:14:42 +00:00
|
|
|
m_LastActionTick = Server()->Tick();
|
2010-05-29 07:25:38 +00:00
|
|
|
// we got to wait 0.5 secs before respawning
|
|
|
|
m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
|
2010-11-12 21:50:51 +00:00
|
|
|
//str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' m_Team=%d", m_ClientID, Server()->ClientName(m_ClientID), m_Team);
|
|
|
|
//GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-07-29 05:21:18 +00:00
|
|
|
//GameServer()->m_pController->OnPlayerInfoChange(GameServer()->m_apPlayers[m_ClientID]);
|
2011-03-28 21:45:47 +00:00
|
|
|
|
|
|
|
if(Team == TEAM_SPECTATORS)
|
|
|
|
{
|
|
|
|
// update spectator modes
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; ++i)
|
|
|
|
{
|
|
|
|
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
|
|
|
|
GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
|
|
|
|
}
|
|
|
|
}
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CPlayer::TryRespawn()
|
2008-08-14 18:46:52 +00:00
|
|
|
{
|
2010-09-17 06:05:27 +00:00
|
|
|
if(m_PauseInfo.m_Respawn)
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Character = new(m_ClientID) CCharacter(&GameServer()->m_World);
|
2010-08-22 13:17:57 +00:00
|
|
|
Character->Spawn(this, m_PauseInfo.m_Core.m_Pos);
|
2011-01-29 00:59:50 +00:00
|
|
|
GameServer()->CreatePlayerSpawn(m_PauseInfo.m_Core.m_Pos, ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.TeamMask((m_PauseInfo.m_Team > 0 && m_PauseInfo.m_Team < TEAM_SUPER) ? m_PauseInfo.m_Team : 0));
|
2010-08-22 13:17:57 +00:00
|
|
|
LoadCharacter();
|
2010-09-17 06:05:27 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-02-14 07:43:44 +00:00
|
|
|
vec2 SpawnPos;
|
2008-08-14 18:46:52 +00:00
|
|
|
|
2011-02-14 07:43:44 +00:00
|
|
|
if(!GameServer()->m_pController->CanSpawn(m_Team, &SpawnPos))
|
2010-08-22 13:17:57 +00:00
|
|
|
return;
|
|
|
|
|
2011-02-14 07:43:44 +00:00
|
|
|
m_Spawning = false;
|
|
|
|
Character = new(m_ClientID) CCharacter(&GameServer()->m_World);
|
|
|
|
Character->Spawn(this, SpawnPos);
|
|
|
|
GameServer()->CreatePlayerSpawn(SpawnPos);
|
2008-08-14 18:46:52 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-29 19:55:33 +00:00
|
|
|
|
2010-09-17 09:34:13 +00:00
|
|
|
void CPlayer::LoadCharacter()
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
Character->SetCore(m_PauseInfo.m_Core);
|
2010-09-05 18:37:42 +00:00
|
|
|
if(g_Config.m_SvPauseTime)
|
|
|
|
Character->m_StartTime = Server()->Tick() - (m_PauseInfo.m_PauseTime - m_PauseInfo.m_StartTime);
|
2010-09-17 12:21:12 +00:00
|
|
|
else
|
|
|
|
Character->m_StartTime = m_PauseInfo.m_StartTime;
|
2010-10-29 21:28:15 +00:00
|
|
|
Character->m_DDRaceState = m_PauseInfo.m_DDRaceState;
|
2010-08-22 13:17:57 +00:00
|
|
|
Character->m_RefreshTime = Server()->Tick();
|
2010-09-17 09:34:13 +00:00
|
|
|
for(int i = 0; i < NUM_WEAPONS; ++i)
|
|
|
|
{
|
2010-08-22 22:46:39 +00:00
|
|
|
if(m_PauseInfo.m_aHasWeapon[i])
|
2010-12-07 17:44:23 +00:00
|
|
|
{
|
|
|
|
if(!m_PauseInfo.m_FreezeTime)
|
|
|
|
Character->GiveWeapon(i, -1);
|
|
|
|
else
|
|
|
|
Character->GiveWeapon(i, 0);
|
|
|
|
}
|
2010-08-22 13:17:57 +00:00
|
|
|
}
|
2010-08-22 22:04:26 +00:00
|
|
|
Character->m_FreezeTime = m_PauseInfo.m_FreezeTime;
|
2011-01-29 00:59:50 +00:00
|
|
|
Character->SetLastAction(Server()->Tick());
|
|
|
|
Character->SetArmor(m_PauseInfo.m_Armor);
|
2010-08-22 22:04:26 +00:00
|
|
|
Character->m_LastMove = m_PauseInfo.m_LastMove;
|
|
|
|
Character->m_PrevPos = m_PauseInfo.m_PrevPos;
|
2011-01-29 00:59:50 +00:00
|
|
|
Character->SetActiveWeapon(m_PauseInfo.m_ActiveWeapon);
|
|
|
|
Character->SetLastWeapon(m_PauseInfo.m_LastWeapon);
|
2010-08-22 22:04:26 +00:00
|
|
|
Character->m_HammerType = m_PauseInfo.m_HammerType;
|
|
|
|
Character->m_Super = m_PauseInfo.m_Super;
|
2011-01-14 13:37:02 +00:00
|
|
|
Character->m_DeepFreeze = m_PauseInfo.m_DeepFreeze;
|
2011-01-16 22:13:21 +00:00
|
|
|
Character->m_EndlessHook = m_PauseInfo.m_EndlessHook;
|
2010-11-22 07:21:02 +00:00
|
|
|
CGameControllerDDRace* Controller = (CGameControllerDDRace*)GameServer()->m_pController;
|
|
|
|
Controller->m_Teams.m_Core.Team(GetCID(), m_PauseInfo.m_Team);
|
2010-08-22 13:17:57 +00:00
|
|
|
m_PauseInfo.m_Respawn = false;
|
2010-09-17 06:05:27 +00:00
|
|
|
m_InfoSaved = false;
|
2010-08-22 13:17:57 +00:00
|
|
|
}
|
|
|
|
|
2010-08-22 22:04:26 +00:00
|
|
|
void CPlayer::SaveCharacter()
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
m_PauseInfo.m_Core = Character->GetCore();
|
2010-08-22 13:17:57 +00:00
|
|
|
m_PauseInfo.m_StartTime = Character->m_StartTime;
|
2010-10-29 21:28:15 +00:00
|
|
|
m_PauseInfo.m_DDRaceState = Character->m_DDRaceState;
|
2010-08-22 22:04:26 +00:00
|
|
|
for(int i = 0; i < WEAPON_NINJA; ++i)
|
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
m_PauseInfo.m_aHasWeapon[i] = Character->GetWeaponGot(i);
|
2010-08-22 13:17:57 +00:00
|
|
|
}
|
2010-08-22 22:04:26 +00:00
|
|
|
m_PauseInfo.m_FreezeTime=Character->m_FreezeTime;
|
2011-01-29 00:59:50 +00:00
|
|
|
m_PauseInfo.m_Armor = Character->GetArmor();
|
2010-08-22 22:04:26 +00:00
|
|
|
m_PauseInfo.m_LastMove = Character->m_LastMove;
|
|
|
|
m_PauseInfo.m_PrevPos = Character->m_PrevPos;
|
2011-01-29 00:59:50 +00:00
|
|
|
m_PauseInfo.m_ActiveWeapon = Character->GetActiveWeapon();
|
|
|
|
m_PauseInfo.m_LastWeapon = Character->GetLastWeapon();
|
2010-08-22 22:04:26 +00:00
|
|
|
m_PauseInfo.m_HammerType = Character->m_HammerType;
|
|
|
|
m_PauseInfo.m_Super = Character->m_Super;
|
2011-01-14 13:37:02 +00:00
|
|
|
m_PauseInfo.m_DeepFreeze = Character->m_DeepFreeze;
|
2011-01-16 22:13:21 +00:00
|
|
|
m_PauseInfo.m_EndlessHook = Character->m_EndlessHook;
|
2010-11-22 07:21:02 +00:00
|
|
|
CGameControllerDDRace* Controller = (CGameControllerDDRace*)GameServer()->m_pController;
|
|
|
|
m_PauseInfo.m_Team = Controller->m_Teams.m_Core.Team(GetCID());
|
2010-08-22 23:59:54 +00:00
|
|
|
m_PauseInfo.m_PauseTime = Server()->Tick();
|
2010-08-22 13:17:57 +00:00
|
|
|
//m_PauseInfo.m_RefreshTime = Character->m_RefreshTime;
|
|
|
|
}
|
2011-03-22 19:49:12 +00:00
|
|
|
|
|
|
|
void CPlayer::AfkTimer(int new_target_x, int new_target_y)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
afk timer (x, y = mouse coordinates)
|
|
|
|
Since a player has to move the mouse to play, this is a better method than checking
|
|
|
|
the player's position in the game world, because it can easily be bypassed by just locking a key.
|
|
|
|
Frozen players could be kicked as well, because they can't move.
|
|
|
|
It also works for spectators.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if(m_Authed) return; // don't kick admins
|
|
|
|
if(g_Config.m_SvMaxAfkTime == 0) return; // 0 = disabled
|
|
|
|
|
|
|
|
if(new_target_x != m_LastTarget_x || new_target_y != m_LastTarget_y)
|
|
|
|
{
|
|
|
|
m_LastPlaytime = time_get();
|
|
|
|
m_LastTarget_x = new_target_x;
|
|
|
|
m_LastTarget_y = new_target_y;
|
|
|
|
m_SentAfkWarning = 0; // afk timer's 1st warning after 50% of sv_max_afk_time
|
|
|
|
m_SentAfkWarning2 = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// not playing, check how long
|
|
|
|
if(m_SentAfkWarning == 0 && m_LastPlaytime < time_get()-time_freq()*(int)(g_Config.m_SvMaxAfkTime*0.5))
|
|
|
|
{
|
|
|
|
sprintf(
|
|
|
|
m_pAfkMsg,
|
|
|
|
"You have been afk for %d seconds now. Please note that you get kicked after not playing for %d seconds.",
|
|
|
|
(int)(g_Config.m_SvMaxAfkTime*0.5),
|
|
|
|
g_Config.m_SvMaxAfkTime
|
|
|
|
);
|
|
|
|
m_pGameServer->SendChatTarget(m_ClientID, m_pAfkMsg);
|
|
|
|
m_SentAfkWarning = 1;
|
|
|
|
} else if(m_SentAfkWarning2 == 0 && m_LastPlaytime < time_get()-time_freq()*(int)(g_Config.m_SvMaxAfkTime*0.9))
|
|
|
|
{
|
|
|
|
sprintf(
|
|
|
|
m_pAfkMsg,
|
|
|
|
"You have been afk for %d seconds now. Please note that you get kicked after not playing for %d seconds.",
|
|
|
|
(int)(g_Config.m_SvMaxAfkTime*0.9),
|
|
|
|
g_Config.m_SvMaxAfkTime
|
|
|
|
);
|
|
|
|
m_pGameServer->SendChatTarget(m_ClientID, m_pAfkMsg);
|
|
|
|
m_SentAfkWarning = 1;
|
|
|
|
} else if(m_LastPlaytime < time_get()-time_freq()*g_Config.m_SvMaxAfkTime)
|
|
|
|
{
|
|
|
|
CServer* serv = (CServer*)m_pGameServer->Server();
|
|
|
|
serv->Kick(m_ClientID,"Away from keyboard");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|