Teams with leaders

this maybe buggy but i will fix the bugs when they are reported
This commit is contained in:
GreYFoXGTi 2011-02-02 12:49:19 +02:00
parent ff839af9ba
commit 30f010593c
11 changed files with 425 additions and 101 deletions

3
license DDRace.txt Normal file
View file

@ -0,0 +1,3 @@
Copyright (c) 2010-2011 Shereef Marzouk
This code was originally by Magnus Auvinen and we work also under the same license.
available to you in license.txt

View file

@ -190,4 +190,7 @@ MACRO_CONFIG_INT(BrFilterPlayerHitting, br_filter_player_hitting, 0, 0, 2, CFGFL
MACRO_CONFIG_INT(BrFilterEndlessHooking, br_filter_endless_hooking, 0, 0, 2, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering player endless hooking (default: 0 don't care, 1 must be Off, 2 must be On)", -1)
MACRO_CONFIG_INT(BrFilterTestMap, br_filter_test_map, 0, 0, 2, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering Test Maps (default: 0 don't care, 1 must be Off, 2 must be On)", -1)
MACRO_CONFIG_INT(BrFilterTestServer, br_filter_test_server, 0, 0, 2, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering Test Servers (default: 0 don't care, 1 must be Off, 2 must be On)", -1)
MACRO_CONFIG_INT(SvTeamAskTime, sv_team_ask_time, 10, 0, 9999, CFGFLAG_SERVER, "How much time the player has to accept or refuse", 3)
MACRO_CONFIG_INT(SvAllowTeamLeader, sv_allow_team_leader, 1, 0, 1, CFGFLAG_SERVER, "Whether the admin allows teams to have leaders or not", 4)
#endif

View file

@ -1,3 +1,4 @@
/* (c) Shereef Marzouk. See "licence DDRace.txt" and the readme.txt in the root of the distribution for more information. */
#ifndef GAME_SERVER_DDRACECOMMANDS_H
#define GAME_SERVER_DDRACECOMMANDS_H
#undef GAME_SERVER_DDRACECOMMANDS_H // this file can be included several times
@ -59,6 +60,11 @@ CONSOLE_COMMAND("team", "?i", CFGFLAG_SERVER, ConJoinTeam, this, "Lets you join
CONSOLE_COMMAND("top5", "?i", CFGFLAG_SERVER, ConTop5, this, "Shows five ranks of the ladder beginning with rank i (1 by default)", -1)
CONSOLE_COMMAND("showothers", "", CFGFLAG_SERVER, ConShowOthers, this, "Whether to showplayers from other teams or not (off by default)", -1)
CONSOLE_COMMAND("ask", "s", CFGFLAG_SERVER, ConAsk, this, "Ask to join a player in a team or to start one with him the asker is the leader if the player is not already in a team", -1)
CONSOLE_COMMAND("yes", "", CFGFLAG_SERVER, ConYes, this, "Reply yes", -1)
CONSOLE_COMMAND("no", "", CFGFLAG_SERVER, ConNo, this, "Reply no", -1)
CONSOLE_COMMAND("invite", "s", CFGFLAG_SERVER, ConInvite, this, "Invite a player to your team (You must be the leader)", -1)
#undef CONSOLE_COMMAND
#endif

View file

@ -1,3 +1,4 @@
/* (c) Shereef Marzouk. See "licence DDRace.txt" and the readme.txt in the root of the distribution for more information. */
#include "gamecontext.h"
#include <engine/shared/config.h>
#include <engine/server/server.h>
@ -821,39 +822,66 @@ void CGameContext::ConJoinTeam(IConsole::IResult *pResult, void *pUserData, int
{
CGameContext *pSelf = (CGameContext *)pUserData;
if(g_Config.m_SvTeam == -1) {
CGameControllerDDRace* Controller = (CGameControllerDDRace*)pSelf->m_pController;
if(g_Config.m_SvTeam == -1)
{
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Admin disable teams");
return;
} else if (g_Config.m_SvTeam == 1) {
}
else if (g_Config.m_SvTeam == 1)
{
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You must join to any team and play with anybody or you will not play");
}
CPlayer *pPlayer = pSelf->m_apPlayers[ClientId];
if(pResult->NumArguments() > 0)
{
int Team = pResult->GetInteger(0);
if(pPlayer->GetCharacter() == 0)
{
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can't change teams while you are dead/a spectator.");
}
else
{
if(((CGameControllerDDRace*)pSelf->m_pController)->m_Teams.SetCharacterTeam(pPlayer->GetCID(), pResult->GetInteger(0)))
if(pPlayer->m_Last_Team + pSelf->Server()->TickSpeed() * g_Config.m_SvTeamChangeDelay <= pSelf->Server()->Tick())
{
if(pPlayer->m_Last_Team + pSelf->Server()->TickSpeed() * g_Config.m_SvTeamChangeDelay <= pSelf->Server()->Tick())
{
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "%s joined team %d", pSelf->Server()->ClientName(pPlayer->GetCID()), pResult->GetInteger(0));
pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
pPlayer->m_Last_Team = pSelf->Server()->Tick();
}
if(Controller->m_Teams.GetTeamLeader(Team) == -1)
switch(Controller->m_Teams.SetCharacterTeam(pPlayer->GetCID(), Team))
{
case 0:
char aBuf[512];
pPlayer->m_Last_Team = pSelf->Server()->Tick();
break;
case CGameTeams::ERROR_ALREADY_THERE:
str_format(aBuf, sizeof(aBuf), "You are already in team %d...!", Team);
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf);
break;
case CGameTeams::ERROR_CLOSED:
str_format(aBuf, sizeof(aBuf), "Team %d is closed, they have to kill or finish for u to join.", Team);
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf);
break;
case CGameTeams::ERROR_NOT_SUPER:
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You are trying to join team Super but you are not super.");
break;
case CGameTeams::ERROR_STARTED:
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You already started, kill first.");
break;
case CGameTeams::ERROR_WRONG_PARAMS:
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "The wrong parameters were given.");
break;
default:
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You cannot join this team at this time");
}
else
{
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can\'t join teams that fast!");
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "Team %d is led by \'%s\', please ask him to join his team.", Team, pSelf->Server()->ClientName(Controller->m_Teams.GetTeamLeader(Team)));
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf);
}
}
else
{
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You cannot join this team at this time");
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can\'t change teams that fast!");
}
}
}
@ -971,3 +999,224 @@ void CGameContext::ConShowOthers(IConsole::IResult *pResult, void *pUserData, in
pSelf->SendChatTarget(ClientId, "Showing players from other teams is only available with DDRace Client, http://DDRace.info");
}
void CGameContext::ConAsk(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
char aBuf[512];
CServer* pServ = (CServer*)pSelf->Server();
const char *Name = pResult->GetString(0);
int Matches = 0;
int Victim = -1;
CCharacter* pAsker = pSelf->m_apPlayers[ClientId]->GetCharacter();
CCharacter* pVictim;
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(pSelf->m_apPlayers[i] && i != ClientId && !str_comp_nocase(pServ->ClientName(i), Name))
{
Victim = i;
pVictim = pSelf->m_apPlayers[i]->GetCharacter();
Matches = 1;
pSelf->SendChatTarget(ClientId, "Exact Match found");
break;
}
else if(pSelf->m_apPlayers[i] && i != ClientId && str_find_nocase(pServ->ClientName(i), Name))
{
Victim = i;
pVictim = pSelf->m_apPlayers[i]->GetCharacter();
Matches++;
}
}
if(!pAsker || !pAsker->IsAlive())
str_format(aBuf, sizeof(aBuf), "You can\'t invite while dead.");
else if(pAsker->Team())
str_format(aBuf, sizeof(aBuf), "You already are in team %d, you can use /invite if you are the leader.", pAsker->Team());
else if(Matches > 1)
str_format(aBuf, sizeof(aBuf), "More Than one player matches the given string, maybe use auto complete (tab in any 0.5 trunk client)");
else if(Matches == 0)
str_format(aBuf, sizeof(aBuf), "No matches found.");
else if(pAsker->m_DDRaceState != DDRACE_NONE)
str_format(aBuf, sizeof(aBuf), "You can't start a team at this time, please kill.");
else if(!pVictim || !pVictim->IsAlive())
str_format(aBuf, sizeof(aBuf), "You can\'t invite him while he is dead.");
else if(pVictim->m_DDRaceState != DDRACE_NONE)
str_format(aBuf, sizeof(aBuf), "He can't change teams at this time, please tell him to kill.");
else if(pSelf->m_apPlayers[Victim]->m_Asker != -1 && pSelf->m_apPlayers[Victim]->m_AskedTick > pSelf->Server()->Tick() - g_Config.m_SvTeamAskTime)
str_format(aBuf, sizeof(aBuf), "\'%s\' is already being asked wait for %.1f seconds.", pServ->ClientName(Victim), (pSelf->m_apPlayers[Victim]->m_AskedTick + g_Config.m_SvTeamAskTime * pSelf->Server()->TickSpeed() - pSelf->Server()->Tick()) / (float)pSelf->Server()->TickSpeed());
else if(pSelf->m_apPlayers[Victim]->m_Asked != -1 && pSelf->m_apPlayers[Victim]->m_AskerTick > pSelf->Server()->Tick() - g_Config.m_SvTeamAskTime)
str_format(aBuf, sizeof(aBuf), "\'%s\' is already is asking someone wait for %.1f seconds.", pServ->ClientName(Victim), (pSelf->m_apPlayers[Victim]->m_AskedTick + g_Config.m_SvTeamAskTime * pSelf->Server()->TickSpeed() - pSelf->Server()->Tick()) / (float)pSelf->Server()->TickSpeed());
else if(!pVictim->Team())
{
pSelf->m_apPlayers[Victim]->m_Asker = ClientId;
pSelf->m_apPlayers[Victim]->m_AskedTick = pSelf->Server()->Tick();
pSelf->m_apPlayers[ClientId]->m_Asked = Victim;
pSelf->m_apPlayers[ClientId]->m_AskerTick = pSelf->Server()->Tick();
char aTempBuf[512];
str_format(aTempBuf, sizeof(aTempBuf), "Do you want to start a team with \'%s\' as leader ?", pServ->ClientName(ClientId));
pSelf->SendChatTarget(Victim, aTempBuf);
str_format(aTempBuf, sizeof(aTempBuf), "Please say /yes or /no within %d seconds.", g_Config.m_SvTeamAskTime);
pSelf->SendChatTarget(Victim, aTempBuf);
str_format(aBuf, sizeof(aBuf), "\'%s\' has been asked to start a team with you as leader.", pServ->ClientName(Victim));
}
else if(pVictim->Team() && pAsker->Teams()->GetTeamLeader(pVictim->Team()) != Victim)
{
str_format(aBuf, sizeof(aBuf), "You can't ask a team member you can only ask a team leader, Team %d is led by \'%s\'.", pVictim->Team(), pServ->ClientName(Victim));
}
else if(pVictim->Team() && pAsker->Teams()->GetTeamState(pVictim->Team()) == CGameTeams::TEAMSTATE_OPEN)
{
pSelf->m_apPlayers[Victim]->m_Asker = ClientId;
pSelf->m_apPlayers[Victim]->m_AskedTick = pSelf->Server()->Tick();
pSelf->m_apPlayers[ClientId]->m_Asked = Victim;
pSelf->m_apPlayers[ClientId]->m_AskerTick = pSelf->Server()->Tick();
char aTempBuf[512];
str_format(aTempBuf, sizeof(aTempBuf), "%s wants to join your team ?", pServ->ClientName(ClientId));
pSelf->SendChatTarget(Victim, aTempBuf);
str_format(aTempBuf, sizeof(aTempBuf), "Please say /yes or /no within %d seconds.", g_Config.m_SvTeamAskTime);
pSelf->SendChatTarget(Victim, aTempBuf);
str_format(aBuf, sizeof(aBuf), "You asked to join %s\'s team %d.", pServ->ClientName(Victim), pVictim->Team());
}
else
str_format(aBuf, sizeof(aBuf), "hmm, i don't know why but you are not allowed to ask this player");
pSelf->SendChatTarget(ClientId, aBuf);
return;
}
void CGameContext::ConYes(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
CServer* pServ = (CServer*)pSelf->Server();
CGameControllerDDRace* Controller = (CGameControllerDDRace*)pSelf->m_pController;
char aBuf[512];
if(pSelf->m_apPlayers[ClientId]->m_Asker == -1 || pSelf->m_apPlayers[ClientId]->m_Asker != -1 && pSelf->m_apPlayers[ClientId]->m_AskedTick + g_Config.m_SvTeamAskTime > pSelf->Server()->Tick() )
{
pSelf->SendChatTarget(ClientId, "No valid questions, maybe they timed out.");
}
else
{
str_format(aBuf, sizeof(aBuf), "\'%s\' has accepted your request.", pServ->ClientName(ClientId));
pSelf->SendChatTarget(pSelf->m_apPlayers[ClientId]->m_Asker, aBuf);
if(pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->GetCharacter()->Team() != 0)
{
Controller->m_Teams.SetCharacterTeam(ClientId, pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->GetCharacter()->Team());
}
else if(pSelf->m_apPlayers[ClientId]->GetCharacter()->Team() != 0)
{
Controller->m_Teams.SetCharacterTeam(pSelf->m_apPlayers[ClientId]->m_Asker, pSelf->m_apPlayers[ClientId]->GetCharacter()->Team());
str_format(aBuf, sizeof(aBuf), "\'%s\' joined team %d.", pServ->ClientName(pSelf->m_apPlayers[ClientId]->m_Asker), pSelf->m_apPlayers[ClientId]->GetCharacter()->Team());
pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
}
else
for(int i = 1; i < MAX_CLIENTS; ++i)
{
if(Controller->m_Teams.GetTeamState(i) == CGameTeams::TEAMSTATE_EMPTY)
{
Controller->m_Teams.SetCharacterTeam(pSelf->m_apPlayers[ClientId]->m_Asker, i);
Controller->m_Teams.SetCharacterTeam(ClientId, i);
Controller->m_Teams.SetTeamLeader(i, pSelf->m_apPlayers[ClientId]->m_Asker);
return;
}
}
}
/*
if(pSelf->m_apPlayers[ClientId]->m_Asker != -1 && pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->m_Asked == ClientId)
{
pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->m_Asked = -1;
pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->m_AskerTick = -g_Config.m_SvTeamAskTime;
}
pSelf->m_apPlayers[ClientId]->m_Asker = -1;
pSelf->m_apPlayers[ClientId]->m_AskedTick = -g_Config.m_SvTeamAskTime;
*/
}
void CGameContext::ConNo(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
CServer* pServ = (CServer*)pSelf->Server();
char aBuf[512];
if(pSelf->m_apPlayers[ClientId]->m_Asker == -1 || pSelf->m_apPlayers[ClientId]->m_Asker != -1 && pSelf->m_apPlayers[ClientId]->m_AskedTick + g_Config.m_SvTeamAskTime > pSelf->Server()->Tick() )
{
pSelf->SendChatTarget(ClientId, "No valid question, maybe it timed out.");
}
else
{
str_format(aBuf, sizeof(aBuf), "\'%s\' has rejected your request.", pServ->ClientName(ClientId));
pSelf->SendChatTarget(pSelf->m_apPlayers[ClientId]->m_Asker, aBuf);
}
/*
if(pSelf->m_apPlayers[ClientId]->m_Asker != -1 && pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->m_Asked == ClientId)
{
pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->m_Asked = -1;
pSelf->m_apPlayers[pSelf->m_apPlayers[ClientId]->m_Asker]->m_AskerTick = -g_Config.m_SvTeamAskTime;
}
pSelf->m_apPlayers[ClientId]->m_Asker = -1;
pSelf->m_apPlayers[ClientId]->m_AskedTick = -g_Config.m_SvTeamAskTime;
*/
}
void CGameContext::ConInvite(IConsole::IResult *pResult, void *pUserData, int ClientId)
{
CGameContext *pSelf = (CGameContext *)pUserData;
CServer* pServ = (CServer*)pSelf->Server();
CGameControllerDDRace* Controller = (CGameControllerDDRace*)pSelf->m_pController;
char aBuf[512];
const char *Name = pResult->GetString(0);
int Matches = 0;
int Victim = -1;
CCharacter* pAsker = pSelf->m_apPlayers[ClientId]->GetCharacter();
CCharacter* pVictim;
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(pSelf->m_apPlayers[i] && i != ClientId && !str_comp_nocase(pServ->ClientName(i), Name))
{
Victim = i;
pVictim = pSelf->m_apPlayers[i]->GetCharacter();
Matches = 1;
pSelf->SendChatTarget(ClientId, "Exact Match found");
break;
}
else if(pSelf->m_apPlayers[i] && i != ClientId && str_find_nocase(pServ->ClientName(i), Name))
{
Victim = i;
pVictim = pSelf->m_apPlayers[i]->GetCharacter();
Matches++;
}
}
if(!pAsker || !pAsker->IsAlive())
str_format(aBuf, sizeof(aBuf), "You can\'t invite while dead.");
else if(pAsker->Team() == 0)
str_format(aBuf, sizeof(aBuf), "You are in team %d, use /leader or /ask.", pAsker->Team());
else if(pAsker->Team() && ClientId != Controller->m_Teams.GetTeamLeader(pAsker->Team()))
str_format(aBuf, sizeof(aBuf), "You already are in team %d, but not leader.", pAsker->Team());
else if(Matches > 1)
str_format(aBuf, sizeof(aBuf), "More Than one player matches the given string, maybe use auto complete (tab in any 0.5 trunk client)");
else if(Matches == 0)
str_format(aBuf, sizeof(aBuf), "No matches found.");
else if(Controller->m_Teams.GetTeamState(pAsker->Team()) != CGameTeams::TEAMSTATE_OPEN)
str_format(aBuf, sizeof(aBuf), "You can't invite anyone at this time, your team is closed.");
else if(!pVictim || !pVictim->IsAlive())
str_format(aBuf, sizeof(aBuf), "You can\'t invite him while he is dead.");
else if(pVictim->m_DDRaceState != DDRACE_NONE)
str_format(aBuf, sizeof(aBuf), "He can't change teams at this time, please tell him to kill.");
else if(pSelf->m_apPlayers[Victim]->m_Asker != -1 && pSelf->m_apPlayers[Victim]->m_AskedTick > pSelf->Server()->Tick() - g_Config.m_SvTeamAskTime)
str_format(aBuf, sizeof(aBuf), "\'%s\' is already being asked wait for %.1f seconds.", pServ->ClientName(Victim), (pSelf->m_apPlayers[Victim]->m_AskedTick + g_Config.m_SvTeamAskTime * pSelf->Server()->TickSpeed() - pSelf->Server()->Tick()) / (float)pSelf->Server()->TickSpeed());
else if(pSelf->m_apPlayers[Victim]->m_Asked != -1 && pSelf->m_apPlayers[Victim]->m_AskerTick > pSelf->Server()->Tick() - g_Config.m_SvTeamAskTime)
str_format(aBuf, sizeof(aBuf), "\'%s\' is already is asking someone wait for %.1f seconds.", pServ->ClientName(Victim), (pSelf->m_apPlayers[Victim]->m_AskedTick + g_Config.m_SvTeamAskTime * pSelf->Server()->TickSpeed() - pSelf->Server()->Tick()) / (float)pSelf->Server()->TickSpeed());
else if(!pVictim->Team())
{
pSelf->m_apPlayers[Victim]->m_Asker = ClientId;
pSelf->m_apPlayers[Victim]->m_AskedTick = pSelf->Server()->Tick();
pSelf->m_apPlayers[ClientId]->m_Asked = Victim;
pSelf->m_apPlayers[ClientId]->m_AskerTick = pSelf->Server()->Tick();
char aTempBuf[512];
str_format(aTempBuf, sizeof(aTempBuf), "Do you want to join \'%s\' \'s team?", pServ->ClientName(ClientId));
pSelf->SendChatTarget(Victim, aTempBuf);
str_format(aTempBuf, sizeof(aTempBuf), "Please say /yes or /no within %d seconds.", g_Config.m_SvTeamAskTime);
pSelf->SendChatTarget(Victim, aTempBuf);
str_format(aBuf, sizeof(aBuf), "\'%s\' has been asked to join your team.", pServ->ClientName(Victim));
}
else
str_format(aBuf, sizeof(aBuf), "hmm, i don't know why but you are not allowed to ask this player");
pSelf->SendChatTarget(ClientId, aBuf);
return;
}

View file

@ -236,6 +236,11 @@ private:
static void ConToggleBroadcast(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConEyeEmote(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConShowOthers(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConAsk(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConYes(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConNo(IConsole::IResult *pResult, void *pUserData, int ClientId);
static void ConInvite(IConsole::IResult *pResult, void *pUserData, int ClientId);
public:
CLayers *Layers() { return &m_Layers; }
class IScore *Score() { return m_pScore; }
@ -257,6 +262,7 @@ public:
virtual bool PlayerCollision();
virtual bool PlayerHooking();
};
bool ComparePlayers(CPlayer *pl1, CPlayer *pl2);
inline int CmaskAll() { return -1; }

View file

@ -1,3 +1,4 @@
/* (c) Shereef Marzouk. See "licence DDRace.txt" and the readme.txt in the root of the distribution for more information. */
/*Based on rajh's, Redix's & Sushi Tee's, DDRace mod stuff and tweaked byt btd and GreYFoX@GTi with STL to fit our DDRace needs*/
#include <engine/server.h>
#include <game/mapitems.h>

View file

@ -1,5 +1,4 @@
/* copyright (c) 2007 rajh and gregwar. Score stuff */
/* (c) Shereef Marzouk. See "licence DDRace.txt" and the readme.txt in the root of the distribution for more information. */
#ifndef DDRACE_H
#define DDRACE_H
#include <game/server/gamecontroller.h>

View file

@ -37,6 +37,7 @@ CPlayer::CPlayer(CGameContext *pGameServer, int CID, int Team)
// Variable initialized:
m_Last_Pause = 0;
m_Last_Team = 0;
m_Asker = -1;
}
CPlayer::~CPlayer()

View file

@ -129,6 +129,12 @@ public:
bool m_IsUsingDDRaceClient;
bool m_ShowOthers;
bool m_RconFreeze;
// necessary for asking mutual exclusion
int m_Asker; // who asked this player
int m_AskedTick; // when was this player asked by another player
int m_Asked; // who did this player ask
int m_AskerTick; // when did this player ask another player
};
#endif

View file

@ -1,5 +1,6 @@
#include "teams.h"
#include <engine/shared/config.h>
#include <engine/server/server.h>
CGameTeams::CGameTeams(CGameContext *pGameContext) : m_pGameContext(pGameContext)
{
@ -11,21 +12,25 @@ void CGameTeams::Reset()
m_Core.Reset();
for(int i = 0; i < MAX_CLIENTS; ++i)
{
m_TeamState[i] = EMPTY;
m_TeamState[i] = TEAMSTATE_EMPTY;
m_TeeFinished[i] = false;
m_MembersCount[i] = 0;
m_LastChat[i] = 0;
m_TeamLeader[i] = -1;
m_TeeJoinTick[i] = -1;
}
}
void CGameTeams::OnCharacterStart(int id){
void CGameTeams::OnCharacterStart(int ClientID)
{
int Tick = Server()->Tick();
CCharacter* StartingChar = Character(id);
int Team = m_Core.Team(ClientID);
CCharacter* StartingChar = Character(ClientID);
if(!StartingChar)
return;
if(StartingChar->m_DDRaceState == DDRACE_FINISHED)
StartingChar->m_DDRaceState = DDRACE_NONE;
if(m_Core.Team(id) == TEAM_FLOCK || m_Core.Team(id) == TEAM_SUPER)
if(Team == TEAM_FLOCK || Team == TEAM_SUPER)
{
StartingChar->m_DDRaceState = DDRACE_STARTED;
StartingChar->m_StartTime = Tick;
@ -36,23 +41,23 @@ void CGameTeams::OnCharacterStart(int id){
bool Waiting = false;
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(m_Core.Team(id) == m_Core.Team(i))
if(Team == m_Core.Team(i))
{
CCharacter* Char = Character(i);
if(Char->m_DDRaceState == DDRACE_FINISHED)
{
Waiting = true;
if(m_LastChat[id] + Server()->TickSpeed() + g_Config.m_SvChatDelay < Tick)
if(m_LastChat[ClientID] + Server()->TickSpeed() + g_Config.m_SvChatDelay < Tick)
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "%s has finished and didn't go through start yet, wait for him or join another team.", Server()->ClientName(i));
GameServer()->SendChatTarget(id, aBuf);
m_LastChat[id] = Tick;
GameServer()->SendChatTarget(ClientID, aBuf);
m_LastChat[ClientID] = Tick;
}
if(m_LastChat[i] + Server()->TickSpeed() + g_Config.m_SvChatDelay < Tick)
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "%s wants to start a new round, kill or walk to start.", Server()->ClientName(id));
str_format(aBuf, sizeof(aBuf), "%s wants to start a new round, kill or walk to start.", Server()->ClientName(ClientID));
GameServer()->SendChatTarget(i, aBuf);
m_LastChat[i] = Tick;
}
@ -60,12 +65,12 @@ void CGameTeams::OnCharacterStart(int id){
}
}
if(m_TeamState[m_Core.Team(id)] <= CLOSED && !Waiting)
if(m_TeamState[Team] <= TEAMSTATE_CLOSED && !Waiting)
{
ChangeTeamState(m_Core.Team(id), STARTED);
ChangeTeamState(Team, TEAMSTATE_STARTED);
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(m_Core.Team(id) == m_Core.Team(i))
if(Team == m_Core.Team(i))
{
CCharacter* Char = Character(i);
if(Char)
@ -80,22 +85,22 @@ void CGameTeams::OnCharacterStart(int id){
}
}
void CGameTeams::OnCharacterFinish(int id)
void CGameTeams::OnCharacterFinish(int ClientID)
{
if(m_Core.Team(id) == TEAM_FLOCK || m_Core.Team(id) == TEAM_SUPER)
int Team = m_Core.Team(ClientID);
if(Team == TEAM_FLOCK || Team == TEAM_SUPER)
{
Character(id)->OnFinish();
Character(ClientID)->OnFinish();
}
else
{
m_TeeFinished[id] = true;
if(TeamFinished(m_Core.Team(id)))
m_TeeFinished[ClientID] = true;
if(TeamFinished(Team))
{
//ChangeTeamState(m_Core.Team(id), FINISHED);//TODO: Make it better
ChangeTeamState(m_Core.Team(id), OPEN);
ChangeTeamState(Team, TEAMSTATE_OPEN);
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(m_Core.Team(id) == m_Core.Team(i))
if(Team == m_Core.Team(i))
{
CCharacter * Char = Character(i);
if(Char != 0)
@ -103,11 +108,6 @@ void CGameTeams::OnCharacterFinish(int id)
Char->OnFinish();
m_TeeFinished[i] = false;
}
/*else
*{
* m_Core.Team(id) = 0; //i saw zomby =)
*}
*/
}
}
@ -115,81 +115,99 @@ void CGameTeams::OnCharacterFinish(int id)
}
}
bool CGameTeams::SetCharacterTeam(int id, int Team)
int CGameTeams::SetCharacterTeam(int ClientID, int Team)
{
//Check on wrong parameters. +1 for TEAM_SUPER
if(id < 0 || id >= MAX_CLIENTS || Team < 0 || Team >= MAX_CLIENTS + 1)
return false;
if(ClientID < 0 || ClientID >= MAX_CLIENTS || Team < 0 || Team >= MAX_CLIENTS + 1)
return ERROR_WRONG_PARAMS;
//You can join to TEAM_SUPER at any time, but any other group you cannot if it started
if(Team != TEAM_SUPER && m_TeamState[Team] >= CLOSED)
return false;
if(Team != TEAM_SUPER && m_TeamState[Team] >= TEAMSTATE_CLOSED)
return ERROR_CLOSED;
//No need to switch team if you there
if(m_Core.Team(id) == Team)
return false;
if(m_Core.Team(ClientID) == Team)
return ERROR_ALREADY_THERE;
//You cannot be in TEAM_SUPER if you not super
if(Team == TEAM_SUPER && !Character(id)->m_Super) return false;
if(Team == TEAM_SUPER && !Character(ClientID)->m_Super)
return ERROR_NOT_SUPER;
//if you begin race
if(Character(id)->m_DDRaceState != DDRACE_NONE)
{
//you will be killed if you try to join FLOCK
if(Team == TEAM_FLOCK && m_Core.Team(id) != TEAM_FLOCK)
Character(id)->GetPlayer()->KillCharacter(WEAPON_GAME);
else if(Team != TEAM_SUPER)
return false;
}
SetForceCharacterTeam(id, Team);
if(Character(ClientID)->m_DDRaceState != DDRACE_NONE && Team != TEAM_SUPER)
return ERROR_STARTED;
SetForceCharacterTeam(ClientID, Team);
//GameServer()->CreatePlayerSpawn(Character(id)->m_Core.m_Pos, TeamMask());
return true;
return 0;
}
void CGameTeams::SetForceCharacterTeam(int id, int Team)
void CGameTeams::SetForceCharacterTeam(int ClientID, int Team)
{
m_TeeFinished[id] = false;
if(m_Core.Team(id) != TEAM_FLOCK
&& m_Core.Team(id) != TEAM_SUPER
&& m_TeamState[m_Core.Team(id)] != EMPTY)
char aBuf[64];
CServer* pServ = (CServer*)Server();
CPlayer *pPlayer = GameServer()->m_apPlayers[ClientID];
m_TeeFinished[ClientID] = false;
int OldTeam = m_Core.Team(ClientID);
if(OldTeam != TEAM_FLOCK && OldTeam != TEAM_SUPER && m_TeamState[OldTeam] != TEAMSTATE_EMPTY)
{
bool NoOneInOldTeam = true;
for(int i = 0; i < MAX_CLIENTS; ++i)
if(i != id && m_Core.Team(id) == m_Core.Team(i))
if(i != ClientID && OldTeam == m_Core.Team(i))
{
NoOneInOldTeam = false;//all good exists someone in old team
break;
}
if(NoOneInOldTeam)
m_TeamState[m_Core.Team(id)] = EMPTY;
m_TeamState[OldTeam] = TEAMSTATE_EMPTY;
}
if(Count(m_Core.Team(id)) > 0) m_MembersCount[m_Core.Team(id)]--;
m_Core.Team(id, Team);
if(m_Core.Team(id) != TEAM_SUPER) m_MembersCount[m_Core.Team(id)]++;
if(Team != TEAM_SUPER && m_TeamState[Team] == EMPTY)
ChangeTeamState(Team, OPEN);
dbg_msg1("Teams", "Id = %d Team = %d", id, Team);
if(Count(OldTeam) > 0)
m_MembersCount[OldTeam]--;
m_Core.Team(ClientID, Team);
for (int ClientID = 0; ClientID < MAX_CLIENTS; ++ClientID)
if(Team)
{
if(Character(ClientID) && Character(ClientID)->GetPlayer()->m_IsUsingDDRaceClient)
SendTeamsState(ClientID);
str_format(aBuf, sizeof(aBuf), "\'%s\' joined team %d.", pServ->ClientName(pPlayer->GetCID()), Team);
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
}
if(Count(OldTeam) > 0)
m_TeeJoinTick[ClientID] = Server()->Tick();
if(Team != TEAM_SUPER)
m_MembersCount[Team]++;
if(Team != TEAM_SUPER && m_TeamState[Team] == TEAMSTATE_EMPTY)
ChangeTeamState(Team, TEAMSTATE_OPEN);
if(OldTeam != TEAM_FLOCK && OldTeam != TEAM_SUPER && ClientID == GetTeamLeader(OldTeam))
{
if(Count(OldTeam))
{
int FirstJoinedID = -1;
int Tick = Server()->Tick();
for (int LoopCID = 0; LoopCID < MAX_CLIENTS; ++LoopCID)
if(m_Core.Team(LoopCID) == OldTeam)
if(m_TeeJoinTick[LoopCID] < Tick)
FirstJoinedID = LoopCID;
SetTeamLeader(OldTeam, FirstJoinedID);
}
else
SetTeamLeader(OldTeam, -1);
}
dbg_msg1("Teams", "Id = %d Team = %d", ClientID, Team);
for (int LoopCID = 0; LoopCID < MAX_CLIENTS; ++LoopCID)
{
if(Character(LoopCID) && Character(LoopCID)->GetPlayer()->m_IsUsingDDRaceClient)
SendTeamsState(LoopCID);
}
}
int CGameTeams::Count(int Team) const
{
if(Team == TEAM_SUPER) return -1;
if(Team == TEAM_SUPER)
return -1;
return m_MembersCount[Team];
}
void CGameTeams::ChangeTeamState(int Team, int State)
{
m_TeamState[Team] = State;
}
bool CGameTeams::TeamFinished(int Team)
{
for(int i = 0; i < MAX_CLIENTS; ++i)
@ -210,7 +228,7 @@ int CGameTeams::TeamMask(int Team, int ExceptID)
return Mask;
}
void CGameTeams::SendTeamsState(int Cid)
void CGameTeams::SendTeamsState(int ClientID)
{
CNetMsg_Cl_TeamsState Msg;
Msg.m_Tee0 = m_Core.Team(0);
@ -230,6 +248,23 @@ void CGameTeams::SendTeamsState(int Cid)
Msg.m_Tee14 = m_Core.Team(14);
Msg.m_Tee15 = m_Core.Team(15);
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, Cid);
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID);
}
void CGameTeams::SetTeamLeader(int Team, int ClientID)
{
if(Team == TEAM_FLOCK || Team == TEAM_SUPER)
return;
char aBuf[64];
m_TeamLeader[Team] = ClientID;
str_format(aBuf, sizeof(aBuf), "\'%s\' is now the team %d leader.", Server()->ClientName(ClientID), Team);
if(Count(Team) > 1)
for (int LoopCID = 0; LoopCID < MAX_CLIENTS; ++LoopCID)
if(LoopCID != ClientID)
if(m_Core.Team(LoopCID) == Team)
GameServer()->SendChatTarget(LoopCID, aBuf);
str_format(aBuf, sizeof(aBuf), "You are now the team %d leader.", Team);
GameServer()->SendChatTarget(ClientID, aBuf);
}

View file

@ -9,18 +9,19 @@ class CGameTeams
int m_TeamState[MAX_CLIENTS];
int m_MembersCount[MAX_CLIENTS];
bool m_TeeFinished[MAX_CLIENTS];
int m_TeamLeader[MAX_CLIENTS];
int m_TeeJoinTick[MAX_CLIENTS];
class CGameContext * m_pGameContext;
public:
enum
enum TeamState
{
EMPTY,
OPEN,
CLOSED,
STARTED,
FINISHED
TEAMSTATE_EMPTY,
TEAMSTATE_OPEN,
TEAMSTATE_CLOSED,
TEAMSTATE_STARTED
};
CTeamsCore m_Core;
@ -28,17 +29,25 @@ public:
CGameTeams(CGameContext *pGameContext);
//helper methods
CCharacter* Character(int id) { return GameServer()->GetPlayerChar(id); }
CCharacter* Character(int ClientID) { return GameServer()->GetPlayerChar(ClientID); }
class CGameContext *GameServer() { return m_pGameContext; }
class IServer *Server() { return m_pGameContext->Server(); }
void OnCharacterStart(int id);
void OnCharacterFinish(int id);
void OnCharacterStart(int ClientID);
void OnCharacterFinish(int ClientID);
bool SetCharacterTeam(int id, int Team);
int SetCharacterTeam(int ClientID, int Team);
enum TeamErrors
{
ERROR_WRONG_PARAMS = -5,
ERROR_CLOSED,
ERROR_ALREADY_THERE,
ERROR_NOT_SUPER,
ERROR_STARTED
};
void ChangeTeamState(int Team, int State);
void ChangeTeamState(int Team, int State) { m_TeamState[Team] = State; };
bool TeamFinished(int Team);
@ -46,14 +55,20 @@ public:
int Count(int Team) const;
//need to be very carefull using this method
void SetForceCharacterTeam(int id, int Team);
//need to be very careful using this method
void SetForceCharacterTeam(int ClientID, int Team);
void Reset();
void SendTeamsState(int Cid);
void SendTeamsState(int ClientID);
int m_LastChat[MAX_CLIENTS];
bool GetTeamState(int Team) { return m_TeamState[Team]; };
int GetTeamLeader(int Team) { return m_TeamLeader[Team]; };
void SetTeamLeader(int Team, int ClientID);
};
#endif