diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..ff2bd627a --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +clean: + ./bam -c + +build: + ./bam server_release \ No newline at end of file diff --git a/build server.bat b/build server.bat new file mode 100644 index 000000000..2bbc2cd7d --- /dev/null +++ b/build server.bat @@ -0,0 +1,5 @@ +:start +call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" +.\bam server_release +pause +goto start \ No newline at end of file diff --git a/src/engine/console.h b/src/engine/console.h index 34fa42725..a5785faab 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -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; diff --git a/src/engine/server.h b/src/engine/server.h index fa5d24981..e2ee3c35c 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -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; }; diff --git a/src/engine/server/register.h b/src/engine/server/register.h index a800ec1ed..dbface3c4 100644 --- a/src/engine/server/register.h +++ b/src/engine/server/register.h @@ -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 class CRegister { diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index c45b2dd47..a58e6d615 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -25,6 +25,8 @@ #include +#include + #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 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(); - 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); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 70c8899c6..09d1c0683 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -2,6 +2,14 @@ #define ENGINE_SERVER_SERVER_H #include +#include +#include +#include +#include +#include +#include +#include +#include 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); diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index e11eab6d6..e00ed4284 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -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") diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index b7850bea2..e38b2930c 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -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); diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 9064fa867..17907cc94 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -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); diff --git a/src/engine/shared/network.h b/src/engine/shared/network.h index 7de534a44..c48e570c7 100644 --- a/src/engine/shared/network.h +++ b/src/engine/shared/network.h @@ -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); diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 2d30a7d1b..b4b7b8455 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -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; } diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 0dee57c8f..871cb19a9 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -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(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data)); + if(m_pLayers->FGameLayer() != 0) { + m_pFTiles = static_cast(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; +} + diff --git a/src/game/collision.h b/src/game/collision.h index 66603890b..b40e0118a 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -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 diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index f5aa18cfc..96231dfcf 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -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) { diff --git a/src/game/layers.cpp b/src/game/layers.cpp index e99befd2d..93b8387e0 100644 --- a/src/game/layers.cpp +++ b/src/game/layers.cpp @@ -1,4 +1,5 @@ #include "layers.h" +#include 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)); } } } diff --git a/src/game/layers.h b/src/game/layers.h index 198fe6952..eae296e69 100644 --- a/src/game/layers.h +++ b/src/game/layers.h @@ -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; }; diff --git a/src/game/mapitems.h b/src/game/mapitems.h index 4fe4c1599..ff66b6ce6 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -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, diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 81d1f85bb..c2bb9dc8e 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -1,10 +1,13 @@ #include +#include #include +#include #include #include - +#include #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= 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; diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h index bea0c002e..333b4b9a7 100644 --- a/src/game/server/entities/character.h +++ b/src/game/server/entities/character.h @@ -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 diff --git a/src/game/server/entities/drager.cpp b/src/game/server/entities/drager.cpp new file mode 100644 index 000000000..f18fda282 --- /dev/null +++ b/src/game/server/entities/drager.cpp @@ -0,0 +1,144 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include +#include +#include +#include +#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(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_tickTick()-4) + start_tick=Server()->Tick()-4; + else if (start_tick>Server()->Tick()) + start_tick=Server()->Tick(); + obj->m_StartTick = start_tick; +} +//я тут был +//я тоже diff --git a/src/game/server/entities/drager.h b/src/game/server/entities/drager.h new file mode 100644 index 000000000..0fdf48869 --- /dev/null +++ b/src/game/server/entities/drager.h @@ -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 + +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 diff --git a/src/game/server/entities/gun.cpp b/src/game/server/entities/gun.cpp new file mode 100644 index 000000000..d86414593 --- /dev/null +++ b/src/game/server/entities/gun.cpp @@ -0,0 +1,95 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include +#include +#include +#include +#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(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; +} diff --git a/src/game/server/entities/gun.h b/src/game/server/entities/gun.h new file mode 100644 index 000000000..a3eea2093 --- /dev/null +++ b/src/game/server/entities/gun.h @@ -0,0 +1,29 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ + +#ifndef CGun_TYPE +#define CGun_TYPE + +#include +#include + +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 \ No newline at end of file diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp index 6bc260741..80bb13f47 100644 --- a/src/game/server/entities/laser.cpp +++ b/src/game/server/entities/laser.cpp @@ -1,9 +1,10 @@ // copyright (c) 2007 magnus auvinen, see licence.txt for more info #include #include +#include #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() diff --git a/src/game/server/entities/laser.h b/src/game/server/entities/laser.h index 040cfb4cb..c4c5ad1f3 100644 --- a/src/game/server/entities/laser.h +++ b/src/game/server/entities/laser.h @@ -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 diff --git a/src/game/server/entities/light.cpp b/src/game/server/entities/light.cpp new file mode 100644 index 000000000..58fb3f8d2 --- /dev/null +++ b/src/game/server/entities/light.cpp @@ -0,0 +1,119 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include +#include +#include +#include +#include "light.h" +#include + +////////////////////////////////////////////////// +// 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(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_tickTick()-4) + start_tick=Server()->Tick()-4; + else if (start_tick>Server()->Tick()) + start_tick=Server()->Tick(); + pObj->m_StartTick = start_tick; +} diff --git a/src/game/server/entities/light.h b/src/game/server/entities/light.h new file mode 100644 index 000000000..bac96eac6 --- /dev/null +++ b/src/game/server/entities/light.h @@ -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 + +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 diff --git a/src/game/server/entities/pickup.cpp b/src/game/server/entities/pickup.cpp index 9798e2c3e..68ec3b8ee 100644 --- a/src/game/server/entities/pickup.cpp +++ b/src/game/server/entities/pickup.cpp @@ -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;iCreateSound(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(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(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_Id, sizeof(CNetObj_Pickup))); pP->m_X = (int)m_Pos.x; pP->m_Y = (int)m_Pos.y; diff --git a/src/game/server/entities/pickup.h b/src/game/server/entities/pickup.h index c076464c5..b21a0a1d7 100644 --- a/src/game/server/entities/pickup.h +++ b/src/game/server/entities/pickup.h @@ -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 diff --git a/src/game/server/entities/plasma.cpp b/src/game/server/entities/plasma.cpp new file mode 100644 index 000000000..cf2354d10 --- /dev/null +++ b/src/game/server/entities/plasma.cpp @@ -0,0 +1,78 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include +#include +#include +#include +#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(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; +} diff --git a/src/game/server/entities/plasma.h b/src/game/server/entities/plasma.h new file mode 100644 index 000000000..9cd82a1d4 --- /dev/null +++ b/src/game/server/entities/plasma.h @@ -0,0 +1,27 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ + +#ifndef PLASMA_TYPE +#define PLASMA_TYPE + +#include + +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 \ No newline at end of file diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index 18652ba1b..342534f56 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -1,9 +1,10 @@ #include #include +#include #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); } } diff --git a/src/game/server/entities/projectile.h b/src/game/server/entities/projectile.h index 87f4f6c39..d3ecc541e 100644 --- a/src/game/server/entities/projectile.h +++ b/src/game/server/entities/projectile.h @@ -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 diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 0c3c1ef5e..9e0201b0f 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1,16 +1,15 @@ #include +#include #include #include +#include #include #include #include "gamecontext.h" #include #include #include -#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(); m_pConsole = Kernel()->RequestInterface(); + + 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()->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()->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) diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index d55203e70..bac77b81e 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -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(); diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 07f8bf86a..69d7060e8 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -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 + 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; } diff --git a/src/game/server/gamecontroller.h b/src/game/server/gamecontroller.h index 0624dcab0..45eef7ae6 100644 --- a/src/game/server/gamecontroller.h +++ b/src/game/server/gamecontroller.h @@ -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(); diff --git a/src/game/server/gamemodes/race.cpp b/src/game/server/gamemodes/race.cpp new file mode 100644 index 000000000..45348cab9 --- /dev/null +++ b/src/game/server/gamemodes/race.cpp @@ -0,0 +1,20 @@ +/* copyright (c) 2007 rajh, race mod stuff */ +#include +#include +#include +#include +#include +#include "race.h" + +CGameControllerRace::CGameControllerRace(class CGameContext *pGameServer) +: IGameController(pGameServer), m_Score(pGameServer) +{ + + m_pGameType = "DDRace"; +} + + +void CGameControllerRace::Tick() +{ + IGameController::Tick(); +} diff --git a/src/game/server/gamemodes/race.h b/src/game/server/gamemodes/race.h new file mode 100644 index 000000000..485a7e3c6 --- /dev/null +++ b/src/game/server/gamemodes/race.h @@ -0,0 +1,18 @@ +/* copyright (c) 2007 rajh and gregwar. Score stuff */ + +#ifndef RACE_H +#define RACE_H +#include +#include + +class CGameControllerRace : public IGameController +{ +public: + CGameControllerRace(class CGameContext *pGameServer); + + CScore m_Score; + + virtual void Tick(); +}; + +#endif diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 2d5d244f9..3ed23a872 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -1,6 +1,11 @@ #include -#include "player.h" +#include +#include +#include "player.h" +#include "gamecontext.h" +#include +#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() diff --git a/src/game/server/player.h b/src/game/server/player.h index ca7ab0720..b511513d0 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -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 { diff --git a/src/game/server/score.cpp b/src/game/server/score.cpp new file mode 100644 index 000000000..577f95cee --- /dev/null +++ b/src/game/server/score.cpp @@ -0,0 +1,139 @@ +/* copyright (c) 2008 rajh and gregwar. Score stuff */ + +#include "score.h" +#include "gamecontext.h" +#include +#include +#include +#include +#include +#include +#include + +CPlayerScore::CPlayerScore(const char *name, float score) +{ + str_copy(this->name, name, sizeof(this->name)); + this->m_Score = score; +} + +std::list 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::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::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::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::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, "-----------------------------"); +} \ No newline at end of file diff --git a/src/game/server/score.h b/src/game/server/score.h new file mode 100644 index 000000000..b5b8b9238 --- /dev/null +++ b/src/game/server/score.h @@ -0,0 +1,34 @@ +/* copyright (c) 2008 rajh and gregwar. Score stuff */ + +#ifndef SCORE_H_RACE +#define SCORE_H_RACE +#include +#include + +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 diff --git a/src/game/tuning.h b/src/game/tuning.h index b336fcb38..a7b7f931a 100644 --- a/src/game/tuning.h +++ b/src/game/tuning.h @@ -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) diff --git a/src/game/variables.h b/src/game/variables.h index 6a247671b..215b51677 100644 --- a/src/game/variables.h +++ b/src/game/variables.h @@ -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 diff --git a/src/game/version.h b/src/game/version.h index 534a5dd28..18d89b419 100644 --- a/src/game/version.h +++ b/src/game/version.h @@ -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