mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 01:24:18 +00:00
The Porting of DDRace-Beta to trunk by [BlackTee] den Maps with one and two layer works properly. Laser works. Fix second game layer Re-added logs Readded the rcon commands addvote and scoring system and time Fixed Weapons
Signed-off-by: btd <bardadymchik@gmail.com>
This commit is contained in:
parent
a8acf8c6ff
commit
434b4aad86
5
build server.bat
Normal file
5
build server.bat
Normal file
|
@ -0,0 +1,5 @@
|
|||
:start
|
||||
call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
|
||||
.\bam server_release
|
||||
pause
|
||||
goto start
|
|
@ -30,11 +30,12 @@ public:
|
|||
const char *m_pName;
|
||||
const char *m_pHelp;
|
||||
const char *m_pParams;
|
||||
int m_Level;
|
||||
};
|
||||
|
||||
typedef void (*FPrintCallback)(const char *pStr, void *pUser);
|
||||
typedef void (*FPossibleCallback)(const char *pCmd, void *pUser);
|
||||
typedef void (*FCommandCallback)(IResult *pResult, void *pUserData);
|
||||
typedef void (*FCommandCallback)(IResult *pResult, void *pUserData, int ClientId);
|
||||
typedef void (*FChainCommandCallback)(IResult *pResult, void *pUserData, FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
|
||||
virtual CCommandInfo *GetCommandInfo(const char *pName, int FlagMask) = 0;
|
||||
|
@ -42,11 +43,11 @@ public:
|
|||
virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0;
|
||||
|
||||
virtual void Register(const char *pName, const char *pParams,
|
||||
int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0;
|
||||
int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp, const int Level) = 0;
|
||||
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0;
|
||||
|
||||
virtual void ExecuteLine(const char *Sptr) = 0;
|
||||
virtual void ExecuteLineStroked(int Stroke, const char *pStr) = 0;
|
||||
virtual void ExecuteLine(const char *Sptr, const int ClientLevel, const int ClientId) = 0;
|
||||
virtual void ExecuteLineStroked(int Stroke, const char *pStr, const int ClientLevel, const int ClientId) = 0;
|
||||
virtual void ExecuteFile(const char *pFilename) = 0;
|
||||
|
||||
virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData) = 0;
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
virtual void SetBrowseInfo(char const *pGameType, int Progression) = 0;
|
||||
virtual void SetClientName(int ClientID, char const *pName) = 0;
|
||||
virtual void SetClientScore(int ClientID, int Score) = 0;
|
||||
virtual void SetClientAuthed(int ClientID, int Authed) = 0;
|
||||
|
||||
virtual int SnapNewID() = 0;
|
||||
virtual void SnapFreeID(int ID) = 0;
|
||||
|
@ -75,6 +76,9 @@ public:
|
|||
virtual void OnClientDirectInput(int ClientID, void *pInput) = 0;
|
||||
virtual void OnClientPredictedInput(int ClientID, void *pInput) = 0;
|
||||
|
||||
virtual void OnSetAuthed(int ClientId, void *pInput) = 0;
|
||||
virtual void OnSetResistent(int ClientId, void *pInput) = 0;
|
||||
|
||||
virtual const char *Version() = 0;
|
||||
virtual const char *NetVersion() = 0;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#ifndef ENGINE_SERVER_REGISTER_H
|
||||
#define ENGINE_SERVER_REGISTER_H
|
||||
#ifndef ENGINE_SERVER_REGISTER_H
|
||||
#define ENGINE_SERVER_REGISTER_H
|
||||
|
||||
#include <engine/masterserver.h>
|
||||
|
||||
class CRegister
|
||||
{
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include <mastersrv/mastersrv.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "register.h"
|
||||
#include "server.h"
|
||||
|
||||
|
@ -320,6 +322,14 @@ void CServer::GetClientIP(int ClientID, char *pIPString, int Size)
|
|||
str_format(pIPString, Size, "%d.%d.%d.%d", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::SetClientAuthed(int ClientID, int Level) {
|
||||
if(ClientID < 0 || ClientID >= MAX_CLIENTS || m_aClients[ClientID].m_State == CClient::STATE_READY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_aClients[ClientID].m_Authed = Level;
|
||||
}
|
||||
|
||||
|
||||
int *CServer::LatestInput(int ClientId, int *size)
|
||||
|
@ -531,6 +541,10 @@ int CServer::NewClientCallback(int ClientId, void *pUser)
|
|||
pThis->m_aClients[ClientId].m_aName[0] = 0;
|
||||
pThis->m_aClients[ClientId].m_aClan[0] = 0;
|
||||
pThis->m_aClients[ClientId].m_Authed = 0;
|
||||
pThis->m_aClients[ClientId].m_PwTries = 0; // init pw tries
|
||||
memset(&pThis->m_aClients[ClientId].m_Addr, 0, sizeof(NETADDR)); // init that too
|
||||
pThis->m_aClients[ClientId].m_CmdTries = 0; //Floff init cmd tries
|
||||
pThis->m_aClients[ClientId].m_Resistent = 0;
|
||||
pThis->m_aClients[ClientId].Reset();
|
||||
return 0;
|
||||
}
|
||||
|
@ -547,6 +561,10 @@ int CServer::DelClientCallback(int ClientId, void *pUser)
|
|||
pThis->m_aClients[ClientId].m_aName[0] = 0;
|
||||
pThis->m_aClients[ClientId].m_aClan[0] = 0;
|
||||
pThis->m_aClients[ClientId].m_Authed = 0;
|
||||
pThis->m_aClients[ClientId].m_PwTries = 0; // init pw tries
|
||||
memset(&pThis->m_aClients[ClientId].m_Addr, 0, sizeof(NETADDR)); // init that too
|
||||
pThis->m_aClients[ClientId].m_CmdTries = 0; //Floff init cmd tries
|
||||
pThis->m_aClients[ClientId].m_Resistent = 0;
|
||||
pThis->m_aClients[ClientId].m_Snapshots.PurgeAll();
|
||||
return 0;
|
||||
}
|
||||
|
@ -634,6 +652,47 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
return;
|
||||
}
|
||||
|
||||
// reserved slot
|
||||
if(ClientId >= (g_Config.m_SvMaxClients-g_Config.m_SvReservedSlots) && g_Config.m_SvReservedSlotsPass[0] != 0 && strcmp(g_Config.m_SvReservedSlotsPass, pPassword) != 0)
|
||||
{
|
||||
m_NetServer.Drop(ClientId, "Dropped due reserved slot");
|
||||
return;
|
||||
}
|
||||
int i/*, ipcnt = 0*/; // ip count
|
||||
//Start of 2cpip LemonFace
|
||||
/*m_NetServer.ClientAddr(ClientId, &Addr);
|
||||
m_aClients[ClientId].m_Addr = Addr; // store the address info
|
||||
for(i=0; i<MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_aClients[i].m_State != CClient::STATE_EMPTY) // if not an empty slot
|
||||
{
|
||||
if (m_aClients[i].m_Addr.ip[0] == Addr.ip[0] && // check each ip byte
|
||||
m_aClients[i].m_Addr.ip[1] == Addr.ip[1] &&
|
||||
m_aClients[i].m_Addr.ip[2] == Addr.ip[2] &&
|
||||
m_aClients[i].m_Addr.ip[3] == Addr.ip[3])
|
||||
{
|
||||
|
||||
if(clients[i].authed > 0) // authed players can have clones
|
||||
{
|
||||
ipcnt = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ipcnt++; // ++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ipcnt > config.sv_max_connections) // if already n connections exist, drop him
|
||||
{
|
||||
dbg_msg("server", "player dropped, too many connections. cid=%x ip=%d.%d.%d.%d",
|
||||
cid,
|
||||
clients[i].addr.ip[0], clients[i].addr.ip[1], clients[i].addr.ip[2], clients[i].addr.ip[3]
|
||||
);
|
||||
netserver_drop(net, cid, "Connections Per IP limit Exceeded");
|
||||
return;
|
||||
}
|
||||
*/
|
||||
m_aClients[ClientId].m_State = CClient::STATE_CONNECTING;
|
||||
SendMap(ClientId);
|
||||
}
|
||||
|
@ -682,6 +741,8 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
ClientId, Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3]);
|
||||
m_aClients[ClientId].m_State = CClient::STATE_READY;
|
||||
GameServer()->OnClientConnected(ClientId);
|
||||
GameServer()->OnSetAuthed(ClientId, (void*)m_aClients[ClientId].m_Authed);
|
||||
GameServer()->OnSetResistent(ClientId, (void*)m_aClients[ClientId].m_Resistent);
|
||||
}
|
||||
}
|
||||
else if(Msg == NETMSG_ENTERGAME)
|
||||
|
@ -752,10 +813,22 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
{
|
||||
const char *pCmd = Unpacker.GetString();
|
||||
|
||||
if(Unpacker.Error() == 0 && m_aClients[ClientId].m_Authed)
|
||||
if(Unpacker.Error() == 0/* && m_aClients[ClientId].m_Authed*/)
|
||||
{
|
||||
dbg_msg("server", "ClientId=%d rcon='%s'", ClientId, pCmd);
|
||||
Console()->ExecuteLine(pCmd);
|
||||
dbg_msg("server", "ClientId=%d Level=%d rcon='%s'", ClientId, m_aClients[ClientId].m_Authed, pCmd);
|
||||
Addr = m_NetServer.ClientAddr(ClientId);
|
||||
if(m_aClients[ClientId].m_Authed == 0)
|
||||
{
|
||||
if(++m_aClients[ClientId].m_CmdTries > g_Config.m_SvRconTries)
|
||||
{
|
||||
dbg_msg("server", "client tried rcon command without permissions, ban. cid=%x ip=%d.%d.%d.%d",
|
||||
ClientId,
|
||||
m_aClients[ClientId].m_Addr.ip[0], m_aClients[ClientId].m_Addr.ip[1], m_aClients[ClientId].m_Addr.ip[2], m_aClients[ClientId].m_Addr.ip[3]);
|
||||
BanAdd(m_aClients[ClientId].m_Addr, g_Config.m_SvRconTriesBantime); // bye
|
||||
}
|
||||
}
|
||||
else
|
||||
Console()->ExecuteLine(pCmd, m_aClients[ClientId].m_Authed, ClientId);
|
||||
}
|
||||
}
|
||||
else if(Msg == NETMSG_RCON_AUTH)
|
||||
|
@ -766,23 +839,50 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
|
||||
if(Unpacker.Error() == 0)
|
||||
{
|
||||
if(g_Config.m_SvRconPassword[0] == 0)
|
||||
if(g_Config.m_SvRconPasswordHelper[0] == 0 &&
|
||||
g_Config.m_SvRconPasswordModer[0] == 0 &&
|
||||
g_Config.m_SvRconPasswordAdmin[0] == 0)
|
||||
{
|
||||
SendRconLine(ClientId, "No rcon password set on server. Set sv_rcon_password to enable the remote console.");
|
||||
}
|
||||
else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0)
|
||||
{
|
||||
CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS);
|
||||
Msg.AddInt(1);
|
||||
SendMsgEx(&Msg, MSGFLAG_VITAL, ClientId, true);
|
||||
|
||||
m_aClients[ClientId].m_Authed = 1;
|
||||
SendRconLine(ClientId, "Authentication successful. Remote console access granted.");
|
||||
dbg_msg("server", "ClientId=%d authed", ClientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendRconLine(ClientId, "Wrong password.");
|
||||
} else {
|
||||
/*else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0)
|
||||
{
|
||||
CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS);
|
||||
Msg.AddInt(1);
|
||||
SendMsgEx(&Msg, MSGFLAG_VITAL, ClientId, true);
|
||||
|
||||
m_aClients[ClientId].m_Authed = 1;
|
||||
SendRconLine(ClientId, "Authentication successful. Remote console access granted.");
|
||||
dbg_msg("server", "ClientId=%d authed", ClientId);
|
||||
}*/
|
||||
int level = -1;
|
||||
if(str_comp(pPw, g_Config.m_SvRconPasswordHelper) == 0) {
|
||||
level = 1;
|
||||
} else if(str_comp(pPw, g_Config.m_SvRconPasswordModer) == 0) {
|
||||
level = 2;
|
||||
} else if(str_comp(pPw, g_Config.m_SvRconPasswordAdmin) == 0) {
|
||||
level = 3;
|
||||
}
|
||||
if(level != -1) {
|
||||
CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS);
|
||||
Msg.AddInt(1);
|
||||
SendMsgEx(&Msg, MSGFLAG_VITAL, ClientId, true);
|
||||
|
||||
m_aClients[ClientId].m_Authed = level;
|
||||
GameServer()->OnSetAuthed(ClientId, (void*)m_aClients[ClientId].m_Authed);
|
||||
SendRconLine(ClientId, "Authentication successful. Remote console access granted.");
|
||||
dbg_msg("server", "ClientId=%d authed with Level=%d", ClientId, level);
|
||||
m_aClients[ClientId].m_PwTries = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendRconLine(ClientId, "Wrong password.");
|
||||
if(++m_aClients[ClientId].m_PwTries > g_Config.m_SvRconTries)
|
||||
{ // rcon Kottizen LemonFace
|
||||
BanAdd(m_NetServer.ClientAddr(ClientId), g_Config.m_SvRconTriesBantime); // bye
|
||||
dbg_msg("server", "cid=%d banned, wrong rcon pw", ClientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1031,7 +1131,7 @@ int CServer::Run()
|
|||
return -1;
|
||||
}
|
||||
|
||||
m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this);
|
||||
m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this, 0);
|
||||
|
||||
dbg_msg("server", "server name is '%s'", g_Config.m_SvName);
|
||||
|
||||
|
@ -1168,12 +1268,18 @@ int CServer::Run()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CServer::ConKick(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConKick(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
((CServer *)pUser)->Kick(pResult->GetInteger(0), "kicked by console");
|
||||
int ClientId1 = pResult->GetInteger(0);
|
||||
if (ClientId == -1 || ((CServer *)pUser)->m_aClients[ClientId].m_Authed > ((CServer *)pUser)->m_aClients[ClientId1].m_Authed)
|
||||
{
|
||||
char buf[128];
|
||||
str_format(buf, sizeof(buf),"Kicked by %s", ((CServer *)pUser)->ClientName(ClientId));
|
||||
((CServer *)pUser)->Kick(ClientId1, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void CServer::ConBan(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConBan(IConsole::IResult *pResult, void *pUser, int ClientId1)
|
||||
{
|
||||
NETADDR Addr;
|
||||
char aAddrStr[128];
|
||||
|
@ -1188,6 +1294,8 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser)
|
|||
else if(StrAllnum(pStr))
|
||||
{
|
||||
int ClientId = str_toint(pStr);
|
||||
if (ClientId1 != -1 && ((CServer *)pUser)->m_aClients[ClientId1].m_Authed <= ((CServer *)pUser)->m_aClients[ClientId].m_Authed)
|
||||
return;
|
||||
|
||||
if(ClientId < 0 || ClientId >= MAX_CLIENTS || ((CServer *)pUser)->m_aClients[ClientId].m_State == CClient::STATE_EMPTY)
|
||||
{
|
||||
|
@ -1203,12 +1311,12 @@ void CServer::ConBan(IConsole::IResult *pResult, void *pUser)
|
|||
net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));
|
||||
|
||||
if(Minutes)
|
||||
dbg_msg("server", "banned %s for %d minutes", aAddrStr, Minutes);
|
||||
dbg_msg("server", "banned %s for %d Minutes", aAddrStr, Minutes);
|
||||
else
|
||||
dbg_msg("server", "banned %s for life", aAddrStr);
|
||||
}
|
||||
|
||||
void CServer::ConUnban(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConUnban(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
NETADDR Addr;
|
||||
CServer *pServer = (CServer *)pUser;
|
||||
|
@ -1229,13 +1337,14 @@ void CServer::ConUnban(IConsole::IResult *pResult, void *pUser)
|
|||
dbg_msg("server", "invalid network address");
|
||||
}
|
||||
|
||||
void CServer::ConBans(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConBans(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
unsigned Now = time_timestamp();
|
||||
char aBuf[1024];
|
||||
CServer* pServer = (CServer *)pUser;
|
||||
|
||||
int Num = pServer->m_NetServer.BanNum();
|
||||
|
||||
for(int i = 0; i < Num; i++)
|
||||
{
|
||||
CNetServer::CBanInfo Info;
|
||||
|
@ -1259,7 +1368,7 @@ void CServer::ConBans(IConsole::IResult *pResult, void *pUser)
|
|||
dbg_msg("server", "%s", aBuf);
|
||||
}
|
||||
|
||||
void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConStatus(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
int i;
|
||||
NETADDR Addr;
|
||||
|
@ -1284,38 +1393,38 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
|
|||
}
|
||||
}
|
||||
|
||||
void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
((CServer *)pUser)->m_RunServer = 0;
|
||||
}
|
||||
|
||||
void CServer::ConRecord(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConRecord(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
char aFilename[512];
|
||||
str_format(aFilename, sizeof(aFilename), "demos/%s.demo", pResult->GetString(0));
|
||||
((CServer *)pUser)->m_DemoRecorder.Start(((CServer *)pUser)->Storage(), aFilename, ((CServer *)pUser)->GameServer()->NetVersion(), ((CServer *)pUser)->m_aCurrentMap, ((CServer *)pUser)->m_CurrentMapCrc, "server");
|
||||
}
|
||||
|
||||
void CServer::ConStopRecord(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConStopRecord(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
((CServer *)pUser)->m_DemoRecorder.Stop();
|
||||
}
|
||||
|
||||
void CServer::ConMapReload(IConsole::IResult *pResult, void *pUser)
|
||||
void CServer::ConMapReload(IConsole::IResult *pResult, void *pUser, int ClientId)
|
||||
{
|
||||
((CServer *)pUser)->m_MapReload = 1;
|
||||
}
|
||||
|
||||
void CServer::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
pfnCallback(pResult, pCallbackUserData);
|
||||
pfnCallback(pResult, pCallbackUserData, -1);
|
||||
if(pResult->NumArguments())
|
||||
((CServer *)pUserData)->UpdateServerInfo();
|
||||
}
|
||||
|
||||
void CServer::ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
pfnCallback(pResult, pCallbackUserData);
|
||||
pfnCallback(pResult, pCallbackUserData, -1);
|
||||
if(pResult->NumArguments())
|
||||
((CServer *)pUserData)->m_NetServer.SetMaxClientsPerIP(pResult->GetInteger(0));
|
||||
}
|
||||
|
@ -1324,17 +1433,17 @@ void CServer::RegisterCommands()
|
|||
{
|
||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||
|
||||
Console()->Register("kick", "i", CFGFLAG_SERVER, ConKick, this, "");
|
||||
Console()->Register("ban", "s?i", CFGFLAG_SERVER, ConBan, this, "");
|
||||
Console()->Register("unban", "s", CFGFLAG_SERVER, ConUnban, this, "");
|
||||
Console()->Register("bans", "", CFGFLAG_SERVER, ConBans, this, "");
|
||||
Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "");
|
||||
Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "");
|
||||
Console()->Register("kick", "i", CFGFLAG_SERVER, ConKick, this, "", 2);
|
||||
Console()->Register("ban", "s?i", CFGFLAG_SERVER, ConBan, this, "", 2);
|
||||
Console()->Register("unban", "s", CFGFLAG_SERVER, ConUnban, this, "", 3);
|
||||
Console()->Register("bans", "", CFGFLAG_SERVER, ConBans, this, "", 2);
|
||||
Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "", 1);
|
||||
Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "", 3);
|
||||
|
||||
Console()->Register("record", "s", CFGFLAG_SERVER, ConRecord, this, "");
|
||||
Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, "");
|
||||
Console()->Register("record", "s", CFGFLAG_SERVER, ConRecord, this, "", 3);
|
||||
Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, "", 3);
|
||||
|
||||
Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, "");
|
||||
Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, "", 3);
|
||||
|
||||
Console()->Chain("sv_name", ConchainSpecialInfoupdate, this);
|
||||
Console()->Chain("password", ConchainSpecialInfoupdate, this);
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
#define ENGINE_SERVER_SERVER_H
|
||||
|
||||
#include <engine/server.h>
|
||||
#include <engine/map.h>
|
||||
#include <engine/shared/demorec.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
#include <engine/shared/snapshot.h>
|
||||
#include <engine/shared/network.h>
|
||||
#include <engine/shared/engine.h>
|
||||
#include <engine/server/register.h>
|
||||
#include <engine/shared/console.h>
|
||||
|
||||
class CSnapIDPool
|
||||
{
|
||||
|
@ -90,6 +98,12 @@ public:
|
|||
int m_Score;
|
||||
int m_Authed;
|
||||
|
||||
int m_Resistent;
|
||||
|
||||
NETADDR m_Addr; // for storing address
|
||||
int m_PwTries; // a players rcon pw tries
|
||||
int m_CmdTries; //Floff players rcon command tries, to prevent command flood server crash
|
||||
|
||||
void Reset();
|
||||
};
|
||||
|
||||
|
@ -129,6 +143,7 @@ public:
|
|||
virtual void SetClientName(int ClientID, const char *pName);
|
||||
virtual void SetClientScore(int ClientID, int Score);
|
||||
virtual void SetBrowseInfo(const char *pGameType, int Progression);
|
||||
virtual void SetClientAuthed(int ClientID, int Authed);
|
||||
|
||||
void Kick(int ClientID, const char *pReason);
|
||||
|
||||
|
@ -175,15 +190,15 @@ public:
|
|||
void InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer);
|
||||
int Run();
|
||||
|
||||
static void ConKick(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConBan(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConUnban(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConBans(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConStatus(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConShutdown(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConRecord(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConStopRecord(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConMapReload(IConsole::IResult *pResult, void *pUser);
|
||||
static void ConKick(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConBan(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConUnban(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConBans(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConStatus(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConShutdown(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConRecord(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConStopRecord(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConMapReload(IConsole::IResult *pResult, void *pUser, int ClientId);
|
||||
static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
static void ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
|
||||
|
|
|
@ -5,6 +5,23 @@
|
|||
// TODO: remove this
|
||||
#include "././game/variables.h"
|
||||
|
||||
//===============================
|
||||
MACRO_CONFIG_INT(SvPauseable, sv_pauseable, 0, 0, 1, CFGFLAG_SERVER, "players can pause their char or not")
|
||||
MACRO_CONFIG_INT(SvCheattime, sv_cheattime, 0, 0, 1, CFGFLAG_SERVER, "players can cheat with time or not")
|
||||
MACRO_CONFIG_INT(SvHit, sv_hit, 1, 0, 1, CFGFLAG_SERVER, "players can hammer/grenade/laser one another")
|
||||
MACRO_CONFIG_INT(SvTunes, sv_tunes, 1, 0, 1, CFGFLAG_SERVER, "Turns Tuning On/Off")
|
||||
//MACRO_CONFIG_INT(SvPhook, sv_phook, 1, 0, 1, CFGFLAG_SERVER, "Turns Player On/Off")
|
||||
//MACRO_CONFIG_INT(SvNpc, sv_npc, 0, 0, 1, CFGFLAG_SERVER, "Turns NPC (No Player Collision) On/Off")
|
||||
MACRO_CONFIG_INT(SvEndlessDrag, sv_endless_drag, 0, 0, 1, CFGFLAG_SERVER, "Turns Endless hooking On/Off")
|
||||
MACRO_CONFIG_INT(SvCheats, sv_cheats, 0, 0, 1, CFGFLAG_SERVER, "Turns Cheats On/Off")
|
||||
MACRO_CONFIG_INT(SvAllowColorChange, sv_allow_color_change, 1, 0, 1, CFGFLAG_SERVER, "Allow color change (can block rainbowmod)")
|
||||
MACRO_CONFIG_INT(SvRconTries, sv_rcon_tries, 5, 0, 100, CFGFLAG_SERVER, "How Many Password Tries Before ban")
|
||||
MACRO_CONFIG_INT(SvRconTriesBantime, sv_rcon_tries_bantime, 300, 0, 9999, CFGFLAG_SERVER, "How Much time will the brute rcon password attacker will be banned")
|
||||
|
||||
MACRO_CONFIG_STR(SvRconPasswordAdmin, sv_rcon_password_admin, 32, "", CFGFLAG_SERVER, "Remote console admin password")
|
||||
MACRO_CONFIG_STR(SvRconPasswordModer, sv_rcon_password_moder, 32, "", CFGFLAG_SERVER, "Remote console moderator password")
|
||||
MACRO_CONFIG_STR(SvRconPasswordHelper, sv_rcon_password_helper, 32, "", CFGFLAG_SERVER, "Remote console helper password")
|
||||
//=============================== */
|
||||
|
||||
MACRO_CONFIG_STR(PlayerName, player_name, 24, "nameless tee", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Name of the player")
|
||||
MACRO_CONFIG_STR(ClanName, clan_name, 32, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "(not used)")
|
||||
|
@ -67,7 +84,6 @@ MACRO_CONFIG_INT(SvMaxClients, sv_max_clients, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER
|
|||
MACRO_CONFIG_INT(SvMaxClientsPerIP, sv_max_clients_per_ip, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients with the same IP that can connect to the server")
|
||||
MACRO_CONFIG_INT(SvHighBandwidth, sv_high_bandwidth, 0, 0, 1, CFGFLAG_SERVER, "Use high bandwidth mode. Doubles the bandwidth required for the server. LAN use only")
|
||||
MACRO_CONFIG_INT(SvRegister, sv_register, 1, 0, 1, CFGFLAG_SERVER, "Register server with master server for public listing")
|
||||
MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password")
|
||||
|
||||
MACRO_CONFIG_INT(Debug, debug, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Debug mode")
|
||||
MACRO_CONFIG_INT(DbgStress, dbg_stress, 0, 0, 0, CFGFLAG_CLIENT|CFGFLAG_SERVER, "Stress systems")
|
||||
|
|
|
@ -170,7 +170,7 @@ void CConsole::Print(const char *pStr)
|
|||
m_pfnPrintCallback(pStr, m_pPrintCallbackUserdata);
|
||||
}
|
||||
|
||||
void CConsole::ExecuteLineStroked(int Stroke, const char *pStr)
|
||||
void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int ClientLevel, const int ClientId)
|
||||
{
|
||||
CResult Result;
|
||||
|
||||
|
@ -230,8 +230,18 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr)
|
|||
str_format(aBuf, sizeof(aBuf), "Invalid arguments... Usage: %s %s", pCommand->m_pName, pCommand->m_pParams);
|
||||
Print(aBuf);
|
||||
}
|
||||
else
|
||||
pCommand->m_pfnCallback(&Result, pCommand->m_pUserData);
|
||||
if (pCommand->m_Level <= ClientLevel) {
|
||||
pCommand->m_pfnCallback(&Result, pCommand->m_pUserData, ClientId);
|
||||
} else {
|
||||
char aBuf[256];
|
||||
if (pCommand->m_Level == 100 && ClientLevel < 100)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "You can't use this command: %s", pCommand->m_pName);
|
||||
} else {
|
||||
str_format(aBuf, sizeof(aBuf), "You have low level to use command: %s. Your level: %d. Need level: %d", pCommand->m_pName, ClientLevel, pCommand->m_Level);
|
||||
}
|
||||
Print(aBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(Stroke)
|
||||
|
@ -273,10 +283,10 @@ CConsole::CCommand *CConsole::FindCommand(const char *pName, int FlagMask)
|
|||
return 0x0;
|
||||
}
|
||||
|
||||
void CConsole::ExecuteLine(const char *pStr)
|
||||
void CConsole::ExecuteLine(const char *pStr, const int ClientLevel, const int ClientId)
|
||||
{
|
||||
CConsole::ExecuteLineStroked(1, pStr); // press it
|
||||
CConsole::ExecuteLineStroked(0, pStr); // then release it
|
||||
CConsole::ExecuteLineStroked(1, pStr, ClientLevel, ClientId); // press it
|
||||
CConsole::ExecuteLineStroked(0, pStr, ClientLevel, ClientId); // then release it
|
||||
}
|
||||
|
||||
|
||||
|
@ -311,7 +321,7 @@ void CConsole::ExecuteFile(const char *pFilename)
|
|||
lr.Init(File);
|
||||
|
||||
while((pLine = lr.Get()))
|
||||
ExecuteLine(pLine);
|
||||
ExecuteLine(pLine, 4, -1);
|
||||
|
||||
io_close(File);
|
||||
}
|
||||
|
@ -321,12 +331,12 @@ void CConsole::ExecuteFile(const char *pFilename)
|
|||
m_pFirstExec = pPrev;
|
||||
}
|
||||
|
||||
void CConsole::Con_Echo(IResult *pResult, void *pUserData)
|
||||
void CConsole::Con_Echo(IResult *pResult, void *pUserData, int ClientId)
|
||||
{
|
||||
((CConsole*)pUserData)->Print(pResult->GetString(0));
|
||||
}
|
||||
|
||||
void CConsole::Con_Exec(IResult *pResult, void *pUserData)
|
||||
void CConsole::Con_Exec(IResult *pResult, void *pUserData, int ClientId)
|
||||
{
|
||||
((CConsole*)pUserData)->ExecuteFile(pResult->GetString(0));
|
||||
}
|
||||
|
@ -346,7 +356,7 @@ struct CStrVariableData
|
|||
int m_MaxSize;
|
||||
};
|
||||
|
||||
static void IntVariableCommand(IConsole::IResult *pResult, void *pUserData)
|
||||
static void IntVariableCommand(IConsole::IResult *pResult, void *pUserData, int ClientId)
|
||||
{
|
||||
CIntVariableData *pData = (CIntVariableData *)pUserData;
|
||||
|
||||
|
@ -373,7 +383,7 @@ static void IntVariableCommand(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
}
|
||||
|
||||
static void StrVariableCommand(IConsole::IResult *pResult, void *pUserData)
|
||||
static void StrVariableCommand(IConsole::IResult *pResult, void *pUserData, int ClientId)
|
||||
{
|
||||
CStrVariableData *pData = (CStrVariableData *)pUserData;
|
||||
|
||||
|
@ -398,20 +408,20 @@ CConsole::CConsole(int FlagMask)
|
|||
m_pStorage = 0;
|
||||
|
||||
// register some basic commands
|
||||
Register("echo", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, Con_Echo, this, "Echo the text");
|
||||
Register("exec", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, Con_Exec, this, "Execute the specified file");
|
||||
Register("echo", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, Con_Echo, this, "Echo the text", 3);
|
||||
Register("exec", "r", CFGFLAG_SERVER|CFGFLAG_CLIENT, Con_Exec, this, "Execute the specified file", 3);
|
||||
|
||||
// TODO: this should disappear
|
||||
#define MACRO_CONFIG_INT(Name,ScriptName,Def,Min,Max,Flags,Desc) \
|
||||
{ \
|
||||
static CIntVariableData Data = { this, &g_Config.m_##Name, Min, Max }; \
|
||||
Register(#ScriptName, "?i", Flags, IntVariableCommand, &Data, Desc); \
|
||||
Register(#ScriptName, "?i", Flags, IntVariableCommand, &Data, Desc, 3); \
|
||||
}
|
||||
|
||||
#define MACRO_CONFIG_STR(Name,ScriptName,Len,Def,Flags,Desc) \
|
||||
{ \
|
||||
static CStrVariableData Data = { this, g_Config.m_##Name, Len }; \
|
||||
Register(#ScriptName, "?r", Flags, StrVariableCommand, &Data, Desc); \
|
||||
Register(#ScriptName, "?r", Flags, StrVariableCommand, &Data, Desc, 3); \
|
||||
}
|
||||
|
||||
#include "config_variables.h"
|
||||
|
@ -433,13 +443,13 @@ void CConsole::ParseArguments(int NumArgs, const char **ppArguments)
|
|||
else
|
||||
{
|
||||
// search arguments for overrides
|
||||
ExecuteLine(ppArguments[i]);
|
||||
ExecuteLine(ppArguments[i], 100, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CConsole::Register(const char *pName, const char *pParams,
|
||||
int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp)
|
||||
int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp, const int Level)
|
||||
{
|
||||
CCommand *pCommand = (CCommand *)mem_alloc(sizeof(CCommand), sizeof(void*));
|
||||
pCommand->m_pfnCallback = pfnFunc;
|
||||
|
@ -448,13 +458,13 @@ void CConsole::Register(const char *pName, const char *pParams,
|
|||
pCommand->m_pName = pName;
|
||||
pCommand->m_pParams = pParams;
|
||||
pCommand->m_Flags = Flags;
|
||||
|
||||
pCommand->m_Level = Level;
|
||||
|
||||
pCommand->m_pNext = m_pFirstCommand;
|
||||
m_pFirstCommand = pCommand;
|
||||
}
|
||||
|
||||
void CConsole::Con_Chain(IResult *pResult, void *pUserData)
|
||||
void CConsole::Con_Chain(IResult *pResult, void *pUserData, int ClientId)
|
||||
{
|
||||
CChain *pInfo = (CChain *)pUserData;
|
||||
pInfo->m_pfnChainCallback(pResult, pInfo->m_pUserData, pInfo->m_pfnCallback, pInfo->m_pCallbackUserData);
|
||||
|
|
|
@ -37,12 +37,12 @@ class CConsole : public IConsole
|
|||
CExecFile *m_pFirstExec;
|
||||
class IStorage *m_pStorage;
|
||||
|
||||
static void Con_Chain(IResult *pResult, void *pUserData);
|
||||
static void Con_Echo(IResult *pResult, void *pUserData);
|
||||
static void Con_Exec(IResult *pResult, void *pUserData);
|
||||
static void Con_Chain(IResult *pResult, void *pUserData, int ClientId);
|
||||
static void Con_Echo(IResult *pResult, void *pUserData, int ClientId);
|
||||
static void Con_Exec(IResult *pResult, void *pUserData, int ClientId);
|
||||
|
||||
void ExecuteFileRecurse(const char *pFilename);
|
||||
void ExecuteLineStroked(int Stroke, const char *pStr);
|
||||
void ExecuteLineStroked(int Stroke, const char *pStr, const int ClientLevel, const int ClientId);
|
||||
|
||||
FPrintCallback m_pfnPrintCallback;
|
||||
void *m_pPrintCallbackUserdata;
|
||||
|
@ -84,10 +84,10 @@ public:
|
|||
virtual void PossibleCommands(const char *pStr, int FlagMask, FPossibleCallback pfnCallback, void *pUser) ;
|
||||
|
||||
virtual void ParseArguments(int NumArgs, const char **ppArguments);
|
||||
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp);
|
||||
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp, const int Level);
|
||||
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser);
|
||||
|
||||
virtual void ExecuteLine(const char *pStr);
|
||||
virtual void ExecuteLine(const char *pStr, const int ClientLevel, const int ClientId);
|
||||
virtual void ExecuteFile(const char *pFilename);
|
||||
|
||||
virtual void RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUserData);
|
||||
|
|
|
@ -260,7 +260,7 @@ private:
|
|||
void BanRemoveByObject(CBan *pBan);
|
||||
|
||||
public:
|
||||
int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
|
||||
int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser, const char* reason);
|
||||
|
||||
//
|
||||
bool Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int Flags);
|
||||
|
|
|
@ -60,7 +60,7 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int
|
|||
return true;
|
||||
}
|
||||
|
||||
int CNetServer::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser)
|
||||
int CNetServer::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser, const char* pReason)
|
||||
{
|
||||
m_pfnNewClient = pfnNewClient;
|
||||
m_pfnDelClient = pfnDelClient;
|
||||
|
@ -85,11 +85,10 @@ int CNetServer::Drop(int ClientID, const char *pReason)
|
|||
pReason
|
||||
);
|
||||
|
||||
m_aSlots[ClientID].m_Connection.Disconnect(pReason);
|
||||
|
||||
if(m_pfnDelClient)
|
||||
m_pfnDelClient(ClientID, m_UserPtr);
|
||||
|
||||
m_aSlots[ClientID].m_Connection.Disconnect(pReason);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,16 @@
|
|||
CCollision::CCollision()
|
||||
{
|
||||
m_pTiles = 0;
|
||||
m_pFTiles = 0;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_pLayers = 0;
|
||||
isOneLayer = false;
|
||||
}
|
||||
int CCollision::IsSolid(int x, int y)
|
||||
{
|
||||
return (GetTile(x,y)&COLFLAG_SOLID);
|
||||
}
|
||||
|
||||
void CCollision::Init(class CLayers *pLayers)
|
||||
{
|
||||
|
@ -25,12 +31,50 @@ void CCollision::Init(class CLayers *pLayers)
|
|||
m_Width = m_pLayers->GameLayer()->m_Width;
|
||||
m_Height = m_pLayers->GameLayer()->m_Height;
|
||||
m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data));
|
||||
if(m_pLayers->FGameLayer() != 0) {
|
||||
m_pFTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->FGameLayer()->m_Data));
|
||||
isOneLayer = false;
|
||||
} else {
|
||||
m_pFTiles = 0;
|
||||
isOneLayer = true;
|
||||
}
|
||||
//race
|
||||
mem_zero(&m_Len, sizeof(m_Len));
|
||||
mem_zero(&m_Tele, sizeof(m_Tele));
|
||||
m_pTeleporter = new int[m_Width * m_Height];
|
||||
m_pFTeleporter = new int[m_Width * m_Height];
|
||||
|
||||
|
||||
for(int i = m_Width * m_Height - 1; i >= 0; i--)
|
||||
{
|
||||
if(m_pTiles[i].m_Index > 34 && m_pTiles[i].m_Index < 190)
|
||||
{
|
||||
if(m_pTiles[i].m_Index & 1)
|
||||
m_Len[m_pTiles[i].m_Index >> 1]++;
|
||||
else if(!(m_pTiles[i].m_Index & 1))
|
||||
m_Tele[(m_pTiles[i].m_Index - 1) >> 1]++;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < 95; i++)
|
||||
{
|
||||
m_pDest[i] = new int[m_Len[i]];
|
||||
m_Len[i] = 0;
|
||||
}
|
||||
for(int i = m_Width * m_Height - 1; i >= 0; i--)
|
||||
{
|
||||
if(m_pTiles[i].m_Index & 1 && m_pTiles[i].m_Index > 34 && m_pTiles[i].m_Index < 190)
|
||||
m_pDest[m_pTiles[i].m_Index >> 1][m_Len[m_pTiles[i].m_Index >> 1]++] = i;
|
||||
}
|
||||
|
||||
for(int i = 0; i < m_Width*m_Height; i++)
|
||||
{
|
||||
int Index = m_pTiles[i].m_Index;
|
||||
|
||||
if(Index > 128)
|
||||
int FIndex = 0;
|
||||
if(!isOneLayer)
|
||||
FIndex = m_pFTiles[i].m_Index;
|
||||
if (FIndex!=0)
|
||||
dbg_msg ("flayer", "tile found at (%d, %d)",(i - (i/ m_Width) * m_Width) ,(i / m_Width));
|
||||
if(Index > 190)
|
||||
continue;
|
||||
|
||||
switch(Index)
|
||||
|
@ -44,12 +88,24 @@ void CCollision::Init(class CLayers *pLayers)
|
|||
case TILE_NOHOOK:
|
||||
m_pTiles[i].m_Index = COLFLAG_SOLID|COLFLAG_NOHOOK;
|
||||
break;
|
||||
case TILE_NOLASER:
|
||||
m_pTiles[i].m_Index = COLFLAG_NOLASER;
|
||||
break;
|
||||
default:
|
||||
m_pTiles[i].m_Index = 0;
|
||||
m_pTeleporter[i] = Index;
|
||||
}
|
||||
m_pFTeleporter[i] = FIndex;
|
||||
}
|
||||
}
|
||||
|
||||
int CCollision::GetIndex(int x, int y, bool flayer) {
|
||||
CTile *tiles = (flayer) ? m_pFTiles: m_pTiles;
|
||||
int index = tiles[y*m_Width+x].m_Index;
|
||||
return index-ENTITY_OFFSET;
|
||||
}
|
||||
|
||||
|
||||
int CCollision::GetTile(int x, int y)
|
||||
{
|
||||
int nx = clamp(x/32, 0, m_Width-1);
|
||||
|
@ -60,7 +116,7 @@ int CCollision::GetTile(int x, int y)
|
|||
|
||||
bool CCollision::IsTileSolid(int x, int y)
|
||||
{
|
||||
return GetTile(x,y)&COLFLAG_SOLID;
|
||||
return (GetTile(x,y)&COLFLAG_SOLID);
|
||||
}
|
||||
|
||||
// TODO: rewrite this smarter!
|
||||
|
@ -200,3 +256,257 @@ void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elas
|
|||
*pInoutPos = Pos;
|
||||
*pInoutVel = Vel;
|
||||
}
|
||||
|
||||
int CCollision::IsNolaser(int x, int y)
|
||||
{
|
||||
return (CCollision::GetTile(x,y) & COLFLAG_NOLASER);
|
||||
}
|
||||
|
||||
//race
|
||||
int CCollision::IsTeleport(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
int z = m_pTeleporter[ny * m_Width + nx]-1;
|
||||
if(z > 34 && z < 190 && z & 1)
|
||||
return z >> 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CCollision::IsBegin(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
|
||||
return m_pTeleporter[ny*m_Width+nx] == TILE_BEGIN;
|
||||
}
|
||||
|
||||
int CCollision::IsEnd(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
return m_pTeleporter[ny * m_Width + nx] == TILE_END;
|
||||
}
|
||||
|
||||
int CCollision::IsFreeze(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
return (m_pTeleporter[ny * m_Width + nx] == TILE_FREEZE) || (m_pFTeleporter[ny * m_Width + nx] == TILE_FREEZE);
|
||||
}
|
||||
|
||||
int CCollision::IsUnfreeze(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
return (m_pTeleporter[ny * m_Width + nx] == TILE_UNFREEZE) || (m_pFTeleporter[ny * m_Width + nx] == TILE_UNFREEZE);
|
||||
}
|
||||
|
||||
int CCollision::IsKick(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
return (m_pTeleporter[ny * m_Width + nx] == TILE_KICK) || (m_pFTeleporter[ny * m_Width + nx] == TILE_KICK);
|
||||
}
|
||||
|
||||
int CCollision::IsCp(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
int ind = m_pTeleporter[ny * m_Width + nx];
|
||||
if (ind >= TILE_CP_D && ind <= TILE_CP_L_F)
|
||||
return ind;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CCollision::IsBoost(int x, int y)
|
||||
{
|
||||
int nx = x/32;
|
||||
int ny = y/32;
|
||||
if(y < 0 || nx < 0 || nx >= m_Width || ny >= m_Height)
|
||||
return 0;
|
||||
if ((m_pTeleporter[ny * m_Width + nx] >= TILE_BOOST_L && m_pTeleporter[ny * m_Width + nx] <= TILE_BOOST_U) || (m_pTeleporter[ny * m_Width + nx] >= TILE_BOOST_L2 && m_pTeleporter[ny * m_Width + nx] <= TILE_BOOST_U2))
|
||||
return m_pTeleporter[ny * m_Width + nx];
|
||||
else if ((m_pFTeleporter[ny * m_Width + nx] >= TILE_BOOST_L && m_pFTeleporter[ny * m_Width + nx]<= TILE_BOOST_U) || (m_pFTeleporter[ny * m_Width + nx] >= TILE_BOOST_L2 && m_pFTeleporter[ny * m_Width + nx] <= TILE_BOOST_U2))
|
||||
return m_pFTeleporter[ny * m_Width + nx];
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec2 CCollision::CpSpeed(int index)
|
||||
{
|
||||
|
||||
vec2 target;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case TILE_CP_U:
|
||||
case TILE_CP_U_F:
|
||||
target.x=0;
|
||||
target.y=-4;
|
||||
break;
|
||||
case TILE_CP_R:
|
||||
case TILE_CP_R_F:
|
||||
target.x=4;
|
||||
target.y=0;
|
||||
break;
|
||||
case TILE_CP_D:
|
||||
case TILE_CP_D_F:
|
||||
target.x=0;
|
||||
target.y=4;
|
||||
break;
|
||||
case TILE_CP_L:
|
||||
case TILE_CP_L_F:
|
||||
target.x=-4;
|
||||
target.y=0;
|
||||
break;
|
||||
default:
|
||||
target=vec2(0,0);
|
||||
break;
|
||||
}
|
||||
if (index>=TILE_CP_D_F && index<=TILE_CP_L_F)
|
||||
target*=4;
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec2 CCollision::BoostAccel(int index)
|
||||
{
|
||||
if (index==TILE_BOOST_L)
|
||||
return vec2(-3,0);
|
||||
else if(index==TILE_BOOST_R)
|
||||
return vec2(3,0);
|
||||
else if(index==TILE_BOOST_D)
|
||||
return vec2(0,2);
|
||||
else if(index==TILE_BOOST_U)
|
||||
return vec2(0,-2);
|
||||
else if(index==TILE_BOOST_L2)
|
||||
return vec2(-15,0);
|
||||
else if(index==TILE_BOOST_R2)
|
||||
return vec2(15,0);
|
||||
else if(index==TILE_BOOST_D2)
|
||||
return vec2(0,15);
|
||||
else if(index==TILE_BOOST_U2)
|
||||
return vec2(0,-15);
|
||||
|
||||
return vec2(0,0);
|
||||
}
|
||||
|
||||
|
||||
vec2 CCollision::Teleport(int a)
|
||||
{
|
||||
if(m_Len[a] > 0)
|
||||
{
|
||||
int r = rand()%m_Len[a];
|
||||
int x = (m_pDest[a][r] % m_Width)<<5;
|
||||
int y = (m_pDest[a][r] / m_Width)<<5;
|
||||
return vec2((float)x+16.0, (float)y+16.0);
|
||||
}
|
||||
else
|
||||
return vec2(0, 0);
|
||||
}
|
||||
|
||||
void CCollision::Set(int x, int y, int flag)
|
||||
{
|
||||
int nx = clamp(x/32, 0, m_Width-1);
|
||||
int ny = clamp(y/32, 0, m_Height-1);
|
||||
|
||||
m_pTiles[ny * m_Width + nx].m_Index = flag;
|
||||
}
|
||||
|
||||
|
||||
int CCollision::IntersectNolaser2(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision)
|
||||
{
|
||||
float d = distance(pos0, pos1);
|
||||
vec2 last = pos0;
|
||||
|
||||
for(float f = 0; f < d; f++)
|
||||
{
|
||||
float a = f/d;
|
||||
vec2 pos = mix(pos0, pos1, a);
|
||||
if(CCollision::IsNolaser(round(pos.x), round(pos.y)))
|
||||
{
|
||||
if(out_collision)
|
||||
*out_collision = pos;
|
||||
if(out_before_collision)
|
||||
*out_before_collision = last;
|
||||
return GetTile(round(pos.x), round(pos.y));
|
||||
}
|
||||
last = pos;
|
||||
}
|
||||
if(out_collision)
|
||||
*out_collision = pos1;
|
||||
if(out_before_collision)
|
||||
*out_before_collision = pos1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CCollision::IntersectNolaser(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision)
|
||||
{
|
||||
float d = distance(pos0, pos1);
|
||||
vec2 last = pos0;
|
||||
|
||||
for(float f = 0; f < d; f++)
|
||||
{
|
||||
float a = f/d;
|
||||
vec2 pos = mix(pos0, pos1, a);
|
||||
if(IsNolaser(round(pos.x), round(pos.y)) || IsSolid(round(pos.x), round(pos.y)))
|
||||
{
|
||||
if(out_collision)
|
||||
*out_collision = pos;
|
||||
if(out_before_collision)
|
||||
*out_before_collision = last;
|
||||
return GetTile(round(pos.x), round(pos.y));
|
||||
}
|
||||
last = pos;
|
||||
}
|
||||
if(out_collision)
|
||||
*out_collision = pos1;
|
||||
if(out_before_collision)
|
||||
*out_before_collision = pos1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CCollision::IntersectAir(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision)
|
||||
{
|
||||
float d = distance(pos0, pos1);
|
||||
vec2 last = pos0;
|
||||
|
||||
for(float f = 0; f < d; f++)
|
||||
{
|
||||
float a = f/d;
|
||||
vec2 pos = mix(pos0, pos1, a);
|
||||
if(IsSolid(round(pos.x), round(pos.y)) || !GetTile(round(pos.x), round(pos.y)))
|
||||
{
|
||||
if(out_collision)
|
||||
*out_collision = pos;
|
||||
if(out_before_collision)
|
||||
*out_before_collision = last;
|
||||
if(!GetTile(round(pos.x), round(pos.y)))
|
||||
return -1;
|
||||
else
|
||||
return GetTile(round(pos.x), round(pos.y));
|
||||
}
|
||||
last = pos;
|
||||
}
|
||||
if(out_collision)
|
||||
*out_collision = pos1;
|
||||
if(out_before_collision)
|
||||
*out_before_collision = pos1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,23 @@
|
|||
class CCollision
|
||||
{
|
||||
class CTile *m_pTiles;
|
||||
class CTile *m_pFTiles;
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
|
||||
bool isOneLayer;
|
||||
|
||||
int *m_pDest[95];
|
||||
int m_Len[95];
|
||||
int m_Tele[95];
|
||||
|
||||
int *m_pTeleporter;
|
||||
int *m_pFTeleporter;
|
||||
|
||||
class CLayers *m_pLayers;
|
||||
|
||||
bool IsTileSolid(int x, int y);
|
||||
int GetTile(int x, int y);
|
||||
|
||||
|
||||
public:
|
||||
enum
|
||||
|
@ -19,8 +30,9 @@ public:
|
|||
COLFLAG_SOLID=1,
|
||||
COLFLAG_DEATH=2,
|
||||
COLFLAG_NOHOOK=4,
|
||||
COLFLAG_NOLASER=8,
|
||||
};
|
||||
|
||||
int GetTile(int x, int y);
|
||||
CCollision();
|
||||
void Init(class CLayers *pLayers);
|
||||
bool CheckPoint(float x, float y) { return IsTileSolid(round(x), round(y)); }
|
||||
|
@ -32,6 +44,29 @@ public:
|
|||
void MovePoint(vec2 *pInoutPos, vec2 *pInoutVel, float Elasticity, int *Bpounces);
|
||||
void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity);
|
||||
bool TestBox(vec2 Pos, vec2 Size);
|
||||
|
||||
void Set(int x, int y, int flags);
|
||||
int IntersectNolaser(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision);
|
||||
int IntersectNolaser2(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision);
|
||||
int IntersectAir(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision);
|
||||
//race
|
||||
int IsSolid(int x, int y);
|
||||
int IsTeleport(int x, int y);
|
||||
int IsBegin(int x, int y);
|
||||
int IsNolaser(int x, int y);
|
||||
int IsEnd(int x, int y);
|
||||
int IsBoost(int x, int y);
|
||||
int IsFreeze(int x, int y);
|
||||
int IsUnfreeze(int x, int y);
|
||||
int IsKick(int x, int y);
|
||||
int IsCp(int x, int y);
|
||||
|
||||
int GetIndex(int x, int y, bool flayer);
|
||||
vec2 Speed(int index);
|
||||
vec2 BoostAccel(int index);
|
||||
vec2 Teleport(int z);
|
||||
|
||||
vec2 CpSpeed(int index);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
|
||||
#include "gamecore.h"
|
||||
#include "server/entities/character.h"
|
||||
|
||||
const char *CTuningParams::m_apNames[] =
|
||||
{
|
||||
|
@ -251,8 +252,9 @@ void CCharacterCore::Tick(bool UseInput)
|
|||
{
|
||||
if(m_HookedPlayer != -1)
|
||||
{
|
||||
CCharacterCore *p = m_pWorld->m_apCharacters[m_HookedPlayer];
|
||||
if(p)
|
||||
CCharacterCore *p = m_pWorld->m_apCharacters[m_HookedPlayer];//TODO: Ýòî ïèçäåö
|
||||
//CCharacter* pl = GameServer()->m_apPlayers[m_HookedPlayer]->GetCharacter();
|
||||
if(p/*&&pl->m_RaceState != RACE_PAUSE*/)
|
||||
m_HookPos = p->m_Pos;
|
||||
else
|
||||
{
|
||||
|
@ -301,7 +303,7 @@ void CCharacterCore::Tick(bool UseInput)
|
|||
}
|
||||
}
|
||||
|
||||
if(m_pWorld && m_pWorld->m_Tuning.m_PlayerCollision)
|
||||
if(m_pWorld/* && m_pWorld->m_Tuning.m_PlayerCollision*/)
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
|
@ -312,22 +314,23 @@ void CCharacterCore::Tick(bool UseInput)
|
|||
//player *p = (player*)ent;
|
||||
if(p == this) // || !(p->flags&FLAG_ALIVE)
|
||||
continue; // make sure that we don't nudge our self
|
||||
|
||||
// handle player <-> player collision
|
||||
float d = distance(m_Pos, p->m_Pos);
|
||||
vec2 Dir = normalize(m_Pos - p->m_Pos);
|
||||
if(d < PhysSize*1.25f && d > 1.0f)
|
||||
{
|
||||
float a = (PhysSize*1.45f - d);
|
||||
if (m_pWorld->m_Tuning.m_PlayerCollision) {
|
||||
|
||||
// make sure that we don't add excess force by checking the
|
||||
// direction against the current velocity
|
||||
vec2 VelDir = normalize(m_Vel);
|
||||
float v = 1-(dot(VelDir, Dir)+1)/2;
|
||||
m_Vel = m_Vel + Dir*a*(v*0.75f);
|
||||
m_Vel = m_Vel * 0.85f;
|
||||
if(d < PhysSize*1.25f && d > 1.0f)
|
||||
{
|
||||
float a = (PhysSize*1.45f - d);
|
||||
|
||||
// make sure that we don't add excess force by checking the
|
||||
// direction against the current velocity
|
||||
vec2 VelDir = normalize(m_Vel);
|
||||
float v = 1-(dot(VelDir, Dir)+1)/2;
|
||||
m_Vel = m_Vel + Dir*a*(v*0.75f);
|
||||
m_Vel = m_Vel * 0.85f;
|
||||
}
|
||||
}
|
||||
|
||||
// handle hook influence
|
||||
if(m_HookedPlayer == i)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "layers.h"
|
||||
#include <string.h>
|
||||
|
||||
CLayers::CLayers()
|
||||
{
|
||||
|
@ -8,6 +9,7 @@ CLayers::CLayers()
|
|||
m_LayersStart = 0;
|
||||
m_pGameGroup = 0;
|
||||
m_pGameLayer = 0;
|
||||
m_pFGameLayer = 0;
|
||||
m_pMap = 0;
|
||||
}
|
||||
|
||||
|
@ -43,7 +45,10 @@ void CLayers::Init(class IKernel *pKernel)
|
|||
m_pGameGroup->m_ClipW = 0;
|
||||
m_pGameGroup->m_ClipH = 0;
|
||||
|
||||
break;
|
||||
//break;
|
||||
} else if(g == 0 && l == 0) {
|
||||
m_pFGameLayer = new CMapItemLayerTilemap;
|
||||
memcpy(m_pFGameLayer, pTilemap, sizeof(CMapItemLayerTilemap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ class CLayers
|
|||
int m_LayersStart;
|
||||
CMapItemGroup *m_pGameGroup;
|
||||
CMapItemLayerTilemap *m_pGameLayer;
|
||||
CMapItemLayerTilemap *m_pFGameLayer;
|
||||
class IMap *m_pMap;
|
||||
|
||||
public:
|
||||
|
@ -21,6 +22,7 @@ public:
|
|||
class IMap *Map() const { return m_pMap; };
|
||||
CMapItemGroup *GameGroup() const { return m_pGameGroup; };
|
||||
CMapItemLayerTilemap *GameLayer() const { return m_pGameLayer; };
|
||||
CMapItemLayerTilemap *FGameLayer() const { return m_pFGameLayer; };
|
||||
CMapItemGroup *GetGroup(int Index) const;
|
||||
CMapItemLayer *GetLayer(int Index) const;
|
||||
};
|
||||
|
|
|
@ -38,6 +38,49 @@ enum
|
|||
ENTITY_WEAPON_GRENADE,
|
||||
ENTITY_POWERUP_NINJA,
|
||||
ENTITY_WEAPON_RIFLE,
|
||||
|
||||
//DDRace
|
||||
ENTITY_LASER_FAST_CW, //M&F
|
||||
ENTITY_LASER_NORMAL_CW, //M&F
|
||||
ENTITY_LASER_SLOW_CW, //M&F
|
||||
ENTITY_LASER_STOP, //M&F
|
||||
ENTITY_LASER_SLOW_CCW, //M&F
|
||||
ENTITY_LASER_NORMAL_CCW,//M&F
|
||||
ENTITY_LASER_FAST_CCW, //M&F
|
||||
|
||||
ENTITY_LASER_SHORT, //M&F
|
||||
ENTITY_LASER_MIDDLE, //M&F
|
||||
ENTITY_LASER_LONG, //M&F
|
||||
|
||||
ENTITY_LASER_C_SLOW, //M&F
|
||||
ENTITY_LASER_C_NORMAL, //M&F
|
||||
ENTITY_LASER_C_FAST, //M&F
|
||||
|
||||
ENTITY_LASER_O_SLOW, //M&F
|
||||
ENTITY_LASER_O_NORMAL, //M&F
|
||||
ENTITY_LASER_O_FAST, //M&F
|
||||
|
||||
ENTITY_DRAGER_WEAK, //M&F
|
||||
ENTITY_DRAGER_NORMAL, //M&F
|
||||
ENTITY_DRAGER_STRONG, //M&F
|
||||
|
||||
ENTITY_PLASMA, //M&F
|
||||
ENTITY_NOTHING1,
|
||||
ENTITY_NOTHING2,
|
||||
ENTITY_NOTHING3,
|
||||
ENTITY_NOTHING4,
|
||||
ENTITY_NOTHING5,
|
||||
ENTITY_NOTHING6,
|
||||
ENTITY_NOTHING7,
|
||||
ENTITY_NOTHING8,
|
||||
ENTITY_NOTHING9,
|
||||
ENTITY_NOTHING10,
|
||||
ENTITY_NOTHING11,
|
||||
ENTITY_NOTHING12,
|
||||
|
||||
ENTITY_DRAGER_WEAK_NW, //M&F
|
||||
ENTITY_DRAGER_NORMAL_NW, //M&F
|
||||
ENTITY_DRAGER_STRONG_NW, //M&F
|
||||
NUM_ENTITIES,
|
||||
|
||||
TILE_AIR=0,
|
||||
|
@ -45,6 +88,31 @@ enum
|
|||
TILE_DEATH,
|
||||
TILE_NOHOOK,
|
||||
|
||||
TILE_NOLASER, //M
|
||||
TILE_BOOST_L, //M
|
||||
TILE_BOOST_R, //M
|
||||
TILE_BOOST_D, //M
|
||||
TILE_BOOST_U, //M
|
||||
TILE_FREEZE, //M&F
|
||||
TILE_KICK, //M&F
|
||||
TILE_UNFREEZE, //M&F
|
||||
TILE_BOOST_L2, //M
|
||||
TILE_BOOST_R2, //M
|
||||
TILE_BOOST_D2, //M
|
||||
TILE_BOOST_U2, //M
|
||||
TILE_NOTHING, //M&F
|
||||
TILE_CP_D, //M //no collision
|
||||
TILE_CP_U, //M //endless hook
|
||||
TILE_CP_R, //M
|
||||
TILE_CP_L, //M
|
||||
TILE_CP_D_F, //M
|
||||
TILE_CP_U_F, //M
|
||||
TILE_CP_R_F, //M
|
||||
TILE_CP_L_F, //M
|
||||
|
||||
TILE_BEGIN=33, //M
|
||||
TILE_END, //M
|
||||
|
||||
TILEFLAG_VFLIP=1,
|
||||
TILEFLAG_HFLIP=2,
|
||||
TILEFLAG_OPAQUE=4,
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#include <new>
|
||||
#include <string.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/server/server.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include <game/mapitems.h>
|
||||
|
||||
#include <game/server/gamemodes/race.h>
|
||||
#include "character.h"
|
||||
#include "laser.h"
|
||||
#include "light.h"
|
||||
#include "projectile.h"
|
||||
|
||||
//input count
|
||||
|
@ -36,7 +39,7 @@ CInputCount CountInput(int Prev, int Cur)
|
|||
|
||||
MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
|
||||
|
||||
// Character, "physical" player's part
|
||||
// Character, "physical" m_pPlayer's part
|
||||
CCharacter::CCharacter(CGameWorld *pWorld)
|
||||
: CEntity(pWorld, NETOBJTYPE_CHARACTER)
|
||||
{
|
||||
|
@ -61,6 +64,9 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
|
|||
|
||||
m_pPlayer = pPlayer;
|
||||
m_Pos = Pos;
|
||||
m_OlderPos = Pos;
|
||||
m_OldPos = Pos;
|
||||
m_RaceState = RACE_NONE;
|
||||
|
||||
m_Core.Reset();
|
||||
m_Core.Init(&GameServer()->m_World.m_Core, GameServer()->Collision());
|
||||
|
@ -123,7 +129,7 @@ void CCharacter::HandleNinja()
|
|||
m_ActiveWeapon = m_LastWeapon;
|
||||
if(m_ActiveWeapon == WEAPON_NINJA)
|
||||
m_ActiveWeapon = WEAPON_GUN;
|
||||
|
||||
Direction= normalize(vec2(0,0)) ;
|
||||
SetWeapon(m_ActiveWeapon);
|
||||
return;
|
||||
}
|
||||
|
@ -176,7 +182,7 @@ void CCharacter::HandleNinja()
|
|||
if (distance(aEnts[i]->m_Pos, m_Pos) > (m_ProximityRadius * 2.0f))
|
||||
continue;
|
||||
|
||||
// Hit a player, give him damage and stuffs...
|
||||
// Hit a m_pPlayer, give him damage and stuffs...
|
||||
GameServer()->CreateSound(aEnts[i]->m_Pos, SOUND_NINJA_HIT);
|
||||
// set his velocity to fast upward (for now)
|
||||
if(m_NumObjectsHit < 10)
|
||||
|
@ -246,7 +252,7 @@ void CCharacter::HandleWeaponSwitch()
|
|||
|
||||
void CCharacter::FireWeapon()
|
||||
{
|
||||
if(m_ReloadTimer != 0)
|
||||
if(m_ReloadTimer != 0 || m_FreezeTime > 0)
|
||||
return;
|
||||
|
||||
DoWeaponSwitch();
|
||||
|
@ -287,6 +293,8 @@ void CCharacter::FireWeapon()
|
|||
m_NumObjectsHit = 0;
|
||||
GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);
|
||||
|
||||
if (!g_Config.m_SvHit || m_RaceState == RACE_PAUSE) break;
|
||||
|
||||
CCharacter *aEnts[64];
|
||||
int Hits = 0;
|
||||
int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)aEnts,
|
||||
|
@ -297,7 +305,7 @@ void CCharacter::FireWeapon()
|
|||
CCharacter *Target = aEnts[i];
|
||||
|
||||
//for race mod or any other mod, which needs hammer hits through the wall remove second condition
|
||||
if ((Target == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, Target->m_Pos, NULL, NULL))
|
||||
if ((Target == this) /*|| GameServer()->Collision()->IntersectLine(ProjStartPos, Target->m_Pos, NULL, NULL)*/)
|
||||
continue;
|
||||
|
||||
// set his velocity to fast upward (for now)
|
||||
|
@ -310,7 +318,8 @@ void CCharacter::FireWeapon()
|
|||
else
|
||||
Dir = vec2(0.f, -1.f);
|
||||
|
||||
Target->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * 10.0f;
|
||||
Target->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * 10.0f * (m_HammerType + 1);
|
||||
Target->UnFreeze();
|
||||
Hits++;
|
||||
}
|
||||
|
||||
|
@ -327,7 +336,11 @@ void CCharacter::FireWeapon()
|
|||
ProjStartPos,
|
||||
Direction,
|
||||
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),
|
||||
1, 0, 0, -1, WEAPON_GUN);
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
WEAPON_GUN);
|
||||
|
||||
// pack the Projectile and send it to the client Directly
|
||||
CNetObj_Projectile p;
|
||||
|
@ -345,7 +358,11 @@ void CCharacter::FireWeapon()
|
|||
|
||||
case WEAPON_SHOTGUN:
|
||||
{
|
||||
int ShotSpread = 2;
|
||||
if(m_RaceState != RACE_PAUSE) {
|
||||
new CLaser(&GameServer()->m_World, m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID(), 1);
|
||||
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
|
||||
}
|
||||
/*int ShotSpread = 2;
|
||||
|
||||
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
||||
Msg.AddInt(ShotSpread*2+1);
|
||||
|
@ -361,7 +378,7 @@ void CCharacter::FireWeapon()
|
|||
m_pPlayer->GetCID(),
|
||||
ProjStartPos,
|
||||
vec2(cosf(a), sinf(a))*Speed,
|
||||
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
|
||||
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_Shotm_GunLifetime),
|
||||
1, 0, 0, -1, WEAPON_SHOTGUN);
|
||||
|
||||
// pack the Projectile and send it to the client Directly
|
||||
|
@ -374,56 +391,66 @@ void CCharacter::FireWeapon()
|
|||
|
||||
Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID());
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
|
||||
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);*/
|
||||
} break;
|
||||
|
||||
case WEAPON_GRENADE:
|
||||
{
|
||||
CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GRENADE,
|
||||
m_pPlayer->GetCID(),
|
||||
ProjStartPos,
|
||||
Direction,
|
||||
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),
|
||||
1, true, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
|
||||
if (m_RaceState != RACE_PAUSE) {
|
||||
|
||||
CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GRENADE,
|
||||
m_pPlayer->GetCID(),
|
||||
ProjStartPos,
|
||||
Direction,
|
||||
(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),
|
||||
0,
|
||||
true,
|
||||
0,
|
||||
SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
|
||||
|
||||
// pack the Projectile and send it to the client Directly
|
||||
CNetObj_Projectile p;
|
||||
Proj->FillInfo(&p);
|
||||
|
||||
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
||||
Msg.AddInt(1);
|
||||
for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
|
||||
Msg.AddInt(((int *)&p)[i]);
|
||||
Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
|
||||
// pack the Projectile and send it to the client Directly
|
||||
CNetObj_Projectile p;
|
||||
Proj->FillInfo(&p);
|
||||
|
||||
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
||||
Msg.AddInt(1);
|
||||
for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
|
||||
Msg.AddInt(((int *)&p)[i]);
|
||||
Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
|
||||
}
|
||||
} break;
|
||||
|
||||
case WEAPON_RIFLE:
|
||||
{
|
||||
new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID());
|
||||
GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
|
||||
if (m_RaceState != RACE_PAUSE) {
|
||||
new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID(), 0);
|
||||
//GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
|
||||
}
|
||||
} break;
|
||||
|
||||
case WEAPON_NINJA:
|
||||
{
|
||||
// reset Hit objects
|
||||
m_NumObjectsHit = 0;
|
||||
|
||||
m_AttackTick = Server()->Tick();
|
||||
m_Ninja.m_ActivationDir = Direction;
|
||||
m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
|
||||
|
||||
GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
|
||||
if (m_RaceState != RACE_PAUSE) {
|
||||
// reset Hit objects
|
||||
m_NumObjectsHit = 0;
|
||||
|
||||
m_AttackTick = Server()->Tick();
|
||||
m_Ninja.m_ActivationDir = Direction;
|
||||
//m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
|
||||
m_Ninja.m_CurrentMoveTime = 10;
|
||||
//GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
|
||||
}
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
m_AttackTick = Server()->Tick();
|
||||
|
||||
/*
|
||||
if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited
|
||||
m_aWeapons[m_ActiveWeapon].m_Ammo--;
|
||||
|
||||
*/
|
||||
if(!m_ReloadTimer)
|
||||
m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000;
|
||||
}
|
||||
|
@ -444,7 +471,7 @@ void CCharacter::HandleWeapons()
|
|||
|
||||
// fire Weapon, if wanted
|
||||
FireWeapon();
|
||||
|
||||
/*
|
||||
// ammo regen
|
||||
int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Ammoregentime;
|
||||
if(AmmoRegenTime)
|
||||
|
@ -467,7 +494,7 @@ void CCharacter::HandleWeapons()
|
|||
m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -530,6 +557,16 @@ void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
|
|||
|
||||
void CCharacter::Tick()
|
||||
{
|
||||
|
||||
|
||||
if(m_RaceState == RACE_PAUSE) {
|
||||
m_Input.m_Direction = 0;
|
||||
m_Input.m_Jump = 0;
|
||||
m_Input.m_Hook = 0;
|
||||
m_Input.m_Fire = 0;
|
||||
ResetPos();
|
||||
}
|
||||
|
||||
if(m_pPlayer->m_ForceBalanced)
|
||||
{
|
||||
char Buf[128];
|
||||
|
@ -539,14 +576,109 @@ void CCharacter::Tick()
|
|||
m_pPlayer->m_ForceBalanced = false;
|
||||
}
|
||||
|
||||
if(m_Input.m_Direction != 0 || m_Input.m_Jump != 0)
|
||||
m_LastMove = Server()->Tick();
|
||||
if(m_FreezeTime > 0) {
|
||||
if (m_FreezeTime % Server()->TickSpeed() == 0) {
|
||||
GameServer()->CreateDamageInd(m_Pos, 0, m_FreezeTime / Server()->TickSpeed());
|
||||
}
|
||||
m_FreezeTime--;
|
||||
m_Input.m_Direction = 0;
|
||||
m_Input.m_Jump = 0;
|
||||
m_Input.m_Hook = 0;
|
||||
m_Input.m_Fire = 0;
|
||||
if (m_FreezeTime == 1) {
|
||||
UnFreeze();
|
||||
}
|
||||
}
|
||||
m_Core.m_Input = m_Input;
|
||||
m_Core.Tick(true);
|
||||
|
||||
m_DoSplash = false;
|
||||
if (g_Config.m_SvEndlessDrag)
|
||||
m_Core.m_HookTick = 0;
|
||||
if (m_Super && m_Core.m_Jumped > 1)
|
||||
m_Core.m_Jumped = 1;
|
||||
|
||||
//race
|
||||
char aBuftime[128];
|
||||
float time = (float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed());
|
||||
if(Server()->Tick() - m_RefreshTime >= Server()->TickSpeed())
|
||||
{
|
||||
//GameServer()->SendBroadcast("FIRST_IF", m_pPlayer->GetCID());
|
||||
if (m_RaceState == RACE_STARTED) {
|
||||
//GameServer()->SendBroadcast("SECOND_IF", m_pPlayer->GetCID());
|
||||
int int_time = (int)time;
|
||||
str_format(aBuftime, sizeof(aBuftime), "%d m %d s\n%s", int_time/60,(int_time%60), ( g_Config.m_SvBroadcast[0] == 0) ? "" : g_Config.m_SvBroadcast);
|
||||
GameServer()->SendBroadcast(aBuftime, m_pPlayer->GetCID());
|
||||
} else {
|
||||
if (g_Config.m_SvBroadcast[0] != 0)
|
||||
GameServer()->SendBroadcast(g_Config.m_SvBroadcast, m_pPlayer->GetCID());
|
||||
}
|
||||
m_RefreshTime = Server()->Tick();
|
||||
}
|
||||
if(GameServer()->Collision()->IsBegin(m_Pos.x,m_Pos.y) && m_RaceState == RACE_NONE)
|
||||
{
|
||||
m_StartTime = Server()->Tick();
|
||||
m_RefreshTime = Server()->Tick();
|
||||
m_RaceState = RACE_STARTED;
|
||||
}
|
||||
if(GameServer()->Collision()->IsEnd(m_Pos.x, m_Pos.y) && m_RaceState == RACE_STARTED)
|
||||
{
|
||||
char aBuf[128];
|
||||
if ((int)time / 60 != 0)
|
||||
str_format(aBuf, sizeof(aBuf), "%s finished in: %d minute(s) %5.3f second(s)", (!g_Config.m_SvHideScore)?Server()->ClientName(m_pPlayer->GetCID()):"You", (int)time/60, time - ((int)time/60*60));
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "%s finished in: %5.3f second(s)", (!g_Config.m_SvHideScore) ? Server()->ClientName(m_pPlayer->GetCID()):"You", time - ((int)time/60*60));
|
||||
if (!g_Config.m_SvHideScore)
|
||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
||||
else
|
||||
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
|
||||
CPlayerScore *pPScore = ((CGameControllerRace*) GameServer()->m_pController)->m_Score.SearchName(Server()->ClientName(m_pPlayer->GetCID()));
|
||||
if(pPScore && time - pPScore->m_Score < 0)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "New record: %5.3f second(s) better", time - pPScore->m_Score);
|
||||
if (!g_Config.m_SvHideScore)
|
||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
|
||||
else
|
||||
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
|
||||
}
|
||||
m_RaceState = RACE_NONE;
|
||||
if(strncmp(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0)
|
||||
((CGameControllerRace*)GameServer()->m_pController)->m_Score.ParsePlayer(Server()->ClientName(m_pPlayer->GetCID()), (float)time);
|
||||
}
|
||||
if(GameServer()->Collision()->IsKick(m_Pos.x, m_Pos.y) && !m_Super)
|
||||
{
|
||||
if (m_pPlayer->m_Authed > 0)
|
||||
Die(-1, WEAPON_WORLD);
|
||||
else
|
||||
((CServer*)GameServer()->Server())->Kick(m_pPlayer->GetCID(), "You was kicked by kick zone");
|
||||
}
|
||||
if(GameServer()->Collision()->IsFreeze(m_Pos.x, m_Pos.y) && !m_Super)
|
||||
{
|
||||
Freeze(Server()->TickSpeed()*3);
|
||||
}
|
||||
if(GameServer()->Collision()->IsUnfreeze(m_Pos.x, m_Pos.y) && !m_Super)
|
||||
{
|
||||
UnFreeze();
|
||||
}
|
||||
int booster = GameServer()->Collision()->IsBoost(m_Pos.x, m_Pos.y);
|
||||
m_Core.m_Vel += GameServer()->Collision()->BoostAccel(booster);
|
||||
int z = GameServer()->Collision()->IsTeleport(m_Pos.x, m_Pos.y);
|
||||
if(z)
|
||||
{
|
||||
m_Core.m_HookedPlayer = -1;
|
||||
m_Core.m_HookState = HOOK_RETRACTED;
|
||||
m_Core.m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
||||
m_Core.m_HookPos = m_Core.m_Pos;
|
||||
m_Core.m_Pos = GameServer()->Collision()->Teleport(z);
|
||||
}
|
||||
|
||||
// handle death-tiles
|
||||
if(GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
||||
if((GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
||||
GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
||||
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
|
||||
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH)
|
||||
GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH) && !m_Super)
|
||||
{
|
||||
Die(m_pPlayer->GetCID(), WEAPON_WORLD);
|
||||
}
|
||||
|
@ -558,9 +690,39 @@ void CCharacter::Tick()
|
|||
|
||||
// Previnput
|
||||
m_PrevInput = m_Input;
|
||||
if (!m_Doored)
|
||||
{
|
||||
m_OlderPos = m_OldPos;
|
||||
m_OldPos = m_Core.m_Pos;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float point_distance(vec2 point, vec2 line_start, vec2 line_end)
|
||||
{
|
||||
float res = -1.0f;
|
||||
vec2 dir = normalize(line_end-line_start);
|
||||
for(int i = 0; i < length(line_end-line_start); i++)
|
||||
{
|
||||
vec2 step = dir;
|
||||
step.x *= i;
|
||||
step.y *= i;
|
||||
float dist = distance(step+line_start, point);
|
||||
if(res < 0 || dist < res)
|
||||
res = dist;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void CCharacter::ResetPos()
|
||||
{
|
||||
m_Core.m_Pos = m_OlderPos;
|
||||
//core.pos-=core.vel;
|
||||
m_Core.m_Vel = vec2(0,0);
|
||||
if(m_Core.m_Jumped >= 2)
|
||||
m_Core.m_Jumped = 1;
|
||||
}
|
||||
|
||||
void CCharacter::TickDefered()
|
||||
{
|
||||
// advance the dummy
|
||||
|
@ -578,6 +740,11 @@ void CCharacter::TickDefered()
|
|||
bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
|
||||
|
||||
m_Core.Move();
|
||||
if(m_Doored)
|
||||
{
|
||||
ResetPos();
|
||||
m_Doored = false;
|
||||
}
|
||||
bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
|
||||
m_Core.Quantize();
|
||||
bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
|
||||
|
@ -642,6 +809,54 @@ void CCharacter::TickDefered()
|
|||
}
|
||||
}
|
||||
|
||||
bool CCharacter::Freeze(int time)
|
||||
{
|
||||
if (time <= 1 || m_Super)
|
||||
return false;
|
||||
if (m_FreezeTick < Server()->Tick() - Server()->TickSpeed())
|
||||
{
|
||||
m_FreezeTick = Server()->Tick();
|
||||
m_FreezeTime = time;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCharacter::Freeze()
|
||||
{
|
||||
int time = Server()->TickSpeed()*3;
|
||||
if (time <= 1 || m_Super)
|
||||
return false;
|
||||
if (m_FreezeTick < Server()->Tick()- Server()->TickSpeed())
|
||||
{
|
||||
m_FreezeTick = Server()->Tick();
|
||||
m_FreezeTime = time;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCharacter::UnFreeze()
|
||||
{
|
||||
if (m_FreezeTime > 0)
|
||||
{
|
||||
m_FreezeTick = 0;
|
||||
m_FreezeTime = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCharacter::GiveAllWeapons()
|
||||
{
|
||||
for(int i=1;i<NUM_WEAPONS-1;i++)
|
||||
{
|
||||
m_aWeapons[i].m_Got = true;
|
||||
m_aWeapons[i].m_Ammo = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool CCharacter::IncreaseHealth(int Amount)
|
||||
{
|
||||
if(m_Health >= 10)
|
||||
|
@ -692,7 +907,7 @@ void CCharacter::Die(int Killer, int Weapon)
|
|||
bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
|
||||
{
|
||||
m_Core.m_Vel += Force;
|
||||
|
||||
/*
|
||||
if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage)
|
||||
return false;
|
||||
|
||||
|
@ -771,7 +986,7 @@ bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
|
|||
|
||||
m_EmoteType = EMOTE_PAIN;
|
||||
m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000;
|
||||
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -796,6 +1011,9 @@ void CCharacter::Snap(int SnappingClient)
|
|||
m_SendCore.Write(Character);
|
||||
}
|
||||
|
||||
if(m_DoSplash) {
|
||||
Character->m_Jumped = 3;
|
||||
}
|
||||
// set emote
|
||||
if (m_EmoteStop < Server()->Tick())
|
||||
{
|
||||
|
@ -809,7 +1027,13 @@ void CCharacter::Snap(int SnappingClient)
|
|||
Character->m_Health = 0;
|
||||
Character->m_Armor = 0;
|
||||
|
||||
Character->m_Weapon = m_ActiveWeapon;
|
||||
if (m_FreezeTime > 0)
|
||||
{
|
||||
Character->m_Emote = EMOTE_PAIN;
|
||||
Character->m_Weapon = WEAPON_NINJA;
|
||||
}
|
||||
else
|
||||
Character->m_Weapon = m_ActiveWeapon;
|
||||
Character->m_AttackTick = m_AttackTick;
|
||||
|
||||
Character->m_Direction = m_Input.m_Direction;
|
||||
|
|
|
@ -14,6 +14,14 @@ enum
|
|||
WEAPON_WORLD = -1, // death tiles etc
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RACE_NONE = 0,
|
||||
RACE_STARTED,
|
||||
RACE_CHEAT, // no time and won't start again unless oredered by a mod or death
|
||||
RACE_PAUSE//No time nor movement
|
||||
};
|
||||
|
||||
class CCharacter : public CEntity
|
||||
{
|
||||
MACRO_ALLOC_POOL_ID()
|
||||
|
@ -55,21 +63,20 @@ public:
|
|||
bool GiveWeapon(int Weapon, int Ammo);
|
||||
void GiveNinja();
|
||||
|
||||
void ResetPos();
|
||||
|
||||
bool Freeze(int Time);
|
||||
bool Freeze();
|
||||
bool UnFreeze();
|
||||
|
||||
void GiveAllWeapons();
|
||||
|
||||
void SetEmote(int Emote, int Tick);
|
||||
|
||||
bool IsAlive() const { return m_Alive; }
|
||||
class CPlayer *GetPlayer() { return m_pPlayer; }
|
||||
|
||||
private:
|
||||
// player controlling this character
|
||||
class CPlayer *m_pPlayer;
|
||||
|
||||
bool m_Alive;
|
||||
|
||||
// weapon info
|
||||
CEntity *m_apHitObjects[10];
|
||||
int m_NumObjectsHit;
|
||||
|
||||
// the player core for the physics
|
||||
CCharacterCore m_Core;
|
||||
struct WeaponStat
|
||||
{
|
||||
int m_AmmoRegenStart;
|
||||
|
@ -78,9 +85,42 @@ private:
|
|||
bool m_Got;
|
||||
|
||||
} m_aWeapons[NUM_WEAPONS];
|
||||
|
||||
int m_ActiveWeapon;
|
||||
int m_LastWeapon;
|
||||
// player controlling this character
|
||||
class CPlayer *m_pPlayer;
|
||||
|
||||
int m_RaceState;
|
||||
|
||||
struct
|
||||
{
|
||||
vec2 m_ActivationDir;
|
||||
int m_ActivationTick;
|
||||
int m_CurrentMoveTime;
|
||||
|
||||
} m_Ninja;
|
||||
|
||||
int m_HammerType;
|
||||
bool m_Super;
|
||||
|
||||
//DDRace
|
||||
int m_FreezeTime;
|
||||
int m_FreezeTick;
|
||||
|
||||
bool m_Doored;
|
||||
|
||||
vec2 m_OldPos;
|
||||
vec2 m_OlderPos;
|
||||
|
||||
bool m_Alive;
|
||||
|
||||
// weapon info
|
||||
CEntity *m_apHitObjects[10];
|
||||
int m_NumObjectsHit;
|
||||
|
||||
|
||||
|
||||
|
||||
int m_QueuedWeapon;
|
||||
|
||||
int m_ReloadTimer;
|
||||
|
@ -110,18 +150,23 @@ private:
|
|||
int m_Armor;
|
||||
|
||||
// ninja
|
||||
struct
|
||||
{
|
||||
vec2 m_ActivationDir;
|
||||
int m_ActivationTick;
|
||||
int m_CurrentMoveTime;
|
||||
|
||||
} m_Ninja;
|
||||
|
||||
|
||||
int m_PlayerState;// if the client is chatting, accessing a menu or so
|
||||
|
||||
bool m_IsWater;
|
||||
bool m_DoSplash;
|
||||
int m_LastMove;
|
||||
// race var
|
||||
int m_StartTime;
|
||||
int m_RefreshTime;
|
||||
|
||||
// checkpoints
|
||||
int m_CpTick;
|
||||
int m_CpActive;
|
||||
float m_CpCurrent[149];
|
||||
|
||||
|
||||
// the player core for the physics
|
||||
CCharacterCore m_Core;
|
||||
|
||||
// info for dead reckoning
|
||||
int m_ReckoningTick; // tick that we are performing dead reckoning From
|
||||
|
|
144
src/game/server/entities/drager.cpp
Normal file
144
src/game/server/entities/drager.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/config.h>
|
||||
#include <engine/server.h>
|
||||
#include <game/generated/protocol.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include "drager.h"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// CDrager
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
const int LENGTH=700;
|
||||
|
||||
CDrager::CDrager(CGameWorld *pGameWorld, vec2 pos, float strength, bool nw)
|
||||
: CEntity(pGameWorld, NETOBJTYPE_LASER)
|
||||
{
|
||||
this->m_Pos = pos;
|
||||
this->strength = strength;
|
||||
this->eval_tick=Server()->Tick();
|
||||
this->nw=nw;
|
||||
GameWorld()->InsertEntity(this);
|
||||
}
|
||||
|
||||
void CDrager::move()
|
||||
{
|
||||
if (target)
|
||||
return;
|
||||
CCharacter *ents[16];
|
||||
int num = -1;
|
||||
num = GameServer()->m_World.FindEntities(m_Pos,LENGTH, (CEntity**)ents, 16, NETOBJTYPE_CHARACTER);
|
||||
int id=-1;
|
||||
int minlen=0;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
target = ents[i];
|
||||
int res=0;
|
||||
if (!nw)
|
||||
res = GameServer()->Collision()->IntersectNolaser(m_Pos, target->m_Pos, 0, 0);
|
||||
else
|
||||
res = GameServer()->Collision()->IntersectNolaser2(m_Pos, target->m_Pos, 0, 0);
|
||||
|
||||
if (res==0)
|
||||
{
|
||||
int len=length(ents[i]->m_Pos - m_Pos);
|
||||
if (minlen==0 || minlen>len)
|
||||
{
|
||||
minlen=len;
|
||||
id=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (id!=-1)
|
||||
{
|
||||
target = ents[id];
|
||||
}
|
||||
else
|
||||
{
|
||||
target=0;
|
||||
}
|
||||
}
|
||||
|
||||
void CDrager::drag()
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
|
||||
int res = 0;
|
||||
if (!nw)
|
||||
res = GameServer()->Collision()->IntersectNolaser(m_Pos, target->m_Pos, 0, 0);
|
||||
else
|
||||
res = GameServer()->Collision()->IntersectNolaser2(m_Pos, target->m_Pos, 0, 0);
|
||||
|
||||
if (res || length(m_Pos-target->m_Pos)>700)
|
||||
{
|
||||
target=0;
|
||||
}
|
||||
else
|
||||
if (length(m_Pos-target->m_Pos)>28)
|
||||
{
|
||||
target->m_Core.m_Vel+=normalize(m_Pos-target->m_Pos)*strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDrager::Reset()
|
||||
{
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
|
||||
void CDrager::Tick()
|
||||
{
|
||||
if (Server()->Tick()%int(Server()->TickSpeed()*0.15f)==0)
|
||||
{
|
||||
eval_tick=Server()->Tick();
|
||||
int index = GameServer()->Collision()->IsCp(m_Pos.x, m_Pos.y);
|
||||
if (index)
|
||||
{
|
||||
core=GameServer()->Collision()->CpSpeed(index);
|
||||
}
|
||||
m_Pos+=core;
|
||||
move();
|
||||
}
|
||||
drag();
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CDrager::Snap(int snapping_client)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
if(NetworkClipped(snapping_client, m_Pos) && NetworkClipped(snapping_client,target->m_Pos))
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(NetworkClipped(snapping_client,m_Pos))
|
||||
return;
|
||||
|
||||
CNetObj_Laser *obj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, m_Id, sizeof(CNetObj_Laser)));
|
||||
|
||||
obj->m_X = (int)m_Pos.x;
|
||||
obj->m_Y = (int)m_Pos.y;
|
||||
if (target)
|
||||
{
|
||||
obj->m_FromX = (int)target->m_Pos.x;
|
||||
obj->m_FromY = (int)target->m_Pos.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->m_FromX = (int)m_Pos.x;
|
||||
obj->m_FromY = (int)m_Pos.y;
|
||||
}
|
||||
|
||||
|
||||
int start_tick = eval_tick;
|
||||
if (start_tick<Server()->Tick()-4)
|
||||
start_tick=Server()->Tick()-4;
|
||||
else if (start_tick>Server()->Tick())
|
||||
start_tick=Server()->Tick();
|
||||
obj->m_StartTick = start_tick;
|
||||
}
|
||||
//ÿ òóò áûë
|
||||
//ÿ òîæå
|
29
src/game/server/entities/drager.h
Normal file
29
src/game/server/entities/drager.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef GAME_SERVER_ENTITY_DRAGER_H
|
||||
#define GAME_SERVER_ENTITY_DRAGER_H
|
||||
|
||||
#include <game/server/entity.h>
|
||||
|
||||
class CCharacter;
|
||||
|
||||
class CDrager : public CEntity
|
||||
{
|
||||
vec2 core;
|
||||
float strength;
|
||||
int eval_tick;
|
||||
void move();
|
||||
void drag();
|
||||
CCharacter *target;
|
||||
bool nw;
|
||||
public:
|
||||
|
||||
|
||||
CDrager(CGameWorld *pGameWorld, vec2 pos, float strength, bool nw=false);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Tick();
|
||||
virtual void Snap(int snapping_client);
|
||||
};
|
||||
|
||||
#endif
|
95
src/game/server/entities/gun.cpp
Normal file
95
src/game/server/entities/gun.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/server.h>
|
||||
#include <engine/config.h>
|
||||
#include <game/generated/protocol.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include "gun.h"
|
||||
#include "plasma.h"
|
||||
|
||||
|
||||
const int RANGE=700;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// CGun
|
||||
//////////////////////////////////////////////////
|
||||
CGun::CGun(CGameWorld *pGameWorld, vec2 m_Pos)
|
||||
: CEntity(pGameWorld, NETOBJTYPE_LASER)
|
||||
{
|
||||
DELAY=Server()->TickSpeed()*0.3f;
|
||||
this->m_Pos = m_Pos;
|
||||
this->eval_tick=Server()->Tick();
|
||||
|
||||
GameWorld()->InsertEntity(this);
|
||||
}
|
||||
|
||||
|
||||
void CGun::fire()
|
||||
{
|
||||
CCharacter *ents[16];
|
||||
int num = -1;
|
||||
num = GameServer()->m_World.FindEntities(m_Pos,RANGE, (CEntity**)ents, 16, NETOBJTYPE_CHARACTER);
|
||||
int id=-1;
|
||||
int minlen=0;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
CCharacter *target = ents[i];
|
||||
int res=0;
|
||||
vec2 coltile;
|
||||
res = GameServer()->Collision()->IntersectLine(m_Pos, target->m_Pos,0,0);
|
||||
if (!res)
|
||||
{
|
||||
int len=length(ents[i]->m_Pos - m_Pos);
|
||||
if (minlen==0)
|
||||
{
|
||||
minlen=len;
|
||||
id=i;
|
||||
}
|
||||
else if(minlen>len)
|
||||
{
|
||||
minlen=len;
|
||||
id=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (id!=-1)
|
||||
{
|
||||
CCharacter *target = ents[id];
|
||||
vec2 fdir = normalize(target->m_Pos - m_Pos);
|
||||
new CPlasma(&GameServer()->m_World, m_Pos,fdir);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CGun::Reset()
|
||||
{
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
|
||||
void CGun::Tick()
|
||||
{
|
||||
if (Server()->Tick()%int(Server()->TickSpeed()*0.15f)==0)
|
||||
{
|
||||
eval_tick=Server()->Tick();
|
||||
int index = GameServer()->Collision()->IsCp(m_Pos.x,m_Pos.y);
|
||||
if (index)
|
||||
{
|
||||
core=GameServer()->Collision()->CpSpeed(index);
|
||||
}
|
||||
m_Pos+=core;
|
||||
fire();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CGun::Snap(int snapping_client)
|
||||
{
|
||||
if(NetworkClipped(snapping_client))
|
||||
return;
|
||||
|
||||
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, m_Id, sizeof(CNetObj_Laser)));
|
||||
pObj->m_X = (int)m_Pos.x;
|
||||
pObj->m_Y = (int)m_Pos.y;
|
||||
pObj->m_FromX = (int)m_Pos.x;
|
||||
pObj->m_FromY = (int)m_Pos.y;
|
||||
pObj->m_StartTick = eval_tick;
|
||||
}
|
29
src/game/server/entities/gun.h
Normal file
29
src/game/server/entities/gun.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef CGun_TYPE
|
||||
#define CGun_TYPE
|
||||
|
||||
#include <game/server/entity.h>
|
||||
#include <game/gamecore.h>
|
||||
|
||||
class CCharacter;
|
||||
|
||||
class CGun : public CEntity
|
||||
{
|
||||
int eval_tick;
|
||||
|
||||
vec2 core;
|
||||
|
||||
void fire();
|
||||
int DELAY;
|
||||
|
||||
public:
|
||||
CGun(CGameWorld *pGameWorld, vec2 pos);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Tick();
|
||||
virtual void Snap(int SnappingClient);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,9 +1,10 @@
|
|||
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
|
||||
#include <game/generated/protocol.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include "laser.h"
|
||||
|
||||
CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner)
|
||||
CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner, int type)
|
||||
: CEntity(pGameWorld, NETOBJTYPE_LASER)
|
||||
{
|
||||
m_Pos = Pos;
|
||||
|
@ -12,6 +13,7 @@ CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEner
|
|||
m_Dir = Direction;
|
||||
m_Bounces = 0;
|
||||
m_EvalTick = 0;
|
||||
m_Type = type;
|
||||
GameWorld()->InsertEntity(this);
|
||||
DoBounce();
|
||||
}
|
||||
|
@ -27,13 +29,20 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
|
|||
|
||||
m_From = From;
|
||||
m_Pos = At;
|
||||
m_Energy = -1;
|
||||
Hit->TakeDamage(vec2(0.f, 0.f), GameServer()->Tuning()->m_LaserDamage, m_Owner, WEAPON_RIFLE);
|
||||
m_Energy = -1;
|
||||
if ((m_Type == 1 && g_Config.m_SvHit))
|
||||
{
|
||||
Hit->m_Core.m_Vel += normalize(m_PrevPos - Hit->m_Core.m_Pos) * 10;
|
||||
} else if (m_Type == 0)
|
||||
{
|
||||
Hit->UnFreeze();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLaser::DoBounce()
|
||||
{
|
||||
CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
|
||||
m_EvalTick = Server()->Tick();
|
||||
|
||||
if(m_Energy < 0)
|
||||
|
@ -41,11 +50,15 @@ void CLaser::DoBounce()
|
|||
GameServer()->m_World.DestroyEntity(this);
|
||||
return;
|
||||
}
|
||||
|
||||
m_PrevPos = m_Pos;
|
||||
vec2 To = m_Pos + m_Dir * m_Energy;
|
||||
vec2 OrgTo = To;
|
||||
vec2 Coltile;
|
||||
|
||||
if(GameServer()->Collision()->IntersectLine(m_Pos, To, 0x0, &To))
|
||||
int res;
|
||||
res = GameServer()->Collision()->IntersectLine(m_Pos, To, &Coltile, &To);
|
||||
|
||||
if(res)
|
||||
{
|
||||
if(!HitCharacter(m_Pos, To))
|
||||
{
|
||||
|
@ -56,7 +69,15 @@ void CLaser::DoBounce()
|
|||
vec2 TempPos = m_Pos;
|
||||
vec2 TempDir = m_Dir * 4.0f;
|
||||
|
||||
int f;
|
||||
if(res == -1) {
|
||||
f = GameServer()->Collision()->GetTile(round(Coltile.x), round(Coltile.y));
|
||||
GameServer()->Collision()->Set(round(Coltile.x), round(Coltile.y), CCollision::COLFLAG_SOLID);
|
||||
}
|
||||
GameServer()->Collision()->MovePoint(&TempPos, &TempDir, 1.0f, 0);
|
||||
if(res == -1) {
|
||||
GameServer()->Collision()->Set(round(Coltile.x), round(Coltile.y), f);
|
||||
}
|
||||
m_Pos = TempPos;
|
||||
m_Dir = normalize(TempDir);
|
||||
|
||||
|
@ -78,6 +99,7 @@ void CLaser::DoBounce()
|
|||
m_Energy = -1;
|
||||
}
|
||||
}
|
||||
m_Owner = -1;
|
||||
}
|
||||
|
||||
void CLaser::Reset()
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
class CLaser : public CEntity
|
||||
{
|
||||
public:
|
||||
CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner);
|
||||
CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner, int type);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Tick();
|
||||
|
@ -17,12 +17,14 @@ protected:
|
|||
void DoBounce();
|
||||
|
||||
private:
|
||||
vec2 m_PrevPos;
|
||||
vec2 m_From;
|
||||
vec2 m_Dir;
|
||||
float m_Energy;
|
||||
int m_Bounces;
|
||||
int m_EvalTick;
|
||||
int m_Owner;
|
||||
int m_Type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
119
src/game/server/entities/light.cpp
Normal file
119
src/game/server/entities/light.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/config.h>
|
||||
#include <engine/server.h>
|
||||
#include <game/generated/protocol.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include "light.h"
|
||||
#include <game/mapitems.h>
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// CLight
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
CLight::CLight(CGameWorld *pGameWorld, vec2 pos, float rotation, int length)
|
||||
: CEntity(pGameWorld, NETOBJTYPE_LASER)
|
||||
{
|
||||
TICK=(Server()->TickSpeed()*0.15f);
|
||||
this->m_Pos = pos;
|
||||
this->rotation = rotation;
|
||||
this->length = length;
|
||||
this->eval_tick=Server()->Tick();
|
||||
GameWorld()->InsertEntity(this);
|
||||
step();
|
||||
}
|
||||
|
||||
|
||||
bool CLight::hit_character()
|
||||
{
|
||||
vec2 nothing;
|
||||
CCharacter *hit = GameServer()->m_World.IntersectCharacter(m_Pos, to, 0.0f, nothing, 0);
|
||||
if(!hit)
|
||||
return false;
|
||||
hit->Freeze(Server()->TickSpeed()*3);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void CLight::move()
|
||||
{
|
||||
if (speed != 0)
|
||||
{
|
||||
if ((cur_length>=length && speed>0) || (cur_length<=0 && speed<0))
|
||||
speed=-speed;
|
||||
cur_length+=speed*TICK + length_l;
|
||||
length_l=0;
|
||||
if (cur_length>length)
|
||||
{
|
||||
length_l=cur_length-length;
|
||||
cur_length=length;
|
||||
}
|
||||
else if(cur_length<0)
|
||||
{
|
||||
length_l=0+cur_length;
|
||||
cur_length=0;
|
||||
}
|
||||
}
|
||||
|
||||
rotation+=ang_speed*TICK;
|
||||
if (rotation>pi*2)
|
||||
rotation-=pi*2;
|
||||
else if(rotation<0)
|
||||
rotation+=pi*2;
|
||||
}
|
||||
|
||||
void CLight::step()
|
||||
{
|
||||
move();
|
||||
vec2 dir(sin(rotation), cos(rotation));
|
||||
vec2 to2 = m_Pos + normalize(dir)*cur_length;
|
||||
GameServer()->Collision()->IntersectNolaser(m_Pos, to2, &to,0 );
|
||||
}
|
||||
|
||||
void CLight::Reset()
|
||||
{
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
|
||||
void CLight::Tick()
|
||||
{
|
||||
|
||||
if (Server()->Tick()%int(Server()->TickSpeed()*0.15f)==0)
|
||||
{
|
||||
eval_tick=Server()->Tick();
|
||||
int index = GameServer()->Collision()->IsCp(m_Pos.x,m_Pos.y);
|
||||
if (index)
|
||||
{
|
||||
core=GameServer()->Collision()->CpSpeed(index);
|
||||
}
|
||||
m_Pos+=core;
|
||||
step();
|
||||
}
|
||||
|
||||
hit_character();
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CLight::Snap(int snapping_client)
|
||||
{
|
||||
if(NetworkClipped(snapping_client,m_Pos) && NetworkClipped(snapping_client,to))
|
||||
return;
|
||||
|
||||
|
||||
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, m_Id, sizeof(CNetObj_Laser)));
|
||||
pObj->m_X = (int)m_Pos.x;
|
||||
pObj->m_Y = (int)m_Pos.y;
|
||||
pObj->m_FromX = (int)to.x;
|
||||
pObj->m_FromY = (int)to.y;
|
||||
|
||||
|
||||
int start_tick = eval_tick;
|
||||
if (start_tick<Server()->Tick()-4)
|
||||
start_tick=Server()->Tick()-4;
|
||||
else if (start_tick>Server()->Tick())
|
||||
start_tick=Server()->Tick();
|
||||
pObj->m_StartTick = start_tick;
|
||||
}
|
36
src/game/server/entities/light.h
Normal file
36
src/game/server/entities/light.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef GAME_SERVER_CEntity_CLight_H
|
||||
#define GAME_SERVER_CEntity_CLight_H
|
||||
|
||||
#include <game/server/entity.h>
|
||||
|
||||
class CLight : public CEntity
|
||||
{
|
||||
float rotation;
|
||||
vec2 to;
|
||||
vec2 core;
|
||||
|
||||
int eval_tick;
|
||||
|
||||
int TICK;
|
||||
|
||||
bool hit_character();
|
||||
void move();
|
||||
void step();
|
||||
public:
|
||||
int cur_length;
|
||||
int length_l;
|
||||
float ang_speed;
|
||||
int speed;
|
||||
int length;
|
||||
|
||||
|
||||
CLight(CGameWorld *pGameWorld, vec2 pos, float rotation, int length);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Tick();
|
||||
virtual void Snap(int SnappingClient);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -16,16 +16,32 @@ CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType)
|
|||
|
||||
void CPickup::Reset()
|
||||
{
|
||||
/*
|
||||
if (g_pData->m_aPickups[m_Type].m_Spawndelay > 0)
|
||||
m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * g_pData->m_aPickups[m_Type].m_Spawndelay;
|
||||
else
|
||||
m_SpawnTick = -1;
|
||||
*/
|
||||
}
|
||||
|
||||
void CPickup::Move()
|
||||
{
|
||||
if (Server()->Tick()%int(Server()->TickSpeed() * 0.15f) == 0)
|
||||
{
|
||||
int index = GameServer()->Collision()->IsCp(m_Pos.x, m_Pos.y);
|
||||
if (index)
|
||||
{
|
||||
m_Core = GameServer()->Collision()->CpSpeed(index);
|
||||
}
|
||||
m_Pos += m_Core;
|
||||
}
|
||||
}
|
||||
|
||||
void CPickup::Tick()
|
||||
{
|
||||
Move();
|
||||
// wait for respawn
|
||||
if(m_SpawnTick > 0)
|
||||
/*if(m_SpawnTick > 0)
|
||||
{
|
||||
if(Server()->Tick() > m_SpawnTick)
|
||||
{
|
||||
|
@ -37,38 +53,46 @@ void CPickup::Tick()
|
|||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
// Check if a player intersected us
|
||||
CCharacter *pChr = GameServer()->m_World.ClosestCharacter(m_Pos, 20.0f, 0);
|
||||
if(pChr && pChr->IsAlive())
|
||||
{
|
||||
bool sound = false;
|
||||
// player picked us up, is someone was hooking us, let them go
|
||||
int RespawnTime = -1;
|
||||
switch (m_Type)
|
||||
{
|
||||
case POWERUP_HEALTH:
|
||||
if(pChr->IncreaseHealth(1))
|
||||
{
|
||||
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
|
||||
RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
|
||||
}
|
||||
if(pChr->Freeze()) GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
|
||||
break;
|
||||
|
||||
case POWERUP_ARMOR:
|
||||
if(pChr->IncreaseArmor(1))
|
||||
for(int i=WEAPON_SHOTGUN;i<NUM_WEAPONS;i++)
|
||||
{
|
||||
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
|
||||
RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
|
||||
if (pChr->m_aWeapons[i].m_Got)
|
||||
{
|
||||
pChr->m_aWeapons[i].m_Got = false;
|
||||
pChr->m_aWeapons[i].m_Ammo = 0;
|
||||
sound = true;
|
||||
}
|
||||
}
|
||||
if (sound)
|
||||
{
|
||||
pChr->m_LastWeapon = WEAPON_GUN;
|
||||
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
|
||||
}
|
||||
pChr->m_ActiveWeapon = WEAPON_HAMMER;
|
||||
break;
|
||||
|
||||
case POWERUP_WEAPON:
|
||||
|
||||
if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS)
|
||||
{
|
||||
if(pChr->GiveWeapon(m_Subtype, 10))
|
||||
if(pChr->GiveWeapon(m_Subtype, -1))
|
||||
{
|
||||
RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
|
||||
|
||||
//RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
|
||||
|
||||
if(m_Subtype == WEAPON_GRENADE)
|
||||
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
|
||||
else if(m_Subtype == WEAPON_SHOTGUN)
|
||||
|
@ -86,41 +110,30 @@ void CPickup::Tick()
|
|||
{
|
||||
// activate ninja on target player
|
||||
pChr->GiveNinja();
|
||||
RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
|
||||
|
||||
// loop through all players, setting their emotes
|
||||
CEntity *apEnts[64];
|
||||
int Num = GameServer()->m_World.FindEntities(vec2(0, 0), 1000000, apEnts, 64, NETOBJTYPE_CHARACTER);
|
||||
//RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
|
||||
|
||||
for (int i = 0; i < Num; ++i)
|
||||
{
|
||||
CCharacter *pC = static_cast<CCharacter *>(apEnts[i]);
|
||||
if (pC != pChr)
|
||||
pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed());
|
||||
}
|
||||
|
||||
pChr->SetEmote(EMOTE_ANGRY, Server()->Tick() + 1200 * Server()->TickSpeed() / 1000);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
/*
|
||||
if(RespawnTime >= 0)
|
||||
{
|
||||
dbg_msg("game", "pickup player='%d:%s' item=%d/%d",
|
||||
pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type, m_Subtype);
|
||||
m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * RespawnTime;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void CPickup::Snap(int SnappingClient)
|
||||
{
|
||||
/*
|
||||
if(m_SpawnTick != -1 || NetworkClipped(SnappingClient))
|
||||
return;
|
||||
|
||||
*/
|
||||
CNetObj_Pickup *pP = static_cast<CNetObj_Pickup *>(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_Id, sizeof(CNetObj_Pickup)));
|
||||
pP->m_X = (int)m_Pos.x;
|
||||
pP->m_Y = (int)m_Pos.y;
|
||||
|
|
|
@ -15,9 +15,12 @@ public:
|
|||
virtual void Snap(int SnappingClient);
|
||||
|
||||
private:
|
||||
|
||||
void Move();
|
||||
int m_Type;
|
||||
int m_Subtype;
|
||||
int m_SpawnTick;
|
||||
//int m_SpawnTick;
|
||||
vec2 m_Core;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
78
src/game/server/entities/plasma.cpp
Normal file
78
src/game/server/entities/plasma.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/server.h>
|
||||
#include <engine/config.h>
|
||||
#include <game/generated/protocol.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include "plasma.h"
|
||||
|
||||
const float ACCEL=1.1f;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// turret
|
||||
//////////////////////////////////////////////////
|
||||
CPlasma::CPlasma(CGameWorld *pGameWorld, vec2 pos,vec2 dir)
|
||||
: CEntity(pGameWorld, NETOBJTYPE_LASER)
|
||||
{
|
||||
this->m_Pos = pos;
|
||||
this->core = dir;
|
||||
this->eval_tick=Server()->Tick();
|
||||
this->lifetime=Server()->TickSpeed()*1.5;
|
||||
GameWorld()->InsertEntity(this);
|
||||
}
|
||||
|
||||
bool CPlasma::hit_character()
|
||||
{
|
||||
vec2 to2;
|
||||
CCharacter *hit = GameServer()->m_World.IntersectCharacter(m_Pos, m_Pos+core, 0.0f,to2);
|
||||
if(!hit)
|
||||
return false;
|
||||
hit->Freeze(Server()->TickSpeed()*3);
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlasma::move()
|
||||
{
|
||||
m_Pos += core;
|
||||
core *= ACCEL;
|
||||
}
|
||||
|
||||
void CPlasma::Reset()
|
||||
{
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
|
||||
void CPlasma::Tick()
|
||||
{
|
||||
if (lifetime==0)
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
lifetime--;
|
||||
move();
|
||||
hit_character();
|
||||
|
||||
int res=0;
|
||||
res = GameServer()->Collision()->IntersectNolaser(m_Pos, m_Pos+core,0, 0);
|
||||
if(res)
|
||||
{
|
||||
GameServer()->CreateExplosion(m_Pos, -1, WEAPON_GRENADE, false);
|
||||
Reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CPlasma::Snap(int snapping_client)
|
||||
{
|
||||
if(NetworkClipped(snapping_client))
|
||||
return;
|
||||
|
||||
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, m_Id, sizeof(CNetObj_Laser)));
|
||||
pObj->m_X = (int)m_Pos.x;
|
||||
pObj->m_Y = (int)m_Pos.y;
|
||||
pObj->m_FromX = (int)m_Pos.x;
|
||||
pObj->m_FromY = (int)m_Pos.y;
|
||||
pObj->m_StartTick = eval_tick;
|
||||
}
|
27
src/game/server/entities/plasma.h
Normal file
27
src/game/server/entities/plasma.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef PLASMA_TYPE
|
||||
#define PLASMA_TYPE
|
||||
|
||||
#include <game/server/entity.h>
|
||||
|
||||
class CGun;
|
||||
|
||||
class CPlasma : public CEntity
|
||||
{
|
||||
vec2 core;
|
||||
int eval_tick;
|
||||
int lifetime;
|
||||
|
||||
bool hit_character();
|
||||
void move();
|
||||
public:
|
||||
CPlasma(CGameWorld *pGameWorld, vec2 pos,vec2 dir);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Tick();
|
||||
virtual void Snap(int snapping_client);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,9 +1,10 @@
|
|||
#include <game/generated/protocol.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include "projectile.h"
|
||||
|
||||
CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
|
||||
int Damage, bool Explosive, float Force, int SoundImpact, int Weapon)
|
||||
bool Freeze, bool Explosive, float Force, int SoundImpact, int Weapon)
|
||||
: CEntity(pGameWorld, NETOBJTYPE_PROJECTILE)
|
||||
{
|
||||
m_Type = Type;
|
||||
|
@ -12,7 +13,8 @@ CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos,
|
|||
m_LifeSpan = Span;
|
||||
m_Owner = Owner;
|
||||
m_Force = Force;
|
||||
m_Damage = Damage;
|
||||
//m_Damage = Damage;
|
||||
m_Freeze = Freeze;
|
||||
m_SoundImpact = SoundImpact;
|
||||
m_Weapon = Weapon;
|
||||
m_StartTick = Server()->Tick();
|
||||
|
@ -23,7 +25,8 @@ CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos,
|
|||
|
||||
void CProjectile::Reset()
|
||||
{
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
if(m_LifeSpan > -2)
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
|
||||
vec2 CProjectile::GetPos(float Time)
|
||||
|
@ -59,23 +62,53 @@ void CProjectile::Tick()
|
|||
float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
|
||||
vec2 PrevPos = GetPos(Pt);
|
||||
vec2 CurPos = GetPos(Ct);
|
||||
int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &CurPos, 0);
|
||||
CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
|
||||
CCharacter *TargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, CurPos, 6.0f, CurPos, OwnerChar);
|
||||
|
||||
m_LifeSpan--;
|
||||
vec2 ColPos;
|
||||
vec2 NewPos;
|
||||
vec2 Speed = CurPos - PrevPos;
|
||||
int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &ColPos, &NewPos);
|
||||
CCharacter *OwnerChar;
|
||||
|
||||
if(TargetChr || Collide || m_LifeSpan < 0)
|
||||
|
||||
|
||||
if(m_Owner >= 0)
|
||||
OwnerChar = GameServer()->GetPlayerChar(m_Owner);
|
||||
|
||||
CCharacter *TargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, ColPos, (m_Freeze) ? 1.0f : 6.0f, ColPos, OwnerChar);//TODO êàæåòñÿ òóò áàã ñ äâèæåíèåì âî ôðèçå
|
||||
|
||||
if(m_LifeSpan > -1)
|
||||
m_LifeSpan--;
|
||||
|
||||
|
||||
if( (TargetChr && (g_Config.m_SvHit || TargetChr == OwnerChar)) || Collide)
|
||||
{
|
||||
if(m_Explosive/*??*/ && (!TargetChr || (TargetChr && !m_Freeze)))
|
||||
{
|
||||
GameServer()->CreateExplosion(ColPos, m_Owner, m_Weapon, false);
|
||||
GameServer()->CreateSound(ColPos, m_SoundImpact);
|
||||
}
|
||||
else if(TargetChr && m_Freeze)
|
||||
TargetChr->Freeze(Server()->TickSpeed()*3);
|
||||
if (Collide && m_Bouncing != 0)
|
||||
{
|
||||
m_StartTick = Server()->Tick();
|
||||
m_Pos = NewPos;
|
||||
if (m_Bouncing == 1)
|
||||
m_Direction.x = -m_Direction.x;
|
||||
else if (m_Bouncing == 2)
|
||||
m_Direction.y =- m_Direction.y;
|
||||
m_Pos += m_Direction;
|
||||
}
|
||||
else if (m_Weapon == WEAPON_GUN)
|
||||
{
|
||||
GameServer()->CreateDamageInd(CurPos, -atan2(m_Direction.x, m_Direction.y), 10);
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
else
|
||||
if (!m_Freeze)
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
if (m_LifeSpan == -1)
|
||||
{
|
||||
if(m_LifeSpan >= 0 || m_Weapon == WEAPON_GRENADE)
|
||||
GameServer()->CreateSound(CurPos, m_SoundImpact);
|
||||
|
||||
if(m_Explosive)
|
||||
GameServer()->CreateExplosion(CurPos, m_Owner, m_Weapon, false);
|
||||
|
||||
else if(TargetChr)
|
||||
TargetChr->TakeDamage(m_Direction * max(0.001f, m_Force), m_Damage, m_Owner, m_Weapon);
|
||||
|
||||
GameServer()->m_World.DestroyEntity(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ class CProjectile : public CEntity
|
|||
{
|
||||
public:
|
||||
CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
|
||||
int Damage, bool Explosive, float Force, int SoundImpact, int Weapon);
|
||||
bool Freeeze, bool Explosive, float Force, int SoundImpact, int Weapon);
|
||||
|
||||
vec2 GetPos(float Time);
|
||||
void FillInfo(CNetObj_Projectile *pProj);
|
||||
|
@ -19,12 +19,15 @@ private:
|
|||
int m_LifeSpan;
|
||||
int m_Owner;
|
||||
int m_Type;
|
||||
int m_Damage;
|
||||
//int m_Damage;
|
||||
int m_SoundImpact;
|
||||
int m_Weapon;
|
||||
float m_Force;
|
||||
int m_StartTick;
|
||||
bool m_Explosive;
|
||||
int m_Bouncing;
|
||||
bool m_Freeze;
|
||||
bool m_Collised;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
#include <new>
|
||||
#include <string.h>
|
||||
#include <base/math.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/server/server.h>
|
||||
#include <engine/map.h>
|
||||
#include <engine/console.h>
|
||||
#include "gamecontext.h"
|
||||
#include <game/version.h>
|
||||
#include <game/collision.h>
|
||||
#include <game/gamecore.h>
|
||||
#include "gamemodes/dm.h"
|
||||
#include "gamemodes/tdm.h"
|
||||
#include "gamemodes/ctf.h"
|
||||
#include "gamemodes/mod.h"
|
||||
#include "gamemodes/race.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -33,6 +32,7 @@ void CGameContext::Construct(int Resetting)
|
|||
|
||||
if(Resetting==NO_RESET)
|
||||
m_pVoteOptionHeap = new CHeap();
|
||||
//m_Cheats = g_Config.m_SvCheats;
|
||||
}
|
||||
|
||||
CGameContext::CGameContext(int Resetting)
|
||||
|
@ -60,10 +60,12 @@ void CGameContext::Clear()
|
|||
CVoteOption *pVoteOptionLast = m_pVoteOptionLast;
|
||||
CTuningParams Tuning = m_Tuning;
|
||||
|
||||
//bool cheats = m_Cheats;
|
||||
m_Resetting = true;
|
||||
this->~CGameContext();
|
||||
mem_zero(this, sizeof(*this));
|
||||
new (this) CGameContext(RESET);
|
||||
//this->m_Cheats = cheats;
|
||||
|
||||
m_pVoteOptionHeap = pVoteOptionHeap;
|
||||
m_pVoteOptionFirst = pVoteOptionFirst;
|
||||
|
@ -137,7 +139,11 @@ void CGameContext::CreateExplosion(vec2 p, int Owner, int Weapon, bool NoDamage)
|
|||
l = 1-clamp((l-InnerRadius)/(Radius-InnerRadius), 0.0f, 1.0f);
|
||||
float Dmg = 6 * l;
|
||||
if((int)Dmg)
|
||||
apEnts[i]->TakeDamage(ForceDir*Dmg*2, (int)Dmg, Owner, Weapon);
|
||||
if(g_Config.m_SvHit || Owner == apEnts[i]->m_pPlayer->GetCID()) {
|
||||
apEnts[i]->TakeDamage(ForceDir*Dmg*2, (int)Dmg, Owner, Weapon);
|
||||
if(!g_Config.m_SvHit) break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -445,7 +451,7 @@ void CGameContext::OnTick()
|
|||
|
||||
if(m_VoteEnforce == VOTE_ENFORCE_YES)
|
||||
{
|
||||
Console()->ExecuteLine(m_aVoteCommand);
|
||||
Console()->ExecuteLine(m_aVoteCommand, 4, -1);
|
||||
EndVote();
|
||||
SendChat(-1, CGameContext::CHAT_ALL, "Vote passed");
|
||||
|
||||
|
@ -508,6 +514,26 @@ void CGameContext::OnClientEnter(int ClientId)
|
|||
m_VoteUpdate = true;
|
||||
}
|
||||
|
||||
bool compare_players(CPlayer *pl1, CPlayer *pl2)
|
||||
{
|
||||
if (pl1->m_Authed>pl2->m_Authed)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGameContext::OnSetAuthed(int client_id, void* status)
|
||||
{
|
||||
if(m_apPlayers[client_id])
|
||||
m_apPlayers[client_id]->m_Authed = (int)status;
|
||||
}
|
||||
|
||||
void CGameContext::OnSetResistent(int client_id, void* status)
|
||||
{
|
||||
if(m_apPlayers[client_id])
|
||||
m_apPlayers[client_id]->m_Resistent = (int)status;
|
||||
}
|
||||
|
||||
void CGameContext::OnClientConnected(int ClientId)
|
||||
{
|
||||
// Check which team the player should be on
|
||||
|
@ -517,7 +543,7 @@ void CGameContext::OnClientConnected(int ClientId)
|
|||
//players[client_id].init(client_id);
|
||||
//players[client_id].client_id = client_id;
|
||||
|
||||
(void)m_pController->CheckTeamBalance();
|
||||
//(void)m_pController->CheckTeamBalance();
|
||||
|
||||
#ifdef CONF_DEBUG
|
||||
if(g_Config.m_DbgDummies)
|
||||
|
@ -544,7 +570,7 @@ void CGameContext::OnClientDrop(int ClientId)
|
|||
delete m_apPlayers[ClientId];
|
||||
m_apPlayers[ClientId] = 0;
|
||||
|
||||
(void)m_pController->CheckTeamBalance();
|
||||
//(void)m_pController->CheckTeamBalance();
|
||||
m_VoteUpdate = true;
|
||||
}
|
||||
|
||||
|
@ -581,8 +607,86 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
|||
*pMessage = ' ';
|
||||
pMessage++;
|
||||
}
|
||||
if(pMsg->m_pMessage[0]=='/') {
|
||||
if(!str_comp_nocase(pMsg->m_pMessage, "/Credits"))
|
||||
{
|
||||
SendChatTarget(ClientId, "This mod was originally Created by 3DA");
|
||||
SendChatTarget(ClientId, "But now maintained by GreYFoX@GTi among other please check the changelog on DDRace.info");
|
||||
SendChatTarget(ClientId, "This port are maked by [blacktee] den.");
|
||||
} else if(!str_comp_nocase(pMsg->m_pMessage, "/pause"))
|
||||
{
|
||||
if(g_Config.m_SvPauseable && g_Config.m_SvVoteKick)
|
||||
{
|
||||
CCharacter* chr = m_apPlayers[ClientId]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
if(chr->m_RaceState==RACE_STARTED)
|
||||
chr->m_RaceState = RACE_PAUSE;
|
||||
else if(chr->m_RaceState==RACE_PAUSE)
|
||||
chr->m_RaceState = RACE_STARTED;
|
||||
}
|
||||
}
|
||||
} else if(!str_comp_nocase(pMsg->m_pMessage, "/info"))
|
||||
{
|
||||
char buf[64];
|
||||
SendChatTarget(ClientId, "DDRace mod. Version: " RACE_VERSION);
|
||||
SendChatTarget(ClientId, "Official site: DDRace.info. But this is not official server=)");
|
||||
} else if(!strncmp(pMsg->m_pMessage, "/top5", 5) && !g_Config.m_SvHideScore)
|
||||
{
|
||||
const char *pt = pMsg->m_pMessage;
|
||||
int number = 0;
|
||||
pt += 6;
|
||||
while(*pt && *pt >= '0' && *pt <= '9')
|
||||
{
|
||||
number = number*10+(*pt-'0');
|
||||
pt++;
|
||||
}
|
||||
if(number)
|
||||
((CGameControllerRace*)m_pController)->m_Score.Top5Draw(ClientId, number);
|
||||
else
|
||||
((CGameControllerRace*)m_pController)->m_Score.Top5Draw(ClientId, 0);
|
||||
}
|
||||
else if(!str_comp_nocase(pMsg->m_pMessage, "/rank"))
|
||||
{
|
||||
char buf[512];
|
||||
const char *name = pMsg->m_pMessage;
|
||||
name += 6;
|
||||
int pos=0;
|
||||
CPlayerScore *pscore;
|
||||
|
||||
pscore = ((CGameControllerRace*)m_pController)->m_Score.SearchName(Server()->ClientName(ClientId), pos);
|
||||
|
||||
if(pscore && pos > -1 && pscore->m_Score != -1)
|
||||
{
|
||||
float time = pscore->m_Score;
|
||||
|
||||
str_format(buf, sizeof(buf), "%d. %s",!g_Config.m_SvHideScore? pos: 0, pscore->name);
|
||||
if (!g_Config.m_SvHideScore)
|
||||
SendChat(-1, CGameContext::CHAT_ALL, buf);
|
||||
else
|
||||
SendChatTarget(ClientId, buf);
|
||||
|
||||
if ((int)time/60 >= 1)
|
||||
str_format(buf, sizeof(buf), "Time: %d minute%s %f seconds", (int)time/60, (int)time/60 != 1 ? "s" : "" , time-((int)time/60)*60);
|
||||
else
|
||||
str_format(buf, sizeof(buf), "Time: %f seconds", time-((int)time/60)*60);
|
||||
}
|
||||
else
|
||||
str_format(buf, sizeof(buf), "%s is not ranked", Server()->ClientName(ClientId));
|
||||
|
||||
SendChatTarget(ClientId, buf);
|
||||
}
|
||||
else
|
||||
SendChatTarget(ClientId, "No such command!");
|
||||
|
||||
} else {
|
||||
if (m_apPlayers[ClientId]->m_Muted == 0)
|
||||
SendChat(ClientId, Team, pMsg->m_pMessage);
|
||||
else
|
||||
SendChatTarget(ClientId, "You are muted");
|
||||
}
|
||||
|
||||
|
||||
SendChat(ClientId, Team, pMsg->m_pMessage);
|
||||
}
|
||||
else if(MsgId == NETMSGTYPE_CL_CALLVOTE)
|
||||
{
|
||||
|
@ -709,16 +813,16 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
|||
// Switch team on given client and kill/respawn him
|
||||
if(m_pController->CanJoinTeam(pMsg->m_Team, ClientId))
|
||||
{
|
||||
if(m_pController->CanChangeTeam(p, pMsg->m_Team))
|
||||
{
|
||||
//if(m_pController->CanChangeTeam(p, pMsg->m_Team))
|
||||
//{
|
||||
p->m_Last_SetTeam = Server()->Tick();
|
||||
if(p->GetTeam() == -1 || pMsg->m_Team == -1)
|
||||
m_VoteUpdate = true;
|
||||
p->SetTeam(pMsg->m_Team);
|
||||
(void)m_pController->CheckTeamBalance();
|
||||
}
|
||||
else
|
||||
SendBroadcast("Teams must be balanced, please join other team", ClientId);
|
||||
//(void)m_pController->CheckTeamBalance();
|
||||
//}
|
||||
//else
|
||||
//SendBroadcast("Teams must be balanced, please join other team", ClientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -764,7 +868,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
|||
// set skin
|
||||
str_copy(p->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(p->m_TeeInfos.m_SkinName));
|
||||
|
||||
m_pController->OnPlayerInfoChange(p);
|
||||
//m_pController->OnPlayerInfoChange(p);
|
||||
|
||||
if(MsgId == NETMSGTYPE_CL_STARTINFO)
|
||||
{
|
||||
|
@ -810,7 +914,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConTuneParam(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConTuneParam(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
const char *pParamName = pResult->GetString(0);
|
||||
|
@ -825,7 +929,7 @@ void CGameContext::ConTuneParam(IConsole::IResult *pResult, void *pUserData)
|
|||
dbg_msg("tuning", "No such tuning parameter");
|
||||
}
|
||||
|
||||
void CGameContext::ConTuneReset(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConTuneReset(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
CTuningParams p;
|
||||
|
@ -834,7 +938,7 @@ void CGameContext::ConTuneReset(IConsole::IResult *pResult, void *pUserData)
|
|||
dbg_msg("tuning", "Tuning reset");
|
||||
}
|
||||
|
||||
void CGameContext::ConTuneDump(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConTuneDump(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
for(int i = 0; i < pSelf->Tuning()->Num(); i++)
|
||||
|
@ -845,13 +949,13 @@ void CGameContext::ConTuneDump(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConChangeMap(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConChangeMap(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
pSelf->m_pController->ChangeMap(pResult->GetString(0));
|
||||
}
|
||||
|
||||
void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(pResult->NumArguments())
|
||||
|
@ -860,34 +964,34 @@ void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData)
|
|||
pSelf->m_pController->StartRound();
|
||||
}
|
||||
|
||||
void CGameContext::ConBroadcast(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConBroadcast(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
pSelf->SendBroadcast(pResult->GetString(0), -1);
|
||||
}
|
||||
|
||||
void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
pSelf->SendChat(-1, CGameContext::CHAT_ALL, pResult->GetString(0));
|
||||
}
|
||||
|
||||
void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int ClientId = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
int Team = clamp(pResult->GetInteger(1), -1, 1);
|
||||
|
||||
dbg_msg("", "%d %d", ClientId, Team);
|
||||
dbg_msg("set_team", "%d %d", ClientId, Team);
|
||||
|
||||
if(!pSelf->m_apPlayers[ClientId])
|
||||
if(!pSelf->m_apPlayers[ClientId] || !compare_players(pSelf->m_apPlayers[cid], pSelf->m_apPlayers[ClientId]))
|
||||
return;
|
||||
|
||||
pSelf->m_apPlayers[ClientId]->SetTeam(Team);
|
||||
(void)pSelf->m_pController->CheckTeamBalance();
|
||||
//(void)pSelf->m_pController->CheckTeamBalance();
|
||||
}
|
||||
|
||||
void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int Len = str_length(pResult->GetString(0));
|
||||
|
@ -909,7 +1013,7 @@ void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
|
|||
pSelf->Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, -1);
|
||||
}
|
||||
|
||||
void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData)
|
||||
void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(str_comp_nocase(pResult->GetString(0), "yes") == 0)
|
||||
|
@ -921,7 +1025,7 @@ void CGameContext::ConVote(IConsole::IResult *pResult, void *pUserData)
|
|||
|
||||
void CGameContext::ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
pfnCallback(pResult, pCallbackUserData);
|
||||
pfnCallback(pResult, pCallbackUserData, -1);
|
||||
if(pResult->NumArguments())
|
||||
{
|
||||
CNetMsg_Sv_Motd Msg;
|
||||
|
@ -933,25 +1037,402 @@ void CGameContext::ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *p
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool CGameContext::CheatsAvailable(int cid) {
|
||||
if(!g_Config.m_SvCheats) {
|
||||
((CServer*)Server())->SendRconLine(cid, "Cheats are not available on this server.");
|
||||
}
|
||||
return g_Config.m_SvCheats;
|
||||
}
|
||||
|
||||
void CGameContext::ConGoLeft(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
||||
if (!pSelf->CheatsAvailable(cid))
|
||||
return;
|
||||
CCharacter* chr = pSelf->GetPlayerChar(cid);
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Core.m_Pos.x -= 32;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
void CGameContext::ConGoRight(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if (!pSelf->CheatsAvailable(cid))
|
||||
return;
|
||||
CCharacter* chr = pSelf->GetPlayerChar(cid);
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Core.m_Pos.x += 32;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
void CGameContext::ConGoUp(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if (!pSelf->CheatsAvailable(cid))
|
||||
return;
|
||||
CCharacter* chr = pSelf->GetPlayerChar(cid);
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Core.m_Pos.y -= 32;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
void CGameContext::ConGoDown(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if (!pSelf->CheatsAvailable(cid))
|
||||
return;
|
||||
CCharacter* chr = pSelf->GetPlayerChar(cid);
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Core.m_Pos.y += 32;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConMute(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
int Seconds = pResult->GetInteger(1);
|
||||
char buf[512];
|
||||
if (Seconds < 10)
|
||||
Seconds = 10;
|
||||
if (pSelf->m_apPlayers[cid1] && (compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1])))
|
||||
{
|
||||
if (pSelf->m_apPlayers[cid1]->m_Muted < Seconds * pSelf->Server()->TickSpeed()) {
|
||||
pSelf->m_apPlayers[cid1]->m_Muted = Seconds * pSelf->Server()->TickSpeed();
|
||||
}
|
||||
else
|
||||
Seconds = pSelf->m_apPlayers[cid1]->m_Muted / pSelf->Server()->TickSpeed();
|
||||
str_format(buf, sizeof(buf), "%s muted by %s for %d seconds", pSelf->Server()->ClientName(cid1), pSelf->Server()->ClientName(cid), Seconds);
|
||||
pSelf->SendChat(-1, CGameContext::CHAT_ALL, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConSetlvl(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
int level = clamp(pResult->GetInteger(1), 0, 3);
|
||||
|
||||
if (pSelf->m_apPlayers[cid1] && (pSelf->m_apPlayers[cid1]->m_Authed > level) && (compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1])))
|
||||
{
|
||||
pSelf->m_apPlayers[cid1]->m_Authed = level;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConKillPlayer(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
if(!pSelf->m_apPlayers[cid1])
|
||||
return;
|
||||
|
||||
if (pSelf->m_apPlayers[cid1] && compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1]))
|
||||
{
|
||||
pSelf->m_apPlayers[cid1]->KillCharacter(WEAPON_GAME);
|
||||
char buf[512];
|
||||
str_format(buf, sizeof(buf), "%s killed by %s", pSelf->Server()->ClientName(cid1), pSelf->Server()->ClientName(cid));
|
||||
pSelf->SendChat(-1, CGameContext::CHAT_ALL, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConNinjaMe(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid]->GetCharacter();
|
||||
if(chr) {
|
||||
chr->GiveNinja();
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConNinja(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if(chr) {
|
||||
chr->GiveNinja();
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGameContext::ConHammer(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
char buf[128];
|
||||
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
int type = pResult->GetInteger(1);
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if (!chr)
|
||||
return;
|
||||
CServer* serv = (CServer*)pSelf->Server();
|
||||
if (type>3 || type<0)
|
||||
{
|
||||
serv->SendRconLine(cid, "Select hammer between 0 and 3");
|
||||
}
|
||||
else
|
||||
{
|
||||
chr->m_HammerType = type;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
str_format(buf, sizeof(buf), "Hammer of cid=%d setted to %d",cid1,type);
|
||||
serv->SendRconLine(cid1, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConHammerMe(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
char buf[128];
|
||||
int type = pResult->GetInteger(1);
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid]->GetCharacter();
|
||||
if (!chr)
|
||||
return;
|
||||
CServer* serv = (CServer*)pSelf->Server();
|
||||
if (type>3 || type<0)
|
||||
{
|
||||
serv->SendRconLine(cid, "Select hammer between 0 and 3");
|
||||
}
|
||||
else
|
||||
{
|
||||
chr->m_HammerType = type;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
str_format(buf, sizeof(buf), "Hammer setted to %d",type);
|
||||
serv->SendRconLine(cid, buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGameContext::ConSuper(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
if (pSelf->m_apPlayers[cid1] && compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1]))
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Super = true;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConUnSuper(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
if (pSelf->m_apPlayers[cid1] && compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1]))
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Super = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConSuperMe(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
if (pSelf->m_apPlayers[cid])
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Super = true;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConUnSuperMe(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
if (pSelf->m_apPlayers[cid])
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Super = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConWeapons(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
if (pSelf->m_apPlayers[cid1] && compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1]))
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->GiveAllWeapons();
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConWeaponsMe(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
if (pSelf->m_apPlayers[cid])
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->GiveAllWeapons();
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConTeleport(IConsole::IResult *pResult, void *pUserData, int cid) {
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
int cid2 = clamp(pResult->GetInteger(1), 0, (int)MAX_CLIENTS-1);
|
||||
if(pSelf->m_apPlayers[cid1] && pSelf->m_apPlayers[cid2])
|
||||
{
|
||||
if (cid==cid1
|
||||
|| (compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1]) && compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid2]))
|
||||
|| (compare_players(pSelf->m_apPlayers[cid],pSelf->m_apPlayers[cid1]) && cid2==cid))
|
||||
{
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if(chr)
|
||||
{
|
||||
chr->m_Core.m_Pos = pSelf->m_apPlayers[cid2]->m_ViewPos;
|
||||
if(!g_Config.m_SvCheattime)
|
||||
chr->m_RaceState = RACE_CHEAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConTimer(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
char buf[128];
|
||||
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
int type = pResult->GetInteger(1);
|
||||
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if (!chr)
|
||||
return;
|
||||
CServer* serv = (CServer*)pSelf->Server();
|
||||
if (type>1 || type<0)
|
||||
{
|
||||
serv->SendRconLine(cid, "Select 0 for no time & 1 for with time");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(type)
|
||||
{
|
||||
chr->m_RaceState = RACE_STARTED;
|
||||
str_format(buf, sizeof(buf), "Cid=%d Has time now",cid1);
|
||||
}
|
||||
else if(!type)
|
||||
{
|
||||
chr->m_RaceState=RACE_CHEAT;
|
||||
str_format(buf, sizeof(buf), "Cid=%d Hasn't time now",cid1);
|
||||
}
|
||||
serv->SendRconLine(cid1, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConTimerReset(IConsole::IResult *pResult, void *pUserData, int cid)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
if(!pSelf->CheatsAvailable(cid)) return;
|
||||
char buf[128];
|
||||
|
||||
int cid1 = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1);
|
||||
|
||||
CCharacter* chr = pSelf->m_apPlayers[cid1]->GetCharacter();
|
||||
if (!chr)
|
||||
return;
|
||||
chr->m_StartTime = pSelf->Server()->Tick();
|
||||
chr->m_RefreshTime = pSelf->Server()->Tick();
|
||||
str_format(buf, sizeof(buf), "Cid=%d time resetted.",cid1);
|
||||
CServer* serv = (CServer*)pSelf->Server();
|
||||
serv->SendRconLine(cid1, buf);
|
||||
|
||||
}
|
||||
|
||||
void CGameContext::OnConsoleInit()
|
||||
{
|
||||
m_pServer = Kernel()->RequestInterface<IServer>();
|
||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||
|
||||
Console()->Register("timer", "ii", CFGFLAG_SERVER, ConTimer, this, "Sets the timer of player i1 to i2 0/1 on/off",2);
|
||||
Console()->Register("timerreset", "i", CFGFLAG_SERVER, ConTimerReset, this, "resets the timer of player i (to start count again timer cid 1)",1);
|
||||
|
||||
Console()->Register("tune", "si", CFGFLAG_SERVER, ConTuneParam, this, "");
|
||||
Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "");
|
||||
Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, "");
|
||||
Console()->Register("tele", "ii", CFGFLAG_SERVER, ConTeleport, this, "",2);
|
||||
|
||||
Console()->Register("weapons", "i", CFGFLAG_SERVER, ConWeapons, this, "",2);
|
||||
Console()->Register("weapons_me", "", CFGFLAG_SERVER, ConWeaponsMe, this, "",1);
|
||||
|
||||
Console()->Register("super", "i", CFGFLAG_SERVER, ConSuper, this, "",2);
|
||||
Console()->Register("unsuper", "i", CFGFLAG_SERVER, ConUnSuper, this, "",2);
|
||||
Console()->Register("super_me", "", CFGFLAG_SERVER, ConSuperMe, this, "",1);
|
||||
Console()->Register("unsuper_me", "", CFGFLAG_SERVER, ConUnSuperMe, this, "",1);// Mo
|
||||
|
||||
Console()->Register("hammer_me", "i", CFGFLAG_SERVER, ConHammerMe, this, "",1);
|
||||
Console()->Register("hammer", "ii", CFGFLAG_SERVER, ConHammer, this, "",2);
|
||||
|
||||
Console()->Register("ninja", "i", CFGFLAG_SERVER, ConNinja, this, "",2);
|
||||
Console()->Register("ninja_me", "", CFGFLAG_SERVER, ConNinjaMe, this, "",1);
|
||||
|
||||
|
||||
Console()->Register("kill_pl", "i", CFGFLAG_SERVER, ConKillPlayer, this, "",2);
|
||||
Console()->Register("auth", "ii", CFGFLAG_SERVER, ConSetlvl, this, "",3);
|
||||
Console()->Register("mute", "ii", CFGFLAG_SERVER, ConMute, this, "", 2);
|
||||
|
||||
Console()->Register("tune", "si", CFGFLAG_SERVER, ConTuneParam, this, "", 4);
|
||||
Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "", 4);
|
||||
Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, "", 4);
|
||||
|
||||
Console()->Register("change_map", "r", CFGFLAG_SERVER, ConChangeMap, this, "");
|
||||
Console()->Register("restart", "?i", CFGFLAG_SERVER, ConRestart, this, "");
|
||||
Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "");
|
||||
Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "");
|
||||
Console()->Register("set_team", "ii", CFGFLAG_SERVER, ConSetTeam, this, "");
|
||||
|
||||
Console()->Register("addvote", "r", CFGFLAG_SERVER, ConAddVote, this, "");
|
||||
Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "");
|
||||
Console()->Register("change_map", "r", CFGFLAG_SERVER, ConChangeMap, this, "", 3);
|
||||
Console()->Register("restart", "?i", CFGFLAG_SERVER, ConRestart, this, "", 3);
|
||||
Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "", 3);
|
||||
Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "", 3);
|
||||
Console()->Register("set_team", "ii", CFGFLAG_SERVER, ConSetTeam, this, "", 2);
|
||||
|
||||
Console()->Register("left", "", CFGFLAG_SERVER, ConGoLeft, this, "",1);
|
||||
Console()->Register("right", "", CFGFLAG_SERVER, ConGoRight, this, "",1);
|
||||
Console()->Register("up", "", CFGFLAG_SERVER, ConGoUp, this, "",1);
|
||||
Console()->Register("down", "", CFGFLAG_SERVER, ConGoDown, this, "",1);
|
||||
//Console()->Register("sv_cheats", "i", CFGFLAG_SERVER, ConCheats , 0, "Turns Cheats On/Off",4);
|
||||
Console()->Register("addvote", "r", CFGFLAG_SERVER, ConAddVote, this, "", 4);
|
||||
Console()->Register("vote", "r", CFGFLAG_SERVER, ConVote, this, "", 3);
|
||||
|
||||
Console()->Chain("sv_motd", ConchainSpecialMotdupdate, this);
|
||||
|
||||
}
|
||||
|
||||
void CGameContext::OnInit(/*class IKernel *pKernel*/)
|
||||
|
@ -974,16 +1455,22 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
|
|||
//world = new GAMEWORLD;
|
||||
//players = new CPlayer[MAX_CLIENTS];
|
||||
|
||||
char buf[512];
|
||||
str_format(buf, sizeof(buf), "data/maps/%s.cfg", g_Config.m_SvMap); //
|
||||
Console()->ExecuteFile(buf);
|
||||
str_format(buf, sizeof(buf), "data/maps/%s.map.cfg", g_Config.m_SvMap);
|
||||
Console()->ExecuteFile(buf);
|
||||
// dbg_msg("Note","For map cfgs in windows and linux u need the files");
|
||||
// dbg_msg("Note","in a folder i nthe same dir as teeworlds_srv");
|
||||
// dbg_msg("Note","data/maps/%s.cfg", config.sv_map);
|
||||
// select gametype
|
||||
if(str_comp(g_Config.m_SvGametype, "mod") == 0)
|
||||
m_pController = new CGameControllerMOD(this);
|
||||
else if(str_comp(g_Config.m_SvGametype, "ctf") == 0)
|
||||
m_pController = new CGameControllerCTF(this);
|
||||
else if(str_comp(g_Config.m_SvGametype, "tdm") == 0)
|
||||
m_pController = new CGameControllerTDM(this);
|
||||
else
|
||||
m_pController = new CGameControllerDM(this);
|
||||
|
||||
m_pController = new CGameControllerRace(this);
|
||||
//float temp;
|
||||
//m_Tuning.Get("player_hooking",&temp);
|
||||
//g_Config.m_SvPhook = temp;
|
||||
//m_Tuning.Get("player_collision",&temp);
|
||||
//g_Config.m_SvNpc=(!temp);
|
||||
|
||||
Server()->SetBrowseInfo(m_pController->m_pGameType, -1);
|
||||
|
||||
// setup core world
|
||||
|
@ -994,15 +1481,8 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
|
|||
CMapItemLayerTilemap *pTileMap = m_Layers.GameLayer();
|
||||
CTile *pTiles = (CTile *)Kernel()->RequestInterface<IMap>()->GetData(pTileMap->m_Data);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
num_spawn_points[0] = 0;
|
||||
num_spawn_points[1] = 0;
|
||||
num_spawn_points[2] = 0;
|
||||
*/
|
||||
|
||||
if (!m_Layers.FGameLayer()) dbg_msg("fglayer","Everything is Alright");
|
||||
//windows usually crshes here
|
||||
for(int y = 0; y < pTileMap->m_Height; y++)
|
||||
{
|
||||
for(int x = 0; x < pTileMap->m_Width; x++)
|
||||
|
@ -1011,13 +1491,36 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
|
|||
|
||||
if(Index >= ENTITY_OFFSET)
|
||||
{
|
||||
vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f);
|
||||
m_pController->OnEntity(Index-ENTITY_OFFSET, Pos);
|
||||
//vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f);
|
||||
m_pController->OnEntity(Index-ENTITY_OFFSET, x, y, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//****************FRONT GAME LAYER********************
|
||||
|
||||
pTileMap = m_Layers.FGameLayer();
|
||||
if (pTileMap!=0)
|
||||
{
|
||||
pTiles = (CTile *)Kernel()->RequestInterface<IMap>()->GetData(pTileMap->m_Data);
|
||||
for(int y = 0; y < pTileMap->m_Height; y++)
|
||||
{
|
||||
for(int x = 0; x < pTileMap->m_Width; x++)
|
||||
{
|
||||
int Index = pTiles[y*pTileMap->m_Width+x].m_Index;
|
||||
|
||||
if(Index >= ENTITY_OFFSET)
|
||||
{
|
||||
//vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f);
|
||||
m_pController->OnEntity(Index-ENTITY_OFFSET, x, y, true);
|
||||
} else {
|
||||
m_pController->MapConfig(Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//game.world.insert_entity(game.Controller);
|
||||
|
||||
#ifdef CONF_DEBUG
|
||||
if(g_Config.m_DbgDummies)
|
||||
|
|
|
@ -42,16 +42,49 @@ class CGameContext : public IGameServer
|
|||
CNetObjHandler m_NetObjHandler;
|
||||
CTuningParams m_Tuning;
|
||||
|
||||
static void ConTuneParam(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConTuneReset(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConTuneDump(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConChangeMap(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConRestart(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConBroadcast(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConSay(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConAddVote(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConVote(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConMute(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConSetlvl(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConKillPlayer(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConNinjaMe(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConNinja(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConHammerMe(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConHammer(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConUnSuperMe(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConUnSuper(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConSuper(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConSuperMe(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConWeaponsMe(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConWeapons(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConTeleport(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConTuneParam(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConTuneReset(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConTuneDump(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConPhook(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConTimerReset(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConTimer(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConChangeMap(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConRestart(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConBroadcast(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConSay(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConGoLeft(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConGoRight(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConGoUp(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConGoDown(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
|
||||
static void ConAddVote(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConVote(IConsole::IResult *pResult, void *pUserData, int cid);
|
||||
static void ConchainSpecialMotdupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
|
||||
CGameContext(int Resetting);
|
||||
|
@ -71,6 +104,11 @@ public:
|
|||
|
||||
CEventHandler m_Events;
|
||||
CPlayer *m_apPlayers[MAX_CLIENTS];
|
||||
|
||||
//bool m_Cheats;
|
||||
//bool m_EndlessDrag;
|
||||
//bool m_Tunes;
|
||||
//bool m_PlayersCollision;
|
||||
|
||||
IGameController *m_pController;
|
||||
CGameWorld m_World;
|
||||
|
@ -85,6 +123,8 @@ public:
|
|||
void SendVoteStatus(int ClientId, int Total, int Yes, int No);
|
||||
void AbortVoteKickOnDisconnect(int ClientId);
|
||||
|
||||
bool CheatsAvailable(int cid);
|
||||
|
||||
int m_VoteCreator;
|
||||
int64 m_VoteCloseTime;
|
||||
bool m_VoteUpdate;
|
||||
|
@ -156,6 +196,9 @@ public:
|
|||
virtual void OnClientDrop(int ClientId);
|
||||
virtual void OnClientDirectInput(int ClientId, void *pInput);
|
||||
virtual void OnClientPredictedInput(int ClientId, void *pInput);
|
||||
|
||||
virtual void OnSetAuthed(int ClientId, void *pInput);
|
||||
virtual void OnSetResistent(int ClientId, void *pInput);
|
||||
|
||||
virtual const char *Version();
|
||||
virtual const char *NetVersion();
|
||||
|
|
|
@ -8,6 +8,14 @@
|
|||
#include "gamecontroller.h"
|
||||
#include "gamecontext.h"
|
||||
|
||||
#include "entities/light.h"
|
||||
#include "entities/drager.h"
|
||||
#include "entities/gun.h"
|
||||
#include "entities/projectile.h"
|
||||
#include "entities/plasma.h"
|
||||
|
||||
#include <game/layers.h>
|
||||
|
||||
|
||||
IGameController::IGameController(class CGameContext *pGameServer)
|
||||
{
|
||||
|
@ -22,8 +30,8 @@ IGameController::IGameController(class CGameContext *pGameServer)
|
|||
m_RoundStartTick = Server()->Tick();
|
||||
m_RoundCount = 0;
|
||||
m_GameFlags = 0;
|
||||
m_aTeamscore[0] = 0;
|
||||
m_aTeamscore[1] = 0;
|
||||
//m_aTeamscore[0] = 0;
|
||||
//m_aTeamscore[1] = 0;
|
||||
m_aMapWish[0] = 0;
|
||||
|
||||
m_UnbalancedTick = -1;
|
||||
|
@ -83,7 +91,7 @@ bool IGameController::CanSpawn(CPlayer *pPlayer, vec2 *pOutPos)
|
|||
if(pPlayer->GetTeam() == -1)
|
||||
return false;
|
||||
|
||||
if(IsTeamplay())
|
||||
/*if(IsTeamplay())
|
||||
{
|
||||
Eval.m_FriendlyTeam = pPlayer->GetTeam();
|
||||
|
||||
|
@ -97,16 +105,30 @@ bool IGameController::CanSpawn(CPlayer *pPlayer, vec2 *pOutPos)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{*/
|
||||
EvaluateSpawnType(&Eval, 0);
|
||||
EvaluateSpawnType(&Eval, 1);
|
||||
EvaluateSpawnType(&Eval, 2);
|
||||
}
|
||||
//}
|
||||
|
||||
*pOutPos = Eval.m_Pos;
|
||||
return Eval.m_Got;
|
||||
}
|
||||
|
||||
bool IGameController::MapConfig(int index)
|
||||
{
|
||||
if (index == TILE_CP_D)
|
||||
{
|
||||
//g_Config.m_SvNpc = true;
|
||||
return true;
|
||||
}
|
||||
else if (index == TILE_CP_U)
|
||||
{
|
||||
g_Config.m_SvEndlessDrag = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IGameController::OnEntity(int Index, vec2 Pos)
|
||||
{
|
||||
|
@ -138,7 +160,7 @@ bool IGameController::OnEntity(int Index, vec2 Pos)
|
|||
Type = POWERUP_WEAPON;
|
||||
SubType = WEAPON_RIFLE;
|
||||
}
|
||||
else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
|
||||
else if(Index == ENTITY_POWERUP_NINJA)
|
||||
{
|
||||
Type = POWERUP_NINJA;
|
||||
SubType = WEAPON_NINJA;
|
||||
|
@ -154,6 +176,139 @@ bool IGameController::OnEntity(int Index, vec2 Pos)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool IGameController::OnEntity(int Index, int x, int y, bool flayer)
|
||||
{
|
||||
int Type = -1;
|
||||
int SubType = 0;
|
||||
|
||||
vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f);
|
||||
|
||||
int sides[8];
|
||||
sides[0]=GameServer()->Collision()->GetIndex(x,y+1,flayer);
|
||||
sides[1]=GameServer()->Collision()->GetIndex(x+1,y+1,flayer);
|
||||
sides[2]=GameServer()->Collision()->GetIndex(x+1,y,flayer);
|
||||
sides[3]=GameServer()->Collision()->GetIndex(x+1,y-1,flayer);
|
||||
sides[4]=GameServer()->Collision()->GetIndex(x,y-1,flayer);
|
||||
sides[5]=GameServer()->Collision()->GetIndex(x-1,y-1,flayer);
|
||||
sides[6]=GameServer()->Collision()->GetIndex(x-1,y,flayer);
|
||||
sides[7]=GameServer()->Collision()->GetIndex(x-1,y+1,flayer);
|
||||
|
||||
if (!flayer)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if(Index == ENTITY_POWERUP_NINJA)
|
||||
{
|
||||
Type = POWERUP_NINJA;
|
||||
SubType = WEAPON_NINJA;
|
||||
}
|
||||
else if(Index >= ENTITY_LASER_FAST_CW && Index <= ENTITY_LASER_FAST_CCW)
|
||||
{
|
||||
int sides2[8];
|
||||
sides2[0]=GameServer()->Collision()->GetIndex(x,y+2,flayer);
|
||||
sides2[1]=GameServer()->Collision()->GetIndex(x+2,y+2,flayer);
|
||||
sides2[2]=GameServer()->Collision()->GetIndex(x+2,y,flayer);
|
||||
sides2[3]=GameServer()->Collision()->GetIndex(x+2,y-2,flayer);
|
||||
sides2[4]=GameServer()->Collision()->GetIndex(x,y-2,flayer);
|
||||
sides2[5]=GameServer()->Collision()->GetIndex(x-2,y-2,flayer);
|
||||
sides2[6]=GameServer()->Collision()->GetIndex(x-2,y,flayer);
|
||||
sides2[7]=GameServer()->Collision()->GetIndex(x-2,y+2,flayer);
|
||||
|
||||
float ang_speed;
|
||||
int ind=Index-ENTITY_LASER_STOP;
|
||||
int m;
|
||||
if (ind<0)
|
||||
{
|
||||
ind=-ind;
|
||||
m=1;
|
||||
}
|
||||
else if(ind==0)
|
||||
m=0;
|
||||
else
|
||||
m=-1;
|
||||
|
||||
|
||||
if (ind==0)
|
||||
ang_speed=0.0f;
|
||||
else if (ind==1)
|
||||
ang_speed=pi/360;
|
||||
else if (ind==2)
|
||||
ang_speed=pi/180;
|
||||
else if (ind==3)
|
||||
ang_speed=pi/90;
|
||||
ang_speed*=m;
|
||||
|
||||
for(int i=0; i<8;i++)
|
||||
{
|
||||
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);
|
||||
lgt->ang_speed=ang_speed;
|
||||
if (sides2[i]>=ENTITY_LASER_C_SLOW && sides2[i]<=ENTITY_LASER_C_FAST)
|
||||
{
|
||||
lgt->speed=1+(sides2[i]-ENTITY_LASER_C_SLOW)*2;
|
||||
lgt->cur_length=lgt->length;
|
||||
}
|
||||
else if(sides2[i]>=ENTITY_LASER_O_SLOW && sides2[i]<=ENTITY_LASER_O_FAST)
|
||||
{
|
||||
lgt->speed=1+(sides2[i]-ENTITY_LASER_O_SLOW)*2;
|
||||
lgt->cur_length=0;
|
||||
}
|
||||
else
|
||||
lgt->cur_length=lgt->length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if(Index>=ENTITY_DRAGER_WEAK && Index <=ENTITY_DRAGER_STRONG)
|
||||
{
|
||||
new CDrager(&GameServer()->m_World,Pos,Index-ENTITY_DRAGER_WEAK+1);
|
||||
}
|
||||
else if(Index>=ENTITY_DRAGER_WEAK_NW && Index <=ENTITY_DRAGER_STRONG_NW)
|
||||
{
|
||||
new CDrager(&GameServer()->m_World, Pos,Index-ENTITY_DRAGER_WEAK_NW+1,true);
|
||||
}
|
||||
else if(Index==ENTITY_PLASMA)
|
||||
{
|
||||
new CGun(&GameServer()->m_World, Pos);
|
||||
}
|
||||
if(Type != -1)
|
||||
{
|
||||
CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType);
|
||||
pPickup->m_Pos = Pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void IGameController::EndRound()
|
||||
{
|
||||
if(m_Warmup) // game can't end when we are running warmup
|
||||
|
@ -171,23 +326,58 @@ void IGameController::ResetGame()
|
|||
|
||||
const char *IGameController::GetTeamName(int Team)
|
||||
{
|
||||
if(IsTeamplay())
|
||||
{
|
||||
if(Team == 0)
|
||||
return "red team";
|
||||
else if(Team == 1)
|
||||
return "blue team";
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Team == 0)
|
||||
return "game";
|
||||
}
|
||||
|
||||
return "spectators";
|
||||
}
|
||||
|
||||
static bool IsSeparator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
|
||||
void get_side_pos(int side, int &x, int &y) {
|
||||
if (side==0)
|
||||
{
|
||||
x=0;
|
||||
y=1;
|
||||
}
|
||||
else if(side==1)
|
||||
{
|
||||
x=1;
|
||||
y=1;
|
||||
}
|
||||
else if(side==2)
|
||||
{
|
||||
x=1;
|
||||
y=0;
|
||||
}
|
||||
else if(side==3)
|
||||
{
|
||||
x=1;
|
||||
y=-1;
|
||||
}
|
||||
else if(side==4)
|
||||
|
||||
{
|
||||
x=0;
|
||||
y=-1;
|
||||
}
|
||||
else if(side==5)
|
||||
{
|
||||
x=-1;
|
||||
y=-1;
|
||||
|
||||
}
|
||||
else if(side==6)
|
||||
|
||||
{
|
||||
x=-1;
|
||||
y=0;
|
||||
}
|
||||
else if(side==7)
|
||||
{
|
||||
x=-1;
|
||||
y=+1;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsSeparator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
|
||||
|
||||
void IGameController::StartRound()
|
||||
{
|
||||
|
@ -197,8 +387,6 @@ void IGameController::StartRound()
|
|||
m_SuddenDeath = 0;
|
||||
m_GameOverTick = -1;
|
||||
GameServer()->m_World.m_Paused = false;
|
||||
m_aTeamscore[0] = 0;
|
||||
m_aTeamscore[1] = 0;
|
||||
m_ForceBalanced = false;
|
||||
dbg_msg("game","start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS);
|
||||
}
|
||||
|
@ -208,7 +396,7 @@ void IGameController::ChangeMap(const char *pToMap)
|
|||
str_copy(m_aMapWish, pToMap, sizeof(m_aMapWish));
|
||||
EndRound();
|
||||
}
|
||||
|
||||
/*
|
||||
void IGameController::CycleMap()
|
||||
{
|
||||
if(m_aMapWish[0] != 0)
|
||||
|
@ -276,7 +464,7 @@ void IGameController::CycleMap()
|
|||
dbg_msg("game", "rotating map to %s", &Buf[i]);
|
||||
str_copy(g_Config.m_SvMap, &Buf[i], sizeof(g_Config.m_SvMap));
|
||||
}
|
||||
|
||||
*/
|
||||
void IGameController::PostReset()
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
|
@ -284,13 +472,13 @@ void IGameController::PostReset()
|
|||
if(GameServer()->m_apPlayers[i])
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->Respawn();
|
||||
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;
|
||||
//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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void IGameController::OnPlayerInfoChange(class CPlayer *pP)
|
||||
{
|
||||
const int aTeamColors[2] = {65387, 10223467};
|
||||
|
@ -304,10 +492,11 @@ void IGameController::OnPlayerInfoChange(class CPlayer *pP)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int IGameController::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon)
|
||||
{
|
||||
/*
|
||||
// do scoreing
|
||||
if(!pKiller || Weapon == WEAPON_GAME)
|
||||
return 0;
|
||||
|
@ -319,7 +508,7 @@ int IGameController::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *
|
|||
pKiller->m_Score--; // teamkill
|
||||
else
|
||||
pKiller->m_Score++; // normal kill
|
||||
}
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -329,8 +518,9 @@ void IGameController::OnCharacterSpawn(class CCharacter *pChr)
|
|||
pChr->IncreaseHealth(10);
|
||||
|
||||
// give default weapons
|
||||
//pChr->GiveAllWeapons();
|
||||
pChr->GiveWeapon(WEAPON_HAMMER, -1);
|
||||
pChr->GiveWeapon(WEAPON_GUN, 10);
|
||||
pChr->GiveWeapon(WEAPON_GUN, -1);
|
||||
}
|
||||
|
||||
void IGameController::DoWarmup(int Seconds)
|
||||
|
@ -340,7 +530,7 @@ void IGameController::DoWarmup(int Seconds)
|
|||
else
|
||||
m_Warmup = Seconds*Server()->TickSpeed();
|
||||
}
|
||||
|
||||
/*
|
||||
bool IGameController::IsFriendlyFire(int Cid1, int Cid2)
|
||||
{
|
||||
if(Cid1 == Cid2)
|
||||
|
@ -357,7 +547,7 @@ bool IGameController::IsFriendlyFire(int Cid1, int Cid2)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
*/
|
||||
bool IGameController::IsForceBalanced()
|
||||
{
|
||||
if(m_ForceBalanced)
|
||||
|
@ -389,12 +579,12 @@ void IGameController::Tick()
|
|||
// game over.. wait for restart
|
||||
if(Server()->Tick() > m_GameOverTick+Server()->TickSpeed()*10)
|
||||
{
|
||||
CycleMap();
|
||||
//CycleMap();
|
||||
StartRound();
|
||||
m_RoundCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// do team-balancing
|
||||
if (IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60)
|
||||
{
|
||||
|
@ -447,9 +637,10 @@ void IGameController::Tick()
|
|||
}
|
||||
m_UnbalancedTick = -1;
|
||||
}
|
||||
|
||||
*/
|
||||
// update browse info
|
||||
int Prog = -1;
|
||||
/*
|
||||
if(g_Config.m_SvTimelimit > 0)
|
||||
Prog = max(Prog, (Server()->Tick()-m_RoundStartTick) * 100 / (g_Config.m_SvTimelimit*Server()->TickSpeed()*60));
|
||||
|
||||
|
@ -472,16 +663,16 @@ void IGameController::Tick()
|
|||
|
||||
if(m_Warmup)
|
||||
Prog = -1;
|
||||
|
||||
*/
|
||||
Server()->SetBrowseInfo(m_pGameType, Prog);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool IGameController::IsTeamplay() const
|
||||
{
|
||||
return m_GameFlags&GAMEFLAG_TEAMS;
|
||||
}
|
||||
|
||||
*/
|
||||
void IGameController::Snap(int SnappingClient)
|
||||
{
|
||||
CNetObj_Game *pGameObj = (CNetObj_Game *)Server()->SnapNewItem(NETOBJTYPE_GAME, 0, sizeof(CNetObj_Game));
|
||||
|
@ -489,28 +680,28 @@ void IGameController::Snap(int SnappingClient)
|
|||
pGameObj->m_GameOver = m_GameOverTick==-1?0:1;
|
||||
pGameObj->m_SuddenDeath = m_SuddenDeath;
|
||||
|
||||
pGameObj->m_ScoreLimit = g_Config.m_SvScorelimit;
|
||||
pGameObj->m_TimeLimit = g_Config.m_SvTimelimit;
|
||||
//pGameObj->m_ScoreLimit = g_Config.m_SvScorelimit;
|
||||
//pGameObj->m_TimeLimit = g_Config.m_SvTimelimit;
|
||||
pGameObj->m_RoundStartTick = m_RoundStartTick;
|
||||
pGameObj->m_Flags = m_GameFlags;
|
||||
|
||||
pGameObj->m_Warmup = m_Warmup;
|
||||
|
||||
pGameObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0;
|
||||
pGameObj->m_RoundNum = /*(str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap :*/ 0;
|
||||
pGameObj->m_RoundCurrent = m_RoundCount+1;
|
||||
|
||||
|
||||
if(SnappingClient == -1)
|
||||
{
|
||||
// we are recording a demo, just set the scores
|
||||
pGameObj->m_TeamscoreRed = m_aTeamscore[0];
|
||||
pGameObj->m_TeamscoreBlue = m_aTeamscore[1];
|
||||
pGameObj->m_TeamscoreRed = 0;//m_aTeamscore[0];
|
||||
pGameObj->m_TeamscoreBlue = 0;//m_aTeamscore[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: this little hack should be removed
|
||||
pGameObj->m_TeamscoreRed = IsTeamplay() ? m_aTeamscore[0] : GameServer()->m_apPlayers[SnappingClient]->m_Score;
|
||||
pGameObj->m_TeamscoreBlue = m_aTeamscore[1];
|
||||
pGameObj->m_TeamscoreRed = /*IsTeamplay() ? m_aTeamscore[0] : */GameServer()->m_apPlayers[SnappingClient]->m_Score;
|
||||
pGameObj->m_TeamscoreBlue = 0;//m_aTeamscore[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,8 +722,8 @@ int IGameController::GetAutoTeam(int Notthisid)
|
|||
}
|
||||
|
||||
int Team = 0;
|
||||
if(IsTeamplay())
|
||||
Team = aNumplayers[0] > aNumplayers[1] ? 1 : 0;
|
||||
//if(IsTeamplay())
|
||||
// Team = aNumplayers[0] > aNumplayers[1] ? 1 : 0;
|
||||
|
||||
if(CanJoinTeam(Team, Notthisid))
|
||||
return Team;
|
||||
|
@ -556,7 +747,7 @@ bool IGameController::CanJoinTeam(int Team, int Notthisid)
|
|||
|
||||
return (aNumplayers[0] + aNumplayers[1]) < g_Config.m_SvMaxClients-g_Config.m_SvSpectatorSlots;
|
||||
}
|
||||
|
||||
/*
|
||||
bool IGameController::CheckTeamBalance()
|
||||
{
|
||||
if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime)
|
||||
|
@ -584,7 +775,7 @@ bool IGameController::CheckTeamBalance()
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*//*
|
||||
bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam)
|
||||
{
|
||||
int aT[2] = {0, 0};
|
||||
|
@ -616,7 +807,7 @@ bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam)
|
|||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
*//*
|
||||
void IGameController::DoPlayerScoreWincheck()
|
||||
{
|
||||
if(m_GameOverTick == -1 && !m_Warmup)
|
||||
|
@ -665,12 +856,15 @@ void IGameController::DoTeamScoreWincheck()
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int IGameController::ClampTeam(int Team)
|
||||
{
|
||||
if(Team < 0) // spectator
|
||||
return -1;
|
||||
if(IsTeamplay())
|
||||
return Team&1;
|
||||
//if(IsTeamplay())
|
||||
// return Team&1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ protected:
|
|||
void EvaluateSpawnType(CSpawnEval *pEval, int Type);
|
||||
bool EvaluateSpawn(class CPlayer *pP, vec2 *pPos);
|
||||
|
||||
void CycleMap();
|
||||
//void CycleMap();
|
||||
void ResetGame();
|
||||
|
||||
char m_aMapWish[128];
|
||||
|
@ -49,7 +49,7 @@ protected:
|
|||
int m_GameOverTick;
|
||||
int m_SuddenDeath;
|
||||
|
||||
int m_aTeamscore[2];
|
||||
//int m_aTeamscore[2];
|
||||
|
||||
int m_Warmup;
|
||||
int m_RoundCount;
|
||||
|
@ -61,14 +61,14 @@ protected:
|
|||
public:
|
||||
const char *m_pGameType;
|
||||
|
||||
bool IsTeamplay() const;
|
||||
//bool IsTeamplay() const;
|
||||
|
||||
IGameController(class CGameContext *pGameServer);
|
||||
virtual ~IGameController();
|
||||
|
||||
void DoTeamScoreWincheck();
|
||||
void DoPlayerScoreWincheck();
|
||||
|
||||
//void DoTeamScoreWincheck();
|
||||
//void DoPlayerScoreWincheck();
|
||||
bool MapConfig(int index);
|
||||
void DoWarmup(int Seconds);
|
||||
|
||||
void StartRound();
|
||||
|
@ -101,6 +101,7 @@ public:
|
|||
bool?
|
||||
*/
|
||||
virtual bool OnEntity(int Index, vec2 Pos);
|
||||
virtual bool OnEntity(int Index, int x, int y, bool flayer);
|
||||
|
||||
/*
|
||||
Function: on_CCharacter_spawn
|
||||
|
@ -124,7 +125,7 @@ public:
|
|||
virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
|
||||
|
||||
|
||||
virtual void OnPlayerInfoChange(class CPlayer *pP);
|
||||
//virtual void OnPlayerInfoChange(class CPlayer *pP);
|
||||
|
||||
//
|
||||
virtual bool CanSpawn(class CPlayer *pP, vec2 *pPos);
|
||||
|
@ -135,8 +136,8 @@ public:
|
|||
virtual const char *GetTeamName(int Team);
|
||||
virtual int GetAutoTeam(int NotThisId);
|
||||
virtual bool CanJoinTeam(int Team, int NotThisId);
|
||||
bool CheckTeamBalance();
|
||||
bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam);
|
||||
//bool CheckTeamBalance();
|
||||
//bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam);
|
||||
int ClampTeam(int Team);
|
||||
|
||||
virtual void PostReset();
|
||||
|
|
20
src/game/server/gamemodes/race.cpp
Normal file
20
src/game/server/gamemodes/race.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* copyright (c) 2007 rajh, race mod stuff */
|
||||
#include <engine/server.h>
|
||||
#include <game/mapitems.h>
|
||||
#include <game/server/entities/character.h>
|
||||
#include <game/server/player.h>
|
||||
#include <game/server/gamecontext.h>
|
||||
#include "race.h"
|
||||
|
||||
CGameControllerRace::CGameControllerRace(class CGameContext *pGameServer)
|
||||
: IGameController(pGameServer), m_Score(pGameServer)
|
||||
{
|
||||
|
||||
m_pGameType = "DDRace";
|
||||
}
|
||||
|
||||
|
||||
void CGameControllerRace::Tick()
|
||||
{
|
||||
IGameController::Tick();
|
||||
}
|
18
src/game/server/gamemodes/race.h
Normal file
18
src/game/server/gamemodes/race.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* copyright (c) 2007 rajh and gregwar. Score stuff */
|
||||
|
||||
#ifndef RACE_H
|
||||
#define RACE_H
|
||||
#include <game/server/gamecontroller.h>
|
||||
#include <game/server/score.h>
|
||||
|
||||
class CGameControllerRace : public IGameController
|
||||
{
|
||||
public:
|
||||
CGameControllerRace(class CGameContext *pGameServer);
|
||||
|
||||
CScore m_Score;
|
||||
|
||||
virtual void Tick();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,11 @@
|
|||
#include <new>
|
||||
#include "player.h"
|
||||
#include <engine/server.h>
|
||||
#include <engine/shared/config.h>
|
||||
|
||||
#include "player.h"
|
||||
#include "gamecontext.h"
|
||||
#include <game/gamecore.h>
|
||||
#include "gamemodes/race.h"
|
||||
|
||||
MACRO_ALLOC_POOL_ID_IMPL(CPlayer, MAX_CLIENTS)
|
||||
|
||||
|
@ -13,6 +18,7 @@ CPlayer::CPlayer(CGameContext *pGameServer, int CID, int Team)
|
|||
m_DieTick = Server()->Tick();
|
||||
m_ScoreStartTick = Server()->Tick();
|
||||
Character = 0;
|
||||
m_Muted = 0;
|
||||
this->m_ClientID = CID;
|
||||
m_Team = GameServer()->m_pController->ClampTeam(Team);
|
||||
}
|
||||
|
@ -25,8 +31,21 @@ CPlayer::~CPlayer()
|
|||
|
||||
void CPlayer::Tick()
|
||||
{
|
||||
int pos=0;
|
||||
CPlayerScore *pscore = ((CGameControllerRace*)GameServer()->m_pController)->m_Score.SearchName(Server()->ClientName(m_ClientID), pos);
|
||||
if(pscore && pos > -1 && pscore->m_Score != -1)
|
||||
{
|
||||
float time = pscore->m_Score;
|
||||
//if (!config.sv_hide_score)
|
||||
m_Score = time * 100;
|
||||
//else
|
||||
// score=authed;
|
||||
} else
|
||||
m_Score = 0.0f;
|
||||
Server()->SetClientAuthed(m_ClientID, m_Authed);
|
||||
Server()->SetClientScore(m_ClientID, m_Score);
|
||||
|
||||
if(m_Muted > 0) m_Muted--;
|
||||
// do latency stuff
|
||||
{
|
||||
IServer::CClientInfo Info;
|
||||
|
@ -98,7 +117,11 @@ void CPlayer::OnDisconnect()
|
|||
char Buf[512];
|
||||
str_format(Buf, sizeof(Buf), "%s has left the game", Server()->ClientName(m_ClientID));
|
||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, Buf);
|
||||
|
||||
char Cmd[64];
|
||||
if(m_Muted > 0) {
|
||||
str_format(Cmd, sizeof(Cmd), "ban %d ", m_ClientID, m_Muted/Server()->TickSpeed());
|
||||
GameServer()->Console()->ExecuteLine(Cmd, 3, -1);
|
||||
}
|
||||
dbg_msg("game", "leave player='%d:%s'", m_ClientID, Server()->ClientName(m_ClientID));
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +185,7 @@ void CPlayer::SetTeam(int Team)
|
|||
m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
|
||||
dbg_msg("game", "team_join player='%d:%s' m_Team=%d", m_ClientID, Server()->ClientName(m_ClientID), m_Team);
|
||||
|
||||
GameServer()->m_pController->OnPlayerInfoChange(GameServer()->m_apPlayers[m_ClientID]);
|
||||
//GameServer()->m_pController->OnPlayerInfoChange(GameServer()->m_apPlayers[m_ClientID]);
|
||||
}
|
||||
|
||||
void CPlayer::TryRespawn()
|
||||
|
|
|
@ -48,6 +48,24 @@ public:
|
|||
int m_Last_Emote;
|
||||
int m_Last_Kill;
|
||||
|
||||
//DDRace
|
||||
int m_Muted;
|
||||
//int hammer_ type;
|
||||
|
||||
// TODO: clean this up
|
||||
int m_Authed;
|
||||
int m_Resistent;
|
||||
|
||||
bool m_ColorSet; // Set if player changed color at least once
|
||||
|
||||
//race var
|
||||
int m_Starttime;
|
||||
int m_Refreshtime;
|
||||
int m_RaceState;
|
||||
int m_Besttick;
|
||||
int m_Lasttick;
|
||||
float m_BestLap;
|
||||
|
||||
// TODO: clean this up
|
||||
struct
|
||||
{
|
||||
|
|
139
src/game/server/score.cpp
Normal file
139
src/game/server/score.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/* copyright (c) 2008 rajh and gregwar. Score stuff */
|
||||
|
||||
#include "score.h"
|
||||
#include "gamecontext.h"
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <engine/config.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/server.h>
|
||||
|
||||
CPlayerScore::CPlayerScore(const char *name, float score)
|
||||
{
|
||||
str_copy(this->name, name, sizeof(this->name));
|
||||
this->m_Score = score;
|
||||
}
|
||||
|
||||
std::list<CPlayerScore> top;
|
||||
|
||||
CScore::CScore(class CGameContext *pGameServer)
|
||||
{
|
||||
m_pGameServer = pGameServer;
|
||||
Load();
|
||||
}
|
||||
|
||||
std::string SaveFile()
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << g_Config.m_SvMap << "_record.dtb";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void CScore::Save()
|
||||
{
|
||||
std::fstream f;
|
||||
f.open(SaveFile().c_str(), std::ios::out);
|
||||
if(!f.fail()) {
|
||||
for(std::list<CPlayerScore>::iterator i=top.begin(); i!=top.end(); i++)
|
||||
{
|
||||
f << i->name << std::endl << i->m_Score << std::endl;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
|
||||
void CScore::Load()
|
||||
{
|
||||
std::fstream f;
|
||||
f.open(SaveFile().c_str(), std::ios::in);
|
||||
top.clear();
|
||||
while (!f.eof() && !f.fail())
|
||||
{
|
||||
std::string tmpname, tmpscore;
|
||||
std::getline(f, tmpname);
|
||||
if(!f.eof() && tmpname != "")
|
||||
{
|
||||
std::getline(f, tmpscore);
|
||||
top.push_back(*new CPlayerScore(tmpname.c_str(), atof(tmpscore.c_str())));
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
|
||||
CPlayerScore *CScore::SearchName(const char *name, int &pos)
|
||||
{
|
||||
pos=0;
|
||||
for (std::list<CPlayerScore>::iterator i = top.begin(); i!=top.end(); i++)
|
||||
{
|
||||
pos++;
|
||||
if (!strcmp(i->name, name))
|
||||
{
|
||||
return & (*i);
|
||||
}
|
||||
}
|
||||
pos=-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPlayerScore *CScore::SearchName(const char *name)
|
||||
{
|
||||
for (std::list<CPlayerScore>::iterator i = top.begin(); i!=top.end(); i++)
|
||||
{
|
||||
if (!strcmp(i->name, name))
|
||||
{
|
||||
return & (*i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CScore::ParsePlayer(const char *name, float score)
|
||||
{
|
||||
CPlayerScore *player = SearchName(name);
|
||||
if (player)
|
||||
{
|
||||
if (player->m_Score > score)
|
||||
{
|
||||
player->m_Score = score;
|
||||
top.sort();
|
||||
Save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top.push_back(*new CPlayerScore(name, score));
|
||||
top.sort();
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
void CScore::Top5Draw(int id, int debut)
|
||||
{
|
||||
int pos = 1;
|
||||
//char buf[512];
|
||||
|
||||
m_pGameServer->SendChatTarget(id, "----------- Top 5 -----------");
|
||||
for (std::list<CPlayerScore>::iterator i = top.begin(); i != top.end() && pos <= 5+debut; i++)
|
||||
{
|
||||
if(i->m_Score < 0)
|
||||
continue;
|
||||
|
||||
if(pos >= debut)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << pos << ". " << i->name << " Time: ";
|
||||
|
||||
if ((int)(i->m_Score)/60 != 0)
|
||||
oss << (int)(i->m_Score)/60 << " minute(s) ";
|
||||
if (i->m_Score-((int)i->m_Score/60)*60 != 0)
|
||||
oss << i->m_Score-((int)i->m_Score/60)*60 <<" second(s)";
|
||||
|
||||
m_pGameServer->SendChatTarget(id, oss.str().c_str());
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
m_pGameServer->SendChatTarget(id, "-----------------------------");
|
||||
}
|
34
src/game/server/score.h
Normal file
34
src/game/server/score.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* copyright (c) 2008 rajh and gregwar. Score stuff */
|
||||
|
||||
#ifndef SCORE_H_RACE
|
||||
#define SCORE_H_RACE
|
||||
#include <engine/server.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
|
||||
class CPlayerScore
|
||||
{
|
||||
public:
|
||||
char name[MAX_NAME_LENGTH];
|
||||
float m_Score;
|
||||
|
||||
CPlayerScore(const char *name, float score);
|
||||
|
||||
bool operator==(const CPlayerScore& other) { return (this->m_Score == other.m_Score); }
|
||||
bool operator<(const CPlayerScore& other) { return (this->m_Score < other.m_Score); }
|
||||
};
|
||||
|
||||
class CScore
|
||||
{
|
||||
class CGameContext *m_pGameServer;
|
||||
public:
|
||||
CScore(class CGameContext *pGameServer);
|
||||
|
||||
void Save();
|
||||
void Load();
|
||||
CPlayerScore *SearchName(const char *name, int &pos);
|
||||
CPlayerScore *SearchName(const char *name);
|
||||
void ParsePlayer(const char *name, float score);
|
||||
void Top5Draw(int id, int debut);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -22,13 +22,13 @@ MACRO_TUNING_PARAM(VelrampRange, velramp_range, 2000)
|
|||
MACRO_TUNING_PARAM(VelrampCurvature, velramp_curvature, 1.4f)
|
||||
|
||||
// weapon tuning
|
||||
MACRO_TUNING_PARAM(GunCurvature, gun_curvature, 1.25f)
|
||||
MACRO_TUNING_PARAM(GunSpeed, gun_speed, 2200.0f)
|
||||
MACRO_TUNING_PARAM(GunCurvature, gun_curvature, 0.0f)
|
||||
MACRO_TUNING_PARAM(GunSpeed, gun_speed, 1400.0f)
|
||||
MACRO_TUNING_PARAM(GunLifetime, gun_lifetime, 2.0f)
|
||||
|
||||
MACRO_TUNING_PARAM(ShotgunCurvature, shotgun_curvature, 1.25f)
|
||||
MACRO_TUNING_PARAM(ShotgunSpeed, shotgun_speed, 2750.0f)
|
||||
MACRO_TUNING_PARAM(ShotgunSpeeddiff, shotgun_speeddiff, 0.8f)
|
||||
MACRO_TUNING_PARAM(ShotgunCurvature, shotgun_curvature, 0.0f)
|
||||
MACRO_TUNING_PARAM(ShotgunSpeed, shotgun_speed, 500.0f)
|
||||
MACRO_TUNING_PARAM(ShotgunSpeeddiff, shotgun_speeddiff, 0.0f)
|
||||
MACRO_TUNING_PARAM(ShotgunLifetime, shotgun_lifetime, 0.20f)
|
||||
|
||||
MACRO_TUNING_PARAM(GrenadeCurvature, grenade_curvature, 7.0f)
|
||||
|
|
|
@ -49,25 +49,25 @@ MACRO_CONFIG_INT(UiColorAlpha, ui_color_alpha, 228, 0, 255, CFGFLAG_CLIENT|CFGFL
|
|||
MACRO_CONFIG_INT(GfxNoclip, gfx_noclip, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Disable clipping")
|
||||
|
||||
// server
|
||||
MACRO_CONFIG_INT(SvWarmup, sv_warmup, 0, 0, 0, CFGFLAG_SERVER, "Number of seconds to do warpup before round starts")
|
||||
MACRO_CONFIG_INT(SvWarmup, sv_warmup, 0, 0, 30, CFGFLAG_SERVER, "Number of seconds to do warpup before round starts")
|
||||
MACRO_CONFIG_STR(SvMotd, sv_motd, 900, "", CFGFLAG_SERVER, "Message of the day to display for the clients")
|
||||
MACRO_CONFIG_INT(SvTeamdamage, sv_teamdamage, 0, 0, 1, CFGFLAG_SERVER, "Team damage")
|
||||
/*MACRO_CONFIG_INT(SvTeamdamage, sv_teamdamage, 0, 0, 1, CFGFLAG_SERVER, "Team damage")
|
||||
MACRO_CONFIG_STR(SvMaprotation, sv_maprotation, 768, "", CFGFLAG_SERVER, "Maps to rotate between")
|
||||
MACRO_CONFIG_INT(SvRoundsPerMap, sv_rounds_per_map, 1, 1, 100, CFGFLAG_SERVER, "Number of rounds on each map before rotating")
|
||||
MACRO_CONFIG_INT(SvPowerups, sv_powerups, 1, 0, 1, CFGFLAG_SERVER, "Allow powerups like ninja")
|
||||
MACRO_CONFIG_INT(SvScorelimit, sv_scorelimit, 20, 0, 1000, CFGFLAG_SERVER, "Score limit (0 disables)")
|
||||
MACRO_CONFIG_INT(SvTimelimit, sv_timelimit, 0, 0, 1000, CFGFLAG_SERVER, "Time limit in minutes (0 disables)")
|
||||
MACRO_CONFIG_STR(SvGametype, sv_gametype, 32, "dm", CFGFLAG_SERVER, "Game type (dm, tdm, ctf)")
|
||||
MACRO_CONFIG_STR(SvGametype, sv_gametype, 32, "dm", CFGFLAG_SERVER, "Game type (dm, tdm, ctf)")*/
|
||||
MACRO_CONFIG_INT(SvTournamentMode, sv_tournament_mode, 0, 0, 1, CFGFLAG_SERVER, "Tournament mode. When enabled, players joins the server as spectator")
|
||||
MACRO_CONFIG_INT(SvSpamprotection, sv_spamprotection, 1, 0, 1, CFGFLAG_SERVER, "Spam protection")
|
||||
|
||||
MACRO_CONFIG_INT(SvSpectatorSlots, sv_spectator_slots, 0, 0, MAX_CLIENTS, CFGFLAG_SERVER, "Number of slots to reserve for spectators")
|
||||
MACRO_CONFIG_INT(SvTeambalanceTime, sv_teambalance_time, 1, 0, 1000, CFGFLAG_SERVER, "How many minutes to wait before autobalancing teams")
|
||||
//MACRO_CONFIG_INT(SvTeambalanceTime, sv_teambalance_time, 1, 0, 1000, CFGFLAG_SERVER, "How many minutes to wait before autobalancing teams")
|
||||
|
||||
MACRO_CONFIG_INT(SvVoteKick, sv_vote_kick, 1, 0, 1, CFGFLAG_SERVER, "Allow voting to kick players")
|
||||
MACRO_CONFIG_INT(SvVoteKickBantime, sv_vote_kick_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time to ban a player if kicked by vote. 0 makes it just use kick")
|
||||
MACRO_CONFIG_INT(SvVoteScorelimit, sv_vote_scorelimit, 0, 0, 1, CFGFLAG_SERVER, "Allow voting to change score limit")
|
||||
MACRO_CONFIG_INT(SvVoteTimelimit, sv_vote_timelimit, 0, 0, 1, CFGFLAG_SERVER, "Allow voting to change time limit")
|
||||
MACRO_CONFIG_INT(SvVoteKickBantime, sv_vote_kick_bantime, 300, 0, 1000000, CFGFLAG_SERVER, "The time to ban a player if kicked by vote. 0 makes it just use kick")
|
||||
//MACRO_CONFIG_INT(SvVoteScorelimit, sv_vote_scorelimit, 0, 0, 1, CFGFLAG_SERVER, "Allow voting to change score limit")
|
||||
//MACRO_CONFIG_INT(SvVoteTimelimit, sv_vote_timelimit, 0, 0, 1, CFGFLAG_SERVER, "Allow voting to change time limit")
|
||||
|
||||
// debug
|
||||
#ifdef CONF_DEBUG // this one can crash the server if not used correctly
|
||||
|
@ -76,4 +76,13 @@ MACRO_CONFIG_INT(SvVoteTimelimit, sv_vote_timelimit, 0, 0, 1, CFGFLAG_SERVER, "A
|
|||
|
||||
MACRO_CONFIG_INT(DbgFocus, dbg_focus, 0, 0, 1, CFGFLAG_CLIENT, "")
|
||||
MACRO_CONFIG_INT(DbgTuning, dbg_tuning, 0, 0, 1, CFGFLAG_CLIENT, "")
|
||||
|
||||
MACRO_CONFIG_INT(SvReservedSlots, sv_reserved_slots, 0, 0, 16, CFGFLAG_SERVER, "")
|
||||
MACRO_CONFIG_STR(SvReservedSlotsPass, sv_reserved_slots_pass, 32, "", CFGFLAG_SERVER, "")
|
||||
|
||||
/* MRace */
|
||||
MACRO_CONFIG_STR(SvBroadcast, sv_broadcast, 64, "DDRace is cool!", CFGFLAG_SERVER, "broadcasting message")
|
||||
MACRO_CONFIG_STR(SvWelcome, sv_welcome, 64, "Visit DDRace.info", CFGFLAG_SERVER, "message which players see when joining server")
|
||||
MACRO_CONFIG_INT(SvVotes, sv_votes, 1, 0, 1, CFGFLAG_SERVER, "")
|
||||
MACRO_CONFIG_INT(SvHideScore, sv_hide_score, 0, 0, 1, CFGFLAG_SERVER, "")
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef GAME_VERSION_H
|
||||
#define GAME_VERSION_H
|
||||
#include "generated/nethash.c"
|
||||
|
||||
#define RACE_VERSION "25.07.2010 New"
|
||||
#define GAME_VERSION "0.5 trunk"
|
||||
#define GAME_NETVERSION "0.5 " GAME_NETVERSION_HASH
|
||||
#define GAME_NETVERSION "0.5 b67d1f1a1eea234e"
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue